From 406e89ea5038069c848af33e43b27a9cf8b23db3 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 20 Jan 2026 18:24:13 -0500 Subject: [PATCH 01/32] introducing generic event message services; implementing GalaxyService using the generic framework --- .../session/normal/GalaxyHandlerLogic.scala | 25 ++--- .../support/SessionGalaxyHandlers.scala | 6 +- .../session/support/ZoningOperations.scala | 7 +- .../objects/zones/ZoneHotSpotProjector.scala | 13 +-- .../services/CavernRotationService.scala | 20 ++-- .../net/psforever/services/RemoverActor.scala | 2 +- .../net/psforever/services/Service.scala | 23 ----- .../services/avatar/AvatarService.scala | 3 +- .../avatar/AvatarServiceMessage.scala | 5 +- .../avatar/AvatarServiceResponse.scala | 4 +- .../services/base/EventExchange.scala | 16 ++++ .../services/base/GenericEventBus.scala | 27 ++++++ .../services/base/GenericEventService.scala | 72 +++++++++++++++ .../base/GenericEventServiceWithSupport.scala | 51 +++++++++++ .../support/SimilarityComparator.scala | 2 +- .../{ => base}/support/SupportActor.scala | 2 +- .../support/SupportActorCaseConversions.scala | 2 +- .../psforever/services/chat/ChatService.scala | 7 +- .../services/galaxy/GalaxyService.scala | 91 +++---------------- .../galaxy/GalaxyServiceMessage.scala | 41 ++++++++- .../galaxy/GalaxyServiceResponse.scala | 11 ++- .../psforever/services/hart/HartTimer.scala | 10 +- .../services/local/LocalService.scala | 5 +- .../services/local/LocalServiceMessage.scala | 5 +- .../services/local/LocalServiceResponse.scala | 4 +- .../properties/PropertyOverrideManager.scala | 6 +- .../teamwork/SquadServiceMessage.scala | 5 +- .../teamwork/SquadServiceResponse.scala | 4 +- .../teamwork/SquadSubscriptionEntity.scala | 4 +- .../services/vehicle/VehicleService.scala | 3 +- .../vehicle/VehicleServiceMessage.scala | 5 +- .../vehicle/VehicleServiceResponse.scala | 4 +- .../vehicle/support/TurretUpgrader.scala | 2 +- 33 files changed, 309 insertions(+), 178 deletions(-) create mode 100644 src/main/scala/net/psforever/services/base/EventExchange.scala create mode 100644 src/main/scala/net/psforever/services/base/GenericEventBus.scala create mode 100644 src/main/scala/net/psforever/services/base/GenericEventService.scala create mode 100644 src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala rename src/main/scala/net/psforever/services/{ => base}/support/SimilarityComparator.scala (87%) rename src/main/scala/net/psforever/services/{ => base}/support/SupportActor.scala (99%) rename src/main/scala/net/psforever/services/{ => base}/support/SupportActorCaseConversions.scala (96%) diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index fe2d4b873..28804cf8f 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -3,9 +3,10 @@ package net.psforever.actors.session.normal import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor -import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionGalaxyHandlers, SessionData} +import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers} import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage} +import net.psforever.services.base.EventResponse +import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.types.{MemberAction, PlanetSideEmpire} object GalaxyHandlerLogic { @@ -32,9 +33,9 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A /* response handlers */ - def handle(reply: GalaxyResponse.Response): Unit = { + def handle(reply: EventResponse): Unit = { reply match { - case GalaxyResponse.HotSpotUpdate(zone_index, priority, hot_spot_info) => + case GalaxyAction.HotSpotUpdate(zone_index, priority, hot_spot_info) => sendResponse( HotSpotUpdateMessage( zone_index, @@ -43,7 +44,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A ) ) - case GalaxyResponse.MapUpdate(msg) => + case GalaxyAction.MapUpdate(msg) => sendResponse(msg) import net.psforever.actors.zone.ZoneActor import net.psforever.zones.Zones @@ -53,7 +54,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A case None => } - case GalaxyResponse.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) => + case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) => val faction = player.Faction val from = fromFactions.contains(faction) val to = toFactions.contains(faction) @@ -63,16 +64,16 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction)) } - case GalaxyResponse.FlagMapUpdate(msg) => + case GalaxyAction.FlagMapUpdate(msg) => sendResponse(msg) - case GalaxyResponse.TransferPassenger(temp_channel, vehicle, _, manifest) => + case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, _, manifest) => sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest) - case GalaxyResponse.LockedZoneUpdate(zone, time) => + case GalaxyAction.LockedZoneUpdate(zone, time) => sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time)) - case GalaxyResponse.UnlockedZoneUpdate(zone) => + case GalaxyAction.UnlockedZoneUpdate(zone) => sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L)) val popBO = 0 val pop = zone.LivePlayers.distinctBy(_.CharId) @@ -81,10 +82,10 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A val popVS = pop.count(_.Faction == PlanetSideEmpire.VS) sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO)) - case GalaxyResponse.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) => + case GalaxyAction.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) => avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name) - case GalaxyResponse.SendResponse(msg) => + case GalaxyAction.SendResponse(msg) => sendResponse(msg) case _ => () diff --git a/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala index ad7614296..3f01a8ce6 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala @@ -3,16 +3,18 @@ package net.psforever.actors.session.support import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.packet.game.FriendsResponse +import net.psforever.services.base.EventResponse + +import scala.annotation.unused // import net.psforever.actors.session.AvatarActor -import net.psforever.services.galaxy.GalaxyResponse trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality { def ops: SessionGalaxyHandlers def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit - def handle(reply: GalaxyResponse.Response): Unit + def handle(@unused reply: EventResponse): Unit } class SessionGalaxyHandlers( diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index a69a4a724..0b8e5924f 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -602,7 +602,7 @@ class ZoningOperations( sendResponse(ReplicationStreamMessage(5, Some(6), Vector.empty)) //clear squad list spawn.initializeFriendsAndIgnoredLists() //the following subscriptions last until character switch/logout - galaxyService ! Service.Join("galaxy") //for galaxy-wide messages + galaxyService ! Service.Join("") //for galaxy-wide messages galaxyService ! Service.Join(s"${avatar.faction}") //for hotspots, etc. sessionLogic.squadService ! Service.Join(s"${avatar.faction}") //channel will be player.Faction sessionLogic.squadService ! Service.Join(s"${avatar.id}") //channel will be player.CharId (in order to work with packets) @@ -1470,10 +1470,7 @@ class ZoningOperations( case Some(manifest) => val toChannel = manifest.file val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID) - galaxyService ! GalaxyServiceMessage( - toChannel, - GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest) - ) + galaxyService ! GalaxyServiceMessage(toChannel, GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)) vehicle.CargoHolds.values .collect { case hold if hold.isOccupied => diff --git a/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala b/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala index a22b32314..09c67d47b 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala @@ -5,6 +5,8 @@ import akka.actor.{Actor, ActorRef, Cancellable, Props} import net.psforever.objects.Default import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.services.ServiceManager +import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} + import scala.collection.mutable.ListBuffer import scala.concurrent.duration._ @@ -303,12 +305,11 @@ class ZoneHotSpotProjector(zone: Zone, hotspots: ListBuffer[HotSpotInfo], blanki val zoneNumber = zone.Number val hotSpotInfoList = hotSpotInfos.toList affectedFactions.foreach(faction => - galaxy ! Zone.HotSpot.Update( - faction, - zoneNumber, - 1, - ZoneHotSpotProjector.SpecificHotSpotInfo(faction, hotSpotInfoList) - ) + galaxy ! GalaxyServiceMessage(faction.toString, GalaxyAction.HotSpotUpdate( + zoneNumber, + 1, + ZoneHotSpotProjector.SpecificHotSpotInfo(faction, hotSpotInfoList) + )) ) } } diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index 824a817b1..102bcd9d9 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -12,7 +12,7 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage, GalaxyServiceResponse} +import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage, GalaxyServiceResponse} import net.psforever.types.ChatMessageType import net.psforever.util.Config import net.psforever.zones.Zones @@ -557,20 +557,14 @@ class CavernRotationService( val (lockedZones, unlockedZones) = managedZones.partition(_.locked) //borrow GalaxyService response structure, but send to the specific endpoint math.max(0, monitor.start + monitor.duration - curr) unlockedZones.foreach { monitor => - sendToSession ! GalaxyServiceResponse("", GalaxyResponse.UnlockedZoneUpdate(monitor.zone)) + sendToSession ! GalaxyServiceResponse("", GalaxyAction.UnlockedZoneUpdate(monitor.zone)) } val sortedLocked = lockedZones.sortBy(z => z.start) sortedLocked.take(2).foreach { monitor => - sendToSession ! GalaxyServiceResponse( - "", - GalaxyResponse.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr)) - ) + sendToSession ! GalaxyServiceResponse("", GalaxyAction.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr))) } sortedLocked.takeRight(2).foreach { monitor => - sendToSession ! GalaxyServiceResponse( - "", - GalaxyResponse.LockedZoneUpdate(monitor.zone, 0L) - ) + sendToSession ! GalaxyServiceResponse("", GalaxyAction.LockedZoneUpdate(monitor.zone, 0L)) } } @@ -654,8 +648,8 @@ class CavernRotationService( val unlocking = managedZones(nextToUnlock) val lockingZone = locking.zone val unlockingZone = unlocking.zone - val fullHoursBetweenRotationsAsHours = timeToCompleteAllRotationsHours.hours - val fullHoursBetweenRotationsAsMillis = fullHoursBetweenRotationsAsHours.toMillis + //val fullHoursBetweenRotationsAsHours = timeToCompleteAllRotationsHours.hours + //val fullHoursBetweenRotationsAsMillis = fullHoursBetweenRotationsAsHours.toMillis val hoursBetweenRotationsAsHours = timeBetweenRotationsHours.hours val prevToLock = nextToLock nextToLock = (nextToLock + 1) % managedZones.size @@ -729,7 +723,7 @@ class CavernRotationService( advanceTimeBy: FiniteDuration, galaxyService: ActorRef ) : Unit = { - val curr = System.currentTimeMillis() + //val curr = System.currentTimeMillis() val advanceByTimeAsMillis = advanceTimeBy.toMillis managedZones.foreach { zone => zone.start = zone.start - advanceByTimeAsMillis diff --git a/src/main/scala/net/psforever/services/RemoverActor.scala b/src/main/scala/net/psforever/services/RemoverActor.scala index d6118dccc..6b7ecb9a7 100644 --- a/src/main/scala/net/psforever/services/RemoverActor.scala +++ b/src/main/scala/net/psforever/services/RemoverActor.scala @@ -5,8 +5,8 @@ import akka.actor.Cancellable import net.psforever.objects.guid.{StraightforwardTask, TaskBundle, TaskWorkflow} import net.psforever.objects.zones.Zone import net.psforever.objects.{Default, PlanetSideGameObject} +import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import net.psforever.types.Vector3 -import net.psforever.services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import scala.concurrent.Future import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/services/Service.scala b/src/main/scala/net/psforever/services/Service.scala index 48d7a2f53..19ae064aa 100644 --- a/src/main/scala/net/psforever/services/Service.scala +++ b/src/main/scala/net/psforever/services/Service.scala @@ -1,8 +1,6 @@ // Copyright (c) 2017 PSForever package net.psforever.services -import akka.event.{ActorEventBus, SubchannelClassification} -import akka.util.Subclassification import net.psforever.types.PlanetSideGUID object Service { @@ -14,24 +12,3 @@ object Service { final case class Leave(channel: Option[String] = None) final case class LeaveAll() } - -trait GenericEventBusMsg { - def channel: String -} - -class GenericEventBus[A <: GenericEventBusMsg] extends ActorEventBus with SubchannelClassification { - type Event = A - type Classifier = String - - protected def classify(event: Event): Classifier = event.channel - - protected def subclassification = - new Subclassification[Classifier] { - def isEqual(x: Classifier, y: Classifier) = x == y - def isSubclass(x: Classifier, y: Classifier) = x.startsWith(y) - } - - protected def publish(event: Event, subscriber: Subscriber): Unit = { - subscriber ! event - } -} diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index bbdf1f99a..f76776be9 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -7,7 +7,8 @@ import net.psforever.packet.game.ObjectCreateMessage import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMessageParent, PlacementData} import net.psforever.types.PlanetSideGUID import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover} -import net.psforever.services.{GenericEventBus, RemoverActor, Service} +import net.psforever.services.base.GenericEventBus +import net.psforever.services.{RemoverActor, Service} class AvatarService(zone: Zone) extends Actor { private val undertaker: ActorRef = context.actorOf(Props[CorpseRemovalActor](), s"${zone.id}-corpse-removal-agent") diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala index e17cfe0aa..11e9ca16a 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala @@ -13,6 +13,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.ImplantAction import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent} +import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3} import scala.concurrent.duration.FiniteDuration @@ -25,7 +26,9 @@ object AvatarServiceMessage { } object AvatarAction { - sealed trait Action + sealed trait Action extends EventMessage { + def response(): EventResponse = null + } final case class ArmorChanged(player_guid: PlanetSideGUID, suit: ExoSuitType.Value, subtype: Int) extends Action final case class AvatarImplant(player_guid: PlanetSideGUID, action: ImplantAction.Value, implantSlot: Int, status: Int) extends Action diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala index 87560d293..247a1eef8 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala @@ -13,7 +13,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage} import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3} -import net.psforever.services.GenericEventBusMsg +import net.psforever.services.base.{EventResponse, GenericEventBusMsg} final case class AvatarServiceResponse( channel: String, @@ -22,7 +22,7 @@ final case class AvatarServiceResponse( ) extends GenericEventBusMsg object AvatarResponse { - sealed trait Response + sealed trait Response extends EventResponse final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends Response final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends Response diff --git a/src/main/scala/net/psforever/services/base/EventExchange.scala b/src/main/scala/net/psforever/services/base/EventExchange.scala new file mode 100644 index 000000000..b566be39b --- /dev/null +++ b/src/main/scala/net/psforever/services/base/EventExchange.scala @@ -0,0 +1,16 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base + +trait EventExchange + +trait EventResponse extends EventExchange + +trait EventMessage extends EventExchange { + def response(): EventResponse +} + +trait SelfResponseMessage + extends EventMessage + with EventResponse { + def response(): EventResponse = this +} diff --git a/src/main/scala/net/psforever/services/base/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/GenericEventBus.scala new file mode 100644 index 000000000..72c2c43e3 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/GenericEventBus.scala @@ -0,0 +1,27 @@ +// Copyright (c) 2017 PSForever +package net.psforever.services.base + +import akka.event.{ActorEventBus, SubchannelClassification} +import akka.util.Subclassification + +trait GenericEventBusMsg { + def channel: String +} + +class GenericEventBus[A <: GenericEventBusMsg] extends ActorEventBus with SubchannelClassification { + type Event = A + type Classifier = String + + protected def classify(event: Event): Classifier = event.channel + + protected def subclassification: Subclassification[String] = + new Subclassification[Classifier] { + def isEqual(x: Classifier, y: Classifier): Boolean = x == y + + def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y) + } + + protected def publish(event: Event, subscriber: Subscriber): Unit = { + subscriber ! event + } +} diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala new file mode 100644 index 000000000..dd4477a87 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -0,0 +1,72 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base + +import akka.actor.Actor +import net.psforever.services.Service +import net.psforever.types.PlanetSideGUID +import org.log4s.Logger + +trait GenericResponseEnvelope + extends GenericEventBusMsg { + def exclude: PlanetSideGUID + def reply: EventResponse +} + +trait GenericMessageEnvelope { + def channel: String + def exclude: PlanetSideGUID + def msg: EventMessage + def response(outChannel: String): GenericResponseEnvelope +} + +abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: String) + extends Actor { + protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) + + protected val eventBus = new GenericEventBus[OUT] + + def commonJoinBehavior: Receive = { + case Service.Join(channel) => + val path = formatChannelOnBusName(channel, busName) + val who = sender() + eventBus.subscribe(who, path) + } + + def commonLeaveBehavior: Receive = { + case Service.Leave(None) => + eventBus.unsubscribe(sender()) + + case Service.Leave(Some(channel)) => + val path = formatChannelOnBusName(channel, busName) + eventBus.unsubscribe(sender(), path) + + case Service.LeaveAll() => + eventBus.unsubscribe(sender()) + } + + def receive: Receive = + commonJoinBehavior.orElse(commonLeaveBehavior) + .orElse { + case msg: GenericMessageEnvelope => + compose(msg) + + case msg => () + log.warn(s"Unhandled message $msg from ${sender()}") + } + + protected def compose(msg: GenericMessageEnvelope): Unit = { + eventBus.publish(msg.response(formatChannelOnBusName(msg.channel, busName)).asInstanceOf[OUT]) + } + + def formatChannelOnBusName: (String, String) => String = GenericEventService.BusOnChannelFormat +} + +object GenericEventService { + final def BusOnChannelFormat(channel: String, busName: String): String = { + if (channel.trim.isEmpty) { + s"/$busName" + } else { + s"/$channel/$busName" + } + } +} diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala new file mode 100644 index 000000000..0352ab014 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -0,0 +1,51 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base + +import akka.actor.{ActorContext, ActorRef} + +import scala.annotation.unused + +trait EventServiceSupport { + def label: String + def constructor(@unused context: ActorContext): ActorRef +} + +trait GenericMessageToSupportEnvelope + extends GenericMessageEnvelope { + def toSupport: String + def response(outChannel: String): GenericResponseEnvelope = null +} + +abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope]( + busName: String, + eventSupportServices: List[EventServiceSupport] + ) + extends GenericEventService[OUT](busName) { + + private val supportServices: Map[String, ActorRef] = + eventSupportServices + .map { supportService => (supportService.label, supportService.constructor(context)) } + .toMap[String, ActorRef] + + private def supportReceive: Receive = { + case msg: GenericMessageToSupportEnvelope => + forwardToSupport(msg) + } + + override def receive: Receive = supportReceive.orElse(super.receive) + + private def forwardToSupport(msg: GenericMessageToSupportEnvelope): Unit = { + supportServices + .get(msg.toSupport) + .map { support => + support.forward(msg) + msg + } + .getOrElse { + log.error(s"support service ${msg.toSupport} was not found - check message routing or service params") + } + if (msg.response(outChannel = "") != null) { + compose(msg) + } + } +} diff --git a/src/main/scala/net/psforever/services/support/SimilarityComparator.scala b/src/main/scala/net/psforever/services/base/support/SimilarityComparator.scala similarity index 87% rename from src/main/scala/net/psforever/services/support/SimilarityComparator.scala rename to src/main/scala/net/psforever/services/base/support/SimilarityComparator.scala index d9ea16a1b..f840500cb 100644 --- a/src/main/scala/net/psforever/services/support/SimilarityComparator.scala +++ b/src/main/scala/net/psforever/services/base/support/SimilarityComparator.scala @@ -1,5 +1,5 @@ // Copyright (c) 2017 PSForever -package net.psforever.services.support +package net.psforever.services.base.support abstract class SimilarityComparator[A <: SupportActor.Entry] { diff --git a/src/main/scala/net/psforever/services/support/SupportActor.scala b/src/main/scala/net/psforever/services/base/support/SupportActor.scala similarity index 99% rename from src/main/scala/net/psforever/services/support/SupportActor.scala rename to src/main/scala/net/psforever/services/base/support/SupportActor.scala index bb52e1f0b..07503ad17 100644 --- a/src/main/scala/net/psforever/services/support/SupportActor.scala +++ b/src/main/scala/net/psforever/services/base/support/SupportActor.scala @@ -1,5 +1,5 @@ // Copyright (c) 2017 PSForever -package net.psforever.services.support +package net.psforever.services.base.support import akka.actor.Actor import net.psforever.objects.PlanetSideGameObject diff --git a/src/main/scala/net/psforever/services/support/SupportActorCaseConversions.scala b/src/main/scala/net/psforever/services/base/support/SupportActorCaseConversions.scala similarity index 96% rename from src/main/scala/net/psforever/services/support/SupportActorCaseConversions.scala rename to src/main/scala/net/psforever/services/base/support/SupportActorCaseConversions.scala index 4a1fedd77..3640cceff 100644 --- a/src/main/scala/net/psforever/services/support/SupportActorCaseConversions.scala +++ b/src/main/scala/net/psforever/services/base/support/SupportActorCaseConversions.scala @@ -1,5 +1,5 @@ // Copyright (c) 2017 PSForever -package net.psforever.services.support +package net.psforever.services.base.support import net.psforever.objects.PlanetSideGameObject import net.psforever.objects.zones.Zone diff --git a/src/main/scala/net/psforever/services/chat/ChatService.scala b/src/main/scala/net/psforever/services/chat/ChatService.scala index 68fc0edbb..e0e2d64f1 100644 --- a/src/main/scala/net/psforever/services/chat/ChatService.scala +++ b/src/main/scala/net/psforever/services/chat/ChatService.scala @@ -6,6 +6,7 @@ import akka.actor.typed.{ActorRef, Behavior} import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors} import net.psforever.objects.{Session, SessionSource} import net.psforever.packet.game.ChatMsg +import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.types.{ChatMessageType, PlanetSideEmpire} object ChatService { @@ -17,14 +18,16 @@ object ChatService { new ChatService(context) } - sealed trait Command + sealed trait Command extends EventMessage { + def response(): EventResponse = null + } final case class JoinChannel(actor: ActorRef[MessageResponse], sessionSource: SessionSource, channel: ChatChannel) extends Command final case class LeaveChannel(actor: ActorRef[MessageResponse], channel: ChatChannel) extends Command final case class LeaveAllChannels(actor: ActorRef[MessageResponse]) extends Command final case class Message(session: Session, message: ChatMsg, channel: ChatChannel) extends Command - final case class MessageResponse(session: Session, message: ChatMsg, channel: ChatChannel) + final case class MessageResponse(session: Session, message: ChatMsg, channel: ChatChannel) extends EventResponse } class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBehavior[ChatService.Command](context) { diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index a526db02e..df9195c5f 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -2,26 +2,25 @@ package net.psforever.services.galaxy import akka.actor.Actor -import net.psforever.objects.zones.Zone -import net.psforever.packet.game.BuildingInfoUpdateMessage -import net.psforever.services.{GenericEventBus, Service} +import net.psforever.services.base.GenericEventBus +import net.psforever.services.Service class GalaxyService extends Actor { private[this] val log = org.log4s.getLogger val GalaxyEvents = new GenericEventBus[GalaxyServiceResponse] + private def correctChannelName(channel: String): String = { + if (channel.isEmpty) { + s"/Galaxy" + } else { + s"/$channel/Galaxy" + } + } + def receive: Receive = { - case Service.Join(faction) if "TRNCVS".containsSlice(faction) => - val path = s"/$faction/Galaxy" - GalaxyEvents.subscribe(sender(), path) - - case Service.Join("galaxy") => - val path = s"/Galaxy" - GalaxyEvents.subscribe(sender(), path) - case Service.Join(channel) => - val path = s"/$channel/Galaxy" + val path = correctChannelName(channel) GalaxyEvents.subscribe(sender(), path) case Service.Leave(None) => @@ -34,72 +33,8 @@ class GalaxyService extends Actor { case Service.LeaveAll() => GalaxyEvents.unsubscribe(sender()) - case GalaxyServiceMessage(forChannel, action) => - action match { - case GalaxyAction.MapUpdate(msg: BuildingInfoUpdateMessage) => - GalaxyEvents.publish( - GalaxyServiceResponse(s"/Galaxy", GalaxyResponse.MapUpdate(msg)) - ) - - case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) => - GalaxyEvents.publish( - GalaxyServiceResponse( - s"/$forChannel/Galaxy", - GalaxyResponse.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) - ) - ) - - case GalaxyAction.FlagMapUpdate(msg) => - GalaxyEvents.publish( - GalaxyServiceResponse(s"/Galaxy", GalaxyResponse.FlagMapUpdate(msg)) - ) - - case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, vehicle_to_delete, manifest) => - GalaxyEvents.publish( - GalaxyServiceResponse( - s"/$forChannel/Galaxy", - GalaxyResponse.TransferPassenger(temp_channel, vehicle, vehicle_to_delete, manifest) - ) - ) - - case GalaxyAction.LockedZoneUpdate(zone, time) => - GalaxyEvents.publish( - GalaxyServiceResponse( - s"/Galaxy", - GalaxyResponse.LockedZoneUpdate(zone, time) - ) - ) - - case GalaxyAction.UnlockedZoneUpdate(zone) => - GalaxyEvents.publish( - GalaxyServiceResponse( - s"/Galaxy", - GalaxyResponse.UnlockedZoneUpdate(zone) - ) - ) - - case GalaxyAction.LogStatusChange(name) => - GalaxyEvents.publish( - GalaxyServiceResponse( - s"/Galaxy", - GalaxyResponse.LogStatusChange(name) - ) - ) - - case GalaxyAction.SendResponse(msg) => - GalaxyEvents.publish( - GalaxyServiceResponse( - s"/Galaxy", - GalaxyResponse.SendResponse(msg) - ) - ) - case _ => ; - } - - case Zone.HotSpot.Update(faction, zone_num, priority, info) => - GalaxyEvents.publish( - GalaxyServiceResponse(s"/$faction/Galaxy", GalaxyResponse.HotSpotUpdate(zone_num, priority, info)) - ) + case msg @ GalaxyServiceMessage(forChannel, _) => + GalaxyEvents.publish(msg.response(correctChannelName(forChannel))) case msg => log.warn(s"Unhandled message $msg from ${sender()}") diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala index dcdaebfc2..504c014ff 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala @@ -3,22 +3,43 @@ package net.psforever.services.galaxy import net.psforever.objects.Vehicle import net.psforever.objects.vehicles.VehicleManifest -import net.psforever.objects.zones.Zone +import net.psforever.objects.zones.{HotSpotInfo, Zone} import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} +import net.psforever.services.Service +import net.psforever.services.base.{EventMessage, EventResponse, GenericMessageEnvelope, SelfResponseMessage} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} -final case class GalaxyServiceMessage(forChannel: String, actionMessage: GalaxyAction.Action) +final case class GalaxyServiceMessage(channel: String, msg: EventMessage) + extends GenericMessageEnvelope { + def exclude: PlanetSideGUID = Service.defaultPlayerGUID + + def response(outChannel: String): GalaxyServiceResponse = { + GalaxyServiceResponse(outChannel, msg.response()) + } +} object GalaxyServiceMessage { def apply(actionMessage: GalaxyAction.Action): GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage) } object GalaxyAction { - trait Action + trait Action extends EventMessage + trait Response extends EventResponse + + final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) + extends Action + with Response + with SelfResponseMessage + + final case class MapUpdate(msg: BuildingInfoUpdateMessage) + extends Action + with Response + with SelfResponseMessage - final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Action final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends Action + with Response + with SelfResponseMessage final case class TransferPassenger( player_guid: PlanetSideGUID, @@ -27,6 +48,8 @@ object GalaxyAction { vehicle_to_delete: PlanetSideGUID, manifest: VehicleManifest ) extends Action + with Response + with SelfResponseMessage final case class UpdateBroadcastPrivileges( zoneId: Int, @@ -34,12 +57,22 @@ object GalaxyAction { fromFactions: Set[PlanetSideEmpire.Value], toFactions: Set[PlanetSideEmpire.Value] ) extends Action + with Response + with SelfResponseMessage final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends Action + with Response + with SelfResponseMessage final case class UnlockedZoneUpdate(zone: Zone) extends Action + with Response + with SelfResponseMessage final case class LogStatusChange(name: String) extends Action + with Response + with SelfResponseMessage final case class SendResponse(msg: PlanetSideGamePacket) extends Action + with Response + with SelfResponseMessage } diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala index dcaf93817..64d50871c 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala @@ -7,13 +7,16 @@ import net.psforever.objects.zones.{HotSpotInfo, Zone} import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} -import net.psforever.services.GenericEventBusMsg +import net.psforever.services.Service +import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} -final case class GalaxyServiceResponse(channel: String, replyMessage: GalaxyResponse.Response) - extends GenericEventBusMsg +final case class GalaxyServiceResponse(channel: String, reply: EventResponse) + extends GenericResponseEnvelope { + def exclude: PlanetSideGUID = Service.defaultPlayerGUID +} object GalaxyResponse { - trait Response + trait Response extends EventResponse final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends Response final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Response diff --git a/src/main/scala/net/psforever/services/hart/HartTimer.scala b/src/main/scala/net/psforever/services/hart/HartTimer.scala index 3de884fe0..8267e2f76 100644 --- a/src/main/scala/net/psforever/services/hart/HartTimer.scala +++ b/src/main/scala/net/psforever/services/hart/HartTimer.scala @@ -4,8 +4,8 @@ package net.psforever.services.hart import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Default import net.psforever.objects.zones.Zone +import net.psforever.services.base.{EventResponse, GenericEventBus, GenericEventBusMsg} import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.{GenericEventBus, GenericEventBusMsg} import net.psforever.types.{HartSequence, PlanetSideGUID} import scala.concurrent.duration._ @@ -20,7 +20,7 @@ import scala.concurrent.ExecutionContext.Implicits.global */ class HartTimer(zone: Zone) extends Actor { /** since the system is zone-locked, caching this value is fine */ - val zoneId = zone.id + val zoneId: String = zone.id /** all of the paired HART facility amenities and the shuttle housed in that facility (in that order) */ var padAndShuttlePairs: List[(PlanetSideGUID, PlanetSideGUID)] = List() @@ -45,8 +45,8 @@ class HartTimer(zone: Zone) extends Actor { /** a message bus to which all associated orbital shuttle pads are subscribed */ val padEvents = new GenericEventBus[HartTimer.Command] /** cache common messages */ - val shuttleDockedInThisZone = HartTimer.ShuttleDocked(zoneId) - val shuttleFreeFromDockInThisZone = HartTimer.ShuttleFreeFromDock(zoneId) + val shuttleDockedInThisZone: HartTimer.ShuttleDocked = HartTimer.ShuttleDocked(zoneId) + val shuttleFreeFromDockInThisZone: HartTimer.ShuttleFreeFromDock = HartTimer.ShuttleFreeFromDock(zoneId) /** the behaviors common to both the inert and active operations of the hart */ val commonBehavior: Receive = { @@ -259,7 +259,7 @@ object HartTimer { * to relay instructions back to the individual facility amenity portions of this HART system. * The channel is blank because it does not need special designation. */ - trait Command extends GenericEventBusMsg { def channel: String = "" } + trait Command extends EventResponse with GenericEventBusMsg { def channel: String = "" } /** * Forbid entry through the boartding gantry doors. */ diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index 751dce97b..6ac2eaae0 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -8,8 +8,9 @@ import net.psforever.packet.game.{ObjectCreateMessage, TriggeredEffect, Triggere import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.PlanetSideGUID import net.psforever.services.local.support._ -import net.psforever.services.{GenericEventBus, Service} -import net.psforever.services.support.SupportActor +import net.psforever.services.Service +import net.psforever.services.base.GenericEventBus +import net.psforever.services.base.support.SupportActor class LocalService(zone: Zone) extends Actor { private val doorCloser = context.actorOf( diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index ced629458..c928a2d3a 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -15,6 +15,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, TriggeredSound} +import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -25,7 +26,9 @@ object LocalServiceMessage { } object LocalAction { - trait Action + trait Action extends EventMessage { + def response(): EventResponse = null + } final case class DeployItem(item: Deployable) extends Action final case class DeployableMapIcon( diff --git a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala index 8834ab197..a7144fb5a 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala @@ -12,7 +12,7 @@ import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game._ import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} -import net.psforever.services.GenericEventBusMsg +import net.psforever.services.base.{EventResponse, GenericEventBusMsg} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent final case class LocalServiceResponse( @@ -22,7 +22,7 @@ final case class LocalServiceResponse( ) extends GenericEventBusMsg object LocalResponse { - trait Response + trait Response extends EventResponse final case class DeployableMapIcon(action: DeploymentAction.Value, deployInfo: DeployableInfo) extends Response final case class DeployableUIFor(obj: DeployedItem.Value) extends Response diff --git a/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala b/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala index 9af42b969..6ca16e72b 100644 --- a/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala +++ b/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala @@ -4,7 +4,9 @@ import akka.actor.Actor import net.psforever.packet.game.{GamePropertyTarget, PropertyOverrideMessage} import net.psforever.packet.game.PropertyOverrideMessage.GamePropertyScope import net.psforever.packet.game.objectcreate.ObjectClass +import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.zones.Zones + import scala.collection.mutable.ListBuffer class PropertyOverrideManager extends Actor { @@ -87,5 +89,7 @@ class PropertyOverrideManager extends Actor { } object PropertyOverrideManager { - final case object GetOverridesMessage + final case object GetOverridesMessage extends EventMessage { + def response(): EventResponse = null + } } diff --git a/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala b/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala index f99942df6..4f6548122 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala @@ -5,6 +5,7 @@ import net.psforever.objects.Player import net.psforever.objects.avatar.Certification import net.psforever.objects.zones.Zone import net.psforever.packet.game.{WaypointEventAction, WaypointInfo, SquadAction => PacketSquadAction} +import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.types.{PlanetSideGUID, SquadRequestType, SquadWaypoint, Vector3} final case class SquadServiceMessage(tplayer: Player, zone: Zone, actionMessage: Any) @@ -15,7 +16,9 @@ object SquadServiceMessage { } object SquadAction { - sealed trait Action + sealed trait Action extends EventMessage { + def response(): EventResponse = null + } final case class InitSquadList() extends Action final case class InitCharId() extends Action diff --git a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala index bd2753292..49600cc48 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala @@ -6,10 +6,10 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.teamwork.Squad import net.psforever.packet.game.{SquadDetail, SquadInfo, WaypointEventAction, WaypointInfo} import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadResponseType, SquadWaypoint} -import net.psforever.services.GenericEventBusMsg +import net.psforever.services.base.{EventResponse, GenericEventBusMsg} final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], response: SquadResponse.Response) - extends GenericEventBusMsg + extends EventResponse with GenericEventBusMsg object SquadServiceResponse { def apply(toChannel: String, response: SquadResponse.Response): SquadServiceResponse = diff --git a/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala b/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala index 104bd5320..af47196b6 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala @@ -2,11 +2,11 @@ package net.psforever.services.teamwork import akka.actor.ActorRef -import scala.collection.mutable +import scala.collection.mutable import net.psforever.objects.teamwork.{Squad, SquadFeatures} import net.psforever.packet.game.SquadDetail -import net.psforever.services.GenericEventBus +import net.psforever.services.base.GenericEventBus import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} class SquadSubscriptionEntity { diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 72168faa0..4ac69bfcc 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -6,9 +6,10 @@ import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.objects.zones.Zone import net.psforever.packet.game.ObjectCreateMessage import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent +import net.psforever.services.base.GenericEventBus import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.types.DriveState -import net.psforever.services.{GenericEventBus, Service} +import net.psforever.services.Service class VehicleService(zone: Zone) extends Actor { private val turretUpgrade: ActorRef = context.actorOf(Props[TurretUpgrader](), s"${zone.id}-turret-upgrade-agent") diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala index 07bb29769..54f6d4e96 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala @@ -7,6 +7,7 @@ import net.psforever.objects.inventory.InventoryItem import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.objectcreate.ConstructorData +import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} final case class VehicleServiceMessage(forChannel: String, actionMessage: VehicleAction.Action) @@ -21,7 +22,9 @@ object VehicleServiceMessage { } object VehicleAction { - trait Action + trait Action extends EventMessage { + def response(): EventResponse = null + } final case class ChangeAmmo( player_guid: PlanetSideGUID, diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala index 22e2ed94f..166d12302 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala @@ -11,7 +11,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.packet.game.ObjectCreateMessage import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} -import net.psforever.services.GenericEventBusMsg +import net.psforever.services.base.{EventResponse, GenericEventBusMsg} final case class VehicleServiceResponse( channel: String, @@ -20,7 +20,7 @@ final case class VehicleServiceResponse( ) extends GenericEventBusMsg object VehicleResponse { - trait Response + trait Response extends EventResponse final case class ChangeAmmo( weapon_guid: PlanetSideGUID, diff --git a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala index bd6e02866..96939203a 100644 --- a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala +++ b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.zones.Zone import net.psforever.types.PlanetSideGUID -import net.psforever.services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} +import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.concurrent.Future From be803f0d03ecfb4f0b4954aebdf7026c23eb2d23 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Thu, 22 Jan 2026 01:38:07 -0500 Subject: [PATCH 02/32] working GalaxyService based on GenericEventService --- .../services/base/GenericEventService.scala | 4 +- .../base/GenericEventServiceWithSupport.scala | 10 +-- .../services/galaxy/GalaxyAction.scala | 41 ++++++++++++ .../services/galaxy/GalaxyService.scala | 43 ++---------- .../galaxy/GalaxyServiceMessage.scala | 65 +------------------ .../galaxy/GalaxyServiceResponse.scala | 38 +---------- 6 files changed, 56 insertions(+), 145 deletions(-) create mode 100644 src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index dd4477a87..068ad6a76 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -19,7 +19,7 @@ trait GenericMessageEnvelope { def response(outChannel: String): GenericResponseEnvelope } -abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: String) +abstract class GenericEventService[IN <: GenericMessageEnvelope, OUT <: GenericResponseEnvelope](busName: String) extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) @@ -47,7 +47,7 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri def receive: Receive = commonJoinBehavior.orElse(commonLeaveBehavior) .orElse { - case msg: GenericMessageEnvelope => + case msg: IN => compose(msg) case msg => () diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index 0352ab014..6e3a33b2a 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -16,11 +16,11 @@ trait GenericMessageToSupportEnvelope def response(outChannel: String): GenericResponseEnvelope = null } -abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope]( - busName: String, - eventSupportServices: List[EventServiceSupport] - ) - extends GenericEventService[OUT](busName) { +abstract class GenericEventServiceWithSupport[IN <: GenericMessageEnvelope, OUT <: GenericResponseEnvelope] +( + busName: String, + eventSupportServices: List[EventServiceSupport] +) extends GenericEventService[IN, OUT](busName) { private val supportServices: Map[String, ActorRef] = eventSupportServices diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala new file mode 100644 index 000000000..64a813446 --- /dev/null +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala @@ -0,0 +1,41 @@ +// Copyright (c) 2017-2026 PSForever +package net.psforever.services.galaxy + +import net.psforever.objects.Vehicle +import net.psforever.objects.vehicles.VehicleManifest +import net.psforever.objects.zones.{HotSpotInfo, Zone} +import net.psforever.packet.PlanetSideGamePacket +import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} +import net.psforever.services.base.SelfResponseMessage +import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} + +object GalaxyAction { + final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends SelfResponseMessage + + final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends SelfResponseMessage + + final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends SelfResponseMessage + + final case class TransferPassenger( + player_guid: PlanetSideGUID, + temp_channel: String, + vehicle: Vehicle, + vehicle_to_delete: PlanetSideGUID, + manifest: VehicleManifest + ) extends SelfResponseMessage + + final case class UpdateBroadcastPrivileges( + zoneId: Int, + gateMapId: Int, + fromFactions: Set[PlanetSideEmpire.Value], + toFactions: Set[PlanetSideEmpire.Value] + ) extends SelfResponseMessage + + final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends SelfResponseMessage + + final case class UnlockedZoneUpdate(zone: Zone) extends SelfResponseMessage + + final case class LogStatusChange(name: String) extends SelfResponseMessage + + final case class SendResponse(msg: PlanetSideGamePacket) extends SelfResponseMessage +} diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index df9195c5f..a640d1ddb 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -1,42 +1,7 @@ -// Copyright (c) 2017 PSForever +// Copyright (c) 2017-2026 PSForever package net.psforever.services.galaxy -import akka.actor.Actor -import net.psforever.services.base.GenericEventBus -import net.psforever.services.Service +import net.psforever.services.base.GenericEventService -class GalaxyService extends Actor { - private[this] val log = org.log4s.getLogger - - val GalaxyEvents = new GenericEventBus[GalaxyServiceResponse] - - private def correctChannelName(channel: String): String = { - if (channel.isEmpty) { - s"/Galaxy" - } else { - s"/$channel/Galaxy" - } - } - - def receive: Receive = { - case Service.Join(channel) => - val path = correctChannelName(channel) - GalaxyEvents.subscribe(sender(), path) - - case Service.Leave(None) => - GalaxyEvents.unsubscribe(sender()) - - case Service.Leave(Some(channel)) => - val path = s"/$channel/Galaxy" - GalaxyEvents.unsubscribe(sender(), path) - - case Service.LeaveAll() => - GalaxyEvents.unsubscribe(sender()) - - case msg @ GalaxyServiceMessage(forChannel, _) => - GalaxyEvents.publish(msg.response(correctChannelName(forChannel))) - - case msg => - log.warn(s"Unhandled message $msg from ${sender()}") - } -} +class GalaxyService + extends GenericEventService[GalaxyServiceMessage, GalaxyServiceResponse](busName = "Galaxy") diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala index 504c014ff..8c115ec75 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala @@ -1,14 +1,9 @@ // Copyright (c) 2017 PSForever package net.psforever.services.galaxy -import net.psforever.objects.Vehicle -import net.psforever.objects.vehicles.VehicleManifest -import net.psforever.objects.zones.{HotSpotInfo, Zone} -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, EventResponse, GenericMessageEnvelope, SelfResponseMessage} -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} +import net.psforever.services.base.{EventMessage, GenericMessageEnvelope} +import net.psforever.types.PlanetSideGUID final case class GalaxyServiceMessage(channel: String, msg: EventMessage) extends GenericMessageEnvelope { @@ -20,59 +15,5 @@ final case class GalaxyServiceMessage(channel: String, msg: EventMessage) } object GalaxyServiceMessage { - def apply(actionMessage: GalaxyAction.Action): GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage) -} - -object GalaxyAction { - trait Action extends EventMessage - trait Response extends EventResponse - - final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) - extends Action - with Response - with SelfResponseMessage - - final case class MapUpdate(msg: BuildingInfoUpdateMessage) - extends Action - with Response - with SelfResponseMessage - - final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends Action - with Response - with SelfResponseMessage - - final case class TransferPassenger( - player_guid: PlanetSideGUID, - temp_channel: String, - vehicle: Vehicle, - vehicle_to_delete: PlanetSideGUID, - manifest: VehicleManifest - ) extends Action - with Response - with SelfResponseMessage - - final case class UpdateBroadcastPrivileges( - zoneId: Int, - gateMapId: Int, - fromFactions: Set[PlanetSideEmpire.Value], - toFactions: Set[PlanetSideEmpire.Value] - ) extends Action - with Response - with SelfResponseMessage - - final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends Action - with Response - with SelfResponseMessage - - final case class UnlockedZoneUpdate(zone: Zone) extends Action - with Response - with SelfResponseMessage - - final case class LogStatusChange(name: String) extends Action - with Response - with SelfResponseMessage - - final case class SendResponse(msg: PlanetSideGamePacket) extends Action - with Response - with SelfResponseMessage + def apply(actionMessage: EventMessage): GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage) } diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala index 64d50871c..70d072f9b 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala @@ -1,12 +1,7 @@ // Copyright (c) 2017 PSForever package net.psforever.services.galaxy -import net.psforever.objects.Vehicle -import net.psforever.objects.vehicles.VehicleManifest -import net.psforever.objects.zones.{HotSpotInfo, Zone} -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} +import net.psforever.types.PlanetSideGUID import net.psforever.services.Service import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} @@ -14,34 +9,3 @@ final case class GalaxyServiceResponse(channel: String, reply: EventResponse) extends GenericResponseEnvelope { def exclude: PlanetSideGUID = Service.defaultPlayerGUID } - -object GalaxyResponse { - trait Response extends EventResponse - - final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends Response - final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Response - final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends Response - - - final case class TransferPassenger( - temp_channel: String, - vehicle: Vehicle, - vehicle_to_delete: PlanetSideGUID, - manifest: VehicleManifest - ) extends Response - - final case class UpdateBroadcastPrivileges( - zoneId: Int, - gateMapId: Int, - fromFactions: Set[PlanetSideEmpire.Value], - toFactions: Set[PlanetSideEmpire.Value] - ) extends Response - - final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends Response - - final case class UnlockedZoneUpdate(zone: Zone) extends Response - - final case class LogStatusChange(name: String) extends Response - - final case class SendResponse(msg: PlanetSideGamePacket) extends Response -} From d62dbfdd81a2a0e2823ff98d5baedfe1f42456a6 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sat, 24 Jan 2026 10:28:18 -0500 Subject: [PATCH 03/32] working AvatarService based on GenericEventService(withSupport); manually corrected almost every message to AvatarService to ensure channel and filters are preserved --- .codecov.yml | 6 +- .../actor/service/AvatarServiceTest.scala | 128 +++-- .../actors/session/AvatarActor.scala | 43 +- .../session/csr/AvatarHandlerLogic.scala | 116 ++-- .../actors/session/csr/ChatLogic.scala | 12 +- .../CustomerServiceRepresentativeMode.scala | 23 +- .../actors/session/csr/GeneralLogic.scala | 12 +- ...eAsCustomerServiceRepresentativeMode.scala | 5 +- .../session/normal/AvatarHandlerLogic.scala | 132 ++--- .../actors/session/normal/GeneralLogic.scala | 8 +- .../spectator/AvatarHandlerLogic.scala | 120 ++-- .../session/spectator/GeneralLogic.scala | 8 +- .../session/spectator/SpectatorMode.scala | 2 +- .../session/support/GeneralOperations.scala | 9 +- .../support/SessionAvatarHandlers.scala | 8 +- .../support/SessionOutfitHandlers.scala | 70 ++- .../support/SessionSquadHandlers.scala | 5 +- .../WeaponAndProjectileOperations.scala | 40 +- .../session/support/ZoningOperations.scala | 34 +- .../zone/building/MajorFacilityLogic.scala | 26 +- .../net/psforever/login/WorldSession.scala | 30 +- .../psforever/objects/BoomerDeployable.scala | 2 +- .../scala/net/psforever/objects/Players.scala | 27 +- .../scala/net/psforever/objects/Tools.scala | 5 +- .../net/psforever/objects/Vehicles.scala | 7 +- .../objects/avatar/CorpseControl.scala | 10 +- .../objects/avatar/PlayerControl.scala | 124 ++-- .../avatar/interaction/WithEntrance.scala | 6 +- .../avatar/interaction/WithGantry.scala | 10 +- .../objects/ce/DeployableBehavior.scala | 2 +- .../locker/LockerContainerControl.scala | 10 +- .../damage/DamageableAmenity.scala | 4 +- .../damage/DamageableEntity.scala | 5 +- .../damage/DamageableMountable.scala | 18 +- .../damage/DamageableWeaponTurret.scala | 2 +- .../generator/GeneratorControl.scala | 5 +- .../hackable/GenericHackables.scala | 1 - .../repair/RepairableAmenity.scala | 4 +- .../repair/RepairableEntity.scala | 14 +- .../resourcesilo/ResourceSiloControl.scala | 6 +- .../shuttle/OrbitalShuttlePadControl.scala | 1 - .../FacilityHackParticipation.scala | 4 +- .../terminals/ProximityTerminalControl.scala | 11 +- .../serverobject/turret/TurretControl.scala | 8 +- .../serverobject/turret/WeaponTurrets.scala | 5 +- .../objects/vehicles/CarrierBehavior.scala | 1 - .../vehicles/control/VehicleControl.scala | 2 +- .../interaction/WithEntranceInVehicle.scala | 2 +- .../objects/zones/ZoneGroundActor.scala | 11 +- .../objects/zones/ZoneProjectileActor.scala | 8 +- .../account/AccountPersistenceService.scala | 2 +- .../services/avatar/AvatarAction.scala | 249 ++++++++ .../services/avatar/AvatarService.scala | 539 +----------------- .../avatar/AvatarServiceMessage.scala | 237 +++----- .../avatar/AvatarServiceResponse.scala | 140 +---- .../avatar/support/CorpseRemovalActor.scala | 2 +- .../avatar/support/DroppedItemRemover.scala | 2 +- .../services/base/GenericEventService.scala | 29 +- .../base/GenericEventServiceWithSupport.scala | 29 +- .../services/galaxy/GalaxyService.scala | 8 +- .../galaxy/GalaxyServiceMessage.scala | 6 +- .../galaxy/GalaxyServiceResponse.scala | 2 +- .../local/support/HackClearActor.scala | 2 +- 63 files changed, 958 insertions(+), 1441 deletions(-) create mode 100644 src/main/scala/net/psforever/services/avatar/AvatarAction.scala diff --git a/.codecov.yml b/.codecov.yml index 26736d869..c6c1e418a 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -68,9 +68,11 @@ ignore: - "src/main/scala/net/psforever/types/PlanetSideEmpire.scala" - "src/main/scala/net/psforever/types/TransactionType.scala" - "src/main/scala/net/psforever/services/avatar/AvatarAction.scala" - - "src/main/scala/net/psforever/services/avatar/AvatarResponse.scala" + - "src/main/scala/net/psforever/services/galaxy/AvatarServiceMessage.scala" + - "src/main/scala/net/psforever/services/galaxy/AvatarServiceResponse.scala" - "src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala" - - "src/main/scala/net/psforever/services/galaxy/GalaxyResponse.scala" + - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala" + - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala" - "src/main/scala/net/psforever/services/hart/HartEvent.scala" - "src/main/scala/net/psforever/services/hart/HartTimerActions.scala" - "src/main/scala/net/psforever/services/local/LocalAction.scala" diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala index 6e0eab30d..891e2c61a 100644 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ b/server/src/test/scala/actor/service/AvatarServiceTest.scala @@ -3,8 +3,8 @@ package actor.service import akka.actor.Props import akka.testkit.TestProbe -import scala.concurrent.duration._ +import scala.concurrent.duration._ import actor.base.{ActorTest, FreedContextActorTest} import net.psforever.objects._ import net.psforever.objects.avatar.Avatar @@ -80,12 +80,12 @@ class ArmorChangedTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ArmorChanged(PlanetSideGUID(10), ExoSuitType.Reinforced, 0)) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ArmorChanged(ExoSuitType.Reinforced, 0)) expectMsg( AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarResponse.ArmorChanged(ExoSuitType.Reinforced, 0) + AvatarAction.ArmorChanged(ExoSuitType.Reinforced, 0) ) ) } @@ -99,7 +99,7 @@ class ConcealPlayerTest extends ActorTest { val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", AvatarAction.ConcealPlayer(PlanetSideGUID(10))) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ConcealPlayer())) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ConcealPlayer(PlanetSideGUID(10)))) } } } @@ -123,9 +123,10 @@ class EquipmentInHandTest extends ActorTest { service ! Service.Join("test") service ! AvatarServiceMessage( "test", - AvatarAction.EquipmentInHand(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool) + PlanetSideGUID(10), + AvatarAction.EquipmentInHand(PlanetSideGUID(11), 2, tool) ) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentInHand(pkt))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.EquipmentCreatedInHand(pkt))) } } } @@ -151,8 +152,8 @@ class DroptItemTest extends ActorTest { "AvatarService" should { "pass DropItem" in { service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.DropItem(PlanetSideGUID(10), tool)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.DropItem(pkt))) + service ! DropItemMessage("test", PlanetSideGUID(10), AvatarAction.DropItem(tool), Zone.Nowhere) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.DropCreatedItem(pkt))) } } } @@ -176,15 +177,17 @@ class LoadPlayerTest extends ActorTest { //no parent data service ! AvatarServiceMessage( "test", - AvatarAction.LoadPlayer(PlanetSideGUID(20), ObjectClass.avatar, PlanetSideGUID(10), c1data, None) + PlanetSideGUID(20), + AvatarAction.LoadPlayer(ObjectClass.avatar, PlanetSideGUID(10), c1data, None) ) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarResponse.LoadPlayer(pkt1))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarAction.LoadCreatedPlayer(pkt1))) //parent data service ! AvatarServiceMessage( "test", - AvatarAction.LoadPlayer(PlanetSideGUID(20), ObjectClass.avatar, PlanetSideGUID(10), c2data, Some(parent)) + PlanetSideGUID(20), + AvatarAction.LoadPlayer(ObjectClass.avatar, PlanetSideGUID(10), c2data, Some(parent)) ) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarResponse.LoadPlayer(pkt2))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarAction.LoadCreatedPlayer(pkt2))) } } } @@ -195,14 +198,14 @@ class ObjectDeleteTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11))) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 0)) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11), 0)) ) - service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11), 55)) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11), 55)) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 55)) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11), 55)) ) } } @@ -214,8 +217,8 @@ class ObjectHeldTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ObjectHeld(PlanetSideGUID(10), 1, 2)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectHeld(1, 2))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2)) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2))) } } } @@ -228,7 +231,7 @@ class PutDownFDUTest extends ActorTest { service ! Service.Join("test") service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10))) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PutDownFDU(PlanetSideGUID(10))) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.PutDownFDU(PlanetSideGUID(10))) ) } } @@ -240,8 +243,8 @@ class PlanetsideAttributeTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PlanetsideAttribute(5, 1200L))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.PlanetsideAttribute(5, 1200L)) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.PlanetsideAttribute(5, 1200L))) } } } @@ -271,8 +274,8 @@ class PlayerStateTest extends ActorTest { service ! Service.Join("test") service ! AvatarServiceMessage( "test", + PlanetSideGUID(10), AvatarAction.PlayerState( - PlanetSideGUID(10), Vector3(3694.1094f, 2735.4531f, 90.84375f), Some(Vector3(4.375f, 2.59375f, 0.0f)), 61.875f, @@ -291,7 +294,7 @@ class PlayerStateTest extends ActorTest { AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarResponse.PlayerState( + AvatarAction.PlayerState( Vector3(3694.1094f, 2735.4531f, 90.84375f), Some(Vector3(4.375f, 2.59375f, 0.0f)), 61.875f, @@ -320,8 +323,8 @@ class PickupItemTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.PickupItem(PlanetSideGUID(10), tool)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(tool.GUID, 0))) + service ! PickupItemMessage("test", AvatarAction.PickupItem(tool), Zone.Nowhere) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectDelete(tool.GUID, 0))) } } @@ -331,8 +334,8 @@ class ReloadTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.Reload(PlanetSideGUID(10), PlanetSideGUID(40))) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.Reload(PlanetSideGUID(40)))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.Reload(PlanetSideGUID(40))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.Reload(PlanetSideGUID(40)))) } } } @@ -348,8 +351,8 @@ class ChangeAmmoTest extends ActorTest { service ! Service.Join("test") service ! AvatarServiceMessage( "test", + PlanetSideGUID(10), AvatarAction.ChangeAmmo( - PlanetSideGUID(10), PlanetSideGUID(40), 0, PlanetSideGUID(40), @@ -362,7 +365,7 @@ class ChangeAmmoTest extends ActorTest { AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarResponse.ChangeAmmo( + AvatarAction.ChangeAmmo( PlanetSideGUID(40), 0, PlanetSideGUID(40), @@ -385,9 +388,9 @@ class ChangeFireModeTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ChangeFireMode(PlanetSideGUID(10), PlanetSideGUID(40), 0)) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireMode(PlanetSideGUID(40), 0)) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireMode(PlanetSideGUID(40), 0)) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ChangeFireMode(PlanetSideGUID(40), 0)) ) } } @@ -399,12 +402,12 @@ class ChangeFireStateStartTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Start(PlanetSideGUID(10), PlanetSideGUID(40))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireState_Start(PlanetSideGUID(40))) expectMsg( AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarResponse.ChangeFireState_Start(PlanetSideGUID(40)) + AvatarAction.ChangeFireState_Start(PlanetSideGUID(40)) ) ) } @@ -417,12 +420,12 @@ class ChangeFireStateStopTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Stop(PlanetSideGUID(10), PlanetSideGUID(40))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireState_Stop(PlanetSideGUID(40))) expectMsg( AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarResponse.ChangeFireState_Stop(PlanetSideGUID(40)) + AvatarAction.ChangeFireState_Stop(PlanetSideGUID(40)) ) ) } @@ -435,9 +438,9 @@ class WeaponDryFireTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.WeaponDryFire(PlanetSideGUID(10), PlanetSideGUID(40))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.WeaponDryFire(PlanetSideGUID(40))) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.WeaponDryFire(PlanetSideGUID(40))) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.WeaponDryFire(PlanetSideGUID(40))) ) } } @@ -453,13 +456,14 @@ class AvatarStowEquipmentTest extends ActorTest { service ! Service.Join("test") service ! AvatarServiceMessage( "test", - AvatarAction.StowEquipment(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool) + PlanetSideGUID(10), + AvatarAction.StowEquipment(PlanetSideGUID(11), 2, tool) ) expectMsg( AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarResponse.StowEquipment(PlanetSideGUID(11), 2, tool) + AvatarAction.StowEquipment(PlanetSideGUID(11), 2, tool) ) ) } @@ -504,23 +508,23 @@ class AvatarReleaseTest extends FreedContextActorTest { assert(zone.Corpses.size == 1) assert(obj.HasGUID) val guid = obj.GUID - zone.AvatarEvents ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second + zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second val reply1 = subscriber.receiveOne(200 milliseconds) assert(reply1.isInstanceOf[AvatarServiceResponse]) val reply1msg = reply1.asInstanceOf[AvatarServiceResponse] assert(reply1msg.channel == "/test/Avatar") - assert(reply1msg.avatar_guid == guid) - assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release]) - assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj) + assert(reply1msg.filter == guid) + assert(reply1msg.reply.isInstanceOf[AvatarAction.Release]) + assert(reply1msg.reply.asInstanceOf[AvatarAction.Release].player == obj) val reply2 = subscriber.receiveOne(2 seconds) assert(reply2.isInstanceOf[AvatarServiceResponse]) val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] assert(reply2msg.channel.equals("/test/Avatar")) - assert(reply2msg.avatar_guid == Service.defaultPlayerGUID) - assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete]) - assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid) + assert(reply2msg.filter == Service.defaultPlayerGUID) + assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete]) + assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid) subscriber.expectNoMessage(1 seconds) assert(zone.Corpses.isEmpty) @@ -555,24 +559,24 @@ class AvatarReleaseEarly1Test extends FreedContextActorTest { assert(zone.Corpses.size == 1) assert(obj.HasGUID) val guid = obj.GUID - zone.AvatarEvents ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes! + zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes! val reply1 = subscriber.receiveOne(200 milliseconds) assert(reply1.isInstanceOf[AvatarServiceResponse]) val reply1msg = reply1.asInstanceOf[AvatarServiceResponse] assert(reply1msg.channel == "/test/Avatar") - assert(reply1msg.avatar_guid == guid) - assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release]) - assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj) + assert(reply1msg.filter == guid) + assert(reply1msg.reply.isInstanceOf[AvatarAction.Release]) + assert(reply1msg.reply.asInstanceOf[AvatarAction.Release].player == obj) - zone.AvatarEvents ! AvatarServiceMessage.Corpse(RemoverActor.HurrySpecific(List(obj), zone)) //IMPORTANT: ONE ENTRY + zone.AvatarEvents ! CorpseEnvelope(RemoverActor.HurrySpecific(List(obj), zone)) //IMPORTANT: ONE ENTRY val reply2 = subscriber.receiveOne(200 milliseconds) assert(reply2.isInstanceOf[AvatarServiceResponse]) val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] assert(reply2msg.channel.equals("/test/Avatar")) - assert(reply2msg.avatar_guid == Service.defaultPlayerGUID) - assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete]) - assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid) + assert(reply2msg.filter == Service.defaultPlayerGUID) + assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete]) + assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid) subscriber.expectNoMessage(1 seconds) assert(zone.Corpses.isEmpty) @@ -613,26 +617,26 @@ class AvatarReleaseEarly2Test extends FreedContextActorTest { assert(zone.Corpses.size == 1) assert(obj.HasGUID) val guid = obj.GUID - zone.AvatarEvents ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes! + zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes! val reply1 = subscriber.receiveOne(200 milliseconds) assert(reply1.isInstanceOf[AvatarServiceResponse]) val reply1msg = reply1.asInstanceOf[AvatarServiceResponse] assert(reply1msg.channel == "/test/Avatar") - assert(reply1msg.avatar_guid == guid) - assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release]) - assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj) + assert(reply1msg.filter == guid) + assert(reply1msg.reply.isInstanceOf[AvatarAction.Release]) + assert(reply1msg.reply.asInstanceOf[AvatarAction.Release].player == obj) - zone.AvatarEvents ! AvatarServiceMessage.Corpse( + zone.AvatarEvents ! CorpseEnvelope( RemoverActor.HurrySpecific(List(objAlt, obj), zone) ) //IMPORTANT: TWO ENTRIES val reply2 = subscriber.receiveOne(100 milliseconds) assert(reply2.isInstanceOf[AvatarServiceResponse]) val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] assert(reply2msg.channel.equals("/test/Avatar")) - assert(reply2msg.avatar_guid == Service.defaultPlayerGUID) - assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete]) - assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid) + assert(reply2msg.filter == Service.defaultPlayerGUID) + assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete]) + assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid) subscriber.expectNoMessage(1 seconds) assert(zone.Corpses.isEmpty) diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 2b72d42ff..e129405ba 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -587,7 +587,8 @@ object AvatarActor { val player = session.player session.zone.AvatarEvents ! AvatarServiceMessage( player.Faction.toString, - AvatarAction.PlanetsideAttribute(player.GUID, 53, state) + player.GUID, + AvatarAction.PlanetsideAttribute(53, state) ) } @@ -1385,7 +1386,8 @@ class AvatarActor( sessionActor ! SessionActor.SendResponse(PlanetsideAttributeMessage(session.get.player.GUID, 53, 0)) session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.faction.toString, - AvatarAction.PlanetsideAttribute(session.get.player.GUID, 53, if (lfs) 1 else 0) + session.get.player.GUID, + AvatarAction.PlanetsideAttribute(53, if (lfs) 1 else 0) ) Behaviors.same @@ -1796,7 +1798,7 @@ class AvatarActor( val zone = player.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse(Service.defaultPlayerGUID, DisplayedAwardMessage(player.GUID, ribbon, bar)) + AvatarAction.SendResponse(DisplayedAwardMessage(player.GUID, ribbon, bar)) ) Behaviors.same @@ -2075,8 +2077,8 @@ class AvatarActor( avatarCopy(avatar.copy(decoration = avatar.decoration.copy(cosmetics = Some(cosmetics)))) zone.AvatarEvents ! AvatarServiceMessage( zone.id, + session.get.player.GUID, AvatarAction.PlanetsideAttributeToAll( - session.get.player.GUID, 106, Cosmetic.valuesToAttributeValue(cosmetics) ) @@ -3000,13 +3002,13 @@ class AvatarActor( val next = BattleRank.withExperience(newBep).value val br24 = BattleRank.BR24.value sessionActor ! SessionActor.SendResponse(BattleExperienceMessage(pguid, newBep, localModifier)) - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(pguid, 17, newBep)) + events ! AvatarServiceMessage(zoneId, pguid, AvatarAction.PlanetsideAttributeToAll(17, newBep)) if (current < br24 && next >= br24 || current >= br24 && next < br24) { setCosmetics(Set()).onComplete { _ => val evts = events val name = player.Name val guid = pguid - evts ! AvatarServiceMessage(name, AvatarAction.PlanetsideAttributeToAll(guid, 106, 1)) //set to no helmet + evts ! AvatarServiceMessage(name, guid, AvatarAction.PlanetsideAttributeToAll(106, 1)) //set to no helmet } } // when the level is reduced, take away any implants over the implant slot limit @@ -3051,10 +3053,7 @@ class AvatarActor( val sess = session.get val zone = sess.zone avatar = avatar.copy(cep = cep) - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.PlanetsideAttributeToAll(sess.player.GUID, 18, cep) - ) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, sess.player.GUID, AvatarAction.PlanetsideAttributeToAll(18, cep)) case Failure(exception) => log.error(exception)("db failure") } @@ -3165,10 +3164,7 @@ class AvatarActor( val player = _session.player zone.AvatarEvents ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard))) - ) + AvatarAction.SendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))) ) } @@ -3494,8 +3490,7 @@ class AvatarActor( value: Int ): Unit = { import akka.actor.typed.scaladsl.adapter.TypedActorRefOps - import net.psforever.services.avatar.{AvatarResponse => RESP} - sessionActor.toClassic ! AvatarServiceResponse("", guid, RESP.AvatarImplant(action, index, value)) + sessionActor.toClassic ! AvatarServiceResponse("", guid, AvatarAction.AvatarImplant(action, index, value)) } private def buyImplantAction( @@ -3656,7 +3651,7 @@ class AvatarActor( // What is normally a 60s timer that is set to 120s on the server will still visually update as if 60s session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.name, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, actionProgress)) + AvatarAction.SendResponse(ActionProgressMessage(slot + 6, actionProgress)) ) implant.copy(initialized = false, active = false, timer = futureDelay) } else { @@ -3705,7 +3700,7 @@ class AvatarActor( //can not formally stop the initialization time on the character information window; set it to 100 to make it look blank session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.name, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, 100)) + AvatarAction.SendResponse(ActionProgressMessage(slot + 6, 100)) ) implant.copy(initialized = false, active = false, timer = 0L) } @@ -3775,7 +3770,8 @@ class AvatarActor( // Deactivation sound / effect session.get.zone.AvatarEvents ! AvatarServiceMessage( session.get.zone.id, - AvatarAction.PlanetsideAttribute(session.get.player.GUID, 28, implant.definition.implantType.value * 2) + session.get.player.GUID, + AvatarAction.PlanetsideAttribute(28, implant.definition.implantType.value * 2) ) sendAvatarImplantMessageToSelf(session.get.player.GUID, ImplantAction.Activation, slot, value = 0) implant.copy(active = false) @@ -3852,10 +3848,7 @@ class AvatarActor( val newHealth = player.Health = originalHealth + 1 val events = zone.AvatarEvents player.LogActivity(HealFromImplant(implant.definition.implantType, 1)) - events ! AvatarServiceMessage( - zone.id, - AvatarAction.PlanetsideAttributeToAll(guid, 0, newHealth) - ) + events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) false } else { !aliveAndWounded @@ -3869,8 +3862,8 @@ class AvatarActor( val zone = sess.zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, + sess.player.GUID, AvatarAction.PlanetsideAttribute( - sess.player.GUID, 28, implant.definition.implantType.value * 2 + 1 ) @@ -3894,7 +3887,7 @@ class AvatarActor( val actionProgress = calculateImplantTimerStats(implant, AvatarActor.initializationTime(implant))._3 session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.name, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, actionProgress)) + AvatarAction.SendResponse(ActionProgressMessage(slot + 6, actionProgress)) ) implantOpt case (None, _) => 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 764a6c89e..f0a03989b 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -12,7 +12,8 @@ import net.psforever.objects.serverobject.containable.ContainableBehavior import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vital.RevivingActivity import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction} -import net.psforever.services.avatar.AvatarServiceResponse +import net.psforever.services.avatar.{AvatarAction, AvatarServiceResponse} +import net.psforever.services.base.EventResponse import net.psforever.types.ImplantType // @@ -26,7 +27,6 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ArmorChangedMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} -import net.psforever.services.avatar.AvatarResponse import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -48,7 +48,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: AvatarResponse.Response): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { val resolvedPlayerGuid = if (player != null && player.HasGUID) { player.GUID } else { @@ -58,16 +58,16 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val isSameTarget = !isNotSameTarget reply match { /* special messages */ - case AvatarResponse.TeardownConnection() if player.spectator => + case AvatarAction.TeardownConnection() if player.spectator => context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) context.self.forward(AvatarServiceResponse(toChannel, guid, reply)) - case AvatarResponse.TeardownConnection() => + case AvatarAction.TeardownConnection() => context.self ! SessionActor.SetMode(NormalMode) context.self.forward(AvatarServiceResponse(toChannel, guid, reply)) /* really common messages (very frequently, every life) */ - case pstate @ AvatarResponse.PlayerState( + case pstate @ AvatarAction.PlayerState( pos, vel, yaw, @@ -167,7 +167,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } } - case AvatarResponse.AvatarImplant(ImplantAction.Add, implant_slot, value) + case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) if value == ImplantType.SecondWind.value => sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Add, implant_slot, 7)) //second wind does not normally load its icon into the shortcut hotbar @@ -179,7 +179,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } - case AvatarResponse.AvatarImplant(ImplantAction.Remove, implant_slot, value) + case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) if value == ImplantType.SecondWind.value => sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Remove, implant_slot, value)) //second wind does not normally unload its icon from the shortcut hotbar @@ -195,10 +195,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, None)) } - case AvatarResponse.AvatarImplant(action, implant_slot, value) => + case AvatarAction.AvatarImplant(action, implant_slot, value) => sendResponse(AvatarImplantMessage(resolvedPlayerGuid, action, implant_slot, value)) - case AvatarResponse.ObjectHeld(slot, _) + case AvatarAction.ObjectHeld(slot, _) if isSameTarget && player.VisibleSlots.contains(slot) => sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon @@ -209,76 +209,76 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.stopDeconstructing() } - case AvatarResponse.ObjectHeld(slot, _) + case AvatarAction.ObjectHeld(slot, _) if isSameTarget && slot > -1 => sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) - case AvatarResponse.ObjectHeld(_, _) + case AvatarAction.ObjectHeld(_, _) if isSameTarget => () - case AvatarResponse.ObjectHeld(_, previousSlot) => + case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - case AvatarResponse.ChangeFireState_Start(weaponGuid) + case AvatarAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - case AvatarResponse.ChangeFireState_Start(weaponGuid) + case AvatarAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case AvatarResponse.ChangeFireState_Stop(weaponGuid) + case AvatarAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - case AvatarResponse.ChangeFireState_Stop(weaponGuid) + case AvatarAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case AvatarResponse.LoadPlayer(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.EquipmentInHand(pkt) if isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => + case AvatarAction.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideAttributeToAll(attributeType, attributeValue) => + case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => + case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => + case AvatarAction.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - case AvatarResponse.HitHint(sourceGuid) if player.isAlive => + case AvatarAction.HitHint(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, guid)) sessionLogic.zoning.CancelZoningProcess() - case AvatarResponse.Destroy(victim, killer, weapon, pos) => + case AvatarAction.Destroy(victim, killer, weapon, pos) => // guid = victim // killer = killer sendResponse(DestroyMessage(victim, killer, weapon, pos)) - case AvatarResponse.DestroyDisplay(killer, victim, method, unk) => + case AvatarAction.DestroyDisplay(killer, victim, method, unk) => sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - case AvatarResponse.TerminalOrderResult(terminalGuid, action, result) + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true AvatarActor.savePlayerData(player) - case AvatarResponse.TerminalOrderResult(terminalGuid, action, result) => + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true - case AvatarResponse.ChangeExosuit( + case AvatarAction.ChangeExosuit( target, armor, exosuit, @@ -336,7 +336,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } DropLeftovers(player)(drop) - case AvatarResponse.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => + case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to some other player @@ -361,7 +361,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) } - case AvatarResponse.ChangeLoadout( + case AvatarAction.ChangeLoadout( target, armor, exosuit, @@ -398,7 +398,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } DropLeftovers(player)(drops) - case AvatarResponse.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => + case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => //redraw handled by callbacks sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) @@ -407,7 +407,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //cleanup oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - case AvatarResponse.UseKit(kguid, kObjId) => + case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( resolvedPlayerGuid, @@ -425,25 +425,25 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) sendResponse(ObjectDeleteMessage(kguid, unk1=0)) - case AvatarResponse.KitNotUsed(_, "") => + case AvatarAction.KitNotUsed(_, "") => sessionLogic.general.kitToBeUsed = None - case AvatarResponse.KitNotUsed(_, msg) => + case AvatarAction.KitNotUsed(_, msg) => sessionLogic.general.kitToBeUsed = None sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarResponse.SendResponse(msg) => + case AvatarAction.SendResponse(msg) => sendResponse(msg) - case AvatarResponse.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => + case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => sendResponse(msg) /* common messages (maybe once every respawn) */ - case AvatarResponse.Reload(itemGuid) + case AvatarAction.Reload(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case AvatarResponse.Killed(_, mount) => + case AvatarAction.Killed(_, mount) => //pure logic sessionLogic.shooting.shotsWhileDead = 0 sessionLogic.zoning.CancelZoningProcess() @@ -480,10 +480,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //render CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) - case AvatarResponse.Release(tplayer) if isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - case AvatarResponse.Revive(revivalTargetGuid) + case AvatarAction.Revive(revivalTargetGuid) if resolvedPlayerGuid == revivalTargetGuid => ops.revive() player.Actor ! Player.Revive @@ -498,51 +498,51 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } /* uncommon messages (utility, or once in a while) */ - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + case AvatarAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + case AvatarAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - case AvatarResponse.ChangeFireMode(itemGuid, mode) if isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) - case AvatarResponse.ConcealPlayer() => + case AvatarAction.ConcealPlayer(_) => sendResponse(GenericObjectActionMessage(guid, code=9)) - case AvatarResponse.EnvironmentalDamage(_, _, _) => + case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcess() - case AvatarResponse.DropItem(pkt) if isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.ObjectDelete(itemGuid, unk) if isNotSameTarget => + case AvatarAction.ObjectDelete(itemGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) /* rare messages */ - case AvatarResponse.SetEmpire(objectGuid, faction) if isNotSameTarget => + case AvatarAction.SetEmpire(objectGuid, faction) if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) - case AvatarResponse.DropSpecialItem() => + case AvatarAction.DropSpecialItem() => sessionLogic.general.dropSpecialSlotItem() - case AvatarResponse.OxygenState(player, vehicle) => + case AvatarAction.OxygenState(player, vehicle) => sendResponse(OxygenStateMessage( DrowningTarget(player.guid, player.progress, player.state), vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } )) - case AvatarResponse.LoadProjectile(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) - case AvatarResponse.ProjectileExplodes(projectileGuid, projectile) => + case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => sendResponse( ProjectileStateMessage( projectileGuid, @@ -556,13 +556,13 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) - case AvatarResponse.ProjectileAutoLockAwareness(mode) => + case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarResponse.PutDownFDU(target) if isNotSameTarget => + case AvatarAction.PutDownFDU(target) if isNotSameTarget => sendResponse(GenericObjectActionMessage(target, code=53)) - case AvatarResponse.StowEquipment(target, slot, item) if isNotSameTarget => + case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -573,7 +573,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) ) - case AvatarResponse.WeaponDryFire(weaponGuid) + case AvatarAction.WeaponDryFire(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index 3d5d4c45b..322a1fb3c 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -320,7 +320,8 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext val definition = spectator.Definition events ! AvatarServiceMessage( channel, - AvatarAction.LoadPlayer(guid, definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None) + guid, + AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None) ) } true @@ -336,10 +337,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext .filter(_.spectator) .foreach { spectator => val guid = spectator.GUID - events ! AvatarServiceMessage( - channel, - AvatarAction.ObjectDelete(guid, guid) - ) + events ! AvatarServiceMessage(channel, guid, AvatarAction.ObjectDelete(guid)) } true } @@ -394,7 +392,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext o.Faction = foundFaction continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.SetEmpire(Service.defaultPlayerGUID, o.GUID, foundFaction) + AvatarAction.SetEmpire(o.GUID, foundFaction) ) true case o: Building => @@ -407,7 +405,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext o.Faction = foundFaction continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.SetEmpire(Service.defaultPlayerGUID, o.GUID, foundFaction) + AvatarAction.SetEmpire(o.GUID, foundFaction) ) true } diff --git a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala index 0e454f71b..de3d59d25 100644 --- a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala @@ -120,6 +120,10 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic { .GUID(player.VehicleSeated) .collect { case obj: PlanetSideGameObject with Vitality => CustomerServiceRepresentativeMode.topOffHealth(data, obj) + obj + } + .getOrElse { + data.updateBlockMap(player, player.Position) } data.squad.updateSquad() } else { @@ -144,13 +148,16 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { packet.DetailedConstructorData(player).get )) data.zoning.spawn.HandleSetCurrentAvatar(player) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.LoadPlayer( + zone.AvatarEvents ! AvatarServiceMessage( + zone.id, pguid, - objectClass, - pguid, - packet.ConstructorData(player).get, - None - )) + AvatarAction.LoadPlayer( + objectClass, + pguid, + packet.ConstructorData(player).get, + None + ) + ) } def topOffHealth(data: SessionData, obj: PlanetSideGameObject with Vitality): Unit = { @@ -174,14 +181,14 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { player.Health = maxHealthOfPlayer.toInt player.LogActivity(player.ClearHistory().head) data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOfPlayer)) - data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, AvatarAction.PlanetsideAttribute(guid, 0, maxHealthOfPlayer)) + data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, guid, AvatarAction.PlanetsideAttribute(0, maxHealthOfPlayer)) } //below half armor, full armor val maxArmor = player.MaxArmor.toLong if (player.Armor < maxArmor) { player.Armor = maxArmor.toInt data.sendResponse(PlanetsideAttributeMessage(guid, 4, maxArmor)) - data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, AvatarAction.PlanetsideAttribute(guid, 4, maxArmor)) + data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, guid, AvatarAction.PlanetsideAttribute(4, maxArmor)) } } diff --git a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala index 4f168065b..cb6ec6e8f 100644 --- a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala @@ -34,7 +34,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1} import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.RemoverActor -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, CorpseEnvelope} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -134,8 +134,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex (player.isAlive && sessionLogic.zoning.spawn.deadState == DeadState.RespawnTime) continent.AvatarEvents ! AvatarServiceMessage( channel, + avatarGuid, AvatarAction.PlayerState( - avatarGuid, player.Position, player.Velocity, yaw, @@ -239,7 +239,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex case Some(obj: Player) if obj.isBackpack => obj.Position = Vector3.Zero - continent.AvatarEvents ! AvatarServiceMessage.Corpse(RemoverActor.ClearSpecific(List(obj), continent)) + continent.AvatarEvents ! CorpseEnvelope(RemoverActor.ClearSpecific(List(obj), continent)) case Some(obj: Player) => sessionLogic.general.suicide(obj) @@ -441,7 +441,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttribute(player.GUID, 19, 1) + player.GUID, + AvatarAction.PlanetsideAttribute(19, 1) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => @@ -461,7 +462,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttribute(player.GUID, 19, 0) + player.GUID, + AvatarAction.PlanetsideAttribute(19, 0) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => diff --git a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala index 592fbedd5..a17080966 100644 --- a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala @@ -45,7 +45,7 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic { // player.spectator = true data.chat.JoinChannel(SpectatorChannel) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.ObjectDelete(pguid, pguid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, AvatarAction.ObjectDelete(pguid)) sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "on")) sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR SPECTATOR MODE ON")) } @@ -61,7 +61,8 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic { data.chat.LeaveChannel(SpectatorChannel) continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.LoadPlayer(pguid, avatarId, pguid, player.Definition.Packet.ConstructorData(player).get, None) + pguid, + AvatarAction.LoadPlayer(avatarId, pguid, player.Definition.Packet.ConstructorData(player).get, None) ) sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "off")) } 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 586391cf8..c39f5f8e7 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -13,6 +13,7 @@ import net.psforever.objects.vital.RevivingActivity import net.psforever.objects.vital.interaction.Adversarial import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction, PlanetsideStringAttributeMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.EventResponse import net.psforever.types.ImplantType import scala.concurrent.duration._ @@ -29,7 +30,6 @@ import net.psforever.objects.vital.etc.ExplodingEntityReason import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} -import net.psforever.services.avatar.AvatarResponse import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -51,7 +51,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: AvatarResponse.Response): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { val resolvedPlayerGuid = if (player != null && player.HasGUID) { player.GUID } else { @@ -61,12 +61,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val isSameTarget = !isNotSameTarget reply match { /* special messages */ - case AvatarResponse.TeardownConnection() => + case AvatarAction.TeardownConnection() => log.trace(s"ending ${player.Name}'s old session by event system request (relog)") context.stop(context.self) /* really common messages (very frequently, every life) */ - case pstate @ AvatarResponse.PlayerState( + case pstate @ AvatarAction.PlayerState( pos, vel, yaw, @@ -166,7 +166,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } } - case AvatarResponse.AvatarImplant(ImplantAction.Add, implant_slot, value) + case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) if value == ImplantType.SecondWind.value => sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Add, implant_slot, 7)) //second wind does not normally load its icon into the shortcut hotbar @@ -178,7 +178,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } - case AvatarResponse.AvatarImplant(ImplantAction.Remove, implant_slot, value) + case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) if value == ImplantType.SecondWind.value => sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Remove, implant_slot, value)) //second wind does not normally unload its icon from the shortcut hotbar @@ -194,10 +194,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, None)) } - case AvatarResponse.AvatarImplant(action, implant_slot, value) => + case AvatarAction.AvatarImplant(action, implant_slot, value) => sendResponse(AvatarImplantMessage(resolvedPlayerGuid, action, implant_slot, value)) - case AvatarResponse.ObjectHeld(slot, _) + case AvatarAction.ObjectHeld(slot, _) if isSameTarget && player.VisibleSlots.contains(slot) => sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon @@ -208,69 +208,69 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.stopDeconstructing() } - case AvatarResponse.ObjectHeld(slot, _) + case AvatarAction.ObjectHeld(slot, _) if isSameTarget && slot > -1 => sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) - case AvatarResponse.ObjectHeld(_, _) + case AvatarAction.ObjectHeld(_, _) if isSameTarget => () - case AvatarResponse.ObjectHeld(_, previousSlot) => + case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - case AvatarResponse.ChangeFireState_Start(weaponGuid) + case AvatarAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - case AvatarResponse.ChangeFireState_Start(weaponGuid) + case AvatarAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case AvatarResponse.ChangeFireState_Stop(weaponGuid) + case AvatarAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - case AvatarResponse.ChangeFireState_Stop(weaponGuid) + case AvatarAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case AvatarResponse.LoadPlayer(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.EquipmentInHand(pkt) if isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => + case AvatarAction.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideAttributeToAll(attributeType, attributeValue) => + case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => + case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideStringAttribute(attributeType, attributeValue) => + case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => sendResponse(PlanetsideStringAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => + case AvatarAction.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - case AvatarResponse.HitHint(sourceGuid) if player.isAlive => + case AvatarAction.HitHint(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, guid)) sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") - case AvatarResponse.Destroy(victim, killer, weapon, pos) => + case AvatarAction.Destroy(victim, killer, weapon, pos) => // guid = victim // killer = killer sendResponse(DestroyMessage(victim, killer, weapon, pos)) - case AvatarResponse.DestroyDisplay(killer, victim, method, unk) => + case AvatarAction.DestroyDisplay(killer, victim, method, unk) => sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - case AvatarResponse.TerminalOrderResult(terminalGuid, action, result) + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true @@ -280,11 +280,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A Config.app.game.savedMsg.interruptedByAction.variable ) - case AvatarResponse.TerminalOrderResult(terminalGuid, action, result) => + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true - case AvatarResponse.ChangeExosuit( + case AvatarAction.ChangeExosuit( target, armor, exosuit, @@ -360,7 +360,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //deactivate non-passive implants avatarActor ! AvatarActor.DeactivateActiveImplants - case AvatarResponse.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => + case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to some other player @@ -385,7 +385,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) } - case AvatarResponse.ChangeLoadout( + case AvatarAction.ChangeLoadout( target, armor, exosuit, @@ -425,7 +425,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //deactivate non-passive implants avatarActor ! AvatarActor.DeactivateActiveImplants - case AvatarResponse.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => + case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => //redraw handled by callbacks sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) @@ -434,7 +434,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //cleanup oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - case AvatarResponse.UseKit(kguid, kObjId) => + case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( resolvedPlayerGuid, @@ -452,52 +452,52 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) sendResponse(ObjectDeleteMessage(kguid, unk1=0)) - case AvatarResponse.KitNotUsed(_, "") => + case AvatarAction.KitNotUsed(_, "") => sessionLogic.general.kitToBeUsed = None - case AvatarResponse.KitNotUsed(_, msg) => + case AvatarAction.KitNotUsed(_, msg) => sessionLogic.general.kitToBeUsed = None sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarResponse.UpdateKillsDeathsAssists(_, kda) => + case AvatarAction.UpdateKillsDeathsAssists(_, kda) => avatarActor ! AvatarActor.UpdateKillsDeathsAssists(kda) - case AvatarResponse.AwardBep(charId, bep, expType) => + case AvatarAction.AwardBep(charId, bep, expType) => //if the target player, always award (some) BEP if (charId == player.CharId) { avatarActor ! AvatarActor.AwardBep(bep, expType) } - case AvatarResponse.AwardCep(charId, cep) => + case AvatarAction.AwardCep(charId, cep) => //if the target player, always award (some) CEP if (charId == player.CharId) { avatarActor ! AvatarActor.AwardCep(cep) } - case AvatarResponse.FacilityCaptureRewards(buildingId, zoneNumber, cep) => + case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => ops.facilityCaptureRewards(buildingId, zoneNumber, cep) - case AvatarResponse.ShareKillExperienceWithSquad(killer, exp) => + case AvatarAction.ShareKillExperienceWithSquad(killer, exp) => ops.shareKillExperienceWithSquad(killer, exp) - case AvatarResponse.ShareAntExperienceWithSquad(owner, exp, vehicle) => + case AvatarAction.ShareAntExperienceWithSquad(owner, exp, vehicle) => ops.shareAntExperienceWithSquad(owner, exp, vehicle) - case AvatarResponse.RemoveFromOutfitChat(outfit_id) => + case AvatarAction.RemoveFromOutfitChat(outfit_id) => ops.removeFromOutfitChat(outfit_id) - case AvatarResponse.SendResponse(msg) => + case AvatarAction.SendResponse(msg) => sendResponse(msg) - case AvatarResponse.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => + case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => sendResponse(msg) /* common messages (maybe once every respawn) */ - case AvatarResponse.Reload(itemGuid) + case AvatarAction.Reload(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case AvatarResponse.Killed(cause, mount) => + case AvatarAction.Killed(cause, mount) => //log and chat messages //destroy display val zoneChannel = continent.id @@ -587,10 +587,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) } - case AvatarResponse.Release(tplayer) if isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - case AvatarResponse.Revive(revivalTargetGuid) + case AvatarAction.Revive(revivalTargetGuid) if resolvedPlayerGuid == revivalTargetGuid => log.info(s"No time for rest, ${player.Name}. Back on your feet!") ops.revive() @@ -606,51 +606,51 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } /* uncommon messages (utility, or once in a while) */ - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + case AvatarAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + case AvatarAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - case AvatarResponse.ChangeFireMode(itemGuid, mode) if isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) - case AvatarResponse.ConcealPlayer() => + case AvatarAction.ConcealPlayer(_) => sendResponse(GenericObjectActionMessage(guid, code=9)) - case AvatarResponse.EnvironmentalDamage(_, _, _) => + case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") - case AvatarResponse.DropItem(pkt) if isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.ObjectDelete(itemGuid, unk) if isNotSameTarget => + case AvatarAction.ObjectDelete(itemGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) /* rare messages */ - case AvatarResponse.SetEmpire(objectGuid, faction) if isNotSameTarget => + case AvatarAction.SetEmpire(objectGuid, faction) if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) - case AvatarResponse.DropSpecialItem() => + case AvatarAction.DropSpecialItem() => sessionLogic.general.dropSpecialSlotItem() - case AvatarResponse.OxygenState(player, vehicle) => + case AvatarAction.OxygenState(player, vehicle) => sendResponse(OxygenStateMessage( DrowningTarget(player.guid, player.progress, player.state), vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } )) - case AvatarResponse.LoadProjectile(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) - case AvatarResponse.ProjectileExplodes(projectileGuid, projectile) => + case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => sendResponse( ProjectileStateMessage( projectileGuid, @@ -664,13 +664,13 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) - case AvatarResponse.ProjectileAutoLockAwareness(mode) => + case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarResponse.PutDownFDU(target) if isNotSameTarget => + case AvatarAction.PutDownFDU(target) if isNotSameTarget => sendResponse(GenericObjectActionMessage(target, code=53)) - case AvatarResponse.StowEquipment(target, slot, item) if isNotSameTarget => + case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -681,7 +681,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) ) - case AvatarResponse.WeaponDryFire(weaponGuid) + case AvatarAction.WeaponDryFire(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => @@ -698,8 +698,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val events = continent.AvatarEvents ops.killedWhileMounted(obj, playerGuid) //make player invisible on client - events ! AvatarServiceMessage(player.Name, AvatarAction.PlanetsideAttributeToAll(playerGuid, 29, 1)) + events ! AvatarServiceMessage(player.Name, playerGuid, AvatarAction.PlanetsideAttributeToAll(29, 1)) //only the dead player should "see" their own body, so that the death camera has something to focus on - events ! AvatarServiceMessage(continent.id, AvatarAction.ObjectDelete(playerGuid, playerGuid)) + events ! AvatarServiceMessage(continent.id, playerGuid, AvatarAction.ObjectDelete(playerGuid)) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index df8a88363..9be51341e 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -181,8 +181,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex }) continent.AvatarEvents ! AvatarServiceMessage( continent.id, + avatarGuid, AvatarAction.PlayerState( - avatarGuid, player.Position, player.Velocity, yaw, @@ -527,7 +527,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttribute(player.GUID, 19, 1) + player.GUID, + AvatarAction.PlanetsideAttribute(19, 1) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => @@ -548,7 +549,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttribute(player.GUID, 19, 0) + player.GUID, + AvatarAction.PlanetsideAttribute(19, 0) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => 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 cebbb5ba2..8569ea9ab 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -8,6 +8,7 @@ import net.psforever.objects.Players import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.{AvatarImplantMessage, ImplantAction} +import net.psforever.services.base.EventResponse import scala.concurrent.duration._ // @@ -23,7 +24,7 @@ import net.psforever.objects.vital.etc.ExplodingEntityReason import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} -import net.psforever.services.avatar.{AvatarAction, AvatarResponse, AvatarServiceMessage} +import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -45,7 +46,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: AvatarResponse.Response): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { val resolvedPlayerGuid = if (player != null && player.HasGUID) { player.GUID } else { @@ -55,12 +56,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val isSameTarget = !isNotSameTarget reply match { /* special messages */ - case AvatarResponse.TeardownConnection() => + case AvatarAction.TeardownConnection() => log.trace(s"ending ${player.Name}'s old session by event system request (relog)") context.stop(context.self) /* really common messages (very frequently, every life) */ - case pstate @ AvatarResponse.PlayerState( + case pstate @ AvatarAction.PlayerState( pos, vel, yaw, @@ -160,7 +161,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } } - case AvatarResponse.ObjectHeld(slot, _) + case AvatarAction.ObjectHeld(slot, _) if isSameTarget && player.VisibleSlots.contains(slot) => sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon @@ -171,76 +172,76 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.stopDeconstructing() } - case AvatarResponse.ObjectHeld(slot, _) + case AvatarAction.ObjectHeld(slot, _) if isSameTarget && slot > -1 => sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) - case AvatarResponse.ObjectHeld(_, _) + case AvatarAction.ObjectHeld(_, _) if isSameTarget => () - case AvatarResponse.ObjectHeld(_, previousSlot) => + case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - case AvatarResponse.ChangeFireState_Start(weaponGuid) + case AvatarAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - case AvatarResponse.ChangeFireState_Start(weaponGuid) + case AvatarAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case AvatarResponse.ChangeFireState_Stop(weaponGuid) + case AvatarAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - case AvatarResponse.ChangeFireState_Stop(weaponGuid) + case AvatarAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case AvatarResponse.LoadPlayer(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.EquipmentInHand(pkt) if isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => + case AvatarAction.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideAttributeToAll(attributeType, attributeValue) => + case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => + case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarResponse.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => + case AvatarAction.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - case AvatarResponse.HitHint(sourceGuid) if player.isAlive => + case AvatarAction.HitHint(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, guid)) sessionLogic.zoning.CancelZoningProcess() - case AvatarResponse.Destroy(victim, killer, weapon, pos) => + case AvatarAction.Destroy(victim, killer, weapon, pos) => // guid = victim // killer = killer sendResponse(DestroyMessage(victim, killer, weapon, pos)) - case AvatarResponse.DestroyDisplay(killer, victim, method, unk) => + case AvatarAction.DestroyDisplay(killer, victim, method, unk) => sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - case AvatarResponse.TerminalOrderResult(terminalGuid, action, result) + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true AvatarActor.savePlayerData(player) - case AvatarResponse.TerminalOrderResult(terminalGuid, action, result) => + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true - case AvatarResponse.ChangeExosuit( + case AvatarAction.ChangeExosuit( target, armor, exosuit, @@ -298,7 +299,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } DropLeftovers(player)(drop) - case AvatarResponse.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, _, delete) => + case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, _, delete) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to some other player @@ -319,7 +320,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) } - case AvatarResponse.ChangeLoadout( + case AvatarAction.ChangeLoadout( target, armor, exosuit, @@ -353,7 +354,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, player, holsters ++ inventory) DropLeftovers(player)(drops) - case AvatarResponse.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => + case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => //redraw handled by callbacks sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) @@ -362,7 +363,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //cleanup oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - case AvatarResponse.UseKit(kguid, kObjId) => + case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( resolvedPlayerGuid, @@ -380,14 +381,14 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) sendResponse(ObjectDeleteMessage(kguid, unk1=0)) - case AvatarResponse.KitNotUsed(_, "") => + case AvatarAction.KitNotUsed(_, "") => sessionLogic.general.kitToBeUsed = None - case AvatarResponse.KitNotUsed(_, msg) => + case AvatarAction.KitNotUsed(_, msg) => sessionLogic.general.kitToBeUsed = None sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarResponse.UpdateKillsDeathsAssists(_, kda: Kill) if kda.experienceEarned > 0 => + case AvatarAction.UpdateKillsDeathsAssists(_, kda: Kill) if kda.experienceEarned > 0 => continent.actor ! ZoneActor.RewardOurSupporters( PlayerSource(player), Players.produceContributionTranscriptFromKill(continent, player, kda), @@ -395,38 +396,38 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A kda.experienceEarned ) - case AvatarResponse.AwardBep(charId, bep, expType) => + case AvatarAction.AwardBep(charId, bep, expType) => //if the target player, always award (some) BEP if (charId == player.CharId) { avatarActor ! AvatarActor.AwardBep(bep, expType) } - case AvatarResponse.AwardCep(charId, cep) => + case AvatarAction.AwardCep(charId, cep) => //if the target player, always award (some) CEP if (charId == player.CharId) { avatarActor ! AvatarActor.AwardCep(cep) } - case AvatarResponse.FacilityCaptureRewards(buildingId, zoneNumber, cep) => + case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => ops.facilityCaptureRewards(buildingId, zoneNumber, cep) - case AvatarResponse.SendResponse(pkt: AvatarImplantMessage) + case AvatarAction.SendResponse(pkt: AvatarImplantMessage) if pkt.player_guid == player.GUID && pkt.action == ImplantAction.Initialization => //special spectator implants stay initialized and do not deinitialize () - case AvatarResponse.SendResponse(msg) => + case AvatarAction.SendResponse(msg) => sendResponse(msg) - case AvatarResponse.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => + case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => sendResponse(msg) /* common messages (maybe once every respawn) */ - case AvatarResponse.Reload(itemGuid) + case AvatarAction.Reload(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case AvatarResponse.Killed(_, mount) => + case AvatarAction.Killed(_, mount) => //log and chat messages val cause = player.LastDamage.flatMap { damage => val interaction = damage.interaction @@ -477,10 +478,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) } - case AvatarResponse.Release(tplayer) if isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - case AvatarResponse.Revive(revivalTargetGuid) if resolvedPlayerGuid == revivalTargetGuid => + case AvatarAction.Revive(revivalTargetGuid) if resolvedPlayerGuid == revivalTargetGuid => log.info(s"No time for rest, ${player.Name}. Back on your feet!") sessionLogic.zoning.spawn.reviveTimer.cancel() sessionLogic.zoning.spawn.deadState = DeadState.Alive @@ -490,55 +491,56 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttributeToAll(revivalTargetGuid, attribute_type=0, health) + revivalTargetGuid, + AvatarAction.PlanetsideAttributeToAll(attribute_type=0, health) ) /* uncommon messages (utility, or once in a while) */ - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + case AvatarAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + case AvatarAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - case AvatarResponse.ChangeFireMode(itemGuid, mode) if isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) - case AvatarResponse.ConcealPlayer() => + case AvatarAction.ConcealPlayer(_) => sendResponse(GenericObjectActionMessage(guid, code=9)) - case AvatarResponse.EnvironmentalDamage(_, _, _) => + case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcess() - case AvatarResponse.DropItem(pkt) if isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.ObjectDelete(itemGuid, unk) if isNotSameTarget => + case AvatarAction.ObjectDelete(itemGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) /* rare messages */ - case AvatarResponse.SetEmpire(objectGuid, faction) if isNotSameTarget => + case AvatarAction.SetEmpire(objectGuid, faction) if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) - case AvatarResponse.DropSpecialItem() => + case AvatarAction.DropSpecialItem() => sessionLogic.general.dropSpecialSlotItem() - case AvatarResponse.OxygenState(player, vehicle) => + case AvatarAction.OxygenState(player, vehicle) => sendResponse(OxygenStateMessage( DrowningTarget(player.guid, player.progress, player.state), vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } )) - case AvatarResponse.LoadProjectile(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarResponse.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) - case AvatarResponse.ProjectileExplodes(projectileGuid, projectile) => + case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => sendResponse( ProjectileStateMessage( projectileGuid, @@ -552,13 +554,13 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) - case AvatarResponse.ProjectileAutoLockAwareness(mode) => + case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarResponse.PutDownFDU(target) if isNotSameTarget => + case AvatarAction.PutDownFDU(target) if isNotSameTarget => sendResponse(GenericObjectActionMessage(target, code=53)) - case AvatarResponse.StowEquipment(target, slot, item) if isNotSameTarget => + case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -569,7 +571,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) ) - case AvatarResponse.WeaponDryFire(weaponGuid) + case AvatarAction.WeaponDryFire(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala index 0987bfd1c..0e118cb0f 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala @@ -76,8 +76,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.Cloaked = player.ExoSuit == ExoSuitType.Infiltration && isCloaking continent.AvatarEvents ! AvatarServiceMessage( "spectator", + avatarGuid, AvatarAction.PlayerState( - avatarGuid, player.Position, player.Velocity, yaw, @@ -230,7 +230,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttribute(player.GUID, 19, 1) + player.GUID, + AvatarAction.PlanetsideAttribute(19, 1) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => @@ -251,7 +252,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttribute(player.GUID, 19, 0) + player.GUID, + AvatarAction.PlanetsideAttribute(19, 0) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => diff --git a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala index 483f13a31..94eb93823 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala @@ -68,7 +68,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic { player.Inventory.Items .foreach { entry => sendResponse(ObjectDeleteMessage(entry.GUID, 0)) } sendResponse(ObjectDeleteMessage(player.avatar.locker.GUID, 0)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.ObjectDelete(pguid, pguid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, AvatarAction.ObjectDelete(pguid)) player.Holsters() .collect { case slot if slot.Equipment.nonEmpty => sendResponse(ObjectDeleteMessage(slot.Equipment.get.GUID, 0)) } val vehicleAndSeat = data.vehicles.GetMountableAndSeat(None, player, continent) match { diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 9899a1b2c..9b7c7ce73 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -18,6 +18,7 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.RemoverActor +import net.psforever.services.avatar.GroundEnvelope import net.psforever.services.local.{LocalAction, LocalServiceMessage} import scala.collection.mutable @@ -851,7 +852,7 @@ class GeneralOperations( case _ if continent.EquipmentOnGround.contains(obj) => obj.Position = Vector3.Zero continent.Ground ! Zone.Ground.RemoveItem(objectGuid) - continent.AvatarEvents ! AvatarServiceMessage.Ground(RemoverActor.ClearSpecific(List(obj), continent)) + continent.AvatarEvents ! GroundEnvelope(RemoverActor.ClearSpecific(List(obj), continent)) true case _ => Zone.EquipmentIs.Where(obj, objectGuid, continent) match { @@ -988,7 +989,8 @@ class GeneralOperations( player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttributeToAll(player.GUID, 8, 0) + player.GUID, + AvatarAction.PlanetsideAttributeToAll(8, 0) ) } } @@ -997,7 +999,8 @@ class GeneralOperations( private def activateMaxSpecialStateMessage(): Unit = { continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.PlanetsideAttributeToAll(player.GUID, 8, 1) + player.GUID, + AvatarAction.PlanetsideAttributeToAll(8, 1) ) } diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index 7c7002e51..d033b8d0d 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -9,6 +9,7 @@ import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.objects.zones.exp import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, AvatarServiceResponse} +import net.psforever.services.base.EventResponse import net.psforever.services.chat.OutfitChannel import scala.collection.mutable @@ -16,14 +17,13 @@ import scala.collection.mutable import net.psforever.actors.session.AvatarActor import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game._ -import net.psforever.services.avatar.AvatarResponse import net.psforever.types._ import net.psforever.util.Config trait AvatarHandlerFunctions extends CommonSessionInterfacingFunctionality { val ops: SessionAvatarHandlers - def handle(toChannel: String, guid: PlanetSideGUID, reply: AvatarResponse.Response): Unit + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit } class SessionAvatarHandlers( @@ -215,7 +215,7 @@ class SessionAvatarHandlers( context.self ! AvatarServiceResponse( playerName, Service.defaultPlayerGUID, - AvatarResponse.SendResponse( + AvatarAction.SendResponse( ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero) ) ) @@ -239,7 +239,7 @@ class SessionAvatarHandlers( object SessionAvatarHandlers { private[session] case class LastUpstream( - msg: Option[AvatarResponse.PlayerState], + msg: Option[AvatarAction.PlayerState], visible: Boolean, shooting: Option[PlanetSideGUID], time: Long diff --git a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala index 80bebf9c9..be64abbbb 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala @@ -83,11 +83,17 @@ object SessionOutfitHandlers { player.outfit_id = outfit.id player.outfit_name = outfit.name - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id, - AvatarAction.PlanetsideAttributeToAll(player.GUID, 39, outfit.id)) + player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.id, + player.GUID, + AvatarAction.PlanetsideAttributeToAll(39, outfit.id) + ) - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id, - AvatarAction.PlanetsideStringAttribute(player.GUID, 0, outfit.name)) + player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.id, + player.GUID, + AvatarAction.PlanetsideStringAttribute(0, outfit.name) + ) session.chat.JoinChannel(OutfitChannel(player.outfit_id)) } @@ -168,11 +174,17 @@ object SessionOutfitHandlers { invited.outfit_id = outfit.id invited.outfit_name = outfit.name - invited.Zone.AvatarEvents ! AvatarServiceMessage(invited.Zone.id, - AvatarAction.PlanetsideAttributeToAll(invited.GUID, 39, outfit.id)) + invited.Zone.AvatarEvents ! AvatarServiceMessage( + invited.Zone.id, + invited.GUID, + AvatarAction.PlanetsideAttributeToAll(39, outfit.id) + ) - invited.Zone.AvatarEvents ! AvatarServiceMessage(invited.Zone.id, - AvatarAction.PlanetsideStringAttribute(invited.GUID, 0, outfit.name)) + invited.Zone.AvatarEvents ! AvatarServiceMessage( + invited.Zone.id, + invited.GUID, + AvatarAction.PlanetsideStringAttribute(0, outfit.name) + ) case (None, _, _) => PlayerControl.sendResponse(invited.Zone, invited.Name, @@ -230,11 +242,17 @@ object SessionOutfitHandlers { OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked())) ) - kickedBy.Zone.AvatarEvents ! AvatarServiceMessage(kickedBy.Zone.id, - AvatarAction.PlanetsideAttributeToAll(kickedBy.GUID, 39, 0)) + kickedBy.Zone.AvatarEvents ! AvatarServiceMessage( + kickedBy.Zone.id, + kickedBy.GUID, + AvatarAction.PlanetsideAttributeToAll(39, 0) + ) - kickedBy.Zone.AvatarEvents ! AvatarServiceMessage(kickedBy.Zone.id, - AvatarAction.PlanetsideStringAttribute(kickedBy.GUID, 0, "")) + kickedBy.Zone.AvatarEvents ! AvatarServiceMessage( + kickedBy.Zone.id, + kickedBy.GUID, + AvatarAction.PlanetsideStringAttribute(0, "") + ) } }.recover { case e => e.printStackTrace() @@ -254,11 +272,17 @@ object SessionOutfitHandlers { OutfitMembershipResponse(OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1, kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false)) - kicked.Zone.AvatarEvents ! AvatarServiceMessage(kicked.Zone.id, - AvatarAction.PlanetsideAttributeToAll(kicked.GUID, 39, 0)) + kicked.Zone.AvatarEvents ! AvatarServiceMessage( + kicked.Zone.id, + kicked.GUID, + AvatarAction.PlanetsideAttributeToAll(39, 0) + ) - kicked.Zone.AvatarEvents ! AvatarServiceMessage(kicked.Zone.id, - AvatarAction.PlanetsideStringAttribute(kicked.GUID, 0, "")) + kicked.Zone.AvatarEvents ! AvatarServiceMessage( + kicked.Zone.id, + kicked.GUID, + AvatarAction.PlanetsideStringAttribute(0, "") + ) kicked.Zone.AvatarEvents ! AvatarServiceMessage( kicked.Name, AvatarAction.RemoveFromOutfitChat(kickedBy.outfit_id)) @@ -613,11 +637,17 @@ object SessionOutfitHandlers { player.outfit_id = outfit.id player.outfit_name = outfit.name - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id, - AvatarAction.PlanetsideAttributeToAll(player.GUID, 39, outfit.id)) + player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.id, + player.GUID, + AvatarAction.PlanetsideAttributeToAll(39, outfit.id) + ) - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id, - AvatarAction.PlanetsideStringAttribute(player.GUID, 0, outfit.name)) + player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.id, + player.GUID, + AvatarAction.PlanetsideStringAttribute(0, outfit.name) + ) case (None, _, _) => PlayerControl.sendResponse(player.Zone, player.Name, diff --git a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala index 8f5e0e5b2..4f6501914 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala @@ -107,7 +107,8 @@ class SessionSquadHandlers( sendResponse(PlanetsideAttributeMessage(player.GUID, 31, squad_supplement_id)) continent.AvatarEvents ! AvatarServiceMessage( s"${player.Faction}", - AvatarAction.PlanetsideAttribute(player.GUID, 31, squad_supplement_id) + player.GUID, + AvatarAction.PlanetsideAttribute(31, squad_supplement_id) ) sendResponse(PlanetsideAttributeMessage(player.GUID, 32, elem.index)) case _ => @@ -286,7 +287,7 @@ class SessionSquadHandlers( * @param value value to associate the player */ def GiveSquadColorsForOthers(guid: PlanetSideGUID, factionChannel: String, value: Long): Unit = { - continent.AvatarEvents ! AvatarServiceMessage(factionChannel, AvatarAction.PlanetsideAttribute(guid, 31, value)) + continent.AvatarEvents ! AvatarServiceMessage(factionChannel, guid, AvatarAction.PlanetsideAttribute(31, value)) } /** diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index 790343fc8..db1e8e6e0 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -281,10 +281,7 @@ class WeaponAndProjectileOperations( .orElse { continent.GUID(weapon_guid) } .collect { case _: Equipment if containerOpt.exists(_.isInstanceOf[Player]) => - continent.AvatarEvents ! AvatarServiceMessage( - continent.id, - AvatarAction.WeaponDryFire(player.GUID, weapon_guid) - ) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.WeaponDryFire(weapon_guid)) case _: Equipment => continent.VehicleEvents ! VehicleServiceMessage( continent.id, @@ -459,7 +456,8 @@ class WeaponAndProjectileOperations( sendResponse(ChangeFireModeMessage(item_guid, modeIndex)) continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, - AvatarAction.ChangeFireMode(player.GUID, item_guid, modeIndex) + player.GUID, + AvatarAction.ChangeFireMode(item_guid, modeIndex) ) } case Some(_) => @@ -480,8 +478,8 @@ class WeaponAndProjectileOperations( projectile.Velocity = shot_vel continent.AvatarEvents ! AvatarServiceMessage( continent.id, + player.GUID, AvatarAction.ProjectileState( - player.GUID, projectileGlobalUID, shot_pos, shot_vel, @@ -744,10 +742,7 @@ class WeaponAndProjectileOperations( //chain lash effect continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.SendResponse( - PlanetSideGUID(0), - ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList) - ) + AvatarAction.SendResponse(ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList)) ) //chain lash target output outputRefs.toList @@ -931,12 +926,9 @@ class WeaponAndProjectileOperations( tool.Magazine = 0 sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, weapon_guid, 0)) sendResponse(ChangeFireStateMessage_Stop(weapon_guid)) - continent.AvatarEvents ! AvatarServiceMessage( - continent.id, - AvatarAction.ChangeFireState_Stop(player.GUID, weapon_guid) - ) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.ChangeFireState_Stop(weapon_guid)) sendResponse(WeaponDryFireMessage(weapon_guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.WeaponDryFire(player.GUID, weapon_guid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.WeaponDryFire(weapon_guid)) } /** @@ -1079,7 +1071,8 @@ class WeaponAndProjectileOperations( def fireStateStartPlayerMessages(itemGuid: PlanetSideGUID): Unit = { continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, - AvatarAction.ChangeFireState_Start(player.GUID, itemGuid) + player.GUID, + AvatarAction.ChangeFireState_Start(itemGuid) ) } @@ -1118,7 +1111,8 @@ class WeaponAndProjectileOperations( def fireStateStopPlayerMessages(itemGuid: PlanetSideGUID): Unit = { continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, - AvatarAction.ChangeFireState_Stop(player.GUID, itemGuid) + player.GUID, + AvatarAction.ChangeFireState_Stop(itemGuid) ) } @@ -1186,10 +1180,7 @@ class WeaponAndProjectileOperations( used by ReloadMessage handling */ def reloadPlayerMessages(itemGuid: PlanetSideGUID): Unit = { - continent.AvatarEvents ! AvatarServiceMessage( - sessionLogic.zoning.zoneChannel, - AvatarAction.Reload(player.GUID, itemGuid) - ) + continent.AvatarEvents ! AvatarServiceMessage(sessionLogic.zoning.zoneChannel, player.GUID, AvatarAction.Reload(itemGuid)) } def reloadVehicleMessages(itemGuid: PlanetSideGUID): Unit = { @@ -1371,8 +1362,8 @@ class WeaponAndProjectileOperations( sendResponse(ChangeAmmoMessage(tool_guid, box.Capacity)) continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, + player.GUID, AvatarAction.ChangeAmmo( - player.GUID, tool_guid, ammoSlotIndex, previous_box_guid, @@ -1582,10 +1573,7 @@ class WeaponAndProjectileOperations( shootingStop.clear() (prefire ++ shooting).foreach { guid => sendResponse(ChangeFireStateMessage_Stop(guid)) - continent.AvatarEvents ! AvatarServiceMessage( - continent.id, - AvatarAction.ChangeFireState_Stop(player.GUID, guid) - ) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.ChangeFireState_Stop(guid)) } prefire.clear() shooting.clear() diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 0b8e5924f..d3af7943b 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -22,6 +22,7 @@ import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, Reconstr import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage} +import net.psforever.services.avatar.{CorpseEnvelope, ReleaseMessage} import net.psforever.services.chat.DefaultChannel import scala.concurrent.duration._ @@ -2637,7 +2638,8 @@ class ZoningOperations( sendResponse(OCM.detailed(player)) continent.AvatarEvents ! AvatarServiceMessage( s"spectator", - AvatarAction.LoadPlayer(guid, definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None) + guid, + AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None) ) case _ => @@ -2648,7 +2650,8 @@ class ZoningOperations( sendResponse(OCM.detailed(player)) continent.AvatarEvents ! AvatarServiceMessage( zoneid, - AvatarAction.LoadPlayer(guid, definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None) + guid, + AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None) ) } continent.Population ! Zone.Population.Spawn(avatar, player, avatarActor) @@ -2720,8 +2723,8 @@ class ZoningOperations( } continent.AvatarEvents ! AvatarServiceMessage( continent.id, + pguid, AvatarAction.LoadPlayer( - pguid, pdef.ObjectId, pguid, pdef.Packet.ConstructorData(tplayer).get, @@ -2879,7 +2882,7 @@ class ZoningOperations( if (player.VisibleSlots.contains(index)) { events ! AvatarServiceMessage( zoneId, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, obj.GUID) + AvatarAction.ObjectDelete(obj.GUID) ) } else { sendResponse(ObjectDeleteMessage(obj.GUID, 0)) @@ -2913,7 +2916,7 @@ class ZoningOperations( val pguid = tplayer.GUID zone.Population ! Zone.Population.Release(avatar) sendResponse(ObjectDeleteMessage(pguid, 0)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(pguid, pguid)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, pguid, AvatarAction.ObjectDelete(pguid)) TaskWorkflow.execute(GUIDTask.unregisterPlayer(zone.GUID, tplayer)) } } @@ -2936,7 +2939,7 @@ class ZoningOperations( tplayer.Release DepictPlayerAsCorpse(tplayer) zone.Population ! Zone.Corpse.Add(tplayer) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.Release(tplayer, zone)) + zone.AvatarEvents ! ReleaseMessage(zone.id, AvatarAction.Release(tplayer, zone)) } /** @@ -2975,7 +2978,7 @@ class ZoningOperations( */ def TryDisposeOfLootedCorpse(obj: Player): Boolean = { if (obj.isBackpack && WellLootedDeadBody(obj)) { - obj.Zone.AvatarEvents ! AvatarServiceMessage.Corpse(RemoverActor.HurrySpecific(List(obj), obj.Zone)) + obj.Zone.AvatarEvents ! CorpseEnvelope(RemoverActor.HurrySpecific(List(obj), obj.Zone)) true } else { false @@ -3171,7 +3174,8 @@ class ZoningOperations( sendResponse(ObjectDeleteMessage(player_guid, unk1=effect)) continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.ObjectDelete(player_guid, player_guid, unk=effect) + player_guid, + AvatarAction.ObjectDelete(player_guid, unk=effect) ) InGameHistory.SpawnReconstructionActivity(player, toZoneNumber, betterSpawnPoint) LoadZoneAsPlayerUsing(player, pos, ori, toSide, zoneId) @@ -3335,7 +3339,7 @@ class ZoningOperations( //looking for squad (members) if (tplayer.avatar.lookingForSquad) { sendResponse(PlanetsideAttributeMessage(guid, 53, 1)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.PlanetsideAttribute(guid, 53, 1)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, guid, AvatarAction.PlanetsideAttribute(53, 1)) } sendResponse(AvatarSearchCriteriaMessage(guid, List(0, 0, 0, 0, 0, 0))) //these are facilities and towers and bunkers in the zone, but not necessarily all of them for some reason @@ -3361,7 +3365,7 @@ class ZoningOperations( if (tplayer.ExoSuit == ExoSuitType.MAX) { sendResponse(PlanetsideAttributeMessage(guid, 7, tplayer.Capacitor.toLong)) sendResponse(PlanetsideAttributeMessage(guid, 4, tplayer.Armor)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.PlanetsideAttributeToAll(guid, 4, tplayer.Armor)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, guid, AvatarAction.PlanetsideAttributeToAll(4, tplayer.Armor)) } // for issue #1269 continent.AllPlayers.filter(_.ExoSuit == ExoSuitType.MAX).foreach(max => sendResponse(PlanetsideAttributeMessage(max.GUID, 4, max.Armor))) @@ -3484,14 +3488,8 @@ class ZoningOperations( case Some(b: Building) if b.hasCavernLockBenefit => tplayer.MaxHealth = 120 tplayer.Health = 120 - tplayer.Zone.AvatarEvents ! AvatarServiceMessage( - tplayer.Zone.id, - AvatarAction.PlanetsideAttributeToAll(tplayer.GUID, 0, 120) - ) - tplayer.Zone.AvatarEvents ! AvatarServiceMessage( - tplayer.Zone.id, - AvatarAction.PlanetsideAttributeToAll(tplayer.GUID, 1, 120) - ) + tplayer.Zone.AvatarEvents ! AvatarServiceMessage(tplayer.Zone.id, tplayer.GUID, AvatarAction.PlanetsideAttributeToAll(0, 120)) + tplayer.Zone.AvatarEvents ! AvatarServiceMessage(tplayer.Zone.id, tplayer.GUID, AvatarAction.PlanetsideAttributeToAll(1, 120)) case _ => () } doorsThatShouldBeOpenInRange(pos, range = 100f) diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index c90579c55..85ba63316 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -205,7 +205,7 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.UnderAttack) => val events = zone.AvatarEvents val guid = building.GUID - val msg = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, guid, 15) + val msg = AvatarAction.GenericObjectAction(guid, 15) building.PlayersInSOI.foreach { player => events ! AvatarServiceMessage(player.Name, msg) } @@ -213,15 +213,15 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.Critical) => val events = zone.AvatarEvents val guid = building.GUID - val msg = AvatarAction.PlanetsideAttributeToAll(guid, 46, 1) + val msg = AvatarAction.PlanetsideAttributeToAll(46, 1) building.PlayersInSOI.foreach { player => - events ! AvatarServiceMessage(player.Name, msg) + events ! AvatarServiceMessage(player.Name, guid, msg) } true case Some(GeneratorControl.Event.Destabilized) => val events = zone.AvatarEvents val guid = building.GUID - val msg = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, guid, 16) + val msg = AvatarAction.GenericObjectAction(guid, 16) building.PlayersInSOI.foreach { player => events ! AvatarServiceMessage(player.Name, msg) } @@ -237,9 +237,9 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.Offline) => powerLost(details) val zone = building.Zone - val msg = AvatarAction.PlanetsideAttributeToAll(building.GUID, 46, 2) + val msg = AvatarAction.PlanetsideAttributeToAll(46, 2) building.PlayersInSOI.foreach { player => - zone.AvatarEvents ! AvatarServiceMessage(player.Name, msg) + zone.AvatarEvents ! AvatarServiceMessage(player.Name, building.GUID, msg) } //??? true case Some(GeneratorControl.Event.Normal) => @@ -249,11 +249,11 @@ case object MajorFacilityLogic powerRestored(details) val events = zone.AvatarEvents val guid = building.GUID - val msg1 = AvatarAction.PlanetsideAttributeToAll(guid, 46, 0) - val msg2 = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, guid, 17) + val msg1 = AvatarAction.PlanetsideAttributeToAll(46, 0) + val msg2 = AvatarAction.GenericObjectAction(guid, 17) building.PlayersInSOI.foreach { player => val name = player.Name - events ! AvatarServiceMessage(name, msg1) //reset ???; might be global? + events ! AvatarServiceMessage(name, guid, msg1) //reset ???; might be global? events ! AvatarServiceMessage(name, msg2) //This facility's generator is back on line } true @@ -306,9 +306,9 @@ case object MajorFacilityLogic amenity.Actor ! powerMsg } //amenities disabled; red warning lights - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 48, 1)) + events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(48, 1)) //disable spawn target on deployment map - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 38, 0)) + events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(38, 0)) Behaviors.same } @@ -329,9 +329,9 @@ case object MajorFacilityLogic amenity.Actor ! powerMsg } //amenities enabled; normal lights - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 48, 0)) + events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(48, 0)) //enable spawn target on deployment map - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 38, 1)) + events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(38, 1)) Behaviors.same } diff --git a/src/main/scala/net/psforever/login/WorldSession.scala b/src/main/scala/net/psforever/login/WorldSession.scala index e24360396..1cc61d0ba 100644 --- a/src/main/scala/net/psforever/login/WorldSession.scala +++ b/src/main/scala/net/psforever/login/WorldSession.scala @@ -326,10 +326,7 @@ object WorldSession { case _ => forcedTolowerRaisedArm(localPlayer, localPlayer.GUID, localZone) localPlayer.DrawnSlot = localSlot - localZone.AvatarEvents ! AvatarServiceMessage( - localZone.id, - AvatarAction.ObjectHeld(localGUID, localSlot, localSlot) - ) + localZone.AvatarEvents ! AvatarServiceMessage(localZone.id, localGUID, AvatarAction.ObjectHeld(localSlot, localSlot)) } Future(this) } @@ -370,10 +367,7 @@ object WorldSession { localZone.GUID(item_guid) match { case Some(_) => () case None => //acting on old data? - localZone.AvatarEvents ! AvatarServiceMessage( - localZone.id, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item_guid) - ) + localZone.AvatarEvents ! AvatarServiceMessage(localZone.id, AvatarAction.ObjectDelete(item_guid)) } case _ => () } @@ -597,10 +591,7 @@ object WorldSession { localGUID match { case Some(guid) => //see LockerContainerControl.RemoveItemFromSlotCallback - localSource.Zone.AvatarEvents ! AvatarServiceMessage( - localChannel, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid) - ) + localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, AvatarAction.ObjectDelete(guid)) case None => () } val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot))) @@ -702,10 +693,7 @@ object WorldSession { localGUID match { case Some(guid) => //see LockerContainerControl.RemoveItemFromSlotCallback - localSource.Zone.AvatarEvents ! AvatarServiceMessage( - localChannel, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid) - ) + localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, AvatarAction.ObjectDelete(guid)) case None => () } val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot))) @@ -795,10 +783,7 @@ object WorldSession { } //put up hand with grenade in it tplayer.DrawnSlot = slotNum - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.ObjectHeld(guid, slotNum, slotNum) - ) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, guid, AvatarAction.ObjectHeld(slotNum, slotNum)) log.info(s"${tplayer.Name} has quickly drawn a ${grenade.Definition.Name}") None case None => @@ -885,10 +870,7 @@ object WorldSession { val slot = tplayer.DrawnSlot if (slot != Player.HandsDownSlot) { tplayer.DrawnSlot = Player.HandsDownSlot - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.ObjectHeld(guid, Player.HandsDownSlot, slot) - ) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, guid, AvatarAction.ObjectHeld(Player.HandsDownSlot, slot)) true } else { false diff --git a/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/src/main/scala/net/psforever/objects/BoomerDeployable.scala index 6cf03ddb6..70daf0990 100644 --- a/src/main/scala/net/psforever/objects/BoomerDeployable.scala +++ b/src/main/scala/net/psforever/objects/BoomerDeployable.scala @@ -109,7 +109,7 @@ class BoomerDeployableControl(mine: BoomerDeployable) } zone.AvatarEvents! AvatarServiceMessage( zone.id, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid) + AvatarAction.ObjectDelete(guid) ) TaskWorkflow.execute(GUIDTask.unregisterObject(zone.GUID, trigger)) case None => () diff --git a/src/main/scala/net/psforever/objects/Players.scala b/src/main/scala/net/psforever/objects/Players.scala index 720a84728..c36d0e3fa 100644 --- a/src/main/scala/net/psforever/objects/Players.scala +++ b/src/main/scala/net/psforever/objects/Players.scala @@ -50,7 +50,7 @@ object Players { val uname = user.Name events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse(Service.defaultPlayerGUID, RepairMessage(target.GUID, progress.toInt)) + AvatarAction.SendResponse(RepairMessage(target.GUID, progress.toInt)) ) true } else { @@ -61,7 +61,7 @@ object Players { /** * na * @see `AvatarAction.Revive` - * @see `AvatarResponse.Revive` + * @see `AvatarAction.Revive` * @param target the player being revived * @param medic the name of the player doing the reviving * @param item the tool being used to revive the target player @@ -76,12 +76,12 @@ object Players { PlayerControl.sendResponse( target.Zone, medicName, + Service.defaultPlayerGUID, AvatarAction.SendResponse( - Service.defaultPlayerGUID, InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine) ) ) - PlayerControl.sendResponse(target.Zone, name, AvatarAction.Revive(target.GUID)) + PlayerControl.sendResponse(target.Zone, name, Service.defaultPlayerGUID, AvatarAction.Revive(target.GUID)) } /** @@ -347,10 +347,7 @@ object Players { */ def buildCooldownReset(zone: Zone, channel: String, guid: PlanetSideGUID): Unit = { //sent to avatar event bus to preempt additional tool management - zone.AvatarEvents ! AvatarServiceMessage( - channel, - AvatarAction.SendResponse(Service.defaultPlayerGUID, GenericObjectActionMessage(guid, 21)) - ) + zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.SendResponse(GenericObjectActionMessage(guid, 21))) } /** @@ -406,10 +403,7 @@ object Players { } }) { val zone = player.Zone - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, tool.GUID) - ) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(tool.GUID)) true } else { false @@ -449,21 +443,18 @@ object Players { //TODO any penalty for being handed an OCM version of the tool? events ! AvatarServiceMessage( zone.id, - AvatarAction.EquipmentInHand(Service.defaultPlayerGUID, pguid, index, obj) + AvatarAction.EquipmentInHand(pguid, index, obj) ) if (obj.AmmoTypeIndex != ammoType) { obj.AmmoTypeIndex = ammoType events ! AvatarServiceMessage( name, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ChangeAmmoMessage(obj.GUID, ammoType)) + AvatarAction.SendResponse(ChangeAmmoMessage(obj.GUID, ammoType)) ) } if (player.DrawnSlot == Player.HandsDownSlot) { player.DrawnSlot = index - events ! AvatarServiceMessage( - zone.id, - AvatarAction.ObjectHeld(pguid, index, index) - ) + events ! AvatarServiceMessage(zone.id, pguid, AvatarAction.ObjectHeld(index, index)) } } case Nil => ; //no replacements found diff --git a/src/main/scala/net/psforever/objects/Tools.scala b/src/main/scala/net/psforever/objects/Tools.scala index 6744550b3..7931799b1 100644 --- a/src/main/scala/net/psforever/objects/Tools.scala +++ b/src/main/scala/net/psforever/objects/Tools.scala @@ -24,10 +24,7 @@ object Tools { val magazine = tool.Magazine -= mode.RoundsPerInterval player.Zone.AvatarEvents ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine) - ) + AvatarAction.SendResponse(QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine)) ) player.isAlive case _ => diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 019f4d7f2..d260db95d 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.transfer.TransferContainer import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vehicles._ import net.psforever.objects.zones.Zone -import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} +import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} @@ -169,7 +169,8 @@ object Vehicles { (0 to 3).foreach(group => { vehicle.Zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.PlanetsideAttributeToAll(vehicle_guid, group + 10, vehicle.PermissionGroup(group).get.id) + vehicle_guid, + AvatarAction.PlanetsideAttributeToAll(group + 10, vehicle.PermissionGroup(group).get.id) ) }) } @@ -313,7 +314,7 @@ object Vehicles { // And broadcast the faction change to other clients zone.AvatarEvents ! AvatarServiceMessage( zoneid, - AvatarAction.SetEmpire(Service.defaultPlayerGUID, tGuid, hFaction) + AvatarAction.SetEmpire(tGuid, hFaction) ) } localEvents ! LocalServiceMessage( diff --git a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala index 6e1cafafe..2952ec1ba 100644 --- a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala @@ -27,7 +27,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { case Some(slot) => obj.Zone.AvatarEvents ! AvatarServiceMessage( player.Zone.id, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ObjectAttachMessage(obj.GUID, item.GUID, slot)) + AvatarAction.SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) case None => ; } @@ -40,7 +40,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val zone = obj.Zone val events = zone.AvatarEvents item.Faction = PlanetSideEmpire.NEUTRAL - events ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID)) + events ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -51,7 +51,6 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { events ! AvatarServiceMessage( zone.id, AvatarAction.SendResponse( - Service.defaultPlayerGUID, ObjectCreateDetailedMessage( definition.ObjectId, item.GUID, @@ -67,10 +66,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val zone = obj.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f) - ) + AvatarAction.SendResponse(ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f)) ) } } diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index d597ea565..4d74a78d4 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -36,6 +36,7 @@ import net.psforever.objects.vital.collision.CollisionReason import net.psforever.objects.vital.etc.{PainboxReason, SuicideReason} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.PlanetSideGamePacket +import net.psforever.services.base.EventMessage import org.joda.time.{LocalDateTime, Seconds} import scala.concurrent.duration._ @@ -125,7 +126,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val zoneId = zone.id sendResponse(zone, zoneId, PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health)) sendResponse(zone, zoneId, AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) - sendResponse(zone, zoneId, AvatarAction.PlanetsideAttributeToAll(revivalTargetGuid, attribute_type=0, health)) + sendResponse(zone, zoneId, revivalTargetGuid, AvatarAction.PlanetsideAttributeToAll(attribute_type=0, health)) avatarActor ! AvatarActor.InitializeImplants avatarActor ! AvatarActor.SuspendStaminaRegeneration(Duration(1, "second")) @@ -149,12 +150,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val magazine = item.Discharge() events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong) - ) + AvatarAction.SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) - events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 0, newHealth)) + events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) player.LogActivity( HealFromEquipment( PlayerSource(user), @@ -174,14 +172,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } if (player != user) { //"Someone is trying to heal you" - events ! AvatarServiceMessage(player.Name, AvatarAction.PlanetsideAttributeToAll(guid, 55, 1)) + events ! AvatarServiceMessage(player.Name, guid, AvatarAction.PlanetsideAttributeToAll(55, 1)) //progress bar remains visible for all heal attempts events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - RepairMessage(guid, player.Health * 100 / definition.MaxHealth) - ) + AvatarAction.SendResponse(RepairMessage(guid, player.Health * 100 / definition.MaxHealth)) ) } } @@ -221,12 +216,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val magazine = item.Discharge() events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong) - ) + AvatarAction.SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) - events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 4, player.Armor)) + events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(4, player.Armor)) player.LogActivity( RepairFromEquipment( PlayerSource(user), @@ -247,7 +239,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (player != user) { if (player.isAlive) { //"Someone is trying to repair you" gets strobed twice for visibility - val msg = AvatarServiceMessage(player.Name, AvatarAction.PlanetsideAttributeToAll(guid, 56, 1)) + val msg = AvatarServiceMessage(player.Name, guid, AvatarAction.PlanetsideAttributeToAll(56, 1)) events ! msg import scala.concurrent.ExecutionContext.Implicits.global context.system.scheduler.scheduleOnce(250 milliseconds, events, msg) @@ -255,8 +247,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //progress bar remains visible for all repair attempts events ! AvatarServiceMessage( uname, - AvatarAction - .SendResponse(Service.defaultPlayerGUID, RepairMessage(guid, player.Armor * 100 / player.MaxArmor)) + AvatarAction.SendResponse(RepairMessage(guid, player.Armor * 100 / player.MaxArmor)) ) } } @@ -323,7 +314,8 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, kit)) zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttributeToAll(player.GUID, attribute, value) + player.GUID, + AvatarAction.PlanetsideAttributeToAll(attribute, value) ) zone.AvatarEvents ! AvatarServiceMessage( player.Name, @@ -346,13 +338,15 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (resistance && !updateMyHolsterArm) { events ! AvatarServiceMessage( player.Name, - AvatarAction.ObjectHeld(player.GUID, before, -1) + player.GUID, + AvatarAction.ObjectHeld(before, -1) ) } else if ((!resistance && before != slot && (player.DrawnSlot = slot) != before) && ItemSwapSlot != before) { val mySlot = if (updateMyHolsterArm) slot else -1 //use as a short-circuit events ! AvatarServiceMessage( Players.ZoneChannelIfSpectating(player), - AvatarAction.ObjectHeld(player.GUID, mySlot, player.LastDrawnSlot) + player.GUID, + AvatarAction.ObjectHeld(mySlot, player.LastDrawnSlot) ) val isHolsters = player.VisibleSlots.contains(slot) val equipment = player.Slot(slot).Equipment.orElse { player.Slot(before).Equipment } @@ -364,7 +358,8 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //rek beam/icon colour must match the player's correct hack level events ! AvatarServiceMessage( Players.ZoneChannelIfSpectating(player), - AvatarAction.PlanetsideAttribute(unholsteredItem.GUID, 116, player.avatar.hackingSkillLevel()) + unholsteredItem.GUID, + AvatarAction.PlanetsideAttribute(116, player.avatar.hackingSkillLevel()) ) } case None => () @@ -579,7 +574,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (reason.startsWith("@")) { player.Zone.AvatarEvents ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_227, reason)) + AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, reason)) ) } @@ -597,7 +592,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val trigger = new BoomerTrigger trigger.Companion = obj.GUID obj.Trigger = trigger - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, tool.GUID)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(tool.GUID)) TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, tool)) player.Find(tool) match { case Some(index) if player.VisibleSlots.contains(index) => @@ -885,7 +880,8 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttributeToAll(target.GUID, 4, target.Armor) + target.GUID, + AvatarAction.PlanetsideAttributeToAll(4, target.Armor) ) } //choose @@ -941,10 +937,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm target.LogActivity(cause) //stat changes if (damageToCapacitor > 0) { - events ! AvatarServiceMessage( - target.Name, - AvatarAction.PlanetsideAttributeSelf(targetGUID, 7, target.Capacitor.toLong) - ) + events ! AvatarServiceMessage(target.Name, targetGUID, AvatarAction.PlanetsideAttributeSelf(7, target.Capacitor.toLong)) announceConfrontation = true //TODO should we? } if (damageToStamina > 0) { @@ -952,7 +945,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm announceConfrontation = true //TODO should we? } if (damageToHealth > 0) { - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 0, health)) + events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(0, health)) announceConfrontation = true } val countableDamage = damageToHealth + damageToArmor @@ -960,7 +953,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (aggravated) { events ! AvatarServiceMessage( zoneId, - AvatarAction.SendResponse(Service.defaultPlayerGUID, AggravatedDamageMessage(targetGUID, countableDamage)) + AvatarAction.SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) ) } else { //activity on map @@ -975,24 +968,19 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case Some(tplayer) => zone.AvatarEvents ! AvatarServiceMessage( target.Name, - AvatarAction.HitHint(tplayer.GUID, target.GUID) + target.GUID, + AvatarAction.HitHint(tplayer.GUID) ) case None => zone.AvatarEvents ! AvatarServiceMessage( target.Name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - DamageWithPositionMessage(countableDamage, pSource.Position) - ) + AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) ) } case source => zone.AvatarEvents ! AvatarServiceMessage( target.Name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - DamageWithPositionMessage(countableDamage, source.Position) - ) + AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) ) } case None => @@ -1005,7 +993,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case _: CollisionReason => events ! AvatarServiceMessage( zoneId, - AvatarAction.SendResponse(Service.defaultPlayerGUID, AggravatedDamageMessage(targetGUID, countableDamage)) + AvatarAction.SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) ) case _ => zone.AvatarEvents ! AvatarServiceMessage( @@ -1064,19 +1052,16 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm damageLog.info(s"${player.Name} killed ${player.Sex.pronounObject}self") } - events ! AvatarServiceMessage(nameChannel, AvatarAction.Killed(player_guid, cause, target.VehicleSeated)) //align client interface fields with state - events ! AvatarServiceMessage(zoneChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 0, 0)) //health + events ! AvatarServiceMessage(nameChannel, player_guid, AvatarAction.Killed(cause, target.VehicleSeated)) //align client interface fields with state + events ! AvatarServiceMessage(zoneChannel, player_guid, AvatarAction.PlanetsideAttributeToAll(0, 0)) //health if (target.Capacitor > 0) { target.Capacitor = 0 - events ! AvatarServiceMessage(nameChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 7, 0)) // capacitor + events ! AvatarServiceMessage(nameChannel, player_guid, AvatarAction.PlanetsideAttributeToAll(7, 0)) // capacitor } val attribute = DamageableEntity.attributionTo(cause, target.Zone, player_guid) events ! AvatarServiceMessage( nameChannel, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos) - ) //how many players get this message? + AvatarAction.SendResponse(DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos)) //how many players get this message? ) } @@ -1107,10 +1092,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case obj: Player if !jammedSound => obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Zone.id, - AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 1) + obj.GUID, + AvatarAction.PlanetsideAttributeToAll(27, 1) ) super.StartJammeredSound(obj, 3000) - case _ => ; + case _ => () } /** @@ -1143,10 +1129,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case obj: Player if jammedSound => obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Zone.id, - AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 0) + obj.GUID, + AvatarAction.PlanetsideAttributeToAll(27, 0) ) super.CancelJammeredSound(obj) - case _ => ; + case _ => () } def RepairToolValue(item: Tool): Float = { @@ -1167,9 +1154,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm obj.Find(item) match { case Some(slot) => PutItemInSlotCallback(item, slot) - case None => ; + case None => () } - case _ => ; + case _ => () } } @@ -1188,7 +1175,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (slot == obj.DrawnSlot) { obj.DrawnSlot = Player.HandsDownSlot } - events ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID)) + events ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -1209,10 +1196,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case Some(obj: BoomerDeployable) => val deployables = player.avatar.deployables if (!deployables.Contains(obj) && deployables.Valid(obj)) { - events ! AvatarServiceMessage(toChannel, AvatarAction.SendResponse( - Service.defaultPlayerGUID, - GenericObjectAction2Message(1, player.GUID, trigger.GUID) - )) + events ! AvatarServiceMessage( + toChannel, + AvatarAction.SendResponse(GenericObjectAction2Message(1, player.GUID, trigger.GUID)) + ) Players.gainDeployableOwnership(player, obj, deployables.AddOverLimit) } case _ => () @@ -1230,13 +1217,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } events ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - OCM.detailed(item, ObjectCreateMessageParent(guid, slot)) - ) + AvatarAction.SendResponse(OCM.detailed(item, ObjectCreateMessageParent(guid, slot))) ) if (!player.isBackpack && willBeVisible) { - events ! AvatarServiceMessage(zone.id, AvatarAction.EquipmentInHand(guid, guid, slot, item)) + events ! AvatarServiceMessage(zone.id, guid, AvatarAction.EquipmentInHand(guid, slot, item)) } } @@ -1252,7 +1236,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID) + AvatarAction.ObjectDelete(item.GUID) ) } @@ -1260,7 +1244,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} val zone = target.Zone val value = target.Aura.foldLeft(0)(_ + PlayerControl.auraEffectToAttributeValue(_)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(target.GUID, 54, value)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, target.GUID, AvatarAction.PlanetsideAttributeToAll(54, value)) } } @@ -1290,11 +1274,11 @@ object PlayerControl { } def sendResponse(zone: Zone, channel: String, msg: PlanetSideGamePacket): Unit = { - zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.SendResponse(Service.defaultPlayerGUID, msg)) + zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.SendResponse(msg)) } - def sendResponse(zone: Zone, channel: String, msg: AvatarAction.Action): Unit = { - zone.AvatarEvents ! AvatarServiceMessage(channel, msg) + def sendResponse(zone: Zone, channel: String, filter: PlanetSideGUID, msg: EventMessage): Unit = { + zone.AvatarEvents ! AvatarServiceMessage(channel, filter, msg) } def maxRestriction(player: Player, slot: Int): Boolean = { diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala index 4e15faf4f..16d51f2a9 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala @@ -100,7 +100,7 @@ class WithEntrance() if (door.Outwards == Vector3.Zero) { obj.Zone.AvatarEvents ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(PlanetSideGUID(0), ChatMsg(ChatMessageType.UNK_229, "Door not configured.")) + AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_229, "Door not configured.")) ) WhichSide } else { @@ -109,14 +109,14 @@ class WithEntrance() //outside obj.Zone.AvatarEvents ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(PlanetSideGUID(0), ChatMsg(ChatMessageType.UNK_229, "You are now outside")) + AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now outside")) ) Sidedness.OutsideOf } else if (!result && WhichSide != Sidedness.InsideOf) { //inside obj.Zone.AvatarEvents ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(PlanetSideGUID(0), ChatMsg(ChatMessageType.UNK_229, "You are now inside")) + AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now inside")) ) Sidedness.InsideOf } else { diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala index 09d4a330a..2be15ee38 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala @@ -37,16 +37,10 @@ class WithGantry(val channel: String) val events = shuttle.Zone.AvatarEvents events ! AvatarServiceMessage( channel, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - PlayerStateShiftMessage(ShiftState(0, pos, ang, None))) - ) + AvatarAction.SendResponse(PlayerStateShiftMessage(ShiftState(0, pos, ang, None)))) events ! AvatarServiceMessage( channel, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway") - ) + AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway")) ) case (Some(_: Vehicle) , _)=> obj.Actor ! RespondsToZoneEnvironment.Timer( diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index fbdfa85ca..b88d6f3dd 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -288,7 +288,7 @@ object DeployableBehavior { //visual tells in regards to ownership by faction zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SetEmpire(Service.defaultPlayerGUID, dGuid, toFaction) + AvatarAction.SetEmpire(dGuid, toFaction) ) //remove knowledge by the previous owner's faction localEvents ! LocalServiceMessage( diff --git a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala index 67eab42f8..c7a8c2e03 100644 --- a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala +++ b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala @@ -36,7 +36,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) case Some(slot) => obj.Zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ObjectAttachMessage(obj.GUID, item.GUID, slot)) + AvatarAction.SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) case None => ; } @@ -46,7 +46,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) def RemoveItemFromSlotCallback(item: Equipment, slot: Int): Unit = { val zone = locker.Zone - zone.AvatarEvents ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID)) + zone.AvatarEvents ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -56,7 +56,6 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) zone.AvatarEvents ! AvatarServiceMessage( toChannel, AvatarAction.SendResponse( - Service.defaultPlayerGUID, ObjectCreateDetailedMessage( definition.ObjectId, item.GUID, @@ -71,10 +70,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) val zone = locker.Zone zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f) - ) + AvatarAction.SendResponse(ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala index b9369c38a..3e936c25a 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala @@ -36,7 +36,7 @@ object DamageableAmenity { val zoneId = zone.id val events = zone.AvatarEvents val targetGUID = target.GUID - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 50, 1)) - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 51, 1)) + events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(50, 1)) + events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(51, 1)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala index e594de2db..f016155ca 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala @@ -167,7 +167,8 @@ object DamageableEntity { val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttributeToAll(target.GUID, 0, target.Health) + target.GUID, + AvatarAction.PlanetsideAttributeToAll(0, target.Health) ) true } @@ -199,7 +200,7 @@ object DamageableEntity { val zoneId = zone.id val tguid = target.GUID val attribution = attributionTo(cause, target.Zone) - zone.AvatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 0, target.Health)) + zone.AvatarEvents ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(0, target.Health)) if (target.isInstanceOf[SpawnTube]) {}//do nothing to prevent issue #1057 else { zone.AvatarEvents ! AvatarServiceMessage( diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala index 2356fb11b..c6b82c496 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala @@ -45,23 +45,23 @@ object DamageableMountable { val name = pSource.Name (zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match { case Some(player) => - AvatarAction.HitHint(player.GUID, player.GUID) + AvatarAction.HitHint(player.GUID) case None => - AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(countableDamage, pSource.Position)) + AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) }) match { - case AvatarAction.HitHint(_, guid) => - occupants.map { tplayer => (tplayer.Name, AvatarAction.HitHint(guid, tplayer.GUID)) } + case AvatarAction.HitHint(guid) => + occupants.map { tplayer => (tplayer.Name, guid, AvatarAction.HitHint(tplayer.GUID)) } case msg => - occupants.map { tplayer => (tplayer.Name, msg) } + occupants.map { tplayer => (tplayer.Name, Service.defaultPlayerGUID, msg) } } case Some(source) => //object damage - val msg = AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(countableDamage, source.Position)) - occupants.map { tplayer => (tplayer.Name, msg) } + val msg = AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) + occupants.map { tplayer => (tplayer.Name, Service.defaultPlayerGUID, msg) } case None => List.empty }).foreach { - case (channel, msg) => - events ! AvatarServiceMessage(channel, msg) + case (channel, filter, msg) => + events ! AvatarServiceMessage(channel, filter, msg) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index bef9a243a..6900ea938 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -131,7 +131,7 @@ object DamageableWeaponTurret { } .foreach(slot => { val wep = slot.Equipment.get - avatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID)) + avatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.ObjectDelete(wep.GUID)) }) target match { case turret: WeaponTurret => diff --git a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala index a7b0c78d5..9e78167d7 100644 --- a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala @@ -113,10 +113,7 @@ class GeneratorControl(gen: Generator) //kaboom zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - TriggerEffectMessage(gen.GUID, "explosion_generator", None, None) - ) + AvatarAction.SendResponse(TriggerEffectMessage(gen.GUID, "explosion_generator", None, None)) ) queuedExplosion.cancel() queuedExplosion = Default.Cancellable diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index b52f4afd6..f896bd655 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -91,7 +91,6 @@ object GenericHackables { target.Zone.AvatarEvents ! AvatarServiceMessage( hacker.Name, AvatarAction.SendResponse( - Service.defaultPlayerGUID, HackMessage(progressType, target.GUID, hacker.GUID, progressGrade, 0L, progressState, HackState7.Unk8) ) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala index 1042acfe4..038f894b1 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala @@ -37,8 +37,8 @@ object RepairableAmenity { val zoneId = zone.id val events = zone.AvatarEvents val targetGUID = target.GUID - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 50, 0)) - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 51, 0)) + events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(50, 0)) + events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(51, 0)) RestorationOfHistory(target) } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index 232a3c8c5..e5a66a778 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -91,10 +91,7 @@ trait RepairableEntity extends Repairable { val magazine = item.Discharge() events ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong) - ) + AvatarAction.SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) target.LogActivity( RepairFromEquipment( @@ -110,10 +107,7 @@ trait RepairableEntity extends Repairable { //progress bar remains visible events ! AvatarServiceMessage( name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth) - ) + AvatarAction.SendResponse(RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth)) ) //if vehicle and vehicle is owned by another player, send repair chat message to the vehicle's owner if (target.Zone.Vehicles.exists(_.GUID == target.GUID)) { @@ -146,11 +140,11 @@ trait RepairableEntity extends Repairable { val newHealth = target.Health = target.Health + amount if (target.Destroyed) { if (newHealth >= target.Definition.RepairRestoresAt) { - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 0, newHealth)) + events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) Restoration(target) } } else { - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 0, newHealth)) + events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) } newHealth } diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 996b4d876..7e94f947f 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -108,7 +108,8 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val zone = building.Zone building.Zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttribute(building.GUID, 47, if (resourceSilo.LowNtuWarningOn) 1 else 0) + building.GUID, + AvatarAction.PlanetsideAttribute(47, if (resourceSilo.LowNtuWarningOn) 1 else 0) ) } @@ -131,7 +132,8 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) ) zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay) + resourceSilo.GUID, + AvatarAction.PlanetsideAttribute(45, resourceSilo.CapacitorDisplay) ) building.Actor ! BuildingActor.MapUpdate() } diff --git a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala index 7173f5990..f1dc0404e 100644 --- a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala @@ -193,7 +193,6 @@ object OrbitalShuttlePadControl { zone.AvatarEvents ! AvatarServiceMessage( p.Name, AvatarAction.SendResponse( - Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_225, wideContents=false, "", "@DoorWillOpenWhenShuttleReturns", None) ) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index a4962f5a9..2444eb248 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -109,8 +109,8 @@ trait FacilityHackParticipation extends ParticipationLogic { import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} val mainTerm = building.Amenities.filter(x => x.isInstanceOf[Terminal] && x.Definition == GlobalDefinitions.main_terminal).head.GUID - val msg1 = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, mainTerm, 61) - val msg2 = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, mainTerm, 58) + val msg1 = AvatarAction.GenericObjectAction(mainTerm, 61) + val msg2 = AvatarAction.GenericObjectAction(mainTerm, 58) val events = building.Zone.AvatarEvents list.foreach { p => events ! AvatarServiceMessage(p.Name, msg1) diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index b26f1d617..7e3cdae59 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -349,7 +349,8 @@ object ProximityTerminalControl { target.MaxHealth = newMax zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttributeToAll(target.GUID, 1, newMax) + target.GUID, + AvatarAction.PlanetsideAttributeToAll(1, newMax) ) } if (target.Health < newMax) { @@ -364,7 +365,8 @@ object ProximityTerminalControl { val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttributeToAll(target.GUID, 0, target.Health) + target.GUID, + AvatarAction.PlanetsideAttributeToAll(0, target.Health) ) } @@ -403,7 +405,8 @@ object ProximityTerminalControl { val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.PlanetsideAttributeToAll(target.GUID, 4, target.Armor) + target.GUID, + AvatarAction.PlanetsideAttributeToAll(4, target.Armor) ) target.Armor == maxArmor } else { @@ -432,7 +435,7 @@ object ProximityTerminalControl { slots.foreach { slot => events ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(Service.defaultPlayerGUID, InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) + AvatarAction.SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala index 2212a67ea..5b38b2254 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala @@ -39,8 +39,8 @@ trait TurretControl val zoneId = zone.id val events = zone.AvatarEvents val tguid = TurretObject.GUID - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 50, 0)) - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 51, 0)) + events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(50, 0)) + events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(51, 0)) } /** @@ -56,7 +56,7 @@ trait TurretControl val tguid = target.GUID CancelJammeredSound(target) CancelJammeredStatus(target) - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 50, 1)) - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 51, 1)) + events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(50, 1)) + events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(51, 1)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index 03b8925ae..d223c4c56 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -33,7 +33,7 @@ object WeaponTurrets { tool.Magazine = 0 target.Zone.AvatarEvents ! AvatarServiceMessage( user.Name, - AvatarAction.SendResponse(Service.defaultPlayerGUID, InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0)) + AvatarAction.SendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0)) ) FinishUpgradingMannedTurret(target, upgrade) } @@ -88,7 +88,6 @@ object WeaponTurrets { turret.Zone.AvatarEvents ! AvatarServiceMessage( tplayer.Name, AvatarAction.SendResponse( - Service.defaultPlayerGUID, HackMessage(progressType, turret.GUID, tplayer.GUID, progressGrade, -1f, progressState, HackState7.Unk8) ) ) @@ -118,7 +117,7 @@ object WeaponTurrets { //convert faction zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SetEmpire(Service.defaultPlayerGUID, target.GUID, hacker.Faction) + AvatarAction.SetEmpire(target.GUID, hacker.Faction) ) zone.LocalEvents ! LocalServiceMessage( zone.id, diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala index 93d47cabb..59f83f942 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala @@ -61,7 +61,6 @@ trait CarrierBehavior { obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Zone.id, AvatarAction.SendResponse( - Service.defaultPlayerGUID, CargoMountPointStatusMessage( obj.GUID, PlanetSideGUID(0), diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index adf02e282..3f40c8ce0 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -523,7 +523,7 @@ class VehicleControl(vehicle: Vehicle) case Some(slot) => obj.Zone.AvatarEvents ! AvatarServiceMessage( self.toString, - AvatarAction.SendResponse(Service.defaultPlayerGUID, ObjectAttachMessage(obj.GUID, item.GUID, slot)) + AvatarAction.SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) case None => () } diff --git a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala index 41eed6d99..331db4721 100644 --- a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala +++ b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala @@ -44,7 +44,7 @@ class WithEntranceInVehicle import net.psforever.types.ChatMessageType obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Actor.toString(), - AvatarAction.SendResponse(Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_227, msg)) + AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) ) } } diff --git a/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala index cf41f29d7..556f6f9de 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala @@ -6,7 +6,7 @@ import net.psforever.actors.zone.ZoneActor import net.psforever.objects.equipment.Equipment import net.psforever.types.PlanetSideGUID import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, DropItemMessage, PickupItemMessage} import scala.annotation.tailrec import scala.collection.mutable.ListBuffer @@ -31,10 +31,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte equipmentOnGround += item item.Position = pos item.Orientation = orient - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.DropItem(Service.defaultPlayerGUID, item) - ) + zone.AvatarEvents ! DropItemMessage(zone.id, AvatarAction.DropItem(item), zone) zone.actor ! ZoneActor.AddToBlockMap(item, pos) Zone.Ground.ItemOnGround(item, pos, orient) }) @@ -42,7 +39,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte case Zone.Ground.PickupItem(item_guid) => sender() ! (FindItemOnGround(item_guid) match { case Some(item) => - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PickupItem(Service.defaultPlayerGUID, item, 0)) + zone.AvatarEvents ! PickupItemMessage(zone.id, AvatarAction.PickupItem(item, 0), zone) zone.actor ! ZoneActor.RemoveFromBlockMap(item) Zone.Ground.ItemInHand(item) case None => @@ -54,7 +51,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte FindItemOnGround(item_guid) match { case Some(item) => zone.actor ! ZoneActor.RemoveFromBlockMap(item) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PickupItem(Service.defaultPlayerGUID, item, 0)) + zone.AvatarEvents ! PickupItemMessage(zone.id, AvatarAction.PickupItem(item, 0), zone) case None => ; } diff --git a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala index 1fc6deb58..e4feeba91 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala @@ -158,8 +158,8 @@ class ZoneProjectileActor( ) zone.AvatarEvents ! AvatarServiceMessage( zone.id, + clarifiedFilterGuid, AvatarAction.LoadProjectile( - clarifiedFilterGuid, definition.ObjectId, projectileGuid, definition.Packet.ConstructorData(projectile).get @@ -190,17 +190,17 @@ class ZoneProjectileActor( zone.blockMap.removeFrom(projectile) zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.ObjectDelete(PlanetSideGUID(0), projectile_guid, 2) + AvatarAction.ObjectDelete(projectile_guid, 2) ) } else if (projectile.Definition.RemoteClientData == (0,0)) { zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.ObjectDelete(PlanetSideGUID(0), projectile_guid, 2) + AvatarAction.ObjectDelete(projectile_guid, 2) ) } else { zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.ProjectileExplodes(PlanetSideGUID(0), projectile_guid, projectile) + AvatarAction.ProjectileExplodes(projectile_guid, projectile) ) } } diff --git a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala index 3ff3206af..dc91da84f 100644 --- a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala +++ b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala @@ -434,7 +434,7 @@ class PersistenceMonitor( case _ => ; } inZone.Population.tell(Zone.Population.Release(avatar), parent) - inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, AvatarAction.ObjectDelete(pguid, pguid)), parent) + inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, pguid, AvatarAction.ObjectDelete(pguid)), parent) TaskWorkflow.execute(GUIDTask.unregisterPlayer(inZone.GUID, player)) //inZone.tasks.tell(GUIDTask.UnregisterPlayer(player)(inZone.GUID), parent) AvatarLogout(avatar) diff --git a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala new file mode 100644 index 000000000..8744c5b95 --- /dev/null +++ b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala @@ -0,0 +1,249 @@ +// Copyright (c) 2017-2026 PSForever +package net.psforever.services.avatar + +import net.psforever.objects.{Player, Vehicle} +import net.psforever.objects.avatar.scoring.KDAStat +import net.psforever.objects.ballistics.Projectile +import net.psforever.objects.equipment.Equipment +import net.psforever.objects.inventory.InventoryItem +import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget +import net.psforever.objects.sourcing.{SourceEntry, UniquePlayer} +import net.psforever.objects.vital.interaction.DamageResult +import net.psforever.objects.zones.Zone +import net.psforever.packet.PlanetSideGamePacket +import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage} +import net.psforever.packet.game.objectcreate.{ConstructorData, DroppedItemData, ObjectCreateMessageParent, PlacementData} +import net.psforever.services.base.{EventMessage, EventResponse, SelfResponseMessage} +import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3} + +import scala.concurrent.duration.FiniteDuration + +object AvatarAction { + final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends SelfResponseMessage + + final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends SelfResponseMessage + + final case class ChangeAmmo( + weapon_guid: PlanetSideGUID, + weapon_slot: Int, + old_ammo_guid: PlanetSideGUID, + ammo_id: Int, + ammo_guid: PlanetSideGUID, + ammo_data: ConstructorData + ) extends SelfResponseMessage + + final case class ChangeFireMode(item_guid: PlanetSideGUID, mode: Int) extends SelfResponseMessage + + final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class EnvironmentalDamage(player_guid: PlanetSideGUID, source_guid: PlanetSideGUID, amount: Int) extends SelfResponseMessage + + final case class DeactivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfResponseMessage + + final case class ActivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfResponseMessage + + final case class Destroy(victim: PlanetSideGUID, killer: PlanetSideGUID, weapon: PlanetSideGUID, pos: Vector3) extends SelfResponseMessage + + final case class DestroyDisplay(killer: SourceEntry, victim: SourceEntry, method: Int, unk: Int = 121) extends SelfResponseMessage + + final case class DropCreatedItem(packet: ObjectCreateMessage) extends EventResponse + + final case class DropItem(item: Equipment) extends EventMessage { + def response(): EventResponse = { + val definition = item.Definition + val objectData = DroppedItemData( + PlacementData(item.Position, item.Orientation), + definition.Packet.ConstructorData(item).get + ) + AvatarAction.DropCreatedItem(ObjectCreateMessage(definition.ObjectId, item.GUID, objectData)) + } + } + + final case class EquipmentCreatedInHand(packet: ObjectCreateMessage) extends EventResponse + + final case class EquipmentInHand(target_guid: PlanetSideGUID, slot: Int, item: Equipment) extends EventMessage { + def response(): EventResponse = { + val definition = item.Definition + val containerData = ObjectCreateMessageParent(target_guid, slot) + val objectData = definition.Packet.ConstructorData(item).get + AvatarAction.EquipmentCreatedInHand( + ObjectCreateMessage(definition.ObjectId, item.GUID, containerData, objectData) + ) + + AvatarAction.DropCreatedItem( + ObjectCreateMessage(definition.ObjectId, item.GUID, containerData, objectData) + ) + } + } + + final case class GenericObjectAction(object_guid: PlanetSideGUID, action_code: Int) extends SelfResponseMessage + + final case class HitHint(source_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class Killed(cause: DamageResult, mount_guid: Option[PlanetSideGUID]) extends SelfResponseMessage + + final case class LoadCreatedPlayer(pkt: ObjectCreateMessage) extends EventResponse + + final case class LoadPlayer( + object_id: Int, + target_guid: PlanetSideGUID, + cdata: ConstructorData, + pdata: Option[ObjectCreateMessageParent] + ) extends EventMessage { + def response(): EventResponse = { + val pkt = pdata match { + case Some(data) => + ObjectCreateMessage(object_id, target_guid, data, cdata) + case None => + ObjectCreateMessage(object_id, target_guid, cdata) + } + LoadCreatedPlayer(pkt) + } + } + + final case class LoadCreatedProjectile(pkt: ObjectCreateMessage) extends EventResponse + + final case class LoadProjectile( + object_id: Int, + projectile_guid: PlanetSideGUID, + cdata: ConstructorData + ) extends EventMessage { + def response(): EventResponse = { + LoadCreatedProjectile(ObjectCreateMessage(object_id, projectile_guid, cdata)) + } + } + + final case class ObjectDelete(item_guid: PlanetSideGUID, unk: Int = 0) extends SelfResponseMessage + + final case class ObjectHeld(slot: Int, previousSLot: Int) extends SelfResponseMessage + + final case class OxygenState(player: OxygenStateTarget, vehicle: Option[OxygenStateTarget]) extends SelfResponseMessage + + final case class PlanetsideAttribute(attribute_type: Int, attribute_value: Long) extends SelfResponseMessage + + final case class PlanetsideAttributeToAll(attribute_type: Int, attribute_value: Long) extends SelfResponseMessage + + final case class PlanetsideAttributeSelf(attribute_type: Int, attribute_value: Long) extends SelfResponseMessage + + final case class PlanetsideStringAttribute(attribute_type: Int, attribute_value: String) extends SelfResponseMessage + + final case class PlayerState( + pos: Vector3, + vel: Option[Vector3], + facingYaw: Float, + facingPitch: Float, + facingYawUpper: Float, + timestamp: Int, + is_crouching: Boolean, + is_jumping: Boolean, + jump_thrust: Boolean, + is_cloaked: Boolean, + spectator: Boolean, + weaponInHand: Boolean + ) extends SelfResponseMessage + + final case class PickupItem(item: Equipment, unk: Int = 0) extends EventMessage { + def response(): EventResponse = { + ObjectDelete(item.GUID, unk) + } + } + + final case class ProjectileAutoLockAwareness(mode: Int) extends SelfResponseMessage + + final case class ProjectileExplodes(projectile_guid: PlanetSideGUID, projectile: Projectile) extends SelfResponseMessage + + final case class ProjectileState( + projectile_guid: PlanetSideGUID, + shot_pos: Vector3, + shot_vel: Vector3, + shot_orient: Vector3, + sequence: Int, + end: Boolean, + hit_target: PlanetSideGUID + ) extends SelfResponseMessage + + final case class PutDownFDU(player_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class ReleasePlayer(player: Player) extends EventResponse + + final case class Release(player: Player, zone: Zone, time: Option[FiniteDuration] = None) extends EventMessage { + def response(): EventResponse = { + ReleasePlayer(player) + } + } + + final case class Reload(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class Revive(target_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class SetEmpire(object_guid: PlanetSideGUID, faction: PlanetSideEmpire.Value) + extends SelfResponseMessage + + final case class StowEquipment(target_guid: PlanetSideGUID, slot: Int, item: Equipment) + extends SelfResponseMessage + + final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + + final case class SendResponse(msg: PlanetSideGamePacket) extends SelfResponseMessage + + final case class SendResponseTargeted(target_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends SelfResponseMessage + + final case class TerminalOrderResult(terminal_guid: PlanetSideGUID, action: TransactionType.Value, result: Boolean) + extends SelfResponseMessage + + final case class ChangeExosuit( + target_guid: PlanetSideGUID, + armor: Int, + exosuit: ExoSuitType.Value, + subtype: Int, + last_drawn_slot: Int, + new_max_hand: Boolean, + old_holsters: List[(Equipment, PlanetSideGUID)], + holsters: List[InventoryItem], + old_inventory: List[(Equipment, PlanetSideGUID)], + inventory: List[InventoryItem], + drop: List[InventoryItem], + delete: List[(Equipment, PlanetSideGUID)] + ) extends SelfResponseMessage + + final case class ChangeLoadout( + target_guid: PlanetSideGUID, + armor: Int, + exosuit: ExoSuitType.Value, + subtype: Int, + last_drawn_slot: Int, + new_max_hand: Boolean, + old_holsters: List[(Equipment, PlanetSideGUID)], + holsters: List[InventoryItem], + old_inventory: List[(Equipment, PlanetSideGUID)], + inventory: List[InventoryItem], + drop: List[InventoryItem] + ) extends SelfResponseMessage + + final case class DropSpecialItem() extends SelfResponseMessage + + final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends SelfResponseMessage + + final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends SelfResponseMessage + + final case class UpdateKillsDeathsAssists(charId: Long, kda: KDAStat) extends SelfResponseMessage + + final case class AwardBep(charId: Long, bep: Long, expType: ExperienceType) extends SelfResponseMessage + + final case class AwardCep(charId: Long, bep: Long) extends SelfResponseMessage + + final case class FacilityCaptureRewards(building_id: Int, zone_number: Int, exp: Long) extends SelfResponseMessage + + final case class ShareKillExperienceWithSquad(killer: Player, exp: Long) extends SelfResponseMessage + + final case class ShareAntExperienceWithSquad(owner: UniquePlayer, exp: Long, vehicle: Vehicle) extends SelfResponseMessage + + final case class RemoveFromOutfitChat(outfit_id: Long) extends SelfResponseMessage + + final case class TeardownConnection() extends SelfResponseMessage +} diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index f76776be9..7b8fb1e6b 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -1,522 +1,33 @@ // Copyright (c) 2017 PSForever package net.psforever.services.avatar -import akka.actor.{Actor, ActorRef, Props} +import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.zones.Zone -import net.psforever.packet.game.ObjectCreateMessage -import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMessageParent, PlacementData} -import net.psforever.types.PlanetSideGUID import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover} -import net.psforever.services.base.GenericEventBus -import net.psforever.services.{RemoverActor, Service} +import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericMessageEnvelope} -class AvatarService(zone: Zone) extends Actor { - private val undertaker: ActorRef = context.actorOf(Props[CorpseRemovalActor](), s"${zone.id}-corpse-removal-agent") - private val janitor = context.actorOf(Props[DroppedItemRemover](), s"${zone.id}-item-remover-agent") - - private[this] val log = org.log4s.getLogger - - val AvatarEvents = new GenericEventBus[AvatarServiceResponse] //AvatarEventBus - - def receive: Receive = { - case Service.Join(channel) => - val path = s"/$channel/Avatar" - val who = sender() - AvatarEvents.subscribe(who, path) - - case Service.Leave(None) => - AvatarEvents.unsubscribe(sender()) - - case Service.Leave(Some(channel)) => - val path = s"/$channel/Avatar" - AvatarEvents.unsubscribe(sender(), path) - - case Service.LeaveAll() => - AvatarEvents.unsubscribe(sender()) - - case AvatarServiceMessage(forChannel, action) => - action match { - case AvatarAction.ArmorChanged(player_guid, suit, subtype) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ArmorChanged(suit, subtype)) - ) - case AvatarAction.AvatarImplant(player_guid, action, implantSlot, status) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.AvatarImplant(action, implantSlot, status)) - ) - case AvatarAction.ChangeAmmo( - player_guid, - weapon_guid, - weapon_slot, - old_ammo_guid, - ammo_id, - ammo_guid, - ammo_data - ) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, old_ammo_guid, ammo_id, ammo_guid, ammo_data) - ) - ) - case AvatarAction.ChangeFireMode(player_guid, item_guid, mode) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ChangeFireMode(item_guid, mode)) - ) - case AvatarAction.ChangeFireState_Start(player_guid, weapon_guid) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.ChangeFireState_Start(weapon_guid) - ) - ) - case AvatarAction.ChangeFireState_Stop(player_guid, weapon_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ChangeFireState_Stop(weapon_guid)) - ) - case AvatarAction.ConcealPlayer(player_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ConcealPlayer()) - ) - case AvatarAction.EnvironmentalDamage(player_guid, source_guid, amount) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.EnvironmentalDamage(player_guid, source_guid, amount) - ) - ) - case AvatarAction.Destroy(victim, killer, weapon, pos) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", victim, AvatarResponse.Destroy(victim, killer, weapon, pos)) - ) - case AvatarAction.DestroyDisplay(killer, victim, method, unk) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.DestroyDisplay(killer, victim, method, unk) - ) - ) - case AvatarAction.DropItem(player_guid, item) => - val definition = item.Definition - val objectData = DroppedItemData( - PlacementData(item.Position, item.Orientation), - definition.Packet.ConstructorData(item).get - ) - janitor forward RemoverActor.AddTask(item, zone) - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.DropItem(ObjectCreateMessage(definition.ObjectId, item.GUID, objectData)) - ) - ) - case AvatarAction.EquipmentInHand(player_guid, target_guid, slot, item) => - val definition = item.Definition - val containerData = ObjectCreateMessageParent(target_guid, slot) - val objectData = definition.Packet.ConstructorData(item).get - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.EquipmentInHand( - ObjectCreateMessage(definition.ObjectId, item.GUID, containerData, objectData) - ) - ) - ) - case AvatarAction.GenericObjectAction(player_guid, object_guid, action_code) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.GenericObjectAction(object_guid, action_code) - ) - ) - case AvatarAction.HitHint(source_guid, player_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.HitHint(source_guid)) - ) - case AvatarAction.Killed(player_guid, cause, mount_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.Killed(cause, mount_guid)) - ) - case AvatarAction.LoadPlayer(player_guid, object_id, target_guid, cdata, pdata) => - val pkt = pdata match { - case Some(data) => - ObjectCreateMessage(object_id, target_guid, data, cdata) - case None => - ObjectCreateMessage(object_id, target_guid, cdata) - } - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.LoadPlayer(pkt)) - ) - case AvatarAction.LoadProjectile(player_guid, object_id, object_guid, cdata) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.LoadProjectile( - ObjectCreateMessage(object_id, object_guid, cdata) - ) - ) - ) - case AvatarAction.ObjectDelete(player_guid, item_guid, unk) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ObjectDelete(item_guid, unk)) - ) - case AvatarAction.ObjectHeld(player_guid, slot, previousSlot) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ObjectHeld(slot, previousSlot)) - ) - case AvatarAction.OxygenState(player, vehicle) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player.guid, AvatarResponse.OxygenState(player, vehicle)) - ) - case AvatarAction.PlanetsideAttribute(guid, attribute_type, attribute_value) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - guid, - AvatarResponse.PlanetsideAttribute(attribute_type, attribute_value) - ) - ) - case AvatarAction.PlanetsideAttributeToAll(guid, attribute_type, attribute_value) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - guid, - AvatarResponse.PlanetsideAttributeToAll(attribute_type, attribute_value) - ) - ) - case AvatarAction.PlanetsideAttributeSelf(guid, attribute_type, attribute_value) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - guid, - AvatarResponse.PlanetsideAttributeSelf(attribute_type, attribute_value) - ) - ) - case AvatarAction.PlanetsideStringAttribute(guid, attribute_type, attribute_value) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - guid, - AvatarResponse.PlanetsideStringAttribute(attribute_type, attribute_value) - ) - ) - case AvatarAction.PlayerState( - guid, - pos, - vel, - yaw, - pitch, - yaw_upper, - seq_time, - is_crouching, - is_jumping, - jump_thrust, - is_cloaking, - spectating, - weaponInHand - ) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - guid, - AvatarResponse.PlayerState( - pos, - vel, - yaw, - pitch, - yaw_upper, - seq_time, - is_crouching, - is_jumping, - jump_thrust, - is_cloaking, - spectating, - weaponInHand - ) - ) - ) - case AvatarAction.ProjectileAutoLockAwareness(mode) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - PlanetSideGUID(0), - AvatarResponse.ProjectileAutoLockAwareness(mode) - ) - ) - case AvatarAction.ProjectileExplodes(player_guid, projectile_guid, projectile) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.ProjectileExplodes(projectile_guid, projectile) - ) - ) - case AvatarAction.ProjectileState( - player_guid, - projectile_guid, - shot_pos, - shot_vel, - shot_orient, - sequence, - end, - target - ) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.ProjectileState(projectile_guid, shot_pos, shot_vel, shot_orient, sequence, end, target) - ) - ) - case AvatarAction.PickupItem(player_guid, item, unk) => - janitor forward RemoverActor.ClearSpecific(List(item), zone) - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ObjectDelete(item.GUID, unk)) - ) - case AvatarAction.PutDownFDU(player_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", Service.defaultPlayerGUID, AvatarResponse.PutDownFDU(player_guid)) - ) - case AvatarAction.Release(player, _, time) => - undertaker forward RemoverActor.AddTask(player, zone, time) - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player.GUID, AvatarResponse.Release(player)) - ) - case AvatarAction.Reload(player_guid, weapon_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.Reload(weapon_guid)) - ) - case AvatarAction.SetEmpire(player_guid, target_guid, faction) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.SetEmpire(target_guid, faction)) - ) - case AvatarAction.StowEquipment(player_guid, target_guid, slot, obj) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - player_guid, - AvatarResponse.StowEquipment(target_guid, slot, obj) - ) - ) - case AvatarAction.WeaponDryFire(player_guid, weapon_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.WeaponDryFire(weapon_guid)) - ) - case AvatarAction.SendResponse(player_guid, msg) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.SendResponse(msg)) - ) - case AvatarAction.SendResponseTargeted(target_guid, msg) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - target_guid, - AvatarResponse.SendResponseTargeted(target_guid, msg) - ) - ) - case AvatarAction.Revive(target_guid) => - AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", target_guid, AvatarResponse.Revive(target_guid)) - ) - - case AvatarAction.TeardownConnection() => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.TeardownConnection() - ) - ) - - case AvatarAction.TerminalOrderResult(terminal, term_action, result) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.TerminalOrderResult(terminal, term_action, result) - ) - ) - case AvatarAction.ChangeExosuit( - target, - armor, - exosuit, - subtype, - slot, - maxhand, - old_holsters, - holsters, - old_inventory, - inventory, - drop, - delete - ) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.ChangeExosuit( - target, - armor, - exosuit, - subtype, - slot, - maxhand, - old_holsters, - holsters, - old_inventory, - inventory, - drop, - delete - ) - ) - ) - case AvatarAction.ChangeLoadout( - target, - armor, - exosuit, - subtype, - slot, - maxhand, - old_holsters, - holsters, - old_inventory, - inventory, - drop - ) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.ChangeLoadout( - target, - armor, - exosuit, - subtype, - slot, - maxhand, - old_holsters, - holsters, - old_inventory, - inventory, - drop - ) - ) - ) - - case AvatarAction.DropSpecialItem() => - AvatarEvents.publish(AvatarServiceResponse(s"/$forChannel/Avatar", Service.defaultPlayerGUID, AvatarResponse.DropSpecialItem())) - - case AvatarAction.UseKit(kit_guid, kit_objid) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.UseKit(kit_guid, kit_objid) - ) - ) - - case AvatarAction.KitNotUsed(kit_guid, msg) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.KitNotUsed(kit_guid, msg) - ) - ) - - case AvatarAction.UpdateKillsDeathsAssists(charId, stat) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.UpdateKillsDeathsAssists(charId, stat) - ) - ) - - case AvatarAction.AwardBep(charId, bep, expType) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.AwardBep(charId, bep, expType) - ) - ) - - case AvatarAction.AwardCep(charId, bep) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.AwardCep(charId, bep) - ) - ) - - case AvatarAction.FacilityCaptureRewards(building_id, zone_number, exp) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.FacilityCaptureRewards(building_id, zone_number, exp) - ) - ) - - case AvatarAction.ShareKillExperienceWithSquad(killer, exp) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.ShareKillExperienceWithSquad(killer, exp) - ) - ) - - case AvatarAction.ShareAntExperienceWithSquad(owner, exp, vehicle) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.ShareAntExperienceWithSquad(owner, exp, vehicle) - ) - ) - - case AvatarAction.RemoveFromOutfitChat(outfit_id) => - AvatarEvents.publish( - AvatarServiceResponse( - s"/$forChannel/Avatar", - Service.defaultPlayerGUID, - AvatarResponse.RemoveFromOutfitChat(outfit_id) - ) - ) - - case _ => () - } - - //message to Undertaker - case AvatarServiceMessage.Corpse(msg) => - undertaker forward msg - - //message to Janitor - case AvatarServiceMessage.Ground(msg) => - janitor forward msg - - /* - case AvatarService.PlayerStateShift(killer, guid) => - val playerOpt: Option[PlayerAvatar] = PlayerMasterList.getPlayer(guid) - if (playerOpt.isDefined) { - val player: PlayerAvatar = playerOpt.get - AvatarEvents.publish(AvatarMessage("/Avatar/" + player.continent, guid, - AvatarServiceReply.PlayerStateShift(killer) - )) - } - */ - - case msg => - log.warn(s"Unhandled message $msg from ${sender()}") +case object CorpseRemovalSupport + extends EventServiceSupport { + def label: String = "undertaker" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[CorpseRemovalActor](), name = "CorpseRemoval") + } +} + +case object ItemRemoverSupport + extends EventServiceSupport { + def label: String = "janitor" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[DroppedItemRemover](), name = "ItemRemover") + } +} + +class AvatarService(zone: Zone) + extends GenericEventServiceWithSupport[AvatarServiceResponse]( + busName = "Avatar", + eventSupportServices = List(CorpseRemovalSupport, ItemRemoverSupport) + ) { + protected def compose(msg: GenericMessageEnvelope): AvatarServiceResponse = { + AvatarServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) } } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala index 11e9ca16a..529b286bc 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala @@ -1,175 +1,82 @@ -// Copyright (c) 2017 PSForever +// Copyright (c) 2017-2026 PSForever package net.psforever.services.avatar -import net.psforever.objects.{Player, Vehicle} -import net.psforever.objects.avatar.scoring.KDAStat -import net.psforever.objects.ballistics.Projectile -import net.psforever.objects.equipment.Equipment -import net.psforever.objects.inventory.InventoryItem -import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget -import net.psforever.objects.sourcing.{SourceEntry, UniquePlayer} -import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.ImplantAction -import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent} -import net.psforever.services.base.{EventMessage, EventResponse} -import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3} +import net.psforever.services.{RemoverActor, Service} +import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem, Release} +import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly} +import net.psforever.types.PlanetSideGUID -import scala.concurrent.duration.FiniteDuration - -final case class AvatarServiceMessage(forChannel: String, actionMessage: AvatarAction.Action) +final case class AvatarServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) + extends GenericMessageEnvelope object AvatarServiceMessage { - final case class Corpse(msg: Any) - final case class Ground(msg: Any) + def apply(channel: String, actionMessage: EventMessage): AvatarServiceMessage = + AvatarServiceMessage(channel, Service.defaultPlayerGUID, actionMessage) } -object AvatarAction { - sealed trait Action extends EventMessage { - def response(): EventResponse = null +final case class ReleaseMessage( + channel: String, + filter: PlanetSideGUID, + msg: Release + ) + extends GenericMessageToSupportEnvelope { + def supportLabel: String = "undertaker" + def supportMessage: Any = { + val Release(player, zone, time) = msg + RemoverActor.AddTask(player, zone, time) } - - final case class ArmorChanged(player_guid: PlanetSideGUID, suit: ExoSuitType.Value, subtype: Int) extends Action - final case class AvatarImplant(player_guid: PlanetSideGUID, action: ImplantAction.Value, implantSlot: Int, status: Int) extends Action - final case class ChangeAmmo( - player_guid: PlanetSideGUID, - weapon_guid: PlanetSideGUID, - weapon_slot: Int, - old_ammo_guid: PlanetSideGUID, - ammo_id: Int, - ammo_guid: PlanetSideGUID, - ammo_data: ConstructorData - ) extends Action - final case class ChangeFireMode(player_guid: PlanetSideGUID, item_guid: PlanetSideGUID, mode: Int) extends Action - final case class ChangeFireState_Start(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class ChangeFireState_Stop(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends Action - final case class EnvironmentalDamage(player_guid: PlanetSideGUID, source_guid: PlanetSideGUID, amount: Int) - extends Action - final case class DeactivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends Action - final case class ActivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends Action - final case class Destroy(victim: PlanetSideGUID, killer: PlanetSideGUID, weapon: PlanetSideGUID, pos: Vector3) - extends Action - final case class DestroyDisplay(killer: SourceEntry, victim: SourceEntry, method: Int, unk: Int = 121) extends Action - final case class DropItem(player_guid: PlanetSideGUID, item: Equipment) extends Action - final case class EquipmentInHand(player_guid: PlanetSideGUID, target_guid: PlanetSideGUID, slot: Int, item: Equipment) - extends Action - final case class GenericObjectAction(player_guid: PlanetSideGUID, object_guid: PlanetSideGUID, action_code: Int) - extends Action - final case class HitHint(source_guid: PlanetSideGUID, player_guid: PlanetSideGUID) extends Action - final case class Killed(player_guid: PlanetSideGUID, cause: DamageResult, mount_guid: Option[PlanetSideGUID]) extends Action - final case class LoadPlayer( - player_guid: PlanetSideGUID, - object_id: Int, - target_guid: PlanetSideGUID, - cdata: ConstructorData, - pdata: Option[ObjectCreateMessageParent] - ) extends Action - final case class LoadProjectile( - player_guid: PlanetSideGUID, - object_id: Int, - projectile_guid: PlanetSideGUID, - cdata: ConstructorData - ) extends Action - final case class ObjectDelete(player_guid: PlanetSideGUID, item_guid: PlanetSideGUID, unk: Int = 0) extends Action - final case class ObjectHeld(player_guid: PlanetSideGUID, slot: Int, previousSLot: Int) extends Action - final case class OxygenState(player: OxygenStateTarget, vehicle: Option[OxygenStateTarget]) extends Action - final case class PlanetsideAttribute(player_guid: PlanetSideGUID, attribute_type: Int, attribute_value: Long) - extends Action - final case class PlanetsideAttributeToAll(player_guid: PlanetSideGUID, attribute_type: Int, attribute_value: Long) - extends Action - final case class PlanetsideAttributeSelf(player_guid: PlanetSideGUID, attribute_type: Int, attribute_value: Long) - extends Action - final case class PlanetsideStringAttribute(player_guid: PlanetSideGUID, attribute_type: Int, attribute_value: String) - extends Action - final case class PlayerState( - player_guid: PlanetSideGUID, - pos: Vector3, - vel: Option[Vector3], - facingYaw: Float, - facingPitch: Float, - facingYawUpper: Float, - timestamp: Int, - is_crouching: Boolean, - is_jumping: Boolean, - jump_thrust: Boolean, - is_cloaked: Boolean, - spectator: Boolean, - weaponInHand: Boolean - ) extends Action - final case class PickupItem(player_guid: PlanetSideGUID, item: Equipment, unk: Int = 0) extends Action - final case class ProjectileAutoLockAwareness(mode: Int) extends Action - final case class ProjectileExplodes( - player_guid: PlanetSideGUID, - projectile_guid: PlanetSideGUID, - projectile: Projectile - ) extends Action - final case class ProjectileState( - player_guid: PlanetSideGUID, - projectile_guid: PlanetSideGUID, - shot_pos: Vector3, - shot_vel: Vector3, - shot_orient: Vector3, - sequence: Int, - end: Boolean, - hit_target: PlanetSideGUID - ) extends Action - final case class PutDownFDU(player_guid: PlanetSideGUID) extends Action - final case class Release(player: Player, zone: Zone, time: Option[FiniteDuration] = None) extends Action - final case class Revive(target_guid: PlanetSideGUID) extends Action - final case class Reload(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class SetEmpire(player_guid: PlanetSideGUID, object_guid: PlanetSideGUID, faction: PlanetSideEmpire.Value) - extends Action - final case class StowEquipment(player_guid: PlanetSideGUID, target_guid: PlanetSideGUID, slot: Int, item: Equipment) - extends Action - final case class WeaponDryFire(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - - final case class SendResponse(player_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends Action - final case class SendResponseTargeted(target_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends Action - - final case class TerminalOrderResult(terminal_guid: PlanetSideGUID, action: TransactionType.Value, result: Boolean) - extends Action - final case class ChangeExosuit( - target_guid: PlanetSideGUID, - armor: Int, - exosuit: ExoSuitType.Value, - subtype: Int, - last_drawn_slot: Int, - new_max_hand: Boolean, - old_holsters: List[(Equipment, PlanetSideGUID)], - holsters: List[InventoryItem], - old_inventory: List[(Equipment, PlanetSideGUID)], - inventory: List[InventoryItem], - drop: List[InventoryItem], - delete: List[(Equipment, PlanetSideGUID)] - ) extends Action - final case class ChangeLoadout( - target_guid: PlanetSideGUID, - armor: Int, - exosuit: ExoSuitType.Value, - subtype: Int, - last_drawn_slot: Int, - new_max_hand: Boolean, - old_holsters: List[(Equipment, PlanetSideGUID)], - holsters: List[InventoryItem], - old_inventory: List[(Equipment, PlanetSideGUID)], - inventory: List[InventoryItem], - drop: List[InventoryItem] - ) extends Action - final case class DropSpecialItem() extends Action - final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends Action - final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends Action - - final case class UpdateKillsDeathsAssists(charId: Long, kda: KDAStat) extends Action - final case class AwardBep(charId: Long, bep: Long, expType: ExperienceType) extends Action - final case class AwardCep(charId: Long, bep: Long) extends Action - final case class FacilityCaptureRewards(building_id: Int, zone_number: Int, exp: Long) extends Action - final case class ShareKillExperienceWithSquad(killer: Player, exp: Long) extends Action - final case class ShareAntExperienceWithSquad(owner: UniquePlayer, exp: Long, vehicle: Vehicle) extends Action - final case class RemoveFromOutfitChat(outfit_id: Long) extends Action - - final case class TeardownConnection() extends Action - // final case class PlayerStateShift(killer : PlanetSideGUID, victim : PlanetSideGUID) extends Action - // final case class DestroyDisplay(killer : PlanetSideGUID, victim : PlanetSideGUID) extends Action +} + +object ReleaseMessage { + def apply(channel: String, actionMessage: Release): ReleaseMessage = + ReleaseMessage(channel, Service.defaultPlayerGUID, actionMessage) +} + +final case class PickupItemMessage( + channel: String, + filter: PlanetSideGUID, + msg: PickupItem, + zone: Zone + ) + extends GenericMessageToSupportEnvelope { + def supportLabel: String = "janitor" + def supportMessage: Any = { + val PickupItem(item, _) = msg + RemoverActor.ClearSpecific(List(item), zone) + } +} + +object PickupItemMessage { + def apply(channel: String, actionMessage: PickupItem, zone: Zone): PickupItemMessage = + PickupItemMessage(channel, Service.defaultPlayerGUID, actionMessage, zone) +} + +final case class DropItemMessage( + channel: String, + filter: PlanetSideGUID, + msg: DropItem, + zone: Zone + ) + extends GenericMessageToSupportEnvelope { + def supportLabel: String = "janitor" + def supportMessage: Any = { + val DropItem(item) = msg + RemoverActor.AddTask(item, zone) + } +} + +object DropItemMessage { + def apply(channel: String, actionMessage: DropItem, zone: Zone): DropItemMessage = + DropItemMessage(channel, Service.defaultPlayerGUID, actionMessage, zone) +} + +final case class CorpseEnvelope(supportMessage: Any) + extends GenericMessageToSupportEnvelopeOnly { + def supportLabel: String = "undertaker" +} + +final case class GroundEnvelope(supportMessage: Any) + extends GenericMessageToSupportEnvelopeOnly { + def supportLabel: String = "janitor" } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala index 247a1eef8..3f523cb69 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala @@ -1,139 +1,11 @@ // Copyright (c) 2017 PSForever package net.psforever.services.avatar -import net.psforever.objects.{Player, Vehicle} -import net.psforever.objects.avatar.scoring.KDAStat -import net.psforever.objects.ballistics.Projectile -import net.psforever.objects.equipment.Equipment -import net.psforever.objects.inventory.InventoryItem -import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget -import net.psforever.objects.sourcing.{SourceEntry, UniquePlayer} -import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.objectcreate.ConstructorData -import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage} -import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3} -import net.psforever.services.base.{EventResponse, GenericEventBusMsg} +import net.psforever.types.PlanetSideGUID +import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} final case class AvatarServiceResponse( - channel: String, - avatar_guid: PlanetSideGUID, - replyMessage: AvatarResponse.Response -) extends GenericEventBusMsg - -object AvatarResponse { - sealed trait Response extends EventResponse - - final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends Response - final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends Response - final case class ChangeAmmo( - weapon_guid: PlanetSideGUID, - weapon_slot: Int, - old_ammo_guid: PlanetSideGUID, - ammo_id: Int, - ammo_guid: PlanetSideGUID, - ammo_data: ConstructorData - ) extends Response - final case class ChangeFireMode(item_guid: PlanetSideGUID, mode: Int) extends Response - final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends Response - final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends Response - final case class ConcealPlayer() extends Response - final case class EnvironmentalDamage(target: PlanetSideGUID, source_guid: PlanetSideGUID, amount: Int) - extends Response - final case class Destroy(victim: PlanetSideGUID, killer: PlanetSideGUID, weapon: PlanetSideGUID, pos: Vector3) - extends Response - final case class DestroyDisplay(killer: SourceEntry, victim: SourceEntry, method: Int, unk: Int) extends Response - final case class DropItem(pkt: ObjectCreateMessage) extends Response - final case class EquipmentInHand(pkt: ObjectCreateMessage) extends Response - final case class GenericObjectAction(object_guid: PlanetSideGUID, action_code: Int) extends Response - final case class HitHint(source_guid: PlanetSideGUID) extends Response - final case class Killed(cause: DamageResult, mount_guid: Option[PlanetSideGUID]) extends Response - final case class LoadPlayer(pkt: ObjectCreateMessage) extends Response - final case class LoadProjectile(pkt: ObjectCreateMessage) extends Response - final case class ObjectDelete(item_guid: PlanetSideGUID, unk: Int) extends Response - final case class ObjectHeld(slot: Int, previousSLot: Int) extends Response - final case class OxygenState(player: OxygenStateTarget, vehicle: Option[OxygenStateTarget]) extends Response - final case class PlanetsideAttribute(attribute_type: Int, attribute_value: Long) extends Response - final case class PlanetsideAttributeToAll(attribute_type: Int, attribute_value: Long) extends Response - final case class PlanetsideAttributeSelf(attribute_type: Int, attribute_value: Long) extends Response - final case class PlanetsideStringAttribute(attribute_type: Int, attribute_value: String) extends Response - final case class PlayerState( - pos: Vector3, - vel: Option[Vector3], - facingYaw: Float, - facingPitch: Float, - facingYawUpper: Float, - timestamp: Int, - is_crouching: Boolean, - is_jumping: Boolean, - jump_thrust: Boolean, - is_cloaked: Boolean, - spectator: Boolean, - weaponInHand: Boolean - ) extends Response - final case class ProjectileAutoLockAwareness(mode: Int) extends Response - final case class ProjectileExplodes(projectile_guid: PlanetSideGUID, projectile: Projectile) extends Response - final case class ProjectileState( - projectile_guid: PlanetSideGUID, - shot_pos: Vector3, - shot_vel: Vector3, - shot_orient: Vector3, - sequence: Int, - end: Boolean, - hit_target: PlanetSideGUID - ) extends Response - final case class PutDownFDU(target_guid: PlanetSideGUID) extends Response - final case class Release(player: Player) extends Response - final case class Reload(weapon_guid: PlanetSideGUID) extends Response - final case class Revive(target_guid: PlanetSideGUID) extends Response - final case class SetEmpire(object_guid: PlanetSideGUID, faction: PlanetSideEmpire.Value) extends Response - final case class StowEquipment(target_guid: PlanetSideGUID, slot: Int, item: Equipment) extends Response - final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends Response - - final case class SendResponse(msg: PlanetSideGamePacket) extends Response - final case class SendResponseTargeted(target_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends Response - - final case class TerminalOrderResult(terminal_guid: PlanetSideGUID, action: TransactionType.Value, result: Boolean) - extends Response - final case class ChangeExosuit( - target_guid: PlanetSideGUID, - armor: Int, - exosuit: ExoSuitType.Value, - subtype: Int, - last_drawn_slot: Int, - new_max_hand: Boolean, - old_holsters: List[(Equipment, PlanetSideGUID)], - holsters: List[InventoryItem], - old_inventory: List[(Equipment, PlanetSideGUID)], - inventory: List[InventoryItem], - drop: List[InventoryItem], - delete: List[(Equipment, PlanetSideGUID)] - ) extends Response - final case class ChangeLoadout( - target_guid: PlanetSideGUID, - armor: Int, - exosuit: ExoSuitType.Value, - subtype: Int, - last_drawn_slot: Int, - new_max_hand: Boolean, - old_holsters: List[(Equipment, PlanetSideGUID)], - holsters: List[InventoryItem], - old_inventory: List[(Equipment, PlanetSideGUID)], - inventory: List[InventoryItem], - drop: List[InventoryItem] - ) extends Response - final case class DropSpecialItem() extends Response - - final case class TeardownConnection() extends Response - // final case class PlayerStateShift(itemID : PlanetSideGUID) extends Response - final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends Response - final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends Response - - final case class UpdateKillsDeathsAssists(charId: Long, kda: KDAStat) extends Response - final case class AwardBep(charId: Long, bep: Long, expType: ExperienceType) extends Response - final case class AwardCep(charId: Long, bep: Long) extends Response - final case class FacilityCaptureRewards(building_id: Int, zone_number: Int, exp: Long) extends Response - final case class ShareKillExperienceWithSquad(killer: Player, exp: Long) extends Response - final case class ShareAntExperienceWithSquad(owner: UniquePlayer, exp: Long, vehicle: Vehicle) extends Response - final case class RemoveFromOutfitChat(outfit_id: Long) extends Response -} + channel: String, + filter: PlanetSideGUID, + reply: EventResponse + ) extends GenericResponseEnvelope diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 974f0b687..95784b450 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -25,7 +25,7 @@ class CorpseRemovalActor extends RemoverActor() { entry.zone.Population ! Zone.Corpse.Remove(entry.obj.asInstanceOf[Player]) context.parent ! AvatarServiceMessage( entry.zone.id, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, entry.obj.GUID, unk=1) + AvatarAction.ObjectDelete(entry.obj.GUID, unk=1) ) } diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index 80a0ce879..25c224f66 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -24,7 +24,7 @@ class DroppedItemRemover extends RemoverActor() { entry.zone.Ground ! Zone.Ground.RemoveItem(entry.obj.GUID) context.parent ! AvatarServiceMessage( entry.zone.id, - AvatarAction.ObjectDelete(Service.defaultPlayerGUID, entry.obj.GUID) + AvatarAction.ObjectDelete(entry.obj.GUID) ) } diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 068ad6a76..6a4c030c0 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -6,28 +6,31 @@ import net.psforever.services.Service import net.psforever.types.PlanetSideGUID import org.log4s.Logger +import scala.annotation.unused + trait GenericResponseEnvelope extends GenericEventBusMsg { - def exclude: PlanetSideGUID + def filter: PlanetSideGUID def reply: EventResponse } trait GenericMessageEnvelope { def channel: String - def exclude: PlanetSideGUID + def filter: PlanetSideGUID def msg: EventMessage - def response(outChannel: String): GenericResponseEnvelope } -abstract class GenericEventService[IN <: GenericMessageEnvelope, OUT <: GenericResponseEnvelope](busName: String) +abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: String) extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) protected val eventBus = new GenericEventBus[OUT] + def BusName: String = busName + def commonJoinBehavior: Receive = { case Service.Join(channel) => - val path = formatChannelOnBusName(channel, busName) + val path = formatChannelOnBusName(channel) val who = sender() eventBus.subscribe(who, path) } @@ -37,7 +40,7 @@ abstract class GenericEventService[IN <: GenericMessageEnvelope, OUT <: GenericR eventBus.unsubscribe(sender()) case Service.Leave(Some(channel)) => - val path = formatChannelOnBusName(channel, busName) + val path = formatChannelOnBusName(channel) eventBus.unsubscribe(sender(), path) case Service.LeaveAll() => @@ -47,22 +50,24 @@ abstract class GenericEventService[IN <: GenericMessageEnvelope, OUT <: GenericR def receive: Receive = commonJoinBehavior.orElse(commonLeaveBehavior) .orElse { - case msg: IN => - compose(msg) + case msg: GenericMessageEnvelope => + handleMessage(msg) case msg => () log.warn(s"Unhandled message $msg from ${sender()}") } - protected def compose(msg: GenericMessageEnvelope): Unit = { - eventBus.publish(msg.response(formatChannelOnBusName(msg.channel, busName)).asInstanceOf[OUT]) + protected def handleMessage(msg: GenericMessageEnvelope): Unit = { + eventBus.publish(compose(msg)) } - def formatChannelOnBusName: (String, String) => String = GenericEventService.BusOnChannelFormat + protected def compose(@unused msg: GenericMessageEnvelope): OUT + + def formatChannelOnBusName(channel: String): String = GenericEventService.BusOnChannelFormat(busName)(channel) } object GenericEventService { - final def BusOnChannelFormat(channel: String, busName: String): String = { + final def BusOnChannelFormat(busName: String)(channel: String): String = { if (channel.trim.isEmpty) { s"/$busName" } else { diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index 6e3a33b2a..c4a531000 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -2,6 +2,8 @@ package net.psforever.services.base import akka.actor.{ActorContext, ActorRef} +import net.psforever.services.Service +import net.psforever.types.PlanetSideGUID import scala.annotation.unused @@ -12,15 +14,22 @@ trait EventServiceSupport { trait GenericMessageToSupportEnvelope extends GenericMessageEnvelope { - def toSupport: String - def response(outChannel: String): GenericResponseEnvelope = null + def supportLabel: String + def supportMessage: Any } -abstract class GenericEventServiceWithSupport[IN <: GenericMessageEnvelope, OUT <: GenericResponseEnvelope] +trait GenericMessageToSupportEnvelopeOnly + extends GenericMessageToSupportEnvelope { + def channel: String = "" + def filter: PlanetSideGUID = Service.defaultPlayerGUID + def msg: EventMessage = null +} + +abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope] ( busName: String, eventSupportServices: List[EventServiceSupport] -) extends GenericEventService[IN, OUT](busName) { +) extends GenericEventService[OUT](busName) { private val supportServices: Map[String, ActorRef] = eventSupportServices @@ -28,24 +37,24 @@ abstract class GenericEventServiceWithSupport[IN <: GenericMessageEnvelope, OUT .toMap[String, ActorRef] private def supportReceive: Receive = { + case msg: GenericMessageToSupportEnvelopeOnly => + forwardToSupport(msg) case msg: GenericMessageToSupportEnvelope => forwardToSupport(msg) + handleMessage(msg) } override def receive: Receive = supportReceive.orElse(super.receive) private def forwardToSupport(msg: GenericMessageToSupportEnvelope): Unit = { supportServices - .get(msg.toSupport) + .get(msg.supportLabel) .map { support => - support.forward(msg) + support.forward(msg.supportMessage) msg } .getOrElse { - log.error(s"support service ${msg.toSupport} was not found - check message routing or service params") + log.error(s"support service ${msg.supportLabel} was not found - check message routing or service params") } - if (msg.response(outChannel = "") != null) { - compose(msg) - } } } diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index a640d1ddb..65d15b2cd 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -1,7 +1,11 @@ // Copyright (c) 2017-2026 PSForever package net.psforever.services.galaxy -import net.psforever.services.base.GenericEventService +import net.psforever.services.base.{GenericEventService, GenericMessageEnvelope} class GalaxyService - extends GenericEventService[GalaxyServiceMessage, GalaxyServiceResponse](busName = "Galaxy") + extends GenericEventService[GalaxyServiceResponse](busName = "Galaxy") { + protected def compose(msg: GenericMessageEnvelope): GalaxyServiceResponse = { + GalaxyServiceResponse(formatChannelOnBusName(msg.channel), msg.msg.response()) + } +} diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala index 8c115ec75..6b3af1685 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala @@ -7,11 +7,7 @@ import net.psforever.types.PlanetSideGUID final case class GalaxyServiceMessage(channel: String, msg: EventMessage) extends GenericMessageEnvelope { - def exclude: PlanetSideGUID = Service.defaultPlayerGUID - - def response(outChannel: String): GalaxyServiceResponse = { - GalaxyServiceResponse(outChannel, msg.response()) - } + def filter: PlanetSideGUID = Service.defaultPlayerGUID } object GalaxyServiceMessage { diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala index 70d072f9b..3d68799f2 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala @@ -7,5 +7,5 @@ import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} final case class GalaxyServiceResponse(channel: String, reply: EventResponse) extends GenericResponseEnvelope { - def exclude: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Service.defaultPlayerGUID } diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index c93ae2696..97e580b49 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -115,7 +115,7 @@ class HackClearActor() extends Actor { val building = target.asInstanceOf[Terminal].Owner.asInstanceOf[Building] building.virusId = 8 building.virusInstalledBy = None - val msg = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, target.GUID, 60) + val msg = AvatarAction.GenericObjectAction(target.GUID, 60) val events = building.Zone.AvatarEvents building.PlayersInSOI.foreach { player => events ! AvatarServiceMessage(player.Name, msg) From 1cbe1fa14131bad242d737bc757d0373e1593eeb Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 26 Jan 2026 03:47:37 -0500 Subject: [PATCH 04/32] working LocalService based on GenericServiceEvent(WithSupport); manually corrected almost every message to LocalService to ensure channel and filters are preserved --- .codecov.yml | 1 - .../actors/session/AvatarActor.scala | 1 - .../session/normal/LocalHandlerLogic.scala | 100 ++--- .../session/spectator/SquadHandlerLogic.scala | 2 +- .../session/support/ChatOperations.scala | 8 +- .../session/support/GeneralOperations.scala | 15 +- .../support/SessionLocalHandlers.scala | 4 +- .../WeaponAndProjectileOperations.scala | 27 +- .../session/support/ZoningOperations.scala | 21 +- .../zone/building/CavernFacilityLogic.scala | 7 +- .../actors/zone/building/FacilityLogic.scala | 7 +- .../zone/building/MajorFacilityLogic.scala | 14 +- .../net/psforever/login/WorldSession.scala | 1 - .../psforever/objects/BoomerDeployable.scala | 1 - .../net/psforever/objects/Deployables.scala | 6 +- .../objects/ExplosiveDeployable.scala | 2 +- .../psforever/objects/SensorDeployable.scala | 10 +- .../scala/net/psforever/objects/Tools.scala | 1 - .../net/psforever/objects/Vehicles.scala | 7 +- .../objects/avatar/CorpseControl.scala | 1 - .../objects/avatar/PlayerControl.scala | 15 +- .../avatar/interaction/WithEntrance.scala | 2 +- .../avatar/interaction/WithGantry.scala | 1 - .../objects/ce/DeployableBehavior.scala | 10 +- .../locker/LockerContainerControl.scala | 3 +- .../serverobject/doors/DoorControl.scala | 7 +- .../generator/GeneratorControl.scala | 1 - .../hackable/GenericHackables.scala | 77 ++-- .../objects/serverobject/locks/IFFLocks.scala | 9 +- .../repair/RepairableEntity.scala | 1 - .../FacilityHackParticipation.scala | 1 - .../terminals/ProximityTerminalControl.scala | 15 +- .../terminals/TerminalControl.scala | 8 +- .../terminals/capture/CaptureTerminals.scala | 16 +- .../turret/VanuSentryControl.scala | 3 +- .../serverobject/turret/WeaponTurrets.scala | 4 +- .../interaction/WithEntranceInVehicle.scala | 1 - .../objects/zones/ZoneGroundActor.scala | 3 +- .../avatar/support/CorpseRemovalActor.scala | 2 +- .../avatar/support/DroppedItemRemover.scala | 2 +- .../services/local/LocalAction.scala | 204 +++++++++ .../services/local/LocalService.scala | 395 ++---------------- .../services/local/LocalServiceMessage.scala | 178 ++------ .../services/local/LocalServiceResponse.scala | 92 +--- .../local/support/CaptureFlagManager.scala | 48 ++- .../local/support/DoorCloseActor.scala | 9 +- .../local/support/HackCaptureActor.scala | 49 +-- .../local/support/HackClearActor.scala | 30 +- .../objects/DeployableBehaviorTest.scala | 37 +- src/test/scala/objects/DeployableTest.scala | 20 +- src/test/scala/objects/DoorTest.scala | 2 +- .../objects/terminal/ProximityTest.scala | 22 +- src/test/scala/service/LocalServiceTest.scala | 55 ++- 53 files changed, 629 insertions(+), 929 deletions(-) create mode 100644 src/main/scala/net/psforever/services/local/LocalAction.scala diff --git a/.codecov.yml b/.codecov.yml index c6c1e418a..b34307e32 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -76,6 +76,5 @@ ignore: - "src/main/scala/net/psforever/services/hart/HartEvent.scala" - "src/main/scala/net/psforever/services/hart/HartTimerActions.scala" - "src/main/scala/net/psforever/services/local/LocalAction.scala" - - "src/main/scala/net/psforever/services/local/LocalResponse.scala" - "src/main/scala/net/psforever/services/vehicle/VehicleAction.scala" - "src/main/scala/net/psforever/services/vehicle/VehicleResponse.scala" diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index e129405ba..e0d4d99cb 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -49,7 +49,6 @@ import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingAc import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars} import net.psforever.packet.game.{Friend => GameFriend, _} import net.psforever.persistence -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.types.{ CharacterSex, 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 2f12efd95..991cac4f1 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -9,8 +9,9 @@ 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, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} +import net.psforever.services.base.EventResponse import net.psforever.services.{InterstellarClusterService, Service} -import net.psforever.services.local.LocalResponse +import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideGUID, SpawnGroup} object LocalHandlerLogic { @@ -40,7 +41,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: LocalResponse.Response): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { val resolvedPlayerGuid = if (player.HasGUID) { player.GUID } else { @@ -48,26 +49,27 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act } val isNotSameTarget = resolvedPlayerGuid != guid reply match { - case LocalResponse.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget => + case LocalAction.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget => sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) - case LocalResponse.DeployableUIFor(item) => + case LocalAction.DeployableUIFor(item) => sessionLogic.general.updateDeployableUIElements(avatar.deployables.UpdateUIElement(item)) - case LocalResponse.Detonate(dguid, _: BoomerDeployable) => + case LocalAction.Detonate(dguid, _: BoomerDeployable) => sendResponse(TriggerEffectMessage(dguid, "detonate_boomer")) sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1)) sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.Detonate(dguid, _: ExplosiveDeployable) => + case LocalAction.Detonate(dguid, _: ExplosiveDeployable) => sendResponse(GenericObjectActionMessage(dguid, code=19)) sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1)) sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.Detonate(_, obj) => - log.warn(s"LocalResponse.Detonate: ${obj.Definition.Name} not configured to explode correctly") + case LocalAction.Detonate(_, obj) => + log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly") - case LocalResponse.DoorOpens(doorGuid) if isNotSameTarget => + case LocalAction.DoorOpens(_, door) if isNotSameTarget => + val doorGuid = door.GUID val pos = player.Position.xy val range = ops.doorLoadRange() val foundDoor = continent @@ -81,13 +83,13 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(GenericObjectStateMsg(doorGuid, state=16)) } - case LocalResponse.DoorCloses(doorGuid) => //door closes for everyone + case LocalAction.DoorCloses(doorGuid) => //door closes for everyone sendResponse(GenericObjectStateMsg(doorGuid, state=17)) - case LocalResponse.EliminateDeployable(obj: TurretDeployable, dguid, _, _) if obj.Destroyed => + case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _) if obj.Destroyed => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) => + case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) => obj.Destroyed = true ops.DeconstructDeployable( obj, @@ -97,22 +99,22 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act deletionType= if (obj.MountPoints.isEmpty) { 2 } else { 1 } ) - case LocalResponse.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _) + case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _) if obj.Destroyed || obj.Jammed || obj.Health == 0 => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => + case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => obj.Destroyed = true ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) - case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Active && obj.Destroyed => + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Active && obj.Destroyed => //if active, deactivate obj.Active = false ops.deactivateTelpadDeployableMessages(dguid) //standard deployable elimination behavior sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) if obj.Active => + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) if obj.Active => //if active, deactivate obj.Active = false ops.deactivateTelpadDeployableMessages(dguid) @@ -120,44 +122,41 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act obj.Destroyed = true ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) - case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Destroyed => + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Destroyed => //standard deployable elimination behavior sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) => + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) => //standard deployable elimination behavior obj.Destroyed = true ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) - case LocalResponse.EliminateDeployable(obj, dguid, _, _) if obj.Destroyed => + case LocalAction.EliminateDeployable(obj, dguid, _, _) if obj.Destroyed => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - case LocalResponse.EliminateDeployable(obj, dguid, pos, effect) => + case LocalAction.EliminateDeployable(obj, dguid, pos, effect) => obj.Destroyed = true ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) - case LocalResponse.SendHackMessageHackCleared(targetGuid, unk1, unk2) => + case LocalAction.SendHackMessageHackCleared(targetGuid, unk1, unk2) => sendResponse(HackMessage(HackState1.Unk0, targetGuid, guid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) - case LocalResponse.HackObject(targetGuid, unk1, unk2) => + case LocalAction.HackObject(targetGuid, unk1, unk2) => sessionLogic.general.hackObject(targetGuid, unk1, unk2) - case LocalResponse.PlanetsideAttribute(targetGuid, attributeType, attributeValue) => + case LocalAction.PlanetsideAttribute(targetGuid, attributeType, attributeValue) => sessionLogic.general.sendPlanetsideAttributeMessage(targetGuid, attributeType, attributeValue) - case LocalResponse.GenericObjectAction(targetGuid, actionNumber) => + case LocalAction.GenericObjectAction(targetGuid, actionNumber) => sendResponse(GenericObjectActionMessage(targetGuid, actionNumber)) - case LocalResponse.GenericActionMessage(actionNumber) => + case LocalAction.GenericActionMessage(actionNumber) => sendResponse(GenericActionMessage(actionNumber)) - case LocalResponse.ChatMessage(msg) => + case LocalAction.ChatMessage(msg) => sendResponse(msg) - case LocalResponse.SendPacket(packet) => - sendResponse(packet) - - case LocalResponse.LluSpawned(llu) => + case LocalAction.LluSpawned(llu) => // Create LLU on client sendResponse(ObjectCreateMessage( llu.Definition.ObjectId, @@ -166,7 +165,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act )) sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk=20, volume=0.8000001f)) - case LocalResponse.LluDespawned(lluGuid, position) => + case LocalAction.LluDespawned(lluGuid, position) => sendResponse(TriggerSoundMessage(TriggeredSound.LLUDeconstruct, position, unk=20, volume=0.8000001f)) sendResponse(ObjectDeleteMessage(lluGuid, unk1=0)) // If the player was holding the LLU, remove it from their tracked special item slot @@ -175,39 +174,40 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act player.Carrying = None } - case LocalResponse.ObjectDelete(objectGuid, unk) if isNotSameTarget => + case LocalAction.ObjectDelete(objectGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(objectGuid, unk)) - case LocalResponse.ProximityTerminalEffect(object_guid, true) => + case LocalAction.ProximityTerminalEffect(object_guid, true) => sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, object_guid, unk=true)) - case LocalResponse.ProximityTerminalEffect(objectGuid, false) => + case LocalAction.ProximityTerminalEffect(objectGuid, false) => sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, objectGuid, unk=false)) sessionLogic.terminals.ForgetAllProximityTerminals(objectGuid) - case LocalResponse.RouterTelepadMessage(msg) => + case LocalAction.RouterTelepadMessage(msg) => sendResponse(ChatMsg(ChatMessageType.UNK_229, wideContents=false, recipient="", msg, note=None)) - case LocalResponse.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) => + case LocalAction.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) => sessionLogic.general.useRouterTelepadEffect(passengerGuid, srcGuid, destGuid) - case LocalResponse.SendResponse(msg) => + case LocalAction.SendResponse(msg) => msg match { case m: GenericObjectActionMessage => // delay building virus alert if player is dead/respawning if ((m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages) { sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask( SpawnOperations.delaySendGenericObjectActionMessage(msg), 1)) + } else { + sendResponse(msg) } - else sendResponse(msg) case _ => sendResponse(msg) } - case LocalResponse.SetEmpire(objectGuid, empire) => + case LocalAction.SetEmpire(objectGuid, empire) => sendResponse(SetEmpireMessage(objectGuid, empire)) - case LocalResponse.ShuttleEvent(ev) => + case LocalAction.ShuttleEvent(ev) => val msg = OrbitalShuttleTimeMsg( ev.u1, ev.u2, @@ -218,31 +218,31 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act ) sendResponse(msg) - case LocalResponse.ShuttleDock(pguid, sguid, slot) => + case LocalAction.ShuttleDock(pguid, sguid, slot) => sendResponse(ObjectAttachMessage(pguid, sguid, slot)) - case LocalResponse.ShuttleUndock(pguid, sguid, pos, orient) => + case LocalAction.ShuttleUndock(pguid, sguid, pos, orient) => sendResponse(ObjectDetachMessage(pguid, sguid, pos, orient)) - case LocalResponse.ShuttleState(sguid, pos, orient, state) => + case LocalAction.ShuttleState(sguid, pos, orient, state) => sendResponse(VehicleStateMessage(sguid, unk1=0, pos, orient, vel=None, Some(state), unk3=0, unk4=0, wheel_direction=15, is_decelerating=false, is_cloaked=false)) - case LocalResponse.ToggleTeleportSystem(router, systemPlan) => + case LocalAction.ToggleTeleportSystem(router, systemPlan) => sessionLogic.general.toggleTeleportSystem(router, systemPlan) - case LocalResponse.TriggerEffect(targetGuid, effect, effectInfo, triggerLocation) => + case LocalAction.TriggerEffectAtLocation(targetGuid, effect, effectInfo, triggerLocation) => sendResponse(TriggerEffectMessage(targetGuid, effect, effectInfo, triggerLocation)) - case LocalResponse.TriggerSound(sound, pos, unk, volume) => + case LocalAction.TriggerSound(sound, pos, unk, volume) => sendResponse(TriggerSoundMessage(sound, pos, unk, volume)) - case LocalResponse.UpdateForceDomeStatus(buildingGuid, true) => + case LocalAction.UpdateForceDomeStatus(buildingGuid, true) => sendResponse(GenericObjectActionMessage(buildingGuid, 11)) - case LocalResponse.UpdateForceDomeStatus(buildingGuid, false) => + case LocalAction.UpdateForceDomeStatus(buildingGuid, false) => sendResponse(GenericObjectActionMessage(buildingGuid, 12)) - case LocalResponse.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if resolvedPlayerGuid == guid => + case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if resolvedPlayerGuid == guid => continent.GUID(vehicleGuid) .collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) } .collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) } @@ -251,7 +251,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(InventoryStateMessage(weapon.AmmoSlot.Box.GUID, weapon.GUID, weapon.Magazine)) } - case LocalResponse.ForceZoneChange(zone) => + case LocalAction.ForceZoneChange(zone) => //todo we might be able to piggyback this for squad recalls later if(session.zone eq zone) { sessionLogic.zoning.zoneReload = true diff --git a/src/main/scala/net/psforever/actors/session/spectator/SquadHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/SquadHandlerLogic.scala index b73217603..b25d823f8 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/SquadHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/SquadHandlerLogic.scala @@ -10,7 +10,7 @@ import net.psforever.objects.avatar.Avatar import net.psforever.packet.game.{CharacterKnowledgeInfo, CharacterKnowledgeMessage, ChatMsg, PlanetsideAttributeMessage, ReplicationStreamMessage, SquadAction, SquadDefinitionActionMessage, SquadDetailDefinitionUpdateMessage, SquadListing, SquadMemberEvent, SquadMembershipRequest, SquadMembershipResponse, SquadState, SquadStateInfo, SquadWaypointEvent, SquadWaypointRequest, WaypointEventAction} import net.psforever.services.chat.SquadChannel import net.psforever.services.teamwork.SquadResponse -import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadListDecoration, SquadResponseType} +import net.psforever.types.{PlanetSideGUID, SquadListDecoration, SquadResponseType} object SquadHandlerLogic { def apply(ops: SessionSquadHandlers): SquadHandlerLogic = { diff --git a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala index b721628b3..d53a0685f 100644 --- a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala @@ -20,7 +20,8 @@ import net.psforever.packet.game.{SetChatFilterMessage, TimeOfDayMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.HackCaptureActor +import net.psforever.services.local.CaptureMessage import net.psforever.services.teamwork.{SquadResponse, SquadService, SquadServiceResponse} import net.psforever.types.ChatMessageType.CMT_QUIT import org.log4s.Logger @@ -405,10 +406,7 @@ class ChatOperations( } else { if (building.CaptureTerminalIsHacked) { - zone.LocalEvents ! LocalServiceMessage( - zone.id, - LocalAction.ResecureCaptureTerminal(terminal, PlayerSource.Nobody) - ) + zone.LocalEvents ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(terminal, zone, PlayerSource.Nobody)) } building.Actor ! BuildingActor.SetFaction(faction) building.Actor ! BuildingActor.AmenityStateChange(terminal, Some(false)) diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 9b7c7ce73..5e3cdb08e 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -19,7 +19,8 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.RemoverActor import net.psforever.services.avatar.GroundEnvelope -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.HackCaptureActor +import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global @@ -1252,7 +1253,7 @@ class GeneralOperations( continent.GUID(specialItemSlotGuid) match { case Some(llu: CaptureFlag) => if (llu.Target.GUID == captureTerminal.Owner.GUID) { - continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.LluCaptured(llu)) + continent.LocalEvents ! CaptureMessage(HackCaptureActor.FlagCaptured(llu)) } else { log.info( s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}" @@ -1435,13 +1436,12 @@ class GeneralOperations( val events = continent.AvatarEvents val zoneid = continent.id val destinationPosition = dest.Position - events ! AvatarServiceMessage(zoneid, AvatarAction.ObjectDelete(pguid, pguid)) + events ! AvatarServiceMessage(zoneid, pguid, AvatarAction.ObjectDelete(pguid)) events ! AvatarServiceMessage(player.Name, - AvatarAction.SendResponse(PlanetSideGUID(0), PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z))) + AvatarAction.SendResponse(PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z))) ) player.Position = destinationPosition - events ! AvatarServiceMessage(zoneid, AvatarAction.LoadPlayer( - pguid, + events ! AvatarServiceMessage(zoneid, pguid, AvatarAction.LoadPlayer( player.Definition.ObjectId, pguid, player.Definition.Packet.ConstructorData(player).get, @@ -1450,7 +1450,8 @@ class GeneralOperations( useRouterTelepadEffect(pguid, sguid, dguid) continent.LocalEvents ! LocalServiceMessage( continent.id, - LocalAction.RouterTelepadTransport(pguid, pguid, sguid, dguid) + pguid, + LocalAction.RouterTelepadTransport(pguid, sguid, dguid) ) sessionLogic.zoning.spawn.ShiftPosition = destinationPosition player.LogActivity(TelepadUseActivity(VehicleSource(router), DeployableSource(remoteTelepad), PlayerSource(player))) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala index 8480a1d55..b911ffdd1 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala @@ -7,7 +7,7 @@ import net.psforever.objects.ce.Deployable import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.packet.game.{GenericObjectActionMessage, ObjectDeleteMessage, PlanetsideAttributeMessage, TriggerEffectMessage} -import net.psforever.services.local.LocalResponse +import net.psforever.services.base.EventResponse import net.psforever.types.{PlanetSideGUID, Vector3} trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality { @@ -17,7 +17,7 @@ trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality { def handleDeployableIsDismissed(obj: Deployable): Unit - def handle(toChannel: String, guid: PlanetSideGUID, reply: LocalResponse.Response): Unit + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit } class SessionLocalHandlers( diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index db1e8e6e0..13668606c 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -27,6 +27,7 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest +import net.psforever.services.Service import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3} import net.psforever.util.Config @@ -345,14 +346,21 @@ class WeaponAndProjectileOperations( sendResponse(UplinkResponse(code.value, 0)) sendResponse(PlanetsideAttributeMessage(player.GUID, 59, 1200000)) avatarActor ! AvatarActor.UpdateCUDTime("emp_blast") - player.Zone.LocalEvents ! LocalServiceMessage(s"${player.Zone.id}", - LocalAction.SendPacket(TriggerEffectMessage(ValidPlanetSideGUID(0), empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90)))))) + player.Zone.LocalEvents ! LocalServiceMessage( + s"${player.Zone.id}", + PlanetSideGUID(-1), + LocalAction.SendResponse(TriggerEffectMessage(Service.defaultPlayerGUID, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))) + ) context.system.scheduler.scheduleOnce(delay = 1 seconds) { Zone.serverSideDamage(player.Zone, player, empSize, SpecialEmp.createEmpInteraction(empSize, player.Position), ExplosiveDeployableControl.detectionForExplosiveSource(player), Zone.findAllTargets) } case UplinkRequestType.OrbitalStrike => - player.Zone.LocalEvents ! LocalServiceMessage(s"$playerFaction", LocalAction.SendPacket(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y))) + player.Zone.LocalEvents ! LocalServiceMessage( + s"$playerFaction", + PlanetSideGUID(-1), + LocalAction.SendResponse(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y)) + ) sendResponse(UplinkResponse(code.value, 0)) orbitalStrikePos = pos case UplinkRequestType.Unknown5 => @@ -377,9 +385,16 @@ class WeaponAndProjectileOperations( sendResponse(PlanetsideAttributeMessage(player.GUID, 60, 10800000)) avatarActor ! AvatarActor.UpdateCUDTime("orbital_strike") context.system.scheduler.scheduleOnce(delay = 5 seconds) { - player.Zone.LocalEvents ! LocalServiceMessage(s"${player.Zone.id}", - LocalAction.SendPacket(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90)))))) - player.Zone.LocalEvents ! LocalServiceMessage(s"$playerFaction", LocalAction.SendPacket(OrbitalStrikeWaypointMessage(player.GUID, None))) + player.Zone.LocalEvents ! LocalServiceMessage( + s"${player.Zone.id}", + PlanetSideGUID(-1), + LocalAction.SendResponse(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90))))) + ) + player.Zone.LocalEvents ! LocalServiceMessage( + s"$playerFaction", + PlanetSideGUID(-1), + LocalAction.SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) + ) context.system.scheduler.scheduleOnce(delay = 5 seconds) { val sectorTargets = Zone.findOrbitalStrikeTargets(player.Zone, orbitalStrikePos.get, osSize.DamageRadius, Zone.getOrbitbalStrikeTargets) val withinRange = sectorTargets.filter { target => Zone.orbitalStrikeDistanceCheck(orbitalStrikePos.get, target.Position, osSize.DamageRadius) } diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index d3af7943b..e491e35fe 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -119,7 +119,7 @@ object ZoningOperations { additionalChannels: List[String] ): Unit = { val events = zone.LocalEvents - val effectMessage = LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, s"respawn_$faction", position, orientation) + val effectMessage = LocalAction.TriggerEffectLocation(s"respawn_$faction", position, orientation) (zone .blockMap .sector(position, range = 100f) @@ -153,11 +153,11 @@ object ZoningOperations { Vector3.DistanceSquared(t.Position.xy, posxy) < 2500f && /* literal 50m */ heightDiff < 5f && heightDiff > -1f } - val effectMessage = LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, s"respawn_$faction", position, orientation) + val effectMessage = LocalAction.TriggerEffectLocation(s"respawn_$faction", position, orientation) (effectTargets.map(_.Name) ++ additionalChannels).foreach { target => events ! LocalServiceMessage(target, effectMessage) } - val soundMessage = LocalAction.TriggerSound(Service.defaultPlayerGUID, TriggeredSound.SpawnInTube, position, 50, 0.69803923f) + val soundMessage = LocalAction.TriggerSound(TriggeredSound.SpawnInTube, position, 50, 0.69803923f) (soundTargets.map(_.Name) ++ additionalChannels).foreach { target => events ! LocalServiceMessage(target, soundMessage) } @@ -1208,7 +1208,8 @@ class ZoningOperations( if (llu.Carrier.nonEmpty) { continent.LocalEvents ! LocalServiceMessage( continent.id, - LocalAction.SendPacket(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252)) + PlanetSideGUID(-1), + LocalAction.SendResponse(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252)) ) } case _ => () @@ -3993,10 +3994,18 @@ class ZoningOperations( val pZone = player.Zone sendResponse(GenericActionMessage(FirstPersonViewWithEffect)) pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID => - pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendGenericObjectActionMessage(t.GUID, player.GUID, GenericObjectActionEnum.PlayerDeconstructs)) + pZone.LocalEvents ! LocalServiceMessage( + t.Name, + t.GUID, + LocalAction.GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs) + ) } pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction => - pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendGenericObjectActionMessage(t.GUID, player.GUID, GenericObjectActionEnum.PlayerDeconstructs)) + pZone.LocalEvents ! LocalServiceMessage( + t.Name, + t.GUID, + LocalAction.GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs) + ) } } diff --git a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala index ebfb38a80..7cff60fa9 100644 --- a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala @@ -8,8 +8,9 @@ import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails, ZoneAct import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} +import net.psforever.services.local.support.HackClearActor +import net.psforever.services.local.ClearMessage +import net.psforever.types.PlanetSideEmpire /** * The logic that governs facilities and structures found in the cavern regions. @@ -52,7 +53,7 @@ case object CavernFacilityLogic // When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state building.HackableAmenities.foreach(amenity => { if (amenity.HackedBy.isDefined) { - building.Zone.LocalEvents ! LocalServiceMessage(amenity.Zone.id,LocalAction.ClearTemporaryHack(PlanetSideGUID(0), amenity)) + building.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(amenity)) } }) // No map update needed - will be sent by `HackCaptureActor` when required diff --git a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala index 1290b9956..41c39b13e 100644 --- a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala @@ -8,8 +8,9 @@ import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails} import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} +import net.psforever.services.local.support.HackClearActor +import net.psforever.services.local.ClearMessage +import net.psforever.types.PlanetSideEmpire /** * The logic that governs standard facilities and structures. @@ -52,7 +53,7 @@ case object FacilityLogic // When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state building.HackableAmenities.foreach(amenity => { if (amenity.HackedBy.isDefined) { - building.Zone.LocalEvents ! LocalServiceMessage(amenity.Zone.id, LocalAction.ClearTemporaryHack(PlanetSideGUID(0), amenity)) + building.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(amenity)) } }) // No map update needed - will be sent by `HackCaptureActor` when required diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index 85ba63316..c1d1774e2 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -14,11 +14,12 @@ import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.PlanetsideAttributeMessage -import net.psforever.services.{InterstellarClusterService, Service} +import net.psforever.services.InterstellarClusterService import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} +import net.psforever.services.local.{CaptureMessage, ClearMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.{HackCaptureActor, HackClearActor} +import net.psforever.types.PlanetSideEmpire /** * A package class that conveys the important information for handling facility updates. @@ -101,10 +102,7 @@ case object MajorFacilityLogic hackedAmenities } amenitiesToClear.foreach { amenity => - building.Zone.LocalEvents ! LocalServiceMessage( - amenity.Zone.id, - LocalAction.ClearTemporaryHack(PlanetSideGUID(0), amenity) - ) + building.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(amenity)) } // No map update needed - will be sent by `HackCaptureActor` when required case dome: ForceDomePhysics => @@ -283,7 +281,7 @@ case object MajorFacilityLogic (bldg.GetFlag, bldg.CaptureTerminal) match { case (Some(flag), Some(terminal)) if (flag.Target eq building) && flag.Faction != building.Faction => //our hack destination may have been compromised and the hack needs to be cancelled - bldg.Zone.LocalEvents ! LocalServiceMessage("", LocalAction.ResecureCaptureTerminal(terminal, PlayerSource.Nobody)) + bldg.Zone.LocalEvents ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(terminal, terminal.Zone, PlayerSource.Nobody)) case _ => () } Behaviors.same diff --git a/src/main/scala/net/psforever/login/WorldSession.scala b/src/main/scala/net/psforever/login/WorldSession.scala index 1cc61d0ba..18914d471 100644 --- a/src/main/scala/net/psforever/login/WorldSession.scala +++ b/src/main/scala/net/psforever/login/WorldSession.scala @@ -15,7 +15,6 @@ import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.TerminalUsedActivity import net.psforever.objects.zones.Zone import net.psforever.types.{ExoSuitType, PlanetSideGUID, TransactionType, Vector3} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import scala.concurrent.ExecutionContext.Implicits.global diff --git a/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/src/main/scala/net/psforever/objects/BoomerDeployable.scala index 70daf0990..60d2c8fbb 100644 --- a/src/main/scala/net/psforever/objects/BoomerDeployable.scala +++ b/src/main/scala/net/psforever/objects/BoomerDeployable.scala @@ -11,7 +11,6 @@ import net.psforever.objects.vital.Vitality import net.psforever.objects.vital.etc.TriggerUsedReason import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.zones.Zone -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideEmpire diff --git a/src/main/scala/net/psforever/objects/Deployables.scala b/src/main/scala/net/psforever/objects/Deployables.scala index c75057197..961ba941d 100644 --- a/src/main/scala/net/psforever/objects/Deployables.scala +++ b/src/main/scala/net/psforever/objects/Deployables.scala @@ -94,11 +94,7 @@ object Deployables { } events ! LocalServiceMessage( s"${target.Faction}", - LocalAction.DeployableMapIcon( - PlanetSideGUID(0), - DeploymentAction.Dismiss, - DeployableInfo(target.GUID, Deployable.Icon(item), target.Position, PlanetSideGUID(0)) - ) + LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, DeployableInfo(target.GUID, Deployable.Icon(item), target.Position, PlanetSideGUID(0))) ) } diff --git a/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala b/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala index ceea45622..adf103058 100644 --- a/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala +++ b/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala @@ -217,7 +217,7 @@ object ExplosiveDeployableControl { if (target.Health == 0) { zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffect(Service.defaultPlayerGUID, "detonate_damaged_mine", target.GUID) + LocalAction.TriggerEffect("detonate_damaged_mine", target.GUID) ) } } diff --git a/src/main/scala/net/psforever/objects/SensorDeployable.scala b/src/main/scala/net/psforever/objects/SensorDeployable.scala index cd08bedb3..cea1251aa 100644 --- a/src/main/scala/net/psforever/objects/SensorDeployable.scala +++ b/src/main/scala/net/psforever/objects/SensorDeployable.scala @@ -89,7 +89,7 @@ class SensorDeployableControl(sensor: SensorDeployable) val zone = obj.Zone zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, unk1=false, 1000) + LocalAction.TriggerEffectInfo(obj.GUID, "on", unk1=false, 1000) ) super.StartJammeredStatus(obj, dur) case _ => ; @@ -114,7 +114,7 @@ class SensorDeployableControl(sensor: SensorDeployable) val zone = sensor.Zone zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, unk1=true, 1000) + LocalAction.TriggerEffectInfo(obj.GUID, "on", unk1=true, 1000) ) case _ => ; } @@ -126,7 +126,7 @@ class SensorDeployableControl(sensor: SensorDeployable) val zone = sensor.Zone zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", sensor.GUID, unk1=true, 1000) + LocalAction.TriggerEffectInfo(sensor.GUID, "on", unk1=true, 1000) ) } } @@ -143,7 +143,7 @@ object SensorDeployableControl { val zone = target.Zone zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", target.GUID, unk1=false, 1000) + LocalAction.TriggerEffectInfo(target.GUID, "on", unk1=false, 1000) ) //position the explosion effect near the bulky area of the sensor stalk val ang = target.Orientation @@ -159,7 +159,7 @@ object SensorDeployableControl { } zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, "motion_sensor_destroyed", explosionPos, ang) + LocalAction.TriggerEffectLocation("motion_sensor_destroyed", explosionPos, ang) ) //TODO replaced by an alternate model (charred stub)? } diff --git a/src/main/scala/net/psforever/objects/Tools.scala b/src/main/scala/net/psforever/objects/Tools.scala index 7931799b1..2a10cff8b 100644 --- a/src/main/scala/net/psforever/objects/Tools.scala +++ b/src/main/scala/net/psforever/objects/Tools.scala @@ -3,7 +3,6 @@ package net.psforever.objects import net.psforever.objects.equipment.ChargeFireModeDefinition import net.psforever.packet.game.QuantityUpdateMessage -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} object Tools { diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index d260db95d..5ae4191fe 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -279,7 +279,9 @@ object Vehicles { if (GlobalDefinitions.isBattleFrameVehicle(target.Definition) && target.Seat(0).isDefined) { zone.LocalEvents ! LocalServiceMessage( zoneid, - LocalAction.SendGenericObjectActionMessage(PlanetSideGUID(-1), target.GUID, GenericObjectActionEnum.BFRShieldsDown)) + PlanetSideGUID(-1), + LocalAction.GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown) + ) zone.LocalEvents ! LocalServiceMessage( zoneid, LocalAction.SendResponse( @@ -319,7 +321,8 @@ object Vehicles { } localEvents ! LocalServiceMessage( zoneid, - LocalAction.TriggerSound(hGuid, TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f) + hGuid, + LocalAction.TriggerSound(TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f) ) if (zone.Players.exists(_.name.equals(previousOwnerName))) { localEvents ! LocalServiceMessage( diff --git a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala index 2952ec1ba..e8ba49f2d 100644 --- a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala @@ -8,7 +8,6 @@ import net.psforever.objects.serverobject.containable.{Containable, ContainableB import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types.{PlanetSideEmpire, Vector3} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} class CorpseControl(player: Player) extends Actor with ContainableBehavior { diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 4d74a78d4..812abd18c 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -371,7 +371,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //make sure the player didn't just initialte an orbital strike. If not (the if below is true), make sure waypoint is removed if (holsteredEquipment.Definition == GlobalDefinitions.command_detonater && player.avatar.cr.value > 3 && !player.avatar.cooldowns.purchase.exists(os => os._1 == "orbital_strike" && Seconds.secondsBetween(os._2, LocalDateTime.now()).getSeconds < 12)) { - player.Zone.LocalEvents ! LocalServiceMessage(s"${player.Faction}", LocalAction.SendPacket(OrbitalStrikeWaypointMessage(player.GUID, None))) + player.Zone.LocalEvents ! LocalServiceMessage( + s"${player.Faction}", + PlanetSideGUID(-1), + LocalAction.SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) + ) } case None => log.info(s"${player.Name} lowers ${player.Sex.possessive} hand") @@ -764,14 +768,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case GlobalDefinitions.router_telepad => () /* no special animation */ case GlobalDefinitions.ace if obj.Definition.deployAnimation == DeployAnimation.Standard => + val ownerGuid = obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID) zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerEffectLocation( - obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID), - "spawn_object_effect", - obj.Position, - obj.Orientation - ) + ownerGuid, + LocalAction.TriggerEffectLocation("spawn_object_effect", obj.Position, obj.Orientation) ) case GlobalDefinitions.advanced_ace if obj.Definition.deployAnimation == DeployAnimation.Fdu => diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala index 16d51f2a9..2d2b3f038 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala @@ -91,7 +91,7 @@ class WithEntrance() import net.psforever.objects.{Player, Vehicle} import net.psforever.packet.game.ChatMsg import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} - import net.psforever.types.{ChatMessageType, PlanetSideGUID} + import net.psforever.types.ChatMessageType val channel = obj match { case p: Player => p.Name case v: Vehicle => v.Actor.toString() diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala index 2be15ee38..62e84c2c4 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala @@ -7,7 +7,6 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.hart.ShuttleState import net.psforever.types.ChatMessageType diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index b88d6f3dd..d7227edd2 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -202,11 +202,7 @@ trait DeployableBehavior { //zone map icon localEvents ! LocalServiceMessage( obj.Faction.toString, - LocalAction.DeployableMapIcon( - Service.defaultPlayerGUID, - DeploymentAction.Build, - DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID)) - ) + LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID))) ) //local build management callback ! Zone.Deployable.IsBuilt(obj) @@ -293,7 +289,7 @@ object DeployableBehavior { //remove knowledge by the previous owner's faction localEvents ! LocalServiceMessage( originalFaction.toString, - LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Dismiss, info) + LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, info) ) //remove deployable from original owner's toolbox and UI counter zone.AllPlayers.filter(p => obj.OriginalOwnerName.contains(p.Name)) @@ -304,7 +300,7 @@ object DeployableBehavior { //display to the given faction localEvents ! LocalServiceMessage( toFaction.toString, - LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Build, info) + LocalAction.DeployableMapIcon(DeploymentAction.Build, info) ) } } diff --git a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala index c7a8c2e03..c4f410be7 100644 --- a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala +++ b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala @@ -6,7 +6,6 @@ import net.psforever.objects.equipment.Equipment import net.psforever.objects.serverobject.containable.{Containable, ContainableBehavior} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.types.{PlanetSideEmpire, Vector3} @@ -19,7 +18,7 @@ import net.psforever.types.{PlanetSideEmpire, Vector3} class LockerContainerControl(locker: LockerContainer, toChannel: String) extends Actor with ContainableBehavior { - def ContainerObject = locker + def ContainerObject: LockerContainer = locker def receive: Receive = containerBehavior diff --git a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala index 1cd30f116..93db203e1 100644 --- a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffi import net.psforever.objects.serverobject.locks.IFFLock import net.psforever.objects.serverobject.structures.PoweredAmenityControl import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse} +import net.psforever.services.local.{LocalAction, LocalServiceMessage, LocalServiceResponse} /** * An `Actor` that handles messages being dispatched to a specific `Door`. @@ -107,20 +107,19 @@ object DoorControl { */ private def openDoor(player: Player, door: Door, replyTo: ActorRef = Default.Actor): Unit = { val zone = door.Zone - val doorGUID = door.GUID if (!door.isOpen) { //global open door.Open = player zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.DoorOpens(Service.defaultPlayerGUID, zone, door) + LocalAction.DoorOpens(zone, door) ) } else { //the door should already open, but the requesting player does not see it as open replyTo ! LocalServiceResponse( player.Name, Service.defaultPlayerGUID, - LocalResponse.DoorOpens(doorGUID) + LocalAction.DoorOpens(door.Zone, door) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala index 9e78167d7..824c17a01 100644 --- a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala @@ -13,7 +13,6 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.TriggerEffectMessage import net.psforever.types.{PlanetSideGeneratorState, Vector3} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index f896bd655..fa80748ae 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -11,9 +11,9 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.HackClearActor +import net.psforever.services.local.{ClearMessage, HackEntityMessage, LocalAction, LocalServiceMessage} import scala.annotation.unused import scala.util.{Failure, Success} @@ -172,12 +172,15 @@ object GenericHackables { log.info(s"${user.Name} hacked a ${target.Definition.Name}") zone.LocalEvents ! LocalServiceMessage( zoneId, - LocalAction.TriggerSound(pguid, target.HackSound, tplayer.Position, 30, 0.49803925f) + pguid, + LocalAction.TriggerSound(target.HackSound, tplayer.Position, 30, 0.49803925f) ) - zone.LocalEvents ! LocalServiceMessage( + val duration = target.HackEffectDuration(user.avatar.hackingSkillLevel()) + zone.LocalEvents ! HackEntityMessage( zoneId, - LocalAction - .HackTemporarily(pguid, zone, target, hackValue, hackClearValue, target.HackEffectDuration(user.avatar.hackingSkillLevel())) + pguid, + LocalAction.HackTemporarily(zone, target, hackValue, hackClearValue, duration), + HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, duration) ) case Failure(_) => log.warn(s"Hack message failed on target: ${target.Definition.Name}@${target.GUID.guid}") @@ -202,11 +205,7 @@ object GenericHackables { val currVirus = building.virusId building.virusId = 8 building.virusInstalledBy = None - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction - .ClearTemporaryHack(pguid, target) - ) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(target)) zone.LocalEvents ! LocalServiceMessage( zone.id, LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 60)) @@ -214,17 +213,11 @@ object GenericHackables { currVirus match { case 0L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff => - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction.ClearTemporaryHack(PlanetSideGUID(0), iff) - ) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(iff)) } case 4L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term => - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction.ClearTemporaryHack(PlanetSideGUID(0), term) - ) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) } case _ => () } @@ -238,19 +231,13 @@ object GenericHackables { case 0L => if (virus != 0) { building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff => - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction.ClearTemporaryHack(PlanetSideGUID(0), iff) - ) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(iff)) } } case 4L => if (virus != 4) { building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term => - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction.ClearTemporaryHack(PlanetSideGUID(0), term) - ) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) } } case _ => () @@ -275,12 +262,14 @@ object GenericHackables { building.virusInstalledBy = Some(tplayer.Faction.id) zone.LocalEvents ! LocalServiceMessage( zoneId, - LocalAction.TriggerSound(pguid, TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f) + pguid, + LocalAction.TriggerSound(TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f) ) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! HackEntityMessage( zoneId, - LocalAction - .HackTemporarily(pguid, zone, target, installedVirusDuration, hackClearValue, installedVirusDuration, unk2=hackState) + pguid, + LocalAction.HackTemporarily(zone, target, installedVirusDuration, hackClearValue, installedVirusDuration, unk2=hackState), + HackClearActor.ObjectIsHacked(target, zone, hackClearValue, hackState, installedVirusDuration) ) zone.LocalEvents ! LocalServiceMessage( zone.id, @@ -294,21 +283,23 @@ object GenericHackables { virus match { case 0L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach{ iff => - var setHacked = iff.asInstanceOf[PlanetSideServerObject with Hackable] - setHacked.HackedBy = tplayer - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction.HackTemporarily(pguid, zone, iff, hackValue, hackClearValue, installedVirusDuration) - ) + iff.HackedBy = tplayer + zone.LocalEvents ! HackEntityMessage( + zoneId, + pguid, + LocalAction.HackTemporarily(zone, iff, hackValue, hackClearValue, installedVirusDuration), + HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, installedVirusDuration) + ) } case 4L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach{ term => - var setHacked = term.asInstanceOf[PlanetSideServerObject with Hackable] - setHacked.HackedBy = tplayer - zone.LocalEvents ! LocalServiceMessage( - zoneId, - LocalAction.HackTemporarily(pguid, zone, term, hackValue, hackClearValue, installedVirusDuration) - ) + term.HackedBy = tplayer + zone.LocalEvents ! HackEntityMessage( + zoneId, + pguid, + LocalAction.HackTemporarily(zone, term, hackValue, hackClearValue, installedVirusDuration), + HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, installedVirusDuration) + ) } case _ => () } diff --git a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala index 4e10f1fba..35f833ac6 100644 --- a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala +++ b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala @@ -1,8 +1,8 @@ // Copyright (c) 2020 PSForever package net.psforever.objects.serverobject.locks -import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.HackClearActor +import net.psforever.services.local.ClearMessage object IFFLocks { @@ -14,9 +14,6 @@ object IFFLocks { */ def FinishResecuringIFFLock(lock: IFFLock)(): Unit = { val zone = lock.Zone - lock.Zone.LocalEvents ! LocalServiceMessage( - zone.id, - LocalAction.ClearTemporaryHack(Service.defaultPlayerGUID, lock) - ) + lock.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(lock)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index e5a66a778..771c632b9 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -8,7 +8,6 @@ import net.psforever.objects.vital.RepairFromEquipment import net.psforever.objects.{Player, Tool} import net.psforever.packet.game.{ChatMsg, InventoryStateMessage, RepairMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} /** diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index 2444eb248..8871f5bc0 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -106,7 +106,6 @@ trait FacilityHackParticipation extends ParticipationLogic { if (building.virusId != 8) { import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.objects.GlobalDefinitions - import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} val mainTerm = building.Amenities.filter(x => x.isInstanceOf[Terminal] && x.Definition == GlobalDefinitions.main_terminal).head.GUID val msg1 = AvatarAction.GenericObjectAction(mainTerm, 61) diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index 7e3cdae59..d96f0d4c7 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -6,6 +6,8 @@ import net.psforever.objects.serverobject.damage.Damageable import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 +import net.psforever.services.local.ClearMessage +import net.psforever.services.local.support.HackClearActor import org.log4s.Logger import scala.annotation.unused @@ -147,7 +149,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) tryAutoRepair() if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ClearTemporaryHack(Service.defaultPlayerGUID, term)) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) } super.DestructionAwareness(target, cause) } @@ -181,7 +183,8 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) self, ProximityTerminalControl.TerminalAction() ) - TerminalObject.Zone.LocalEvents ! Terminal.StartProximityEffect(term) + val zone = TerminalObject.Zone + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = true)) } } else { log.warn(s"ProximityTerminal.Use: $target was rejected by unit ${term.Definition.Name}@${term.GUID.guid}") @@ -201,7 +204,8 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) //de-activation (global / local) if (term.NumberUsers == 0 && hadUsers) { terminalAction.cancel() - TerminalObject.Zone.LocalEvents ! Terminal.StopProximityEffect(term) + val zone = TerminalObject.Zone + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = false)) } } else { log.debug( @@ -216,12 +220,13 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) terminalAction.cancel() if (callbacks.nonEmpty) { callbacks.clear() - TerminalObject.Zone.LocalEvents ! Terminal.StopProximityEffect(term) + val zone = TerminalObject.Zone + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = true)) } //clear hack state if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ClearTemporaryHack(Service.defaultPlayerGUID, term)) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala index b3a80776e..20608652d 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala @@ -12,8 +12,8 @@ import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableA import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 -import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.HackClearActor +import net.psforever.services.local.ClearMessage /** * An `Actor` that handles messages being dispatched to a specific `Terminal`. @@ -100,7 +100,7 @@ class TerminalControl(term: Terminal) tryAutoRepair() if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ClearTemporaryHack(Service.defaultPlayerGUID, term)) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) } super.DestructionAwareness(target, cause) } @@ -122,7 +122,7 @@ class TerminalControl(term: Terminal) //clear hack state if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ClearTemporaryHack(Service.defaultPlayerGUID, term)) + zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala index 9f07bce14..b1a233b72 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala @@ -6,8 +6,9 @@ import net.psforever.objects.serverobject.hackable.GenericHackables import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideEmpire +import net.psforever.services.local.support.HackCaptureActor import scala.concurrent.duration._ import scala.util.{Failure, Success} @@ -41,20 +42,15 @@ object CaptureTerminals { val isResecured = hackingPlayer.Faction == target.Faction events ! LocalServiceMessage( zoneid, - LocalAction.TriggerSound(hackingPlayer.GUID, target.HackSound, hackingPlayer.Position, 30, 0.49803925f) + hackingPlayer.GUID, + LocalAction.TriggerSound(target.HackSound, hackingPlayer.Position, 30, 0.49803925f) ) if (isResecured) { // Resecure the CC - events ! LocalServiceMessage( - zoneid, - LocalAction.ResecureCaptureTerminal(target, PlayerSource(hackingPlayer)) - ) + events ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(target, zone, PlayerSource(hackingPlayer))) } else { // Start the CC hack timer - events ! LocalServiceMessage( - zoneid, - LocalAction.StartCaptureTerminalHack(target) - ) + events ! CaptureMessage(HackCaptureActor.StartCaptureTerminalHack(target, zone, 0, 8L)) } case Failure(_) => log.warn(s"Hack message failed on target guid: ${target.GUID}") diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala index 4a6cb991c..ed408438e 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala @@ -53,7 +53,8 @@ class VanuSentryControl(turret: FacilityTurret) case player: Player => TurretObject.Zone.LocalEvents ! LocalServiceMessage( TurretObject.Zone.id, - LocalAction.RechargeVehicleWeapon(player.GUID, TurretObject.GUID, weapon.GUID) + player.GUID, + LocalAction.RechargeVehicleWeapon(TurretObject.GUID, weapon.GUID) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index d223c4c56..4d6db7e1b 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -5,7 +5,6 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.ce.Deployable import net.psforever.objects.{Player, Tool, TurretDeployable} import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -121,7 +120,8 @@ object WeaponTurrets { ) zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.TriggerSound(hacker.GUID, target.HackSound, target.Position, 30, 0.49803925f) + hacker.GUID, + LocalAction.TriggerSound(target.HackSound, target.Position, 30, 0.49803925f) ) } else { //deconstruct diff --git a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala index 331db4721..2ab9aa6bf 100644 --- a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala +++ b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala @@ -39,7 +39,6 @@ class WithEntranceInVehicle private def warnAboutProximity(obj: InteractsWithZone, msg: String): Unit = { import net.psforever.packet.game.ChatMsg - import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.types.ChatMessageType obj.Zone.AvatarEvents ! AvatarServiceMessage( diff --git a/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala index 556f6f9de..0d362a661 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala @@ -5,8 +5,7 @@ import akka.actor.Actor import net.psforever.actors.zone.ZoneActor import net.psforever.objects.equipment.Equipment import net.psforever.types.PlanetSideGUID -import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, DropItemMessage, PickupItemMessage} +import net.psforever.services.avatar.{AvatarAction, DropItemMessage, PickupItemMessage} import scala.annotation.tailrec import scala.collection.mutable.ListBuffer diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 95784b450..af9886d5f 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -4,7 +4,7 @@ package net.psforever.services.avatar.support import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.Player import net.psforever.types.ExoSuitType -import net.psforever.services.{RemoverActor, Service} +import net.psforever.services.RemoverActor import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index 25c224f66..11c9fd197 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -3,7 +3,7 @@ package net.psforever.services.avatar.support import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.{GUIDTask, TaskBundle} -import net.psforever.services.{RemoverActor, Service} +import net.psforever.services.RemoverActor import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/services/local/LocalAction.scala b/src/main/scala/net/psforever/services/local/LocalAction.scala new file mode 100644 index 000000000..917af8f46 --- /dev/null +++ b/src/main/scala/net/psforever/services/local/LocalAction.scala @@ -0,0 +1,204 @@ +// Copyright (c) 2017-2026 PSForever +package net.psforever.services.local + +import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle} +import net.psforever.objects.ce.{Deployable, DeployedItem} +import net.psforever.objects.serverobject.PlanetSideServerObject +import net.psforever.objects.serverobject.doors.Door +import net.psforever.objects.serverobject.llu.CaptureFlag +import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} +import net.psforever.objects.vehicles.Utility +import net.psforever.objects.zones.Zone +import net.psforever.packet.PlanetSideGamePacket +import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum +import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum +import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound} +import net.psforever.services.base.{EventMessage, EventResponse, SelfResponseMessage} +import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent +import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} + +object LocalAction { + trait Action extends EventMessage { + def response(): EventResponse = null + } + + final case class DeployItem(item: Deployable) extends EventMessage { + def response(): EventResponse = { + val definition = item.Definition + val objectData = definition.Packet.ConstructorData(item).get + LocalAction.SendResponse(ObjectCreateMessage(definition.ObjectId, item.GUID, objectData)) + } + } + + final case class DeployableMapIcon(behavior: DeploymentAction.Value, deployInfo: DeployableInfo) extends SelfResponseMessage + + final case class DeployableUIFor(obj: DeployedItem.Value) extends SelfResponseMessage + + final case class Detonate(guid: PlanetSideGUID, obj: PlanetSideGameObject) extends SelfResponseMessage + + final case class DoorOpens(continent: Zone, door: Door) extends SelfResponseMessage + + final case class DoorCloses(door_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class DoorSlamsShut(door: Door) extends EventMessage { + def response(): EventResponse = { + //todo important! doorCloser ! SupportActor.HurrySpecific(List(door), zone) + DoorCloses(door.GUID) + } + } + + final case class EliminateDeployable( + obj: Deployable, + object_guid: PlanetSideGUID, + pos: Vector3, + deletionEffect: Int + ) extends SelfResponseMessage + + final case class SendHackMessageHackCleared( + target_guid: PlanetSideGUID, + unk1: Long, + unk2: HackState7 + ) extends SelfResponseMessage + + final case class HackClear( + target: PlanetSideServerObject, + unk1: Long, + unk2: HackState7 = HackState7.Unk8 + ) extends EventMessage { + def response(): EventResponse = { + SendHackMessageHackCleared(target.GUID, unk1, unk2) + } + } + + final case class HackObject(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends EventResponse + + final case class HackTemporarily( + continent: Zone, + target: PlanetSideServerObject, + hackValue: Long, + hackClearValue: Long, + duration: Int, + unk2: HackState7 = HackState7.Unk8 + ) extends EventMessage { + def response(): EventResponse = { + HackObject(target.GUID, hackValue, unk2) + } + } + + final case class LluSpawned(llu: CaptureFlag) extends SelfResponseMessage + + final case class LluDespawned( + guid: PlanetSideGUID, + position: Vector3 + ) extends SelfResponseMessage + + final case class PlanetsideAttribute( + target_guid: PlanetSideGUID, + attribute_number: PlanetsideAttributeEnum, + attribute_value: Long + ) extends SelfResponseMessage + + final case class ChatMessage(msg: ChatMsg) extends SelfResponseMessage + + final case class GenericObjectAction( + target_guid: PlanetSideGUID, + action_number: GenericObjectActionEnum + ) extends SelfResponseMessage + + final case class GenericActionMessage(action_num: GenericAction) extends SelfResponseMessage + + final case class ObjectDelete(item_guid: PlanetSideGUID, unk: Int) extends EventResponse + + final case class ProximityTerminalAction( + terminal: Terminal with ProximityUnit, + target: PlanetSideGameObject + ) extends EventResponse + + final case class ProximityTerminalEffect( + object_guid: PlanetSideGUID, + effectState: Boolean + ) extends SelfResponseMessage + + final case class RouterTelepadMessage(msg: String) extends SelfResponseMessage + + final case class RouterTelepadTransport( + passenger_guid: PlanetSideGUID, + src_guid: PlanetSideGUID, + dest_guid: PlanetSideGUID + ) extends SelfResponseMessage + + final case class SendResponse(pkt: PlanetSideGamePacket) extends SelfResponseMessage + + final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends SelfResponseMessage + + final case class ShuttleDock(pad_guid: PlanetSideGUID, shuttle_guid: PlanetSideGUID, toSlot: Int) extends SelfResponseMessage + + final case class ShuttleUndock( + pad_guid: PlanetSideGUID, + shuttle_guid: PlanetSideGUID, + pos: Vector3, orient: Vector3 + ) extends SelfResponseMessage + + final case class ShuttleEvent(ev: OrbitalShuttleEvent) extends SelfResponseMessage + + final case class ShuttleState(guid: PlanetSideGUID, pos: Vector3, orientation: Vector3, state: Int) extends SelfResponseMessage + + final case class StartRouterInternalTelepad( + router_guid: PlanetSideGUID, + obj_guid: PlanetSideGUID, + obj: Utility.InternalTelepad + ) extends SelfResponseMessage + + final case class ToggleTeleportSystem( + router: Vehicle, + systemPlan: Option[(Utility.InternalTelepad, TelepadDeployable)] + ) extends SelfResponseMessage + + final case class TriggerEffectAtLocation( + target: PlanetSideGUID, + effect: String, + effectInfo: Option[TriggeredEffect] = None, + triggeredLocation: Option[TriggeredEffectLocation] = None + ) extends EventResponse + + final case class TriggerEffect(effect: String, target: PlanetSideGUID) extends EventMessage { + def response(): EventResponse = { + TriggerEffectAtLocation(target, effect) + } + } + + final case class TriggerEffectInfo(target: PlanetSideGUID, effect: String, unk1: Boolean, unk2: Long) extends EventMessage { + def response(): EventResponse = { + TriggerEffectAtLocation(target, effect, Some(TriggeredEffect(unk1, unk2))) + } + } + + final case class TriggerEffectLocation( + effect: String, + pos: Vector3, + orient: Vector3 + ) extends EventMessage { + def response(): EventResponse = { + TriggerEffectAtLocation(PlanetSideGUID(0), effect, None, Some(TriggeredEffectLocation(pos, orient))) + } + } + + final case class TriggerSound( + sound: TriggeredSound.Value, + pos: Vector3, + unk: Int, + volume: Float + ) extends SelfResponseMessage + + final case class UpdateForceDomeStatus( + building_guid: PlanetSideGUID, + activated: Boolean + ) extends SelfResponseMessage + + final case class RechargeVehicleWeapon( + mountable_guid: PlanetSideGUID, + weapon_guid: PlanetSideGUID + ) extends SelfResponseMessage + + final case class ForceZoneChange(zone: Zone) extends SelfResponseMessage +} diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index 6ac2eaae0..e7ee464a8 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -1,363 +1,50 @@ // Copyright (c) 2017 PSForever package net.psforever.services.local -import akka.actor.{Actor, Props} -import net.psforever.objects.serverobject.terminals.Terminal +import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.zones.Zone -import net.psforever.packet.game.{ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation} import net.psforever.services.local.support.CaptureFlagManager -import net.psforever.types.PlanetSideGUID import net.psforever.services.local.support._ -import net.psforever.services.Service -import net.psforever.services.base.GenericEventBus -import net.psforever.services.base.support.SupportActor +import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericMessageEnvelope} -class LocalService(zone: Zone) extends Actor { - private val doorCloser = context.actorOf( - Props[DoorCloseActor](), s"${zone.id}-local-door-closer" - ) - private val hackClearer = context.actorOf( - Props[HackClearActor](), s"${zone.id}-local-hack-clearer" - ) - private val hackCapturer = context.actorOf( - Props[HackCaptureActor](), s"${zone.id}-local-hack-capturer" - ) - private val captureFlagManager = context.actorOf( - Props(classOf[CaptureFlagManager], zone), s"${zone.id}-local-capture-flag-manager" - ) - private[this] val log = org.log4s.getLogger - - val LocalEvents = new GenericEventBus[LocalServiceResponse] - - def receive: Receive = { - case Service.Join(channel) => - val path = s"/$channel/Local" - LocalEvents.subscribe(sender(), path) - - case Service.Leave(None) => - LocalEvents.unsubscribe(sender()) - - case Service.Leave(Some(channel)) => - val path = s"/$channel/Local" - LocalEvents.unsubscribe(sender(), path) - - case Service.LeaveAll() => - LocalEvents.unsubscribe(sender()) - - case LocalServiceMessage(forChannel, action) => - action match { - case LocalAction.DeployItem(item) => - val definition = item.Definition - val objectData = definition.Packet.ConstructorData(item).get - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.SendResponse(ObjectCreateMessage(definition.ObjectId, item.GUID, objectData)) - ) - ) - case LocalAction.DeployableMapIcon(player_guid, behavior, deployInfo) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.DeployableMapIcon(behavior, deployInfo) - ) - ) - case LocalAction.DeployableUIFor(item) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.DeployableUIFor(item) - ) - ) - case LocalAction.Detonate(guid, obj) => - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", Service.defaultPlayerGUID, LocalResponse.Detonate(guid, obj)) - ) - case LocalAction.DoorOpens(player_guid, _, door) => - doorCloser ! DoorCloseActor.DoorIsOpen(door, zone) - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.DoorOpens(door.GUID)) - ) - case LocalAction.DoorCloses(player_guid, door_guid) => - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.DoorCloses(door_guid)) - ) - case LocalAction.DoorSlamsShut(door) => - val door_guid = door.GUID - doorCloser ! SupportActor.HurrySpecific(List(door), zone) - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", Service.defaultPlayerGUID, LocalResponse.DoorCloses(door_guid)) - ) - case LocalAction.EliminateDeployable(obj, guid, pos, effect) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.EliminateDeployable(obj, guid, pos, effect) - ) - ) - case LocalAction.HackClear(player_guid, target, unk1, unk2) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.SendHackMessageHackCleared(target.GUID, unk1, unk2) - ) - ) - case LocalAction.HackTemporarily(player_guid, _, target, hackValue, hackClear, duration, unk2) => - hackClearer ! HackClearActor.ObjectIsHacked(target, zone, hackClear, unk2, duration) - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackObject(target.GUID, hackValue, unk2)) - ) - case LocalAction.ClearTemporaryHack(_, target) => - hackClearer ! HackClearActor.ObjectIsResecured(target) - - case LocalAction.ResecureCaptureTerminal(target, hacker) => - hackCapturer ! HackCaptureActor.ResecureCaptureTerminal(target, zone, hacker) - case LocalAction.StartCaptureTerminalHack(target) => - hackCapturer ! HackCaptureActor.StartCaptureTerminalHack(target, zone, 0, 8L) - case LocalAction.LluCaptured(llu) => - hackCapturer ! HackCaptureActor.FlagCaptured(llu) - case LocalAction.LluLost(llu) => - hackCapturer ! HackCaptureActor.FlagLost(llu) - - case LocalAction.LluSpawned(player_guid, llu) => - // Forward to all clients to create object locally - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.LluSpawned(llu) - ) - ) - - case LocalAction.LluDespawned(player_guid, guid, position) => - // Forward to all clients to destroy object locally - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.LluDespawned(guid, position) - ) - ) - - case LocalAction.SendPacket(packet) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - PlanetSideGUID(-1), - LocalResponse.SendPacket(packet) - ) - ) - - case LocalAction.SendPlanetsideAttributeMessage(player_guid, target_guid, attribute_number, attribute_value) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.PlanetsideAttribute(target_guid, attribute_number, attribute_value) - ) - ) - case LocalAction.SendGenericObjectActionMessage(player_guid, target_guid, action_number) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.GenericObjectAction(target_guid, action_number) - ) - ) - - case LocalAction.SendChatMsg(player_guid, msg) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.ChatMessage(msg) - ) - ) - - case LocalAction.SendGenericActionMessage(player_guid, action_number) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.GenericActionMessage(action_number) - ) - ) - case LocalAction.RouterTelepadMessage(msg) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.RouterTelepadMessage(msg) - ) - ) - case LocalAction.RouterTelepadTransport(player_guid, passenger_guid, src_guid, dest_guid) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.RouterTelepadTransport(passenger_guid, src_guid, dest_guid) - ) - ) - case LocalAction.SendResponse(pkt) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.SendResponse(pkt) - ) - ) - case LocalAction.SetEmpire(object_guid, empire) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.SetEmpire(object_guid, empire) - ) - ) - case LocalAction.ShuttleDock(pad, shuttle, slot) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.ShuttleDock(pad, shuttle, slot) - ) - ) - case LocalAction.ShuttleUndock(pad, shuttle, pos, orient) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.ShuttleUndock(pad, shuttle, pos, orient) - ) - ) - case LocalAction.ShuttleEvent(ev) => - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", Service.defaultPlayerGUID, LocalResponse.ShuttleEvent(ev)) - ) - case LocalAction.ShuttleState(guid, pos, orient, state) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.ShuttleState(guid, pos, orient, state) - ) - ) - case LocalAction.StartRouterInternalTelepad(router_guid, obj_guid, obj) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.StartRouterInternalTelepad(router_guid, obj_guid, obj) - ) - ) - case LocalAction.ToggleTeleportSystem(player_guid, router, system_plan) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.ToggleTeleportSystem(router, system_plan) - ) - ) - case LocalAction.TriggerEffect(player_guid, effect, target) => - LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.TriggerEffect(target, effect)) - ) - case LocalAction.TriggerEffectLocation(player_guid, effect, pos, orient) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.TriggerEffect(PlanetSideGUID(0), effect, None, Some(TriggeredEffectLocation(pos, orient))) - ) - ) - case LocalAction.TriggerEffectInfo(player_guid, effect, target, unk1, unk2) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.TriggerEffect(target, effect, Some(TriggeredEffect(unk1, unk2))) - ) - ) - case LocalAction.TriggerSound(player_guid, sound, pos, unk, volume) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.TriggerSound(sound, pos, unk, volume) - ) - ) - case LocalAction.UpdateForceDomeStatus(player_guid, building_guid, activated) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.UpdateForceDomeStatus(building_guid, activated) - ) - ) - case LocalAction.RechargeVehicleWeapon(player_guid, vehicle_guid, weapon_guid) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - player_guid, - LocalResponse.RechargeVehicleWeapon(vehicle_guid, weapon_guid) - ) - ) - case LocalAction.ForceZoneChange(zone) => - LocalEvents.publish( - LocalServiceResponse( - s"/$forChannel/Local", - Service.defaultPlayerGUID, - LocalResponse.ForceZoneChange(zone) - ) - ) - case _ => ; - } - - //response from DoorCloseActor - case DoorCloseActor.CloseTheDoor(door_guid, _) => - LocalEvents.publish( - LocalServiceResponse(s"/${zone.id}/Local", Service.defaultPlayerGUID, LocalResponse.DoorCloses(door_guid)) - ) - - //response from HackClearActor - case HackClearActor.SendHackMessageHackCleared(target_guid, _, unk1, unk2) => - log.info(s"Clearing hack for $target_guid") - LocalEvents.publish( - LocalServiceResponse( - s"/${zone.id}/Local", - Service.defaultPlayerGUID, - LocalResponse.SendHackMessageHackCleared(target_guid, unk1, unk2) - ) - ) - - //message from ProximityTerminalControl - case Terminal.StartProximityEffect(terminal) => - LocalEvents.publish( - LocalServiceResponse( - s"/${zone.id}/Local", - PlanetSideGUID(0), - LocalResponse.ProximityTerminalEffect(terminal.GUID, effectState = true) - ) - ) - case Terminal.StopProximityEffect(terminal) => - LocalEvents.publish( - LocalServiceResponse( - s"/${zone.id}/Local", - PlanetSideGUID(0), - LocalResponse.ProximityTerminalEffect(terminal.GUID, effectState = false) - ) - ) - - // Forward all CaptureFlagManager messages - case msg: CaptureFlagManager.Command => - captureFlagManager.forward(msg) - - case msg => - log.warn(s"Unhandled message $msg from ${sender()}") +case object DoorCloserSupport + extends EventServiceSupport { + def label: String = "doorCloser" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[DoorCloseActor](), name = "DoorCloser") + } +} + +case object HackClearSupport + extends EventServiceSupport { + def label: String = "hackClearer" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[HackClearActor](), name = "HackClearer") + } +} + +case object HackCaptureSupport + extends EventServiceSupport { + def label: String = "hackCapturer" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[HackCaptureActor](), name = "HackCapturer") + } +} + +case class CaptureFlagSupport(zone: Zone) + extends EventServiceSupport { + def label: String = "captureFlagManager" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props(classOf[CaptureFlagManager], zone), name = "CaptureFlagManager") + } +} + +class LocalService(zone: Zone) + extends GenericEventServiceWithSupport[LocalServiceResponse]( + busName = "Local", + eventSupportServices = List(DoorCloserSupport, HackClearSupport, HackCaptureSupport, CaptureFlagSupport(zone)) + ) { + protected def compose(msg: GenericMessageEnvelope): LocalServiceResponse = { + LocalServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) } } diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index c928a2d3a..0cfa55e9c 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -1,145 +1,53 @@ // Copyright (c) 2017 PSForever package net.psforever.services.local -import net.psforever.objects.ce.{Deployable, DeployedItem} -import net.psforever.objects.serverobject.PlanetSideServerObject -import net.psforever.objects.serverobject.doors.Door -import net.psforever.objects.serverobject.hackable.Hackable -import net.psforever.objects.serverobject.llu.CaptureFlag -import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal -import net.psforever.objects.sourcing.PlayerSource -import net.psforever.objects.vehicles.Utility -import net.psforever.objects.zones.Zone -import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle} -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum -import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum -import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, TriggeredSound} -import net.psforever.services.base.{EventMessage, EventResponse} -import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} +import net.psforever.services.Service +import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly} +import net.psforever.services.local.LocalAction.DoorSlamsShut +import net.psforever.types.PlanetSideGUID -final case class LocalServiceMessage(forChannel: String, actionMessage: LocalAction.Action) + +final case class LocalServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) + extends GenericMessageEnvelope object LocalServiceMessage { + def apply(channel: String, localMessage: EventMessage): LocalServiceMessage = + LocalServiceMessage(channel, Service.defaultPlayerGUID, localMessage) + final case class Deployables(msg: Any) } -object LocalAction { - trait Action extends EventMessage { - def response(): EventResponse = null - } - - final case class DeployItem(item: Deployable) extends Action - final case class DeployableMapIcon( - player_guid: PlanetSideGUID, - behavior: DeploymentAction.Value, - deployInfo: DeployableInfo - ) extends Action - final case class DeployableUIFor(obj: DeployedItem.Value) extends Action - final case class Detonate(guid: PlanetSideGUID, obj: PlanetSideGameObject) extends Action - final case class DoorOpens(player_guid: PlanetSideGUID, continent: Zone, door: Door) extends Action - final case class DoorCloses(player_guid: PlanetSideGUID, door_guid: PlanetSideGUID) extends Action - final case class DoorSlamsShut(door: Door) extends Action - final case class EliminateDeployable( - obj: Deployable, - object_guid: PlanetSideGUID, - pos: Vector3, - deletionEffect: Int - ) extends Action - final case class HackClear(player_guid: PlanetSideGUID, target: PlanetSideServerObject, unk1: Long, unk2: HackState7 = HackState7.Unk8) - extends Action - final case class HackTemporarily( - player_guid: PlanetSideGUID, - continent: Zone, - target: PlanetSideServerObject, - hackValue: Long, - hackClearValue: Long, - duration: Int, - unk2: HackState7 = HackState7.Unk8 - ) extends Action - final case class ClearTemporaryHack(player_guid: PlanetSideGUID, target: PlanetSideServerObject with Hackable) - extends Action - - final case class ResecureCaptureTerminal(target: CaptureTerminal, hacker: PlayerSource) extends Action - final case class StartCaptureTerminalHack(target: CaptureTerminal) extends Action - final case class LluCaptured(llu: CaptureFlag) extends Action - final case class LluLost(llu: CaptureFlag) extends Action - final case class LluSpawned(player_guid: PlanetSideGUID, llu: CaptureFlag) extends Action - final case class LluDespawned(player_guid: PlanetSideGUID, guid: PlanetSideGUID, position: Vector3) extends Action - - final case class SendPacket(packet: PlanetSideGamePacket) extends Action - final case class SendPlanetsideAttributeMessage( - player_guid: PlanetSideGUID, - target: PlanetSideGUID, - attribute_number: PlanetsideAttributeEnum, - attribute_value: Long - ) extends Action - final case class SendGenericObjectActionMessage( - player_guid: PlanetSideGUID, - target: PlanetSideGUID, - action_number: GenericObjectActionEnum - ) extends Action - - final case class SendChatMsg( - player_guid: PlanetSideGUID, - msg: ChatMsg - ) extends Action - - final case class SendGenericActionMessage( - player_guid: PlanetSideGUID, - action_number: GenericAction - ) extends Action - final case class RouterTelepadMessage(msg: String) extends Action - final case class RouterTelepadTransport( - player_guid: PlanetSideGUID, - passenger_guid: PlanetSideGUID, - src_guid: PlanetSideGUID, - dest_guid: PlanetSideGUID - ) extends Action - final case class SendResponse(pkt: PlanetSideGamePacket) extends Action - final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Action - final case class ShuttleDock(pad_guid: PlanetSideGUID, shuttle_guid: PlanetSideGUID, toSlot: Int) extends Action - final case class ShuttleUndock( - pad_guid: PlanetSideGUID, - shuttle_guid: PlanetSideGUID, - pos: Vector3, orient: Vector3 - ) extends Action - final case class ShuttleEvent(ev: OrbitalShuttleEvent) extends Action - final case class ShuttleState(guid: PlanetSideGUID, pos: Vector3, orientation: Vector3, state: Int) extends Action - final case class StartRouterInternalTelepad( - router_guid: PlanetSideGUID, - obj_guid: PlanetSideGUID, - obj: Utility.InternalTelepad - ) extends Action - final case class ToggleTeleportSystem( - player_guid: PlanetSideGUID, - router: Vehicle, - systemPlan: Option[(Utility.InternalTelepad, TelepadDeployable)] - ) extends Action - final case class TriggerEffect(player_guid: PlanetSideGUID, effect: String, target: PlanetSideGUID) extends Action - final case class TriggerEffectInfo( - player_guid: PlanetSideGUID, - effect: String, - target: PlanetSideGUID, - unk1: Boolean, - unk2: Long - ) extends Action - final case class TriggerEffectLocation(player_guid: PlanetSideGUID, effect: String, pos: Vector3, orient: Vector3) - extends Action - final case class TriggerSound( - player_guid: PlanetSideGUID, - sound: TriggeredSound.Value, - pos: Vector3, - unk: Int, - volume: Float - ) extends Action - final case class UpdateForceDomeStatus(player_guid: PlanetSideGUID, building_guid: PlanetSideGUID, activated: Boolean) - extends Action - final case class RechargeVehicleWeapon( - player_guid: PlanetSideGUID, - mountable_guid: PlanetSideGUID, - weapon_guid: PlanetSideGUID - ) extends Action - final case class ForceZoneChange(zone: Zone) extends Action +final case class DoorMessage( + channel: String, + filter: PlanetSideGUID, + msg: DoorSlamsShut, + supportMessage: Any + ) + extends GenericMessageToSupportEnvelope { + def supportLabel: String = "doorCloser" +} + +final case class HackEntityMessage( + channel: String, + filter: PlanetSideGUID, + msg: EventMessage, + supportMessage: Any + ) + extends GenericMessageToSupportEnvelope { + def supportLabel: String = "hackClearer" +} + +final case class ClearMessage(supportMessage: Any) + extends GenericMessageToSupportEnvelopeOnly { + def supportLabel: String = "hackClearer" +} + +final case class CaptureMessage(supportMessage: Any) + extends GenericMessageToSupportEnvelopeOnly { + def supportLabel: String = "hackCapturer" +} + +final case class FlagMessage(supportMessage: Any) + extends GenericMessageToSupportEnvelopeOnly { + def supportLabel: String = "captureFlagManager" } diff --git a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala index a7144fb5a..7788471d2 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala @@ -1,91 +1,11 @@ // Copyright (c) 2017 PSForever package net.psforever.services.local -import net.psforever.objects.serverobject.llu.CaptureFlag -import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle} -import net.psforever.objects.ce.{Deployable, DeployedItem} -import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} -import net.psforever.objects.vehicles.Utility -import net.psforever.objects.zones.Zone -import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum -import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game._ -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} -import net.psforever.services.base.{EventResponse, GenericEventBusMsg} -import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent +import net.psforever.types.PlanetSideGUID +import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} final case class LocalServiceResponse( - channel: String, - avatar_guid: PlanetSideGUID, - replyMessage: LocalResponse.Response -) extends GenericEventBusMsg - -object LocalResponse { - trait Response extends EventResponse - - final case class DeployableMapIcon(action: DeploymentAction.Value, deployInfo: DeployableInfo) extends Response - final case class DeployableUIFor(obj: DeployedItem.Value) extends Response - final case class Detonate(guid: PlanetSideGUID, obj: PlanetSideGameObject) extends Response - final case class DoorOpens(door_guid: PlanetSideGUID) extends Response - final case class DoorCloses(door_guid: PlanetSideGUID) extends Response - final case class EliminateDeployable( - obj: Deployable, - object_guid: PlanetSideGUID, - pos: Vector3, - deletionEffect: Int - ) extends Response - final case class SendHackMessageHackCleared(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends Response - final case class HackObject(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends Response - - final case class SendPacket(packet: PlanetSideGamePacket) extends Response - final case class PlanetsideAttribute(target_guid: PlanetSideGUID, attribute_number: PlanetsideAttributeEnum, attribute_value: Long) - extends Response - final case class GenericObjectAction(target_guid: PlanetSideGUID, action_number: GenericObjectActionEnum) - extends Response - final case class ChatMessage(msg: ChatMsg) extends Response - final case class GenericActionMessage(action_num: GenericAction) extends Response - - final case class LluSpawned(llu: CaptureFlag) extends Response - final case class LluDespawned(guid: PlanetSideGUID, position: Vector3) extends Response - - final case class ObjectDelete(item_guid: PlanetSideGUID, unk: Int) extends Response - final case class ProximityTerminalAction(terminal: Terminal with ProximityUnit, target: PlanetSideGameObject) - extends Response - final case class ProximityTerminalEffect(object_guid: PlanetSideGUID, effectState: Boolean) extends Response - final case class RouterTelepadMessage(msg: String) extends Response - final case class RouterTelepadTransport( - passenger_guid: PlanetSideGUID, - src_guid: PlanetSideGUID, - dest_guid: PlanetSideGUID - ) extends Response - final case class SendResponse(pkt: PlanetSideGamePacket) extends Response - final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends Response - final case class ShuttleDock(pad_guid: PlanetSideGUID, shuttle_guid: PlanetSideGUID, toSlot: Int) extends Response - final case class ShuttleUndock( - pad_guid: PlanetSideGUID, - shuttle_guid: PlanetSideGUID, - pos: Vector3, orient: Vector3 - ) extends Response - final case class ShuttleEvent(ev: OrbitalShuttleEvent) extends Response - final case class ShuttleState(guid: PlanetSideGUID, pos: Vector3, orientation: Vector3, state: Int) extends Response - final case class StartRouterInternalTelepad( - router_guid: PlanetSideGUID, - obj_guid: PlanetSideGUID, - obj: Utility.InternalTelepad - ) extends Response - final case class ToggleTeleportSystem( - router: Vehicle, - systemPlan: Option[(Utility.InternalTelepad, TelepadDeployable)] - ) extends Response - final case class TriggerEffect( - target: PlanetSideGUID, - effect: String, - effectInfo: Option[TriggeredEffect] = None, - triggeredLocation: Option[TriggeredEffectLocation] = None - ) extends Response - final case class TriggerSound(sound: TriggeredSound.Value, pos: Vector3, unk: Int, volume: Float) extends Response - final case class UpdateForceDomeStatus(building_guid: PlanetSideGUID, activated: Boolean) extends Response - final case class RechargeVehicleWeapon(mountable_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Response - final case class ForceZoneChange(zone: Zone) extends Response -} + channel: String, + filter: PlanetSideGUID, + reply: EventResponse + ) extends GenericResponseEnvelope diff --git a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala index 980a0f756..9ea03cc7a 100644 --- a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala +++ b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala @@ -13,10 +13,10 @@ import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game._ -import net.psforever.services.{Service, ServiceManager} +import net.psforever.services.ServiceManager import net.psforever.services.ServiceManager.{Lookup, LookupResult} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.duration.DurationInt @@ -45,10 +45,10 @@ class CaptureFlagManager(zone: Zone) extends Actor { case CaptureFlagManager.SpawnCaptureFlag(capture_terminal, target, hackingFaction) => val socket = capture_terminal.Owner.asInstanceOf[Building].GetFlagSocket.get // Override CC message when looked at - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendGenericObjectActionMessage( - PlanetSideGUID(-1), + PlanetSideGUID(-1), + LocalAction.GenericObjectAction( capture_terminal.GUID, GenericObjectActionEnum.FlagSpawned ) @@ -69,7 +69,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { zone.LocalEvents, LocalServiceMessage( zone.id, - LocalAction.LluSpawned(Service.defaultPlayerGUID, flag) + LocalAction.LluSpawned(flag) ) )) // Broadcast chat message for LLU spawn @@ -82,7 +82,11 @@ class CaptureFlagManager(zone: Zone) extends Actor { case None => "A soldier" } // Trigger Install sound - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.TriggerSound(PlanetSideGUID(-1), TriggeredSound.LLUInstall, flag.Target.CaptureTerminal.get.Position, 20, 0.8000001f)) + zone.LocalEvents ! LocalServiceMessage( + zone.id, + PlanetSideGUID(-1), + LocalAction.TriggerSound(TriggeredSound.LLUInstall, flag.Target.CaptureTerminal.get.Position, 20, 0.8000001f) + ) // Broadcast capture chat message CaptureFlagManager.ChatBroadcast(zone, CaptureFlagChatMessageStrings.CTF_Success(name, flag.Faction, flag.Owner.asInstanceOf[Building].Name)) // Despawn flag @@ -115,8 +119,16 @@ class CaptureFlagManager(zone: Zone) extends Actor { case CaptureFlagManager.PickupFlag(flag: CaptureFlag, player: Player) => flag.Carrier = Some(player) - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendPacket(ObjectAttachMessage(player.GUID, flag.GUID, 252))) - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.TriggerSound(PlanetSideGUID(-1), TriggeredSound.LLUPickup, player.Position, 15, volume = 0.8f)) + zone.LocalEvents ! LocalServiceMessage( + zone.id, + PlanetSideGUID(-1), + LocalAction.SendResponse(ObjectAttachMessage(player.GUID, flag.GUID, 252)) + ) + zone.LocalEvents ! LocalServiceMessage( + zone.id, + PlanetSideGUID(-1), + LocalAction.TriggerSound(TriggeredSound.LLUPickup, player.Position, 15, volume = 0.8f) + ) CaptureFlagManager.ChatBroadcast( zone, CaptureFlagChatMessageStrings.CTF_FlagPickedUp(player.Name, player.Faction, flag.Owner.asInstanceOf[Building].Name), @@ -132,7 +144,11 @@ class CaptureFlagManager(zone: Zone) extends Actor { // Remove attached player from flag flag.Carrier = None // Send drop packet - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendPacket(ObjectDetachMessage(player.GUID, flag.GUID, player.Position, 0, 0, 0))) + zone.LocalEvents ! LocalServiceMessage( + zone.id, + PlanetSideGUID(-1), + LocalAction.SendResponse(ObjectDetachMessage(player.GUID, flag.GUID, player.Position, 0, 0, 0)) + ) // Send dropped chat message CaptureFlagManager.ChatBroadcast( zone, @@ -157,7 +173,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { zone.LocalEvents, LocalServiceMessage( zone.id, - LocalAction.LluSpawned(Service.defaultPlayerGUID, replacementLlu) + LocalAction.LluSpawned(replacementLlu) ) )) case _ => @@ -216,7 +232,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { flag.Owner.asInstanceOf[Building].GetFlagSocket.get.captureFlag = None UntrackFlag(flag) // Unregister LLU from clients, - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.LluDespawned(PlanetSideGUID(-1), flag.GUID, flag.Position)) + zone.LocalEvents ! LocalServiceMessage(zone.id, PlanetSideGUID(-1), LocalAction.LluDespawned(flag.GUID, flag.Position)) // Then unregister it from the GUID pool TaskWorkflow.execute(GUIDTask.unregisterObject(zone.GUID, flag)) } @@ -248,10 +264,8 @@ object CaptureFlagManager { } zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendChatMsg( - PlanetSideGUID(-1), - ChatMsg(messageType, wideContents = true, "", message, None) - ) + PlanetSideGUID(-1), + LocalAction.ChatMessage(ChatMsg(messageType, wideContents = true, "", message, None)) ) } @@ -288,7 +302,7 @@ object CaptureFlagManager { if LoseFlagViolentlyToEnvironment(target, Set(EnvironmentAttribute.Water, EnvironmentAttribute.Lava, EnvironmentAttribute.Death)) /*|| LoseFlagViolentlyToWarpGateEnvelope(zone, target)*/ => flag.Destroyed = true - zone.LocalEvents ! LocalServiceMessage("", LocalAction.LluLost(flag)) + zone.LocalEvents ! CaptureMessage(HackCaptureActor.FlagLost(flag)) true } .getOrElse(false) diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index 115924267..ef959035e 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -5,6 +5,7 @@ import akka.actor.{Actor, Cancellable} import net.psforever.objects.{Default, Doors} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec @@ -43,10 +44,10 @@ class DoorCloseActor() extends Actor { doorsLeftOpen1 ++ doorsLeftOpen2.map(entry => DoorCloseActor.DoorEntry(entry.door, entry.zone, now)) ).sortBy(_.time) - doorsToClose2.foreach(entry => { - entry.door.Open = None //permissible break from synchronization - context.parent ! DoorCloseActor.CloseTheDoor(entry.door.GUID, entry.zone.id) //call up to the main event system - }) + doorsToClose2.foreach { case DoorCloseActor.DoorEntry(door, zone, _) => + door.Open = None //permissible break from synchronization + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.DoorCloses(door.GUID)) //call up to the main event system + } if (openDoors.nonEmpty) { val short_timeout: FiniteDuration = math.max(1, DoorCloseActor.timeout_time - (now - openDoors.head.time)).milliseconds diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index ffe816566..729a339d2 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -13,9 +13,8 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.services.Service import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.{FlagMessage, LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} import java.util.concurrent.{Executors, TimeUnit} @@ -156,24 +155,19 @@ class HackCaptureActor extends Actor { case HackCaptureActor.FlagLost(flag) => val owner = flag.Owner.asInstanceOf[Building] val guid = owner.GUID - val terminalOpt = owner.CaptureTerminal - hackedObjects - .find(entry => guid == entry.target.Owner.GUID) - .collect { entry => - val terminal = terminalOpt.get - hackedObjects = hackedObjects.filterNot(x => x eq entry) - log.info(s"FlagLost: ${flag.Carrier.map(_.Name).getOrElse("")} the flag carrier screwed up the capture for ${flag.Target.Name} and the LLU has been lost") - terminal.Actor ! CommonMessages.ClearHack() - NotifyHackStateChange(terminal, isResecured = true) - // If there's hacked objects left in the list restart the timer with the shortest hack time left - RestartTimer() - entry - } - .orElse{ - log.warn(s"FlagLost: flag data does not match to an entry in the hacked objects list") - None - } - context.parent ! CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.FlagLost) + val (found, remaining) = hackedObjects.partition(_.target.Owner.GUID == guid) + hackedObjects = remaining + found.collectFirst { _ => + val terminal = owner.CaptureTerminal.get + log.info(s"FlagLost: ${flag.Carrier.map(_.Name).getOrElse("")} the flag carrier screwed up the capture for ${flag.Target.Name} and the LLU has been lost") + terminal.Actor ! CommonMessages.ClearHack() + NotifyHackStateChange(terminal, isResecured = true) + RestartTimer() // If there's hacked objects left in the list restart the timer with the shortest hack time left + } + if (found.isEmpty) { + log.warn(s"FlagLost: flag data does not match to an entry in the hacked objects list") + } + owner.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.FlagLost)) case _ => () } @@ -195,7 +189,7 @@ class HackCaptureActor extends Actor { true case Some((owner, Some(flag), Some(neighbours))) if neighbours.nonEmpty && hackingFaction != flag.Faction => log.info(s"$hackingFaction is overriding the ongoing LLU hack of facility ${owner.Name} by ${flag.Faction}") - terminal.Zone.LocalEvents ! CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended) + terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended)) NotifyHackStateChange(terminal, isResecured = false) RestartTimer() spawnCaptureFlag(neighbours, terminal, hackingFaction) @@ -209,7 +203,7 @@ class HackCaptureActor extends Actor { case Some((owner, Some(flag), _)) => log.warn(s"TrySpawnCaptureFlag: couldn't find any neighbouring $hackingFaction facilities of ${owner.Name} for LLU hack") owner.GetFlagSocket.foreach { _.clearOldFlagData() } - terminal.Zone.LocalEvents ! CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended) + terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended)) false case _ => log.error(s"TrySpawnCaptureFlag: expecting a terminal ${terminal.GUID.guid} with the ctf owning facility") @@ -225,7 +219,7 @@ class HackCaptureActor extends Actor { // Find a random neighbouring base matching the hacking faction val targetBase = neighbours.toVector((new Random).nextInt(neighbours.size)) // Request LLU is created by CaptureFlagActor via LocalService - terminal.Zone.LocalEvents ! CaptureFlagManager.SpawnCaptureFlag(terminal, targetBase, hackingFaction) + terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.SpawnCaptureFlag(terminal, targetBase, hackingFaction)) } private def NotifyHackStateChange( @@ -236,8 +230,8 @@ class HackCaptureActor extends Actor { // Notify all clients that CC has had its hack state changed terminal.Zone.LocalEvents ! LocalServiceMessage( terminal.Zone.id, - LocalAction.SendPlanetsideAttributeMessage( - PlanetSideGUID(-1), + PlanetSideGUID(-1), + LocalAction.PlanetsideAttribute( terminal.GUID, PlanetsideAttributeEnum.ControlConsoleHackUpdate, attributeValue @@ -273,7 +267,7 @@ class HackCaptureActor extends Actor { log.info(s"Setting base ${building.GUID} / MapId: ${building.MapId} as owned by $hackedByFaction") //dispatch to players aligned with the capturing faction within the SOI val events = building.Zone.LocalEvents - val msg = LocalAction.SendGenericActionMessage(Service.defaultPlayerGUID, GenericAction.FacilityCaptureFanfare) + val msg = LocalAction.GenericActionMessage(GenericAction.FacilityCaptureFanfare) building .PlayersInSOI .collect { case p if p.Faction == hackedByFaction => @@ -312,7 +306,8 @@ class HackCaptureActor extends Actor { } NotifyHackStateChange(terminal, isResecured = true) // todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. - context.parent ! HackClearActor.SendHackMessageHackCleared(building.GUID, terminal.Zone.id, 3212836864L, HackState7.Unk8) //call up + val zone = building.Zone + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendHackMessageHackCleared(building.GUID, 3212836864L, HackState7.Unk8)) } private def RestartTimer(): Unit = { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index 97e580b49..e49ebf96b 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -8,6 +8,7 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.HackState7 +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec @@ -45,32 +46,22 @@ class HackClearActor() extends Actor { //TODO we can just walk across the list of doors and extract only the first few entries val (unhackObjects, stillHackedObjects) = PartitionEntries(hackedObjects, now) hackedObjects = stillHackedObjects - unhackObjects.foreach(entry => { - entry.target.Actor ! CommonMessages.ClearHack() - context.parent ! HackClearActor.SendHackMessageHackCleared( - entry.target.GUID, - entry.zone.id, - entry.unk1, - entry.unk2 - ) //call up to the main event system - if (entry.target.Definition == GlobalDefinitions.main_terminal) { - ClearVirusFromBuilding(entry.target) + unhackObjects.foreach { case HackClearActor.HackEntry(target, zone, unk1, unk2, _, _) => + target.Actor ! CommonMessages.ClearHack() + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendHackMessageHackCleared(target.GUID, unk1, unk2)) + if (target.Definition == GlobalDefinitions.main_terminal) { + ClearVirusFromBuilding(target) } - }) + } RestartTimer() case HackClearActor.ObjectIsResecured(target) => hackedObjects.find { _.target == target } match { - case Some(entry: HackClearActor.HackEntry) => + case Some(HackClearActor.HackEntry(target, zone, unk1, unk2, _, _)) => hackedObjects = hackedObjects.filterNot(x => x.target == target) - entry.target.Actor ! CommonMessages.ClearHack() - context.parent ! HackClearActor.SendHackMessageHackCleared( - entry.target.GUID, - entry.zone.id, - entry.unk1, - entry.unk2 - ) //call up to the main event system + target.Actor ! CommonMessages.ClearHack() + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendHackMessageHackCleared(target.GUID, 3212836864L, HackState7.Unk8)) // Restart the timer in case the object we just removed was the next one scheduled RestartTimer() @@ -109,7 +100,6 @@ class HackClearActor() extends Actor { import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.actors.zone.BuildingActor - import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} val building = target.asInstanceOf[Terminal].Owner.asInstanceOf[Building] diff --git a/src/test/scala/objects/DeployableBehaviorTest.scala b/src/test/scala/objects/DeployableBehaviorTest.scala index e9ac7df88..fb0371db5 100644 --- a/src/test/scala/objects/DeployableBehaviorTest.scala +++ b/src/test/scala/objects/DeployableBehaviorTest.scala @@ -50,16 +50,14 @@ class DeployableBehaviorSetupTest extends ActorTest { val eventsMsgs = eventsProbe.receiveN(2, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", LocalAction.DeployItem(obj)) => + case LocalServiceMessage("test", _, LocalAction.DeployItem(obj)) => assert(obj eq jmine, "self-setup test - not same mine") case _ => assert( false, "self-setup test - wrong deploy message") } eventsMsgs(1) match { - case LocalServiceMessage( - "TR", + case LocalServiceMessage("TR", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, Vector3(1,2,3), PlanetSideGUID(0)) ) @@ -162,8 +160,8 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { eventsMsgs.head match { case AvatarServiceMessage( "TestCharacter1", + _, AvatarAction.SendResponse( - Service.defaultPlayerGUID, ObjectDeployedMessage(0, "jammer_mine", DeployOutcome.Success, 1, 20) ) ) => ; @@ -171,28 +169,27 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { assert(false, "owned setup test, 2 - did not receive build confirmation") } eventsMsgs(1) match { - case LocalServiceMessage("TestCharacter1", LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; + case LocalServiceMessage("TestCharacter1", _, LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; case _ => assert(false, "owned setup test, 2 - did not receive ui update") } eventsMsgs(2) match { case LocalServiceMessage( "test", - LocalAction.TriggerEffectLocation(PlanetSideGUID(3), "spawn_object_effect", Vector3(1,2,3), Vector3(4,5,6)) + PlanetSideGUID(3), + LocalAction.TriggerEffectLocation("spawn_object_effect", Vector3(1,2,3), Vector3(4,5,6)) ) => ; case _ => assert(false, "owned setup test, 2 - no spawn fx") } eventsMsgs(3) match { - case LocalServiceMessage("test", LocalAction.DeployItem(obj)) => + case LocalServiceMessage("test", _, LocalAction.DeployItem(obj)) => assert(obj eq jmine, "owned setup test, 2 - not same mine") case _ => assert( false, "owned setup test, 2 - wrong deploy message") } //the message order can be jumbled from here-on eventsMsgs(4) match { - case LocalServiceMessage( - "TR", + case LocalServiceMessage("TR", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, Vector3(1,2,3), PlanetSideGUID(3)) ) @@ -202,14 +199,14 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { } eventsMsgs(5) match { case AvatarServiceMessage( - "TestCharacter1", - AvatarAction.SendResponse(Service.defaultPlayerGUID, GenericObjectActionMessage(PlanetSideGUID(1), 21)) + "TestCharacter1", _, + AvatarAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(1), 21)) ) => ; case _ => assert(false, "owned setup test, 2 - build action not reset (GOAM21)") } eventsMsgs(6) match { - case AvatarServiceMessage("test", AvatarAction.ObjectDelete(Service.defaultPlayerGUID, PlanetSideGUID(2), 0)) => ; + case AvatarServiceMessage("test", _, AvatarAction.ObjectDelete(PlanetSideGUID(2), 0)) => ; case _ => assert(false, "owned setup test, 2 - construction tool not deleted") } @@ -250,14 +247,13 @@ class DeployableBehaviorDeconstructTest extends ActorTest { jmine.Actor ! Deployable.Deconstruct() val eventsMsgs = eventsProbe.receiveN(2, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", LocalAction.EliminateDeployable(_, PlanetSideGUID(1), Vector3(1,2,3), 2)) => ; + case LocalServiceMessage("test", _, LocalAction.EliminateDeployable(_, PlanetSideGUID(1), Vector3(1,2,3), 2)) => ; case _ => assert(false, "deconstruct test - not eliminating deployable") } eventsMsgs(1) match { case LocalServiceMessage( - "TR", + "TR", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, Vector3(1, 2, 3), PlanetSideGUID(0)) ) @@ -313,15 +309,14 @@ class DeployableBehaviorDeconstructOwnedTest extends FreedContextActorTest { jmine.Actor ! Deployable.Deconstruct() val eventsMsgs = eventsProbe.receiveN(3, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test",LocalAction.EliminateDeployable(mine, ValidPlanetSideGUID(1), Vector3(1.0,2.0,3.0),2)) + case LocalServiceMessage("test", _, LocalAction.EliminateDeployable(mine, ValidPlanetSideGUID(1), Vector3(1.0,2.0,3.0),2)) if mine eq jmine => ; case _ => assert(false, "owned deconstruct test - not eliminating deployable") } eventsMsgs(1) match { case LocalServiceMessage( - "TR", + "TR", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, Vector3(1, 2, 3), PlanetSideGUID(0)) ) @@ -329,7 +324,7 @@ class DeployableBehaviorDeconstructOwnedTest extends FreedContextActorTest { case _ => assert(false, "owned deconstruct test - not removing icon") } eventsMsgs(2) match { - case LocalServiceMessage("TestCharacter1", LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; + case LocalServiceMessage("TestCharacter1", _, LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; case _ => assert(false, "") } diff --git a/src/test/scala/objects/DeployableTest.scala b/src/test/scala/objects/DeployableTest.scala index b02c1ed21..c728f9f1e 100644 --- a/src/test/scala/objects/DeployableTest.scala +++ b/src/test/scala/objects/DeployableTest.scala @@ -381,14 +381,13 @@ class ExplosiveDeployableJammerTest extends ActorTest { // case _ => assert(false, "") // } eventMsgs(1) match { - case LocalServiceMessage("test", LocalAction.Detonate(PlanetSideGUID(1), _)) => ; + case LocalServiceMessage("test", _, LocalAction.Detonate(PlanetSideGUID(1), _)) => ; case _ => assert(false, "") } eventMsgs(2) match { case LocalServiceMessage( - "NC", + "NC", _, LocalAction.DeployableMapIcon( - ValidPlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(ValidPlanetSideGUID(1), DeployableIcon.HEMine, Vector3.Zero, ValidPlanetSideGUID(0)) ) @@ -398,8 +397,9 @@ class ExplosiveDeployableJammerTest extends ActorTest { eventMsgs(3) match { case AvatarServiceMessage( "test", + _, AvatarAction.Destroy( - ValidPlanetSideGUID(1), + ValidPlanetSideGUID(1), ValidPlanetSideGUID(3), ValidPlanetSideGUID(0), Vector3.Zero @@ -484,15 +484,14 @@ class ExplosiveDeployableJammerExplodeTest extends ActorTest { case _ => assert(false, "") } eventMsgs(1) match { - case LocalServiceMessage("test", LocalAction.Detonate(PlanetSideGUID(2), target)) + case LocalServiceMessage("test", _, LocalAction.Detonate(PlanetSideGUID(2), target)) if target eq h_mine => () case _ => assert(false, "") } eventMsgs(2) match { case LocalServiceMessage( - "NC", + "NC", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(2), DeployableIcon.HEMine, _, PlanetSideGUID(0)) ) @@ -578,9 +577,8 @@ class ExplosiveDeployableDestructionTest extends ActorTest { val p2Msgs = player2Probe.receiveN(1, 200 milliseconds) eventMsgs.head match { case LocalServiceMessage( - "NC", + "NC", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(2), DeployableIcon.HEMine, _, PlanetSideGUID(0)) ) @@ -589,13 +587,13 @@ class ExplosiveDeployableDestructionTest extends ActorTest { } eventMsgs(1) match { case AvatarServiceMessage( - "test", + "test", _, AvatarAction.Destroy(PlanetSideGUID(2), PlanetSideGUID(3), Service.defaultPlayerGUID, Vector3.Zero) ) => ; case _ => assert(false, "") } eventMsgs(2) match { - case LocalServiceMessage("test", LocalAction.TriggerEffect(_, "detonate_damaged_mine", PlanetSideGUID(2))) => ; + case LocalServiceMessage("test", _, LocalAction.TriggerEffect("detonate_damaged_mine", PlanetSideGUID(2))) => ; case _ => assert(false, "") } p2Msgs.head match { diff --git a/src/test/scala/objects/DoorTest.scala b/src/test/scala/objects/DoorTest.scala index 15d9db03b..84d096522 100644 --- a/src/test/scala/objects/DoorTest.scala +++ b/src/test/scala/objects/DoorTest.scala @@ -105,7 +105,7 @@ class DoorControlAlreadyOpenTest extends ActorTest { door.Actor.tell(CommonMessages.Use(player), probe.ref) val reply = probe.receiveOne(1000 milliseconds) assert(reply match { - case LocalServiceResponse("test", _, LocalResponse.DoorOpens(guid)) => guid == door.GUID + case LocalServiceResponse("test", _, LocalAction.DoorOpens(guid)) => guid == door.GUID case _ => false }) } diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index f3c89992a..600d748bf 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -2,25 +2,19 @@ package objects.terminal import java.util.concurrent.atomic.AtomicInteger - import akka.actor.Props import akka.testkit.TestProbe import base.ActorTest import net.psforever.actors.zone.ZoneActor import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.structures.{Building, StructureType} -import net.psforever.objects.serverobject.terminals.{ - ProximityTerminal, - ProximityTerminalControl, - ProximityUnit, - Terminal -} +import net.psforever.objects.serverobject.terminals.{ProximityTerminal, ProximityTerminalControl, ProximityUnit, Terminal} import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.objects.{GlobalDefinitions, Player} import net.psforever.types.{CharacterSex, CharacterVoice, PlanetSideEmpire, PlanetSideGUID} import org.specs2.mutable.Specification import net.psforever.services.Service -import net.psforever.services.local.LocalService +import net.psforever.services.local.{LocalService, LocalServiceMessage} import scala.concurrent.duration._ import akka.actor.typed.scaladsl.adapter._ @@ -206,7 +200,7 @@ class ProximityTerminalControlStartTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect]) + probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action]) assert(terminal.NumberUsers == 1) } @@ -276,7 +270,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect]) + probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) probe2.expectMsgClass(5 second, classOf[ProximityUnit.Action]) terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref) @@ -334,7 +328,7 @@ class ProximityTerminalControlStopTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect]) + probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action]) terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar)) @@ -346,7 +340,7 @@ class ProximityTerminalControlStopTest extends ActorTest { case out => assert(false, s"last message $out is not StopAction") } //probe2.expectMsgClass(1 second, classOf[ProximityUnit.StopAction]) - probe1.expectMsgClass(1 second, classOf[Terminal.StopProximityEffect]) + probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) assert(terminal.NumberUsers == 0) } } @@ -412,7 +406,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(100 millisecond, classOf[Terminal.StartProximityEffect]) + probe1.expectMsgClass(100 millisecond, classOf[LocalServiceMessage]) assert(terminal.NumberUsers == 1) terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref) @@ -424,7 +418,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest { assert(terminal.NumberUsers == 1) terminal.Actor ! CommonMessages.Unuse(avatar2, Some(avatar2)) - probe1.expectMsgClass(100 millisecond, classOf[Terminal.StopProximityEffect]) + probe1.expectMsgClass(100 millisecond, classOf[LocalServiceMessage]) assert(terminal.NumberUsers == 0) } } diff --git a/src/test/scala/service/LocalServiceTest.scala b/src/test/scala/service/LocalServiceTest.scala index 4bdaac10e..2b6187f7a 100644 --- a/src/test/scala/service/LocalServiceTest.scala +++ b/src/test/scala/service/LocalServiceTest.scala @@ -98,7 +98,7 @@ class DeployItemTest extends ActorTest { "pass DeployItem" in { service ! Service.Join("test") service ! LocalServiceMessage("test", LocalAction.DeployItem(obj)) - expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), LocalResponse.SendResponse(pkt))) + expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), LocalAction.SendResponse(pkt))) } } } @@ -112,17 +112,14 @@ class DeployableMapIconTest extends ActorTest { service ! Service.Join("test") service ! LocalServiceMessage( "test", - LocalAction.DeployableMapIcon( - PlanetSideGUID(10), - DeploymentAction.Build, - DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11)) - ) + PlanetSideGUID(10), + LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11))) ) expectMsg( LocalServiceResponse( "/test/Local", PlanetSideGUID(10), - LocalResponse.DeployableMapIcon( + LocalAction.DeployableMapIcon( DeploymentAction.Build, DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11)) ) @@ -143,8 +140,8 @@ class DoorClosesTest extends FreedContextActorTest { "LocalService" should { "pass DoorCloses" in { zone.LocalEvents.tell(Service.Join("test"), probe.ref) - zone.LocalEvents ! LocalServiceMessage("test", LocalAction.DoorCloses(PlanetSideGUID(10), PlanetSideGUID(40))) - probe.expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.DoorCloses(PlanetSideGUID(40)))) + zone.LocalEvents ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.DoorCloses(PlanetSideGUID(40))) + probe.expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.DoorCloses(PlanetSideGUID(40)))) } } } @@ -161,9 +158,9 @@ class HackClearTest extends ActorTest { "pass HackClear" in { val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.HackClear(PlanetSideGUID(10), obj, 0L, HackState7.Unk8)) + service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.HackClear(obj, 0L, HackState7.Unk8)) expectMsg( - LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.SendHackMessageHackCleared(PlanetSideGUID(40), 0L, HackState7.Unk8)) + LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.SendHackMessageHackCleared(PlanetSideGUID(40), 0L, HackState7.Unk8)) ) } } @@ -178,12 +175,12 @@ class ProximityTerminalEffectOnTest extends ActorTest { "LocalService" should { "pass ProximityTerminalEffect (true)" in { service ! Service.Join("nowhere") - service ! Terminal.StartProximityEffect(terminal) + service ! LocalServiceMessage("nowhere", LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), effectState = true)) expectMsg( LocalServiceResponse( "/nowhere/Local", PlanetSideGUID(0), - LocalResponse.ProximityTerminalEffect(PlanetSideGUID(1), true) + LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), true) ) ) } @@ -199,12 +196,12 @@ class ProximityTerminalEffectOffTest extends ActorTest { "LocalService" should { "pass ProximityTerminalEffect (false)" in { service ! Service.Join("nowhere") - service ! Terminal.StopProximityEffect(terminal) + service ! LocalServiceMessage("nowhere", LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), effectState = false)) expectMsg( LocalServiceResponse( "/nowhere/Local", PlanetSideGUID(0), - LocalResponse.ProximityTerminalEffect(PlanetSideGUID(1), false) + LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), false) ) ) } @@ -220,8 +217,8 @@ class RouterTelepadTransportTest extends ActorTest { service ! Service.Join("test") service ! LocalServiceMessage( "test", + PlanetSideGUID(10), LocalAction.RouterTelepadTransport( - PlanetSideGUID(10), PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13) @@ -231,7 +228,7 @@ class RouterTelepadTransportTest extends ActorTest { LocalServiceResponse( "/test/Local", PlanetSideGUID(10), - LocalResponse.RouterTelepadTransport(PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13)) + LocalAction.RouterTelepadTransport(PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13)) ) ) } @@ -251,7 +248,7 @@ class SetEmpireTest extends ActorTest { LocalServiceResponse( "/test/Local", PlanetSideGUID(0), - LocalResponse.SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR) + LocalAction.SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR) ) ) } @@ -267,9 +264,9 @@ class ToggleTeleportSystemTest extends ActorTest { router.Actor = system.actorOf(Props(classOf[VehicleControl], router), "test-router") val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.ToggleTeleportSystem(PlanetSideGUID(10), router, None)) + service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.ToggleTeleportSystem(router, None)) expectMsg( - LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.ToggleTeleportSystem(router, None)) + LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.ToggleTeleportSystem(router, None)) ) } } @@ -282,12 +279,12 @@ class TriggerEffectTest extends ActorTest { "pass TriggerEffect (1)" in { val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.TriggerEffect(PlanetSideGUID(10), "on", PlanetSideGUID(40))) + service ! LocalServiceMessage("test", LocalAction.TriggerEffect("on", PlanetSideGUID(40))) expectMsg( LocalServiceResponse( "/test/Local", PlanetSideGUID(10), - LocalResponse.TriggerEffect(PlanetSideGUID(40), "on", None, None) + LocalAction.TriggerEffectAtLocation(PlanetSideGUID(40), "on", None, None) ) ) } @@ -303,13 +300,14 @@ class TriggerEffectInfoTest extends ActorTest { service ! Service.Join("test") service ! LocalServiceMessage( "test", - LocalAction.TriggerEffectInfo(PlanetSideGUID(10), "on", PlanetSideGUID(40), true, 1000) + PlanetSideGUID(10), + LocalAction.TriggerEffectInfo(PlanetSideGUID(40), "on", true, 1000) ) expectMsg( LocalServiceResponse( "/test/Local", PlanetSideGUID(10), - LocalResponse.TriggerEffect(PlanetSideGUID(40), "on", Some(TriggeredEffect(true, 1000)), None) + LocalAction.TriggerEffectAtLocation(PlanetSideGUID(40), "on", Some(TriggeredEffect(true, 1000)), None) ) ) } @@ -325,8 +323,8 @@ class TriggerEffectLocationTest extends ActorTest { service ! Service.Join("test") service ! LocalServiceMessage( "test", + PlanetSideGUID(10), LocalAction.TriggerEffectLocation( - PlanetSideGUID(10), "spawn_object_failed_effect", Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f) @@ -336,7 +334,7 @@ class TriggerEffectLocationTest extends ActorTest { LocalServiceResponse( "/test/Local", PlanetSideGUID(10), - LocalResponse.TriggerEffect( + LocalAction.TriggerEffectAtLocation( PlanetSideGUID(0), "spawn_object_failed_effect", None, @@ -358,13 +356,14 @@ class TriggerSoundTest extends ActorTest { service ! Service.Join("test") service ! LocalServiceMessage( "test", - LocalAction.TriggerSound(PlanetSideGUID(10), TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f) + PlanetSideGUID(10), + LocalAction.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f) ) expectMsg( LocalServiceResponse( "/test/Local", PlanetSideGUID(10), - LocalResponse.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f) + LocalAction.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f) ) ) } From 9ba1b3048ed29fc73cd65820299872e5da15b53e Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 26 Jan 2026 16:49:50 -0500 Subject: [PATCH 05/32] adapted but did not implement the event bus rate limiting mechanisms from Chinese PSF fork --- .../services/base/GenericEventBus.scala | 4 +- .../services/base/GenericEventService.scala | 1 + .../services/base/GenericGuidEventBus.scala | 106 ++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala diff --git a/src/main/scala/net/psforever/services/base/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/GenericEventBus.scala index 72c2c43e3..74e929a91 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventBus.scala @@ -6,9 +6,11 @@ import akka.util.Subclassification trait GenericEventBusMsg { def channel: String + def inner: Any } -class GenericEventBus[A <: GenericEventBusMsg] extends ActorEventBus with SubchannelClassification { +class GenericEventBus[A <: GenericEventBusMsg] + extends ActorEventBus with SubchannelClassification { type Event = A type Classifier = String diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 6a4c030c0..a9c69a4df 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -12,6 +12,7 @@ trait GenericResponseEnvelope extends GenericEventBusMsg { def filter: PlanetSideGUID def reply: EventResponse + def inner: EventResponse = reply } trait GenericMessageEnvelope { diff --git a/src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala b/src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala new file mode 100644 index 000000000..16ed9d188 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala @@ -0,0 +1,106 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base + +import net.psforever.types.PlanetSideGUID +import scala.collection.concurrent.{Map => CMap} +import scala.jdk.CollectionConverters._ +import java.util.concurrent.ConcurrentHashMap +import scala.annotation.unused + +/* +Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission + */ + +trait GenericGuidEventBusMsg extends GenericEventBusMsg { + def guid: PlanetSideGUID +} + +class RateLimitScheduler[A <: GenericGuidEventBusMsg](eventBus: GenericGuidEventBus[A], interval: Long) extends Thread { + private var hasWork: Boolean = false + private var working: Boolean = false + private var timeOfLastFlush: Long = 0L + private val buffer: CMap[String, CMap[String, CMap[PlanetSideGUID, A]]] = + new ConcurrentHashMap[String, CMap[String, CMap[PlanetSideGUID, A]]]().asScala + + override def run(): Unit = { + while (working) { + //originally, there was a Thread.sleep(interval) here, replaced by timeOfLastFlush logic + flushBuffer() + } + } + + def push(event: A): Unit = { + val eventClassName = event.inner.getClass.getName + val cache = + buffer + .getOrElseUpdate(event.channel, new ConcurrentHashMap[String, CMap[PlanetSideGUID, A]]().asScala) + .getOrElseUpdate(eventClassName, new ConcurrentHashMap[PlanetSideGUID, A]().asScala) + cache.updateWith(event.guid) { _ => Some(event) } + hasWork = true + } + + def flushBuffer(): Unit = { + val curr = System.currentTimeMillis() + if (hasWork && timeOfLastFlush + interval <= curr) { + flushBufferNow(curr) + } + } + + def flushBufferNow(curr: Long = System.currentTimeMillis()): Unit = { + buffer.foreachEntry { (_, map) => + map.foreachEntry { (_, map) => + map.foreachEntry { (_, event) => + eventBus.publishForce(event) + } + map.clear() + } + } + hasWork = false + timeOfLastFlush = curr + } + + override def start(): Unit = { + working = true + timeOfLastFlush = System.currentTimeMillis() + super.start() + } + + def isRunning: Boolean = { + working + } + + def stopRunning(): Unit = { + working = false + flushBufferNow() + } +} + +abstract class GenericGuidEventBus[A <: GenericGuidEventBusMsg](rateLimit: Double) + extends GenericEventBus[A] { + private val rateLimitedDispatch = new RateLimitScheduler[A]( + eventBus = this, + scala.math.floor(1000.0 / rateLimit).toInt + ) + rateLimitedDispatch.start() + + override def publish(event: Event): Unit = { + if (rateLimit > 0 && shouldRateLimit(event) && rateLimitedDispatch.isRunning) { + rateLimitedDispatch.push(event) + } else { + publishForce(event) + } + } + + def shouldRateLimit(@unused event: Event): Boolean + + def publishForce(event: Event): Unit = { + super.publish(event) + } + +// override protected def publish(event: Event, subscriber: Subscriber): Unit = { +// val trimmedEventClassName = +// event.inner.getClass().getName().stripPrefix(event.inner.getClass.getPackageName() + ".").stripSuffix("$") +// GenericGuidEventBus.genericGuidEventBusPublish.labels(event.channel, trimmedEventClassName).inc() +// subscriber ! event +// } +} From 5ece864bfd89fe760dc8b35bcce6ac320979e8f0 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 27 Jan 2026 19:23:37 -0500 Subject: [PATCH 06/32] solved issue with redundant support actor messaging; refactored event buses out of event systems --- .../services/base/GenericEventService.scala | 36 +++++++++---------- .../base/GenericEventServiceWithSupport.scala | 28 +++++++++------ .../base/{ => bus}/GenericEventBus.scala | 16 ++++++--- .../base/bus/GenericEventBusWithSupport.scala | 32 +++++++++++++++++ .../base/{ => bus}/GenericGuidEventBus.scala | 23 ++++++------ .../psforever/services/hart/HartTimer.scala | 9 +++-- .../teamwork/SquadServiceResponse.scala | 11 +++--- .../teamwork/SquadSubscriptionEntity.scala | 2 +- .../services/vehicle/VehicleService.scala | 2 +- .../vehicle/VehicleServiceResponse.scala | 11 +++--- 10 files changed, 113 insertions(+), 57 deletions(-) rename src/main/scala/net/psforever/services/base/{ => bus}/GenericEventBus.scala (66%) create mode 100644 src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala rename src/main/scala/net/psforever/services/base/{ => bus}/GenericGuidEventBus.scala (86%) diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index a9c69a4df..0ec9aa690 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -3,21 +3,18 @@ package net.psforever.services.base import akka.actor.Actor import net.psforever.services.Service -import net.psforever.types.PlanetSideGUID +import net.psforever.services.base.bus.{AllGenericBusMsg, GenericEventBus, GenericEventBusResponse} import org.log4s.Logger import scala.annotation.unused trait GenericResponseEnvelope - extends GenericEventBusMsg { - def filter: PlanetSideGUID + extends GenericEventBusResponse { def reply: EventResponse - def inner: EventResponse = reply } -trait GenericMessageEnvelope { - def channel: String - def filter: PlanetSideGUID +trait GenericMessageEnvelope + extends AllGenericBusMsg { def msg: EventMessage } @@ -25,7 +22,7 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) - protected val eventBus = new GenericEventBus[OUT] + protected val eventBus: GenericEventBus[OUT] = setupEventBus() def BusName: String = busName @@ -48,20 +45,23 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri eventBus.unsubscribe(sender()) } - def receive: Receive = - commonJoinBehavior.orElse(commonLeaveBehavior) - .orElse { - case msg: GenericMessageEnvelope => - handleMessage(msg) + def receive: Receive = commonJoinBehavior + .orElse(commonLeaveBehavior) + .orElse { + case msg: GenericMessageEnvelope => + handleMessage(msg) + case msg => () + log.warn(s"Unhandled message $msg from ${sender()}") + } - case msg => () - log.warn(s"Unhandled message $msg from ${sender()}") - } - - protected def handleMessage(msg: GenericMessageEnvelope): Unit = { + private def handleMessage(msg: GenericMessageEnvelope): Unit = { eventBus.publish(compose(msg)) } + protected def setupEventBus(): GenericEventBus[OUT] = { + new GenericEventBus[OUT] + } + protected def compose(@unused msg: GenericMessageEnvelope): OUT def formatChannelOnBusName(channel: String): String = GenericEventService.BusOnChannelFormat(busName)(channel) diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index c4a531000..c40368389 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -3,6 +3,7 @@ package net.psforever.services.base import akka.actor.{ActorContext, ActorRef} import net.psforever.services.Service +import net.psforever.services.base.bus.{GenericEventBus, GenericEventBusResponseToSupport, GenericEventBusWithSupport} import net.psforever.types.PlanetSideGUID import scala.annotation.unused @@ -36,16 +37,6 @@ abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope] .map { supportService => (supportService.label, supportService.constructor(context)) } .toMap[String, ActorRef] - private def supportReceive: Receive = { - case msg: GenericMessageToSupportEnvelopeOnly => - forwardToSupport(msg) - case msg: GenericMessageToSupportEnvelope => - forwardToSupport(msg) - handleMessage(msg) - } - - override def receive: Receive = supportReceive.orElse(super.receive) - private def forwardToSupport(msg: GenericMessageToSupportEnvelope): Unit = { supportServices .get(msg.supportLabel) @@ -57,4 +48,21 @@ abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope] log.error(s"support service ${msg.supportLabel} was not found - check message routing or service params") } } + + override protected def setupEventBus(): GenericEventBus[OUT] = { + new GenericEventBus[OUT] with GenericEventBusWithSupport[OUT] { + override def publish(event: OUT): Unit = publishingWithSupport(event) + + override def forwardToExternalSupport(msg: GenericEventBusResponseToSupport): Unit = { + msg match { + case supportMessage: GenericMessageToSupportEnvelope => forwardToExternal(supportMessage) + case _ => () + } + } + + private def forwardToExternal(msg: GenericMessageToSupportEnvelope): Unit = { + forwardToSupport(msg) + } + } + } } diff --git a/src/main/scala/net/psforever/services/base/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala similarity index 66% rename from src/main/scala/net/psforever/services/base/GenericEventBus.scala rename to src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala index 74e929a91..faaa81490 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala @@ -1,15 +1,19 @@ // Copyright (c) 2017 PSForever -package net.psforever.services.base +package net.psforever.services.base.bus import akka.event.{ActorEventBus, SubchannelClassification} import akka.util.Subclassification +import net.psforever.types.PlanetSideGUID -trait GenericEventBusMsg { +trait AllGenericBusMsg { def channel: String - def inner: Any + def filter: PlanetSideGUID } -class GenericEventBus[A <: GenericEventBusMsg] +trait GenericEventBusResponse + extends AllGenericBusMsg + +class GenericEventBus[A <: GenericEventBusResponse] extends ActorEventBus with SubchannelClassification { type Event = A type Classifier = String @@ -26,4 +30,8 @@ class GenericEventBus[A <: GenericEventBusMsg] protected def publish(event: Event, subscriber: Subscriber): Unit = { subscriber ! event } + + def truePublish(event: Event): Unit = { + super[SubchannelClassification].publish(event) + } } diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala new file mode 100644 index 000000000..34381ccb1 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala @@ -0,0 +1,32 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.bus + +import scala.annotation.unused + +trait GenericEventBusResponseToSupport + extends GenericEventBusResponse { + def supportLabel: String + def supportMessage: Any +} + +trait GenericEventBusResponseToSupportOnly + extends GenericEventBusResponseToSupport { + def channel: String = "" +} + +trait GenericEventBusWithSupport[T <: GenericEventBusResponse] { + bus: GenericEventBus[T] => + def publishingWithSupport(event: T): Unit = { + event match { + case msg: GenericEventBusResponseToSupportOnly => + forwardToExternalSupport(msg) + case msg: GenericEventBusResponseToSupport => + forwardToExternalSupport(msg) + bus.truePublish(event) + case _ => + bus.truePublish(event) + } + } + + def forwardToExternalSupport(@unused msg: GenericEventBusResponseToSupport): Unit +} diff --git a/src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala similarity index 86% rename from src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala rename to src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala index 16ed9d188..d583194e2 100644 --- a/src/main/scala/net/psforever/services/base/GenericGuidEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala @@ -1,21 +1,24 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base +package net.psforever.services.base.bus import net.psforever.types.PlanetSideGUID -import scala.collection.concurrent.{Map => CMap} -import scala.jdk.CollectionConverters._ + import java.util.concurrent.ConcurrentHashMap import scala.annotation.unused +import scala.collection.concurrent.{Map => CMap} +import scala.jdk.CollectionConverters._ /* Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission */ -trait GenericGuidEventBusMsg extends GenericEventBusMsg { +trait GenericGuidEventBusResponse + extends GenericEventBusResponse { def guid: PlanetSideGUID + def inner: Any } -class RateLimitScheduler[A <: GenericGuidEventBusMsg](eventBus: GenericGuidEventBus[A], interval: Long) extends Thread { +class RateLimitScheduler[A <: GenericGuidEventBusResponse](eventBus: GenericEventBus[A], interval: Long) extends Thread { private var hasWork: Boolean = false private var working: Boolean = false private var timeOfLastFlush: Long = 0L @@ -50,7 +53,7 @@ class RateLimitScheduler[A <: GenericGuidEventBusMsg](eventBus: GenericGuidEvent buffer.foreachEntry { (_, map) => map.foreachEntry { (_, map) => map.foreachEntry { (_, event) => - eventBus.publishForce(event) + eventBus.truePublish(event) } map.clear() } @@ -75,7 +78,7 @@ class RateLimitScheduler[A <: GenericGuidEventBusMsg](eventBus: GenericGuidEvent } } -abstract class GenericGuidEventBus[A <: GenericGuidEventBusMsg](rateLimit: Double) +abstract class GenericGuidEventBus[A <: GenericGuidEventBusResponse](rateLimit: Double) extends GenericEventBus[A] { private val rateLimitedDispatch = new RateLimitScheduler[A]( eventBus = this, @@ -87,16 +90,12 @@ abstract class GenericGuidEventBus[A <: GenericGuidEventBusMsg](rateLimit: Doubl if (rateLimit > 0 && shouldRateLimit(event) && rateLimitedDispatch.isRunning) { rateLimitedDispatch.push(event) } else { - publishForce(event) + truePublish(event) } } def shouldRateLimit(@unused event: Event): Boolean - def publishForce(event: Event): Unit = { - super.publish(event) - } - // override protected def publish(event: Event, subscriber: Subscriber): Unit = { // val trimmedEventClassName = // event.inner.getClass().getName().stripPrefix(event.inner.getClass.getPackageName() + ".").stripSuffix("$") diff --git a/src/main/scala/net/psforever/services/hart/HartTimer.scala b/src/main/scala/net/psforever/services/hart/HartTimer.scala index 8267e2f76..ab5d2d4d7 100644 --- a/src/main/scala/net/psforever/services/hart/HartTimer.scala +++ b/src/main/scala/net/psforever/services/hart/HartTimer.scala @@ -4,7 +4,9 @@ package net.psforever.services.hart import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Default import net.psforever.objects.zones.Zone -import net.psforever.services.base.{EventResponse, GenericEventBus, GenericEventBusMsg} +import net.psforever.services.Service +import net.psforever.services.base.bus.{GenericEventBus, GenericEventBusResponse} +import net.psforever.services.base.EventResponse import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{HartSequence, PlanetSideGUID} @@ -259,7 +261,10 @@ object HartTimer { * to relay instructions back to the individual facility amenity portions of this HART system. * The channel is blank because it does not need special designation. */ - trait Command extends EventResponse with GenericEventBusMsg { def channel: String = "" } + trait Command extends EventResponse with GenericEventBusResponse { + def channel: String = "" + def filter: PlanetSideGUID = Service.defaultPlayerGUID + } /** * Forbid entry through the boartding gantry doors. */ diff --git a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala index 49600cc48..af6b2f622 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala @@ -5,11 +5,14 @@ import akka.actor.ActorRef import net.psforever.objects.avatar.Certification import net.psforever.objects.teamwork.Squad import net.psforever.packet.game.{SquadDetail, SquadInfo, WaypointEventAction, WaypointInfo} +import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadResponseType, SquadWaypoint} -import net.psforever.services.base.{EventResponse, GenericEventBusMsg} +import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} -final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], response: SquadResponse.Response) - extends EventResponse with GenericEventBusMsg +final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], reply: SquadResponse.Response) + extends EventResponse with GenericResponseEnvelope { + override def filter: PlanetSideGUID = Service.defaultPlayerGUID +} object SquadServiceResponse { def apply(toChannel: String, response: SquadResponse.Response): SquadServiceResponse = @@ -20,7 +23,7 @@ object SquadServiceResponse { } object SquadResponse { - sealed trait Response + sealed trait Response extends EventResponse final case class ListSquadFavorite(line: Int, task: String) extends Response diff --git a/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala b/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala index af47196b6..e1aca37d9 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala @@ -6,7 +6,7 @@ import akka.actor.ActorRef import scala.collection.mutable import net.psforever.objects.teamwork.{Squad, SquadFeatures} import net.psforever.packet.game.SquadDetail -import net.psforever.services.base.GenericEventBus +import net.psforever.services.base.bus.GenericEventBus import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} class SquadSubscriptionEntity { diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 4ac69bfcc..0116f278a 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -6,10 +6,10 @@ import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.objects.zones.Zone import net.psforever.packet.game.ObjectCreateMessage import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.services.base.GenericEventBus import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.types.DriveState import net.psforever.services.Service +import net.psforever.services.base.bus.GenericEventBus class VehicleService(zone: Zone) extends Actor { private val turretUpgrade: ActorRef = context.actorOf(Props[TurretUpgrader](), s"${zone.id}-turret-upgrade-agent") diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala index 166d12302..dd052809f 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala @@ -11,13 +11,14 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.packet.game.ObjectCreateMessage import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} -import net.psforever.services.base.{EventResponse, GenericEventBusMsg} +import net.psforever.services.base.EventResponse +import net.psforever.services.base.bus.GenericEventBusResponse final case class VehicleServiceResponse( - channel: String, - avatar_guid: PlanetSideGUID, - replyMessage: VehicleResponse.Response -) extends GenericEventBusMsg + channel: String, + filter: PlanetSideGUID, + reply: VehicleResponse.Response + ) extends GenericEventBusResponse object VehicleResponse { trait Response extends EventResponse From 4838c991b3d17fbcb78abd73752539de99d9ec73 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 1 Feb 2026 09:46:15 -0500 Subject: [PATCH 07/32] working VehicleService based on GenericServiceEvent(WithSupport); manually corrected almost every message to VehicleService to ensure channel and filters are preserved --- .codecov.yml | 1 - .../actor/objects/VehicleSpawnPadTest.scala | 10 +- .../CustomerServiceRepresentativeMode.scala | 4 +- .../session/csr/MountHandlerLogic.scala | 14 +- .../actors/session/csr/VehicleLogic.scala | 43 +- .../session/normal/MountHandlerLogic.scala | 14 +- .../session/normal/VehicleHandlerLogic.scala | 247 +++++----- .../actors/session/normal/VehicleLogic.scala | 43 +- .../session/spectator/MountHandlerLogic.scala | 14 +- .../spectator/VehicleHandlerLogic.scala | 115 ++--- .../session/spectator/VehicleLogic.scala | 19 +- .../session/support/GeneralOperations.scala | 3 +- .../actors/session/support/SessionData.scala | 3 +- .../support/SessionMountHandlers.scala | 27 +- .../support/SessionVehicleHandlers.scala | 4 +- .../WeaponAndProjectileOperations.scala | 21 +- .../session/support/ZoningOperations.scala | 20 +- .../objects/FieldTurretDeployable.scala | 3 +- .../psforever/objects/SensorDeployable.scala | 4 +- .../objects/ShieldGeneratorDeployable.scala | 19 +- .../psforever/objects/TurretDeployable.scala | 3 +- .../net/psforever/objects/Vehicles.scala | 21 +- .../equipment/ArmorSiphonBehavior.scala | 7 +- .../objects/equipment/JammingUnit.scala | 7 +- .../damage/DamageableVehicle.scala | 12 +- .../damage/DamageableWeaponTurret.scala | 14 +- .../deploy/DeploymentBehavior.scala | 8 +- .../pad/VehicleSpawnControl.scala | 40 +- .../serverobject/pad/VehicleSpawnPad.scala | 34 +- .../VehicleSpawnControlConcealPlayer.scala | 3 +- .../VehicleSpawnControlDriverControl.scala | 3 +- .../VehicleSpawnControlFinalClearance.scala | 12 +- .../VehicleSpawnControlLoadVehicle.scala | 3 +- .../process/VehicleSpawnControlRailJack.scala | 3 +- .../VehicleSpawnControlSeatDriver.scala | 5 +- ...cleSpawnControlServerVehicleOverride.scala | 7 +- .../repair/RepairableWeaponTurret.scala | 3 +- .../resourcesilo/ResourceSiloControl.scala | 4 +- .../terminals/ProximityTerminalControl.scala | 5 +- .../implant/ImplantTerminalMechControl.scala | 4 +- .../turret/FacilityTurretControl.scala | 7 +- .../serverobject/turret/WeaponTurrets.scala | 11 +- .../vehicles/AntTransferBehavior.scala | 13 +- .../vehicles/BfrTransferBehavior.scala | 2 +- .../objects/vehicles/CarrierBehavior.scala | 46 +- .../objects/vehicles/control/AmsControl.scala | 9 +- .../objects/vehicles/control/ApcControl.scala | 7 +- .../objects/vehicles/control/BfrControl.scala | 21 +- .../vehicles/control/VehicleCapacitance.scala | 3 +- .../vehicles/control/VehicleControl.scala | 27 +- .../net/psforever/objects/zones/MapInfo.scala | 5 +- .../objects/zones/ZoneVehicleActor.scala | 3 +- .../services/avatar/AvatarService.scala | 2 +- .../services/base/GenericEventService.scala | 28 +- .../base/GenericEventServiceWithSupport.scala | 22 +- .../services/base/bus/GenericEventBus.scala | 4 + .../base/bus/GenericEventBusWithSupport.scala | 2 +- .../services/galaxy/GalaxyService.scala | 10 +- .../services/local/LocalService.scala | 2 +- .../services/vehicle/VehicleAction.scala | 196 ++++++++ .../services/vehicle/VehicleService.scala | 452 +----------------- .../vehicle/VehicleServiceMessage.scala | 162 +------ .../vehicle/VehicleServiceResponse.scala | 138 +----- .../vehicle/support/TurretUpgrader.scala | 5 +- src/test/scala/objects/DamageableTest.scala | 26 +- src/test/scala/objects/DeploymentTest.scala | 26 +- .../scala/objects/FacilityTurretTest.scala | 2 +- src/test/scala/objects/RepairableTest.scala | 2 +- .../scala/objects/VehicleControlTest.scala | 48 +- .../scala/service/VehicleServiceTest.scala | 92 ++-- 70 files changed, 793 insertions(+), 1406 deletions(-) create mode 100644 src/main/scala/net/psforever/services/vehicle/VehicleAction.scala diff --git a/.codecov.yml b/.codecov.yml index b34307e32..06eb9388a 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -77,4 +77,3 @@ ignore: - "src/main/scala/net/psforever/services/hart/HartTimerActions.scala" - "src/main/scala/net/psforever/services/local/LocalAction.scala" - "src/main/scala/net/psforever/services/vehicle/VehicleAction.scala" - - "src/main/scala/net/psforever/services/vehicle/VehicleResponse.scala" diff --git a/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala b/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala index 6ca49eca0..1691f6244 100644 --- a/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala +++ b/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala @@ -82,11 +82,11 @@ class VehicleSpawnControl3Test extends ActorTest { probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideStart]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideEnd]) assert(probe.receiveOne(1 minute) match { - case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true case _ => false }) assert(probe.receiveOne(1 minute) match { - case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true case _ => false }) @@ -139,7 +139,7 @@ class VehicleSpawnControl5Test extends ActorTest() { probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer]) assert(probe.receiveOne(1 minute) match { - case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true + case VehicleServiceMessage(_, _, VehicleAction.LoadVehicle(_, _, _, _, _)) => true case _ => false }) assert(probe.receiveOne(1 minute) match { @@ -166,7 +166,7 @@ class VehicleSpawnControl6Test extends ActorTest() { probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer]) assert(probe.receiveOne(1 minute) match { - case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true + case VehicleServiceMessage(_, _, VehicleAction.LoadVehicle(_, _, _, _, _)) => true case _ => false }) assert(probe.receiveOne(1 minute) match { @@ -194,7 +194,7 @@ class VehicleSpawnControl7Test extends ActorTest { probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer]) assert(probe.receiveOne(1 minute) match { - case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true + case VehicleServiceMessage(_, _, VehicleAction.LoadVehicle(_, _, _, _, _)) => true case _ => false }) assert(probe.receiveOne(1 minute) match { diff --git a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala index de3d59d25..419174a9c 100644 --- a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala @@ -203,7 +203,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle)) data.continent.VehicleEvents ! VehicleServiceMessage( data.continent.id, - VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, shieldsUi, maxShieldsOfVehicle) + VehicleAction.PlanetsideAttribute(guid, shieldsUi, maxShieldsOfVehicle) ) } } @@ -217,7 +217,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf)) data.continent.VehicleEvents ! VehicleServiceMessage( data.continent.id, - VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, 0, maxHealthOf) + VehicleAction.PlanetsideAttribute(guid, 0, maxHealthOf) ) } } diff --git a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala index 1965825ab..a397908dd 100644 --- a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala @@ -15,7 +15,6 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.Service import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} @@ -215,7 +214,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse(Service.defaultPlayerGUID, PlayerStasisMessage(pguid)) //the stasis message + VehicleAction.SendResponse(PlayerStasisMessage(pguid)) //the stasis message ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state @@ -223,14 +222,12 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) //cower in the shuttle bay - ) + VehicleAction.SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) ) events ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(pguid, GenericObjectActionMessage(pguid, code=9)) //conceal the player + pguid, + VehicleAction.SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive @@ -258,7 +255,8 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act case Mountable.CanDismount(obj: Vehicle, seat_num, _) => continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.KickPassenger(tplayer.GUID, seat_num, unk2=true, obj.GUID) + tplayer.GUID, + VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID) ) case Mountable.CanDismount(obj: PlanetSideGameObject with PlanetSideGameObject with Mountable with FactionAffinity with InGameHistory, seatNum, _) => diff --git a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala index 6870f3c12..30400f266 100644 --- a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala @@ -78,8 +78,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex // continent.VehicleEvents ! VehicleServiceMessage( continent.id, + player.GUID, VehicleAction.VehicleState( - player.GUID, vehicle_guid, unk1, position, @@ -166,23 +166,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.FrameVehicleState( - player.GUID, - vehicle_guid, - unk1, - position, - angle, - velocity, - unk2, - unk3, - unk4, - is_crouched, - is_airborne, - ascending_flight, - flight_time, - unk9, - unkA - ) + player.GUID, + VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA) ) sessionLogic.squad.updateSquad() case (None, _) => @@ -236,7 +221,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex player.Orientation = angle continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw) + player.GUID, + VehicleAction.ChildObjectState(object_guid, pitch, yaw) ) } //TODO status condition of "playing getting out of vehicle to allow for late packets without warning @@ -258,20 +244,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.zoneInteractions() continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.VehicleState( - player.GUID, - vehicle_guid, - unk1, - pos, - ang, - obj.Velocity, - obj.Flying, - 0, - 0, - 15, - unk5 = false, - obj.Cloaked - ) + player.GUID, + VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) ) } } @@ -330,7 +304,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero)) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) + player.GUID, + VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) ) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala index ae8399757..96f629a6b 100644 --- a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala @@ -16,7 +16,6 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.Service import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} @@ -251,7 +250,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse(Service.defaultPlayerGUID, PlayerStasisMessage(pguid)) //the stasis message + VehicleAction.SendResponse(PlayerStasisMessage(pguid)) //the stasis message ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state @@ -259,14 +258,12 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) //cower in the shuttle bay - ) + VehicleAction.SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) ) events ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(pguid, GenericObjectActionMessage(pguid, code=9)) //conceal the player + pguid, + VehicleAction.SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive @@ -295,7 +292,8 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act case Mountable.CanDismount(obj: Vehicle, seat_num, _) => continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.KickPassenger(tplayer.GUID, seat_num, unk2=true, obj.GUID) + tplayer.GUID, + VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID) ) case Mountable.CanDismount(obj: PlanetSideGameObject with Mountable with FactionAffinity with InGameHistory, seatNum, _) => 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 f6102dedb..4eef98263 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -14,8 +14,9 @@ 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.services.Service +import net.psforever.services.base.EventResponse import net.psforever.services.local.support.CaptureFlagManager -import net.psforever.services.vehicle.{VehicleResponse, VehicleServiceResponse} +import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3} object VehicleHandlerLogic { @@ -38,7 +39,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: VehicleResponse.Response): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { val resolvedPlayerGuid = if (player.HasGUID) { player.GUID } else { @@ -46,7 +47,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: } val isNotSameTarget = resolvedPlayerGuid != guid reply match { - case VehicleResponse.VehicleState( + case VehicleAction.VehicleState( vehicleGuid, unk1, pos, @@ -74,7 +75,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: } } - case VehicleResponse.VehicleState( + case VehicleAction.VehicleState( vehicleGuid, unk1, pos, @@ -90,23 +91,23 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: //player who is watching the vehicle from the outside sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - case VehicleResponse.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => + case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) - case VehicleResponse.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 => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleResponse.ChangeFireState_Start(weaponGuid) if isNotSameTarget => + case VehicleAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case VehicleResponse.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => + case VehicleAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case VehicleResponse.Reload(itemGuid) if isNotSameTarget => + case VehicleAction.Reload(itemGuid) if isNotSameTarget => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case VehicleResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => + case VehicleAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0)) //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) sendResponse( @@ -119,7 +120,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: ) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case VehicleResponse.WeaponDryFire(weaponGuid) if isNotSameTarget => + case VehicleAction.WeaponDryFire(weaponGuid) if isNotSameTarget => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage @@ -127,45 +128,28 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(WeaponDryFireMessage(weaponGuid)) } - case VehicleResponse.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => sendResponse(DismountVehicleMsg(guid, bailType, wasKickedByDriver)) - case VehicleResponse.MountVehicle(vehicleGuid, seat) if isNotSameTarget => + case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => sendResponse(ObjectAttachMessage(vehicleGuid, guid, seat)) - case VehicleResponse.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => + case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos)) - case VehicleResponse.SendResponse(msg) => + case VehicleAction.SendResponse(msg) => sendResponse(msg) - case VehicleResponse.AttachToRails(vehicleGuid, padGuid) => - sendResponse(ObjectAttachMessage(padGuid, vehicleGuid, slot=3)) - - case VehicleResponse.ConcealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=9)) - - case VehicleResponse.DetachFromRails(vehicleGuid, padGuid, padPosition, padOrientationZ) => - val pad = continent.GUID(padGuid).get.asInstanceOf[VehicleSpawnPad].Definition - sendResponse( - ObjectDetachMessage( - padGuid, - vehicleGuid, - padPosition + Vector3.z(pad.VehicleCreationZOffset), - padOrientationZ + pad.VehicleCreationZOrientOffset - ) - ) - - case VehicleResponse.EquipmentInSlot(pkt) if isNotSameTarget => + case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) - case VehicleResponse.GenericObjectAction(objectGuid, action) if isNotSameTarget => + case VehicleAction.GenericObjectAction(objectGuid, action) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, action)) - case VehicleResponse.HitHint(sourceGuid) if player.isAlive => + case VehicleAction.HitHint(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, player.GUID)) - case VehicleResponse.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => + case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -176,7 +160,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: conData )) - case VehicleResponse.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid => + case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid => //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(guid, BailType.Kicked, wasKickedByDriver)) @@ -190,47 +174,41 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: log.info(s"${player.Name} has been kicked from $typeOfRide!") player.WhichSide = OutsideOf - case VehicleResponse.KickPassenger(_, wasKickedByDriver, _) => + 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(guid, BailType.Kicked, wasKickedByDriver)) - case VehicleResponse.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => + case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) - case VehicleResponse.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => + case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => //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)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleResponse.ObjectDelete(itemGuid) if isNotSameTarget => + case VehicleAction.ObjectDelete(itemGuid) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - case VehicleResponse.Ownership(vehicleGuid) if resolvedPlayerGuid == guid => + case VehicleAction.Ownership(vehicleGuid) if resolvedPlayerGuid == guid => //Only the player that owns this vehicle needs the ownership packet avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) sendResponse(PlanetsideAttributeMessage(resolvedPlayerGuid, attribute_type=21, vehicleGuid)) - case VehicleResponse.LoseOwnership(_, vehicleGuid) => + case VehicleAction.LoseOwnership(_, vehicleGuid) => ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") - case VehicleResponse.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => + case VehicleAction.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue)) - case VehicleResponse.ResetSpawnPad(padGuid) => - sendResponse(GenericObjectActionMessage(padGuid, code=23)) - - case VehicleResponse.RevealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=10)) - - case VehicleResponse.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => + case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) - case VehicleResponse.StowEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if isNotSameTarget => + case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if isNotSameTarget => //TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly? sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData)) - case VehicleResponse.UnloadVehicle(_, vehicleGuid) => + case VehicleAction.UnloadVehicle(_, vehicleGuid) => sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists { case ams: Vehicle => @@ -243,22 +221,22 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed")) } - case VehicleResponse.UnstowEquipment(itemGuid) if isNotSameTarget => + case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - case VehicleResponse.UpdateAmsSpawnPoint(list) => + case VehicleAction.UpdateAmsSpawnList(list) => sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() - case VehicleResponse.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget => + case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget => sessionLogic.zoning.interstellarFerry = Some(vehicle) sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) continent.VehicleEvents ! Service.Leave(Some(oldChannel)) //old vehicle-specific channel (was s"${vehicle.Actor}") galaxyService ! Service.Join(tempChannel) //temporary vehicle-specific channel log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating") - case VehicleResponse.KickCargo(vehicle, speed, delay) + case VehicleAction.KickCargo(vehicle, speed, delay) if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => val strafe = 1 + Vehicles.CargoOrientation(vehicle) val reverseSpeed = if (strafe > 1) { 0 } else { speed } @@ -281,75 +259,14 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: context.system.scheduler.scheduleOnce( delay milliseconds, context.self, - VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleResponse.KickCargo(vehicle, speed=0, delay)) + VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleAction.KickCargo(vehicle, speed=0, delay)) ) - case VehicleResponse.KickCargo(cargo, _, _) + case VehicleAction.KickCargo(cargo, _, _) if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => sessionLogic.vehicles.TotalDriverVehicleControl(cargo) - case VehicleResponse.StartPlayerSeatedInVehicle(vehicle, _) - if player.VisibleSlots.contains(player.DrawnSlot) => - player.DrawnSlot = Player.HandsDownSlot - startPlayerSeatedInVehicle(vehicle) - - case VehicleResponse.StartPlayerSeatedInVehicle(vehicle, _) => - startPlayerSeatedInVehicle(vehicle) - - case VehicleResponse.PlayerSeatedInVehicle(vehicle, _) => - Vehicles.ReloadAccessPermissions(vehicle, player.Name) - sessionLogic.vehicles.ServerVehicleOverrideWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=true, - lock_wheel=true, - reverse=true, - unk4=false, - lock_vthrust=1, - lock_strafe=0, - movement_speed=0, - unk8=Some(0) - ) - ) - sessionLogic.vehicles.serverVehicleControlVelocity = Some(0) - - case VehicleResponse.ServerVehicleOverrideStart(vehicle, _) => - val vdef = vehicle.Definition - sessionLogic.vehicles.ServerVehicleOverrideWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=true, - lock_wheel=true, - reverse=false, - unk4=false, - lock_vthrust=if (GlobalDefinitions.isFlightVehicle(vdef)) { 1 } else { 0 }, - lock_strafe=0, - movement_speed=vdef.AutoPilotSpeed1, - unk8=Some(0) - ) - ) - - case VehicleResponse.ServerVehicleOverrideEnd(vehicle, _) => - sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) - - case VehicleResponse.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, data) => - val str = s"${data.getOrElse("The vehicle spawn pad where you placed your order is blocked.")}" - val msg = if (str.contains("@")) { - ChatMsg(ChatMessageType.UNK_229, str) - } else { - ChatMsg(ChatMessageType.CMT_OPEN, wideContents = true, recipient = "", str, note = None) - } - sendResponse(msg) - - case VehicleResponse.PeriodicReminder(_, data) => - val (isType, flag, msg): (ChatMessageType, Boolean, String) = data match { - case Some(msg: String) if msg.startsWith("@") => (ChatMessageType.UNK_227, false, msg) - case Some(msg: String) => (ChatMessageType.CMT_OPEN, true, msg) - case _ => (ChatMessageType.CMT_OPEN, true, "Your vehicle order has been cancelled.") - } - sendResponse(ChatMsg(isType, flag, recipient="", msg, None)) - - case VehicleResponse.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory) + case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory) if player.avatar.vehicle.contains(target) => //TODO when vehicle weapons can be changed without visual glitches, rewrite this continent.GUID(target).collect { case vehicle: Vehicle => @@ -373,7 +290,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) } - case VehicleResponse.ChangeLoadout(target, oldWeapons, _, oldInventory, _) + case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) if sessionLogic.general.accessedContainer.map(_.GUID).contains(target) => //TODO when vehicle weapons can be changed without visual glitches, rewrite this continent.GUID(target).collect { case vehicle: Vehicle => @@ -382,12 +299,96 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) } - case VehicleResponse.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => + case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => //TODO when vehicle weapons can be changed without visual glitches, rewrite this continent.GUID(target).collect { case vehicle: Vehicle => changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) } + case VehicleSpawnPad.AttachToRails(vehicle, pad) => + sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3)) + + case VehicleSpawnPad.ConcealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=9)) + + case VehicleSpawnPad.DetachFromRails(vehicle, pad) => + val padDefinition = pad.Definition + sendResponse( + ObjectDetachMessage( + pad.GUID, + vehicle.GUID, + pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset), + pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset + ) + ) + + case VehicleSpawnPad.ResetSpawnPad(pad) => + sendResponse(GenericObjectActionMessage(pad.GUID, code=23)) + + case VehicleSpawnPad.RevealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=10)) + + case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) + if player.VisibleSlots.contains(player.DrawnSlot) => + player.DrawnSlot = Player.HandsDownSlot + startPlayerSeatedInVehicle(vehicle) + + case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) => + startPlayerSeatedInVehicle(vehicle) + + case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle, _) => + Vehicles.ReloadAccessPermissions(vehicle, player.Name) + sessionLogic.vehicles.ServerVehicleOverrideWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=true, + lock_wheel=true, + reverse=true, + unk4=false, + lock_vthrust=1, + lock_strafe=0, + movement_speed=0, + unk8=Some(0) + ) + ) + sessionLogic.vehicles.serverVehicleControlVelocity = Some(0) + + case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, _) => + val vdef = vehicle.Definition + sessionLogic.vehicles.ServerVehicleOverrideWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=true, + lock_wheel=true, + reverse=false, + unk4=false, + lock_vthrust=if (GlobalDefinitions.isFlightVehicle(vdef)) { 1 } else { 0 }, + lock_strafe=0, + movement_speed=vdef.AutoPilotSpeed1, + unk8=Some(0) + ) + ) + + case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) => + sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) + + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, data) => + val str = s"${data.getOrElse("The vehicle spawn pad where you placed your order is blocked.")}" + val msg = if (str.contains("@")) { + ChatMsg(ChatMessageType.UNK_229, str) + } else { + ChatMsg(ChatMessageType.CMT_OPEN, wideContents = true, recipient = "", str, note = None) + } + sendResponse(msg) + + case VehicleSpawnPad.PeriodicReminder(_, data) => + val (isType, flag, msg): (ChatMessageType, Boolean, String) = data match { + case Some(msg: String) if msg.startsWith("@") => (ChatMessageType.UNK_227, false, msg) + case Some(msg: String) => (ChatMessageType.CMT_OPEN, true, msg) + case _ => (ChatMessageType.CMT_OPEN, true, "Your vehicle order has been cancelled.") + } + sendResponse(ChatMsg(isType, flag, recipient="", msg, None)) + case _ => () } } diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala index 883fbfe94..ed6e4171e 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala @@ -77,8 +77,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex // continent.VehicleEvents ! VehicleServiceMessage( continent.id, + player.GUID, VehicleAction.VehicleState( - player.GUID, vehicle_guid, unk1, position, @@ -164,23 +164,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.FrameVehicleState( - player.GUID, - vehicle_guid, - unk1, - position, - angle, - velocity, - unk2, - unk3, - unk4, - is_crouched, - is_airborne, - ascending_flight, - flight_time, - unk9, - unkA - ) + player.GUID, + VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA) ) sessionLogic.squad.updateSquad() case (None, _) => @@ -232,7 +217,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex player.Orientation = angle continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw) + player.GUID, + VehicleAction.ChildObjectState(object_guid, pitch, yaw) ) } //TODO status condition of "playing getting out of vehicle to allow for late packets without warning @@ -254,20 +240,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.zoneInteractions() continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.VehicleState( - player.GUID, - vehicle_guid, - unk1, - pos, - ang, - obj.Velocity, - obj.Flying, - 0, - 0, - 15, - unk5 = false, - obj.Cloaked - ) + player.GUID, + VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) ) } } @@ -348,7 +322,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero)) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) + player.GUID, + VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) ) "; enforcing Mobile deployment state" } else { diff --git a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala index 42214bbd4..de1e1323b 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala @@ -12,7 +12,6 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.Service import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -78,7 +77,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse(Service.defaultPlayerGUID, PlayerStasisMessage(pguid)) //the stasis message + VehicleAction.SendResponse(PlayerStasisMessage(pguid)) //the stasis message ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state @@ -86,14 +85,12 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) //cower in the shuttle bay - ) + VehicleAction.SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) ) events ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(pguid, GenericObjectActionMessage(pguid, code=9)) //conceal the player + pguid, + VehicleAction.SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player ) context.self ! SessionActor.SetMode(NormalMode) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive @@ -113,7 +110,8 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act case Mountable.CanDismount(obj: Vehicle, seat_num, _) => continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.KickPassenger(tplayer.GUID, seat_num, unk2=true, obj.GUID) + tplayer.GUID, + VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID) ) case Mountable.CanDismount(obj: PlanetSideGameObject with PlanetSideGameObject with Mountable with FactionAffinity with InGameHistory, seatNum, _) => 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 d68308a68..ddb2d7b27 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -7,8 +7,9 @@ import net.psforever.objects.{Tool, 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, HitHint, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ReloadMessage, ServerVehicleOverrideMsg, VehicleStateMessage, WeaponDryFireMessage} -import net.psforever.services.vehicle.{VehicleResponse, VehicleServiceResponse} +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.services.base.EventResponse +import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} object VehicleHandlerLogic { @@ -31,7 +32,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: VehicleResponse.Response): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { val resolvedPlayerGuid = if (player.HasGUID) { player.GUID } else { @@ -39,7 +40,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: } val isNotSameTarget = resolvedPlayerGuid != guid reply match { - case VehicleResponse.VehicleState( + case VehicleAction.VehicleState( vehicleGuid, unk1, pos, @@ -59,7 +60,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: player.Velocity = vel sessionLogic.updateLocalBlockMap(pos) - case VehicleResponse.VehicleState( + case VehicleAction.VehicleState( vehicleGuid, unk1, pos, @@ -75,23 +76,23 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: //player who is watching the vehicle from the outside sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - case VehicleResponse.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => + case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) - case VehicleResponse.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 => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleResponse.ChangeFireState_Start(weaponGuid) if isNotSameTarget => + case VehicleAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case VehicleResponse.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => + case VehicleAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case VehicleResponse.Reload(itemGuid) if isNotSameTarget => + case VehicleAction.Reload(itemGuid) if isNotSameTarget => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case VehicleResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => + case VehicleAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0)) //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) sendResponse( @@ -104,7 +105,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: ) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case VehicleResponse.WeaponDryFire(weaponGuid) if isNotSameTarget => + case VehicleAction.WeaponDryFire(weaponGuid) if isNotSameTarget => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage @@ -112,42 +113,25 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(WeaponDryFireMessage(weaponGuid)) } - case VehicleResponse.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => sendResponse(DismountVehicleMsg(guid, bailType, wasKickedByDriver)) - case VehicleResponse.MountVehicle(vehicleGuid, seat) if isNotSameTarget => + case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => sendResponse(ObjectAttachMessage(vehicleGuid, guid, seat)) - case VehicleResponse.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => + case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos)) - case VehicleResponse.SendResponse(msg) => + case VehicleAction.SendResponse(msg) => sendResponse(msg) - case VehicleResponse.AttachToRails(vehicleGuid, padGuid) => - sendResponse(ObjectAttachMessage(padGuid, vehicleGuid, slot=3)) - - case VehicleResponse.ConcealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=9)) - - case VehicleResponse.DetachFromRails(vehicleGuid, padGuid, padPosition, padOrientationZ) => - val pad = continent.GUID(padGuid).get.asInstanceOf[VehicleSpawnPad].Definition - sendResponse( - ObjectDetachMessage( - padGuid, - vehicleGuid, - padPosition + Vector3.z(pad.VehicleCreationZOffset), - padOrientationZ + pad.VehicleCreationZOrientOffset - ) - ) - - case VehicleResponse.EquipmentInSlot(pkt) if isNotSameTarget => + case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) - case VehicleResponse.GenericObjectAction(objectGuid, action) if isNotSameTarget => + case VehicleAction.GenericObjectAction(objectGuid, action) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, action)) - case VehicleResponse.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => + case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -158,7 +142,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: conData )) - case VehicleResponse.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid => + case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid => //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(guid, BailType.Kicked, wasKickedByDriver)) @@ -168,46 +152,40 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case _ => () } - case VehicleResponse.KickPassenger(_, wasKickedByDriver, _) => + 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(guid, BailType.Kicked, wasKickedByDriver)) - case VehicleResponse.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => + case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) - case VehicleResponse.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => + case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => //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)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleResponse.ObjectDelete(itemGuid) if isNotSameTarget => + case VehicleAction.ObjectDelete(itemGuid) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - case VehicleResponse.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => + case VehicleAction.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue)) - case VehicleResponse.ResetSpawnPad(padGuid) => - sendResponse(GenericObjectActionMessage(padGuid, code=23)) - - case VehicleResponse.RevealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=10)) - - case VehicleResponse.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => + case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) - case VehicleResponse.UnloadVehicle(_, vehicleGuid) => + case VehicleAction.UnloadVehicle(_, vehicleGuid) => sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) - case VehicleResponse.UnstowEquipment(itemGuid) if isNotSameTarget => + case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - case VehicleResponse.UpdateAmsSpawnPoint(list) => + case VehicleAction.UpdateAmsSpawnList(list) => sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() - case VehicleResponse.KickCargo(vehicle, speed, delay) + case VehicleAction.KickCargo(vehicle, speed, delay) if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => val strafe = 1 + Vehicles.CargoOrientation(vehicle) val reverseSpeed = if (strafe > 1) { 0 } else { speed } @@ -230,17 +208,40 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: context.system.scheduler.scheduleOnce( delay milliseconds, context.self, - VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleResponse.KickCargo(vehicle, speed=0, delay)) + VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleAction.KickCargo(vehicle, speed=0, delay)) ) - case VehicleResponse.KickCargo(cargo, _, _) + case VehicleAction.KickCargo(cargo, _, _) if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => sessionLogic.vehicles.TotalDriverVehicleControl(cargo) - case VehicleResponse.ServerVehicleOverrideEnd(vehicle, _) => + case VehicleSpawnPad.AttachToRails(vehicle, pad) => + sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3)) + + case VehicleSpawnPad.ConcealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=9)) + + case VehicleSpawnPad.DetachFromRails(vehicle, pad) => + val padDefinition = pad.Definition + sendResponse( + ObjectDetachMessage( + pad.GUID, + vehicle.GUID, + pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset), + pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset + ) + ) + + case VehicleSpawnPad.ResetSpawnPad(pad) => + sendResponse(GenericObjectActionMessage(pad.GUID, code=23)) + + case VehicleSpawnPad.RevealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=10)) + + case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) => sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) - case VehicleResponse.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => + case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => //TODO when vehicle weapons can be changed without visual glitches, rewrite this continent.GUID(target).collect { case vehicle: Vehicle => changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) diff --git a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala index c61499dd8..ec7b4d4b4 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala @@ -41,20 +41,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.zoneInteractions() continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.VehicleState( - player.GUID, - vehicle_guid, - unk1, - pos, - ang, - obj.Velocity, - obj.Flying, - 0, - 0, - 15, - unk5 = false, - obj.Cloaked - ) + player.GUID, + VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) ) case _ => () } @@ -94,7 +82,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero)) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) + player.GUID, + VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) ) "; enforcing Mobile deployment state" } else { diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 5e3cdb08e..5cef27ea4 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -1016,7 +1016,8 @@ class GeneralOperations( obj.Seats(seatNum).unmount(tplayer) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.KickPassenger(tplayer.GUID, seatNum, unk2=false, obj.GUID) + tplayer.GUID, + VehicleAction.KickPassenger(seatNum, unk2=false, obj.GUID) ) case _ => () } 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 33b838102..cf17f9a4a 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -569,7 +569,8 @@ class SessionData( obj.Seats(seatNum).unmount(tplayer) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.KickPassenger(tplayer.GUID, seatNum, unk2=false, obj.GUID) + tplayer.GUID, + VehicleAction.KickPassenger(seatNum, unk2=false, obj.GUID) ) case _ => () } diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index 7f5004529..c2f1c543e 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -8,7 +8,6 @@ import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle} import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} // @@ -187,7 +186,8 @@ class SessionMountHandlers( sendResponse(ObjectAttachMessage(objGuid, playerGuid, seatNum)) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.MountVehicle(playerGuid, objGuid, seatNum) + playerGuid, + VehicleAction.MountVehicle(objGuid, seatNum) ) } @@ -204,11 +204,11 @@ class SessionMountHandlers( sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(Service.defaultPlayerGUID, PlanetsideAttributeMessage(obj.GUID, 81, 1)) + VehicleAction.SendResponse(PlanetsideAttributeMessage(obj.GUID, 81, 1)) ) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(Service.defaultPlayerGUID, ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) + VehicleAction.SendResponse(ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) ) } else { @@ -225,20 +225,8 @@ class SessionMountHandlers( v.Velocity = Vector3.Zero continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.VehicleState( - tplayer.GUID, - v.GUID, - unk1 = 0, - tplayer.Position, - v.Orientation, - v.Velocity, - v.Flying, - unk3 = 0, - unk4 = 0, - wheel_direction = 15, - unk5 = false, - unk6 = v.Cloaked - ) + tplayer.GUID, + VehicleAction.VehicleState(v.GUID, unk1 = 0, tplayer.Position, v.Orientation, v.Velocity, v.Flying, unk3 = 0, unk4 = 0, wheel_direction = 15, unk5 = false, unk6 = v.Cloaked) ) case _ => () } @@ -262,7 +250,8 @@ class SessionMountHandlers( sendResponse(DismountVehicleMsg(playerGuid, bailType, wasKickedByDriver = false)) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.DismountVehicle(playerGuid, bailType, unk2 = false) + playerGuid, + VehicleAction.DismountVehicle(bailType, unk2 = false) ) } diff --git a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala index b493b1ff2..03d0f0df2 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala @@ -5,13 +5,13 @@ import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.objects.Vehicle import net.psforever.packet.game.ChatMsg -import net.psforever.services.vehicle.VehicleResponse +import net.psforever.services.base.EventResponse import net.psforever.types.{ChatMessageType, DriveState, PlanetSideGUID} trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality { def ops: SessionVehicleHandlers - def handle(toChannel: String, guid: PlanetSideGUID, reply: VehicleResponse.Response): Unit + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit } class SessionVehicleHandlers( diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index 13668606c..f9dbb878f 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -286,7 +286,8 @@ class WeaponAndProjectileOperations( case _: Equipment => continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.WeaponDryFire(player.GUID, weapon_guid) + player.GUID, + VehicleAction.WeaponDryFire(weapon_guid) ) } .orElse { @@ -1098,7 +1099,8 @@ class WeaponAndProjectileOperations( } continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.ChangeFireState_Start(player.GUID, itemGuid) + player.GUID, + VehicleAction.ChangeFireState_Start(itemGuid) ) } @@ -1138,7 +1140,8 @@ class WeaponAndProjectileOperations( } continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.ChangeFireState_Stop(player.GUID, itemGuid) + player.GUID, + VehicleAction.ChangeFireState_Stop(itemGuid) ) } @@ -1201,7 +1204,8 @@ class WeaponAndProjectileOperations( def reloadVehicleMessages(itemGuid: PlanetSideGUID): Unit = { continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.Reload(player.GUID, itemGuid) + player.GUID, + VehicleAction.Reload(itemGuid) ) } @@ -1478,13 +1482,8 @@ class WeaponAndProjectileOperations( obj.Find(box).collect { index => continent.VehicleEvents ! VehicleServiceMessage( s"${obj.Actor}", - VehicleAction.InventoryState( - player.GUID, - box, - obj.GUID, - index, - box.Definition.Packet.DetailedConstructorData(box).get - ) + player.GUID, + VehicleAction.InventoryState(box, obj.GUID, index, box.Definition.Packet.DetailedConstructorData(box).get) ) } } diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index e491e35fe..846a0449d 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -549,7 +549,7 @@ class ZoningOperations( } //spawn point update request continent.VehicleEvents ! VehicleServiceMessage( - continent.id, + player.Name, VehicleAction.UpdateAmsSpawnPoint(continent) ) spawn.upstreamMessageCount = 0 @@ -1353,7 +1353,8 @@ class ZoningOperations( val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID) continent.VehicleEvents ! VehicleServiceMessage( s"${vehicle.Actor}", - VehicleAction.TransferPassengerChannel(pguid, s"${vehicle.Actor}", toChannel, vehicle, topLevel) + pguid, + VehicleAction.TransferPassengerChannel(s"${vehicle.Actor}", toChannel, vehicle, topLevel) ) manifest.cargo.foreach { case ManifestPassengerEntry("MISSING_DRIVER", index) => @@ -1366,7 +1367,8 @@ class ZoningOperations( val cargo = vehicle.CargoHolds(entry.mount).occupant.get continent.VehicleEvents ! VehicleServiceMessage( entry.name, - VehicleAction.TransferPassengerChannel(pguid, s"${cargo.Actor}", toChannel, cargo, topLevel) + pguid, + VehicleAction.TransferPassengerChannel(s"${cargo.Actor}", toChannel, cargo, topLevel) ) } // @@ -1397,7 +1399,8 @@ class ZoningOperations( //do not delete if vehicle has passengers or cargo continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.UnloadVehicle(pguid, vehicle, topLevel) + pguid, + VehicleAction.UnloadVehicle(vehicle, topLevel) ) None } else { @@ -2595,7 +2598,8 @@ class ZoningOperations( .foreach { _.MountedIn = vguid } events ! VehicleServiceMessage( zoneid, - VehicleAction.LoadVehicle(player.GUID, vehicle, vObjectId, vguid, data) + player.GUID, + VehicleAction.LoadVehicle(vehicle, vObjectId, vguid, data) ) carrierInfo match { case (Some(carrier), Some((index, _))) => @@ -2622,7 +2626,8 @@ class ZoningOperations( val zone = vehicle.PreviousGatingManifest().get.origin zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.UnloadVehicle(player.GUID, vehicle, vehicleToDelete) + player.GUID, + VehicleAction.UnloadVehicle(vehicle, vehicleToDelete) ) log.debug( s"AvatarCreate: cleaning up ghost of transitioning vehicle ${vehicle.Definition.Name}@${vehicleToDelete.guid} in zone ${zone.id}" @@ -3392,7 +3397,8 @@ class ZoningOperations( vehicle.OwnerGuid = guid continent.VehicleEvents ! VehicleServiceMessage( s"${tplayer.Faction}", - VehicleAction.Ownership(guid, vehicle.GUID) + guid, + VehicleAction.Ownership(vehicle.GUID) ) case _ => avatarActor ! AvatarActor.SetVehicle(None) diff --git a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala index be51a5cba..d1088a9bf 100644 --- a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala @@ -13,7 +13,6 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, TurretSource} import net.psforever.objects.vital.{DismountingActivity, InGameActivity, MountingActivity, ShieldCharge} import net.psforever.packet.game.HackState1 import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} -import net.psforever.types.PlanetSideGUID import scala.annotation.unused @@ -100,7 +99,7 @@ class FieldTurretControl(turret: TurretDeployable) turret.Shields = turret.Shields + amount turret.Zone.VehicleEvents ! VehicleServiceMessage( s"${turret.Actor}", - VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields) + VehicleAction.PlanetsideAttribute(turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields) ) } } diff --git a/src/main/scala/net/psforever/objects/SensorDeployable.scala b/src/main/scala/net/psforever/objects/SensorDeployable.scala index cea1251aa..b3a2fad81 100644 --- a/src/main/scala/net/psforever/objects/SensorDeployable.scala +++ b/src/main/scala/net/psforever/objects/SensorDeployable.scala @@ -77,7 +77,7 @@ class SensorDeployableControl(sensor: SensorDeployable) case obj: PlanetSideServerObject if !jammedSound => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 1) + VehicleAction.PlanetsideAttribute(obj.GUID, 54, 1) ) super.StartJammeredSound(obj, dur) case _ => ; @@ -101,7 +101,7 @@ class SensorDeployableControl(sensor: SensorDeployable) val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 0) + VehicleAction.PlanetsideAttribute(obj.GUID, 54, 0) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala index 15a7ceadc..f6247f13f 100644 --- a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala +++ b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala @@ -14,7 +14,6 @@ import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.resolution.ResolutionCalculations import net.psforever.types.PlanetSideGUID -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} class ShieldGeneratorDeployable(cdef: ShieldGeneratorDefinition) @@ -22,12 +21,12 @@ class ShieldGeneratorDeployable(cdef: ShieldGeneratorDefinition) with Hackable with JammableUnit -class ShieldGeneratorDefinition extends DeployableDefinition(240) +class ShieldGeneratorDefinition extends DeployableDefinition(objectId = 240) with WithShields { Packet = new ShieldGeneratorConverter DeployCategory = DeployableCategory.ShieldGenerators - override def Initialize(obj: Deployable, context: ActorContext) = { + override def Initialize(obj: Deployable, context: ActorContext): Unit = { obj.Actor = context.actorOf(Props(classOf[ShieldGeneratorControl], obj), PlanetSideServerObject.UniqueActorName(obj)) } @@ -39,10 +38,10 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) with JammableBehavior with DamageableEntity with RepairableEntity { - def DeployableObject = gen - def JammableObject = gen - def DamageableObject = gen - def RepairableObject = gen + def DeployableObject: ShieldGeneratorDeployable = gen + def JammableObject: ShieldGeneratorDeployable = gen + def DamageableObject: ShieldGeneratorDeployable = gen + def RepairableObject: ShieldGeneratorDeployable = gen deletionType = 1 //from DeployableBehavior override def postStop(): Unit = { @@ -127,7 +126,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) case obj: PlanetSideServerObject with JammableUnit => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1) + VehicleAction.PlanetsideAttribute(obj.GUID, 27, 1) ) super.StartJammeredStatus(obj, dur) case _ => ; @@ -140,7 +139,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) case obj: PlanetSideServerObject with JammableUnit if obj.Jammed => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 0) + VehicleAction.PlanetsideAttribute(obj.GUID, 27, 0) ) case _ => ; } @@ -162,7 +161,7 @@ object ShieldGeneratorControl { val zone = target.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 68, target.Shields) + VehicleAction.PlanetsideAttribute(target.GUID, 68, target.Shields) ) } } diff --git a/src/main/scala/net/psforever/objects/TurretDeployable.scala b/src/main/scala/net/psforever/objects/TurretDeployable.scala index f21f74707..576a1629c 100644 --- a/src/main/scala/net/psforever/objects/TurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/TurretDeployable.scala @@ -111,7 +111,8 @@ abstract class TurretDeployableControl player.VehicleSeated = None zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.KickPassenger(player.GUID, 4, wasKickedByDriver, TurretObject.GUID) + player.GUID, + VehicleAction.KickPassenger(4, wasKickedByDriver, TurretObject.GUID) ) } } diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 5ae4191fe..5db132936 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -47,7 +47,8 @@ object Vehicles { Vehicles.ReloadAccessPermissions(vehicle, tplayer.Faction.toString) vehicle.Zone.VehicleEvents ! VehicleServiceMessage( vehicle.Zone.id, - VehicleAction.Ownership(tplayer.GUID, vehicle.GUID) + tplayer.GUID, + VehicleAction.Ownership(vehicle.GUID) ) Some(vehicle) case None => @@ -138,13 +139,14 @@ object Vehicles { val pguid = player.GUID if (vehicle.OwnerGuid.contains(pguid)) { vehicle.AssignOwnership(None) - //vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, VehicleAction.Ownership(pguid, PlanetSideGUID(0))) + //vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, pguid, VehicleAction.Ownership(pguid, PlanetSideGUID(0))) //val vguid = vehicle.GUID val empire = VehicleLockState.Empire.id (0 to 2).foreach(group => { vehicle.PermissionGroup(group, empire) /*vehicle.Zone.VehicleEvents ! VehicleServiceMessage( s"${vehicle.Faction}", + pguid, VehicleAction.SeatPermissions(pguid, vguid, group, empire) )*/ }) @@ -252,10 +254,7 @@ object Vehicles { val previousOwnerName = target.OwnerName.getOrElse("") vehicleEvents ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8) - ) + VehicleAction.SendResponse(HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8)) ) target.Actor ! CommonMessages.Hack(hacker, target) // Forcefully dismount any cargo @@ -272,7 +271,8 @@ object Vehicles { player.VehicleSeated = None vehicleEvents ! VehicleServiceMessage( zoneid, - VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, tGuid) + player.GUID, + VehicleAction.KickPassenger(4, unk2 = false, tGuid) ) } // In case BFR is occupied and may or may not be crouched @@ -345,15 +345,12 @@ object Vehicles { util.Actor ! TelepadLike.Activate(util) } case GlobalDefinitions.ams if target.DeploymentState == DriveState.Deployed => - vehicleEvents ! VehicleServiceMessage.AMSDeploymentChange(zone) + vehicleEvents ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) case _ => () } vehicleEvents ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8) - ) + VehicleAction.SendResponse(HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8)) ) target.Actor ! CommonMessages.ClearHack() } diff --git a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala index 5547f36fd..faee62ec9 100644 --- a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala +++ b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala @@ -10,7 +10,6 @@ import net.psforever.objects.vital.RepairFromArmorSiphon import net.psforever.objects.vital.etc.{ArmorSiphonModifiers, ArmorSiphonReason} import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.packet.game.QuantityUpdateMessage -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.PlanetSideGUID @@ -80,7 +79,7 @@ object ArmorSiphonBehavior { val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 0, after) + VehicleAction.PlanetsideAttribute(obj.GUID, 0, after) ) } case _ => ; @@ -99,7 +98,7 @@ object ArmorSiphonBehavior { //update current charge level zone.VehicleEvents ! VehicleServiceMessage( obj.Actor.toString, - VehicleAction.SendResponse(Service.defaultPlayerGUID, QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine)) + VehicleAction.SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine)) ) siphonRecharge.put(guid, context.system.scheduler.scheduleWithFixedDelay( initialDelay = 3000 milliseconds, @@ -121,7 +120,7 @@ object ArmorSiphonBehavior { if (after > before) { zone.VehicleEvents ! VehicleServiceMessage( obj.Actor.toString, - VehicleAction.SendResponse(Service.defaultPlayerGUID, QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after)) + VehicleAction.SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after)) ) if (after == siphon.MaxMagazine) { endSiphonRecharge(guid) diff --git a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala index 84443d560..ed89d9ba2 100644 --- a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala +++ b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala @@ -9,7 +9,6 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.{Zone, ZoneAware} import net.psforever.types.Vector3 -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.collection.mutable @@ -245,7 +244,7 @@ trait JammableMountedWeapons extends JammableBehavior { case obj: PlanetSideServerObject with MountedWeapons with JammableUnit if !jammedSound => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1) + VehicleAction.PlanetsideAttribute(obj.GUID, 27, 1) ) super.StartJammeredSound(target, dur) case _ => ; @@ -266,7 +265,7 @@ trait JammableMountedWeapons extends JammableBehavior { case obj: PlanetSideServerObject if jammedSound => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 0) + VehicleAction.PlanetsideAttribute(obj.GUID, 27, 0) ) case _ => ; } @@ -310,7 +309,7 @@ object JammableMountedWeapons { target.Jammed = statusCode == 1 zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 27, statusCode) + VehicleAction.PlanetsideAttribute(target.GUID, 27, statusCode) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index 28cb07aae..0f177da03 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -144,21 +144,21 @@ trait DamageableVehicle if (damageToShields > 0) { events ! VehicleServiceMessage( shieldChannel, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, obj.Definition.shieldUiAttribute, obj.Shields) + VehicleAction.PlanetsideAttribute(targetGUID, obj.Definition.shieldUiAttribute, obj.Shields) ) announceConfrontation = true } if (damageToHealth > 0) { events ! VehicleServiceMessage( healthChannel, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, obj.Health) + VehicleAction.PlanetsideAttribute(targetGUID, 0, obj.Health) ) announceConfrontation = true } } if (announceConfrontation) { if (showAsAggravated) { - val msg = VehicleAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(totalDamage, Vector3.Zero)) + val msg = VehicleAction.SendResponse(DamageWithPositionMessage(totalDamage, Vector3.Zero)) obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } .foreach { channel => @@ -219,7 +219,7 @@ trait DamageableVehicle obj.Shields = 0 zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, obj.Definition.shieldUiAttribute, 0) + VehicleAction.PlanetsideAttribute(target.GUID, obj.Definition.shieldUiAttribute, 0) ) } //database entry @@ -252,13 +252,13 @@ trait DamageableVehicle val guid = obj.GUID events ! VehicleServiceMessage( zoneid, - VehicleAction.PlanetsideAttribute(guid0, guid, 0, 1) + VehicleAction.PlanetsideAttribute(guid, 0, 1) ) if (obj.Shields > 0) { obj.Shields = 0 zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, obj.Definition.shieldUiAttribute, 0) + VehicleAction.PlanetsideAttribute(obj.GUID, obj.Definition.shieldUiAttribute, 0) ) } //aggravation cancel diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index 6900ea938..b901fb193 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -9,10 +9,10 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types.Vector3 -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.support.SupportActor import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} /** * The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects. @@ -64,14 +64,14 @@ trait DamageableWeaponTurret DamageableMountable.DamageAwareness(DamageableObject, cause, damageToHealth) events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, obj.Health) + VehicleAction.PlanetsideAttribute(targetGUID, 0, obj.Health) ) announceConfrontation = true } } if (announceConfrontation) { if (aggravated) { - val msg = VehicleAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(damageToHealth, Vector3.Zero)) + val msg = VehicleAction.SendResponse(DamageWithPositionMessage(damageToHealth, Vector3.Zero)) obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } .foreach { channel => @@ -112,7 +112,7 @@ object DamageableWeaponTurret { * @see `TurretUpgrader.AddTask` * @see `TurretUpgrader.ClearSpecific` * @see `WeaponTurret` - * @see `VehicleServiceMessage.TurretUpgrade` + * @see `TurretMessage` * @see `Zone.AvatarEvents` * @see `Zone.VehicleEvents` * @param target the entity being destroyed; @@ -137,8 +137,8 @@ object DamageableWeaponTurret { case turret: WeaponTurret => if (turret.Upgrade != TurretUpgrade.None) { val vehicleEvents = zone.VehicleEvents - vehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(turret), zone)) - vehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None)) + vehicleEvents ! TurretMessage(SupportActor.ClearSpecific(List(turret), zone)) + vehicleEvents ! TurretMessage(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None)) } case _ => } diff --git a/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala index 0eb8cf718..49df2465a 100644 --- a/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala @@ -106,7 +106,7 @@ trait DeploymentBehavior { obj.Velocity = Some(Vector3.Zero) //no velocity zone.VehicleEvents ! VehicleServiceMessage( zoneChannel, - VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero) + VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) deploymentTimer.cancel() deploymentTimer = context.system.scheduler.scheduleOnce(obj.DeployTime.milliseconds)({ @@ -117,7 +117,7 @@ trait DeploymentBehavior { obj.Velocity = Some(Vector3.Zero) //no velocity zone.VehicleEvents ! VehicleServiceMessage( zoneChannel, - VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero) + VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) state } else { @@ -138,7 +138,7 @@ trait DeploymentBehavior { if (state == DriveState.Undeploying) { zone.VehicleEvents ! VehicleServiceMessage( zoneChannel, - VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero) + VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) import scala.concurrent.ExecutionContext.Implicits.global deploymentTimer.cancel() @@ -149,7 +149,7 @@ trait DeploymentBehavior { } else if (state == DriveState.Mobile) { zone.VehicleEvents ! VehicleServiceMessage( zoneChannel, - VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero) + VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) state } else { diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala index 29bd0f511..4eb50c1e1 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala @@ -11,6 +11,7 @@ import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.TerminalUsedActivity import net.psforever.objects.zones.{Zone, ZoneAware, Zoning} import net.psforever.objects.{Default, PlanetSideGameObject, Player, Vehicle} +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{PlanetSideGUID, TransactionType, Vector3} import scala.annotation.tailrec @@ -128,7 +129,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) } trackedOrder = None handleOrderFunc = NewTasking - pad.Zone.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad) //cautious animation reset + pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) //cautious animation reset self ! akka.actor.Kill //should cause the actor to restart, which will abort any trapped messages case _ => () @@ -164,19 +165,17 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) //first queued order orders = List(order) queueManagementTask() - pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder( + pad.Zone.VehicleEvents ! VehicleServiceMessage( name, - VehicleSpawnPad.Reminders.Queue, - Some(s"@SVCP_PositionInQueue^2~^2~") + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^2~^2~")) ) case -1 => //new order orders = orders :+ order val size = orders.size + 1 - pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder( + pad.Zone.VehicleEvents ! VehicleServiceMessage( name, - VehicleSpawnPad.Reminders.Queue, - Some(s"@SVCP_PositionInQueue^$size~^$size~") + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^$size~^$size~")) ) case n if orders(n).vehicle.Definition ne order.vehicle.Definition => //replace existing order with new order @@ -185,10 +184,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) val originalVehicle = originalOrder.vehicle.Definition.Name orders = (orders.take(n) :+ order) ++ orders.drop(n+1) VehicleSpawnControl.DisposeVehicle(originalOrder.vehicle, zone) - zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder( + zone.VehicleEvents ! VehicleServiceMessage( name, - VehicleSpawnPad.Reminders.Queue, - Some(s"@SVCP_ReplacedVehicleWithVehicle^@$originalVehicle~^@${order.vehicle.Definition.Name}~") + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_ReplacedVehicleWithVehicle^@$originalVehicle~^@${order.vehicle.Definition.Name}~")) ) case _ => //order is the duplicate of an existing order; do nothing to the queue @@ -245,10 +243,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) val newOrder = VehicleSpawnControl.Order(driver, vehicle) recursiveOrderReminder(orders.iterator, size) trace(s"processing next order - a ${vehicle.Definition.Name} for $name") - pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder( + pad.Zone.VehicleEvents ! VehicleServiceMessage( name, - VehicleSpawnPad.Reminders.Queue, - Some(s"@SVCP_PositionInQueue^1~^$size~") + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^1~^$size~")) ) trackedOrder = Some(newOrder) //guard on context.system.scheduler.scheduleOnce(2000 milliseconds, concealPlayer, newOrder) @@ -324,7 +321,10 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) private def CancelOrder(vehicle: Vehicle, player: Player, msg: Option[String]): Unit = { if (vehicle.Seats.values.count(_.isOccupied) == 0) { VehicleSpawnControl.DisposeSpawnedVehicle(vehicle, player, pad.Zone) - pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(player.Name, VehicleSpawnPad.Reminders.Cancelled, msg) + pad.Zone.VehicleEvents ! VehicleServiceMessage( + player.Name, + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Cancelled, msg) + ) } } @@ -451,10 +451,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) entry: VehicleSpawnPad.VehicleOrder, cause: Option[Any] ): Unit = { - pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder( + pad.Zone.VehicleEvents ! VehicleServiceMessage( entry.player.Name, - VehicleSpawnPad.Reminders.Blocked, - cause + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, cause) ) } @@ -465,10 +464,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) ): Unit = { if (iter.hasNext) { val recipient = iter.next() - pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder( + pad.Zone.VehicleEvents ! VehicleServiceMessage( recipient.player.Name, - VehicleSpawnPad.Reminders.Queue, - Some(s"@SVCP_PositionInQueue^$position~^$size~") + VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^$position~^$size~")) ) recursiveOrderReminder(iter, size, position + 1) } @@ -564,7 +562,7 @@ object VehicleSpawnControl { */ private def DisposeSpawnedVehicle(vehicle: Vehicle, player: Player, zone: Zone): Unit = { DisposeVehicle(vehicle, zone) - zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(player.GUID) + zone.VehicleEvents ! VehicleServiceMessage(zone.id, VehicleSpawnPad.RevealPlayer(player.GUID)) } /** diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala index 4b9bb47c4..a08939d98 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala @@ -5,6 +5,7 @@ import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.objects.{Player, Vehicle} import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.serverobject.terminals.Terminal +import net.psforever.services.base.SelfResponseMessage import net.psforever.types.PlanetSideGUID /** @@ -25,7 +26,6 @@ class VehicleSpawnPad(spDef: VehicleSpawnPadDefinition) extends Amenity { } object VehicleSpawnPad { - /** * Message to the spawn pad to enqueue the following vehicle order. * This is the entry point to vehicle spawn pad functionality. @@ -39,14 +39,14 @@ object VehicleSpawnPad { * @see `GenericObjectActionMessage` * @param player_guid the player */ - final case class ConcealPlayer(player_guid: PlanetSideGUID) + final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage /** * Message is intended to undo the effects of the above message, `ConcealPlayer`. * @see `ConcealPlayer` * @param player_guid the player */ - final case class RevealPlayer(player_guid: PlanetSideGUID) + final case class RevealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage /** * Message to attach the vehicle to the spawn pad's lifting platform ("put on rails"). @@ -55,7 +55,7 @@ object VehicleSpawnPad { * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad) + final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message to detach the vehicle from the spawn pad's lifting platform ("put on rails"). @@ -63,72 +63,64 @@ object VehicleSpawnPad { * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad) + final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message that resets the spawn pad for its next order fulfillment operation by lowering the lifting platform. * @see `GenericObjectActionMessage` * @param pad the spawn pad */ - final case class ResetSpawnPad(pad: VehicleSpawnPad) + final case class ResetSpawnPad(pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message that acts as callback to the driver that the process of sitting in the driver mount will be initiated soon. * This information should only be communicated to the driver's client only. - * @param driver_name the person who will drive the vehicle * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class StartPlayerSeatedInVehicle(driver_name: String, vehicle: Vehicle, pad: VehicleSpawnPad) + final case class StartPlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message that acts as callback to the driver that the process of sitting in the driver mount should be finished. * This information should only be communicated to the driver's client only. - * @param driver_name the person who will drive the vehicle * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class PlayerSeatedInVehicle( - driver_name: String, - vehicle: Vehicle, - pad: VehicleSpawnPad - ) //TODO while using fake rails + //TODO while using fake rails (later edit: what does this mean?) + final case class PlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message that starts the newly-spawned vehicle to begin driving away from the spawn pad. * Information about the driving process is available on the vehicle itself. * This information should only be communicated to the driver's client only. * @see `VehicleDefinition` - * @param driver_name the person who will drive the vehicle * @param vehicle the vehicle * @param pad the spawn pad */ - final case class ServerVehicleOverrideStart(driver_name: String, vehicle: Vehicle, pad: VehicleSpawnPad) + final case class ServerVehicleOverrideStart(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message that transitions the newly-spawned vehicle into a cancellable auto-drive state. * Information about the driving process is available on the vehicle itself. * This information should only be communicated to the driver's client only. * @see `VehicleDefinition` - * @param driver_name the person who will drive the vehicle * @param vehicle the vehicle * @param pad the spawn pad */ - final case class ServerVehicleOverrideEnd(driver_name: String, vehicle: Vehicle, pad: VehicleSpawnPad) + final case class ServerVehicleOverrideEnd(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage /** * Message to initiate the process of properly disposing of the vehicle that may have been or was spawned into the game world. * @param vehicle the vehicle */ - final case class DisposeVehicle(vehicle: Vehicle) + final case class DisposeVehicle(vehicle: Vehicle) extends SelfResponseMessage /** * Message to send targeted messages to the clients of specific users. - * @param driver_name the person who will drive the vehicle * @param reason the nature of the message * @param data optional information for rendering the message to the client */ - final case class PeriodicReminder(driver_name: String, reason: Reminders.Value, data: Option[Any] = None) + final case class PeriodicReminder(reason: Reminders.Value, data: Option[Any] = None) extends SelfResponseMessage /** * An `Enumeration` of reasons for sending a periodic reminder to the user. diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala index b035a7849..3f3813584 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala @@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Props import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} +import net.psforever.services.vehicle.VehicleServiceMessage import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -28,7 +29,7 @@ class VehicleSpawnControlConcealPlayer(pad: VehicleSpawnPad) extends VehicleSpaw case order @ VehicleSpawnControl.Order(driver, vehicle) => if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty) { trace(s"hiding ${driver.Name}") - pad.Zone.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID) + pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.ConcealPlayer(driver.GUID)) context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order) } else { trace(s"integral component lost; abort order fulfillment") diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala index dbef9a3c8..d43d36a43 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala @@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Props import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} +import net.psforever.services.vehicle.VehicleServiceMessage /** * An `Actor` that handles vehicle spawning orders for a `VehicleSpawnPad`. @@ -24,7 +25,7 @@ class VehicleSpawnControlDriverControl(pad: VehicleSpawnPad) extends VehicleSpaw case order @ VehicleSpawnControl.Order(driver, vehicle) => trace(s"returning control of ${vehicle.Definition.Name} to its current driver") if (vehicle.PassengerInSeat(driver).nonEmpty) { - pad.Zone.VehicleEvents ! VehicleSpawnPad.ServerVehicleOverrideEnd(driver.Name, vehicle, pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(driver.Name, VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, pad)) } finalClear ! order diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala index 67c8d6e61..d8ab0a7c5 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala @@ -4,7 +4,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Cancellable import net.psforever.objects.Default import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} -import net.psforever.types.{PlanetSideGUID, Vector3} +import net.psforever.types.Vector3 import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.concurrent.ExecutionContext.Implicits.global @@ -37,13 +37,7 @@ class VehicleSpawnControlFinalClearance(pad: VehicleSpawnPad) extends VehicleSpa val definition = vehicle.Definition pad.Zone.VehicleEvents ! VehicleServiceMessage( s"${pad.Continent}", - VehicleAction.LoadVehicle( - PlanetSideGUID(0), - vehicle, - definition.ObjectId, - vehicle.GUID, - definition.Packet.ConstructorData(vehicle).get - ) + VehicleAction.LoadVehicle(vehicle, definition.ObjectId, vehicle.GUID, definition.Packet.ConstructorData(vehicle).get) ) } context.parent ! VehicleSpawnControl.ProcessControl.Reminder @@ -70,7 +64,7 @@ class VehicleSpawnControlFinalClearance(pad: VehicleSpawnPad) extends VehicleSpa } case VehicleSpawnControlFinalClearance.NextOrder => - pad.Zone.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder case _ => () diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala index 7bbb1123c..bf2a90b48 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala @@ -7,7 +7,6 @@ import akka.util.Timeout import net.psforever.objects.GlobalDefinitions import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} import net.psforever.objects.zones.Zone -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.Vector3 import net.psforever.zones.Zones @@ -70,7 +69,7 @@ class VehicleSpawnControlLoadVehicle(pad: VehicleSpawnPad) extends VehicleSpawnC val vdata = definition.Packet.ConstructorData(v).get zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.LoadVehicle(Service.defaultPlayerGUID, v, vtype, vguid, vdata) + VehicleAction.LoadVehicle(v, vtype, vguid, vdata) ) railJack ! temp.get temp = None diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala index c7740c7da..f3142039b 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala @@ -11,6 +11,7 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.objects.vital.prop.DamageProperties import net.psforever.objects.vital.Vitality import net.psforever.objects.zones.Zone +import net.psforever.services.vehicle.VehicleServiceMessage import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -40,7 +41,7 @@ class VehicleSpawnControlRailJack(pad: VehicleSpawnPad) extends VehicleSpawnCont pad.Definition.killBox(pad, vehicle.Definition.CanFly), Zone.findAllTargets ) - pad.Zone.VehicleEvents ! VehicleSpawnPad.AttachToRails(vehicle, pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.AttachToRails(vehicle, pad)) context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, order) case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) => diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala index 520d0c1ec..92ca1f010 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala @@ -4,6 +4,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.{ActorRef, Props} import net.psforever.objects.{Default, Vehicle} import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} +import net.psforever.services.vehicle.VehicleServiceMessage import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -46,7 +47,7 @@ class VehicleSpawnControlSeatDriver(pad: VehicleSpawnPad) extends VehicleSpawnCo vehicle.Actor ! Vehicle.Deconstruct(Some(pad.Definition.VehicleCreationDeconstructTime.seconds)) if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty) { trace("driver to be made seated in vehicle") - pad.Zone.VehicleEvents ! VehicleSpawnPad.StartPlayerSeatedInVehicle(driver.Name, vehicle, pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(driver.Name, VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, pad)) } else { trace("driver lost; vehicle stranded on pad") } @@ -58,7 +59,7 @@ class VehicleSpawnControlSeatDriver(pad: VehicleSpawnPad) extends VehicleSpawnCo if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty && entry.vehicle.PassengerInSeat(entry.driver).contains(0)) { trace(s"driver ${entry.driver.Name} has taken the wheel") - pad.Zone.VehicleEvents ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.driver.Name, entry.vehicle, pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(entry.driver.Name, VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle, pad)) } else { trace("driver lost, but operations can continue") } diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala index bbec75af4..0dabf4807 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala @@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Props import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.Vector3 import scala.concurrent.ExecutionContext.Implicits.global @@ -31,18 +32,18 @@ class VehicleSpawnControlServerVehicleOverride(pad: VehicleSpawnPad) extends Veh val driverFailState = !driver.isAlive || driver.Continent != pad.Continent || !vehicle.PassengerInSeat(driver).contains(0) vehicle.MountedIn = None - pad.Zone.VehicleEvents ! VehicleSpawnPad.DetachFromRails(vehicle, pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.DetachFromRails(vehicle, pad)) if (vehicleFailState || driverFailState) { if (vehicleFailState) { trace(s"vehicle was already destroyed") } else { trace(s"driver is not ready") } - pad.Zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(order.DriverGUID) + pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.RevealPlayer(order.DriverGUID)) driverControl ! order } else { trace(s"telling ${driver.Name} that the server is assuming control of the ${vehicle.Definition.Name}") - pad.Zone.VehicleEvents ! VehicleSpawnPad.ServerVehicleOverrideStart(driver.Name, vehicle, pad) + pad.Zone.VehicleEvents ! VehicleServiceMessage(driver.Name, VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad)) context.system.scheduler.scheduleOnce(4000 milliseconds, driverControl, order) } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala index f7f5fd693..64e4b5ced 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala @@ -5,7 +5,6 @@ import net.psforever.objects.Tool import net.psforever.objects.equipment.EquipmentSlot import net.psforever.objects.serverobject.turret.WeaponTurret import net.psforever.objects.vehicles.MountedWeapons -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} /** @@ -48,7 +47,7 @@ object RepairableWeaponTurret { case (index: Int, Some(tool: Tool)) => events ! VehicleServiceMessage( zoneId, - VehicleAction.EquipmentInSlot(Service.defaultPlayerGUID, tguid, index, tool) + VehicleAction.EquipmentInSlot(tguid, index, tool) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 7e94f947f..a3eff3c11 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -233,7 +233,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val zone = resourceSilo.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, resourceSilo.GUID, 49, 1) + VehicleAction.PlanetsideAttribute(resourceSilo.GUID, 49, 1) ) math.min(resourceSilo.MaxNtuCapacitor - currentlyHas, trigger) } else if (trigger < 0) { @@ -244,7 +244,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val zone = resourceSilo.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, resourceSilo.GUID, 49, 0) + VehicleAction.PlanetsideAttribute(resourceSilo.GUID, 49, 0) ) 0 }) * 0.9f diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index d96f0d4c7..3db74a369 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -26,7 +26,6 @@ import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityCo import net.psforever.objects.vital.{HealFromTerminal, RepairFromTerminal, Vitality} import net.psforever.objects.zones.ZoneAware import net.psforever.packet.game.InventoryStateMessage -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -379,7 +378,7 @@ object ProximityTerminalControl { val zone = target.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 0, target.Health) + VehicleAction.PlanetsideAttribute(target.GUID, 0, target.Health) ) } @@ -466,7 +465,7 @@ object ProximityTerminalControl { slots.foreach { slot => events ! VehicleServiceMessage( channel, - VehicleAction.SendResponse(Service.defaultPlayerGUID, InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) + VehicleAction.SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala index c03709e69..04cab01a4 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala @@ -149,7 +149,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) case player => seat.unmount(player) player.VehicleSeated = None - events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2=false, guid)) + events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) } ) } @@ -277,7 +277,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) case player if test(player.Faction) => seat.unmount(player) player.VehicleSeated = None - events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, guid)) + events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, guid)) } ) } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index 24f1bdea4..75f2f1aee 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -13,7 +13,6 @@ import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.{ChangeFireModeMessage, HackState1} -import net.psforever.services.Service import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideEmpire, PlanetSideGUID} @@ -179,7 +178,7 @@ class FacilityTurretControl(turret: FacilityTurret) seat.unmount(player) player.VehicleSeated = None if (player.HasGUID) { - events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2=false, guid)) + events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) } case None => () } @@ -239,7 +238,7 @@ class FacilityTurretControl(turret: FacilityTurret) weapon.FireModeIndex = 0 events ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse(Service.defaultPlayerGUID, ChangeFireModeMessage(weapon.GUID, 0)) + VehicleAction.SendResponse(ChangeFireModeMessage(weapon.GUID, 0)) ) } } @@ -341,7 +340,7 @@ class FacilityTurretControl(turret: FacilityTurret) case player => seat.unmount(player) player.VehicleSeated = None - events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, seat_num, unk2=true, guid)) + events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, guid)) } } captureTerminalChanges(terminal, super.captureTerminalIsHacked, actionDelays = 3000L) diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index 4d6db7e1b..510fc7416 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -7,8 +7,8 @@ import net.psforever.objects.{Player, Tool, TurretDeployable} import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.services.vehicle.support.TurretUpgrader +import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} import net.psforever.types.PlanetSideGUID object WeaponTurrets { @@ -44,7 +44,7 @@ object WeaponTurrets { * @see `TurretUpgrade` * @see `TurretUpgrader.AddTask` * @see `TurretUpgrader.ClearSpecific` - * @see `VehicleServiceMessage.TurretUpgrade` + * @see `TurretMessage` * @param target the facility turret being upgraded * @param upgrade the upgrade being applied to the turret (usually, it's weapon system) */ @@ -52,8 +52,8 @@ object WeaponTurrets { log.info(s"Manned wall turret weapon being converted to $upgrade") val zone = target.Zone val events = zone.VehicleEvents - events ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), zone)) - events ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, zone, upgrade)) + events ! TurretMessage(TurretUpgrader.ClearSpecific(List(target), zone)) + events ! TurretMessage(TurretUpgrader.AddTask(target, zone, upgrade)) } /** @@ -106,7 +106,8 @@ object WeaponTurrets { player.VehicleSeated = None zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, target.GUID) + player.GUID, + VehicleAction.KickPassenger(4, unk2 = false, target.GUID) ) } } diff --git a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala index 10efab816..1dd9643e9 100644 --- a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala @@ -10,7 +10,6 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} import net.psforever.objects.{NtuContainer, _} import net.psforever.types.DriveState -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.serverobject.transfer.TransferContainer.TransferMaterial @@ -35,7 +34,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vehicle.GUID, 52, 1L) + VehicleAction.PlanetsideAttribute(vehicle.GUID, 52, 1L) ) // panel glow on } @@ -45,7 +44,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vehicle.GUID, 49, 1L) + VehicleAction.PlanetsideAttribute(vehicle.GUID, 49, 1L) ) // orb particle effect on } @@ -54,7 +53,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val display = vehicle.NtuCapacitorScaled.toLong vehicle.Zone.VehicleEvents ! VehicleServiceMessage( vehicle.Actor.toString, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vehicle.GUID, 45, display) + VehicleAction.PlanetsideAttribute(vehicle.GUID, 45, display) ) } } @@ -160,16 +159,16 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { if (transferEvent == TransferBehavior.Event.Charging) { events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vguid, 52, 0L) + VehicleAction.PlanetsideAttribute(vguid, 52, 0L) ) // panel glow off events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vguid, 49, 0L) + VehicleAction.PlanetsideAttribute(vguid, 49, 0L) ) // orb particle effect off } else if (transferEvent == TransferBehavior.Event.Discharging) { events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vguid, 52, 0L) + VehicleAction.PlanetsideAttribute(vguid, 52, 0L) ) // panel glow off } } diff --git a/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala index 24aa6d9c2..96bd4ed86 100644 --- a/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala @@ -118,7 +118,7 @@ trait BfrTransferBehavior case equip: NtuSiphon => vehicle.Zone.VehicleEvents ! VehicleServiceMessage( vehicle.Actor.toString, - VehicleAction.InventoryState2(PlanetSideGUID(0), equip.storageGUID, siphon.GUID, siphon.NtuCapacitor.toInt) + VehicleAction.InventoryState2(equip.storageGUID, siphon.GUID, siphon.NtuCapacitor.toInt) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala index 59f83f942..9883ea11e 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala @@ -207,11 +207,11 @@ object CarrierBehavior { cargo.Velocity = None zone.VehicleEvents ! VehicleServiceMessage( s"${cargo.Actor}", - VehicleAction.SendResponse(PlanetSideGUID(0), PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health)) + VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health)) ) zone.VehicleEvents ! VehicleServiceMessage( s"${cargo.Actor}", - VehicleAction.SendResponse(PlanetSideGUID(0), PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields)) + VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields)) ) CargoMountBehaviorForAll(carrier, cargo, mountPoint) zone.actor ! ZoneActor.RemoveFromBlockMap(cargo) @@ -225,9 +225,8 @@ object CarrierBehavior { val cargoDriverGUID = cargo.Seats(0).occupant.get.GUID zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.SendResponse( - cargoDriverGUID, - CargoMountPointStatusMessage( + cargoDriverGUID, + VehicleAction.SendResponse(CargoMountPointStatusMessage( carrierGUID, PlanetSideGUID(0), PlanetSideGUID(0), @@ -235,8 +234,7 @@ object CarrierBehavior { mountPoint, CargoStatus.Empty, 0 - ) - ) + )) ) false //sending packet to the cargo vehicle's client results in player being lock in own vehicle @@ -327,9 +325,8 @@ object CarrierBehavior { val cargoDriverGUID = cargo.Seats(0).occupant.get.GUID zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.SendResponse( - cargoDriverGUID, - CargoMountPointStatusMessage( + cargoDriverGUID, + VehicleAction.SendResponse(CargoMountPointStatusMessage( carrierGUID, PlanetSideGUID(0), PlanetSideGUID(0), @@ -337,8 +334,7 @@ object CarrierBehavior { mountPoint, CargoStatus.Empty, 0 - ) - ) + )) ) false //sending packet to the cargo vehicle's client results in player being lock in own vehicle @@ -453,11 +449,11 @@ object CarrierBehavior { val cargoActor = cargo.Actor events ! VehicleServiceMessage( s"$cargoActor", - VehicleAction.SendResponse(GUID0, PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health)) + VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health)) ) events ! VehicleServiceMessage( s"$cargoActor", - VehicleAction.SendResponse(GUID0, PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields)) + VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields)) ) zone.actor ! ZoneActor.AddToBlockMap(cargo, carrier.Position) if (carrier.isFlying) { @@ -467,9 +463,9 @@ object CarrierBehavior { val detachCargoMsg = ObjectDetachMessage(carrierGUID, cargoGUID, cargoHoldPosition - Vector3.z(1), rotation) val resetCargoMsg = CargoMountPointStatusMessage(carrierGUID, GUID0, GUID0, cargoGUID, mountPoint, CargoStatus.Empty, 0) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(GUID0, ejectCargoMsg)) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(GUID0, detachCargoMsg)) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(GUID0, resetCargoMsg)) + events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(ejectCargoMsg)) + events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(detachCargoMsg)) + events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(resetCargoMsg)) log.debug(s"HandleVehicleCargoDismount: eject - $ejectCargoMsg, detach - $detachCargoMsg") if (driverOpt.isEmpty) { //TODO cargo should drop like a rock like normal; until then, deconstruct it @@ -482,18 +478,18 @@ object CarrierBehavior { CargoMountPointStatusMessage(carrierGUID, GUID0, cargoGUID, GUID0, mountPoint, CargoStatus.InProgress, 0) val cargoDetachMessage = ObjectDetachMessage(carrierGUID, cargoGUID, cargoHoldPosition + Vector3.z(1f), rotation) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(GUID0, cargoStatusMessage)) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(GUID0, cargoDetachMessage)) + events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(cargoStatusMessage)) + events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(cargoDetachMessage)) driverOpt match { case Some(driver) => events ! VehicleServiceMessage( s"${driver.Name}", - VehicleAction.KickCargo(GUID0, cargo, cargo.Definition.AutoPilotSpeed2, 2500) + VehicleAction.KickCargo(cargo, cargo.Definition.AutoPilotSpeed2, 2500) ) case None => val resetCargoMsg = CargoMountPointStatusMessage(carrierGUID, GUID0, GUID0, cargoGUID, mountPoint, CargoStatus.Empty, 0) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(GUID0, resetCargoMsg)) //lazy + events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(resetCargoMsg)) //lazy //TODO cargo should back out like normal; until then, deconstruct it cargoActor ! Vehicle.Deconstruct() } @@ -609,8 +605,8 @@ object CarrierBehavior { attachMessage: ObjectAttachMessage, mountPointStatusMessage: CargoMountPointStatusMessage ): Unit = { - zone.VehicleEvents ! VehicleServiceMessage(zone.id, VehicleAction.SendResponse(exclude, attachMessage)) - zone.VehicleEvents ! VehicleServiceMessage(zone.id, VehicleAction.SendResponse(exclude, mountPointStatusMessage)) + zone.VehicleEvents ! VehicleServiceMessage(zone.id, exclude, VehicleAction.SendResponse(attachMessage)) + zone.VehicleEvents ! VehicleServiceMessage(zone.id, exclude, VehicleAction.SendResponse(mountPointStatusMessage)) } /** @@ -632,11 +628,11 @@ object CarrierBehavior { val msgs @ (attachMessage, mountPointStatusMessage) = CargoMountMessages(carrier, cargo, mountPoint) zone.VehicleEvents ! VehicleServiceMessage( zoneId, - VehicleAction.SendResponse(Service.defaultPlayerGUID, attachMessage) + VehicleAction.SendResponse(attachMessage) ) zone.VehicleEvents ! VehicleServiceMessage( zoneId, - VehicleAction.SendResponse(Service.defaultPlayerGUID, mountPointStatusMessage) + VehicleAction.SendResponse(mountPointStatusMessage) ) msgs } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala index ccb69f2fe..d3d77a588 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala @@ -2,7 +2,6 @@ package net.psforever.objects.vehicles.control import net.psforever.objects._ -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.DriveState @@ -29,8 +28,8 @@ class AmsControl(vehicle: Vehicle) case None => "" } val events = zone.VehicleEvents - events ! VehicleServiceMessage.AMSDeploymentChange(zone) - events ! VehicleServiceMessage(driverChannel, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vehicle.GUID, 81, 1)) + events ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) + events ! VehicleServiceMessage(driverChannel, VehicleAction.PlanetsideAttribute(vehicle.GUID, 81, 1)) case _ => ; } } @@ -49,8 +48,8 @@ class AmsControl(vehicle: Vehicle) case None => "" } val events = zone.VehicleEvents - events ! VehicleServiceMessage.AMSDeploymentChange(zone) - events ! VehicleServiceMessage(driverChannel, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vehicle.GUID, 81, 0)) + events ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) + events ! VehicleServiceMessage(driverChannel, VehicleAction.PlanetsideAttribute(vehicle.GUID, 81, 0)) case _ => ; } } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala index c08b7a432..c11dfa2d6 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala @@ -54,15 +54,12 @@ class ApcControl(vehicle: Vehicle) //cause the emp events ! VehicleServiceMessage( zone.id, - VehicleAction.SendResponse( - GUID0, - TriggerEffectMessage( + VehicleAction.SendResponse(TriggerEffectMessage( GUID0, s"apc_explosion_emp_${faction.toString.toLowerCase}", None, Some(TriggeredEffectLocation(pos, obj.Orientation)) - ) - ) + )) ) //resolve what targets are affected by the emp Zone.serverSideDamage( diff --git a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala index 4f956351b..b9f62726f 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala @@ -271,7 +271,7 @@ class BfrControl(vehicle: Vehicle) val zone = vehicle.Zone zone.VehicleEvents ! VehicleServiceMessage( s"${zone.id}", - VehicleAction.SendResponse(PlanetSideGUID(0), GenericObjectActionMessage(vehicle.GUID, 45)) + VehicleAction.SendResponse(GenericObjectActionMessage(vehicle.GUID, 45)) ) } @@ -285,7 +285,7 @@ class BfrControl(vehicle: Vehicle) val zone = vehicle.Zone zone.VehicleEvents ! VehicleServiceMessage( s"${zone.id}", - VehicleAction.SendResponse(PlanetSideGUID(0), GenericObjectActionMessage(vehicle.GUID, 44)) + VehicleAction.SendResponse(GenericObjectActionMessage(vehicle.GUID, 44)) ) } @@ -336,7 +336,7 @@ class BfrControl(vehicle: Vehicle) val shields = vehicle.Shields zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, vguid, vehicle.Definition.shieldUiAttribute, shields) + VehicleAction.PlanetsideAttribute(vguid, vehicle.Definition.shieldUiAttribute, shields) ) } @@ -416,7 +416,8 @@ class BfrControl(vehicle: Vehicle) val zone = vehicle.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.GenericObjectAction(doNotSendTo, useThisGuid, action) + doNotSendTo, + VehicleAction.GenericObjectAction(useThisGuid, action) ) case _ => () } @@ -565,15 +566,12 @@ class BfrControl(vehicle: Vehicle) //TODO this is the apc emp effect; is there an ntu siphon emp effect? events ! VehicleServiceMessage( zone.id, - VehicleAction.SendResponse( - GUID0, - TriggerEffectMessage( + VehicleAction.SendResponse(TriggerEffectMessage( GUID0, s"apc_explosion_emp_${faction.toString.toLowerCase}", None, Some(TriggeredEffectLocation(pos, obj.Orientation)) - ) - ) + )) ) //resolve what targets are affected by the emp Zone.serverSideDamage( @@ -590,10 +588,7 @@ class BfrControl(vehicle: Vehicle) //it does not even dispatch the packet before that, making it rare if this precautionary message is seen events ! VehicleServiceMessage( obj.Seats(0).occupant.get.Name, - VehicleAction.SendResponse( - GUID0, - ChatMsg(ChatMessageType.UNK_225, wideContents = false, "", s"@TimeUntilNextUse^${30000 - elapsedWait}", None) - ) + VehicleAction.SendResponse(ChatMsg(ChatMessageType.UNK_225, wideContents = false, "", s"@TimeUntilNextUse^${30000 - elapsedWait}", None)) ) } case _ => () diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala index 2b84932a9..4c54fce31 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala @@ -3,7 +3,6 @@ package net.psforever.objects.vehicles.control import akka.actor.{Actor, Cancellable} import net.psforever.objects._ -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.concurrent.ExecutionContext.Implicits.global @@ -61,7 +60,7 @@ trait VehicleCapacitance { val obj = CapacitanceObject obj.Zone.VehicleEvents ! VehicleServiceMessage( self.toString(), - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 113, obj.Capacitor) + VehicleAction.PlanetsideAttribute(obj.GUID, 113, obj.Capacitor) ) } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index 3f40c8ce0..a32836c17 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -213,7 +213,7 @@ class VehicleControl(vehicle: Vehicle) }) .flatMap { _.getMessage(vehicle) } .foreach { pkt => - events ! VehicleServiceMessage(toChannel, VehicleAction.SendResponse(guid0, pkt)) + events ! VehicleServiceMessage(toChannel, VehicleAction.SendResponse(pkt)) } case FactionAffinity.ConvertFactionAffinity(faction) => @@ -332,7 +332,7 @@ class VehicleControl(vehicle: Vehicle) val zone = vehicle.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.UnloadVehicle(Service.defaultPlayerGUID, vehicle, vehicle.GUID) + VehicleAction.UnloadVehicle(vehicle, vehicle.GUID) ) zone.Transport.tell(Zone.Vehicle.Despawn(vehicle), zone.Transport) //notify target spawner that the vehicle has despawned if this is a VR Shooting Range zone @@ -451,7 +451,7 @@ class VehicleControl(vehicle: Vehicle) zone.actor ! ZoneActor.AddToBlockMap(player, vehicle.Position) } if (player.HasGUID) { - events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2 = true, guid)) + events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = true, guid)) } } } @@ -535,7 +535,7 @@ class VehicleControl(vehicle: Vehicle) val zone = ContainerObject.Zone zone.VehicleEvents ! VehicleServiceMessage( self.toString, - VehicleAction.UnstowEquipment(Service.defaultPlayerGUID, item.GUID) + VehicleAction.UnstowEquipment(item.GUID) ) } @@ -550,22 +550,19 @@ class VehicleControl(vehicle: Vehicle) events ! VehicleServiceMessage( //TODO when a new weapon, the equipment slot ui goes blank, but the weapon functions; remount vehicle to correct it if (obj.VisibleSlots.contains(slot)) zone.id else channel, - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - OCM.detailed(item, ObjectCreateMessageParent(oguid, slot)) - ) + VehicleAction.SendResponse(OCM.detailed(item, ObjectCreateMessageParent(oguid, slot))) ) item match { case box: AmmoBox => events ! VehicleServiceMessage( channel, - VehicleAction.InventoryState2(Service.defaultPlayerGUID, iguid, oguid, box.Capacity) + VehicleAction.InventoryState2(iguid, oguid, box.Capacity) ) case weapon: Tool => weapon.AmmoSlots.map { slot => slot.Box }.foreach { box => events ! VehicleServiceMessage( channel, - VehicleAction.InventoryState2(Service.defaultPlayerGUID, box.GUID, iguid, box.Capacity) + VehicleAction.InventoryState2(box.GUID, iguid, box.Capacity) ) } case _ => () @@ -641,7 +638,7 @@ class VehicleControl(vehicle: Vehicle) vehicle.Shields = vehicle.Shields + amount vehicle.Zone.VehicleEvents ! VehicleServiceMessage( s"${vehicle.Actor}", - VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), vehicle.GUID, vehicle.Definition.shieldUiAttribute, vehicle.Shields) + VehicleAction.PlanetsideAttribute(vehicle.GUID, vehicle.Definition.shieldUiAttribute, vehicle.Shields) ) } } @@ -696,7 +693,8 @@ class VehicleControl(vehicle: Vehicle) log.info(s"$dname changed ${vehicle.Definition.Name}'s access permission $group to $allow") zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.SeatPermissions(dguid, vguid, attribute, value) + dguid, + VehicleAction.SeatPermissions(vguid, attribute, value) ) //kick players who should not be seated in the vehicle due to permission changes if (allow == VehicleLockState.Locked) { //TODO only important permission atm @@ -709,7 +707,8 @@ class VehicleControl(vehicle: Vehicle) tplayer.VehicleSeated = None zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.KickPassenger(tplayer.GUID, 4, unk2 = false, vguid) + tplayer.GUID, + VehicleAction.KickPassenger(4, unk2 = false, vguid) ) } case _ => () // No player seated @@ -761,7 +760,7 @@ class VehicleControl(vehicle: Vehicle) messages.foreach { pkt => events ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse(guid0, pkt) + VehicleAction.SendResponse(pkt) ) } } diff --git a/src/main/scala/net/psforever/objects/zones/MapInfo.scala b/src/main/scala/net/psforever/objects/zones/MapInfo.scala index 31e648aa3..a6edd6b7a 100644 --- a/src/main/scala/net/psforever/objects/zones/MapInfo.scala +++ b/src/main/scala/net/psforever/objects/zones/MapInfo.scala @@ -700,10 +700,7 @@ object MapEnvironment { case v: Vehicle => v.Zone.VehicleEvents ! VehicleServiceMessage( v.Actor.toString(), - VehicleAction.SendResponse( - Service.defaultPlayerGUID, - OffshoreVehicleMessage(v.Seats(0).occupant.get.GUID, v.GUID, msg) - ) + VehicleAction.SendResponse(OffshoreVehicleMessage(v.Seats(0).occupant.get.GUID, v.GUID, msg)) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala index 29dacff8d..be767c726 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala @@ -9,7 +9,6 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vital.InGameHistory import net.psforever.objects.{Default, GlobalDefinitions, Vehicle} import net.psforever.packet.game.ChatMsg -import net.psforever.services.Service import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, Vector3} @@ -206,7 +205,7 @@ object ZoneVehicleActor { msgOpt.foreach { msg => zone.VehicleEvents ! VehicleServiceMessage( vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse(""), - VehicleAction.SendResponse(Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_227, msg)) + VehicleAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) ) } msgOpt.isDefined diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index 7b8fb1e6b..dad3e9070 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -27,7 +27,7 @@ class AvatarService(zone: Zone) busName = "Avatar", eventSupportServices = List(CorpseRemovalSupport, ItemRemoverSupport) ) { - protected def compose(msg: GenericMessageEnvelope): AvatarServiceResponse = { + protected def composeResponseEnvelope(msg: GenericMessageEnvelope): AvatarServiceResponse = { AvatarServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) } } diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 0ec9aa690..913914b2c 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -22,18 +22,18 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) - protected val eventBus: GenericEventBus[OUT] = setupEventBus() + protected val eventBus: GenericEventBus[OUT] = new GenericEventBus[OUT] def BusName: String = busName - def commonJoinBehavior: Receive = { + private def commonJoinBehavior: Receive = { case Service.Join(channel) => val path = formatChannelOnBusName(channel) val who = sender() eventBus.subscribe(who, path) } - def commonLeaveBehavior: Receive = { + private def commonLeaveBehavior: Receive = { case Service.Leave(None) => eventBus.unsubscribe(sender()) @@ -54,25 +54,11 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri log.warn(s"Unhandled message $msg from ${sender()}") } - private def handleMessage(msg: GenericMessageEnvelope): Unit = { - eventBus.publish(compose(msg)) + protected def handleMessage(msg: GenericMessageEnvelope): Unit = { + eventBus.publish(composeResponseEnvelope(msg)) } - protected def setupEventBus(): GenericEventBus[OUT] = { - new GenericEventBus[OUT] - } + protected def composeResponseEnvelope(@unused msg: GenericMessageEnvelope): OUT - protected def compose(@unused msg: GenericMessageEnvelope): OUT - - def formatChannelOnBusName(channel: String): String = GenericEventService.BusOnChannelFormat(busName)(channel) -} - -object GenericEventService { - final def BusOnChannelFormat(busName: String)(channel: String): String = { - if (channel.trim.isEmpty) { - s"/$busName" - } else { - s"/$channel/$busName" - } - } + protected def formatChannelOnBusName(channel: String): String = s"/$channel/$busName" } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index c40368389..508086d4b 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -3,7 +3,6 @@ package net.psforever.services.base import akka.actor.{ActorContext, ActorRef} import net.psforever.services.Service -import net.psforever.services.base.bus.{GenericEventBus, GenericEventBusResponseToSupport, GenericEventBusWithSupport} import net.psforever.types.PlanetSideGUID import scala.annotation.unused @@ -49,20 +48,15 @@ abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope] } } - override protected def setupEventBus(): GenericEventBus[OUT] = { - new GenericEventBus[OUT] with GenericEventBusWithSupport[OUT] { - override def publish(event: OUT): Unit = publishingWithSupport(event) - - override def forwardToExternalSupport(msg: GenericEventBusResponseToSupport): Unit = { - msg match { - case supportMessage: GenericMessageToSupportEnvelope => forwardToExternal(supportMessage) - case _ => () - } - } - - private def forwardToExternal(msg: GenericMessageToSupportEnvelope): Unit = { + override protected def handleMessage(event: GenericMessageEnvelope): Unit = { + event match { + case msg: GenericMessageToSupportEnvelopeOnly => forwardToSupport(msg) - } + case msg: GenericMessageToSupportEnvelope => + forwardToSupport(msg) + eventBus.publish(composeResponseEnvelope(event)) + case _ => + eventBus.publish(composeResponseEnvelope(event)) } } } diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala index faaa81490..a025726d1 100644 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala @@ -31,6 +31,10 @@ class GenericEventBus[A <: GenericEventBusResponse] subscriber ! event } + override def publish(event: Event): Unit = { + truePublish(event) + } + def truePublish(event: Event): Unit = { super[SubchannelClassification].publish(event) } diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala index 34381ccb1..4b0ccd890 100644 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala @@ -16,7 +16,7 @@ trait GenericEventBusResponseToSupportOnly trait GenericEventBusWithSupport[T <: GenericEventBusResponse] { bus: GenericEventBus[T] => - def publishingWithSupport(event: T): Unit = { + def handleMessageWithSupport(event: T): Unit = { event match { case msg: GenericEventBusResponseToSupportOnly => forwardToExternalSupport(msg) diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index 65d15b2cd..b38b68776 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -5,7 +5,15 @@ import net.psforever.services.base.{GenericEventService, GenericMessageEnvelope} class GalaxyService extends GenericEventService[GalaxyServiceResponse](busName = "Galaxy") { - protected def compose(msg: GenericMessageEnvelope): GalaxyServiceResponse = { + protected def composeResponseEnvelope(msg: GenericMessageEnvelope): GalaxyServiceResponse = { GalaxyServiceResponse(formatChannelOnBusName(msg.channel), msg.msg.response()) } + + override protected def formatChannelOnBusName(channel: String): String = { + if (channel.trim.isEmpty) { + s"/$BusName" + } else { + s"/$channel/$BusName" + } + } } diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index e7ee464a8..37f112cc5 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -44,7 +44,7 @@ class LocalService(zone: Zone) busName = "Local", eventSupportServices = List(DoorCloserSupport, HackClearSupport, HackCaptureSupport, CaptureFlagSupport(zone)) ) { - protected def compose(msg: GenericMessageEnvelope): LocalServiceResponse = { + protected def composeResponseEnvelope(msg: GenericMessageEnvelope): LocalServiceResponse = { LocalServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) } } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala new file mode 100644 index 000000000..dcc3535be --- /dev/null +++ b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala @@ -0,0 +1,196 @@ +// Copyright (c) 2017-2026 PSForever +package net.psforever.services.vehicle + +import net.psforever.objects.{PlanetSideGameObject, Vehicle} +import net.psforever.objects.equipment.Equipment +import net.psforever.objects.inventory.InventoryItem +import net.psforever.objects.serverobject.tube.SpawnTube +import net.psforever.objects.zones.Zone +import net.psforever.packet.PlanetSideGamePacket +import net.psforever.packet.game.ObjectCreateMessage +import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent} +import net.psforever.services.base.{EventMessage, EventResponse, SelfResponseMessage} +import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} + +object VehicleAction { + trait Action extends EventMessage { + def response(): EventResponse = null + } + + final case class ChangeAmmo( + weapon_guid: PlanetSideGUID, + weapon_slot: Int, + old_ammo_guid: PlanetSideGUID, + ammo_id: Int, + ammo_guid: PlanetSideGUID, + ammo_data: ConstructorData + ) extends SelfResponseMessage + + final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class ChildObjectState(object_guid: PlanetSideGUID, pitch: Float, yaw: Float) extends SelfResponseMessage + + final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class DeployRequest( + object_guid: PlanetSideGUID, + state: DriveState.Value, + unk1: Int, + unk2: Boolean, + pos: Vector3 + ) extends SelfResponseMessage + + final case class DismountVehicle(bailType: BailType.Value, unk2: Boolean) extends SelfResponseMessage + + final case class EquipmentCreatedInSlot(pkt: ObjectCreateMessage) extends EventResponse + + final case class EquipmentInSlot(target_guid: PlanetSideGUID, slot: Int, equipment: Equipment) extends EventMessage { + override def response(): EventResponse = { + val definition = equipment.Definition + val pkt = ObjectCreateMessage( + definition.ObjectId, + equipment.GUID, + ObjectCreateMessageParent(target_guid, slot), + definition.Packet.ConstructorData(equipment).get + ) + ObjectCreateMessageParent(target_guid, slot) + VehicleAction.EquipmentCreatedInSlot(pkt) + } + } + + final case class FrameVehicleState( + vehicle_guid: PlanetSideGUID, + unk1: Int, + pos: Vector3, + orient: Vector3, + vel: Option[Vector3], + unk2: Boolean, + unk3: Int, + unk4: Int, + is_crouched: Boolean, + unk6: Boolean, + unk7: Boolean, + unk8: Int, + unk9: Long, + unkA: Long + ) extends SelfResponseMessage + + final case class GenericObjectAction(guid: PlanetSideGUID, action: Int) extends SelfResponseMessage + + final case class HitHint(source_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class InventoryState( + obj: PlanetSideGameObject, + parent_guid: PlanetSideGUID, + start: Int, + con_data: ConstructorData + ) extends SelfResponseMessage + + final case class InventoryState2(obj_guid: PlanetSideGUID, parent_guid: PlanetSideGUID, value: Int) extends SelfResponseMessage + + final case class KickPassenger(unk1: Int, unk2: Boolean, vehicle_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class LoadVehicle( + vehicle: Vehicle, + vtype: Int, + vguid: PlanetSideGUID, + vdata: ConstructorData + ) extends SelfResponseMessage + + final case class MountVehicle(object_guid: PlanetSideGUID, seat: Int) extends SelfResponseMessage + + final case class ObjectDelete(guid: PlanetSideGUID) extends SelfResponseMessage + + final case class Ownership(vehicle_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class PlanetsideAttribute( + target_guid: PlanetSideGUID, + attribute_type: Int, + attribute_value: Long + ) extends SelfResponseMessage + + final case class Reload(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class RevealPlayer(player_guid: PlanetSideGUID) extends EventResponse + + final case class SeatPermissions(vehicle_guid: PlanetSideGUID, seat_group: Int, permission: Long) extends SelfResponseMessage + + final case class StowCreatedEquipment( + vehicle_guid: PlanetSideGUID, + slot: Int, + itype: Int, + iguid: PlanetSideGUID, + idata: ConstructorData + ) extends EventResponse + + final case class StowEquipment(vehicle_guid: PlanetSideGUID, slot: Int, item: Equipment) extends SelfResponseMessage + + final case class UnloadVehicle(vehicle: Vehicle, vehicle_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class UnstowEquipment(item_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + + final case class VehicleState( + vehicle_guid: PlanetSideGUID, + unk1: Int, + pos: Vector3, + ang: Vector3, + vel: Option[Vector3], + unk2: Option[Int], + unk3: Int, + unk4: Int, + wheel_direction: Int, + unk5: Boolean, + unk6: Boolean + ) extends SelfResponseMessage + + final case class SendResponse(msg: PlanetSideGamePacket) extends SelfResponseMessage + + final case class UpdateAmsSpawnList(list: List[SpawnTube]) extends EventResponse + + final case class UpdateAmsSpawnPoint(zone: Zone) extends EventMessage { + override def response(): EventResponse = { + VehicleAction.UpdateAmsSpawnList(AmsSpawnPoints(zone)) + } + } + + final case class AMSDeploymentChange(zone: Zone) extends EventMessage { + override def response(): EventResponse = { + VehicleAction.UpdateAmsSpawnList(AmsSpawnPoints(zone)) + } + } + + final case class TransferPassengerChannel( + temp_channel: String, + new_channel: String, + vehicle: Vehicle, + vehicle_to_delete: PlanetSideGUID + ) extends SelfResponseMessage + + final case class KickCargo(cargo: Vehicle, speed: Int, delay: Long) extends SelfResponseMessage + + final case class ChangeLoadout( + target_guid: PlanetSideGUID, + removed_weapons: List[(Equipment, PlanetSideGUID)], + new_weapons: List[InventoryItem], + old_inventory: List[(Equipment, PlanetSideGUID)], + new_inventory: List[InventoryItem] + ) extends SelfResponseMessage + + import net.psforever.objects.serverobject.tube.SpawnTube + private def AmsSpawnPoints(zone: Zone): List[SpawnTube] = { + import net.psforever.objects.vehicles.UtilityType + import net.psforever.objects.GlobalDefinitions + zone.Vehicles + .filter(veh => + veh.Health > 0 && veh.Definition == GlobalDefinitions.ams && veh.DeploymentState == DriveState.Deployed + ) + .flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube)) + .map(util => util().asInstanceOf[SpawnTube]) + } +} diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 0116f278a..47af9487a 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -1,443 +1,25 @@ // Copyright (c) 2017 PSForever package net.psforever.services.vehicle -import akka.actor.{Actor, ActorRef, Props} -import net.psforever.objects.serverobject.pad.VehicleSpawnPad +import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.zones.Zone -import net.psforever.packet.game.ObjectCreateMessage -import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent +import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericMessageEnvelope} import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.types.DriveState -import net.psforever.services.Service -import net.psforever.services.base.bus.GenericEventBus -class VehicleService(zone: Zone) extends Actor { - private val turretUpgrade: ActorRef = context.actorOf(Props[TurretUpgrader](), s"${zone.id}-turret-upgrade-agent") - private[this] val log = org.log4s.getLogger - - val VehicleEvents = new GenericEventBus[VehicleServiceResponse] - - def receive: Receive = { - case Service.Join(channel) => - val path = s"/$channel/Vehicle" - VehicleEvents.subscribe(sender(), path) - - case Service.Leave(None) => - VehicleEvents.unsubscribe(sender()) - - case Service.Leave(Some(channel)) => - val path = s"/$channel/Vehicle" - VehicleEvents.unsubscribe(sender(), path) - - case Service.LeaveAll() => - VehicleEvents.unsubscribe(sender()) - - case VehicleServiceMessage(forChannel, action) => - action match { - case VehicleAction.ChangeAmmo(player_guid, weapon_guid, weapon_slot, old_ammo_guid, ammo_id, ammo_guid, ammo_data) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.ChangeAmmo(weapon_guid, weapon_slot, old_ammo_guid, ammo_id, ammo_guid, ammo_data) - ) - ) - case VehicleAction.ChangeFireState_Start(player_guid, weapon_guid) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.ChangeFireState_Start(weapon_guid) - ) - ) - case VehicleAction.ChangeFireState_Stop(player_guid, weapon_guid) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.ChangeFireState_Stop(weapon_guid)) - ) - case VehicleAction.ChildObjectState(player_guid, object_guid, pitch, yaw) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.ChildObjectState(object_guid, pitch, yaw) - ) - ) - case VehicleAction.DeployRequest(player_guid, object_guid, state, unk1, unk2, pos) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.DeployRequest(object_guid, state, unk1, unk2, pos) - ) - ) - case VehicleAction.DismountVehicle(player_guid, bailType, unk2) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.DismountVehicle(bailType, unk2) - ) - ) - case VehicleAction.EquipmentInSlot(player_guid, target_guid, slot, equipment) => - val definition = equipment.Definition - val pkt = ObjectCreateMessage( - definition.ObjectId, - equipment.GUID, - ObjectCreateMessageParent(target_guid, slot), - definition.Packet.ConstructorData(equipment).get - ) - ObjectCreateMessageParent(target_guid, slot) - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.EquipmentInSlot(pkt)) - ) - case VehicleAction.FrameVehicleState( - player_guid, - vehicle_guid, - unk1, - pos, - orient, - vel, - unk2, - unk3, - unk4, - is_crouched, - unk6, - unk7, - unk8, - unk9, - unkA - ) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.FrameVehicleState( - vehicle_guid, - unk1, - pos, - orient, - vel, - unk2, - unk3, - unk4, - is_crouched, - unk6, - unk7, - unk8, - unk9, - unkA - ) - ) - ) - case VehicleAction.GenericObjectAction(player_guid, guid, code) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.GenericObjectAction(guid, code) - ) - ) - case VehicleAction.InventoryState(player_guid, obj, parent_guid, start, con_data) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.InventoryState(obj, parent_guid, start, con_data) - ) - ) - case VehicleAction.InventoryState2(player_guid, obj_guid, parent_guid, value) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.InventoryState2(obj_guid, parent_guid, value) - ) - ) - case VehicleAction.KickPassenger(player_guid, seat_num, kickedByDriver, vehicle_guid) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.KickPassenger(seat_num, kickedByDriver, vehicle_guid) - ) - ) - case VehicleAction.ObjectDelete(guid) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.ObjectDelete(guid) - ) - ) - case VehicleAction.LoadVehicle(player_guid, vehicle, vtype, vguid, vdata) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.LoadVehicle(vehicle, vtype, vguid, vdata) - ) - ) - case VehicleAction.MountVehicle(player_guid, vehicle_guid, seat) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.MountVehicle(vehicle_guid, seat) - ) - ) - case VehicleAction.LoseOwnership(owner_guid, vehicle_guid) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", Service.defaultPlayerGUID, VehicleResponse.LoseOwnership(owner_guid, vehicle_guid)) - ) - case VehicleAction.Ownership(player_guid, vehicle_guid) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.Ownership(vehicle_guid)) - ) - case VehicleAction.PlanetsideAttribute(exclude_guid, target_guid, attribute_type, attribute_value) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - exclude_guid, - VehicleResponse.PlanetsideAttribute(target_guid, attribute_type, attribute_value) - ) - ) - - case VehicleAction.Reload(player_guid, weapon_guid) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.Reload(weapon_guid)) - ) - case VehicleAction.SeatPermissions(player_guid, vehicle_guid, seat_group, permission) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.SeatPermissions(vehicle_guid, seat_group, permission) - ) - ) - case VehicleAction.StowEquipment(player_guid, vehicle_guid, slot, item) => - val definition = item.Definition - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.StowEquipment( - vehicle_guid, - slot, - definition.ObjectId, - item.GUID, - definition.Packet.DetailedConstructorData(item).get - ) - ) - ) - case VehicleAction.WeaponDryFire(player_guid, weapon_guid) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.WeaponDryFire(weapon_guid)) - ) - case VehicleAction.UnloadVehicle(player_guid, vehicle, vehicle_guid) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.UnloadVehicle(vehicle, vehicle_guid) - ) - ) - case VehicleAction.UnstowEquipment(player_guid, item_guid) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.UnstowEquipment(item_guid)) - ) - case VehicleAction.VehicleState( - player_guid, - vehicle_guid, - unk1, - pos, - ang, - vel, - unk2, - unk3, - unk4, - wheel_direction, - unk5, - unk6 - ) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.VehicleState( - vehicle_guid, - unk1, - pos, - ang, - vel, - unk2, - unk3, - unk4, - wheel_direction, - unk5, - unk6 - ) - ) - ) - case VehicleAction.SendResponse(player_guid, msg) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.SendResponse(msg)) - ) - - //unlike other messages, just return to sender, don't publish - case VehicleAction.UpdateAmsSpawnPoint(zone: Zone) => - sender() ! VehicleServiceResponse( - s"/$forChannel/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.UpdateAmsSpawnPoint(AmsSpawnPoints(zone)) - ) - - case VehicleAction.TransferPassengerChannel( - player_guid, - old_channel, - temp_channel, - vehicle, - vehicle_to_delete - ) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - player_guid, - VehicleResponse.TransferPassengerChannel(old_channel, temp_channel, vehicle, vehicle_to_delete) - ) - ) - case VehicleAction.KickCargo(player_guid, cargo, speed, delay) => - VehicleEvents.publish( - VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.KickCargo(cargo, speed, delay)) - ) - - case VehicleAction.ChangeLoadout(target_guid, removed_weapons, new_weapons, old_inventory, new_inventory) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$forChannel/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.ChangeLoadout(target_guid, removed_weapons, new_weapons, old_inventory, new_inventory) - ) - ) - case _ => ; - } - - //message to TurretUpgrader - case VehicleServiceMessage.TurretUpgrade(msg) => - turretUpgrade forward msg - - //from VehicleSpawnControl, etc. - case VehicleSpawnPad.ConcealPlayer(player_guid) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/${zone.id}/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.ConcealPlayer(player_guid) - ) - ) - - case VehicleSpawnPad.AttachToRails(vehicle, pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/${zone.id}/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.AttachToRails(vehicle.GUID, pad.GUID) - ) - ) - - case VehicleSpawnPad.StartPlayerSeatedInVehicle(driver_name, vehicle, pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$driver_name/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.StartPlayerSeatedInVehicle(vehicle, pad) - ) - ) - - case VehicleSpawnPad.PlayerSeatedInVehicle(driver_name, vehicle, pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$driver_name/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.PlayerSeatedInVehicle(vehicle, pad) - ) - ) - - case VehicleSpawnPad.ServerVehicleOverrideStart(driver_name, vehicle, pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$driver_name/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.ServerVehicleOverrideStart(vehicle, pad) - ) - ) - - case VehicleSpawnPad.ServerVehicleOverrideEnd(driver_name, vehicle, pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$driver_name/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.ServerVehicleOverrideEnd(vehicle, pad) - ) - ) - - case VehicleSpawnPad.DetachFromRails(vehicle, pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/${zone.id}/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.DetachFromRails(vehicle.GUID, pad.GUID, pad.Position, pad.Orientation.z) - ) - ) - case VehicleSpawnPad.ResetSpawnPad(pad) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/${zone.id}/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.ResetSpawnPad(pad.GUID) - ) - ) - - case VehicleSpawnPad.RevealPlayer(player_guid) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/${zone.id}/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.RevealPlayer(player_guid) - ) - ) - - case VehicleSpawnPad.PeriodicReminder(to, reason, data) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/$to/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.PeriodicReminder(reason, data) - ) - ) - - //correspondence from WorldSessionActor - case VehicleServiceMessage.AMSDeploymentChange(_) => - VehicleEvents.publish( - VehicleServiceResponse( - s"/${zone.id}/Vehicle", - Service.defaultPlayerGUID, - VehicleResponse.UpdateAmsSpawnPoint(AmsSpawnPoints(zone)) - ) - ) - - case msg => - log.warn(s"Unhandled message $msg from ${sender()}") - } - - import net.psforever.objects.serverobject.tube.SpawnTube - def AmsSpawnPoints(zone: Zone): List[SpawnTube] = { - import net.psforever.objects.vehicles.UtilityType - import net.psforever.objects.GlobalDefinitions - zone.Vehicles - .filter(veh => - veh.Health > 0 && veh.Definition == GlobalDefinitions.ams && veh.DeploymentState == DriveState.Deployed - ) - .flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube)) - .map(util => util().asInstanceOf[SpawnTube]) +case object TurretUpgradeSupport + extends EventServiceSupport { + def label: String = "turretUpgrader" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[TurretUpgrader](), name = "TurretUpgrader") + } +} + +class VehicleService(zone: Zone) + extends GenericEventServiceWithSupport[VehicleServiceResponse]( + busName = "Vehicle", + eventSupportServices = List(TurretUpgradeSupport) + ) { + protected def composeResponseEnvelope(msg: GenericMessageEnvelope): VehicleServiceResponse = { + VehicleServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) } } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala index 54f6d4e96..1eb35fd26 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala @@ -1,157 +1,19 @@ // Copyright (c) 2017 PSForever package net.psforever.services.vehicle -import net.psforever.objects.{PlanetSideGameObject, Vehicle} -import net.psforever.objects.equipment.Equipment -import net.psforever.objects.inventory.InventoryItem -import net.psforever.objects.zones.Zone -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.objectcreate.ConstructorData -import net.psforever.services.base.{EventMessage, EventResponse} -import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} +import net.psforever.services.Service +import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelopeOnly} +import net.psforever.types.PlanetSideGUID -final case class VehicleServiceMessage(forChannel: String, actionMessage: VehicleAction.Action) +final case class VehicleServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) + extends GenericMessageEnvelope + +final case class TurretMessage(supportMessage: Any) + extends GenericMessageToSupportEnvelopeOnly { + def supportLabel: String = "turretUpgrader" +} object VehicleServiceMessage { - final case class GiveActorControl(vehicle: Vehicle, actorName: String) - final case class RevokeActorControl(vehicle: Vehicle) - - final case class TurretUpgrade(msg: Any) - - final case class AMSDeploymentChange(zone: Zone) -} - -object VehicleAction { - trait Action extends EventMessage { - def response(): EventResponse = null - } - - final case class ChangeAmmo( - player_guid: PlanetSideGUID, - weapon_guid: PlanetSideGUID, - weapon_slot: Int, - old_ammo_guid: PlanetSideGUID, - ammo_id: Int, - ammo_guid: PlanetSideGUID, - ammo_data: ConstructorData - ) extends Action - final case class ChangeFireState_Start(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class ChangeFireState_Stop(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class ChildObjectState(player_guid: PlanetSideGUID, object_guid: PlanetSideGUID, pitch: Float, yaw: Float) - extends Action - final case class DeployRequest( - player_guid: PlanetSideGUID, - object_guid: PlanetSideGUID, - state: DriveState.Value, - unk1: Int, - unk2: Boolean, - pos: Vector3 - ) extends Action - final case class DismountVehicle(player_guid: PlanetSideGUID, bailType: BailType.Value, unk2: Boolean) extends Action - final case class EquipmentInSlot( - player_guid: PlanetSideGUID, - target_guid: PlanetSideGUID, - slot: Int, - equipment: Equipment - ) extends Action - final case class FrameVehicleState( - player_guid: PlanetSideGUID, - vehicle_guid: PlanetSideGUID, - unk1: Int, - pos: Vector3, - orient: Vector3, - vel: Option[Vector3], - unk2: Boolean, - unk3: Int, - unk4: Int, - is_crouched: Boolean, - unk6: Boolean, - unk7: Boolean, - unk8: Int, - unk9: Long, - unkA: Long - ) extends Action - final case class GenericObjectAction(player_guid: PlanetSideGUID, guid: PlanetSideGUID, action: Int) extends Action - final case class InventoryState( - player_guid: PlanetSideGUID, - obj: PlanetSideGameObject, - parent_guid: PlanetSideGUID, - start: Int, - con_data: ConstructorData - ) extends Action - final case class InventoryState2( - player_guid: PlanetSideGUID, - obj_guid: PlanetSideGUID, - parent_guid: PlanetSideGUID, - value: Int - ) extends Action - final case class KickPassenger(player_guid: PlanetSideGUID, unk1: Int, unk2: Boolean, vehicle_guid: PlanetSideGUID) - extends Action - final case class LoadVehicle( - player_guid: PlanetSideGUID, - vehicle: Vehicle, - vtype: Int, - vguid: PlanetSideGUID, - vdata: ConstructorData - ) extends Action - final case class MountVehicle(player_guid: PlanetSideGUID, object_guid: PlanetSideGUID, seat: Int) extends Action - final case class ObjectDelete(guid: PlanetSideGUID) extends Action - final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends Action - final case class Ownership(player_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends Action - final case class PlanetsideAttribute( - player_guid: PlanetSideGUID, - target_guid: PlanetSideGUID, - attribute_type: Int, - attribute_value: Long - ) extends Action - final case class Reload(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class SeatPermissions( - player_guid: PlanetSideGUID, - vehicle_guid: PlanetSideGUID, - seat_group: Int, - permission: Long - ) extends Action - final case class StowEquipment(player_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID, slot: Int, item: Equipment) - extends Action - final case class UnloadVehicle( - player_guid: PlanetSideGUID, - vehicle: Vehicle, - vehicle_guid: PlanetSideGUID - ) extends Action - final case class UnstowEquipment(player_guid: PlanetSideGUID, item_guid: PlanetSideGUID) extends Action - final case class VehicleState( - player_guid: PlanetSideGUID, - vehicle_guid: PlanetSideGUID, - unk1: Int, - pos: Vector3, - ang: Vector3, - vel: Option[Vector3], - unk2: Option[Int], - unk3: Int, - unk4: Int, - wheel_direction: Int, - unk5: Boolean, - unk6: Boolean - ) extends Action - final case class SendResponse(player_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends Action - final case class WeaponDryFire(player_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID) extends Action - final case class UpdateAmsSpawnPoint(zone: Zone) extends Action - - final case class TransferPassengerChannel( - player_guid: PlanetSideGUID, - temp_channel: String, - new_channel: String, - vehicle: Vehicle, - vehicle_to_delete: PlanetSideGUID - ) extends Action - - final case class KickCargo(player_guid: PlanetSideGUID, cargo: Vehicle, speed: Int, delay: Long) extends Action - - final case class ChangeLoadout( - target_guid: PlanetSideGUID, - removed_weapons: List[(Equipment, PlanetSideGUID)], - new_weapons: List[InventoryItem], - old_inventory: List[(Equipment, PlanetSideGUID)], - new_inventory: List[InventoryItem] - ) extends Action + def apply(channel: String, actionMessage: EventMessage): VehicleServiceMessage = + VehicleServiceMessage(channel, Service.defaultPlayerGUID, actionMessage) } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala index dd052809f..f28b5652e 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala @@ -1,141 +1,11 @@ // Copyright (c) 2017 PSForever package net.psforever.services.vehicle -import net.psforever.objects.equipment.Equipment -import net.psforever.objects.inventory.InventoryItem -import net.psforever.objects.serverobject.pad.VehicleSpawnPad -import net.psforever.objects.serverobject.pad.VehicleSpawnPad.Reminders -import net.psforever.objects.{PlanetSideGameObject, Vehicle} -import net.psforever.objects.serverobject.tube.SpawnTube -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.objectcreate.ConstructorData -import net.psforever.packet.game.ObjectCreateMessage -import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.bus.GenericEventBusResponse +import net.psforever.types.PlanetSideGUID +import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} final case class VehicleServiceResponse( channel: String, filter: PlanetSideGUID, - reply: VehicleResponse.Response - ) extends GenericEventBusResponse - -object VehicleResponse { - trait Response extends EventResponse - - final case class ChangeAmmo( - weapon_guid: PlanetSideGUID, - weapon_slot: Int, - old_ammo_guid: PlanetSideGUID, - ammo_id: Int, - ammo_guid: PlanetSideGUID, - ammo_data: ConstructorData - ) extends Response - final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends Response - final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends Response - final case class ChildObjectState(object_guid: PlanetSideGUID, pitch: Float, yaw: Float) extends Response - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends Response - final case class DeployRequest( - object_guid: PlanetSideGUID, - state: DriveState.Value, - unk1: Int, - unk2: Boolean, - pos: Vector3 - ) extends Response - final case class DismountVehicle(bailType: BailType.Value, unk2: Boolean) extends Response - final case class EquipmentInSlot(pkt: ObjectCreateMessage) extends Response - final case class FrameVehicleState( - vehicle_guid: PlanetSideGUID, - unk1: Int, - pos: Vector3, - orient: Vector3, - vel: Option[Vector3], - unk2: Boolean, - unk3: Int, - unk4: Int, - is_crouched: Boolean, - unk6: Boolean, - unk7: Boolean, - unk8: Int, - unk9: Long, - unkA: Long - ) extends Response - final case class GenericObjectAction(guid: PlanetSideGUID, action: Int) extends Response - final case class HitHint(source_guid: PlanetSideGUID) extends Response - final case class InventoryState( - obj: PlanetSideGameObject, - parent_guid: PlanetSideGUID, - start: Int, - con_data: ConstructorData - ) extends Response - final case class InventoryState2(obj_guid: PlanetSideGUID, parent_guid: PlanetSideGUID, value: Int) extends Response - final case class KickPassenger(seat_num: Int, kickedByDriver: Boolean, vehicle_guid: PlanetSideGUID) extends Response - final case class LoadVehicle(vehicle: Vehicle, vtype: Int, vguid: PlanetSideGUID, vdata: ConstructorData) - extends Response - final case class MountVehicle(object_guid: PlanetSideGUID, seat: Int) extends Response - final case class ObjectDelete(guid: PlanetSideGUID) extends Response - final case class Ownership(vehicle_guid: PlanetSideGUID) extends Response - final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) - extends Response - final case class PlanetsideAttribute(vehicle_guid: PlanetSideGUID, attribute_type: Int, attribute_value: Long) - extends Response - final case class Reload(weapon_guid: PlanetSideGUID) extends Response - final case class RevealPlayer(player_guid: PlanetSideGUID) extends Response - final case class SeatPermissions(vehicle_guid: PlanetSideGUID, seat_group: Int, permission: Long) extends Response - final case class StowEquipment( - vehicle_guid: PlanetSideGUID, - slot: Int, - itype: Int, - iguid: PlanetSideGUID, - idata: ConstructorData - ) extends Response - final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends Response - final case class UnloadVehicle(vehicle: Vehicle, vehicle_guid: PlanetSideGUID) extends Response - final case class UnstowEquipment(item_guid: PlanetSideGUID) extends Response - final case class VehicleState( - vehicle_guid: PlanetSideGUID, - unk1: Int, - pos: Vector3, - ang: Vector3, - vel: Option[Vector3], - unk2: Option[Int], - unk3: Int, - unk4: Int, - wheel_direction: Int, - unk5: Boolean, - unk6: Boolean - ) extends Response - final case class SendResponse(msg: PlanetSideGamePacket) extends Response - final case class UpdateAmsSpawnPoint(list: List[SpawnTube]) extends Response - - final case class AttachToRails(vehicle_guid: PlanetSideGUID, rails_guid: PlanetSideGUID) extends Response - final case class StartPlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends Response - final case class PlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends Response - final case class DetachFromRails( - vehicle_guid: PlanetSideGUID, - rails_guid: PlanetSideGUID, - rails_pos: Vector3, - rails_rot: Float - ) extends Response - final case class ServerVehicleOverrideStart(vehicle: Vehicle, pad: VehicleSpawnPad) extends Response - final case class ServerVehicleOverrideEnd(vehicle: Vehicle, pad: VehicleSpawnPad) extends Response - final case class ResetSpawnPad(pad_guid: PlanetSideGUID) extends Response - final case class PeriodicReminder(reason: Reminders.Value, data: Option[Any] = None) extends Response - - final case class TransferPassengerChannel( - old_channel: String, - temp_channel: String, - vehicle: Vehicle, - vehicle_to_delete: PlanetSideGUID - ) extends Response - - final case class KickCargo(cargo: Vehicle, speed: Int, delay: Long) extends Response - - final case class ChangeLoadout( - target_guid: PlanetSideGUID, - removed_weapons: List[(Equipment, PlanetSideGUID)], - new_weapons: List[InventoryItem], - old_inventory: List[(Equipment, PlanetSideGUID)], - new_inventory: List[InventoryItem] - ) extends Response -} + reply: EventResponse + ) extends GenericResponseEnvelope diff --git a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala index 96939203a..ac08220e4 100644 --- a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala +++ b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala @@ -161,7 +161,8 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { if (tplayer.HasGUID) { context.parent ! VehicleServiceMessage( zoneId, - VehicleAction.KickPassenger(tplayer.GUID, 4, unk2=false, turretGUID) + tplayer.GUID, + VehicleAction.KickPassenger(4, unk2=false, turretGUID) ) } }) @@ -235,7 +236,7 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { case (index, Some(tool: Tool)) => context.parent ! VehicleServiceMessage( zone.id, - VehicleAction.EquipmentInSlot(PlanetSideGUID(0), targetGUID, index, tool) + VehicleAction.EquipmentInSlot(targetGUID, index, tool) ) } } diff --git a/src/test/scala/objects/DamageableTest.scala b/src/test/scala/objects/DamageableTest.scala index bd2381fb9..aae4b98e6 100644 --- a/src/test/scala/objects/DamageableTest.scala +++ b/src/test/scala/objects/DamageableTest.scala @@ -24,9 +24,8 @@ import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types._ import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.support.SupportActor -import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.support.SupportActor +import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} import org.specs2.mutable.Specification import scala.concurrent.duration._ @@ -831,7 +830,7 @@ class DamageableWeaponTurretDamageTest extends ActorTest { val msg4 = avatarProbe.receiveOne(500 milliseconds) assert( msg12 match { - case VehicleServiceMessage("test", VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(2), 0, _)) => true + case VehicleServiceMessage("test", _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -933,6 +932,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest { msg12.head match { case VehicleServiceMessage( "test", + _, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(2), 27, 1) ) => true @@ -943,6 +943,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest { msg12(1) match { case VehicleServiceMessage( "test", + _, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(5), 27, 1) ) => true @@ -1085,17 +1086,17 @@ class DamageableWeaponTurretDestructionTest extends ActorTest { assert(false, s"DamageableWeaponTurretDestructionTest-3: player not dead - $msg3") } msg12_4(2) match { - case AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(0), PlanetSideGUID(5), _)) => ; + case AvatarServiceMessage("test", _, AvatarAction.ObjectDelete(PlanetSideGUID(5), _)) => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-4: ${msg12_4(2)}") } msg56.head match { - case VehicleServiceMessage.TurretUpgrade(SupportActor.ClearSpecific(List(t), _)) if turret eq t => ; + case TurretMessage(SupportActor.ClearSpecific(List(t), _)) if turret eq t => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-5: ${msg56.head}") } msg56(1) match { - case VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(t, _, TurretUpgrade.None, _)) if t eq turret => () + case TurretMessage(TurretUpgrader.AddTask(t, _, TurretUpgrade.None, _)) if t eq turret => () case _ => assert(false, s"DamageableWeaponTurretDestructionTest-6: ${msg56(1)}") } assert(turret.Health <= turret.Definition.DamageDestroysAt) @@ -1180,13 +1181,13 @@ class DamageableVehicleDamageTest extends ActorTest { val msg4 = avatarProbe.receiveOne(200 milliseconds) assert( msg12.head match { - case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 68, _)) => true + case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 68, _)) => true case _ => false } ) assert( msg12(1) match { - case VehicleServiceMessage("test", VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 0, _)) => true + case VehicleServiceMessage("test", _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 0, _)) => true case _ => false } ) @@ -1316,11 +1317,11 @@ class DamageableVehicleDamageMountedTest extends FreedContextActorTest { val msg3 = activityProbe.receiveOne(500 milliseconds) val msg45 = avatarProbe.receiveN(2,500 milliseconds) msg12.head match { - case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 68, _)) => ; + case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 68, _)) => ; case _ => assert(false) } msg12(1) match { - case VehicleServiceMessage("test", VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 0, _)) => ; + case VehicleServiceMessage("test", _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 0, _)) => ; case _ => assert(false) } msg3 match { @@ -1453,6 +1454,7 @@ class DamageableVehicleJammeringMountedTest extends FreedContextActorTest { msg12 match { case VehicleServiceMessage( "test", + _, VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(4), 27, 1) ) => true @@ -1754,6 +1756,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // msg_vehicle.exists({ // case VehicleServiceMessage( // "test", +// _, // VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(4), 27, 0) // ) => // true @@ -1764,6 +1767,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // msg_vehicle.exists({ // case VehicleServiceMessage( // "test", +// _, // VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(1), 68, 0) // ) => // true diff --git a/src/test/scala/objects/DeploymentTest.scala b/src/test/scala/objects/DeploymentTest.scala index 0b86da3f9..d723f0720 100644 --- a/src/test/scala/objects/DeploymentTest.scala +++ b/src/test/scala/objects/DeploymentTest.scala @@ -74,7 +74,8 @@ class DeploymentBehavior2Test extends ActorTest { reply2.head match { case VehicleServiceMessage( "test", - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) + _, + VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -86,6 +87,7 @@ class DeploymentBehavior2Test extends ActorTest { reply2(1) match { case VehicleServiceMessage( "test", + _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") @@ -102,6 +104,7 @@ class DeploymentBehavior2Test extends ActorTest { reply4.head match { case VehicleServiceMessage( "test", + _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") @@ -114,6 +117,7 @@ class DeploymentBehavior2Test extends ActorTest { reply4(1) match { case VehicleServiceMessage( "test", + _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") @@ -141,8 +145,9 @@ class DeploymentBehavior3Test extends ActorTest { } reply2.head match { case VehicleServiceMessage( - "test", - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) + "test", + _, + VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -153,8 +158,9 @@ class DeploymentBehavior3Test extends ActorTest { } reply2(1) match { case VehicleServiceMessage( - "test", - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) + "test", + _, + VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -169,8 +175,9 @@ class DeploymentBehavior3Test extends ActorTest { } reply4.head match { case VehicleServiceMessage( - "test", - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) + "test", + _, + VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -181,8 +188,9 @@ class DeploymentBehavior3Test extends ActorTest { } reply4(1) match { case VehicleServiceMessage( - "test", - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) + "test", + _, + VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } diff --git a/src/test/scala/objects/FacilityTurretTest.scala b/src/test/scala/objects/FacilityTurretTest.scala index 4fcc4f218..51a52c702 100644 --- a/src/test/scala/objects/FacilityTurretTest.scala +++ b/src/test/scala/objects/FacilityTurretTest.scala @@ -298,7 +298,7 @@ class FacilityTurretControlRestorationTest extends ActorTest { ) assert( msg4 match { - case VehicleServiceMessage("test", VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) + case VehicleServiceMessage("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true case _ => false diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index 3d2c6fc38..fad1035e3 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -313,7 +313,7 @@ class RepairableTurretWeapon extends ActorTest { ) assert( msg4 match { - case VehicleServiceMessage("test", VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) + case VehicleServiceMessage("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true case _ => false diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index 9b9b7ca79..119fab0b3 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -72,7 +72,7 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest { val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds) vehicle_msg.head match { - case VehicleServiceMessage("test", VehicleAction.KickPassenger(PlanetSideGUID(2), 4, true, PlanetSideGUID(1))) => ; + case VehicleServiceMessage("test", _, VehicleAction.KickPassenger(PlanetSideGUID(2), 4, true, PlanetSideGUID(1))) => ; case _ => assert(false, s"VehicleControlPrepareForDeletionPassengerTest: ${vehicle_msg.head}") } @@ -136,32 +136,32 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest { // val vehicle_msg = vehicleProbe.receiveN(6, 1 minute) // //dismounting as cargo messages // vehicle_msg.head match { -// case VehicleServiceMessage("test", VehicleAction.KickPassenger(PlanetSideGUID(3), 4, true, PlanetSideGUID(1))) => ; +// case VehicleServiceMessage("test", _, VehicleAction.KickPassenger(PlanetSideGUID(3), 4, true, PlanetSideGUID(1))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-1: ${vehicle_msg.head}") // } // vehicle_msg(1) match { -// case VehicleServiceMessage(_, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => ; +// case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-2: ${vehicle_msg(1)}") // } // vehicle_msg(2) match { -// case VehicleServiceMessage(_, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => ; +// case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-3: ${vehicle_msg(2)}") // } // vehicle_msg(3) match { -// case VehicleServiceMessage("test", VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; +// case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-4: ${vehicle_msg(3)}") // } // vehicle_msg(4) match { -// case VehicleServiceMessage("test", VehicleAction.SendResponse(_, ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => ; +// case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-5: ${vehicle_msg(4)}") // } // vehicle_msg(5) match { -// case VehicleServiceMessage("test", VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => ; +// case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-6: ${vehicle_msg(5)}") // } @@ -224,7 +224,7 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor val vehicleMsgs = eventsProbe.receiveN(6, 10.seconds) val cargoMsgs = cargoProbe.receiveN(1, 1.seconds) vehicleMsgs.head match { - case VehicleServiceMessage("test", VehicleAction.KickPassenger(PlanetSideGUID(4), 4, true, PlanetSideGUID(2))) => () + case VehicleServiceMessage("test", _, VehicleAction.KickPassenger(PlanetSideGUID(4), 4, true, PlanetSideGUID(2))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-1: ${vehicleMsgs.head}") } @@ -232,27 +232,27 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor assert(lodestar.Seats(0).occupant.isEmpty) //cargo dismounting messages vehicleMsgs(1) match { - case VehicleServiceMessage(_, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => () + case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-2: ${vehicleMsgs(1)}") } vehicleMsgs(2) match { - case VehicleServiceMessage(_, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => () + case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-3: ${vehicleMsgs(2)}") } vehicleMsgs(3) match { - case VehicleServiceMessage("test", VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; + case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-4: ${vehicleMsgs(3)}") } vehicleMsgs(4) match { - case VehicleServiceMessage("test", VehicleAction.SendResponse(_, ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => () + case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-5: ${vehicleMsgs(4)}") } vehicleMsgs(5) match { - case VehicleServiceMessage("test", VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => () + case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-6: ${vehicleMsgs(5)}") } @@ -476,7 +476,7 @@ class VehicleControlShieldsChargingTest extends ActorTest { vehicle.Actor ! CommonMessages.ChargeShields(15, None) val msg = probe.receiveOne(500 milliseconds) assert(msg match { - case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true + case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true case _ => false }) assert(vehicle.Shields == 15) @@ -544,7 +544,7 @@ class VehicleControlShieldsNotChargingTooEarlyTest extends ActorTest { val msg = probe.receiveOne(200 milliseconds) //assert(msg.isInstanceOf[Vehicle.UpdateShieldsCharge]) assert(msg match { - case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true + case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true case _ => false }) assert(vehicle.Shields == 15) @@ -1004,7 +1004,7 @@ class VehicleControlInteractWithLavaTest extends ActorTest { msg_burn.foreach { msg => assert( msg match { - case VehicleServiceMessage("test-zone", VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(2), 0, _)) => true + case VehicleServiceMessage("test-zone", _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -1102,7 +1102,7 @@ class ApcControlCanChargeCapacitor extends FreedContextActorTest { do { val msg = vehicleProbe.receiveOne(3.seconds) msg match { - case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(1), 113, capacitance)) => + case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(1), 113, capacitance)) => assert(capacitance > 0) case _ => assert(false) @@ -1176,17 +1176,17 @@ class ApcControlCanEmp extends FreedContextActorTest { apc.Actor ! SpecialEmp.Burst() val vehicleMsgs = vehicleProbe.receiveN(2, 500.milliseconds) vehicleMsgs.head match { - case VehicleServiceMessage(_, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(1), 113, 0)) => ; + case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(1), 113, 0)) => ; case _ => assert(false) } vehicleMsgs(1) match { case VehicleServiceMessage( - "test-zone", - VehicleAction.SendResponse( - _, - TriggerEffectMessage(_, "apc_explosion_emp_vs", None, Some(TriggeredEffectLocation(Vector3.Zero, Vector3.Zero))) - ) - ) => ; + "test-zone", + _, + VehicleAction.SendResponse(_, + TriggerEffectMessage(_, "apc_explosion_emp_vs", None, Some(TriggeredEffectLocation(Vector3.Zero, Vector3.Zero))) + ) + ) => ; case _ => assert(false) } assert(apc.Capacitor == 0) diff --git a/src/test/scala/service/VehicleServiceTest.scala b/src/test/scala/service/VehicleServiceTest.scala index 691780b58..deeb05930 100644 --- a/src/test/scala/service/VehicleServiceTest.scala +++ b/src/test/scala/service/VehicleServiceTest.scala @@ -79,9 +79,9 @@ class OwnershipTest extends ActorTest { "pass Awareness" in { val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") service ! Service.Join("test") - service ! VehicleServiceMessage("test", VehicleAction.Ownership(PlanetSideGUID(10), PlanetSideGUID(11))) + service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11))) expectMsg( - VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.Ownership(PlanetSideGUID(11))) + VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11))) ) } } @@ -96,13 +96,14 @@ class ChildObjectStateTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.ChildObjectState(PlanetSideGUID(10), PlanetSideGUID(11), 1.2f, 3.4f) + PlanetSideGUID(10), + VehicleAction.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f) + VehicleAction.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f) ) ) } @@ -118,20 +119,14 @@ class DeployRequestTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.DeployRequest( - PlanetSideGUID(10), - PlanetSideGUID(11), - DriveState.Mobile, - 0, - false, - Vector3(1.2f, 3.4f, 5.6f) - ) + PlanetSideGUID(10), + VehicleAction.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f)) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f)) + VehicleAction.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f)) ) ) } @@ -145,12 +140,12 @@ class DismountVehicleTest extends ActorTest { "pass DismountVehicle" in { val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") service ! Service.Join("test") - service ! VehicleServiceMessage("test", VehicleAction.DismountVehicle(PlanetSideGUID(10), BailType.Normal, false)) + service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.DismountVehicle(BailType.Normal, false)) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.DismountVehicle(BailType.Normal, false) + VehicleAction.DismountVehicle(BailType.Normal, false) ) ) } @@ -169,13 +164,14 @@ class InventoryStateTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.InventoryState(PlanetSideGUID(10), tool, PlanetSideGUID(11), 0, cdata) + PlanetSideGUID(10), + VehicleAction.InventoryState(tool, PlanetSideGUID(11), 0, cdata) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.InventoryState(tool, PlanetSideGUID(11), 0, cdata) + VehicleAction.InventoryState(tool, PlanetSideGUID(11), 0, cdata) ) ) } @@ -194,13 +190,14 @@ class InventoryState2Test extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.InventoryState2(PlanetSideGUID(10), PlanetSideGUID(11), PlanetSideGUID(12), 13) + PlanetSideGUID(10), + VehicleAction.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13) + VehicleAction.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13) ) ) } @@ -216,13 +213,14 @@ class KickPassengerTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.KickPassenger(PlanetSideGUID(10), 0, false, PlanetSideGUID(11)) + PlanetSideGUID(10), + VehicleAction.KickPassenger(0, false, PlanetSideGUID(11)) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.KickPassenger(0, false, PlanetSideGUID(11)) + VehicleAction.KickPassenger(0, false, PlanetSideGUID(11)) ) ) } @@ -241,13 +239,14 @@ class LoadVehicleTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.LoadVehicle(PlanetSideGUID(10), vehicle, 12, PlanetSideGUID(11), cdata) + PlanetSideGUID(10), + VehicleAction.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata) + VehicleAction.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata) ) ) } @@ -261,9 +260,9 @@ class MountVehicleTest extends ActorTest { "pass MountVehicle" in { val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") service ! Service.Join("test") - service ! VehicleServiceMessage("test", VehicleAction.MountVehicle(PlanetSideGUID(10), PlanetSideGUID(11), 0)) + service ! VehicleServiceMessage("test", VehicleAction.MountVehicle(PlanetSideGUID(11), 0)) expectMsg( - VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.MountVehicle(PlanetSideGUID(11), 0)) + VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.MountVehicle(PlanetSideGUID(11), 0)) ) } } @@ -278,13 +277,13 @@ class SeatPermissionsTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.SeatPermissions(PlanetSideGUID(10), PlanetSideGUID(11), 0, 12L) + VehicleAction.SeatPermissions(PlanetSideGUID(11), 0, 12L) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.SeatPermissions(PlanetSideGUID(11), 0, 12L) + VehicleAction.SeatPermissions(PlanetSideGUID(11), 0, 12L) ) ) } @@ -305,13 +304,14 @@ class StowEquipmentTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.StowEquipment(PlanetSideGUID(10), PlanetSideGUID(11), 0, tool) + PlanetSideGUID(10), + VehicleAction.StowEquipment(PlanetSideGUID(11), 0, tool) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.StowEquipment(PlanetSideGUID(11), 0, toolDef.ObjectId, tool.GUID, cdata) + VehicleAction.StowEquipment(PlanetSideGUID(11), 0, toolDef.ObjectId, tool.GUID, cdata) ) ) } @@ -325,9 +325,9 @@ class UnstowEquipmentTest extends ActorTest { "pass UnstowEquipment" in { val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") service ! Service.Join("test") - service ! VehicleServiceMessage("test", VehicleAction.UnstowEquipment(PlanetSideGUID(10), PlanetSideGUID(11))) + service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11))) expectMsg( - VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.UnstowEquipment(PlanetSideGUID(11))) + VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11))) ) } } @@ -342,26 +342,13 @@ class VehicleStateTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.VehicleState( - PlanetSideGUID(10), - PlanetSideGUID(11), - 0, - Vector3(1.2f, 3.4f, 5.6f), - Vector3(7.8f, 9.1f, 2.3f), - Some(Vector3(4.5f, 6.7f, 8.9f)), - Option(1), - 2, - 3, - 4, - false, - true - ) + VehicleAction.VehicleState(PlanetSideGUID(11), 0, Vector3(1.2f, 3.4f, 5.6f), Vector3(7.8f, 9.1f, 2.3f), Some(Vector3(4.5f, 6.7f, 8.9f)), Option(1), 2, 3, 4, false, true) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.VehicleState( + VehicleAction.VehicleState( PlanetSideGUID(11), 0, Vector3(1.2f, 3.4f, 5.6f), @@ -391,19 +378,14 @@ class TransferPassengerChannelTest extends ActorTest { service ! Service.Join("test") service ! VehicleServiceMessage( "test", - VehicleAction.TransferPassengerChannel( - PlanetSideGUID(10), - "old_channel", - "new_channel", - fury, - PlanetSideGUID(11) - ) + PlanetSideGUID(10), + VehicleAction.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11)) ) expectMsg( VehicleServiceResponse( "/test/Vehicle", PlanetSideGUID(10), - VehicleResponse.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11)) + VehicleAction.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11)) ) ) } @@ -418,7 +400,7 @@ class TransferPassengerChannelTest extends ActorTest { // val service = system.actorOf(Props[VehicleService], "v-service") // service ! Service.Join("test") // service ! VehicleServiceMessage("test", VehicleAction.TransferPassenger(PlanetSideGUID(10), "temp_channel", fury, PlanetSideGUID(11))) -// expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.TransferPassenger("temp_channel", fury, PlanetSideGUID(11)))) +// expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.TransferPassenger("temp_channel", fury, PlanetSideGUID(11)))) // } // } //} From d6925131a493e8b3b989063f9d899814d273a274 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 3 Feb 2026 22:20:35 -0500 Subject: [PATCH 08/32] implemented proper generic event messages that do not have an [System]Action prefix, e.g., Foo not AvatarAction.Foo; made SendResponse accommodate multiple packets at once --- .../actor/service/AvatarServiceTest.scala | 31 ++--- .../actors/session/AvatarActor.scala | 20 +-- .../session/csr/AvatarHandlerLogic.scala | 37 +++--- .../actors/session/csr/ChatLogic.scala | 7 +- .../CustomerServiceRepresentativeMode.scala | 9 +- .../actors/session/csr/GeneralLogic.scala | 17 +-- .../session/csr/MountHandlerLogic.scala | 13 +- ...eAsCustomerServiceRepresentativeMode.scala | 3 +- .../actors/session/csr/VehicleLogic.scala | 4 +- .../session/normal/AvatarHandlerLogic.scala | 35 +++--- .../session/normal/GalaxyHandlerLogic.scala | 5 +- .../actors/session/normal/GeneralLogic.scala | 17 +-- .../session/normal/LocalHandlerLogic.scala | 29 +++-- .../session/normal/MountHandlerLogic.scala | 21 ++-- .../session/normal/VehicleHandlerLogic.scala | 23 ++-- .../spectator/AvatarHandlerLogic.scala | 45 +++---- .../session/spectator/GeneralLogic.scala | 8 +- .../session/spectator/MountHandlerLogic.scala | 19 ++- .../session/spectator/SpectatorMode.scala | 5 +- .../spectator/VehicleHandlerLogic.scala | 21 ++-- .../session/support/GeneralOperations.scala | 42 ++++++- .../support/SessionAvatarHandlers.scala | 5 +- .../support/SessionMountHandlers.scala | 5 +- .../support/SessionSquadHandlers.scala | 7 +- .../WeaponAndProjectileOperations.scala | 37 +++--- .../session/support/ZoningOperations.scala | 17 +-- .../psforever/actors/zone/BuildingActor.scala | 13 +- .../net/psforever/actors/zone/ZoneActor.scala | 11 +- .../zone/building/CavernFacilityLogic.scala | 4 +- .../actors/zone/building/FacilityLogic.scala | 4 +- .../zone/building/MajorFacilityLogic.scala | 13 +- .../actors/zone/building/WarpGateLogic.scala | 2 +- .../net/psforever/login/WorldSession.scala | 9 +- .../psforever/objects/BoomerDeployable.scala | 5 +- .../objects/FieldTurretDeployable.scala | 5 +- .../scala/net/psforever/objects/Players.scala | 11 +- .../psforever/objects/SensorDeployable.scala | 8 +- .../objects/ShieldGeneratorDeployable.scala | 9 +- .../scala/net/psforever/objects/Tools.scala | 5 +- .../net/psforever/objects/Vehicles.scala | 17 +-- .../objects/avatar/CorpseControl.scala | 11 +- .../objects/avatar/PlayerControl.scala | 39 +++--- .../avatar/interaction/WithEntrance.scala | 9 +- .../avatar/interaction/WithGantry.scala | 7 +- .../objects/ce/DeployableBehavior.scala | 5 +- .../psforever/objects/ce/TelepadLike.scala | 31 ++--- .../equipment/ArmorSiphonBehavior.scala | 9 +- .../objects/equipment/JammingUnit.scala | 9 +- .../locker/LockerContainerControl.scala | 11 +- .../damage/DamageableEntity.scala | 2 +- .../damage/DamageableMountable.scala | 15 +-- .../damage/DamageableVehicle.scala | 15 +-- .../damage/DamageableWeaponTurret.scala | 11 +- .../objects/serverobject/doors/Door.scala | 27 ---- .../serverobject/doors/DoorControl.scala | 32 ++--- .../generator/GeneratorControl.scala | 5 +- .../hackable/GenericHackables.scala | 31 ++--- .../objects/serverobject/locks/IFFLocks.scala | 4 +- .../serverobject/pad/VehicleSpawnPad.scala | 24 ++-- .../repair/RepairableEntity.scala | 7 +- .../resourcesilo/ResourceSiloControl.scala | 11 +- .../shuttle/OrbitalShuttlePadControl.scala | 21 ++-- .../FacilityHackParticipation.scala | 7 +- .../MajorFacilityHackParticipation.scala | 5 +- .../terminals/ProximityTerminalControl.scala | 15 +-- .../terminals/TerminalControl.scala | 6 +- .../implant/ImplantTerminalMechControl.scala | 9 +- .../turret/FacilityTurretControl.scala | 3 +- .../serverobject/turret/WeaponTurrets.scala | 9 +- .../turret/auto/AutomatedTurretBehavior.scala | 11 +- .../vehicles/AntTransferBehavior.scala | 15 +-- .../objects/vehicles/CarrierBehavior.scala | 57 ++++----- .../objects/vehicles/control/AmsControl.scala | 5 +- .../objects/vehicles/control/ApcControl.scala | 5 +- .../objects/vehicles/control/BfrControl.scala | 15 +-- .../vehicles/control/VehicleCapacitance.scala | 5 +- .../vehicles/control/VehicleControl.scala | 28 ++--- .../interaction/WithEntranceInVehicle.scala | 5 +- .../net/psforever/objects/zones/MapInfo.scala | 7 +- .../objects/zones/ZoneDeployableActor.scala | 5 +- .../objects/zones/ZoneProjectileActor.scala | 5 +- .../objects/zones/ZoneVehicleActor.scala | 5 +- .../psforever/packet/game/HackMessage.scala | 12 -- .../services/CavernRotationService.scala | 5 +- .../account/AccountPersistenceService.scala | 3 +- .../services/avatar/AvatarAction.scala | 114 ++++++----------- .../avatar/support/CorpseRemovalActor.scala | 5 +- .../avatar/support/DroppedItemRemover.scala | 5 +- .../services/base/EventExchange.scala | 2 +- .../base/bus/GenericEventBusWithSupport.scala | 32 ----- .../services/base/messages/ChangeAmmo.scala | 15 +++ .../base/messages/ChangeFireState_Start.scala | 7 ++ .../base/messages/ChangeFireState_Stop.scala | 7 ++ .../base/messages/GenericObjectAction.scala | 7 ++ .../base/messages/HintsAtAttacker.scala | 8 ++ .../services/base/messages/ObjectDelete.scala | 7 ++ .../base/messages/PlanetsideAttribute.scala | 11 ++ .../services/base/messages/ReloadTool.scala | 7 ++ .../services/base/messages/SendResponse.scala | 11 ++ .../services/base/messages/SetEmpire.scala | 7 ++ .../base/messages/WeaponDryFire.scala | 7 ++ .../services/galaxy/GalaxyAction.scala | 21 ++-- .../services/local/LocalAction.scala | 116 +++++------------- .../services/local/LocalServiceMessage.scala | 26 ++-- .../local/support/CaptureFlagManager.scala | 9 +- .../local/support/HackCaptureActor.scala | 7 +- .../local/support/HackClearActor.scala | 9 +- .../properties/PropertyOverrideManager.scala | 52 ++++---- .../services/vehicle/VehicleAction.scala | 79 ++++-------- src/test/scala/objects/DamageableTest.scala | 42 ++++--- .../objects/DeployableBehaviorTest.scala | 12 +- src/test/scala/objects/DoorTest.scala | 6 +- .../scala/objects/FacilityTurretTest.scala | 8 +- src/test/scala/objects/GeneratorTest.scala | 14 ++- .../scala/objects/PlayerControlTest.scala | 34 +++-- src/test/scala/objects/RepairableTest.scala | 29 +++-- src/test/scala/objects/ResourceSiloTest.scala | 11 +- .../scala/objects/TelepadRouterTest.scala | 24 ++-- .../scala/objects/VehicleControlTest.scala | 35 +++--- src/test/scala/service/LocalServiceTest.scala | 11 +- 120 files changed, 985 insertions(+), 988 deletions(-) delete mode 100644 src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/ReloadTool.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/SendResponse.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/SetEmpire.scala create mode 100644 src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala index 891e2c61a..8b437a173 100644 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ b/server/src/test/scala/actor/service/AvatarServiceTest.scala @@ -16,6 +16,7 @@ import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstrea import net.psforever.types._ import net.psforever.services.{RemoverActor, Service, ServiceManager} import net.psforever.services.avatar._ +import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ObjectDelete, PlanetsideAttribute, WeaponDryFire} class AvatarService1Test extends ActorTest { "AvatarService" should { @@ -198,14 +199,14 @@ class ObjectDeleteTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11))) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11), 0)) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11), 0)) ) - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11), 55)) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11), 55)) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectDelete(PlanetSideGUID(11), 55)) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11), 55)) ) } } @@ -243,8 +244,8 @@ class PlanetsideAttributeTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.PlanetsideAttribute(5, 1200L)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.PlanetsideAttribute(5, 1200L))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L)) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))) } } } @@ -324,7 +325,7 @@ class PickupItemTest extends ActorTest { val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") service ! PickupItemMessage("test", AvatarAction.PickupItem(tool), Zone.Nowhere) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectDelete(tool.GUID, 0))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0))) } } @@ -352,7 +353,7 @@ class ChangeAmmoTest extends ActorTest { service ! AvatarServiceMessage( "test", PlanetSideGUID(10), - AvatarAction.ChangeAmmo( + ChangeAmmo( PlanetSideGUID(40), 0, PlanetSideGUID(40), @@ -365,7 +366,7 @@ class ChangeAmmoTest extends ActorTest { AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarAction.ChangeAmmo( + ChangeAmmo( PlanetSideGUID(40), 0, PlanetSideGUID(40), @@ -402,12 +403,12 @@ class ChangeFireStateStartTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireState_Start(PlanetSideGUID(40))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Start(PlanetSideGUID(40))) expectMsg( AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarAction.ChangeFireState_Start(PlanetSideGUID(40)) + ChangeFireState_Start(PlanetSideGUID(40)) ) ) } @@ -420,12 +421,12 @@ class ChangeFireStateStopTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireState_Stop(PlanetSideGUID(40))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Stop(PlanetSideGUID(40))) expectMsg( AvatarServiceResponse( "/test/Avatar", PlanetSideGUID(10), - AvatarAction.ChangeFireState_Stop(PlanetSideGUID(40)) + ChangeFireState_Stop(PlanetSideGUID(40)) ) ) } @@ -438,9 +439,9 @@ class WeaponDryFireTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.WeaponDryFire(PlanetSideGUID(40))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), WeaponDryFire(PlanetSideGUID(40))) expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.WeaponDryFire(PlanetSideGUID(40))) + AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), WeaponDryFire(PlanetSideGUID(40))) ) } } diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index e0d4d99cb..749255c23 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -49,6 +49,7 @@ import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingAc import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars} import net.psforever.packet.game.{Friend => GameFriend, _} import net.psforever.persistence +import net.psforever.services.base.messages.{SendResponse, PlanetsideAttribute} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.types.{ CharacterSex, @@ -587,7 +588,7 @@ object AvatarActor { session.zone.AvatarEvents ! AvatarServiceMessage( player.Faction.toString, player.GUID, - AvatarAction.PlanetsideAttribute(53, state) + PlanetsideAttribute(player.GUID, 53, state) ) } @@ -1386,7 +1387,7 @@ class AvatarActor( session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.faction.toString, session.get.player.GUID, - AvatarAction.PlanetsideAttribute(53, if (lfs) 1 else 0) + PlanetsideAttribute(session.get.player.GUID, 53, if (lfs) 1 else 0) ) Behaviors.same @@ -1797,7 +1798,7 @@ class AvatarActor( val zone = player.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse(DisplayedAwardMessage(player.GUID, ribbon, bar)) + SendResponse(DisplayedAwardMessage(player.GUID, ribbon, bar)) ) Behaviors.same @@ -3163,7 +3164,7 @@ class AvatarActor( val player = _session.player zone.AvatarEvents ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))) + SendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))) ) } @@ -3650,7 +3651,7 @@ class AvatarActor( // What is normally a 60s timer that is set to 120s on the server will still visually update as if 60s session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.name, - AvatarAction.SendResponse(ActionProgressMessage(slot + 6, actionProgress)) + SendResponse(ActionProgressMessage(slot + 6, actionProgress)) ) implant.copy(initialized = false, active = false, timer = futureDelay) } else { @@ -3699,7 +3700,7 @@ class AvatarActor( //can not formally stop the initialization time on the character information window; set it to 100 to make it look blank session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.name, - AvatarAction.SendResponse(ActionProgressMessage(slot + 6, 100)) + SendResponse(ActionProgressMessage(slot + 6, 100)) ) implant.copy(initialized = false, active = false, timer = 0L) } @@ -3770,7 +3771,7 @@ class AvatarActor( session.get.zone.AvatarEvents ! AvatarServiceMessage( session.get.zone.id, session.get.player.GUID, - AvatarAction.PlanetsideAttribute(28, implant.definition.implantType.value * 2) + PlanetsideAttribute(session.get.player.GUID, 28, implant.definition.implantType.value * 2) ) sendAvatarImplantMessageToSelf(session.get.player.GUID, ImplantAction.Activation, slot, value = 0) implant.copy(active = false) @@ -3862,7 +3863,8 @@ class AvatarActor( zone.AvatarEvents ! AvatarServiceMessage( zone.id, sess.player.GUID, - AvatarAction.PlanetsideAttribute( + PlanetsideAttribute( + sess.player.GUID, 28, implant.definition.implantType.value * 2 + 1 ) @@ -3886,7 +3888,7 @@ class AvatarActor( val actionProgress = calculateImplantTimerStats(implant, AvatarActor.initializationTime(implant))._3 session.get.zone.AvatarEvents ! AvatarServiceMessage( avatar.name, - AvatarAction.SendResponse(ActionProgressMessage(slot + 6, actionProgress)) + SendResponse(ActionProgressMessage(slot + 6, actionProgress)) ) implantOpt case (None, _) => 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 f0a03989b..84dadf753 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -11,9 +11,10 @@ import net.psforever.objects.inventory.Container import net.psforever.objects.serverobject.containable.ContainableBehavior import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vital.RevivingActivity -import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction} +import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, HitHint, ImplantAction} import net.psforever.services.avatar.{AvatarAction, AvatarServiceResponse} import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import net.psforever.types.ImplantType // @@ -26,7 +27,7 @@ import net.psforever.objects.inventory.InventoryItem import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.packet.game.{ArmorChangedMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} +import net.psforever.packet.game.{ArmorChangedMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -219,23 +220,23 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - case AvatarAction.ChangeFireState_Start(weaponGuid) + case ChangeFireState_Start(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - case AvatarAction.ChangeFireState_Start(weaponGuid) + case ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case AvatarAction.ChangeFireState_Stop(weaponGuid) + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - case AvatarAction.ChangeFireState_Stop(weaponGuid) + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) @@ -245,8 +246,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) + case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => + sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) @@ -254,10 +255,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarAction.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => + case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - case AvatarAction.HitHint(sourceGuid) if player.isAlive => + case HintsAtAttacker(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, guid)) sessionLogic.zoning.CancelZoningProcess() @@ -432,14 +433,14 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.general.kitToBeUsed = None sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarAction.SendResponse(msg) => - sendResponse(msg) + case SendResponse(msgs) => + msgs.foreach(sendResponse) case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => sendResponse(msg) /* common messages (maybe once every respawn) */ - case AvatarAction.Reload(itemGuid) + case ReloadTool(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) @@ -498,12 +499,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } /* uncommon messages (utility, or once in a while) */ - case AvatarAction.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 && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarAction.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 => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) @@ -520,11 +521,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.ObjectDelete(itemGuid, unk) if isNotSameTarget => + case ObjectDelete(itemGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) /* rare messages */ - case AvatarAction.SetEmpire(objectGuid, faction) if isNotSameTarget => + case SetEmpire(objectGuid, faction) if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) case AvatarAction.DropSpecialItem() => @@ -573,7 +574,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) ) - case AvatarAction.WeaponDryFire(weaponGuid) + case WeaponDryFire(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index 322a1fb3c..313cb6b62 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -17,6 +17,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{ObjectDelete, SetEmpire} import net.psforever.services.chat.{ChatChannel, DefaultChannel, SpectatorChannel, SquadChannel} import net.psforever.types.ChatMessageType.{CMT_TOGGLESPECTATORMODE, CMT_TOGGLE_GM} import net.psforever.types.{ChatMessageType, PlanetSideEmpire} @@ -337,7 +338,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext .filter(_.spectator) .foreach { spectator => val guid = spectator.GUID - events ! AvatarServiceMessage(channel, guid, AvatarAction.ObjectDelete(guid)) + events ! AvatarServiceMessage(channel, guid, ObjectDelete(guid)) } true } @@ -392,7 +393,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext o.Faction = foundFaction continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.SetEmpire(o.GUID, foundFaction) + SetEmpire(o.GUID, foundFaction) ) true case o: Building => @@ -405,7 +406,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext o.Faction = foundFaction continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.SetEmpire(o.GUID, foundFaction) + SetEmpire(o.GUID, foundFaction) ) true } diff --git a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala index 419174a9c..bedddfaf2 100644 --- a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala @@ -11,6 +11,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage, PlanetsideAttributeMessage} import net.psforever.packet.game.objectcreate.RibbonBars import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.chat.{CustomerServiceChannel, SpectatorChannel} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{ChatMessageType, MeritCommendation, PlanetSideGUID} @@ -181,14 +182,14 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { player.Health = maxHealthOfPlayer.toInt player.LogActivity(player.ClearHistory().head) data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOfPlayer)) - data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, guid, AvatarAction.PlanetsideAttribute(0, maxHealthOfPlayer)) + data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, PlanetsideAttribute(guid, 0, maxHealthOfPlayer)) } //below half armor, full armor val maxArmor = player.MaxArmor.toLong if (player.Armor < maxArmor) { player.Armor = maxArmor.toInt data.sendResponse(PlanetsideAttributeMessage(guid, 4, maxArmor)) - data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, guid, AvatarAction.PlanetsideAttribute(4, maxArmor)) + data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, PlanetsideAttribute(guid, 4, maxArmor)) } } @@ -203,7 +204,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle)) data.continent.VehicleEvents ! VehicleServiceMessage( data.continent.id, - VehicleAction.PlanetsideAttribute(guid, shieldsUi, maxShieldsOfVehicle) + PlanetsideAttribute(guid, shieldsUi, maxShieldsOfVehicle) ) } } @@ -217,7 +218,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf)) data.continent.VehicleEvents ! VehicleServiceMessage( data.continent.id, - VehicleAction.PlanetsideAttribute(guid, 0, maxHealthOf) + PlanetsideAttribute(guid, 0, maxHealthOf) ) } } diff --git a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala index cb6ec6e8f..65fc5b052 100644 --- a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala @@ -35,7 +35,7 @@ import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitR import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.RemoverActor import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, CorpseEnvelope} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.duration._ @@ -163,15 +163,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex } def handleEmote(pkt: EmoteMsg): Unit = { - val EmoteMsg(avatarGuid, emote) = pkt - val pZone = player.Zone - sendResponse(EmoteMsg(avatarGuid, emote)) - pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID => - pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote))) - } - pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction => - pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote))) - } + sendResponse(pkt) + ops.handleEmote(pkt) } def handleDropItem(pkt: DropItemMessage): Unit = { @@ -442,7 +435,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent.AvatarEvents ! AvatarServiceMessage( continent.id, player.GUID, - AvatarAction.PlanetsideAttribute(19, 1) + PlanetsideAttribute(player.GUID, 19, 1) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => @@ -463,7 +456,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent.AvatarEvents ! AvatarServiceMessage( continent.id, player.GUID, - AvatarAction.PlanetsideAttribute(19, 0) + PlanetsideAttribute(player.GUID, 19, 0) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => diff --git a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala index a397908dd..33dfbf483 100644 --- a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala @@ -15,7 +15,8 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} @@ -159,7 +160,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act case Mountable.CanMount(obj: FacilityTurret, seatNumber, _) if obj.Definition == GlobalDefinitions.vanu_sentry_turret => sessionLogic.zoning.CancelZoningProcess() - obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, LocalAction.SetEmpire(obj.GUID, player.Faction)) + obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, SetEmpire(obj.GUID, player.Faction)) sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health)) ops.updateWeaponAtSeatPosition(obj, seatNumber) ops.MountingAction(tplayer, obj, seatNumber) @@ -200,7 +201,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true)) continent.LocalEvents ! LocalServiceMessage( continent.id, - LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) + SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive @@ -214,7 +215,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse(PlayerStasisMessage(pguid)) //the stasis message + SendResponse(PlayerStasisMessage(pguid)) //the stasis message ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state @@ -222,12 +223,12 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock events ! VehicleServiceMessage( player.Name, - VehicleAction.SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) + SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) ) events ! VehicleServiceMessage( continent.id, pguid, - VehicleAction.SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player + SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive diff --git a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala index a17080966..4f5158ef4 100644 --- a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala @@ -8,6 +8,7 @@ import net.psforever.objects.{Player, Session, Vehicle} import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSidePacket import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.ObjectDelete import net.psforever.services.chat.SpectatorChannel import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} import net.psforever.types.{ChatMessageType, SquadRequestType} @@ -45,7 +46,7 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic { // player.spectator = true data.chat.JoinChannel(SpectatorChannel) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, AvatarAction.ObjectDelete(pguid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, ObjectDelete(pguid)) sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "on")) sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR SPECTATOR MODE ON")) } diff --git a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala index 30400f266..d544f6dcf 100644 --- a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala @@ -11,7 +11,9 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vehicles.control.BfrFlight import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone -import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} +import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{DriveState, Vector3} 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 c39f5f8e7..dc6283f45 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -14,6 +14,7 @@ import net.psforever.objects.vital.interaction.Adversarial import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction, PlanetsideStringAttributeMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import net.psforever.types.ImplantType import scala.concurrent.duration._ @@ -218,23 +219,23 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - case AvatarAction.ChangeFireState_Start(weaponGuid) + case ChangeFireState_Start(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - case AvatarAction.ChangeFireState_Start(weaponGuid) + case ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case AvatarAction.ChangeFireState_Stop(weaponGuid) + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - case AvatarAction.ChangeFireState_Stop(weaponGuid) + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) @@ -244,8 +245,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) + case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => + sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) @@ -256,10 +257,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => sendResponse(PlanetsideStringAttributeMessage(guid, attributeType, attributeValue)) - case AvatarAction.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => + case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - case AvatarAction.HitHint(sourceGuid) if player.isAlive => + case HintsAtAttacker(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, guid)) sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") @@ -486,14 +487,14 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.RemoveFromOutfitChat(outfit_id) => ops.removeFromOutfitChat(outfit_id) - case AvatarAction.SendResponse(msg) => - sendResponse(msg) + case SendResponse(msgs) => + msgs.foreach(sendResponse) case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => sendResponse(msg) /* common messages (maybe once every respawn) */ - case AvatarAction.Reload(itemGuid) + case ReloadTool(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) @@ -606,12 +607,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } /* uncommon messages (utility, or once in a while) */ - case AvatarAction.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 && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarAction.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 => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) @@ -628,11 +629,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.ObjectDelete(itemGuid, unk) if isNotSameTarget => + case ObjectDelete(itemGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) /* rare messages */ - case AvatarAction.SetEmpire(objectGuid, faction) if isNotSameTarget => + case SetEmpire(objectGuid, faction) if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) case AvatarAction.DropSpecialItem() => @@ -681,7 +682,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) ) - case AvatarAction.WeaponDryFire(weaponGuid) + case WeaponDryFire(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => @@ -700,6 +701,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //make player invisible on client events ! AvatarServiceMessage(player.Name, playerGuid, AvatarAction.PlanetsideAttributeToAll(29, 1)) //only the dead player should "see" their own body, so that the death camera has something to focus on - events ! AvatarServiceMessage(continent.id, playerGuid, AvatarAction.ObjectDelete(playerGuid)) + events ! AvatarServiceMessage(continent.id, playerGuid, ObjectDelete(playerGuid)) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index 28804cf8f..8ef281b1d 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -6,6 +6,7 @@ import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers} import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo} import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.SendResponse import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.types.{MemberAction, PlanetSideEmpire} @@ -85,8 +86,8 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A case GalaxyAction.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) => avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name) - case GalaxyAction.SendResponse(msg) => - sendResponse(msg) + case SendResponse(msgs) => + msgs.foreach(sendResponse) case _ => () } diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index 9be51341e..14ac88743 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -43,7 +43,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.util.Config @@ -213,15 +213,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex } def handleEmote(pkt: EmoteMsg): Unit = { - val EmoteMsg(avatarGuid, emote) = pkt - val pZone = player.Zone - sendResponse(EmoteMsg(avatarGuid, emote)) - pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID => - pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote))) - } - pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction => - pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote))) - } + sendResponse(pkt) + ops.handleEmote(pkt) } def handleDropItem(pkt: DropItemMessage): Unit = { @@ -528,7 +521,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent.AvatarEvents ! AvatarServiceMessage( continent.id, player.GUID, - AvatarAction.PlanetsideAttribute(19, 1) + PlanetsideAttribute(player.GUID, 19, 1) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => @@ -550,7 +543,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent.AvatarEvents ! AvatarServiceMessage( continent.id, player.GUID, - AvatarAction.PlanetsideAttribute(19, 0) + PlanetsideAttribute(player.GUID, 19, 0) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => 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 991cac4f1..173e76393 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -10,6 +10,7 @@ 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, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse, SetEmpire} import net.psforever.services.{InterstellarClusterService, Service} import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideGUID, SpawnGroup} @@ -138,16 +139,16 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act obj.Destroyed = true ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) - case LocalAction.SendHackMessageHackCleared(targetGuid, unk1, unk2) => + case LocalAction.HackClear(targetGuid, unk1, unk2) => sendResponse(HackMessage(HackState1.Unk0, targetGuid, guid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) case LocalAction.HackObject(targetGuid, unk1, unk2) => sessionLogic.general.hackObject(targetGuid, unk1, unk2) - case LocalAction.PlanetsideAttribute(targetGuid, attributeType, attributeValue) => + case PlanetsideAttribute(targetGuid, attributeType, attributeValue) => sessionLogic.general.sendPlanetsideAttributeMessage(targetGuid, attributeType, attributeValue) - case LocalAction.GenericObjectAction(targetGuid, actionNumber) => + case GenericObjectAction(targetGuid, actionNumber) => sendResponse(GenericObjectActionMessage(targetGuid, actionNumber)) case LocalAction.GenericActionMessage(actionNumber) => @@ -174,7 +175,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act player.Carrying = None } - case LocalAction.ObjectDelete(objectGuid, unk) if isNotSameTarget => + case ObjectDelete(objectGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(objectGuid, unk)) case LocalAction.ProximityTerminalEffect(object_guid, true) => @@ -190,21 +191,19 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act case LocalAction.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) => sessionLogic.general.useRouterTelepadEffect(passengerGuid, srcGuid, destGuid) - case LocalAction.SendResponse(msg) => - msg match { - case m: GenericObjectActionMessage => + case SendResponse(msgs) => + msgs.foreach { + case msg @ (m: GenericObjectActionMessage) + if (m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages => // delay building virus alert if player is dead/respawning - if ((m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages) { - sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask( - SpawnOperations.delaySendGenericObjectActionMessage(msg), 1)) - } else { - sendResponse(msg) - } - case _ => + sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask( + SpawnOperations.delaySendGenericObjectActionMessage(msg), 1) + ) + case msg => sendResponse(msg) } - case LocalAction.SetEmpire(objectGuid, empire) => + case SetEmpire(objectGuid, empire) => sendResponse(SetEmpireMessage(objectGuid, empire)) case LocalAction.ShuttleEvent(ev) => diff --git a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala index 96f629a6b..163ac36fd 100644 --- a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala @@ -16,7 +16,8 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} @@ -190,7 +191,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act if obj.Definition == GlobalDefinitions.vanu_sentry_turret => log.info(s"${player.Name} mounts the ${obj.Definition.Name}") sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_mount") - obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, LocalAction.SetEmpire(obj.GUID, player.Faction)) + obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, SetEmpire(obj.GUID, player.Faction)) sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health)) ops.updateWeaponAtSeatPosition(obj, seatNumber) ops.MountingAction(tplayer, obj, seatNumber) @@ -235,7 +236,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true)) continent.LocalEvents ! LocalServiceMessage( continent.id, - LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) + SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive @@ -248,22 +249,18 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountAction(tplayer, obj, seatNum) continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages - events ! VehicleServiceMessage( - player.Name, - VehicleAction.SendResponse(PlayerStasisMessage(pguid)) //the stasis message - ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! VehicleServiceMessage( - player.Name, - VehicleAction.SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) - ) + events ! VehicleServiceMessage(player.Name, SendResponse(Seq( + PlayerStasisMessage(pguid), + PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) + ))) events ! VehicleServiceMessage( continent.id, pguid, - VehicleAction.SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player + SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive 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 4eef98263..54bef7716 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -15,6 +15,7 @@ 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.services.Service import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.{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, VehicleServiceResponse} import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3} @@ -98,16 +99,16 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: if isNotSameTarget => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => + case ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case VehicleAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case VehicleAction.Reload(itemGuid) if isNotSameTarget => + case ReloadTool(itemGuid) if isNotSameTarget => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case VehicleAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => + case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0)) //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) sendResponse( @@ -120,7 +121,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: ) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case VehicleAction.WeaponDryFire(weaponGuid) if isNotSameTarget => + case WeaponDryFire(weaponGuid) if isNotSameTarget => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage @@ -137,16 +138,16 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos)) - case VehicleAction.SendResponse(msg) => - sendResponse(msg) + case SendResponse(msgs) => + msgs.foreach(sendResponse) case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) - case VehicleAction.GenericObjectAction(objectGuid, action) if isNotSameTarget => + case GenericObjectAction(objectGuid, action) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, action)) - case VehicleAction.HitHint(sourceGuid) if player.isAlive => + case HintsAtAttacker(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, player.GUID)) case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => @@ -187,7 +188,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleAction.ObjectDelete(itemGuid) if isNotSameTarget => + case ObjectDelete(itemGuid, _) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) case VehicleAction.Ownership(vehicleGuid) if resolvedPlayerGuid == guid => @@ -198,7 +199,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.LoseOwnership(_, vehicleGuid) => ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") - case VehicleAction.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => + case PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue)) case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => 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 8569ea9ab..133c9f289 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -9,6 +9,7 @@ import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.{AvatarImplantMessage, ImplantAction} import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import scala.concurrent.duration._ // @@ -182,23 +183,23 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - case AvatarAction.ChangeFireState_Start(weaponGuid) + case ChangeFireState_Start(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - case AvatarAction.ChangeFireState_Start(weaponGuid) + case ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case AvatarAction.ChangeFireState_Stop(weaponGuid) + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) val entry = ops.lastSeenStreamMessage(guid.guid) ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - case AvatarAction.ChangeFireState_Stop(weaponGuid) + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) @@ -208,8 +209,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.PlanetsideAttribute(attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) + case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => + sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) @@ -217,10 +218,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarAction.GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => + case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - case AvatarAction.HitHint(sourceGuid) if player.isAlive => + case HintsAtAttacker(sourceGuid) if player.isAlive => sendResponse(HitHint(sourceGuid, guid)) sessionLogic.zoning.CancelZoningProcess() @@ -411,19 +412,21 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => ops.facilityCaptureRewards(buildingId, zoneNumber, cep) - case AvatarAction.SendResponse(pkt: AvatarImplantMessage) - if pkt.player_guid == player.GUID && pkt.action == ImplantAction.Initialization => - //special spectator implants stay initialized and do not deinitialize - () - - case AvatarAction.SendResponse(msg) => - sendResponse(msg) + case SendResponse(msgs) => + msgs.foreach { + case pkt: AvatarImplantMessage + if pkt.player_guid == player.GUID && pkt.action == ImplantAction.Initialization => + //special spectator implants stay initialized and do not deinitialize + () + case msg => + sendResponse(msg) + } case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => sendResponse(msg) /* common messages (maybe once every respawn) */ - case AvatarAction.Reload(itemGuid) + case ReloadTool(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) @@ -496,12 +499,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) /* uncommon messages (utility, or once in a while) */ - case AvatarAction.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 && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarAction.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 => ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) @@ -518,11 +521,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.ObjectDelete(itemGuid, unk) if isNotSameTarget => + case ObjectDelete(itemGuid, unk) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) /* rare messages */ - case AvatarAction.SetEmpire(objectGuid, faction) if isNotSameTarget => + case SetEmpire(objectGuid, faction) if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) case AvatarAction.DropSpecialItem() => @@ -571,7 +574,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) ) - case AvatarAction.WeaponDryFire(weaponGuid) + case WeaponDryFire(weaponGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala index 0e118cb0f..836538004 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala @@ -17,6 +17,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.AccountPersistenceService import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.types.{ExoSuitType, Vector3} import scala.concurrent.duration.DurationInt @@ -106,8 +107,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex } def handleEmote(pkt: EmoteMsg): Unit = { - val EmoteMsg(avatarGuid, emote) = pkt - sendResponse(EmoteMsg(avatarGuid, emote)) + sendResponse(pkt) } def handleDropItem(pkt: DropItemMessage): Unit = { /* intentionally blank */ } @@ -231,7 +231,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent.AvatarEvents ! AvatarServiceMessage( continent.id, player.GUID, - AvatarAction.PlanetsideAttribute(19, 1) + PlanetsideAttribute(player.GUID, 19, 1) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => @@ -253,7 +253,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent.AvatarEvents ! AvatarServiceMessage( continent.id, player.GUID, - AvatarAction.PlanetsideAttribute(19, 0) + PlanetsideAttribute(player.GUID, 19, 0) ) definition match { case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster => diff --git a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala index de1e1323b..5b9d41beb 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala @@ -12,7 +12,8 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} object MountHandlerLogic { @@ -62,7 +63,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true)) continent.LocalEvents ! LocalServiceMessage( continent.id, - LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) + SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) ) obj.Zone.actor ! ZoneActor.RemoveFromBlockMap(player) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive @@ -75,22 +76,18 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountAction(tplayer, obj, seatNum) continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages - events ! VehicleServiceMessage( - player.Name, - VehicleAction.SendResponse(PlayerStasisMessage(pguid)) //the stasis message - ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! VehicleServiceMessage( - player.Name, - VehicleAction.SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) - ) + events ! VehicleServiceMessage(player.Name, SendResponse(Seq( + PlayerStasisMessage(pguid), + PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) + ))) events ! VehicleServiceMessage( continent.id, pguid, - VehicleAction.SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player + SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player ) context.self ! SessionActor.SetMode(NormalMode) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive diff --git a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala index 94eb93823..1cb2618d2 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala @@ -11,7 +11,8 @@ import net.psforever.packet.PlanetSidePacket import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage, DeploymentAction, ObjectCreateDetailedMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars} import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.ObjectDelete import net.psforever.services.chat.SpectatorChannel import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} import net.psforever.types.{CapacitorStateType, ChatMessageType, ExoSuitType, MeritCommendation, SquadRequestType} @@ -68,7 +69,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic { player.Inventory.Items .foreach { entry => sendResponse(ObjectDeleteMessage(entry.GUID, 0)) } sendResponse(ObjectDeleteMessage(player.avatar.locker.GUID, 0)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, AvatarAction.ObjectDelete(pguid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, ObjectDelete(pguid)) player.Holsters() .collect { case slot if slot.Equipment.nonEmpty => sendResponse(ObjectDeleteMessage(slot.Equipment.get.GUID, 0)) } val vehicleAndSeat = data.vehicles.GetMountableAndSeat(None, player, continent) match { 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 ddb2d7b27..674e39f54 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -9,6 +9,7 @@ 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.services.base.EventResponse +import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} @@ -83,16 +84,16 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: if isNotSameTarget => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleAction.ChangeFireState_Start(weaponGuid) if isNotSameTarget => + case ChangeFireState_Start(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - case VehicleAction.ChangeFireState_Stop(weaponGuid) if isNotSameTarget => + case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - case VehicleAction.Reload(itemGuid) if isNotSameTarget => + case ReloadTool(itemGuid) if isNotSameTarget => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - case VehicleAction.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => + case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0)) //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) sendResponse( @@ -105,7 +106,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: ) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case VehicleAction.WeaponDryFire(weaponGuid) if isNotSameTarget => + case WeaponDryFire(weaponGuid) if isNotSameTarget => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage @@ -122,13 +123,13 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos)) - case VehicleAction.SendResponse(msg) => - sendResponse(msg) + case SendResponse(msgs) => + msgs.foreach(sendResponse) case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) - case VehicleAction.GenericObjectAction(objectGuid, action) if isNotSameTarget => + case GenericObjectAction(objectGuid, action) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, action)) case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => @@ -165,10 +166,10 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleAction.ObjectDelete(itemGuid) if isNotSameTarget => + case ObjectDelete(itemGuid, _) if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - case VehicleAction.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => + case PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue)) case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 5cef27ea4..29a32f7cd 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -19,6 +19,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.RemoverActor import net.psforever.services.avatar.GroundEnvelope +import net.psforever.services.base.messages.SendResponse import net.psforever.services.local.support.HackCaptureActor import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} @@ -195,6 +196,32 @@ class GeneralOperations( private[session] var progressBarUpdate: Cancellable = Default.Cancellable private var charSavedTimer: Cancellable = Default.Cancellable + def handleEmote(pkt: EmoteMsg): Unit = { + val guid = player.GUID + val zone = player.Zone + val events = zone.LocalEvents + val msg = SendResponse(pkt) + sessionLogic + .localSector + .livePlayerList + .filter(_.GUID != guid) + .foreach { p => + events ! LocalServiceMessage(p.Name, msg) + } + //todo better way to collect csr players while utilizing the aforementioned benefit of localSector + val position = player.Position + val rangeSq = { + val range = math.sqrt(2 * math.pow(sessionLogic.localSector.rangeX.toDouble, 2)) + range * range + } + zone + .AllPlayers + .filter { p => !p.allowInteraction && p.GUID != guid && Vector3.DistanceSquared(p.Position, position) < rangeSq } + .foreach { p => + events ! LocalServiceMessage(p.Name, msg) + } + } + def handleDropItem(pkt: DropItemMessage): GeneralOperations.ItemDropState.Behavior = { val DropItemMessage(itemGuid) = pkt (sessionLogic.validObject(itemGuid, decorator = "DropItem"), player.FreeHand.Equipment) match { @@ -881,6 +908,19 @@ class GeneralOperations( sendResponse(HackMessage(HackState1.Unk0, targetGuid, player_guid=Service.defaultPlayerGUID, progress=100, unk1.toFloat, HackState.Hacked, unk2)) } + /** + * Send a PlanetsideAttributeMessage packet to the client + * @param targetGuid The target of the attribute + * @param attribute The attribute + * @param attributeValue The attribute value + */ + def sendPlanetsideAttributeMessage( + targetGuid: PlanetSideGUID, + attribute: PlanetsideAttributeEnum, + attributeValue: Long + ): Unit = { + sendPlanetsideAttributeMessage(targetGuid, attribute.id, attributeValue) + } /** * Send a PlanetsideAttributeMessage packet to the client * @param targetGuid The target of the attribute @@ -889,7 +929,7 @@ class GeneralOperations( */ def sendPlanetsideAttributeMessage( targetGuid: PlanetSideGUID, - attributeNumber: PlanetsideAttributeEnum, + attributeNumber: Int, attributeValue: Long ): Unit = { sendResponse(PlanetsideAttributeMessage(targetGuid, attributeNumber, attributeValue)) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index d033b8d0d..575a8a587 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -10,6 +10,7 @@ import net.psforever.objects.zones.exp import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, AvatarServiceResponse} import net.psforever.services.base.EventResponse +import net.psforever.services.base.messages.SendResponse import net.psforever.services.chat.OutfitChannel import scala.collection.mutable @@ -215,9 +216,7 @@ class SessionAvatarHandlers( context.self ! AvatarServiceResponse( playerName, Service.defaultPlayerGUID, - AvatarAction.SendResponse( - ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero) - ) + SendResponse(ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero)) ) //player no longer seated obj.PassengerInSeat(player).foreach { seatNumber => diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index c2f1c543e..443ac5f85 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -8,6 +8,7 @@ import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle} import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} +import net.psforever.services.base.messages.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} // @@ -204,11 +205,11 @@ class SessionMountHandlers( sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(PlanetsideAttributeMessage(obj.GUID, 81, 1)) + SendResponse(PlanetsideAttributeMessage(obj.GUID, 81, 1)) ) continent.VehicleEvents ! VehicleServiceMessage( continent.id, - VehicleAction.SendResponse(ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) + SendResponse(ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) ) } else { diff --git a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala index 4f6501914..25469f213 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala @@ -2,6 +2,7 @@ package net.psforever.actors.session.support import akka.actor.{ActorContext, ActorRef, typed} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.teamwork.SquadServiceResponse import scala.collection.mutable @@ -10,7 +11,7 @@ import net.psforever.actors.session.AvatarActor import net.psforever.objects.teamwork.Squad import net.psforever.objects.{Default, Player} import net.psforever.packet.game._ -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.teamwork.{SquadResponse, SquadServiceMessage, SquadAction => SquadServiceAction} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -108,7 +109,7 @@ class SessionSquadHandlers( continent.AvatarEvents ! AvatarServiceMessage( s"${player.Faction}", player.GUID, - AvatarAction.PlanetsideAttribute(31, squad_supplement_id) + PlanetsideAttribute(player.GUID, 31, squad_supplement_id) ) sendResponse(PlanetsideAttributeMessage(player.GUID, 32, elem.index)) case _ => @@ -287,7 +288,7 @@ class SessionSquadHandlers( * @param value value to associate the player */ def GiveSquadColorsForOthers(guid: PlanetSideGUID, factionChannel: String, value: Long): Unit = { - continent.AvatarEvents ! AvatarServiceMessage(factionChannel, guid, AvatarAction.PlanetsideAttribute(31, value)) + continent.AvatarEvents ! AvatarServiceMessage(factionChannel, guid, PlanetsideAttribute(guid, 31, value)) } /** diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index f9dbb878f..ca6fb0509 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -28,7 +28,8 @@ import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} +import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3} import net.psforever.util.Config @@ -282,12 +283,12 @@ class WeaponAndProjectileOperations( .orElse { continent.GUID(weapon_guid) } .collect { case _: Equipment if containerOpt.exists(_.isInstanceOf[Player]) => - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.WeaponDryFire(weapon_guid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, WeaponDryFire(weapon_guid)) case _: Equipment => continent.VehicleEvents ! VehicleServiceMessage( continent.id, player.GUID, - VehicleAction.WeaponDryFire(weapon_guid) + WeaponDryFire(weapon_guid) ) } .orElse { @@ -350,7 +351,7 @@ class WeaponAndProjectileOperations( player.Zone.LocalEvents ! LocalServiceMessage( s"${player.Zone.id}", PlanetSideGUID(-1), - LocalAction.SendResponse(TriggerEffectMessage(Service.defaultPlayerGUID, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))) + SendResponse(TriggerEffectMessage(Service.defaultPlayerGUID, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))) ) context.system.scheduler.scheduleOnce(delay = 1 seconds) { Zone.serverSideDamage(player.Zone, player, empSize, SpecialEmp.createEmpInteraction(empSize, player.Position), @@ -360,7 +361,7 @@ class WeaponAndProjectileOperations( player.Zone.LocalEvents ! LocalServiceMessage( s"$playerFaction", PlanetSideGUID(-1), - LocalAction.SendResponse(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y)) + SendResponse(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y)) ) sendResponse(UplinkResponse(code.value, 0)) orbitalStrikePos = pos @@ -389,12 +390,12 @@ class WeaponAndProjectileOperations( player.Zone.LocalEvents ! LocalServiceMessage( s"${player.Zone.id}", PlanetSideGUID(-1), - LocalAction.SendResponse(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90))))) + SendResponse(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90))))) ) player.Zone.LocalEvents ! LocalServiceMessage( s"$playerFaction", PlanetSideGUID(-1), - LocalAction.SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) + SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) ) context.system.scheduler.scheduleOnce(delay = 5 seconds) { val sectorTargets = Zone.findOrbitalStrikeTargets(player.Zone, orbitalStrikePos.get, osSize.DamageRadius, Zone.getOrbitbalStrikeTargets) @@ -758,7 +759,7 @@ class WeaponAndProjectileOperations( //chain lash effect continent.AvatarEvents ! AvatarServiceMessage( continent.id, - AvatarAction.SendResponse(ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList)) + SendResponse(ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList)) ) //chain lash target output outputRefs.toList @@ -942,9 +943,9 @@ class WeaponAndProjectileOperations( tool.Magazine = 0 sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, weapon_guid, 0)) sendResponse(ChangeFireStateMessage_Stop(weapon_guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.ChangeFireState_Stop(weapon_guid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, ChangeFireState_Stop(weapon_guid)) sendResponse(WeaponDryFireMessage(weapon_guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.WeaponDryFire(weapon_guid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, WeaponDryFire(weapon_guid)) } /** @@ -1088,7 +1089,7 @@ class WeaponAndProjectileOperations( continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, player.GUID, - AvatarAction.ChangeFireState_Start(itemGuid) + ChangeFireState_Start(itemGuid) ) } @@ -1100,7 +1101,7 @@ class WeaponAndProjectileOperations( continent.VehicleEvents ! VehicleServiceMessage( continent.id, player.GUID, - VehicleAction.ChangeFireState_Start(itemGuid) + ChangeFireState_Start(itemGuid) ) } @@ -1129,7 +1130,7 @@ class WeaponAndProjectileOperations( continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, player.GUID, - AvatarAction.ChangeFireState_Stop(itemGuid) + ChangeFireState_Stop(itemGuid) ) } @@ -1141,7 +1142,7 @@ class WeaponAndProjectileOperations( continent.VehicleEvents ! VehicleServiceMessage( continent.id, player.GUID, - VehicleAction.ChangeFireState_Stop(itemGuid) + ChangeFireState_Stop(itemGuid) ) } @@ -1198,14 +1199,14 @@ class WeaponAndProjectileOperations( used by ReloadMessage handling */ def reloadPlayerMessages(itemGuid: PlanetSideGUID): Unit = { - continent.AvatarEvents ! AvatarServiceMessage(sessionLogic.zoning.zoneChannel, player.GUID, AvatarAction.Reload(itemGuid)) + continent.AvatarEvents ! AvatarServiceMessage(sessionLogic.zoning.zoneChannel, player.GUID, ReloadTool(itemGuid)) } def reloadVehicleMessages(itemGuid: PlanetSideGUID): Unit = { continent.VehicleEvents ! VehicleServiceMessage( continent.id, player.GUID, - VehicleAction.Reload(itemGuid) + ReloadTool(itemGuid) ) } @@ -1382,7 +1383,7 @@ class WeaponAndProjectileOperations( continent.AvatarEvents ! AvatarServiceMessage( sessionLogic.zoning.zoneChannel, player.GUID, - AvatarAction.ChangeAmmo( + ChangeAmmo( tool_guid, ammoSlotIndex, previous_box_guid, @@ -1587,7 +1588,7 @@ class WeaponAndProjectileOperations( shootingStop.clear() (prefire ++ shooting).foreach { guid => sendResponse(ChangeFireStateMessage_Stop(guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, AvatarAction.ChangeFireState_Stop(guid)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, ChangeFireState_Stop(guid)) } prefire.clear() shooting.clear() diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 846a0449d..c9958e852 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -23,6 +23,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage} import net.psforever.services.avatar.{CorpseEnvelope, ReleaseMessage} +import net.psforever.services.base.messages.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.chat.DefaultChannel import scala.concurrent.duration._ @@ -852,7 +853,7 @@ class ZoningOperations( case None => spawn.deadState = DeadState.Release // cancel movement updates player.Position = position - // continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player.GUID, player.GUID)) + // continent.AvatarEvents ! AvatarServiceMessage(continent.Id, ObjectDelete(player.GUID, player.GUID)) spawn.LoadZonePhysicalSpawnPoint(zoneId, position, Vector3.Zero, 0 seconds, None) case _ => // seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move } @@ -1209,7 +1210,7 @@ class ZoningOperations( continent.LocalEvents ! LocalServiceMessage( continent.id, PlanetSideGUID(-1), - LocalAction.SendResponse(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252)) + SendResponse(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252)) ) } case _ => () @@ -2888,7 +2889,7 @@ class ZoningOperations( if (player.VisibleSlots.contains(index)) { events ! AvatarServiceMessage( zoneId, - AvatarAction.ObjectDelete(obj.GUID) + ObjectDelete(obj.GUID) ) } else { sendResponse(ObjectDeleteMessage(obj.GUID, 0)) @@ -2922,7 +2923,7 @@ class ZoningOperations( val pguid = tplayer.GUID zone.Population ! Zone.Population.Release(avatar) sendResponse(ObjectDeleteMessage(pguid, 0)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, pguid, AvatarAction.ObjectDelete(pguid)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, pguid, ObjectDelete(pguid)) TaskWorkflow.execute(GUIDTask.unregisterPlayer(zone.GUID, tplayer)) } } @@ -3181,7 +3182,7 @@ class ZoningOperations( continent.AvatarEvents ! AvatarServiceMessage( continent.id, player_guid, - AvatarAction.ObjectDelete(player_guid, unk=effect) + ObjectDelete(player_guid, unk=effect) ) InGameHistory.SpawnReconstructionActivity(player, toZoneNumber, betterSpawnPoint) LoadZoneAsPlayerUsing(player, pos, ori, toSide, zoneId) @@ -3345,7 +3346,7 @@ class ZoningOperations( //looking for squad (members) if (tplayer.avatar.lookingForSquad) { sendResponse(PlanetsideAttributeMessage(guid, 53, 1)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, guid, AvatarAction.PlanetsideAttribute(53, 1)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, guid, PlanetsideAttribute(guid, 53, 1)) } sendResponse(AvatarSearchCriteriaMessage(guid, List(0, 0, 0, 0, 0, 0))) //these are facilities and towers and bunkers in the zone, but not necessarily all of them for some reason @@ -4003,14 +4004,14 @@ class ZoningOperations( pZone.LocalEvents ! LocalServiceMessage( t.Name, t.GUID, - LocalAction.GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs) + GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) ) } pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction => pZone.LocalEvents ! LocalServiceMessage( t.Name, t.GUID, - LocalAction.GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs) + GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) ) } } diff --git a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala index 0f385dae4..79c51dd6f 100644 --- a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala +++ b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala @@ -11,8 +11,9 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.ContinentalLockUpdateMessage import net.psforever.persistence +import net.psforever.services.base.messages.{SendResponse, SetEmpire} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalServiceMessage import net.psforever.services.{InterstellarClusterService, ServiceManager} import net.psforever.types.PlanetSideEmpire import net.psforever.util.Database.ctx @@ -167,7 +168,7 @@ object BuildingActor { val building = details.building val zone = building.Zone building.Faction = faction - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SetEmpire(building.GUID, faction)) + zone.LocalEvents ! LocalServiceMessage(zone.id, SetEmpire(building.GUID, faction)) } } @@ -232,7 +233,7 @@ class BuildingActor( case MapUpdate() => details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(details.building.densityLevelUpdateMessage(building))) + details.galaxyService ! GalaxyServiceMessage(SendResponse(details.building.densityLevelUpdateMessage(building))) Behaviors.same case AmenityStateChange(amenity, data) => @@ -254,15 +255,15 @@ class BuildingActor( logic.ntu(details, msg) case DensityLevelUpdate(building) => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(details.building.densityLevelUpdateMessage(building))) + details.galaxyService ! GalaxyServiceMessage(SendResponse(details.building.densityLevelUpdateMessage(building))) Behaviors.same case ContinentalLock(zone) => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(ContinentalLockUpdateMessage(zone.Number, zone.lockedBy))) + details.galaxyService ! GalaxyServiceMessage(SendResponse(ContinentalLockUpdateMessage(zone.Number, zone.lockedBy))) Behaviors.same case HomeLockBenefits(msg) => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(msg)) + details.galaxyService ! GalaxyServiceMessage(SendResponse(msg)) Behaviors.same } } diff --git a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala index 391b0a7c8..8d8a6ef75 100644 --- a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala +++ b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala @@ -20,7 +20,8 @@ import net.psforever.objects.zones.exp.{ExperienceCalculator, SupportExperienceC import net.psforever.packet.game.{BuildingInfoUpdateMessage, PlanetsideAttributeMessage} import net.psforever.util.Database._ import net.psforever.persistence -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.local.LocalServiceMessage import scala.collection.mutable import scala.util.{Failure, Success} @@ -236,24 +237,24 @@ class ZoneActor( if (msg.generator_state == PlanetSideGeneratorState.Normal && building.hasCavernLockBenefit) { zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1)) + SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1)) ) } msg.is_hacked match { case true if building.BuildingType == StructureType.Facility && !zone.map.cavern => zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) + SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) ) case false if building.hasCavernLockBenefit => zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1)) + SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1)) ) case false if building.BuildingType == StructureType.Facility && !zone.map.cavern && !building.hasCavernLockBenefit => zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) + SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) ) case _ => } diff --git a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala index 7cff60fa9..55ef7efd4 100644 --- a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala @@ -9,7 +9,7 @@ import net.psforever.objects.serverobject.structures.{Amenity, Building, Structu import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.ClearMessage +import net.psforever.services.local.HackClearMessage import net.psforever.types.PlanetSideEmpire /** @@ -53,7 +53,7 @@ case object CavernFacilityLogic // When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state building.HackableAmenities.foreach(amenity => { if (amenity.HackedBy.isDefined) { - building.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(amenity)) + building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity)) } }) // No map update needed - will be sent by `HackCaptureActor` when required diff --git a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala index 41c39b13e..de48e4bc7 100644 --- a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala @@ -9,7 +9,7 @@ import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.ClearMessage +import net.psforever.services.local.HackClearMessage import net.psforever.types.PlanetSideEmpire /** @@ -53,7 +53,7 @@ case object FacilityLogic // When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state building.HackableAmenities.foreach(amenity => { if (amenity.HackedBy.isDefined) { - building.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(amenity)) + building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity)) } }) // No map update needed - will be sent by `HackCaptureActor` when required diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index c1d1774e2..ac8dd175b 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -16,8 +16,9 @@ import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.PlanetsideAttributeMessage import net.psforever.services.InterstellarClusterService import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{GenericObjectAction, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{CaptureMessage, ClearMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.{CaptureMessage, HackClearMessage, LocalServiceMessage} import net.psforever.services.local.support.{HackCaptureActor, HackClearActor} import net.psforever.types.PlanetSideEmpire @@ -102,7 +103,7 @@ case object MajorFacilityLogic hackedAmenities } amenitiesToClear.foreach { amenity => - building.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(amenity)) + building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity)) } // No map update needed - will be sent by `HackCaptureActor` when required case dome: ForceDomePhysics => @@ -203,7 +204,7 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.UnderAttack) => val events = zone.AvatarEvents val guid = building.GUID - val msg = AvatarAction.GenericObjectAction(guid, 15) + val msg = GenericObjectAction(guid, 15) building.PlayersInSOI.foreach { player => events ! AvatarServiceMessage(player.Name, msg) } @@ -219,14 +220,14 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.Destabilized) => val events = zone.AvatarEvents val guid = building.GUID - val msg = AvatarAction.GenericObjectAction(guid, 16) + val msg = GenericObjectAction(guid, 16) building.PlayersInSOI.foreach { player => events ! AvatarServiceMessage(player.Name, msg) } if (building.hasCavernLockBenefit) { zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) + SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) ) } false @@ -248,7 +249,7 @@ case object MajorFacilityLogic val events = zone.AvatarEvents val guid = building.GUID val msg1 = AvatarAction.PlanetsideAttributeToAll(46, 0) - val msg2 = AvatarAction.GenericObjectAction(guid, 17) + val msg2 = GenericObjectAction(guid, 17) building.PlayersInSOI.foreach { player => val name = player.Name events ! AvatarServiceMessage(name, guid, msg1) //reset ???; might be global? diff --git a/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala b/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala index b3eb01c1f..05cad4278 100644 --- a/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala @@ -4,7 +4,7 @@ package net.psforever.actors.zone.building import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.Behaviors import net.psforever.actors.commands.NtuCommand -import net.psforever.actors.zone.{BuildingActor, ZoneActor} +import net.psforever.actors.zone.BuildingActor import net.psforever.objects.serverobject.structures.{Amenity, Building, WarpGate} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.types.PlanetSideEmpire diff --git a/src/main/scala/net/psforever/login/WorldSession.scala b/src/main/scala/net/psforever/login/WorldSession.scala index 18914d471..ccc0d4860 100644 --- a/src/main/scala/net/psforever/login/WorldSession.scala +++ b/src/main/scala/net/psforever/login/WorldSession.scala @@ -16,6 +16,7 @@ import net.psforever.objects.vital.TerminalUsedActivity import net.psforever.objects.zones.Zone import net.psforever.types.{ExoSuitType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.ObjectDelete import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future @@ -279,7 +280,7 @@ object WorldSession { * @throws `RuntimeException` if slot is not a player visible slot (holsters) * @see `ask` * @see `AvatarAction.ObjectDelete` - * @see `AvatarAction.SendResponse` + * @see `SendResponse` * @see `Containable.CanNotPutItemInSlot` * @see `Containable.PutItemInSlotOnly` * @see `GUIDTask.registerEquipment` @@ -366,7 +367,7 @@ object WorldSession { localZone.GUID(item_guid) match { case Some(_) => () case None => //acting on old data? - localZone.AvatarEvents ! AvatarServiceMessage(localZone.id, AvatarAction.ObjectDelete(item_guid)) + localZone.AvatarEvents ! AvatarServiceMessage(localZone.id, ObjectDelete(item_guid)) } case _ => () } @@ -590,7 +591,7 @@ object WorldSession { localGUID match { case Some(guid) => //see LockerContainerControl.RemoveItemFromSlotCallback - localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, AvatarAction.ObjectDelete(guid)) + localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, ObjectDelete(guid)) case None => () } val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot))) @@ -692,7 +693,7 @@ object WorldSession { localGUID match { case Some(guid) => //see LockerContainerControl.RemoveItemFromSlotCallback - localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, AvatarAction.ObjectDelete(guid)) + localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, ObjectDelete(guid)) case None => () } val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot))) diff --git a/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/src/main/scala/net/psforever/objects/BoomerDeployable.scala index 60d2c8fbb..3d9c9ade7 100644 --- a/src/main/scala/net/psforever/objects/BoomerDeployable.scala +++ b/src/main/scala/net/psforever/objects/BoomerDeployable.scala @@ -11,7 +11,8 @@ import net.psforever.objects.vital.Vitality import net.psforever.objects.vital.etc.TriggerUsedReason import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.zones.Zone -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.ObjectDelete import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideEmpire @@ -108,7 +109,7 @@ class BoomerDeployableControl(mine: BoomerDeployable) } zone.AvatarEvents! AvatarServiceMessage( zone.id, - AvatarAction.ObjectDelete(guid) + ObjectDelete(guid) ) TaskWorkflow.execute(GUIDTask.unregisterObject(zone.GUID, trigger)) case None => () diff --git a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala index d1088a9bf..1e7f1835c 100644 --- a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala @@ -12,7 +12,8 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, TurretSource} import net.psforever.objects.vital.{DismountingActivity, InGameActivity, MountingActivity, ShieldCharge} import net.psforever.packet.game.HackState1 -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.vehicle.VehicleServiceMessage import scala.annotation.unused @@ -99,7 +100,7 @@ class FieldTurretControl(turret: TurretDeployable) turret.Shields = turret.Shields + amount turret.Zone.VehicleEvents ! VehicleServiceMessage( s"${turret.Actor}", - VehicleAction.PlanetsideAttribute(turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields) + PlanetsideAttribute(turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields) ) } } diff --git a/src/main/scala/net/psforever/objects/Players.scala b/src/main/scala/net/psforever/objects/Players.scala index c36d0e3fa..85a3301a6 100644 --- a/src/main/scala/net/psforever/objects/Players.scala +++ b/src/main/scala/net/psforever/objects/Players.scala @@ -21,6 +21,7 @@ import net.psforever.packet.game._ import net.psforever.types.{ChatMessageType, ExoSuitType, PlanetSideGUID, Vector3} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{ObjectDelete, SendResponse} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import scala.annotation.tailrec @@ -50,7 +51,7 @@ object Players { val uname = user.Name events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse(RepairMessage(target.GUID, progress.toInt)) + SendResponse(RepairMessage(target.GUID, progress.toInt)) ) true } else { @@ -77,7 +78,7 @@ object Players { target.Zone, medicName, Service.defaultPlayerGUID, - AvatarAction.SendResponse( + SendResponse( InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine) ) ) @@ -347,7 +348,7 @@ object Players { */ def buildCooldownReset(zone: Zone, channel: String, guid: PlanetSideGUID): Unit = { //sent to avatar event bus to preempt additional tool management - zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.SendResponse(GenericObjectActionMessage(guid, 21))) + zone.AvatarEvents ! AvatarServiceMessage(channel, SendResponse(GenericObjectActionMessage(guid, 21))) } /** @@ -403,7 +404,7 @@ object Players { } }) { val zone = player.Zone - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(tool.GUID)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, ObjectDelete(tool.GUID)) true } else { false @@ -449,7 +450,7 @@ object Players { obj.AmmoTypeIndex = ammoType events ! AvatarServiceMessage( name, - AvatarAction.SendResponse(ChangeAmmoMessage(obj.GUID, ammoType)) + SendResponse(ChangeAmmoMessage(obj.GUID, ammoType)) ) } if (player.DrawnSlot == Player.HandsDownSlot) { diff --git a/src/main/scala/net/psforever/objects/SensorDeployable.scala b/src/main/scala/net/psforever/objects/SensorDeployable.scala index b3a2fad81..113aad232 100644 --- a/src/main/scala/net/psforever/objects/SensorDeployable.scala +++ b/src/main/scala/net/psforever/objects/SensorDeployable.scala @@ -13,9 +13,9 @@ import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.SimpleResolutions import net.psforever.objects.vital.interaction.DamageResult import net.psforever.types.{PlanetSideGUID, Vector3} -import net.psforever.services.Service +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleServiceMessage import scala.annotation.unused import scala.concurrent.duration._ @@ -77,7 +77,7 @@ class SensorDeployableControl(sensor: SensorDeployable) case obj: PlanetSideServerObject if !jammedSound => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 54, 1) + PlanetsideAttribute(obj.GUID, 54, 1) ) super.StartJammeredSound(obj, dur) case _ => ; @@ -101,7 +101,7 @@ class SensorDeployableControl(sensor: SensorDeployable) val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 54, 0) + PlanetsideAttribute(obj.GUID, 54, 0) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala index f6247f13f..3d84b6df9 100644 --- a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala +++ b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala @@ -13,8 +13,9 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.resolution.ResolutionCalculations +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.types.PlanetSideGUID -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleServiceMessage class ShieldGeneratorDeployable(cdef: ShieldGeneratorDefinition) extends Deployable(cdef) @@ -126,7 +127,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) case obj: PlanetSideServerObject with JammableUnit => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 27, 1) + PlanetsideAttribute(obj.GUID, 27, 1) ) super.StartJammeredStatus(obj, dur) case _ => ; @@ -139,7 +140,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) case obj: PlanetSideServerObject with JammableUnit if obj.Jammed => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 27, 0) + PlanetsideAttribute(obj.GUID, 27, 0) ) case _ => ; } @@ -161,7 +162,7 @@ object ShieldGeneratorControl { val zone = target.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(target.GUID, 68, target.Shields) + PlanetsideAttribute(target.GUID, 68, target.Shields) ) } } diff --git a/src/main/scala/net/psforever/objects/Tools.scala b/src/main/scala/net/psforever/objects/Tools.scala index 2a10cff8b..846e9089a 100644 --- a/src/main/scala/net/psforever/objects/Tools.scala +++ b/src/main/scala/net/psforever/objects/Tools.scala @@ -3,7 +3,8 @@ package net.psforever.objects import net.psforever.objects.equipment.ChargeFireModeDefinition import net.psforever.packet.game.QuantityUpdateMessage -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.SendResponse object Tools { /** @@ -23,7 +24,7 @@ object Tools { val magazine = tool.Magazine -= mode.RoundsPerInterval player.Zone.AvatarEvents ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse(QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine)) + SendResponse(QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine)) ) player.isAlive case _ => diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 5db132936..88dd99c1d 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -14,6 +14,7 @@ import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObje import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{GenericObjectAction, SendResponse, SetEmpire} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -254,7 +255,7 @@ object Vehicles { val previousOwnerName = target.OwnerName.getOrElse("") vehicleEvents ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse(HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8)) + SendResponse(HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8)) ) target.Actor ! CommonMessages.Hack(hacker, target) // Forcefully dismount any cargo @@ -280,15 +281,15 @@ object Vehicles { zone.LocalEvents ! LocalServiceMessage( zoneid, PlanetSideGUID(-1), - LocalAction.GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown) + GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown.id) ) zone.LocalEvents ! LocalServiceMessage( zoneid, - LocalAction.SendResponse( + SendResponse( FrameVehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), unk2=false, 0, 0, is_crouched=true, is_airborne=false, ascending_flight=false, 10, 0, 0))) zone.LocalEvents ! LocalServiceMessage( zoneid, - LocalAction.SendResponse( + SendResponse( VehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), None, 0, 0, 15, is_decelerating=false, is_cloaked=false))) } }) @@ -316,7 +317,7 @@ object Vehicles { // And broadcast the faction change to other clients zone.AvatarEvents ! AvatarServiceMessage( zoneid, - AvatarAction.SetEmpire(tGuid, hFaction) + SetEmpire(tGuid, hFaction) ) } localEvents ! LocalServiceMessage( @@ -327,12 +328,12 @@ object Vehicles { if (zone.Players.exists(_.name.equals(previousOwnerName))) { localEvents ! LocalServiceMessage( previousOwnerName, - LocalAction.SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen")) + SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen")) ) } localEvents ! LocalServiceMessage( hacker.Name, - LocalAction.SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned")) + SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned")) ) // Clean up after specific vehicles, e.g. remove router telepads // If AMS is deployed, swap it to the new faction @@ -350,7 +351,7 @@ object Vehicles { } vehicleEvents ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse(HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8)) + SendResponse(HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8)) ) target.Actor ! CommonMessages.ClearHack() } diff --git a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala index e8ba49f2d..99d1d38ba 100644 --- a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala @@ -8,7 +8,8 @@ import net.psforever.objects.serverobject.containable.{Containable, ContainableB import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types.{PlanetSideEmpire, Vector3} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{ObjectDelete, SendResponse} class CorpseControl(player: Player) extends Actor with ContainableBehavior { def ContainerObject = player @@ -26,7 +27,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { case Some(slot) => obj.Zone.AvatarEvents ! AvatarServiceMessage( player.Zone.id, - AvatarAction.SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) + SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) case None => ; } @@ -39,7 +40,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val zone = obj.Zone val events = zone.AvatarEvents item.Faction = PlanetSideEmpire.NEUTRAL - events ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(item.GUID)) + events ! AvatarServiceMessage(zone.id, ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -49,7 +50,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val definition = item.Definition events ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse( + SendResponse( ObjectCreateDetailedMessage( definition.ObjectId, item.GUID, @@ -65,7 +66,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val zone = obj.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse(ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f)) + SendResponse(ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f)) ) } } diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 812abd18c..860994d03 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -37,6 +37,7 @@ import net.psforever.objects.vital.etc.{PainboxReason, SuicideReason} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.PlanetSideGamePacket import net.psforever.services.base.EventMessage +import net.psforever.services.base.messages.{HintsAtAttacker, ObjectDelete, PlanetsideAttribute, SendResponse} import org.joda.time.{LocalDateTime, Seconds} import scala.concurrent.duration._ @@ -150,7 +151,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val magazine = item.Discharge() events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) + SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) player.LogActivity( @@ -176,7 +177,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //progress bar remains visible for all heal attempts events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse(RepairMessage(guid, player.Health * 100 / definition.MaxHealth)) + SendResponse(RepairMessage(guid, player.Health * 100 / definition.MaxHealth)) ) } } @@ -216,7 +217,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val magazine = item.Discharge() events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) + SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(4, player.Armor)) player.LogActivity( @@ -247,7 +248,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //progress bar remains visible for all repair attempts events ! AvatarServiceMessage( uname, - AvatarAction.SendResponse(RepairMessage(guid, player.Armor * 100 / player.MaxArmor)) + SendResponse(RepairMessage(guid, player.Armor * 100 / player.MaxArmor)) ) } } @@ -359,7 +360,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm events ! AvatarServiceMessage( Players.ZoneChannelIfSpectating(player), unholsteredItem.GUID, - AvatarAction.PlanetsideAttribute(116, player.avatar.hackingSkillLevel()) + PlanetsideAttribute(unholsteredItem.GUID, 116, player.avatar.hackingSkillLevel()) ) } case None => () @@ -374,7 +375,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm player.Zone.LocalEvents ! LocalServiceMessage( s"${player.Faction}", PlanetSideGUID(-1), - LocalAction.SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) + SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) ) } case None => @@ -578,7 +579,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (reason.startsWith("@")) { player.Zone.AvatarEvents ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, reason)) + SendResponse(ChatMsg(ChatMessageType.UNK_227, reason)) ) } @@ -596,7 +597,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val trigger = new BoomerTrigger trigger.Companion = obj.GUID obj.Trigger = trigger - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(tool.GUID)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, ObjectDelete(tool.GUID)) TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, tool)) player.Find(tool) match { case Some(index) if player.VisibleSlots.contains(index) => @@ -954,7 +955,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (aggravated) { events ! AvatarServiceMessage( zoneId, - AvatarAction.SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) + SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) ) } else { //activity on map @@ -970,18 +971,18 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm zone.AvatarEvents ! AvatarServiceMessage( target.Name, target.GUID, - AvatarAction.HitHint(tplayer.GUID) + HintsAtAttacker(tplayer.GUID) ) case None => zone.AvatarEvents ! AvatarServiceMessage( target.Name, - AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) + SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) ) } case source => zone.AvatarEvents ! AvatarServiceMessage( target.Name, - AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) + SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) ) } case None => @@ -994,7 +995,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case _: CollisionReason => events ! AvatarServiceMessage( zoneId, - AvatarAction.SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) + SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) ) case _ => zone.AvatarEvents ! AvatarServiceMessage( @@ -1062,7 +1063,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val attribute = DamageableEntity.attributionTo(cause, target.Zone, player_guid) events ! AvatarServiceMessage( nameChannel, - AvatarAction.SendResponse(DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos)) //how many players get this message? + SendResponse(DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos)) //how many players get this message? ) } @@ -1176,7 +1177,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (slot == obj.DrawnSlot) { obj.DrawnSlot = Player.HandsDownSlot } - events ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(item.GUID)) + events ! AvatarServiceMessage(toChannel, ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -1199,7 +1200,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (!deployables.Contains(obj) && deployables.Valid(obj)) { events ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse(GenericObjectAction2Message(1, player.GUID, trigger.GUID)) + SendResponse(GenericObjectAction2Message(1, player.GUID, trigger.GUID)) ) Players.gainDeployableOwnership(player, obj, deployables.AddOverLimit) } @@ -1218,7 +1219,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } events ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse(OCM.detailed(item, ObjectCreateMessageParent(guid, slot))) + SendResponse(OCM.detailed(item, ObjectCreateMessageParent(guid, slot))) ) if (!player.isBackpack && willBeVisible) { events ! AvatarServiceMessage(zone.id, guid, AvatarAction.EquipmentInHand(guid, slot, item)) @@ -1237,7 +1238,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.ObjectDelete(item.GUID) + ObjectDelete(item.GUID) ) } @@ -1275,7 +1276,7 @@ object PlayerControl { } def sendResponse(zone: Zone, channel: String, msg: PlanetSideGamePacket): Unit = { - zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.SendResponse(msg)) + zone.AvatarEvents ! AvatarServiceMessage(channel, SendResponse(msg)) } def sendResponse(zone: Zone, channel: String, filter: PlanetSideGUID, msg: EventMessage): Unit = { diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala index 2d2b3f038..8e453f38e 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala @@ -6,6 +6,7 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.serverobject.environment.interaction.{InteractionWith, RespondsToZoneEnvironment} import net.psforever.objects.serverobject.interior.{Sidedness, TraditionalInteriorAware} import net.psforever.objects.zones.interaction.InteractsWithZone +import net.psforever.services.base.messages.SendResponse import net.psforever.types.Vector3 import scala.annotation.unused @@ -90,7 +91,7 @@ class WithEntrance() ): Sidedness = { import net.psforever.objects.{Player, Vehicle} import net.psforever.packet.game.ChatMsg - import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} + import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.types.ChatMessageType val channel = obj match { case p: Player => p.Name @@ -100,7 +101,7 @@ class WithEntrance() if (door.Outwards == Vector3.Zero) { obj.Zone.AvatarEvents ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_229, "Door not configured.")) + SendResponse(ChatMsg(ChatMessageType.UNK_229, "Door not configured.")) ) WhichSide } else { @@ -109,14 +110,14 @@ class WithEntrance() //outside obj.Zone.AvatarEvents ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now outside")) + SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now outside")) ) Sidedness.OutsideOf } else if (!result && WhichSide != Sidedness.InsideOf) { //inside obj.Zone.AvatarEvents ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now inside")) + SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now inside")) ) Sidedness.InsideOf } else { diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala index 62e84c2c4..40d6a1a15 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala @@ -7,7 +7,8 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.SendResponse import net.psforever.services.hart.ShuttleState import net.psforever.types.ChatMessageType @@ -36,10 +37,10 @@ class WithGantry(val channel: String) val events = shuttle.Zone.AvatarEvents events ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(PlayerStateShiftMessage(ShiftState(0, pos, ang, None)))) + SendResponse(PlayerStateShiftMessage(ShiftState(0, pos, ang, None)))) events ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway")) + SendResponse(ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway")) ) case (Some(_: Vehicle) , _)=> obj.Actor ! RespondsToZoneEnvironment.Timer( diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index d7227edd2..2bd35981d 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -7,7 +7,8 @@ import net.psforever.objects._ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.SetEmpire import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideEmpire @@ -284,7 +285,7 @@ object DeployableBehavior { //visual tells in regards to ownership by faction zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SetEmpire(dGuid, toFaction) + SetEmpire(dGuid, toFaction) ) //remove knowledge by the previous owner's faction localEvents ! LocalServiceMessage( diff --git a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala index ad018f418..8bf33f935 100644 --- a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala +++ b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala @@ -9,6 +9,7 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.Zone import net.psforever.packet.game.{GenericObjectActionMessage, ObjectCreateMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent +import net.psforever.services.base.messages.SendResponse import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID @@ -115,7 +116,7 @@ object TelepadLike { */ events ! LocalServiceMessage( zoneId, - LocalAction.SendResponse( + SendResponse( ObjectCreateMessage( udef.ObjectId, utilityGUID, @@ -124,28 +125,20 @@ object TelepadLike { ) ) ) - events ! LocalServiceMessage( - zoneId, - LocalAction.SendResponse(GenericObjectActionMessage(utilityGUID, 27)) - ) - events ! LocalServiceMessage( - zoneId, - LocalAction.SendResponse(GenericObjectActionMessage(utilityGUID, 30)) - ) + events ! LocalServiceMessage(zoneId, SendResponse(Seq( + GenericObjectActionMessage(utilityGUID, 27), + GenericObjectActionMessage(utilityGUID, 30) + ))) LinkTelepad(zone, utilityGUID) } def LinkTelepad(zone: Zone, telepadGUID: PlanetSideGUID): Unit = { val events = zone.LocalEvents val zoneId = zone.id - events ! LocalServiceMessage( - zoneId, - LocalAction.SendResponse(GenericObjectActionMessage(telepadGUID, 27)) - ) - events ! LocalServiceMessage( - zoneId, - LocalAction.SendResponse(GenericObjectActionMessage(telepadGUID, 28)) - ) + events ! LocalServiceMessage(zoneId, SendResponse(Seq( + GenericObjectActionMessage(telepadGUID, 27), + GenericObjectActionMessage(telepadGUID, 28) + ))) } def InitializeTelepadDeployable(zone: Zone, internal: InternalTelepad, pad: TelepadDeployable): Unit = { @@ -175,7 +168,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor { oldTpad.Actor ! TelepadLike.SeverLink(obj) } obj.Telepad = None - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendResponse(ObjectDeleteMessage(obj.GUID, 0))) + zone.LocalEvents ! LocalServiceMessage(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0))) case TelepadLike.RequestLink(tpad: TelepadDeployable) => val zone = obj.Zone @@ -204,7 +197,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor { if (obj.Telepad.contains(tpad.GUID)) { obj.Telepad = None val zone = obj.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendResponse(ObjectDeleteMessage(obj.GUID, 0))) + zone.LocalEvents ! LocalServiceMessage(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0))) } case _ => () diff --git a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala index faee62ec9..259d2ca34 100644 --- a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala +++ b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala @@ -10,7 +10,8 @@ import net.psforever.objects.vital.RepairFromArmorSiphon import net.psforever.objects.vital.etc.{ArmorSiphonModifiers, ArmorSiphonReason} import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.packet.game.QuantityUpdateMessage -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.PlanetSideGUID import scala.collection.mutable @@ -79,7 +80,7 @@ object ArmorSiphonBehavior { val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 0, after) + PlanetsideAttribute(obj.GUID, 0, after) ) } case _ => ; @@ -98,7 +99,7 @@ object ArmorSiphonBehavior { //update current charge level zone.VehicleEvents ! VehicleServiceMessage( obj.Actor.toString, - VehicleAction.SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine)) + SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine)) ) siphonRecharge.put(guid, context.system.scheduler.scheduleWithFixedDelay( initialDelay = 3000 milliseconds, @@ -120,7 +121,7 @@ object ArmorSiphonBehavior { if (after > before) { zone.VehicleEvents ! VehicleServiceMessage( obj.Actor.toString, - VehicleAction.SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after)) + SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after)) ) if (after == siphon.MaxMagazine) { endSiphonRecharge(guid) diff --git a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala index ed89d9ba2..727955fb6 100644 --- a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala +++ b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala @@ -8,8 +8,9 @@ import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.{Zone, ZoneAware} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.types.Vector3 -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleServiceMessage import scala.collection.mutable import scala.concurrent.duration._ @@ -244,7 +245,7 @@ trait JammableMountedWeapons extends JammableBehavior { case obj: PlanetSideServerObject with MountedWeapons with JammableUnit if !jammedSound => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 27, 1) + PlanetsideAttribute(obj.GUID, 27, 1) ) super.StartJammeredSound(target, dur) case _ => ; @@ -265,7 +266,7 @@ trait JammableMountedWeapons extends JammableBehavior { case obj: PlanetSideServerObject if jammedSound => obj.Zone.VehicleEvents ! VehicleServiceMessage( obj.Zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, 27, 0) + PlanetsideAttribute(obj.GUID, 27, 0) ) case _ => ; } @@ -309,7 +310,7 @@ object JammableMountedWeapons { target.Jammed = statusCode == 1 zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(target.GUID, 27, statusCode) + PlanetsideAttribute(target.GUID, 27, statusCode) ) } } diff --git a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala index c4f410be7..fcab05d63 100644 --- a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala +++ b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala @@ -6,7 +6,8 @@ import net.psforever.objects.equipment.Equipment import net.psforever.objects.serverobject.containable.{Containable, ContainableBehavior} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{ObjectDelete, SendResponse} import net.psforever.types.{PlanetSideEmpire, Vector3} /** @@ -35,7 +36,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) case Some(slot) => obj.Zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) + SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) case None => ; } @@ -45,7 +46,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) def RemoveItemFromSlotCallback(item: Equipment, slot: Int): Unit = { val zone = locker.Zone - zone.AvatarEvents ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(item.GUID)) + zone.AvatarEvents ! AvatarServiceMessage(toChannel, ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -54,7 +55,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) item.Faction = PlanetSideEmpire.NEUTRAL zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse( + SendResponse( ObjectCreateDetailedMessage( definition.ObjectId, item.GUID, @@ -69,7 +70,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) val zone = locker.Zone zone.AvatarEvents ! AvatarServiceMessage( toChannel, - AvatarAction.SendResponse(ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f)) + SendResponse(ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala index f016155ca..86777bf54 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala @@ -141,7 +141,7 @@ object DamageableEntity { * - alert the activity monitor for that `Zone` about the damage; and, * - provide a feedback message regarding the damage. * @see `AvatarAction.PlanetsideAttributeToAll` - * @see `AvatarAction.SendResponse` + * @see `SendResponse` * @see `AvatarServiceMessage` * @see `DamageFeedbackMessage` * @see `JammableUnit.Jammered` diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala index c6b82c496..73fe52c68 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala @@ -8,6 +8,7 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{HintsAtAttacker, SendResponse} /** * Functions to assist other damage-dealing code for objects that contain users. @@ -17,8 +18,8 @@ object DamageableMountable { /** * A damaged target alerts its occupants (as it is a `Mountable` object) of the source of the damage. * - * @see `AvatarAction.HitHint` - * @see `AvatarAction.SendResponse` + * @see `HitHint` + * @see `SendResponse` * @see `AvatarServiceMessage` * @see `DamageWithPositionMessage` * @see `Mountable.Seats` @@ -45,17 +46,17 @@ object DamageableMountable { val name = pSource.Name (zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match { case Some(player) => - AvatarAction.HitHint(player.GUID) + HintsAtAttacker(player.GUID) case None => - AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) + SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) }) match { - case AvatarAction.HitHint(guid) => - occupants.map { tplayer => (tplayer.Name, guid, AvatarAction.HitHint(tplayer.GUID)) } + case msg @ HintsAtAttacker(guid) => + occupants.map { tplayer => (tplayer.Name, guid, msg) } case msg => occupants.map { tplayer => (tplayer.Name, Service.defaultPlayerGUID, msg) } } case Some(source) => //object damage - val msg = AvatarAction.SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) + val msg = SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) occupants.map { tplayer => (tplayer.Name, Service.defaultPlayerGUID, msg) } case None => List.empty diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index 0f177da03..5ca796630 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -13,7 +13,8 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.Service -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.Vector3 import scala.concurrent.duration._ @@ -144,21 +145,21 @@ trait DamageableVehicle if (damageToShields > 0) { events ! VehicleServiceMessage( shieldChannel, - VehicleAction.PlanetsideAttribute(targetGUID, obj.Definition.shieldUiAttribute, obj.Shields) + PlanetsideAttribute(targetGUID, obj.Definition.shieldUiAttribute, obj.Shields) ) announceConfrontation = true } if (damageToHealth > 0) { events ! VehicleServiceMessage( healthChannel, - VehicleAction.PlanetsideAttribute(targetGUID, 0, obj.Health) + PlanetsideAttribute(targetGUID, 0, obj.Health) ) announceConfrontation = true } } if (announceConfrontation) { if (showAsAggravated) { - val msg = VehicleAction.SendResponse(DamageWithPositionMessage(totalDamage, Vector3.Zero)) + val msg = SendResponse(DamageWithPositionMessage(totalDamage, Vector3.Zero)) obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } .foreach { channel => @@ -219,7 +220,7 @@ trait DamageableVehicle obj.Shields = 0 zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(target.GUID, obj.Definition.shieldUiAttribute, 0) + PlanetsideAttribute(target.GUID, obj.Definition.shieldUiAttribute, 0) ) } //database entry @@ -252,13 +253,13 @@ trait DamageableVehicle val guid = obj.GUID events ! VehicleServiceMessage( zoneid, - VehicleAction.PlanetsideAttribute(guid, 0, 1) + PlanetsideAttribute(guid, 0, 1) ) if (obj.Shields > 0) { obj.Shields = 0 zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(obj.GUID, obj.Definition.shieldUiAttribute, 0) + PlanetsideAttribute(obj.GUID, obj.Definition.shieldUiAttribute, 0) ) } //aggravation cancel diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index b901fb193..595d8eb40 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -9,10 +9,11 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types.Vector3 -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.base.support.SupportActor import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.{TurretMessage, VehicleServiceMessage} /** * The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects. @@ -64,14 +65,14 @@ trait DamageableWeaponTurret DamageableMountable.DamageAwareness(DamageableObject, cause, damageToHealth) events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(targetGUID, 0, obj.Health) + PlanetsideAttribute(targetGUID, 0, obj.Health) ) announceConfrontation = true } } if (announceConfrontation) { if (aggravated) { - val msg = VehicleAction.SendResponse(DamageWithPositionMessage(damageToHealth, Vector3.Zero)) + val msg = SendResponse(DamageWithPositionMessage(damageToHealth, Vector3.Zero)) obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } .foreach { channel => @@ -131,7 +132,7 @@ object DamageableWeaponTurret { } .foreach(slot => { val wep = slot.Equipment.get - avatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.ObjectDelete(wep.GUID)) + avatarEvents ! AvatarServiceMessage(zoneId, ObjectDelete(wep.GUID)) }) target match { case turret: WeaponTurret => diff --git a/src/main/scala/net/psforever/objects/serverobject/doors/Door.scala b/src/main/scala/net/psforever/objects/serverobject/doors/Door.scala index eb90ed91d..9d8d635ee 100644 --- a/src/main/scala/net/psforever/objects/serverobject/doors/Door.scala +++ b/src/main/scala/net/psforever/objects/serverobject/doors/Door.scala @@ -67,37 +67,10 @@ object Door { */ sealed trait Exchange - /** - * Message that carries the result of the processed request message back to the original user (`player`). - * @param player the player who sent this request message - * @param msg the original packet carrying the request - * @param response the result of the processed request - */ - final case class DoorMessage(player: Player, msg: UseItemMessage, response: Exchange) - - /** - * This door will open. - */ - final case class OpenEvent() extends Exchange - - /** - * This door will close. - */ - final case class CloseEvent() extends Exchange - - /** - * This door will do nothing. - */ - final case class NoEvent() extends Exchange - type LockingMechanismLogic = (PlanetSideServerObject, Door) => Boolean final case class UpdateMechanism(mechanism: LockingMechanismLogic) extends Exchange - case object Lock extends Exchange - - case object Unlock extends Exchange - /** * Overloaded constructor. * @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields diff --git a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala index 93db203e1..e9997872e 100644 --- a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala @@ -8,7 +8,9 @@ import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffi import net.psforever.objects.serverobject.locks.IFFLock import net.psforever.objects.serverobject.structures.PoweredAmenityControl import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalServiceMessage, LocalServiceResponse} +import net.psforever.services.base.support.SupportActor +import net.psforever.services.local.support.DoorCloseActor +import net.psforever.services.local.{DoorMessage, LocalAction, LocalServiceResponse} /** * An `Actor` that handles messages being dispatched to a specific `Door`. @@ -19,24 +21,21 @@ class DoorControl(door: Door) with FactionAffinityBehavior.Check { def FactionObject: FactionAffinity = door - private var isLocked: Boolean = false private var lockingMechanism: Door.LockingMechanismLogic = DoorControl.alwaysOpen def commonBehavior: Receive = checkBehavior .orElse { - case Door.Lock => - isLocked = true + case Door.UpdateMechanism(logic) => + lockingMechanism = logic if (door.isOpen) { val zone = door.Zone door.Open = None - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.DoorSlamsShut(door)) + zone.LocalEvents ! DoorMessage( + zone.id, + LocalAction.DoorCloses(door.GUID), + SupportActor.ClearSpecific(List(door), zone) + ) } - - case Door.Unlock => - isLocked = false - - case Door.UpdateMechanism(logic) => - lockingMechanism = logic } def poweredStateLogic: Receive = @@ -48,7 +47,7 @@ class DoorControl(door: Door) case CommonMessages.Use(player, _) => testToOpenDoor(player, door, door.Definition.initialOpeningDistance, sender()) - case IFFLock.DoorOpenResponse(target: Player) if !isLocked => + case IFFLock.DoorOpenResponse(target: Player) => DoorControl.openDoor(target, door) case _ => () @@ -57,7 +56,7 @@ class DoorControl(door: Door) def unpoweredStateLogic: Receive = { commonBehavior .orElse { - case CommonMessages.Use(player, _) if !isLocked => + case CommonMessages.Use(player, _) => //without power, the door opens freely DoorControl.openDoor(player, door) @@ -83,7 +82,7 @@ class DoorControl(door: Door) ): Unit = { if ( Doors.testForSpecificTargetHoldingDoorOpen(player, door, maximumDistance * maximumDistance).contains(player) && - lockingMechanism(player, door) && !isLocked + lockingMechanism(player, door) ) { DoorControl.openDoor(player, door, replyTo) } @@ -110,9 +109,10 @@ object DoorControl { if (!door.isOpen) { //global open door.Open = player - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! DoorMessage( zone.id, - LocalAction.DoorOpens(zone, door) + LocalAction.DoorOpens(zone, door), + DoorCloseActor.DoorIsOpen(door, zone, System.currentTimeMillis()) ) } else { //the door should already open, but the requesting player does not see it as open diff --git a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala index 824c17a01..6d6e469a7 100644 --- a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala @@ -13,7 +13,8 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.TriggerEffectMessage import net.psforever.types.{PlanetSideGeneratorState, Vector3} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.SendResponse import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global @@ -112,7 +113,7 @@ class GeneratorControl(gen: Generator) //kaboom zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SendResponse(TriggerEffectMessage(gen.GUID, "explosion_generator", None, None)) + SendResponse(TriggerEffectMessage(gen.GUID, "explosion_generator", None, None)) ) queuedExplosion.cancel() queuedExplosion = Default.Cancellable diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index fa80748ae..07a3138ea 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -11,9 +11,10 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.SendResponse import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.{ClearMessage, HackEntityMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.{HackClearMessage, HackEntityMessage, LocalAction, LocalServiceMessage} import scala.annotation.unused import scala.util.{Failure, Success} @@ -90,7 +91,7 @@ object GenericHackables { } target.Zone.AvatarEvents ! AvatarServiceMessage( hacker.Name, - AvatarAction.SendResponse( + SendResponse( HackMessage(progressType, target.GUID, hacker.GUID, progressGrade, 0L, progressState, HackState7.Unk8) ) ) @@ -179,7 +180,7 @@ object GenericHackables { zone.LocalEvents ! HackEntityMessage( zoneId, pguid, - LocalAction.HackTemporarily(zone, target, hackValue, hackClearValue, duration), + LocalAction.HackObject(target.GUID, hackValue, HackState7.Unk8), HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, duration) ) case Failure(_) => @@ -205,19 +206,19 @@ object GenericHackables { val currVirus = building.virusId building.virusId = 8 building.virusInstalledBy = None - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(target)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(target)) zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 60)) + SendResponse(GenericObjectActionMessage(target.GUID, 60)) ) currVirus match { case 0L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff => - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(iff)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(iff)) } case 4L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term => - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) } case _ => () } @@ -231,13 +232,13 @@ object GenericHackables { case 0L => if (virus != 0) { building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff => - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(iff)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(iff)) } } case 4L => if (virus != 4) { building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term => - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) } } case _ => () @@ -268,16 +269,16 @@ object GenericHackables { zone.LocalEvents ! HackEntityMessage( zoneId, pguid, - LocalAction.HackTemporarily(zone, target, installedVirusDuration, hackClearValue, installedVirusDuration, unk2=hackState), + LocalAction.HackObject(target.GUID, installedVirusDuration.toLong, hackState), HackClearActor.ObjectIsHacked(target, zone, hackClearValue, hackState, installedVirusDuration) ) zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 61)) + SendResponse(GenericObjectActionMessage(target.GUID, 61)) ) zone.LocalEvents ! LocalServiceMessage( zone.id, - LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 58)) + SendResponse(GenericObjectActionMessage(target.GUID, 58)) ) //amenities if applicable virus match { @@ -287,7 +288,7 @@ object GenericHackables { zone.LocalEvents ! HackEntityMessage( zoneId, pguid, - LocalAction.HackTemporarily(zone, iff, hackValue, hackClearValue, installedVirusDuration), + LocalAction.HackObject(target.GUID, hackValue.toLong, HackState7.Unk8), HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, installedVirusDuration) ) } @@ -297,7 +298,7 @@ object GenericHackables { zone.LocalEvents ! HackEntityMessage( zoneId, pguid, - LocalAction.HackTemporarily(zone, term, hackValue, hackClearValue, installedVirusDuration), + LocalAction.HackObject(term.GUID, hackValue.toLong, HackState7.Unk8), HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, installedVirusDuration) ) } diff --git a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala index 35f833ac6..6404445f4 100644 --- a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala +++ b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala @@ -2,7 +2,7 @@ package net.psforever.objects.serverobject.locks import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.ClearMessage +import net.psforever.services.local.HackClearMessage object IFFLocks { @@ -14,6 +14,6 @@ object IFFLocks { */ def FinishResecuringIFFLock(lock: IFFLock)(): Unit = { val zone = lock.Zone - lock.Zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(lock)) + lock.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(lock)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala index a08939d98..a48d69cbd 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala @@ -5,7 +5,7 @@ import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.objects.{Player, Vehicle} import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.serverobject.terminals.Terminal -import net.psforever.services.base.SelfResponseMessage +import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID /** @@ -39,14 +39,14 @@ object VehicleSpawnPad { * @see `GenericObjectActionMessage` * @param player_guid the player */ - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage + final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent /** * Message is intended to undo the effects of the above message, `ConcealPlayer`. * @see `ConcealPlayer` * @param player_guid the player */ - final case class RevealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage + final case class RevealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent /** * Message to attach the vehicle to the spawn pad's lifting platform ("put on rails"). @@ -55,7 +55,7 @@ object VehicleSpawnPad { * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage + final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message to detach the vehicle from the spawn pad's lifting platform ("put on rails"). @@ -63,14 +63,14 @@ object VehicleSpawnPad { * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage + final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message that resets the spawn pad for its next order fulfillment operation by lowering the lifting platform. * @see `GenericObjectActionMessage` * @param pad the spawn pad */ - final case class ResetSpawnPad(pad: VehicleSpawnPad) extends SelfResponseMessage + final case class ResetSpawnPad(pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message that acts as callback to the driver that the process of sitting in the driver mount will be initiated soon. @@ -78,7 +78,7 @@ object VehicleSpawnPad { * @param vehicle the vehicle being spawned * @param pad the spawn pad */ - final case class StartPlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage + final case class StartPlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message that acts as callback to the driver that the process of sitting in the driver mount should be finished. @@ -87,7 +87,7 @@ object VehicleSpawnPad { * @param pad the spawn pad */ //TODO while using fake rails (later edit: what does this mean?) - final case class PlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage + final case class PlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message that starts the newly-spawned vehicle to begin driving away from the spawn pad. @@ -97,7 +97,7 @@ object VehicleSpawnPad { * @param vehicle the vehicle * @param pad the spawn pad */ - final case class ServerVehicleOverrideStart(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage + final case class ServerVehicleOverrideStart(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message that transitions the newly-spawned vehicle into a cancellable auto-drive state. @@ -107,20 +107,20 @@ object VehicleSpawnPad { * @param vehicle the vehicle * @param pad the spawn pad */ - final case class ServerVehicleOverrideEnd(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfResponseMessage + final case class ServerVehicleOverrideEnd(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent /** * Message to initiate the process of properly disposing of the vehicle that may have been or was spawned into the game world. * @param vehicle the vehicle */ - final case class DisposeVehicle(vehicle: Vehicle) extends SelfResponseMessage + final case class DisposeVehicle(vehicle: Vehicle) extends SelfRespondingEvent /** * Message to send targeted messages to the clients of specific users. * @param reason the nature of the message * @param data optional information for rendering the message to the client */ - final case class PeriodicReminder(reason: Reminders.Value, data: Option[Any] = None) extends SelfResponseMessage + final case class PeriodicReminder(reason: Reminders.Value, data: Option[Any] = None) extends SelfRespondingEvent /** * An `Enumeration` of reasons for sending a periodic reminder to the user. diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index 771c632b9..642ee6774 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -9,6 +9,7 @@ import net.psforever.objects.{Player, Tool} import net.psforever.packet.game.{ChatMsg, InventoryStateMessage, RepairMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.SendResponse /** * The "control" `Actor` mixin for repair-handling code, @@ -67,7 +68,7 @@ trait RepairableEntity extends Repairable { * Restore the target entity to a not destroyed state if applicable. * Always show the repair progress bar window by using the appropriate packet. * @see `AvatarAction.PlanetsideAttributeToAll` - * @see `AvatarAction.SendResponse` + * @see `SendResponse` * @see `AvatarService` * @see `InventoryStateMessage` * @see `PlanetSideGameObject.isMoving` @@ -90,7 +91,7 @@ trait RepairableEntity extends Repairable { val magazine = item.Discharge() events ! AvatarServiceMessage( player.Name, - AvatarAction.SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) + SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) target.LogActivity( RepairFromEquipment( @@ -106,7 +107,7 @@ trait RepairableEntity extends Repairable { //progress bar remains visible events ! AvatarServiceMessage( name, - AvatarAction.SendResponse(RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth)) + SendResponse(RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth)) ) //if vehicle and vehicle is owned by another player, send repair chat message to the vehicle's owner if (target.Zone.Vehicles.exists(_.GUID == target.GUID)) { diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index a3eff3c11..6d6ce69e3 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -12,7 +12,8 @@ import net.psforever.objects.{GlobalDefinitions, Ntu, NtuContainer, NtuStorageBe import net.psforever.types.{ExperienceType, PlanetSideEmpire} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.util.Config import scala.concurrent.ExecutionContext.Implicits.global @@ -109,7 +110,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) building.Zone.AvatarEvents ! AvatarServiceMessage( zone.id, building.GUID, - AvatarAction.PlanetsideAttribute(47, if (resourceSilo.LowNtuWarningOn) 1 else 0) + PlanetsideAttribute(building.GUID, 47, if (resourceSilo.LowNtuWarningOn) 1 else 0) ) } @@ -133,7 +134,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) zone.AvatarEvents ! AvatarServiceMessage( zone.id, resourceSilo.GUID, - AvatarAction.PlanetsideAttribute(45, resourceSilo.CapacitorDisplay) + PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay) ) building.Actor ! BuildingActor.MapUpdate() } @@ -233,7 +234,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val zone = resourceSilo.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(resourceSilo.GUID, 49, 1) + PlanetsideAttribute(resourceSilo.GUID, 49, 1) ) math.min(resourceSilo.MaxNtuCapacitor - currentlyHas, trigger) } else if (trigger < 0) { @@ -244,7 +245,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val zone = resourceSilo.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(resourceSilo.GUID, 49, 0) + PlanetsideAttribute(resourceSilo.GUID, 49, 0) ) 0 }) * 0.9f diff --git a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala index f1dc0404e..c15e723c9 100644 --- a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala @@ -8,8 +8,10 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.support.SupportActor +import net.psforever.services.local.{DoorMessage, LocalAction} import net.psforever.services.hart.{HartTimer, HartTimerActions} import net.psforever.services.{Service, ServiceManager} import net.psforever.types.ChatMessageType @@ -48,8 +50,13 @@ class OrbitalShuttlePadControl(pad: OrbitalShuttlePad) extends Actor { managedDoors.foreach { door => door.Actor ! Door.UpdateMechanism(OrbitalShuttlePadControl.lockedWaitingForShuttle) val zone = pad.Zone - if(door.isOpen) { - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.DoorSlamsShut(door)) + if (door.isOpen) { + door.Open = None + zone.LocalEvents ! DoorMessage( + zone.id, + LocalAction.DoorCloses(door.GUID), + SupportActor.ClearSpecific(List(door), zone) + ) } } @@ -175,7 +182,7 @@ object OrbitalShuttlePadControl { * Logic for door mechanism that keeps select doors shut when the shuttle is not ready for boarding. * A message flashes onscreen to explain this reason. * The message will not flash if the door has no expectation of ever opening for a user. - * @see `AvatarAction.SendResponse` + * @see `SendResponse` * @see `AvatarServiceMessage` * @see `ChatMessageType` * @see `ChatMsg` @@ -192,12 +199,12 @@ object OrbitalShuttlePadControl { case p: Player if p.Faction == door.Faction => zone.AvatarEvents ! AvatarServiceMessage( p.Name, - AvatarAction.SendResponse( + SendResponse( ChatMsg(ChatMessageType.UNK_225, wideContents=false, "", "@DoorWillOpenWhenShuttleReturns", None) ) ) p.Name - case _ => ; + case _ => () } false } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index 8871f5bc0..2680a70e1 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -4,6 +4,7 @@ package net.psforever.objects.serverobject.structures.participation import net.psforever.objects.Player import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.UniquePlayer +import net.psforever.services.base.messages.GenericObjectAction import net.psforever.types.{PlanetSideEmpire, Vector3} import scala.collection.mutable @@ -106,10 +107,10 @@ trait FacilityHackParticipation extends ParticipationLogic { if (building.virusId != 8) { import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.objects.GlobalDefinitions - import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} + import net.psforever.services.avatar.AvatarServiceMessage val mainTerm = building.Amenities.filter(x => x.isInstanceOf[Terminal] && x.Definition == GlobalDefinitions.main_terminal).head.GUID - val msg1 = AvatarAction.GenericObjectAction(mainTerm, 61) - val msg2 = AvatarAction.GenericObjectAction(mainTerm, 58) + val msg1 = GenericObjectAction(mainTerm, 61) + val msg2 = GenericObjectAction(mainTerm, 58) val events = building.Zone.AvatarEvents list.foreach { p => events ! AvatarServiceMessage(p.Name, msg1) diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala index 29fd9a7c3..eea512207 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala @@ -15,7 +15,8 @@ import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.ChatMsg -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.local.LocalServiceMessage import scala.collection.mutable import scala.concurrent.duration._ @@ -438,7 +439,7 @@ object MajorFacilityHackParticipation { msg: ChatMsg ): Unit = { val events = building.Zone.LocalEvents - val message = LocalAction.SendResponse(msg) + val message = SendResponse(msg) targets.foreach { player => events ! LocalServiceMessage(player.Name, message) } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index 3db74a369..6c6d40b35 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -6,7 +6,8 @@ import net.psforever.objects.serverobject.damage.Damageable import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 -import net.psforever.services.local.ClearMessage +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.local.HackClearMessage import net.psforever.services.local.support.HackClearActor import org.log4s.Logger @@ -28,7 +29,7 @@ import net.psforever.objects.zones.ZoneAware import net.psforever.packet.game.InventoryStateMessage import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleServiceMessage /** * An `Actor` that handles messages being dispatched to a specific `ProximityTerminal`. @@ -148,7 +149,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) tryAutoRepair() if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) } super.DestructionAwareness(target, cause) } @@ -225,7 +226,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) //clear hack state if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) } } @@ -378,7 +379,7 @@ object ProximityTerminalControl { val zone = target.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(target.GUID, 0, target.Health) + PlanetsideAttribute(target.GUID, 0, target.Health) ) } @@ -439,7 +440,7 @@ object ProximityTerminalControl { slots.foreach { slot => events ! AvatarServiceMessage( channel, - AvatarAction.SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) + SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) } } @@ -465,7 +466,7 @@ object ProximityTerminalControl { slots.foreach { slot => events ! VehicleServiceMessage( channel, - VehicleAction.SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) + SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala index 20608652d..46d124b81 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala @@ -13,7 +13,7 @@ import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityCo import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.ClearMessage +import net.psforever.services.local.HackClearMessage /** * An `Actor` that handles messages being dispatched to a specific `Terminal`. @@ -100,7 +100,7 @@ class TerminalControl(term: Terminal) tryAutoRepair() if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) } super.DestructionAwareness(target, cause) } @@ -122,7 +122,7 @@ class TerminalControl(term: Terminal) //clear hack state if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! ClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala index 04cab01a4..efddb12cb 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala @@ -16,7 +16,8 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.objects.{GlobalDefinitions, Player, SimpleItem} import net.psforever.packet.game.HackState1 -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.SetEmpire +import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} @@ -173,7 +174,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) if (player.Faction == localFaction) { if (mech.Owner.asInstanceOf[Building].CaptureTerminalIsHacked) { //this is actually futile, as a hacked base does not grant access to the terminal - events ! LocalServiceMessage(localFaction.toString, LocalAction.SetEmpire(guid, localFaction)) + events ! LocalServiceMessage(localFaction.toString, SetEmpire(guid, localFaction)) } kickAllOccupantsNotOfFaction(zone, guid, mech, localFaction) } else { @@ -225,7 +226,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) ): Unit = { val events = zone.LocalEvents opposingFactionsAre(setToFaction).foreach { faction => - events ! LocalServiceMessage(faction.toString, LocalAction.SetEmpire(guid, faction)) + events ! LocalServiceMessage(faction.toString, SetEmpire(guid, faction)) } } @@ -236,7 +237,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) ): Unit = { val events = zone.LocalEvents opposingFactionsAre(setToFaction).foreach { faction => - events ! LocalServiceMessage(faction.toString, LocalAction.SetEmpire(guid, setToFaction)) + events ! LocalServiceMessage(faction.toString, SetEmpire(guid, setToFaction)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index 75f2f1aee..c60458646 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -13,6 +13,7 @@ import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.{ChangeFireModeMessage, HackState1} +import net.psforever.services.base.messages.SendResponse import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideEmpire, PlanetSideGUID} @@ -238,7 +239,7 @@ class FacilityTurretControl(turret: FacilityTurret) weapon.FireModeIndex = 0 events ! VehicleServiceMessage( zoneid, - VehicleAction.SendResponse(ChangeFireModeMessage(weapon.GUID, 0)) + SendResponse(ChangeFireModeMessage(weapon.GUID, 0)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index 510fc7416..186122128 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -5,7 +5,8 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.ce.Deployable import net.psforever.objects.{Player, Tool, TurretDeployable} import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{SendResponse, SetEmpire} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} @@ -32,7 +33,7 @@ object WeaponTurrets { tool.Magazine = 0 target.Zone.AvatarEvents ! AvatarServiceMessage( user.Name, - AvatarAction.SendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0)) + SendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0)) ) FinishUpgradingMannedTurret(target, upgrade) } @@ -86,7 +87,7 @@ object WeaponTurrets { } turret.Zone.AvatarEvents ! AvatarServiceMessage( tplayer.Name, - AvatarAction.SendResponse( + SendResponse( HackMessage(progressType, turret.GUID, tplayer.GUID, progressGrade, -1f, progressState, HackState7.Unk8) ) ) @@ -117,7 +118,7 @@ object WeaponTurrets { //convert faction zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.SetEmpire(target.GUID, hacker.Faction) + SetEmpire(target.GUID, hacker.Faction) ) zone.LocalEvents ! LocalServiceMessage( zone.id, diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala index b9ef525ac..c8d073e4d 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala @@ -18,7 +18,8 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.objects.{Default, PlanetSideGameObject, Player} import net.psforever.packet.game.{ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ObjectDetectedMessage} import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{PlanetSideGUID, Vector3} import scala.concurrent.ExecutionContext.Implicits.global @@ -891,7 +892,7 @@ object AutomatedTurretBehavior { def startTracking(zone: Zone, channel: String, turretGuid: PlanetSideGUID, list: List[PlanetSideGUID]): Unit = { zone.LocalEvents ! LocalServiceMessage( channel, - LocalAction.SendResponse(ObjectDetectedMessage(turretGuid, turretGuid, 0, list)) + SendResponse(ObjectDetectedMessage(turretGuid, turretGuid, 0, list)) ) } @@ -904,7 +905,7 @@ object AutomatedTurretBehavior { def stopTracking(zone: Zone, channel: String, turretGuid: PlanetSideGUID): Unit = { zone.LocalEvents ! LocalServiceMessage( channel, - LocalAction.SendResponse(ObjectDetectedMessage(turretGuid, turretGuid, 0, noTargets)) + SendResponse(ObjectDetectedMessage(turretGuid, turretGuid, 0, noTargets)) ) } @@ -917,7 +918,7 @@ object AutomatedTurretBehavior { def startShooting(zone: Zone, channel: String, weaponGuid: PlanetSideGUID): Unit = { zone.LocalEvents ! LocalServiceMessage( channel, - LocalAction.SendResponse(ChangeFireStateMessage_Start(weaponGuid)) + SendResponse(ChangeFireStateMessage_Start(weaponGuid)) ) } @@ -930,7 +931,7 @@ object AutomatedTurretBehavior { def stopShooting(zone: Zone, channel: String, weaponGuid: PlanetSideGUID): Unit = { zone.LocalEvents ! LocalServiceMessage( channel, - LocalAction.SendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + SendResponse(ChangeFireStateMessage_Stop(weaponGuid)) ) } diff --git a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala index 1dd9643e9..16d74d1b8 100644 --- a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala @@ -10,9 +10,10 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} import net.psforever.objects.{NtuContainer, _} import net.psforever.types.DriveState -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleServiceMessage import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.serverobject.transfer.TransferContainer.TransferMaterial +import net.psforever.services.base.messages.PlanetsideAttribute import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -34,7 +35,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(vehicle.GUID, 52, 1L) + PlanetsideAttribute(vehicle.GUID, 52, 1L) ) // panel glow on } @@ -44,7 +45,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val zone = obj.Zone zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(vehicle.GUID, 49, 1L) + PlanetsideAttribute(vehicle.GUID, 49, 1L) ) // orb particle effect on } @@ -53,7 +54,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val display = vehicle.NtuCapacitorScaled.toLong vehicle.Zone.VehicleEvents ! VehicleServiceMessage( vehicle.Actor.toString, - VehicleAction.PlanetsideAttribute(vehicle.GUID, 45, display) + PlanetsideAttribute(vehicle.GUID, 45, display) ) } } @@ -159,16 +160,16 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { if (transferEvent == TransferBehavior.Event.Charging) { events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(vguid, 52, 0L) + PlanetsideAttribute(vguid, 52, 0L) ) // panel glow off events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(vguid, 49, 0L) + PlanetsideAttribute(vguid, 49, 0L) ) // orb particle effect off } else if (transferEvent == TransferBehavior.Event.Discharging) { events ! VehicleServiceMessage( zoneId, - VehicleAction.PlanetsideAttribute(vguid, 52, 0L) + PlanetsideAttribute(vguid, 52, 0L) ) // panel glow off } } diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala index 9883ea11e..1ae3c28ec 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala @@ -9,8 +9,9 @@ import net.psforever.objects.sourcing.VehicleSource import net.psforever.objects.vital.VehicleCargoMountActivity import net.psforever.packet.game.{CargoMountPointStatusMessage, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} import net.psforever.types.{BailType, CargoStatus, PlanetSideGUID, Vector3} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.Service +import net.psforever.services.base.messages.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.concurrent.duration._ @@ -60,7 +61,7 @@ trait CarrierBehavior { //open the cargo bay door obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Zone.id, - AvatarAction.SendResponse( + SendResponse( CargoMountPointStatusMessage( obj.GUID, PlanetSideGUID(0), @@ -205,14 +206,10 @@ object CarrierBehavior { log.debug(s"HandleCheckCargoMounting: mounting cargo vehicle in carrier at distance of $distance") CargoMountAction(carrier, cargo, hold, carrierGUID) cargo.Velocity = None - zone.VehicleEvents ! VehicleServiceMessage( - s"${cargo.Actor}", - VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health)) - ) - zone.VehicleEvents ! VehicleServiceMessage( - s"${cargo.Actor}", - VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields)) - ) + zone.VehicleEvents ! VehicleServiceMessage(s"${cargo.Actor}", SendResponse(Seq( + PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health), + PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields) + ))) CargoMountBehaviorForAll(carrier, cargo, mountPoint) zone.actor ! ZoneActor.RemoveFromBlockMap(cargo) false @@ -226,7 +223,7 @@ object CarrierBehavior { zone.VehicleEvents ! VehicleServiceMessage( zone.id, cargoDriverGUID, - VehicleAction.SendResponse(CargoMountPointStatusMessage( + SendResponse(CargoMountPointStatusMessage( carrierGUID, PlanetSideGUID(0), PlanetSideGUID(0), @@ -326,7 +323,7 @@ object CarrierBehavior { zone.VehicleEvents ! VehicleServiceMessage( zone.id, cargoDriverGUID, - VehicleAction.SendResponse(CargoMountPointStatusMessage( + SendResponse(CargoMountPointStatusMessage( carrierGUID, PlanetSideGUID(0), PlanetSideGUID(0), @@ -447,14 +444,10 @@ object CarrierBehavior { val zoneId = zone.id val events = zone.VehicleEvents val cargoActor = cargo.Actor - events ! VehicleServiceMessage( - s"$cargoActor", - VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health)) - ) - events ! VehicleServiceMessage( - s"$cargoActor", - VehicleAction.SendResponse(PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields)) - ) + events ! VehicleServiceMessage(s"$cargoActor", SendResponse(Seq( + PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health), + PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields) + ))) zone.actor ! ZoneActor.AddToBlockMap(cargo, carrier.Position) if (carrier.isFlying) { //the carrier vehicle is flying; eject the cargo vehicle @@ -463,9 +456,7 @@ object CarrierBehavior { val detachCargoMsg = ObjectDetachMessage(carrierGUID, cargoGUID, cargoHoldPosition - Vector3.z(1), rotation) val resetCargoMsg = CargoMountPointStatusMessage(carrierGUID, GUID0, GUID0, cargoGUID, mountPoint, CargoStatus.Empty, 0) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(ejectCargoMsg)) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(detachCargoMsg)) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(resetCargoMsg)) + events ! VehicleServiceMessage(zoneId, SendResponse(Seq(ejectCargoMsg, detachCargoMsg, resetCargoMsg))) log.debug(s"HandleVehicleCargoDismount: eject - $ejectCargoMsg, detach - $detachCargoMsg") if (driverOpt.isEmpty) { //TODO cargo should drop like a rock like normal; until then, deconstruct it @@ -478,8 +469,7 @@ object CarrierBehavior { CargoMountPointStatusMessage(carrierGUID, GUID0, cargoGUID, GUID0, mountPoint, CargoStatus.InProgress, 0) val cargoDetachMessage = ObjectDetachMessage(carrierGUID, cargoGUID, cargoHoldPosition + Vector3.z(1f), rotation) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(cargoStatusMessage)) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(cargoDetachMessage)) + events ! VehicleServiceMessage(zoneId, SendResponse(Seq(cargoStatusMessage, cargoDetachMessage))) driverOpt match { case Some(driver) => events ! VehicleServiceMessage( @@ -489,7 +479,7 @@ object CarrierBehavior { case None => val resetCargoMsg = CargoMountPointStatusMessage(carrierGUID, GUID0, GUID0, cargoGUID, mountPoint, CargoStatus.Empty, 0) - events ! VehicleServiceMessage(zoneId, VehicleAction.SendResponse(resetCargoMsg)) //lazy + events ! VehicleServiceMessage(zoneId, SendResponse(resetCargoMsg)) //lazy //TODO cargo should back out like normal; until then, deconstruct it cargoActor ! Vehicle.Deconstruct() } @@ -605,8 +595,7 @@ object CarrierBehavior { attachMessage: ObjectAttachMessage, mountPointStatusMessage: CargoMountPointStatusMessage ): Unit = { - zone.VehicleEvents ! VehicleServiceMessage(zone.id, exclude, VehicleAction.SendResponse(attachMessage)) - zone.VehicleEvents ! VehicleServiceMessage(zone.id, exclude, VehicleAction.SendResponse(mountPointStatusMessage)) + zone.VehicleEvents ! VehicleServiceMessage(zone.id, exclude, SendResponse(Seq(attachMessage, mountPointStatusMessage))) } /** @@ -626,14 +615,10 @@ object CarrierBehavior { val zone = carrier.Zone val zoneId = zone.id val msgs @ (attachMessage, mountPointStatusMessage) = CargoMountMessages(carrier, cargo, mountPoint) - zone.VehicleEvents ! VehicleServiceMessage( - zoneId, - VehicleAction.SendResponse(attachMessage) - ) - zone.VehicleEvents ! VehicleServiceMessage( - zoneId, - VehicleAction.SendResponse(mountPointStatusMessage) - ) + zone.VehicleEvents ! VehicleServiceMessage(zoneId, SendResponse(Seq( + attachMessage, + mountPointStatusMessage + ))) msgs } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala index d3d77a588..d86ff43d5 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala @@ -2,6 +2,7 @@ package net.psforever.objects.vehicles.control import net.psforever.objects._ +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.DriveState @@ -29,7 +30,7 @@ class AmsControl(vehicle: Vehicle) } val events = zone.VehicleEvents events ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) - events ! VehicleServiceMessage(driverChannel, VehicleAction.PlanetsideAttribute(vehicle.GUID, 81, 1)) + events ! VehicleServiceMessage(driverChannel, PlanetsideAttribute(vehicle.GUID, 81, 1)) case _ => ; } } @@ -49,7 +50,7 @@ class AmsControl(vehicle: Vehicle) } val events = zone.VehicleEvents events ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) - events ! VehicleServiceMessage(driverChannel, VehicleAction.PlanetsideAttribute(vehicle.GUID, 81, 0)) + events ! VehicleServiceMessage(driverChannel, PlanetsideAttribute(vehicle.GUID, 81, 0)) case _ => ; } } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala index c11dfa2d6..034006cbe 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala @@ -11,7 +11,8 @@ import net.psforever.objects.vital.prop.DamageWithPosition import net.psforever.objects.zones.Zone import net.psforever.packet.game.{TriggerEffectMessage, TriggeredEffectLocation} import net.psforever.services.Service -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.PlanetSideGUID /** @@ -54,7 +55,7 @@ class ApcControl(vehicle: Vehicle) //cause the emp events ! VehicleServiceMessage( zone.id, - VehicleAction.SendResponse(TriggerEffectMessage( + SendResponse(TriggerEffectMessage( GUID0, s"apc_explosion_emp_${faction.toString.toLowerCase}", None, diff --git a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala index b9f62726f..47782dc74 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala @@ -17,7 +17,8 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.services.Service -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.{GenericObjectAction, PlanetsideAttribute, SendResponse} +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types._ import scala.annotation.unused @@ -271,7 +272,7 @@ class BfrControl(vehicle: Vehicle) val zone = vehicle.Zone zone.VehicleEvents ! VehicleServiceMessage( s"${zone.id}", - VehicleAction.SendResponse(GenericObjectActionMessage(vehicle.GUID, 45)) + SendResponse(GenericObjectActionMessage(vehicle.GUID, 45)) ) } @@ -285,7 +286,7 @@ class BfrControl(vehicle: Vehicle) val zone = vehicle.Zone zone.VehicleEvents ! VehicleServiceMessage( s"${zone.id}", - VehicleAction.SendResponse(GenericObjectActionMessage(vehicle.GUID, 44)) + SendResponse(GenericObjectActionMessage(vehicle.GUID, 44)) ) } @@ -336,7 +337,7 @@ class BfrControl(vehicle: Vehicle) val shields = vehicle.Shields zone.VehicleEvents ! VehicleServiceMessage( zone.id, - VehicleAction.PlanetsideAttribute(vguid, vehicle.Definition.shieldUiAttribute, shields) + PlanetsideAttribute(vguid, vehicle.Definition.shieldUiAttribute, shields) ) } @@ -417,7 +418,7 @@ class BfrControl(vehicle: Vehicle) zone.VehicleEvents ! VehicleServiceMessage( zone.id, doNotSendTo, - VehicleAction.GenericObjectAction(useThisGuid, action) + GenericObjectAction(useThisGuid, action) ) case _ => () } @@ -566,7 +567,7 @@ class BfrControl(vehicle: Vehicle) //TODO this is the apc emp effect; is there an ntu siphon emp effect? events ! VehicleServiceMessage( zone.id, - VehicleAction.SendResponse(TriggerEffectMessage( + SendResponse(TriggerEffectMessage( GUID0, s"apc_explosion_emp_${faction.toString.toLowerCase}", None, @@ -588,7 +589,7 @@ class BfrControl(vehicle: Vehicle) //it does not even dispatch the packet before that, making it rare if this precautionary message is seen events ! VehicleServiceMessage( obj.Seats(0).occupant.get.Name, - VehicleAction.SendResponse(ChatMsg(ChatMessageType.UNK_225, wideContents = false, "", s"@TimeUntilNextUse^${30000 - elapsedWait}", None)) + SendResponse(ChatMsg(ChatMessageType.UNK_225, wideContents = false, "", s"@TimeUntilNextUse^${30000 - elapsedWait}", None)) ) } case _ => () diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala index 4c54fce31..27201cb64 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala @@ -3,7 +3,8 @@ package net.psforever.objects.vehicles.control import akka.actor.{Actor, Cancellable} import net.psforever.objects._ -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.vehicle.VehicleServiceMessage import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -60,7 +61,7 @@ trait VehicleCapacitance { val obj = CapacitanceObject obj.Zone.VehicleEvents ! VehicleServiceMessage( self.toString(), - VehicleAction.PlanetsideAttribute(obj.GUID, 113, obj.Capacitor) + PlanetsideAttribute(obj.GUID, 113, obj.Capacitor) ) } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index a32836c17..b1aed1796 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -36,8 +36,8 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game._ import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types._ -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.annotation.unused @@ -204,8 +204,7 @@ class VehicleControl(vehicle: Vehicle) case Vehicle.UpdateSubsystemStates(toChannel, stateToResolve) => val events = vehicle.Zone.VehicleEvents - val guid0 = Service.defaultPlayerGUID - (stateToResolve match { + val pkts = (stateToResolve match { case Some(state) => vehicle.Subsystems().filter { _.Enabled == state } //only subsystems that are enabled or are disabled case None => @@ -213,7 +212,7 @@ class VehicleControl(vehicle: Vehicle) }) .flatMap { _.getMessage(vehicle) } .foreach { pkt => - events ! VehicleServiceMessage(toChannel, VehicleAction.SendResponse(pkt)) + events ! VehicleServiceMessage(toChannel, SendResponse(pkt)) } case FactionAffinity.ConvertFactionAffinity(faction) => @@ -523,7 +522,7 @@ class VehicleControl(vehicle: Vehicle) case Some(slot) => obj.Zone.AvatarEvents ! AvatarServiceMessage( self.toString, - AvatarAction.SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) + SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) case None => () } @@ -550,7 +549,7 @@ class VehicleControl(vehicle: Vehicle) events ! VehicleServiceMessage( //TODO when a new weapon, the equipment slot ui goes blank, but the weapon functions; remount vehicle to correct it if (obj.VisibleSlots.contains(slot)) zone.id else channel, - VehicleAction.SendResponse(OCM.detailed(item, ObjectCreateMessageParent(oguid, slot))) + SendResponse(OCM.detailed(item, ObjectCreateMessageParent(oguid, slot))) ) item match { case box: AmmoBox => @@ -575,7 +574,7 @@ class VehicleControl(vehicle: Vehicle) val toChannel = if (obj.VisibleSlots.contains(fromSlot)) zone.id else self.toString zone.VehicleEvents ! VehicleServiceMessage( toChannel, - VehicleAction.ObjectDelete(item.GUID) + ObjectDelete(item.GUID) ) } @@ -638,7 +637,7 @@ class VehicleControl(vehicle: Vehicle) vehicle.Shields = vehicle.Shields + amount vehicle.Zone.VehicleEvents ! VehicleServiceMessage( s"${vehicle.Actor}", - VehicleAction.PlanetsideAttribute(vehicle.GUID, vehicle.Definition.shieldUiAttribute, vehicle.Shields) + PlanetsideAttribute(vehicle.GUID, vehicle.Definition.shieldUiAttribute, vehicle.Shields) ) } } @@ -754,15 +753,10 @@ class VehicleControl(vehicle: Vehicle) def vehicleSubsystemMessages(messages: List[PlanetSideGamePacket]): Unit = { val zone = vehicle.Zone - val zoneid = zone.id - val events = zone.VehicleEvents - val guid0 = Service.defaultPlayerGUID - messages.foreach { pkt => - events ! VehicleServiceMessage( - zoneid, - VehicleAction.SendResponse(pkt) - ) - } + zone.VehicleEvents ! VehicleServiceMessage( + zone.id, + SendResponse(messages) + ) } override protected def canChangeVulnerability(state: Damageable.PersonalVulnerability): Boolean = { diff --git a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala index 2ab9aa6bf..f8f807423 100644 --- a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala +++ b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala @@ -6,6 +6,7 @@ import net.psforever.objects.avatar.interaction.WithEntrance import net.psforever.objects.serverobject.doors.InteriorDoorPassage import net.psforever.objects.serverobject.environment.PieceOfEnvironment import net.psforever.objects.zones.interaction.InteractsWithZone +import net.psforever.services.base.messages.SendResponse class WithEntranceInVehicle extends WithEntrance() { @@ -39,11 +40,11 @@ class WithEntranceInVehicle private def warnAboutProximity(obj: InteractsWithZone, msg: String): Unit = { import net.psforever.packet.game.ChatMsg - import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} + import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.types.ChatMessageType obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Actor.toString(), - AvatarAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) + SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) ) } } diff --git a/src/main/scala/net/psforever/objects/zones/MapInfo.scala b/src/main/scala/net/psforever/objects/zones/MapInfo.scala index a6edd6b7a..3635eecbd 100644 --- a/src/main/scala/net/psforever/objects/zones/MapInfo.scala +++ b/src/main/scala/net/psforever/objects/zones/MapInfo.scala @@ -2,11 +2,12 @@ package net.psforever.objects.zones import enumeratum.values.{StringEnum, StringEnumEntry} import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle} -import net.psforever.objects.serverobject.environment.{Pool, _} +import net.psforever.objects.serverobject.environment._ import net.psforever.packet.game.{ChatMsg, OffshoreVehicleMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} sealed abstract class MapInfo( @@ -700,7 +701,7 @@ object MapEnvironment { case v: Vehicle => v.Zone.VehicleEvents ! VehicleServiceMessage( v.Actor.toString(), - VehicleAction.SendResponse(OffshoreVehicleMessage(v.Seats(0).occupant.get.GUID, v.GUID, msg)) + SendResponse(OffshoreVehicleMessage(v.Seats(0).occupant.get.GUID, v.GUID, msg)) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala index f5c0197b7..b58e29a77 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala @@ -10,7 +10,8 @@ import net.psforever.objects.sourcing.ObjectSource import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vital.SpawningActivity import net.psforever.packet.game.ChatMsg -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.local.LocalServiceMessage import net.psforever.types.ChatMessageType import scala.annotation.tailrec @@ -109,7 +110,7 @@ object ZoneDeployableActor { case _ if Interference.Test(zone, obj).nonEmpty => zone.LocalEvents ! LocalServiceMessage( obj.OwnerName.getOrElse(""), - LocalAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, "@nomove_intersecting")) + SendResponse(ChatMsg(ChatMessageType.UNK_227, "@nomove_intersecting")) ) //may not be the correct message but is sufficient at explaining why the deployable can not be built false case None => diff --git a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala index e4feeba91..cf0052e88 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala @@ -6,6 +6,7 @@ import net.psforever.objects.ballistics.Projectile import net.psforever.objects.guid.{GUIDTask, StraightforwardTask, TaskBundle, TaskWorkflow} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.ObjectDelete import net.psforever.types.PlanetSideGUID import scala.collection.mutable @@ -190,12 +191,12 @@ class ZoneProjectileActor( zone.blockMap.removeFrom(projectile) zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.ObjectDelete(projectile_guid, 2) + ObjectDelete(projectile_guid, 2) ) } else if (projectile.Definition.RemoteClientData == (0,0)) { zone.AvatarEvents ! AvatarServiceMessage( zone.id, - AvatarAction.ObjectDelete(projectile_guid, 2) + ObjectDelete(projectile_guid, 2) ) } else { zone.AvatarEvents ! AvatarServiceMessage( diff --git a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala index be767c726..8f1afb302 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala @@ -9,7 +9,8 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vital.InGameHistory import net.psforever.objects.{Default, GlobalDefinitions, Vehicle} import net.psforever.packet.game.ChatMsg -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, Vector3} import scala.annotation.tailrec @@ -205,7 +206,7 @@ object ZoneVehicleActor { msgOpt.foreach { msg => zone.VehicleEvents ! VehicleServiceMessage( vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse(""), - VehicleAction.SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) + SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) ) } msgOpt.isDefined diff --git a/src/main/scala/net/psforever/packet/game/HackMessage.scala b/src/main/scala/net/psforever/packet/game/HackMessage.scala index b5d0c7e7b..7a5ee8f38 100644 --- a/src/main/scala/net/psforever/packet/game/HackMessage.scala +++ b/src/main/scala/net/psforever/packet/game/HackMessage.scala @@ -129,18 +129,6 @@ final case class HackMessage( } object HackMessage extends Marshallable[HackMessage] { - def apply( - unk1: HackState1, - target_guid: PlanetSideGUID, - player_guid: PlanetSideGUID, - progress: Int, - unk5: Int, - hack_state: HackState, - unk7: HackState7 - ): HackMessage = { - new HackMessage(unk1, target_guid, player_guid, progress, unk5.toFloat, hack_state, unk7) - } - implicit val codec: Codec[HackMessage] = ( ("unk1" | HackState1.codec) :: ("object_guid" | PlanetSideGUID.codec) :: diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index 102bcd9d9..ddd46e693 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -12,6 +12,7 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg +import net.psforever.services.base.messages.SendResponse import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage, GalaxyServiceResponse} import net.psforever.types.ChatMessageType import net.psforever.util.Config @@ -89,7 +90,7 @@ object CavernRotationService { */ private def closedCavernWarning(zone: ZoneMonitor, counter: Int, galaxyService: ActorRef): Boolean = { if (!zone.locked) { - galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse( + galaxyService ! GalaxyServiceMessage(SendResponse( ChatMsg(ChatMessageType.UNK_229, s"@cavern_closing_warning^@${zone.zone.id}~^@$counter~") )) true @@ -664,7 +665,7 @@ class CavernRotationService( lockTimerToDisplayWarning(hoursBetweenRotationsAsHours - firstClosingWarningAtMinutes.minutes) //alert clients to change if (lockingZone ne unlockingZone) { - galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse( + galaxyService ! GalaxyServiceMessage(SendResponse( ChatMsg(ChatMessageType.UNK_229, s"@cavern_switched^@${lockingZone.id}~^@${unlockingZone.id}") )) //change warp gate statuses to reflect zone lock state diff --git a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala index dc91da84f..1fc186ab9 100644 --- a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala +++ b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala @@ -16,6 +16,7 @@ import net.psforever.persistence import net.psforever.types.Vector3 import net.psforever.services.{Service, ServiceManager} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.ObjectDelete import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.zones.Zones @@ -434,7 +435,7 @@ class PersistenceMonitor( case _ => ; } inZone.Population.tell(Zone.Population.Release(avatar), parent) - inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, pguid, AvatarAction.ObjectDelete(pguid)), parent) + inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, pguid, ObjectDelete(pguid)), parent) TaskWorkflow.execute(GUIDTask.unregisterPlayer(inZone.GUID, player)) //inZone.tasks.tell(GUIDTask.UnregisterPlayer(player)(inZone.GUID), parent) AvatarLogout(avatar) diff --git a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala index 8744c5b95..928f23e93 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala @@ -13,42 +13,30 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage} import net.psforever.packet.game.objectcreate.{ConstructorData, DroppedItemData, ObjectCreateMessageParent, PlacementData} -import net.psforever.services.base.{EventMessage, EventResponse, SelfResponseMessage} -import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3} +import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.{EventMessage, EventResponse, SelfRespondingEvent} +import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideGUID, TransactionType, Vector3} import scala.concurrent.duration.FiniteDuration object AvatarAction { - final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends SelfResponseMessage + final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends SelfRespondingEvent - final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends SelfResponseMessage + final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends SelfRespondingEvent - final case class ChangeAmmo( - weapon_guid: PlanetSideGUID, - weapon_slot: Int, - old_ammo_guid: PlanetSideGUID, - ammo_id: Int, - ammo_guid: PlanetSideGUID, - ammo_data: ConstructorData - ) extends SelfResponseMessage + final case class ChangeFireMode(item_guid: PlanetSideGUID, mode: Int) extends SelfRespondingEvent - final case class ChangeFireMode(item_guid: PlanetSideGUID, mode: Int) extends SelfResponseMessage + final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent - final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + final case class EnvironmentalDamage(player_guid: PlanetSideGUID, source_guid: PlanetSideGUID, amount: Int) extends SelfRespondingEvent - final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + final case class DeactivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfRespondingEvent - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage + final case class ActivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfRespondingEvent - final case class EnvironmentalDamage(player_guid: PlanetSideGUID, source_guid: PlanetSideGUID, amount: Int) extends SelfResponseMessage + final case class Destroy(victim: PlanetSideGUID, killer: PlanetSideGUID, weapon: PlanetSideGUID, pos: Vector3) extends SelfRespondingEvent - final case class DeactivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfResponseMessage - - final case class ActivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfResponseMessage - - final case class Destroy(victim: PlanetSideGUID, killer: PlanetSideGUID, weapon: PlanetSideGUID, pos: Vector3) extends SelfResponseMessage - - final case class DestroyDisplay(killer: SourceEntry, victim: SourceEntry, method: Int, unk: Int = 121) extends SelfResponseMessage + final case class DestroyDisplay(killer: SourceEntry, victim: SourceEntry, method: Int, unk: Int = 121) extends SelfRespondingEvent final case class DropCreatedItem(packet: ObjectCreateMessage) extends EventResponse @@ -73,18 +61,10 @@ object AvatarAction { AvatarAction.EquipmentCreatedInHand( ObjectCreateMessage(definition.ObjectId, item.GUID, containerData, objectData) ) - - AvatarAction.DropCreatedItem( - ObjectCreateMessage(definition.ObjectId, item.GUID, containerData, objectData) - ) } } - final case class GenericObjectAction(object_guid: PlanetSideGUID, action_code: Int) extends SelfResponseMessage - - final case class HitHint(source_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class Killed(cause: DamageResult, mount_guid: Option[PlanetSideGUID]) extends SelfResponseMessage + final case class Killed(cause: DamageResult, mount_guid: Option[PlanetSideGUID]) extends SelfRespondingEvent final case class LoadCreatedPlayer(pkt: ObjectCreateMessage) extends EventResponse @@ -117,19 +97,15 @@ object AvatarAction { } } - final case class ObjectDelete(item_guid: PlanetSideGUID, unk: Int = 0) extends SelfResponseMessage + final case class ObjectHeld(slot: Int, previousSLot: Int) extends SelfRespondingEvent - final case class ObjectHeld(slot: Int, previousSLot: Int) extends SelfResponseMessage + final case class OxygenState(player: OxygenStateTarget, vehicle: Option[OxygenStateTarget]) extends SelfRespondingEvent - final case class OxygenState(player: OxygenStateTarget, vehicle: Option[OxygenStateTarget]) extends SelfResponseMessage + final case class PlanetsideAttributeToAll(attribute_type: Int, attribute_value: Long) extends SelfRespondingEvent - final case class PlanetsideAttribute(attribute_type: Int, attribute_value: Long) extends SelfResponseMessage + final case class PlanetsideAttributeSelf(attribute_type: Int, attribute_value: Long) extends SelfRespondingEvent - final case class PlanetsideAttributeToAll(attribute_type: Int, attribute_value: Long) extends SelfResponseMessage - - final case class PlanetsideAttributeSelf(attribute_type: Int, attribute_value: Long) extends SelfResponseMessage - - final case class PlanetsideStringAttribute(attribute_type: Int, attribute_value: String) extends SelfResponseMessage + final case class PlanetsideStringAttribute(attribute_type: Int, attribute_value: String) extends SelfRespondingEvent final case class PlayerState( pos: Vector3, @@ -144,7 +120,7 @@ object AvatarAction { is_cloaked: Boolean, spectator: Boolean, weaponInHand: Boolean - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class PickupItem(item: Equipment, unk: Int = 0) extends EventMessage { def response(): EventResponse = { @@ -152,9 +128,9 @@ object AvatarAction { } } - final case class ProjectileAutoLockAwareness(mode: Int) extends SelfResponseMessage + final case class ProjectileAutoLockAwareness(mode: Int) extends SelfRespondingEvent - final case class ProjectileExplodes(projectile_guid: PlanetSideGUID, projectile: Projectile) extends SelfResponseMessage + final case class ProjectileExplodes(projectile_guid: PlanetSideGUID, projectile: Projectile) extends SelfRespondingEvent final case class ProjectileState( projectile_guid: PlanetSideGUID, @@ -164,9 +140,9 @@ object AvatarAction { sequence: Int, end: Boolean, hit_target: PlanetSideGUID - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class PutDownFDU(player_guid: PlanetSideGUID) extends SelfResponseMessage + final case class PutDownFDU(player_guid: PlanetSideGUID) extends SelfRespondingEvent final case class ReleasePlayer(player: Player) extends EventResponse @@ -176,25 +152,15 @@ object AvatarAction { } } - final case class Reload(weapon_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class Revive(target_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class SetEmpire(object_guid: PlanetSideGUID, faction: PlanetSideEmpire.Value) - extends SelfResponseMessage + final case class Revive(target_guid: PlanetSideGUID) extends SelfRespondingEvent final case class StowEquipment(target_guid: PlanetSideGUID, slot: Int, item: Equipment) - extends SelfResponseMessage + extends SelfRespondingEvent - final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends SelfResponseMessage - - - final case class SendResponse(msg: PlanetSideGamePacket) extends SelfResponseMessage - - final case class SendResponseTargeted(target_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends SelfResponseMessage + final case class SendResponseTargeted(target_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends SelfRespondingEvent final case class TerminalOrderResult(terminal_guid: PlanetSideGUID, action: TransactionType.Value, result: Boolean) - extends SelfResponseMessage + extends SelfRespondingEvent final case class ChangeExosuit( target_guid: PlanetSideGUID, @@ -209,7 +175,7 @@ object AvatarAction { inventory: List[InventoryItem], drop: List[InventoryItem], delete: List[(Equipment, PlanetSideGUID)] - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class ChangeLoadout( target_guid: PlanetSideGUID, @@ -223,27 +189,27 @@ object AvatarAction { old_inventory: List[(Equipment, PlanetSideGUID)], inventory: List[InventoryItem], drop: List[InventoryItem] - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class DropSpecialItem() extends SelfResponseMessage + final case class DropSpecialItem() extends SelfRespondingEvent - final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends SelfResponseMessage + final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends SelfRespondingEvent - final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends SelfResponseMessage + final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends SelfRespondingEvent - final case class UpdateKillsDeathsAssists(charId: Long, kda: KDAStat) extends SelfResponseMessage + final case class UpdateKillsDeathsAssists(charId: Long, kda: KDAStat) extends SelfRespondingEvent - final case class AwardBep(charId: Long, bep: Long, expType: ExperienceType) extends SelfResponseMessage + final case class AwardBep(charId: Long, bep: Long, expType: ExperienceType) extends SelfRespondingEvent - final case class AwardCep(charId: Long, bep: Long) extends SelfResponseMessage + final case class AwardCep(charId: Long, bep: Long) extends SelfRespondingEvent - final case class FacilityCaptureRewards(building_id: Int, zone_number: Int, exp: Long) extends SelfResponseMessage + final case class FacilityCaptureRewards(building_id: Int, zone_number: Int, exp: Long) extends SelfRespondingEvent - final case class ShareKillExperienceWithSquad(killer: Player, exp: Long) extends SelfResponseMessage + final case class ShareKillExperienceWithSquad(killer: Player, exp: Long) extends SelfRespondingEvent - final case class ShareAntExperienceWithSquad(owner: UniquePlayer, exp: Long, vehicle: Vehicle) extends SelfResponseMessage + final case class ShareAntExperienceWithSquad(owner: UniquePlayer, exp: Long, vehicle: Vehicle) extends SelfRespondingEvent - final case class RemoveFromOutfitChat(outfit_id: Long) extends SelfResponseMessage + final case class RemoveFromOutfitChat(outfit_id: Long) extends SelfRespondingEvent - final case class TeardownConnection() extends SelfResponseMessage + final case class TeardownConnection() extends SelfRespondingEvent } diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index af9886d5f..822afa1d9 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -5,7 +5,8 @@ import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.Player import net.psforever.types.ExoSuitType import net.psforever.services.RemoverActor -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.ObjectDelete import scala.concurrent.duration._ @@ -25,7 +26,7 @@ class CorpseRemovalActor extends RemoverActor() { entry.zone.Population ! Zone.Corpse.Remove(entry.obj.asInstanceOf[Player]) context.parent ! AvatarServiceMessage( entry.zone.id, - AvatarAction.ObjectDelete(entry.obj.GUID, unk=1) + ObjectDelete(entry.obj.GUID, unk=1) ) } diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index 11c9fd197..8e4245e56 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -4,7 +4,8 @@ package net.psforever.services.avatar.support import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.services.RemoverActor -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.ObjectDelete import scala.concurrent.duration._ @@ -24,7 +25,7 @@ class DroppedItemRemover extends RemoverActor() { entry.zone.Ground ! Zone.Ground.RemoveItem(entry.obj.GUID) context.parent ! AvatarServiceMessage( entry.zone.id, - AvatarAction.ObjectDelete(entry.obj.GUID) + ObjectDelete(entry.obj.GUID) ) } diff --git a/src/main/scala/net/psforever/services/base/EventExchange.scala b/src/main/scala/net/psforever/services/base/EventExchange.scala index b566be39b..eea7ac7b1 100644 --- a/src/main/scala/net/psforever/services/base/EventExchange.scala +++ b/src/main/scala/net/psforever/services/base/EventExchange.scala @@ -9,7 +9,7 @@ trait EventMessage extends EventExchange { def response(): EventResponse } -trait SelfResponseMessage +trait SelfRespondingEvent extends EventMessage with EventResponse { def response(): EventResponse = this diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala deleted file mode 100644 index 4b0ccd890..000000000 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBusWithSupport.scala +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2026 PSForever -package net.psforever.services.base.bus - -import scala.annotation.unused - -trait GenericEventBusResponseToSupport - extends GenericEventBusResponse { - def supportLabel: String - def supportMessage: Any -} - -trait GenericEventBusResponseToSupportOnly - extends GenericEventBusResponseToSupport { - def channel: String = "" -} - -trait GenericEventBusWithSupport[T <: GenericEventBusResponse] { - bus: GenericEventBus[T] => - def handleMessageWithSupport(event: T): Unit = { - event match { - case msg: GenericEventBusResponseToSupportOnly => - forwardToExternalSupport(msg) - case msg: GenericEventBusResponseToSupport => - forwardToExternalSupport(msg) - bus.truePublish(event) - case _ => - bus.truePublish(event) - } - } - - def forwardToExternalSupport(@unused msg: GenericEventBusResponseToSupport): Unit -} diff --git a/src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala b/src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala new file mode 100644 index 000000000..2b51767dd --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala @@ -0,0 +1,15 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.packet.game.objectcreate.ConstructorData +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class ChangeAmmo( + weapon_guid: PlanetSideGUID, + weapon_slot: Int, + old_ammo_guid: PlanetSideGUID, + ammo_id: Int, + ammo_guid: PlanetSideGUID, + ammo_data: ConstructorData + ) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala b/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala new file mode 100644 index 000000000..b73e740b8 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala b/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala new file mode 100644 index 000000000..fa6f1a7d6 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala b/src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala new file mode 100644 index 000000000..2bfe69b26 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class GenericObjectAction(object_guid: PlanetSideGUID, action_code: Int) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala b/src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala new file mode 100644 index 000000000..8768fcb73 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala @@ -0,0 +1,8 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +//analogue for HitHint +final case class HintsAtAttacker(source_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala b/src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala new file mode 100644 index 000000000..d8f3343bc --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class ObjectDelete(obj_guid: PlanetSideGUID, unk: Int = 0) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala b/src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala new file mode 100644 index 000000000..0df0cfb3b --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala @@ -0,0 +1,11 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class PlanetsideAttribute( + target_guid: PlanetSideGUID, + attribute_type: Int, + attribute_value: Long + ) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/ReloadTool.scala b/src/main/scala/net/psforever/services/base/messages/ReloadTool.scala new file mode 100644 index 000000000..34e118391 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/ReloadTool.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class ReloadTool(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/SendResponse.scala b/src/main/scala/net/psforever/services/base/messages/SendResponse.scala new file mode 100644 index 000000000..6de55c9d6 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/SendResponse.scala @@ -0,0 +1,11 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.packet.PlanetSideGamePacket +import net.psforever.services.base.SelfRespondingEvent + +final case class SendResponse(pkts: Seq[PlanetSideGamePacket]) extends SelfRespondingEvent + +object SendResponse { + def apply(pkt: PlanetSideGamePacket): SendResponse = SendResponse(Seq(pkt)) +} diff --git a/src/main/scala/net/psforever/services/base/messages/SetEmpire.scala b/src/main/scala/net/psforever/services/base/messages/SetEmpire.scala new file mode 100644 index 000000000..dc52a15e4 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/SetEmpire.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} + +final case class SetEmpire(object_guid: PlanetSideGUID, faction: PlanetSideEmpire.Value) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala b/src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala new file mode 100644 index 000000000..9f2f0b8d1 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.messages + +import net.psforever.services.base.SelfRespondingEvent +import net.psforever.types.PlanetSideGUID + +final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala index 64a813446..c23f6ec18 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala @@ -4,17 +4,16 @@ package net.psforever.services.galaxy import net.psforever.objects.Vehicle import net.psforever.objects.vehicles.VehicleManifest import net.psforever.objects.zones.{HotSpotInfo, Zone} -import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} -import net.psforever.services.base.SelfResponseMessage +import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} object GalaxyAction { - final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends SelfResponseMessage + final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends SelfRespondingEvent - final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends SelfResponseMessage + final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends SelfRespondingEvent - final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends SelfResponseMessage + final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends SelfRespondingEvent final case class TransferPassenger( player_guid: PlanetSideGUID, @@ -22,20 +21,18 @@ object GalaxyAction { vehicle: Vehicle, vehicle_to_delete: PlanetSideGUID, manifest: VehicleManifest - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class UpdateBroadcastPrivileges( zoneId: Int, gateMapId: Int, fromFactions: Set[PlanetSideEmpire.Value], toFactions: Set[PlanetSideEmpire.Value] - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends SelfResponseMessage + final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends SelfRespondingEvent - final case class UnlockedZoneUpdate(zone: Zone) extends SelfResponseMessage + final case class UnlockedZoneUpdate(zone: Zone) extends SelfRespondingEvent - final case class LogStatusChange(name: String) extends SelfResponseMessage - - final case class SendResponse(msg: PlanetSideGamePacket) extends SelfResponseMessage + final case class LogStatusChange(name: String) extends SelfRespondingEvent } diff --git a/src/main/scala/net/psforever/services/local/LocalAction.scala b/src/main/scala/net/psforever/services/local/LocalAction.scala index 917af8f46..cb16c29c5 100644 --- a/src/main/scala/net/psforever/services/local/LocalAction.scala +++ b/src/main/scala/net/psforever/services/local/LocalAction.scala @@ -3,111 +3,65 @@ package net.psforever.services.local import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle} import net.psforever.objects.ce.{Deployable, DeployedItem} -import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.llu.CaptureFlag import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.vehicles.Utility import net.psforever.objects.zones.Zone -import net.psforever.packet.PlanetSideGamePacket -import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum -import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound} -import net.psforever.services.base.{EventMessage, EventResponse, SelfResponseMessage} +import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.{EventMessage, EventResponse, SelfRespondingEvent} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} +import net.psforever.types.{PlanetSideGUID, Vector3} object LocalAction { - trait Action extends EventMessage { - def response(): EventResponse = null - } + sealed trait IsADoorMessage extends SelfRespondingEvent + + sealed trait IsAHackMessage extends SelfRespondingEvent final case class DeployItem(item: Deployable) extends EventMessage { def response(): EventResponse = { val definition = item.Definition val objectData = definition.Packet.ConstructorData(item).get - LocalAction.SendResponse(ObjectCreateMessage(definition.ObjectId, item.GUID, objectData)) + SendResponse(ObjectCreateMessage(definition.ObjectId, item.GUID, objectData)) } } - final case class DeployableMapIcon(behavior: DeploymentAction.Value, deployInfo: DeployableInfo) extends SelfResponseMessage + final case class DeployableMapIcon(behavior: DeploymentAction.Value, deployInfo: DeployableInfo) extends SelfRespondingEvent - final case class DeployableUIFor(obj: DeployedItem.Value) extends SelfResponseMessage + final case class DeployableUIFor(obj: DeployedItem.Value) extends SelfRespondingEvent - final case class Detonate(guid: PlanetSideGUID, obj: PlanetSideGameObject) extends SelfResponseMessage + final case class Detonate(guid: PlanetSideGUID, obj: PlanetSideGameObject) extends SelfRespondingEvent - final case class DoorOpens(continent: Zone, door: Door) extends SelfResponseMessage + final case class DoorOpens(continent: Zone, door: Door) extends IsADoorMessage - final case class DoorCloses(door_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class DoorSlamsShut(door: Door) extends EventMessage { - def response(): EventResponse = { - //todo important! doorCloser ! SupportActor.HurrySpecific(List(door), zone) - DoorCloses(door.GUID) - } - } + final case class DoorCloses(door_guid: PlanetSideGUID) extends IsADoorMessage final case class EliminateDeployable( obj: Deployable, object_guid: PlanetSideGUID, pos: Vector3, deletionEffect: Int - ) extends SelfResponseMessage - - final case class SendHackMessageHackCleared( - target_guid: PlanetSideGUID, - unk1: Long, - unk2: HackState7 - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class HackClear( - target: PlanetSideServerObject, + target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7 = HackState7.Unk8 - ) extends EventMessage { - def response(): EventResponse = { - SendHackMessageHackCleared(target.GUID, unk1, unk2) - } - } + ) extends IsAHackMessage - final case class HackObject(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends EventResponse + final case class HackObject(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends IsAHackMessage - final case class HackTemporarily( - continent: Zone, - target: PlanetSideServerObject, - hackValue: Long, - hackClearValue: Long, - duration: Int, - unk2: HackState7 = HackState7.Unk8 - ) extends EventMessage { - def response(): EventResponse = { - HackObject(target.GUID, hackValue, unk2) - } - } - - final case class LluSpawned(llu: CaptureFlag) extends SelfResponseMessage + final case class LluSpawned(llu: CaptureFlag) extends SelfRespondingEvent final case class LluDespawned( guid: PlanetSideGUID, position: Vector3 - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class PlanetsideAttribute( - target_guid: PlanetSideGUID, - attribute_number: PlanetsideAttributeEnum, - attribute_value: Long - ) extends SelfResponseMessage + final case class ChatMessage(msg: ChatMsg) extends SelfRespondingEvent - final case class ChatMessage(msg: ChatMsg) extends SelfResponseMessage - - final case class GenericObjectAction( - target_guid: PlanetSideGUID, - action_number: GenericObjectActionEnum - ) extends SelfResponseMessage - - final case class GenericActionMessage(action_num: GenericAction) extends SelfResponseMessage - - final case class ObjectDelete(item_guid: PlanetSideGUID, unk: Int) extends EventResponse + final case class GenericActionMessage(action_num: GenericAction) extends SelfRespondingEvent final case class ProximityTerminalAction( terminal: Terminal with ProximityUnit, @@ -117,42 +71,38 @@ object LocalAction { final case class ProximityTerminalEffect( object_guid: PlanetSideGUID, effectState: Boolean - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class RouterTelepadMessage(msg: String) extends SelfResponseMessage + final case class RouterTelepadMessage(msg: String) extends SelfRespondingEvent final case class RouterTelepadTransport( passenger_guid: PlanetSideGUID, src_guid: PlanetSideGUID, dest_guid: PlanetSideGUID - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class SendResponse(pkt: PlanetSideGamePacket) extends SelfResponseMessage - - final case class SetEmpire(object_guid: PlanetSideGUID, empire: PlanetSideEmpire.Value) extends SelfResponseMessage - - final case class ShuttleDock(pad_guid: PlanetSideGUID, shuttle_guid: PlanetSideGUID, toSlot: Int) extends SelfResponseMessage + final case class ShuttleDock(pad_guid: PlanetSideGUID, shuttle_guid: PlanetSideGUID, toSlot: Int) extends SelfRespondingEvent final case class ShuttleUndock( pad_guid: PlanetSideGUID, shuttle_guid: PlanetSideGUID, pos: Vector3, orient: Vector3 - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class ShuttleEvent(ev: OrbitalShuttleEvent) extends SelfResponseMessage + final case class ShuttleEvent(ev: OrbitalShuttleEvent) extends SelfRespondingEvent - final case class ShuttleState(guid: PlanetSideGUID, pos: Vector3, orientation: Vector3, state: Int) extends SelfResponseMessage + final case class ShuttleState(guid: PlanetSideGUID, pos: Vector3, orientation: Vector3, state: Int) extends SelfRespondingEvent final case class StartRouterInternalTelepad( router_guid: PlanetSideGUID, obj_guid: PlanetSideGUID, obj: Utility.InternalTelepad - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class ToggleTeleportSystem( router: Vehicle, systemPlan: Option[(Utility.InternalTelepad, TelepadDeployable)] - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class TriggerEffectAtLocation( target: PlanetSideGUID, @@ -188,17 +138,17 @@ object LocalAction { pos: Vector3, unk: Int, volume: Float - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class UpdateForceDomeStatus( building_guid: PlanetSideGUID, activated: Boolean - ) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class RechargeVehicleWeapon( mountable_guid: PlanetSideGUID, weapon_guid: PlanetSideGUID - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class ForceZoneChange(zone: Zone) extends SelfResponseMessage + final case class ForceZoneChange(zone: Zone) extends SelfRespondingEvent } diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index 0cfa55e9c..469d1cc5e 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -3,41 +3,37 @@ package net.psforever.services.local import net.psforever.services.Service import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly} -import net.psforever.services.local.LocalAction.DoorSlamsShut +import net.psforever.services.local.LocalAction.{IsADoorMessage, IsAHackMessage} +import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.PlanetSideGUID - final case class LocalServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) extends GenericMessageEnvelope object LocalServiceMessage { def apply(channel: String, localMessage: EventMessage): LocalServiceMessage = LocalServiceMessage(channel, Service.defaultPlayerGUID, localMessage) - - final case class Deployables(msg: Any) } final case class DoorMessage( - channel: String, - filter: PlanetSideGUID, - msg: DoorSlamsShut, - supportMessage: Any - ) - extends GenericMessageToSupportEnvelope { + channel: String, + msg: IsADoorMessage, + supportMessage: Any + ) extends GenericMessageToSupportEnvelope { + def filter: PlanetSideGUID = Service.defaultPlayerGUID def supportLabel: String = "doorCloser" } final case class HackEntityMessage( channel: String, filter: PlanetSideGUID, - msg: EventMessage, + msg: IsAHackMessage, supportMessage: Any - ) - extends GenericMessageToSupportEnvelope { + ) extends GenericMessageToSupportEnvelope { def supportLabel: String = "hackClearer" } -final case class ClearMessage(supportMessage: Any) +final case class HackClearMessage(supportMessage: Any) extends GenericMessageToSupportEnvelopeOnly { def supportLabel: String = "hackClearer" } @@ -47,7 +43,7 @@ final case class CaptureMessage(supportMessage: Any) def supportLabel: String = "hackCapturer" } -final case class FlagMessage(supportMessage: Any) +final case class FlagMessage(supportMessage: CaptureFlagManager.Command) extends GenericMessageToSupportEnvelopeOnly { def supportLabel: String = "captureFlagManager" } diff --git a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala index 9ea03cc7a..d79251944 100644 --- a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala +++ b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala @@ -15,6 +15,7 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.ServiceManager.{Lookup, LookupResult} +import net.psforever.services.base.messages.{GenericObjectAction, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -48,9 +49,9 @@ class CaptureFlagManager(zone: Zone) extends Actor { zone.LocalEvents ! LocalServiceMessage( zone.id, PlanetSideGUID(-1), - LocalAction.GenericObjectAction( + GenericObjectAction( capture_terminal.GUID, - GenericObjectActionEnum.FlagSpawned + GenericObjectActionEnum.FlagSpawned.id ) ) // Register LLU object create task and callback to create on clients @@ -122,7 +123,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { zone.LocalEvents ! LocalServiceMessage( zone.id, PlanetSideGUID(-1), - LocalAction.SendResponse(ObjectAttachMessage(player.GUID, flag.GUID, 252)) + SendResponse(ObjectAttachMessage(player.GUID, flag.GUID, 252)) ) zone.LocalEvents ! LocalServiceMessage( zone.id, @@ -147,7 +148,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { zone.LocalEvents ! LocalServiceMessage( zone.id, PlanetSideGUID(-1), - LocalAction.SendResponse(ObjectDetachMessage(player.GUID, flag.GUID, player.Position, 0, 0, 0)) + SendResponse(ObjectDetachMessage(player.GUID, flag.GUID, player.Position, 0, 0, 0)) ) // Send dropped chat message CaptureFlagManager.ChatBroadcast( diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index 729a339d2..cddd949a1 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -13,6 +13,7 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction import net.psforever.services.local.{FlagMessage, LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} @@ -231,9 +232,9 @@ class HackCaptureActor extends Actor { terminal.Zone.LocalEvents ! LocalServiceMessage( terminal.Zone.id, PlanetSideGUID(-1), - LocalAction.PlanetsideAttribute( + PlanetsideAttribute( terminal.GUID, - PlanetsideAttributeEnum.ControlConsoleHackUpdate, + PlanetsideAttributeEnum.ControlConsoleHackUpdate.id, attributeValue ) ) @@ -307,7 +308,7 @@ class HackCaptureActor extends Actor { NotifyHackStateChange(terminal, isResecured = true) // todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. val zone = building.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendHackMessageHackCleared(building.GUID, 3212836864L, HackState7.Unk8)) + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.HackClear(building.GUID, 3212836864L, HackState7.Unk8)) } private def RestartTimer(): Unit = { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index e49ebf96b..b2b7fad37 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -8,6 +8,7 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.HackState7 +import net.psforever.services.base.messages.GenericObjectAction import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID @@ -48,7 +49,7 @@ class HackClearActor() extends Actor { hackedObjects = stillHackedObjects unhackObjects.foreach { case HackClearActor.HackEntry(target, zone, unk1, unk2, _, _) => target.Actor ! CommonMessages.ClearHack() - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendHackMessageHackCleared(target.GUID, unk1, unk2)) + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.HackClear(target.GUID, unk1, unk2)) if (target.Definition == GlobalDefinitions.main_terminal) { ClearVirusFromBuilding(target) } @@ -61,7 +62,7 @@ class HackClearActor() extends Actor { case Some(HackClearActor.HackEntry(target, zone, unk1, unk2, _, _)) => hackedObjects = hackedObjects.filterNot(x => x.target == target) target.Actor ! CommonMessages.ClearHack() - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendHackMessageHackCleared(target.GUID, 3212836864L, HackState7.Unk8)) + zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.HackClear(target.GUID, 3212836864L, HackState7.Unk8)) // Restart the timer in case the object we just removed was the next one scheduled RestartTimer() @@ -100,12 +101,12 @@ class HackClearActor() extends Actor { import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.actors.zone.BuildingActor - import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} + import net.psforever.services.avatar.AvatarServiceMessage val building = target.asInstanceOf[Terminal].Owner.asInstanceOf[Building] building.virusId = 8 building.virusInstalledBy = None - val msg = AvatarAction.GenericObjectAction(target.GUID, 60) + val msg = GenericObjectAction(target.GUID, 60) val events = building.Zone.AvatarEvents building.PlayersInSOI.foreach { player => events ! AvatarServiceMessage(player.Name, msg) diff --git a/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala b/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala index 6ca16e72b..0a7888ae4 100644 --- a/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala +++ b/src/main/scala/net/psforever/services/properties/PropertyOverrideManager.scala @@ -4,7 +4,6 @@ import akka.actor.Actor import net.psforever.packet.game.{GamePropertyTarget, PropertyOverrideMessage} import net.psforever.packet.game.PropertyOverrideMessage.GamePropertyScope import net.psforever.packet.game.objectcreate.ObjectClass -import net.psforever.services.base.{EventMessage, EventResponse} import net.psforever.zones.Zones import scala.collection.mutable.ListBuffer @@ -14,11 +13,10 @@ class PropertyOverrideManager extends Actor { private var overrides: Map[Int, Map[String, List[(String, String)]]] = Map() private var gamePropertyScopes: List[PropertyOverrideMessage.GamePropertyScope] = List() - lazy private val zoneIds: Iterable[Int] = Zones.zones.map(_.Number) override def preStart(): Unit = { LoadOverridesFromFile(zoneId = 0) // Global overrides - for (zoneId <- zoneIds) { + for (zoneId <- Zones.zones.map(_.Number)) { LoadOverridesFromFile(zoneId) } ProcessGamePropertyScopes() @@ -28,7 +26,7 @@ class PropertyOverrideManager extends Actor { case PropertyOverrideManager.GetOverridesMessage => sender() ! gamePropertyScopes - case _ => ; + case _ => () } private def LoadOverridesFromFile(zoneId: Int): Unit = { @@ -39,11 +37,11 @@ class PropertyOverrideManager extends Actor { } if (zoneOverrides == null) { log.debug(s"PropertyOverride: no overrides found for zone $zoneId using filename game_objects$zoneId.adb.lst") - return + } else { + val grouped = zoneOverrides.groupBy(_._1).view.mapValues(_.map(x => (x._2, x._3)).toList).toMap + log.debug(s"PropertyOverride: loaded property overrides for zone $zoneId: ${grouped.toString}") + overrides += (zoneId -> grouped) } - val grouped = zoneOverrides.groupBy(_._1).view.mapValues(_.map(x => (x._2, x._3)).toList).toMap - log.debug(s"PropertyOverride: loaded property overrides for zone $zoneId: ${grouped.toString}") - overrides += (zoneId -> grouped) } private def ProcessGamePropertyScopes(): Unit = { @@ -63,33 +61,29 @@ class PropertyOverrideManager extends Actor { gamePropertyScopes = scopesBuffer.toList } - def LoadFile(path: String): ListBuffer[(String, String, String)] = { + def LoadFile(path: String): List[(String, String, String)] = { val stream = getClass.getClassLoader.getResourceAsStream(path) if (stream == null) { - return null - } - val content = scala.io.Source.fromInputStream(stream).getLines().filter(x => x.startsWith("add_property")) - val data: ListBuffer[(String, String, String)] = ListBuffer() - for (line <- content) { - val splitLine = line.split(" ") - if (splitLine.length >= 3) { - val objectName = splitLine(1) - val property = splitLine(2) - var propertyValue = "" - for (i <- 3 until splitLine.length) { - propertyValue += splitLine(i) + " " + List.empty[(String, String, String)] + } else { + val content = scala.io.Source.fromInputStream(stream).getLines() + val data = content + .filter(_.startsWith("add_property")) + .map { line => (line, line.split("\\s+")) } + .filter(_._2.length > 2) //n >= 3 + .map { case (line, tokens) => + val objectName = tokens(1) + val property = tokens(2) + val propertyValue = line.drop(objectName.length + property.length + 15) //"add_property" (12) + spaces (3) + (objectName, property, propertyValue) } - propertyValue = propertyValue.trim - data += ((objectName, property, propertyValue)) - } + .toList + stream.close() + data } - stream.close() - data } } object PropertyOverrideManager { - final case object GetOverridesMessage extends EventMessage { - def response(): EventResponse = null - } + final case object GetOverridesMessage } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala index dcc3535be..bd15519f0 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala @@ -6,33 +6,15 @@ import net.psforever.objects.equipment.Equipment import net.psforever.objects.inventory.InventoryItem import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.zones.Zone -import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.ObjectCreateMessage import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent} -import net.psforever.services.base.{EventMessage, EventResponse, SelfResponseMessage} +import net.psforever.services.base.{EventMessage, EventResponse, SelfRespondingEvent} import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} object VehicleAction { - trait Action extends EventMessage { - def response(): EventResponse = null - } + final case class ChildObjectState(object_guid: PlanetSideGUID, pitch: Float, yaw: Float) extends SelfRespondingEvent - final case class ChangeAmmo( - weapon_guid: PlanetSideGUID, - weapon_slot: Int, - old_ammo_guid: PlanetSideGUID, - ammo_id: Int, - ammo_guid: PlanetSideGUID, - ammo_data: ConstructorData - ) extends SelfResponseMessage - - final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class ChildObjectState(object_guid: PlanetSideGUID, pitch: Float, yaw: Float) extends SelfResponseMessage - - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfResponseMessage + final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent final case class DeployRequest( object_guid: PlanetSideGUID, @@ -40,9 +22,9 @@ object VehicleAction { unk1: Int, unk2: Boolean, pos: Vector3 - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class DismountVehicle(bailType: BailType.Value, unk2: Boolean) extends SelfResponseMessage + final case class DismountVehicle(bailType: BailType.Value, unk2: Boolean) extends SelfRespondingEvent final case class EquipmentCreatedInSlot(pkt: ObjectCreateMessage) extends EventResponse @@ -55,7 +37,6 @@ object VehicleAction { ObjectCreateMessageParent(target_guid, slot), definition.Packet.ConstructorData(equipment).get ) - ObjectCreateMessageParent(target_guid, slot) VehicleAction.EquipmentCreatedInSlot(pkt) } } @@ -75,49 +56,35 @@ object VehicleAction { unk8: Int, unk9: Long, unkA: Long - ) extends SelfResponseMessage - - final case class GenericObjectAction(guid: PlanetSideGUID, action: Int) extends SelfResponseMessage - - final case class HitHint(source_guid: PlanetSideGUID) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class InventoryState( obj: PlanetSideGameObject, parent_guid: PlanetSideGUID, start: Int, con_data: ConstructorData - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class InventoryState2(obj_guid: PlanetSideGUID, parent_guid: PlanetSideGUID, value: Int) extends SelfResponseMessage + final case class InventoryState2(obj_guid: PlanetSideGUID, parent_guid: PlanetSideGUID, value: Int) extends SelfRespondingEvent - final case class KickPassenger(unk1: Int, unk2: Boolean, vehicle_guid: PlanetSideGUID) extends SelfResponseMessage + final case class KickPassenger(unk1: Int, unk2: Boolean, vehicle_guid: PlanetSideGUID) extends SelfRespondingEvent final case class LoadVehicle( vehicle: Vehicle, vtype: Int, vguid: PlanetSideGUID, vdata: ConstructorData - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class MountVehicle(object_guid: PlanetSideGUID, seat: Int) extends SelfResponseMessage + final case class MountVehicle(object_guid: PlanetSideGUID, seat: Int) extends SelfRespondingEvent - final case class ObjectDelete(guid: PlanetSideGUID) extends SelfResponseMessage + final case class Ownership(vehicle_guid: PlanetSideGUID) extends SelfRespondingEvent - final case class Ownership(vehicle_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class PlanetsideAttribute( - target_guid: PlanetSideGUID, - attribute_type: Int, - attribute_value: Long - ) extends SelfResponseMessage - - final case class Reload(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends SelfRespondingEvent final case class RevealPlayer(player_guid: PlanetSideGUID) extends EventResponse - final case class SeatPermissions(vehicle_guid: PlanetSideGUID, seat_group: Int, permission: Long) extends SelfResponseMessage + final case class SeatPermissions(vehicle_guid: PlanetSideGUID, seat_group: Int, permission: Long) extends SelfRespondingEvent final case class StowCreatedEquipment( vehicle_guid: PlanetSideGUID, @@ -127,13 +94,11 @@ object VehicleAction { idata: ConstructorData ) extends EventResponse - final case class StowEquipment(vehicle_guid: PlanetSideGUID, slot: Int, item: Equipment) extends SelfResponseMessage + final case class StowEquipment(vehicle_guid: PlanetSideGUID, slot: Int, item: Equipment) extends SelfRespondingEvent - final case class UnloadVehicle(vehicle: Vehicle, vehicle_guid: PlanetSideGUID) extends SelfResponseMessage + final case class UnloadVehicle(vehicle: Vehicle, vehicle_guid: PlanetSideGUID) extends SelfRespondingEvent - final case class UnstowEquipment(item_guid: PlanetSideGUID) extends SelfResponseMessage - - final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends SelfResponseMessage + final case class UnstowEquipment(item_guid: PlanetSideGUID) extends SelfRespondingEvent final case class VehicleState( vehicle_guid: PlanetSideGUID, @@ -147,9 +112,7 @@ object VehicleAction { wheel_direction: Int, unk5: Boolean, unk6: Boolean - ) extends SelfResponseMessage - - final case class SendResponse(msg: PlanetSideGamePacket) extends SelfResponseMessage + ) extends SelfRespondingEvent final case class UpdateAmsSpawnList(list: List[SpawnTube]) extends EventResponse @@ -170,9 +133,9 @@ object VehicleAction { new_channel: String, vehicle: Vehicle, vehicle_to_delete: PlanetSideGUID - ) extends SelfResponseMessage + ) extends SelfRespondingEvent - final case class KickCargo(cargo: Vehicle, speed: Int, delay: Long) extends SelfResponseMessage + final case class KickCargo(cargo: Vehicle, speed: Int, delay: Long) extends SelfRespondingEvent final case class ChangeLoadout( target_guid: PlanetSideGUID, @@ -180,7 +143,7 @@ object VehicleAction { new_weapons: List[InventoryItem], old_inventory: List[(Equipment, PlanetSideGUID)], new_inventory: List[InventoryItem] - ) extends SelfResponseMessage + ) extends SelfRespondingEvent import net.psforever.objects.serverobject.tube.SpawnTube private def AmsSpawnPoints(zone: Zone): List[SpawnTube] = { diff --git a/src/test/scala/objects/DamageableTest.scala b/src/test/scala/objects/DamageableTest.scala index aae4b98e6..d3ac0235d 100644 --- a/src/test/scala/objects/DamageableTest.scala +++ b/src/test/scala/objects/DamageableTest.scala @@ -37,6 +37,7 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.base.DamageResolution import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.vital.resolution.ResolutionCalculations.Output +import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} class DamageableTest extends Specification { val player1: Player = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.TR, CharacterSex.Male, 0, CharacterVoice.Mute)) @@ -657,7 +658,8 @@ class DamageableMountableDamageTest extends ActorTest { msg1_3(1) match { case AvatarServiceMessage( "TestCharacter2", - AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(_, Vector3(2, 2, 2))) + _, + SendResponse(Seq(DamageWithPositionMessage(_, Vector3(2, 2, 2)))) ) => true case _ => false @@ -830,7 +832,7 @@ class DamageableWeaponTurretDamageTest extends ActorTest { val msg4 = avatarProbe.receiveOne(500 milliseconds) assert( msg12 match { - case VehicleServiceMessage("test", _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(2), 0, _)) => true + case VehicleServiceMessage("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -847,7 +849,8 @@ class DamageableWeaponTurretDamageTest extends ActorTest { msg4 match { case AvatarServiceMessage( "TestCharacter2", - AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(_, Vector3(2, 2, 2))) + _, + SendResponse(Seq(DamageWithPositionMessage(_, Vector3(2, 2, 2)))) ) => true case _ => false @@ -933,7 +936,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest { case VehicleServiceMessage( "test", _, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(2), 27, 1) + PlanetsideAttribute(PlanetSideGUID(2), 27, 1) ) => true case _ => false @@ -944,7 +947,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest { case VehicleServiceMessage( "test", _, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(5), 27, 1) + PlanetsideAttribute(PlanetSideGUID(5), 27, 1) ) => true case _ => false @@ -1086,7 +1089,7 @@ class DamageableWeaponTurretDestructionTest extends ActorTest { assert(false, s"DamageableWeaponTurretDestructionTest-3: player not dead - $msg3") } msg12_4(2) match { - case AvatarServiceMessage("test", _, AvatarAction.ObjectDelete(PlanetSideGUID(5), _)) => ; + case AvatarServiceMessage("test", _, ObjectDelete(PlanetSideGUID(5), _)) => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-4: ${msg12_4(2)}") } @@ -1181,13 +1184,13 @@ class DamageableVehicleDamageTest extends ActorTest { val msg4 = avatarProbe.receiveOne(200 milliseconds) assert( msg12.head match { - case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 68, _)) => true + case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 68, _)) => true case _ => false } ) assert( msg12(1) match { - case VehicleServiceMessage("test", _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 0, _)) => true + case VehicleServiceMessage("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true case _ => false } ) @@ -1203,8 +1206,9 @@ class DamageableVehicleDamageTest extends ActorTest { assert( msg4 match { case AvatarServiceMessage( - "TestCharacter2", - AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(9, Vector3(2, 0, 0))) + "TestCharacter2", + _, + SendResponse(Seq(DamageWithPositionMessage(9, Vector3(2, 0, 0)))) ) => true case _ => false @@ -1317,11 +1321,11 @@ class DamageableVehicleDamageMountedTest extends FreedContextActorTest { val msg3 = activityProbe.receiveOne(500 milliseconds) val msg45 = avatarProbe.receiveN(2,500 milliseconds) msg12.head match { - case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 68, _)) => ; + case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 68, _)) => ; case _ => assert(false) } msg12(1) match { - case VehicleServiceMessage("test", _, VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), PlanetSideGUID(1), 0, _)) => ; + case VehicleServiceMessage("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => ; case _ => assert(false) } msg3 match { @@ -1334,14 +1338,16 @@ class DamageableVehicleDamageMountedTest extends FreedContextActorTest { msg45.head match { case AvatarServiceMessage( "TestCharacter2", - AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(400, Vector3(2, 0, 0))) + _, + SendResponse(Seq(DamageWithPositionMessage(400, Vector3(2, 0, 0)))) ) => ; case _ => assert(false) } msg45(1) match { case AvatarServiceMessage( "TestCharacter3", - AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(0, Vector3(2, 0, 0))) + _, + SendResponse(Seq(DamageWithPositionMessage(0, Vector3(2, 0, 0)))) ) => ; case _ => assert(false) } @@ -1455,7 +1461,7 @@ class DamageableVehicleJammeringMountedTest extends FreedContextActorTest { case VehicleServiceMessage( "test", _, - VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(4), 27, 1) + PlanetsideAttribute(PlanetSideGUID(4), 27, 1) ) => true case _ => false @@ -1736,7 +1742,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // ) // assert( // msg_avatar.exists({ -// case AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(0), PlanetSideGUID(2), _)) => true +// case AvatarServiceMessage("test", ObjectDelete(PlanetSideGUID(0), PlanetSideGUID(2), _)) => true // case _ => false // }) // ) @@ -1757,7 +1763,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // case VehicleServiceMessage( // "test", // _, -// VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(4), 27, 0) +// PlanetsideAttribute(PlanetSideGUID(4), 27, 0) // ) => // true // case _ => false @@ -1768,7 +1774,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // case VehicleServiceMessage( // "test", // _, -// VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, PlanetSideGUID(1), 68, 0) +// PlanetsideAttribute(PlanetSideGUID(1), 68, 0) // ) => // true // case _ => false diff --git a/src/test/scala/objects/DeployableBehaviorTest.scala b/src/test/scala/objects/DeployableBehaviorTest.scala index fb0371db5..dab1aafcf 100644 --- a/src/test/scala/objects/DeployableBehaviorTest.scala +++ b/src/test/scala/objects/DeployableBehaviorTest.scala @@ -15,6 +15,7 @@ import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} import net.psforever.packet.game._ import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{ObjectDelete, SendResponse} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types._ @@ -161,9 +162,7 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { case AvatarServiceMessage( "TestCharacter1", _, - AvatarAction.SendResponse( - ObjectDeployedMessage(0, "jammer_mine", DeployOutcome.Success, 1, 20) - ) + SendResponse(Seq(ObjectDeployedMessage(0, "jammer_mine", DeployOutcome.Success, 1, 20))) ) => ; case _ => assert(false, "owned setup test, 2 - did not receive build confirmation") @@ -199,14 +198,15 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { } eventsMsgs(5) match { case AvatarServiceMessage( - "TestCharacter1", _, - AvatarAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(1), 21)) + "TestCharacter1", + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(1), 21))) ) => ; case _ => assert(false, "owned setup test, 2 - build action not reset (GOAM21)") } eventsMsgs(6) match { - case AvatarServiceMessage("test", _, AvatarAction.ObjectDelete(PlanetSideGUID(2), 0)) => ; + case AvatarServiceMessage("test", _, ObjectDelete(PlanetSideGUID(2), 0)) => ; case _ => assert(false, "owned setup test, 2 - construction tool not deleted") } diff --git a/src/test/scala/objects/DoorTest.scala b/src/test/scala/objects/DoorTest.scala index 84d096522..486b8b5cb 100644 --- a/src/test/scala/objects/DoorTest.scala +++ b/src/test/scala/objects/DoorTest.scala @@ -12,7 +12,7 @@ import net.psforever.objects.{Default, GlobalDefinitions, Player} import net.psforever.objects.serverobject.doors.{Door, DoorControl} import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.zones.{Zone, ZoneMap} -import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse} +import net.psforever.services.local.{DoorMessage, LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse} import net.psforever.types._ import org.specs2.mutable.Specification @@ -77,7 +77,7 @@ class DoorControlOpenTest extends ActorTest { door.Actor ! CommonMessages.Use(player) val reply = probe.receiveOne(1000 milliseconds) assert(reply match { - case LocalServiceMessage("test", LocalAction.DoorOpens(PlanetSideGUID(0), _, d)) => d eq door + case DoorMessage("test", LocalAction.DoorOpens(_, thisDoor), _) => thisDoor eq door case _ => false }) assert(door.Open.isDefined) @@ -105,7 +105,7 @@ class DoorControlAlreadyOpenTest extends ActorTest { door.Actor.tell(CommonMessages.Use(player), probe.ref) val reply = probe.receiveOne(1000 milliseconds) assert(reply match { - case LocalServiceResponse("test", _, LocalAction.DoorOpens(guid)) => guid == door.GUID + case LocalServiceResponse("test", _, LocalAction.DoorOpens(_, thisDoor)) => thisDoor eq door case _ => false }) } diff --git a/src/test/scala/objects/FacilityTurretTest.scala b/src/test/scala/objects/FacilityTurretTest.scala index 51a52c702..c3fd3483b 100644 --- a/src/test/scala/objects/FacilityTurretTest.scala +++ b/src/test/scala/objects/FacilityTurretTest.scala @@ -20,6 +20,7 @@ import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.collection.mutable @@ -261,8 +262,8 @@ class FacilityTurretControlRestorationTest extends ActorTest { msg12345.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction - .SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _))) ) => true case _ => false @@ -290,7 +291,8 @@ class FacilityTurretControlRestorationTest extends ActorTest { msg12345(4) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) ) => true case _ => false diff --git a/src/test/scala/objects/GeneratorTest.scala b/src/test/scala/objects/GeneratorTest.scala index ef2c175e4..df0d2f927 100644 --- a/src/test/scala/objects/GeneratorTest.scala +++ b/src/test/scala/objects/GeneratorTest.scala @@ -25,6 +25,7 @@ import net.psforever.packet.game.{InventoryStateMessage, RepairMessage, TriggerE import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.SendResponse import scala.concurrent.duration._ @@ -326,7 +327,8 @@ class GeneratorControlDestroyedTest extends ActorTest { msg_avatar2(2) match { case AvatarServiceMessage( "test", - AvatarAction.SendResponse(_, TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None)) + _, + SendResponse(Seq(TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None))) ) => true case _ => false @@ -454,7 +456,8 @@ class GeneratorControlKillsTest extends ActorTest { msg_avatar2(2) match { case AvatarServiceMessage( "test", - AvatarAction.SendResponse(_, TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None)) + _, + SendResponse(Seq(TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None))) ) => true case _ => false @@ -820,8 +823,8 @@ class GeneratorControlRepairPastRestorePoint extends ActorTest { msg_avatar.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction - .SendResponse(_, InventoryStateMessage(ValidPlanetSideGUID(5), _, ValidPlanetSideGUID(4), _)) + _, + SendResponse(Seq(InventoryStateMessage(ValidPlanetSideGUID(5), _, ValidPlanetSideGUID(4), _))) ) => true case _ => false @@ -837,7 +840,8 @@ class GeneratorControlRepairPastRestorePoint extends ActorTest { msg_avatar(2) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, RepairMessage(ValidPlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(ValidPlanetSideGUID(2), _))) ) => true case _ => false diff --git a/src/test/scala/objects/PlayerControlTest.scala b/src/test/scala/objects/PlayerControlTest.scala index 3c343b439..7de59c476 100644 --- a/src/test/scala/objects/PlayerControlTest.scala +++ b/src/test/scala/objects/PlayerControlTest.scala @@ -25,6 +25,7 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations.Output import net.psforever.packet.game._ import net.psforever.types._ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.{HintsAtAttacker, SendResponse} import scala.concurrent.duration._ @@ -70,7 +71,8 @@ class PlayerControlHealTest extends ActorTest { msg_avatar.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) ) => true case _ => false @@ -96,7 +98,8 @@ class PlayerControlHealTest extends ActorTest { msg_avatar(3) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, RepairMessage(PlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) ) => true case _ => false @@ -148,7 +151,8 @@ class PlayerControlHealSelfTest extends ActorTest { msg_avatar1.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) ) => true case _ => false @@ -171,7 +175,8 @@ class PlayerControlHealSelfTest extends ActorTest { msg_avatar2.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) ) => true case _ => false @@ -231,7 +236,8 @@ class PlayerControlRepairTest extends ActorTest { msg_avatar.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) ) => true case _ => false @@ -257,7 +263,8 @@ class PlayerControlRepairTest extends ActorTest { msg_avatar(3) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, RepairMessage(PlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) ) => true case _ => false @@ -321,7 +328,8 @@ class PlayerControlRepairSelfTest extends ActorTest { msg_avatar1.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) ) => true case _ => false @@ -344,7 +352,8 @@ class PlayerControlRepairSelfTest extends ActorTest { msg_avatar2.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) ) => true case _ => false @@ -454,7 +463,8 @@ class PlayerControlDamageTest extends ActorTest { msg_avatar(2) match { case AvatarServiceMessage( "TestCharacter2", - AvatarAction.HitHint(PlanetSideGUID(1), PlanetSideGUID(2)) + PlanetSideGUID(1), + HintsAtAttacker(PlanetSideGUID(2)) ) => true case _ => false @@ -570,7 +580,8 @@ class PlayerControlDeathStandingTest extends ActorTest { msg_avatar(4) match { case AvatarServiceMessage( "TestCharacter2", - AvatarAction.SendResponse(_, DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _)) + _, + SendResponse(Seq(DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _))) ) => true case _ => false @@ -681,7 +692,8 @@ class PlayerControlDeathStandingTest extends ActorTest { // msg_avatar(2) match { // case AvatarServiceMessage( // "TestCharacter2", -// AvatarAction.SendResponse(_, DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _)) +// _, +// SendResponse(DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _)) // ) => // true // case _ => false diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index fad1035e3..b3a416422 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -18,6 +18,7 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.concurrent.duration._ @@ -72,8 +73,8 @@ class RepairableEntityRepairTest extends ActorTest { msg123.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction - .SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _))) ) => true case _ => false @@ -89,7 +90,8 @@ class RepairableEntityRepairTest extends ActorTest { msg123(2) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) ) => true case _ => false @@ -189,8 +191,8 @@ class RepairableAmenityTest extends ActorTest { msg12345.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction - .SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _))) ) => true case _ => false @@ -218,7 +220,8 @@ class RepairableAmenityTest extends ActorTest { msg12345(4) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) ) => true case _ => false @@ -287,8 +290,8 @@ class RepairableTurretWeapon extends ActorTest { msg12345.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction - .SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _))) ) => true case _ => false @@ -305,7 +308,8 @@ class RepairableTurretWeapon extends ActorTest { msg12345(4) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(2), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) ) => true case _ => false @@ -368,8 +372,8 @@ class RepairableVehicleRepair extends ActorTest { msg123.head match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction - .SendResponse(PlanetSideGUID(0), InventoryStateMessage(PlanetSideGUID(6), _, PlanetSideGUID(5), _)) + _, + SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(6), _, PlanetSideGUID(5), _))) ) => true case _ => false @@ -385,7 +389,8 @@ class RepairableVehicleRepair extends ActorTest { msg123(2) match { case AvatarServiceMessage( "TestCharacter1", - AvatarAction.SendResponse(PlanetSideGUID(0), RepairMessage(PlanetSideGUID(1), _)) + _, + SendResponse(Seq(RepairMessage(PlanetSideGUID(1), _))) ) => true case _ => false diff --git a/src/test/scala/objects/ResourceSiloTest.scala b/src/test/scala/objects/ResourceSiloTest.scala index aa56739af..4404ab2a3 100644 --- a/src/test/scala/objects/ResourceSiloTest.scala +++ b/src/test/scala/objects/ResourceSiloTest.scala @@ -18,6 +18,7 @@ import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.objects.avatar.Avatar +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.{InterstellarClusterService, Service, ServiceManager} import net.psforever.services.galaxy.GalaxyService @@ -235,7 +236,7 @@ class ResourceSiloControlNtuWarningTest extends ActorTest { val reply = zoneEvents.receiveOne(5000 milliseconds) reply match { - case AvatarServiceMessage("nowhere", AvatarAction.PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; + case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; case _ => assert(ResourceSiloTest.fail, s"$reply is wrong") } assert(!obj.LowNtuWarningOn) @@ -274,12 +275,12 @@ class ResourceSiloControlUpdate1Test extends ActorTest { assert(obj.NtuCapacitor == 305) assert(obj.CapacitorDisplay == 3) reply1.head match { - case AvatarServiceMessage("nowhere", AvatarAction.PlanetsideAttribute(PlanetSideGUID(1), 45, 3)) => ; + case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(1), 45, 3)) => ; case _ => assert(ResourceSiloTest.fail, s"$reply1 is wrong") } assert(reply2.isInstanceOf[BuildingActor.MapUpdate], s"$reply2 is wrong") reply1(1) match { - case AvatarServiceMessage("nowhere", AvatarAction.PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; + case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; case _ => assert(ResourceSiloTest.fail, s"${reply1(1)} is wrong") } assert(!obj.LowNtuWarningOn) @@ -318,12 +319,12 @@ class ResourceSiloControlUpdate2Test extends ActorTest { assert(obj.NtuCapacitor == 205) assert(obj.CapacitorDisplay == 2) reply1.head match { - case AvatarServiceMessage("nowhere", AvatarAction.PlanetsideAttribute(PlanetSideGUID(1), 45, 2)) => ; + case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(1), 45, 2)) => ; case _ => assert(ResourceSiloTest.fail, s"$reply1 is wrong") } assert(reply2.isInstanceOf[BuildingActor.MapUpdate]) reply1(1) match { - case AvatarServiceMessage("nowhere", AvatarAction.PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; + case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; case _ => assert(ResourceSiloTest.fail, s"${reply1(1)} is wrong") } assert(!obj.LowNtuWarningOn) diff --git a/src/test/scala/objects/TelepadRouterTest.scala b/src/test/scala/objects/TelepadRouterTest.scala index 7eff27c37..0af8ff646 100644 --- a/src/test/scala/objects/TelepadRouterTest.scala +++ b/src/test/scala/objects/TelepadRouterTest.scala @@ -15,6 +15,7 @@ import net.psforever.objects.vehicles.{Utility, UtilityType} import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game._ +import net.psforever.services.base.messages.SendResponse import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{DriveState, PlanetSideGUID, Vector3} @@ -281,51 +282,58 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { eventsMsgs(2) match { case LocalServiceMessage( "test", - LocalAction.SendResponse( + _, + SendResponse(Seq( ObjectCreateMessage(_, 744, PlanetSideGUID(3), Some(ObjectCreateMessageParent(PlanetSideGUID(2), 2)), _) - ) + )) ) => ; case _ => assert(false, "link to router test - did not create the internal router telepad (1)") } eventsMsgs(3) match { case LocalServiceMessage( "test", - LocalAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(3), 27)) + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 27))) ) => ; case _ => assert(false, "link to router test - did not create the internal router telepad (2)") } eventsMsgs(4) match { case LocalServiceMessage( "test", - LocalAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(3), 30)) + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 30))) ) => ; case _ => assert(false, "link to router test - did not create the internal router telepad (3)") } eventsMsgs(5) match { case LocalServiceMessage( "test", - LocalAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(3), 27)) + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 27))) ) => ; case _ => assert(false, "link to router test - did not link the internal telepad (1)") } eventsMsgs(6) match { case LocalServiceMessage( "test", - LocalAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(3), 28)) + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 28))) ) => ; case _ => assert(false, "link to router test - did not link the internal telepad (2)") } eventsMsgs(7) match { case LocalServiceMessage( "test", - LocalAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(1), 27)) + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(1), 27))) ) => ; case _ => assert(false, "link to router test - did not link the telepad (1)") } eventsMsgs(8) match { case LocalServiceMessage( "test", - LocalAction.SendResponse(GenericObjectActionMessage(PlanetSideGUID(1), 28)) + _, + SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(1), 28))) ) => ; case _ => assert(false, "link to router test - did not link the telepad (2)") } diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index 119fab0b3..fb723f6ad 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -25,6 +25,7 @@ import net.psforever.objects.vital.{ShieldCharge, SpawningActivity, Vitality} import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game._ import net.psforever.services.ServiceManager +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types._ @@ -141,27 +142,27 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest { // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-1: ${vehicle_msg.head}") // } // vehicle_msg(1) match { -// case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => ; +// case VehicleServiceMessage(_, _, SendResponse(PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-2: ${vehicle_msg(1)}") // } // vehicle_msg(2) match { -// case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => ; +// case VehicleServiceMessage(_, _, SendResponse(PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-3: ${vehicle_msg(2)}") // } // vehicle_msg(3) match { -// case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; +// case VehicleServiceMessage("test", _, SendResponse(CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-4: ${vehicle_msg(3)}") // } // vehicle_msg(4) match { -// case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => ; +// case VehicleServiceMessage("test", _, SendResponse(ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-5: ${vehicle_msg(4)}") // } // vehicle_msg(5) match { -// case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => ; +// case VehicleServiceMessage("test", _, SendResponse(CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-6: ${vehicle_msg(5)}") // } @@ -232,27 +233,27 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor assert(lodestar.Seats(0).occupant.isEmpty) //cargo dismounting messages vehicleMsgs(1) match { - case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => () + case VehicleServiceMessage(_, _, SendResponse(Seq(PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-2: ${vehicleMsgs(1)}") } vehicleMsgs(2) match { - case VehicleServiceMessage(_, _, VehicleAction.SendResponse(_, PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => () + case VehicleServiceMessage(_, _, SendResponse(Seq(PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-3: ${vehicleMsgs(2)}") } vehicleMsgs(3) match { - case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; + case VehicleServiceMessage("test", _, SendResponse(Seq(CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0)))) => ; case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-4: ${vehicleMsgs(3)}") } vehicleMsgs(4) match { - case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => () + case VehicleServiceMessage("test", _, SendResponse(Seq(ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-5: ${vehicleMsgs(4)}") } vehicleMsgs(5) match { - case VehicleServiceMessage("test", _, VehicleAction.SendResponse(_, CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => () + case VehicleServiceMessage("test", _, SendResponse(Seq(CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-6: ${vehicleMsgs(5)}") } @@ -476,7 +477,7 @@ class VehicleControlShieldsChargingTest extends ActorTest { vehicle.Actor ! CommonMessages.ChargeShields(15, None) val msg = probe.receiveOne(500 milliseconds) assert(msg match { - case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true + case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true case _ => false }) assert(vehicle.Shields == 15) @@ -544,7 +545,7 @@ class VehicleControlShieldsNotChargingTooEarlyTest extends ActorTest { val msg = probe.receiveOne(200 milliseconds) //assert(msg.isInstanceOf[Vehicle.UpdateShieldsCharge]) assert(msg match { - case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(10), 68, 15)) => true + case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true case _ => false }) assert(vehicle.Shields == 15) @@ -1004,7 +1005,7 @@ class VehicleControlInteractWithLavaTest extends ActorTest { msg_burn.foreach { msg => assert( msg match { - case VehicleServiceMessage("test-zone", _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(2), 0, _)) => true + case VehicleServiceMessage("test-zone", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -1102,7 +1103,7 @@ class ApcControlCanChargeCapacitor extends FreedContextActorTest { do { val msg = vehicleProbe.receiveOne(3.seconds) msg match { - case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(1), 113, capacitance)) => + case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 113, capacitance)) => assert(capacitance > 0) case _ => assert(false) @@ -1176,16 +1177,16 @@ class ApcControlCanEmp extends FreedContextActorTest { apc.Actor ! SpecialEmp.Burst() val vehicleMsgs = vehicleProbe.receiveN(2, 500.milliseconds) vehicleMsgs.head match { - case VehicleServiceMessage(_, _, VehicleAction.PlanetsideAttribute(_, PlanetSideGUID(1), 113, 0)) => ; + case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 113, 0)) => ; case _ => assert(false) } vehicleMsgs(1) match { case VehicleServiceMessage( "test-zone", _, - VehicleAction.SendResponse(_, + SendResponse(Seq( TriggerEffectMessage(_, "apc_explosion_emp_vs", None, Some(TriggeredEffectLocation(Vector3.Zero, Vector3.Zero))) - ) + )) ) => ; case _ => assert(false) } diff --git a/src/test/scala/service/LocalServiceTest.scala b/src/test/scala/service/LocalServiceTest.scala index 2b6187f7a..832f51a7a 100644 --- a/src/test/scala/service/LocalServiceTest.scala +++ b/src/test/scala/service/LocalServiceTest.scala @@ -10,6 +10,7 @@ import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal import net.psforever.objects.vehicles.control.VehicleControl import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game._ +import net.psforever.services.base.messages.{SendResponse, SetEmpire} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.{Service, ServiceManager} import net.psforever.services.local._ @@ -98,7 +99,7 @@ class DeployItemTest extends ActorTest { "pass DeployItem" in { service ! Service.Join("test") service ! LocalServiceMessage("test", LocalAction.DeployItem(obj)) - expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), LocalAction.SendResponse(pkt))) + expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), SendResponse(Seq(pkt)))) } } } @@ -158,9 +159,9 @@ class HackClearTest extends ActorTest { "pass HackClear" in { val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") service ! Service.Join("test") - service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.HackClear(obj, 0L, HackState7.Unk8)) + service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.HackClear(obj.GUID, 0L, HackState7.Unk8)) expectMsg( - LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.SendHackMessageHackCleared(PlanetSideGUID(40), 0L, HackState7.Unk8)) + LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.HackClear(PlanetSideGUID(40), 0L, HackState7.Unk8)) ) } } @@ -243,12 +244,12 @@ class SetEmpireTest extends ActorTest { "pass SetEmpire" in { val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR)) + service ! LocalServiceMessage("test", SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR)) expectMsg( LocalServiceResponse( "/test/Local", PlanetSideGUID(0), - LocalAction.SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR) + SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR) ) ) } From 78bc93eb09356c0733a3825f72affb243398eac4 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Thu, 5 Feb 2026 02:08:35 -0500 Subject: [PATCH 09/32] a single envelope for inbound messages, replacing [Avatar|Local|Vehicle|Galaxy]ServiceMessage; all variations of PlanetsideAttribute message have been reduced to the PlanetsideAttribute message --- .../actors/session/AvatarActor.scala | 12 +-- .../session/csr/AvatarHandlerLogic.scala | 6 -- .../session/normal/AvatarHandlerLogic.scala | 8 +- .../spectator/AvatarHandlerLogic.scala | 9 +- .../session/support/GeneralOperations.scala | 8 +- .../support/SessionOutfitHandlers.scala | 16 ++-- .../session/support/ZoningOperations.scala | 10 +- .../zone/building/MajorFacilityLogic.scala | 24 ++--- .../net/psforever/objects/Vehicles.scala | 7 +- .../objects/avatar/PlayerControl.scala | 34 +++---- .../damage/DamageableAmenity.scala | 9 +- .../damage/DamageableEntity.scala | 8 +- .../repair/RepairableAmenity.scala | 9 +- .../repair/RepairableEntity.scala | 10 +- .../terminals/ProximityTerminalControl.scala | 11 +-- .../serverobject/turret/TurretControl.scala | 11 ++- .../services/avatar/AvatarAction.scala | 4 - .../avatar/AvatarServiceMessage.scala | 12 +-- .../services/base/MessageEnvelope.scala | 7 ++ .../galaxy/GalaxyServiceMessage.scala | 12 +-- .../services/local/LocalServiceMessage.scala | 12 +-- .../vehicle/VehicleServiceMessage.scala | 16 ++-- src/test/scala/objects/DamageableTest.scala | 77 +++++++-------- .../objects/DeployableBehaviorTest.scala | 33 ++++--- src/test/scala/objects/DeployableTest.scala | 33 ++++--- src/test/scala/objects/DeploymentTest.scala | 19 ++-- src/test/scala/objects/DoorTest.scala | 2 +- .../scala/objects/FacilityTurretTest.scala | 19 ++-- src/test/scala/objects/GeneratorTest.scala | 27 +++--- .../scala/objects/PlayerControlTest.scala | 94 ++++++++++--------- src/test/scala/objects/RepairableTest.scala | 37 ++++---- src/test/scala/objects/ResourceSiloTest.scala | 12 +-- .../scala/objects/TelepadRouterTest.scala | 47 ++++++---- .../scala/objects/VehicleControlTest.scala | 39 ++++---- .../objects/terminal/ProximityTest.scala | 15 +-- 35 files changed, 354 insertions(+), 355 deletions(-) create mode 100644 src/main/scala/net/psforever/services/base/MessageEnvelope.scala diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 749255c23..931c2ee0b 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -2077,8 +2077,8 @@ class AvatarActor( avatarCopy(avatar.copy(decoration = avatar.decoration.copy(cosmetics = Some(cosmetics)))) zone.AvatarEvents ! AvatarServiceMessage( zone.id, - session.get.player.GUID, - AvatarAction.PlanetsideAttributeToAll( + PlanetsideAttribute( + session.get.player.GUID, 106, Cosmetic.valuesToAttributeValue(cosmetics) ) @@ -3002,13 +3002,13 @@ class AvatarActor( val next = BattleRank.withExperience(newBep).value val br24 = BattleRank.BR24.value sessionActor ! SessionActor.SendResponse(BattleExperienceMessage(pguid, newBep, localModifier)) - events ! AvatarServiceMessage(zoneId, pguid, AvatarAction.PlanetsideAttributeToAll(17, newBep)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(pguid, 17, newBep)) if (current < br24 && next >= br24 || current >= br24 && next < br24) { setCosmetics(Set()).onComplete { _ => val evts = events val name = player.Name val guid = pguid - evts ! AvatarServiceMessage(name, guid, AvatarAction.PlanetsideAttributeToAll(106, 1)) //set to no helmet + evts ! AvatarServiceMessage(name, PlanetsideAttribute(guid, 106, 1)) //set to no helmet } } // when the level is reduced, take away any implants over the implant slot limit @@ -3053,7 +3053,7 @@ class AvatarActor( val sess = session.get val zone = sess.zone avatar = avatar.copy(cep = cep) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, sess.player.GUID, AvatarAction.PlanetsideAttributeToAll(18, cep)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, PlanetsideAttribute(sess.player.GUID, 18, cep)) case Failure(exception) => log.error(exception)("db failure") } @@ -3848,7 +3848,7 @@ class AvatarActor( val newHealth = player.Health = originalHealth + 1 val events = zone.AvatarEvents player.LogActivity(HealFromImplant(implant.definition.implantType, 1)) - events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) + events ! AvatarServiceMessage(zone.id, PlanetsideAttribute(guid, 0, newHealth)) false } else { !aliveAndWounded 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 84dadf753..5b6306f24 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -249,12 +249,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) - case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - - case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) 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 dc6283f45..1ff0bdde2 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -248,12 +248,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) - case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - - case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => sendResponse(PlanetsideStringAttributeMessage(guid, attributeType, attributeValue)) @@ -699,7 +693,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val events = continent.AvatarEvents ops.killedWhileMounted(obj, playerGuid) //make player invisible on client - events ! AvatarServiceMessage(player.Name, playerGuid, AvatarAction.PlanetsideAttributeToAll(29, 1)) + events ! AvatarServiceMessage(player.Name, PlanetsideAttribute(playerGuid, 29, 1)) //only the dead player should "see" their own body, so that the death camera has something to focus on events ! AvatarServiceMessage(continent.id, playerGuid, ObjectDelete(playerGuid)) } 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 133c9f289..d1a957407 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -212,12 +212,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) - case AvatarAction.PlanetsideAttributeToAll(attributeType, attributeValue) => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - - case AvatarAction.PlanetsideAttributeSelf(attributeType, attributeValue) if isSameTarget => - sendResponse(PlanetsideAttributeMessage(guid, attributeType, attributeValue)) - case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) @@ -494,8 +488,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) continent.AvatarEvents ! AvatarServiceMessage( continent.id, - revivalTargetGuid, - AvatarAction.PlanetsideAttributeToAll(attribute_type=0, health) + PlanetsideAttribute(revivalTargetGuid, attribute_type=0, health) ) /* uncommon messages (utility, or once in a while) */ diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 29a32f7cd..1f259043b 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -19,7 +19,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.RemoverActor import net.psforever.services.avatar.GroundEnvelope -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} import net.psforever.services.local.support.HackCaptureActor import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} @@ -1030,8 +1030,7 @@ class GeneralOperations( player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal continent.AvatarEvents ! AvatarServiceMessage( continent.id, - player.GUID, - AvatarAction.PlanetsideAttributeToAll(8, 0) + PlanetsideAttribute(player.GUID, 8, 0) ) } } @@ -1040,8 +1039,7 @@ class GeneralOperations( private def activateMaxSpecialStateMessage(): Unit = { continent.AvatarEvents ! AvatarServiceMessage( continent.id, - player.GUID, - AvatarAction.PlanetsideAttributeToAll(8, 1) + PlanetsideAttribute(player.GUID, 8, 1) ) } diff --git a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala index be64abbbb..53c2e0b2d 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala @@ -9,6 +9,7 @@ import net.psforever.packet.game.OutfitEventAction.{Initial, Leaving, OutfitInfo import net.psforever.packet.game.OutfitMembershipResponse.PacketType.CreateResponse import net.psforever.packet.game._ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.chat.OutfitChannel import net.psforever.types.ChatMessageType import net.psforever.util.Config @@ -85,8 +86,7 @@ object SessionOutfitHandlers { player.Zone.AvatarEvents ! AvatarServiceMessage( player.Zone.id, - player.GUID, - AvatarAction.PlanetsideAttributeToAll(39, outfit.id) + PlanetsideAttribute(player.GUID, 39, outfit.id) ) player.Zone.AvatarEvents ! AvatarServiceMessage( @@ -176,8 +176,7 @@ object SessionOutfitHandlers { invited.Zone.AvatarEvents ! AvatarServiceMessage( invited.Zone.id, - invited.GUID, - AvatarAction.PlanetsideAttributeToAll(39, outfit.id) + PlanetsideAttribute(invited.GUID, 39, outfit.id) ) invited.Zone.AvatarEvents ! AvatarServiceMessage( @@ -244,8 +243,7 @@ object SessionOutfitHandlers { kickedBy.Zone.AvatarEvents ! AvatarServiceMessage( kickedBy.Zone.id, - kickedBy.GUID, - AvatarAction.PlanetsideAttributeToAll(39, 0) + PlanetsideAttribute(kickedBy.GUID, 39, 0) ) kickedBy.Zone.AvatarEvents ! AvatarServiceMessage( @@ -274,8 +272,7 @@ object SessionOutfitHandlers { kicked.Zone.AvatarEvents ! AvatarServiceMessage( kicked.Zone.id, - kicked.GUID, - AvatarAction.PlanetsideAttributeToAll(39, 0) + PlanetsideAttribute(kicked.GUID, 39, 0) ) kicked.Zone.AvatarEvents ! AvatarServiceMessage( @@ -639,8 +636,7 @@ object SessionOutfitHandlers { player.Zone.AvatarEvents ! AvatarServiceMessage( player.Zone.id, - player.GUID, - AvatarAction.PlanetsideAttributeToAll(39, outfit.id) + PlanetsideAttribute(player.GUID, 39, outfit.id) ) player.Zone.AvatarEvents ! AvatarServiceMessage( diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index c9958e852..79767068c 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -3372,7 +3372,7 @@ class ZoningOperations( if (tplayer.ExoSuit == ExoSuitType.MAX) { sendResponse(PlanetsideAttributeMessage(guid, 7, tplayer.Capacitor.toLong)) sendResponse(PlanetsideAttributeMessage(guid, 4, tplayer.Armor)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, guid, AvatarAction.PlanetsideAttributeToAll(4, tplayer.Armor)) + continent.AvatarEvents ! AvatarServiceMessage(continent.id, PlanetsideAttribute(guid, 4, tplayer.Armor)) } // for issue #1269 continent.AllPlayers.filter(_.ExoSuit == ExoSuitType.MAX).foreach(max => sendResponse(PlanetsideAttributeMessage(max.GUID, 4, max.Armor))) @@ -3496,8 +3496,12 @@ class ZoningOperations( case Some(b: Building) if b.hasCavernLockBenefit => tplayer.MaxHealth = 120 tplayer.Health = 120 - tplayer.Zone.AvatarEvents ! AvatarServiceMessage(tplayer.Zone.id, tplayer.GUID, AvatarAction.PlanetsideAttributeToAll(0, 120)) - tplayer.Zone.AvatarEvents ! AvatarServiceMessage(tplayer.Zone.id, tplayer.GUID, AvatarAction.PlanetsideAttributeToAll(1, 120)) + val guid = tplayer.GUID + val zone = tplayer.Zone + val channel = zone.id + val events = zone.AvatarEvents + events ! AvatarServiceMessage(channel, PlanetsideAttribute(guid, 0, 120)) + events ! AvatarServiceMessage(channel, PlanetsideAttribute(guid, 1, 120)) case _ => () } doorsThatShouldBeOpenInRange(pos, range = 100f) diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index ac8dd175b..caeb3cf33 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -15,8 +15,8 @@ import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, Ca import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.PlanetsideAttributeMessage import net.psforever.services.InterstellarClusterService -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{GenericObjectAction, SendResponse} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.{CaptureMessage, HackClearMessage, LocalServiceMessage} import net.psforever.services.local.support.{HackCaptureActor, HackClearActor} @@ -212,9 +212,9 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.Critical) => val events = zone.AvatarEvents val guid = building.GUID - val msg = AvatarAction.PlanetsideAttributeToAll(46, 1) + val msg = PlanetsideAttribute(guid, 46, 1) building.PlayersInSOI.foreach { player => - events ! AvatarServiceMessage(player.Name, guid, msg) + events ! AvatarServiceMessage(player.Name, msg) } true case Some(GeneratorControl.Event.Destabilized) => @@ -236,9 +236,9 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.Offline) => powerLost(details) val zone = building.Zone - val msg = AvatarAction.PlanetsideAttributeToAll(46, 2) + val msg = PlanetsideAttribute(building.GUID, 46, 2) building.PlayersInSOI.foreach { player => - zone.AvatarEvents ! AvatarServiceMessage(player.Name, building.GUID, msg) + zone.AvatarEvents ! AvatarServiceMessage(player.Name, msg) } //??? true case Some(GeneratorControl.Event.Normal) => @@ -248,11 +248,11 @@ case object MajorFacilityLogic powerRestored(details) val events = zone.AvatarEvents val guid = building.GUID - val msg1 = AvatarAction.PlanetsideAttributeToAll(46, 0) + val msg1 = PlanetsideAttribute(guid, 46, 0) val msg2 = GenericObjectAction(guid, 17) building.PlayersInSOI.foreach { player => val name = player.Name - events ! AvatarServiceMessage(name, guid, msg1) //reset ???; might be global? + events ! AvatarServiceMessage(name, msg1) //reset ???; might be global? events ! AvatarServiceMessage(name, msg2) //This facility's generator is back on line } true @@ -305,9 +305,9 @@ case object MajorFacilityLogic amenity.Actor ! powerMsg } //amenities disabled; red warning lights - events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(48, 1)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 48, 1)) //disable spawn target on deployment map - events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(38, 0)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 38, 0)) Behaviors.same } @@ -328,9 +328,9 @@ case object MajorFacilityLogic amenity.Actor ! powerMsg } //amenities enabled; normal lights - events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(48, 0)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 48, 0)) //enable spawn target on deployment map - events ! AvatarServiceMessage(zoneId, guid, AvatarAction.PlanetsideAttributeToAll(38, 1)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 38, 1)) Behaviors.same } diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 88dd99c1d..8ae8ce14f 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -13,8 +13,8 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{GenericObjectAction, SendResponse, SetEmpire} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -172,8 +172,7 @@ object Vehicles { (0 to 3).foreach(group => { vehicle.Zone.AvatarEvents ! AvatarServiceMessage( toChannel, - vehicle_guid, - AvatarAction.PlanetsideAttributeToAll(group + 10, vehicle.PermissionGroup(group).get.id) + PlanetsideAttribute(vehicle_guid, group + 10, vehicle.PermissionGroup(group).get.id) ) }) } diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 860994d03..2bfb19697 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -127,7 +127,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val zoneId = zone.id sendResponse(zone, zoneId, PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health)) sendResponse(zone, zoneId, AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) - sendResponse(zone, zoneId, revivalTargetGuid, AvatarAction.PlanetsideAttributeToAll(attribute_type=0, health)) + sendResponse(zone, zoneId, PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health)) avatarActor ! AvatarActor.InitializeImplants avatarActor ! AvatarActor.SuspendStaminaRegeneration(Duration(1, "second")) @@ -153,7 +153,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm uname, SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) - events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) + events ! AvatarServiceMessage(zone.id, PlanetsideAttribute(guid, 0, newHealth)) player.LogActivity( HealFromEquipment( PlayerSource(user), @@ -173,7 +173,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } if (player != user) { //"Someone is trying to heal you" - events ! AvatarServiceMessage(player.Name, guid, AvatarAction.PlanetsideAttributeToAll(55, 1)) + events ! AvatarServiceMessage(player.Name, PlanetsideAttribute(guid, 55, 1)) //progress bar remains visible for all heal attempts events ! AvatarServiceMessage( uname, @@ -219,7 +219,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm uname, SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) - events ! AvatarServiceMessage(zone.id, guid, AvatarAction.PlanetsideAttributeToAll(4, player.Armor)) + events ! AvatarServiceMessage(zone.id, PlanetsideAttribute(guid, 4, player.Armor)) player.LogActivity( RepairFromEquipment( PlayerSource(user), @@ -240,7 +240,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (player != user) { if (player.isAlive) { //"Someone is trying to repair you" gets strobed twice for visibility - val msg = AvatarServiceMessage(player.Name, guid, AvatarAction.PlanetsideAttributeToAll(56, 1)) + val msg = AvatarServiceMessage(player.Name, PlanetsideAttribute(guid, 56, 1)) events ! msg import scala.concurrent.ExecutionContext.Implicits.global context.system.scheduler.scheduleOnce(250 milliseconds, events, msg) @@ -315,8 +315,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, kit)) zone.AvatarEvents ! AvatarServiceMessage( zone.id, - player.GUID, - AvatarAction.PlanetsideAttributeToAll(attribute, value) + PlanetsideAttribute(player.GUID, attribute, value) ) zone.AvatarEvents ! AvatarServiceMessage( player.Name, @@ -882,8 +881,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - target.GUID, - AvatarAction.PlanetsideAttributeToAll(4, target.Armor) + PlanetsideAttribute(target.GUID, 4, target.Armor) ) } //choose @@ -939,7 +937,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm target.LogActivity(cause) //stat changes if (damageToCapacitor > 0) { - events ! AvatarServiceMessage(target.Name, targetGUID, AvatarAction.PlanetsideAttributeSelf(7, target.Capacitor.toLong)) + events ! AvatarServiceMessage(target.Name, PlanetsideAttribute(targetGUID, 7, target.Capacitor.toLong)) announceConfrontation = true //TODO should we? } if (damageToStamina > 0) { @@ -947,7 +945,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm announceConfrontation = true //TODO should we? } if (damageToHealth > 0) { - events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(0, health)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 0, health)) announceConfrontation = true } val countableDamage = damageToHealth + damageToArmor @@ -1055,10 +1053,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } events ! AvatarServiceMessage(nameChannel, player_guid, AvatarAction.Killed(cause, target.VehicleSeated)) //align client interface fields with state - events ! AvatarServiceMessage(zoneChannel, player_guid, AvatarAction.PlanetsideAttributeToAll(0, 0)) //health + events ! AvatarServiceMessage(zoneChannel, PlanetsideAttribute(player_guid, 0, 0)) //health if (target.Capacitor > 0) { target.Capacitor = 0 - events ! AvatarServiceMessage(nameChannel, player_guid, AvatarAction.PlanetsideAttributeToAll(7, 0)) // capacitor + events ! AvatarServiceMessage(nameChannel, PlanetsideAttribute(player_guid, 7, 0)) // capacitor } val attribute = DamageableEntity.attributionTo(cause, target.Zone, player_guid) events ! AvatarServiceMessage( @@ -1094,8 +1092,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case obj: Player if !jammedSound => obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Zone.id, - obj.GUID, - AvatarAction.PlanetsideAttributeToAll(27, 1) + PlanetsideAttribute(obj.GUID, 27, 1) ) super.StartJammeredSound(obj, 3000) case _ => () @@ -1131,8 +1128,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case obj: Player if jammedSound => obj.Zone.AvatarEvents ! AvatarServiceMessage( obj.Zone.id, - obj.GUID, - AvatarAction.PlanetsideAttributeToAll(27, 0) + PlanetsideAttribute(obj.GUID, 27, 0) ) super.CancelJammeredSound(obj) case _ => () @@ -1243,10 +1239,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } def UpdateAuraEffect(target: AuraEffectBehavior.Target) : Unit = { - import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} + import net.psforever.services.avatar.AvatarServiceMessage val zone = target.Zone val value = target.Aura.foldLeft(0)(_ + PlayerControl.auraEffectToAttributeValue(_)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, target.GUID, AvatarAction.PlanetsideAttributeToAll(54, value)) + zone.AvatarEvents ! AvatarServiceMessage(zone.id, PlanetsideAttribute(target.GUID, 54, value)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala index 3e936c25a..ee7329f58 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala @@ -3,7 +3,8 @@ package net.psforever.objects.serverobject.damage import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.PlanetsideAttribute /** * The "control" `Actor` mixin for damage-handling code @@ -25,7 +26,7 @@ object DamageableAmenity { * A destroyed `Amenity` target dispatches two messages to chance its model and operational states. * The common manifestation is a sparking entity that will no longer report being accessible. * These `PlanetSideAttributeMessage` attributes are the same as reported during zone load client configuration. - * @see `AvatarAction.PlanetsideAttributeToAll` + * @see `PlanetsideAttribute` * @see `AvatarServiceMessage` * @see `Zone.AvatarEvents` * @param target the entity being destroyed @@ -36,7 +37,7 @@ object DamageableAmenity { val zoneId = zone.id val events = zone.AvatarEvents val targetGUID = target.GUID - events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(50, 1)) - events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(51, 1)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 50, 1)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 51, 1)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala index 86777bf54..e7aad04fb 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala @@ -9,6 +9,7 @@ import net.psforever.objects.zones.Zone import net.psforever.types.PlanetSideGUID import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.messages.PlanetsideAttribute /** * The "control" `Actor` mixin for damage-handling code, @@ -140,7 +141,7 @@ object DamageableEntity { * - reports its adjusted its health; * - alert the activity monitor for that `Zone` about the damage; and, * - provide a feedback message regarding the damage. - * @see `AvatarAction.PlanetsideAttributeToAll` + * @see `PlanetsideAttribute` * @see `SendResponse` * @see `AvatarServiceMessage` * @see `DamageFeedbackMessage` @@ -167,8 +168,7 @@ object DamageableEntity { val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - target.GUID, - AvatarAction.PlanetsideAttributeToAll(0, target.Health) + PlanetsideAttribute(target.GUID, 0, target.Health) ) true } @@ -200,7 +200,7 @@ object DamageableEntity { val zoneId = zone.id val tguid = target.GUID val attribution = attributionTo(cause, target.Zone) - zone.AvatarEvents ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(0, target.Health)) + zone.AvatarEvents ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 0, target.Health)) if (target.isInstanceOf[SpawnTube]) {}//do nothing to prevent issue #1057 else { zone.AvatarEvents ! AvatarServiceMessage( diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala index 038f894b1..5971778e3 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala @@ -5,7 +5,8 @@ import net.psforever.objects.Tool import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.sourcing.{SourceEntry, SourceWithHealthEntry} import net.psforever.objects.vital.{DamagingActivity, RepairFromEquipment, SpawningActivity} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.PlanetsideAttribute /** * The "control" `Actor` mixin for repair-handling code @@ -27,7 +28,7 @@ object RepairableAmenity { /** * A restored `Amenity` target dispatches two messages to chance its model and operational states. * These `PlanetSideAttributeMessage` attributes are the same as reported during zone load client configuration. - * @see `AvatarAction.PlanetsideAttributeToAll` + * @see `PlanetsideAttribute` * @see `AvatarServiceMessage` * @see `Zone.AvatarEvents` * @param target the entity being destroyed @@ -37,8 +38,8 @@ object RepairableAmenity { val zoneId = zone.id val events = zone.AvatarEvents val targetGUID = target.GUID - events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(50, 0)) - events ! AvatarServiceMessage(zoneId, targetGUID, AvatarAction.PlanetsideAttributeToAll(51, 0)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 50, 0)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 51, 0)) RestorationOfHistory(target) } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index 642ee6774..0fe895f16 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -8,8 +8,8 @@ import net.psforever.objects.vital.RepairFromEquipment import net.psforever.objects.{Player, Tool} import net.psforever.packet.game.{ChatMsg, InventoryStateMessage, RepairMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} /** * The "control" `Actor` mixin for repair-handling code, @@ -67,7 +67,7 @@ trait RepairableEntity extends Repairable { * Calculate the health points change and enact that repair action if the targets are stationary. * Restore the target entity to a not destroyed state if applicable. * Always show the repair progress bar window by using the appropriate packet. - * @see `AvatarAction.PlanetsideAttributeToAll` + * @see `PlanetsideAttribute` * @see `SendResponse` * @see `AvatarService` * @see `InventoryStateMessage` @@ -140,11 +140,11 @@ trait RepairableEntity extends Repairable { val newHealth = target.Health = target.Health + amount if (target.Destroyed) { if (newHealth >= target.Definition.RepairRestoresAt) { - events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 0, newHealth)) Restoration(target) } } else { - events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(0, newHealth)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 0, newHealth)) } newHealth } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index 6c6d40b35..9c9188c27 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -27,7 +27,7 @@ import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityCo import net.psforever.objects.vital.{HealFromTerminal, RepairFromTerminal, Vitality} import net.psforever.objects.zones.ZoneAware import net.psforever.packet.game.InventoryStateMessage -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.VehicleServiceMessage @@ -354,8 +354,7 @@ object ProximityTerminalControl { target.MaxHealth = newMax zone.AvatarEvents ! AvatarServiceMessage( zone.id, - target.GUID, - AvatarAction.PlanetsideAttributeToAll(1, newMax) + PlanetsideAttribute(target.GUID, 1, newMax) ) } if (target.Health < newMax) { @@ -370,8 +369,7 @@ object ProximityTerminalControl { val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - target.GUID, - AvatarAction.PlanetsideAttributeToAll(0, target.Health) + PlanetsideAttribute(target.GUID, 0, target.Health) ) } @@ -410,8 +408,7 @@ object ProximityTerminalControl { val zone = target.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.id, - target.GUID, - AvatarAction.PlanetsideAttributeToAll(4, target.Armor) + PlanetsideAttribute(target.GUID, 4, target.Armor) ) target.Armor == maxArmor } else { diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala index 5b38b2254..150b1513e 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala @@ -8,7 +8,8 @@ import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior import net.psforever.objects.serverobject.damage.{Damageable, DamageableWeaponTurret} import net.psforever.objects.serverobject.repair.RepairableWeaponTurret import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.messages.PlanetsideAttribute trait TurretControl extends Actor @@ -39,8 +40,8 @@ trait TurretControl val zoneId = zone.id val events = zone.AvatarEvents val tguid = TurretObject.GUID - events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(50, 0)) - events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(51, 0)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 50, 0)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 51, 0)) } /** @@ -56,7 +57,7 @@ trait TurretControl val tguid = target.GUID CancelJammeredSound(target) CancelJammeredStatus(target) - events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(50, 1)) - events ! AvatarServiceMessage(zoneId, tguid, AvatarAction.PlanetsideAttributeToAll(51, 1)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 50, 1)) + events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 51, 1)) } } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala index 928f23e93..8be69ed6f 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala @@ -101,10 +101,6 @@ object AvatarAction { final case class OxygenState(player: OxygenStateTarget, vehicle: Option[OxygenStateTarget]) extends SelfRespondingEvent - final case class PlanetsideAttributeToAll(attribute_type: Int, attribute_value: Long) extends SelfRespondingEvent - - final case class PlanetsideAttributeSelf(attribute_type: Int, attribute_value: Long) extends SelfRespondingEvent - final case class PlanetsideStringAttribute(attribute_type: Int, attribute_value: String) extends SelfRespondingEvent final case class PlayerState( diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala index 529b286bc..951fd07c8 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala @@ -4,15 +4,15 @@ package net.psforever.services.avatar import net.psforever.objects.zones.Zone import net.psforever.services.{RemoverActor, Service} import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem, Release} -import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly} +import net.psforever.services.base.{EventMessage, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly, MessageEnvelope} import net.psforever.types.PlanetSideGUID -final case class AvatarServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) - extends GenericMessageEnvelope - object AvatarServiceMessage { - def apply(channel: String, actionMessage: EventMessage): AvatarServiceMessage = - AvatarServiceMessage(channel, Service.defaultPlayerGUID, actionMessage) + def apply(channel: String, msg: EventMessage): MessageEnvelope = + MessageEnvelope(channel, Service.defaultPlayerGUID, msg) + + def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = + MessageEnvelope(channel, filter, msg) } final case class ReleaseMessage( diff --git a/src/main/scala/net/psforever/services/base/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/MessageEnvelope.scala new file mode 100644 index 000000000..faad6d0d1 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/MessageEnvelope.scala @@ -0,0 +1,7 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base + +import net.psforever.types.PlanetSideGUID + +case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) + extends GenericMessageEnvelope diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala index 6b3af1685..410053f8a 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala @@ -2,14 +2,10 @@ package net.psforever.services.galaxy import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, GenericMessageEnvelope} -import net.psforever.types.PlanetSideGUID - -final case class GalaxyServiceMessage(channel: String, msg: EventMessage) - extends GenericMessageEnvelope { - def filter: PlanetSideGUID = Service.defaultPlayerGUID -} +import net.psforever.services.base.{EventMessage, MessageEnvelope} object GalaxyServiceMessage { - def apply(actionMessage: EventMessage): GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage) + def apply(msg: EventMessage): MessageEnvelope = MessageEnvelope("", Service.defaultPlayerGUID, msg) + + def apply(channel: String, msg: EventMessage): MessageEnvelope = MessageEnvelope(channel, Service.defaultPlayerGUID, msg) } diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index 469d1cc5e..5bdaa5b93 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -2,17 +2,17 @@ package net.psforever.services.local import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly} +import net.psforever.services.base.{EventMessage, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly, MessageEnvelope} import net.psforever.services.local.LocalAction.{IsADoorMessage, IsAHackMessage} import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.PlanetSideGUID -final case class LocalServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) - extends GenericMessageEnvelope - object LocalServiceMessage { - def apply(channel: String, localMessage: EventMessage): LocalServiceMessage = - LocalServiceMessage(channel, Service.defaultPlayerGUID, localMessage) + def apply(channel: String, localMessage: EventMessage): MessageEnvelope = + MessageEnvelope(channel, Service.defaultPlayerGUID, localMessage) + + def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = + MessageEnvelope(channel, filter, msg) } final case class DoorMessage( diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala index 1eb35fd26..af13af6cd 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala @@ -2,18 +2,18 @@ package net.psforever.services.vehicle import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, GenericMessageEnvelope, GenericMessageToSupportEnvelopeOnly} +import net.psforever.services.base.{EventMessage, GenericMessageToSupportEnvelopeOnly, MessageEnvelope} import net.psforever.types.PlanetSideGUID -final case class VehicleServiceMessage(channel: String, filter: PlanetSideGUID, msg: EventMessage) - extends GenericMessageEnvelope +object VehicleServiceMessage { + def apply(channel: String, localMessage: EventMessage): MessageEnvelope = + MessageEnvelope(channel, Service.defaultPlayerGUID, localMessage) + + def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = + MessageEnvelope(channel, filter, msg) +} final case class TurretMessage(supportMessage: Any) extends GenericMessageToSupportEnvelopeOnly { def supportLabel: String = "turretUpgrader" } - -object VehicleServiceMessage { - def apply(channel: String, actionMessage: EventMessage): VehicleServiceMessage = - VehicleServiceMessage(channel, Service.defaultPlayerGUID, actionMessage) -} diff --git a/src/test/scala/objects/DamageableTest.scala b/src/test/scala/objects/DamageableTest.scala index d3ac0235d..3d3538116 100644 --- a/src/test/scala/objects/DamageableTest.scala +++ b/src/test/scala/objects/DamageableTest.scala @@ -22,10 +22,9 @@ import net.psforever.objects.vital.{SpawningActivity, Vitality} import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types._ -import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.support.SupportActor -import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.TurretMessage import org.specs2.mutable.Specification import scala.concurrent.duration._ @@ -37,7 +36,9 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.base.DamageResolution import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.vital.resolution.ResolutionCalculations.Output +import net.psforever.services.base.MessageEnvelope import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.vehicle.support.TurretUpgrader class DamageableTest extends Specification { val player1: Player = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.TR, CharacterSex.Male, 0, CharacterVoice.Mute)) @@ -328,7 +329,7 @@ class DamageableEntityDamageTest extends ActorTest { val msg1 = avatarProbe.receiveOne(5000 milliseconds) val msg2 = activityProbe.receiveOne(5000 milliseconds) msg1 match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(ValidPlanetSideGUID(2), 0, 3600)) => () + case MessageEnvelope("test", _, PlanetsideAttribute(ValidPlanetSideGUID(2), 0, 3600)) => () case _ => assert(false, "DamageableEntity:handle taking damage - player not messaged") } msg2 match { @@ -402,13 +403,13 @@ class DamageableEntityDestroyedTest extends ActorTest { val msg1_2 = avatarProbe.receiveN(2, 500 milliseconds) assert( msg1_2.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg1_2(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true case _ => false } ) @@ -553,19 +554,19 @@ class DamageableAmenityTest extends ActorTest { term.Actor ! Vitality.Damage(applyDamageTo) val msg1234 = avatarProbe.receiveN(4, 3000 milliseconds) msg1234.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => () + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => () case _ => assert(false) } msg1234(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => () + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => () case _ => assert(false) } msg1234(2) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 50, 1)) => () + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 50, 1)) => () case _ => assert(false) } msg1234(3) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 51, 1)) => () + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 51, 1)) => () case _ => assert(false) } assert(term.Health <= term.Definition.DamageDestroysAt) @@ -641,7 +642,7 @@ class DamageableMountableDamageTest extends ActorTest { val msg2 = activityProbe.receiveOne(5000 milliseconds) assert( msg1_3.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -656,7 +657,7 @@ class DamageableMountableDamageTest extends ActorTest { ) assert( msg1_3(1) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", _, SendResponse(Seq(DamageWithPositionMessage(_, Vector3(2, 2, 2)))) @@ -745,11 +746,11 @@ class DamageableMountableDestroyTest extends ActorTest { val msg3 = player2Probe.receiveOne(200 milliseconds) msg12.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => () + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => () case _ => assert(false) } msg12(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => () + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => () case _ => assert(false) } msg3 match { @@ -832,7 +833,7 @@ class DamageableWeaponTurretDamageTest extends ActorTest { val msg4 = avatarProbe.receiveOne(500 milliseconds) assert( msg12 match { - case VehicleServiceMessage("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -847,7 +848,7 @@ class DamageableWeaponTurretDamageTest extends ActorTest { ) assert( msg4 match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", _, SendResponse(Seq(DamageWithPositionMessage(_, Vector3(2, 2, 2)))) @@ -933,7 +934,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest { val msg12 = vehicleProbe.receiveN(2, 500 milliseconds) assert( msg12.head match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, PlanetsideAttribute(PlanetSideGUID(2), 27, 1) @@ -944,7 +945,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest { ) assert( msg12(1) match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, PlanetsideAttribute(PlanetSideGUID(5), 27, 1) @@ -1074,12 +1075,12 @@ class DamageableWeaponTurretDestructionTest extends ActorTest { val msg3 = player2Probe.receiveOne(200 milliseconds) val msg56 = vehicleProbe.receiveN(2, 200 milliseconds) msg12_4.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => ; + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-1: ${msg12_4.head}") } msg12_4(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => ; + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-2: ${msg12_4(1)}") } @@ -1089,7 +1090,7 @@ class DamageableWeaponTurretDestructionTest extends ActorTest { assert(false, s"DamageableWeaponTurretDestructionTest-3: player not dead - $msg3") } msg12_4(2) match { - case AvatarServiceMessage("test", _, ObjectDelete(PlanetSideGUID(5), _)) => ; + case MessageEnvelope("test", _, ObjectDelete(PlanetSideGUID(5), _)) => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-4: ${msg12_4(2)}") } @@ -1184,13 +1185,13 @@ class DamageableVehicleDamageTest extends ActorTest { val msg4 = avatarProbe.receiveOne(200 milliseconds) assert( msg12.head match { - case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 68, _)) => true + case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(1), 68, _)) => true case _ => false } ) assert( msg12(1) match { - case VehicleServiceMessage("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true case _ => false } ) @@ -1205,7 +1206,7 @@ class DamageableVehicleDamageTest extends ActorTest { ) assert( msg4 match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", _, SendResponse(Seq(DamageWithPositionMessage(9, Vector3(2, 0, 0)))) @@ -1321,11 +1322,11 @@ class DamageableVehicleDamageMountedTest extends FreedContextActorTest { val msg3 = activityProbe.receiveOne(500 milliseconds) val msg45 = avatarProbe.receiveN(2,500 milliseconds) msg12.head match { - case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 68, _)) => ; + case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(1), 68, _)) => ; case _ => assert(false) } msg12(1) match { - case VehicleServiceMessage("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => ; + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => ; case _ => assert(false) } msg3 match { @@ -1336,7 +1337,7 @@ class DamageableVehicleDamageMountedTest extends FreedContextActorTest { case _ => assert(false) } msg45.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", _, SendResponse(Seq(DamageWithPositionMessage(400, Vector3(2, 0, 0)))) @@ -1344,7 +1345,7 @@ class DamageableVehicleDamageMountedTest extends FreedContextActorTest { case _ => assert(false) } msg45(1) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter3", _, SendResponse(Seq(DamageWithPositionMessage(0, Vector3(2, 0, 0)))) @@ -1458,7 +1459,7 @@ class DamageableVehicleJammeringMountedTest extends FreedContextActorTest { player3Probe.expectNoMessage(200 milliseconds) assert( msg12 match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, PlanetsideAttribute(PlanetSideGUID(4), 27, 1) @@ -1553,11 +1554,11 @@ class DamageableVehicleDestroyTest extends ActorTest { val msg124 = avatarProbe.receiveN(2, 3000 milliseconds) val msg3 = player2Probe.receiveOne(3000 milliseconds) msg124.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => () + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => () case _ => assert(false) } msg124(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(1), _, _, Vector3(1, 0, 0))) => () + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(1), _, _, Vector3(1, 0, 0))) => () case _ => assert(false) } msg3 match { @@ -1718,31 +1719,31 @@ class DamageableVehicleDestroyTest extends ActorTest { // vehicleProbe.expectNoMessage(10 milliseconds) // assert( // msg_avatar.exists({ -// case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(4), 0, _)) => true +// case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(4), 0, _)) => true // case _ => false // }) // ) // assert( // msg_avatar.exists({ -// case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(4), _, _, Vector3(1, 0, 0))) => true +// case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(4), _, _, Vector3(1, 0, 0))) => true // case _ => false // }) // ) // assert( // msg_avatar.exists({ -// case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true +// case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true // case _ => false // }) // ) // assert( // msg_avatar.exists({ -// case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(1), _, _, Vector3(1, 0, 0))) => true +// case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(1), _, _, Vector3(1, 0, 0))) => true // case _ => false // }) // ) // assert( // msg_avatar.exists({ -// case AvatarServiceMessage("test", ObjectDelete(PlanetSideGUID(0), PlanetSideGUID(2), _)) => true +// case MessageEnvelope("test", _, ObjectDelete(PlanetSideGUID(0), PlanetSideGUID(2), _)) => true // case _ => false // }) // ) @@ -1760,7 +1761,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // ) // assert( // msg_vehicle.exists({ -// case VehicleServiceMessage( +// case MessageEnvelope( // "test", // _, // PlanetsideAttribute(PlanetSideGUID(4), 27, 0) @@ -1771,7 +1772,7 @@ class DamageableVehicleDestroyTest extends ActorTest { // ) // assert( // msg_vehicle.exists({ -// case VehicleServiceMessage( +// case MessageEnvelope( // "test", // _, // PlanetsideAttribute(PlanetSideGUID(1), 68, 0) diff --git a/src/test/scala/objects/DeployableBehaviorTest.scala b/src/test/scala/objects/DeployableBehaviorTest.scala index dab1aafcf..8defcd389 100644 --- a/src/test/scala/objects/DeployableBehaviorTest.scala +++ b/src/test/scala/objects/DeployableBehaviorTest.scala @@ -13,10 +13,9 @@ import net.psforever.objects.guid.NumberPoolHub import net.psforever.objects.guid.source.MaxNumberSource import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} import net.psforever.packet.game._ -import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.MessageEnvelope import net.psforever.services.base.messages.{ObjectDelete, SendResponse} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types._ import scala.collection.mutable @@ -51,13 +50,13 @@ class DeployableBehaviorSetupTest extends ActorTest { val eventsMsgs = eventsProbe.receiveN(2, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", _, LocalAction.DeployItem(obj)) => + case MessageEnvelope("test", _, LocalAction.DeployItem(obj)) => assert(obj eq jmine, "self-setup test - not same mine") case _ => assert( false, "self-setup test - wrong deploy message") } eventsMsgs(1) match { - case LocalServiceMessage("TR", _, + case MessageEnvelope("TR", _, LocalAction.DeployableMapIcon( DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, Vector3(1,2,3), PlanetSideGUID(0)) @@ -159,7 +158,7 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { //assert(false, "test needs to be fixed") val eventsMsgs = eventsProbe.receiveN(7, 10.seconds) eventsMsgs.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(ObjectDeployedMessage(0, "jammer_mine", DeployOutcome.Success, 1, 20))) @@ -168,11 +167,11 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { assert(false, "owned setup test, 2 - did not receive build confirmation") } eventsMsgs(1) match { - case LocalServiceMessage("TestCharacter1", _, LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; + case MessageEnvelope("TestCharacter1", _, LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; case _ => assert(false, "owned setup test, 2 - did not receive ui update") } eventsMsgs(2) match { - case LocalServiceMessage( + case MessageEnvelope( "test", PlanetSideGUID(3), LocalAction.TriggerEffectLocation("spawn_object_effect", Vector3(1,2,3), Vector3(4,5,6)) @@ -180,14 +179,14 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { case _ => assert(false, "owned setup test, 2 - no spawn fx") } eventsMsgs(3) match { - case LocalServiceMessage("test", _, LocalAction.DeployItem(obj)) => + case MessageEnvelope("test", _, LocalAction.DeployItem(obj)) => assert(obj eq jmine, "owned setup test, 2 - not same mine") case _ => assert( false, "owned setup test, 2 - wrong deploy message") } //the message order can be jumbled from here-on eventsMsgs(4) match { - case LocalServiceMessage("TR", _, + case MessageEnvelope("TR", _, LocalAction.DeployableMapIcon( DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.DisruptorMine, Vector3(1,2,3), PlanetSideGUID(3)) @@ -197,7 +196,7 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { assert(false, "owned setup test, 2 - no icon or wrong icon") } eventsMsgs(5) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(1), 21))) @@ -206,7 +205,7 @@ class DeployableBehaviorSetupOwnedP2Test extends FreedContextActorTest { assert(false, "owned setup test, 2 - build action not reset (GOAM21)") } eventsMsgs(6) match { - case AvatarServiceMessage("test", _, ObjectDelete(PlanetSideGUID(2), 0)) => ; + case MessageEnvelope("test", _, ObjectDelete(PlanetSideGUID(2), 0)) => ; case _ => assert(false, "owned setup test, 2 - construction tool not deleted") } @@ -247,11 +246,11 @@ class DeployableBehaviorDeconstructTest extends ActorTest { jmine.Actor ! Deployable.Deconstruct() val eventsMsgs = eventsProbe.receiveN(2, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", _, LocalAction.EliminateDeployable(_, PlanetSideGUID(1), Vector3(1,2,3), 2)) => ; + case MessageEnvelope("test", _, LocalAction.EliminateDeployable(_, PlanetSideGUID(1), Vector3(1,2,3), 2)) => ; case _ => assert(false, "deconstruct test - not eliminating deployable") } eventsMsgs(1) match { - case LocalServiceMessage( + case MessageEnvelope( "TR", _, LocalAction.DeployableMapIcon( DeploymentAction.Dismiss, @@ -309,12 +308,12 @@ class DeployableBehaviorDeconstructOwnedTest extends FreedContextActorTest { jmine.Actor ! Deployable.Deconstruct() val eventsMsgs = eventsProbe.receiveN(3, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", _, LocalAction.EliminateDeployable(mine, ValidPlanetSideGUID(1), Vector3(1.0,2.0,3.0),2)) + case MessageEnvelope("test", _, LocalAction.EliminateDeployable(mine, ValidPlanetSideGUID(1), Vector3(1.0,2.0,3.0),2)) if mine eq jmine => ; case _ => assert(false, "owned deconstruct test - not eliminating deployable") } eventsMsgs(1) match { - case LocalServiceMessage( + case MessageEnvelope( "TR", _, LocalAction.DeployableMapIcon( DeploymentAction.Dismiss, @@ -324,7 +323,7 @@ class DeployableBehaviorDeconstructOwnedTest extends FreedContextActorTest { case _ => assert(false, "owned deconstruct test - not removing icon") } eventsMsgs(2) match { - case LocalServiceMessage("TestCharacter1", _, LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; + case MessageEnvelope("TestCharacter1", _, LocalAction.DeployableUIFor(DeployedItem.jammer_mine)) => ; case _ => assert(false, "") } diff --git a/src/test/scala/objects/DeployableTest.scala b/src/test/scala/objects/DeployableTest.scala index c728f9f1e..033d1f2f5 100644 --- a/src/test/scala/objects/DeployableTest.scala +++ b/src/test/scala/objects/DeployableTest.scala @@ -17,14 +17,15 @@ import net.psforever.packet.game.{DeployableIcon, DeployableInfo, DeploymentActi import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.local.LocalAction import net.psforever.objects.avatar.Avatar import net.psforever.objects.vital.base.DamageResolution import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.projectile.ProjectileReason import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} +import net.psforever.services.base.MessageEnvelope import scala.collection.mutable import scala.concurrent.duration._ @@ -370,8 +371,9 @@ class ExplosiveDeployableJammerTest extends ActorTest { case _ => assert(false, "") } // eventMsgs.head match { -// case LocalServiceMessage( +// case MessageEnvelope( // "NC", +// _, // LocalAction.DeployableMapIcon( // ValidPlanetSideGUID(0), // DeploymentAction.Dismiss, @@ -381,12 +383,13 @@ class ExplosiveDeployableJammerTest extends ActorTest { // case _ => assert(false, "") // } eventMsgs(1) match { - case LocalServiceMessage("test", _, LocalAction.Detonate(PlanetSideGUID(1), _)) => ; + case MessageEnvelope("test", _, LocalAction.Detonate(PlanetSideGUID(1), _)) => ; case _ => assert(false, "") } eventMsgs(2) match { - case LocalServiceMessage( - "NC", _, + case MessageEnvelope( + "NC", + _, LocalAction.DeployableMapIcon( DeploymentAction.Dismiss, DeployableInfo(ValidPlanetSideGUID(1), DeployableIcon.HEMine, Vector3.Zero, ValidPlanetSideGUID(0)) @@ -395,7 +398,7 @@ class ExplosiveDeployableJammerTest extends ActorTest { case _ => assert(false, "") } eventMsgs(3) match { - case AvatarServiceMessage( + case MessageEnvelope( "test", _, AvatarAction.Destroy( @@ -484,13 +487,14 @@ class ExplosiveDeployableJammerExplodeTest extends ActorTest { case _ => assert(false, "") } eventMsgs(1) match { - case LocalServiceMessage("test", _, LocalAction.Detonate(PlanetSideGUID(2), target)) + case MessageEnvelope("test", _, LocalAction.Detonate(PlanetSideGUID(2), target)) if target eq h_mine => () case _ => assert(false, "") } eventMsgs(2) match { - case LocalServiceMessage( - "NC", _, + case MessageEnvelope( + "NC", + _, LocalAction.DeployableMapIcon( DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(2), DeployableIcon.HEMine, _, PlanetSideGUID(0)) @@ -576,8 +580,9 @@ class ExplosiveDeployableDestructionTest extends ActorTest { player1Probe.expectNoMessage(200 milliseconds) val p2Msgs = player2Probe.receiveN(1, 200 milliseconds) eventMsgs.head match { - case LocalServiceMessage( - "NC", _, + case MessageEnvelope( + "NC", + _, LocalAction.DeployableMapIcon( DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(2), DeployableIcon.HEMine, _, PlanetSideGUID(0)) @@ -586,14 +591,14 @@ class ExplosiveDeployableDestructionTest extends ActorTest { case _ => assert(false, "") } eventMsgs(1) match { - case AvatarServiceMessage( + case MessageEnvelope( "test", _, AvatarAction.Destroy(PlanetSideGUID(2), PlanetSideGUID(3), Service.defaultPlayerGUID, Vector3.Zero) ) => ; case _ => assert(false, "") } eventMsgs(2) match { - case LocalServiceMessage("test", _, LocalAction.TriggerEffect("detonate_damaged_mine", PlanetSideGUID(2))) => ; + case MessageEnvelope("test", _, LocalAction.TriggerEffect("detonate_damaged_mine", PlanetSideGUID(2))) => ; case _ => assert(false, "") } p2Msgs.head match { diff --git a/src/test/scala/objects/DeploymentTest.scala b/src/test/scala/objects/DeploymentTest.scala index d723f0720..62dc12583 100644 --- a/src/test/scala/objects/DeploymentTest.scala +++ b/src/test/scala/objects/DeploymentTest.scala @@ -8,9 +8,10 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.{GlobalDefinitions, Vehicle} import net.psforever.objects.serverobject.deploy.{Deployment, DeploymentBehavior} import net.psforever.objects.zones.{Zone, ZoneMap} +import net.psforever.services.base.MessageEnvelope import net.psforever.types.{DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import org.specs2.mutable.Specification -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.duration.Duration @@ -72,7 +73,7 @@ class DeploymentBehavior2Test extends ActorTest { case _ => assert(false, "") } reply2.head match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) @@ -85,7 +86,7 @@ class DeploymentBehavior2Test extends ActorTest { case _ => assert(false, "") } reply2(1) match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) @@ -102,7 +103,7 @@ class DeploymentBehavior2Test extends ActorTest { case _ => assert(false, "") } reply4.head match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) @@ -115,7 +116,7 @@ class DeploymentBehavior2Test extends ActorTest { case _ => assert(false, "") } reply4(1) match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) @@ -144,7 +145,7 @@ class DeploymentBehavior3Test extends ActorTest { case _ => assert(false, "") } reply2.head match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) @@ -157,7 +158,7 @@ class DeploymentBehavior3Test extends ActorTest { case _ => assert(false, "") } reply2(1) match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) @@ -174,7 +175,7 @@ class DeploymentBehavior3Test extends ActorTest { case _ => assert(false, "") } reply4.head match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) @@ -187,7 +188,7 @@ class DeploymentBehavior3Test extends ActorTest { case _ => assert(false, "") } reply4(1) match { - case VehicleServiceMessage( + case MessageEnvelope( "test", _, VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) diff --git a/src/test/scala/objects/DoorTest.scala b/src/test/scala/objects/DoorTest.scala index 486b8b5cb..25010c2a7 100644 --- a/src/test/scala/objects/DoorTest.scala +++ b/src/test/scala/objects/DoorTest.scala @@ -12,7 +12,7 @@ import net.psforever.objects.{Default, GlobalDefinitions, Player} import net.psforever.objects.serverobject.doors.{Door, DoorControl} import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.zones.{Zone, ZoneMap} -import net.psforever.services.local.{DoorMessage, LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse} +import net.psforever.services.local.{DoorMessage, LocalAction, LocalServiceResponse} import net.psforever.types._ import org.specs2.mutable.Specification diff --git a/src/test/scala/objects/FacilityTurretTest.scala b/src/test/scala/objects/FacilityTurretTest.scala index c3fd3483b..26f12e8b9 100644 --- a/src/test/scala/objects/FacilityTurretTest.scala +++ b/src/test/scala/objects/FacilityTurretTest.scala @@ -19,9 +19,10 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import org.specs2.mutable.Specification -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.SendResponse -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.vehicle.VehicleAction import scala.collection.mutable import scala.concurrent.duration._ @@ -260,7 +261,7 @@ class FacilityTurretControlRestorationTest extends ActorTest { val msg4 = vehicleProbe.receiveOne(500 milliseconds) assert( msg12345.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _))) @@ -271,25 +272,25 @@ class FacilityTurretControlRestorationTest extends ActorTest { ) assert( msg12345(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg12345(2) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 50, 0)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 50, 0)) => true case _ => false } ) assert( msg12345(3) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 51, 0)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 51, 0)) => true case _ => false } ) assert( msg12345(4) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) @@ -300,7 +301,7 @@ class FacilityTurretControlRestorationTest extends ActorTest { ) assert( msg4 match { - case VehicleServiceMessage("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) + case MessageEnvelope("test", _, VehicleAction.EquipmentInSlot(PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true case _ => false diff --git a/src/test/scala/objects/GeneratorTest.scala b/src/test/scala/objects/GeneratorTest.scala index df0d2f927..9cb8ce8f4 100644 --- a/src/test/scala/objects/GeneratorTest.scala +++ b/src/test/scala/objects/GeneratorTest.scala @@ -24,8 +24,9 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage, TriggerEffectMessage} import net.psforever.types._ import org.specs2.mutable.Specification -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} import scala.concurrent.duration._ @@ -119,7 +120,7 @@ class GeneratorControlDamageTest extends ActorTest { val msg_building = buildingProbe.receiveOne(500 milliseconds) assert( msg_avatar match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -204,7 +205,7 @@ class GeneratorControlCriticalTest extends ActorTest { val msg_building = buildingProbe.receiveOne(500 milliseconds) assert( msg_avatar match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -313,19 +314,19 @@ class GeneratorControlDestroyedTest extends ActorTest { ) assert( msg_avatar2.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg_avatar2(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true case _ => false } ) assert( msg_avatar2(2) match { - case AvatarServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None))) @@ -442,19 +443,19 @@ class GeneratorControlKillsTest extends ActorTest { ) assert( msg_avatar2.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg_avatar2(1) match { - case AvatarServiceMessage("test", AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true + case MessageEnvelope("test", _, AvatarAction.Destroy(PlanetSideGUID(2), _, _, Vector3(1, 0, 0))) => true case _ => false } ) assert( msg_avatar2(2) match { - case AvatarServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(TriggerEffectMessage(PlanetSideGUID(2), "explosion_generator", None, None))) @@ -821,7 +822,7 @@ class GeneratorControlRepairPastRestorePoint extends ActorTest { val msg_building = buildingProbe.receiveOne(200 milliseconds) assert( msg_avatar.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(ValidPlanetSideGUID(5), _, ValidPlanetSideGUID(4), _))) @@ -832,13 +833,13 @@ class GeneratorControlRepairPastRestorePoint extends ActorTest { ) assert( msg_avatar(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg_avatar(2) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(ValidPlanetSideGUID(2), _))) diff --git a/src/test/scala/objects/PlayerControlTest.scala b/src/test/scala/objects/PlayerControlTest.scala index 7de59c476..50d734b75 100644 --- a/src/test/scala/objects/PlayerControlTest.scala +++ b/src/test/scala/objects/PlayerControlTest.scala @@ -24,8 +24,9 @@ import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.vital.resolution.ResolutionCalculations.Output import net.psforever.packet.game._ import net.psforever.types._ -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{HintsAtAttacker, SendResponse} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.messages.{HintsAtAttacker, PlanetsideAttribute, SendResponse} import scala.concurrent.duration._ @@ -69,7 +70,7 @@ class PlayerControlHealTest extends ActorTest { val msg_avatar = avatarProbe.receiveN(4, 500 milliseconds) assert( msg_avatar.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) @@ -80,23 +81,24 @@ class PlayerControlHealTest extends ActorTest { ) assert( msg_avatar(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg_avatar(2) match { - case AvatarServiceMessage( - "TestCharacter2", - AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 55, 1) - ) => + case MessageEnvelope( + "TestCharacter2", + _, + PlanetsideAttribute(PlanetSideGUID(2), 55, 1) + ) => true case _ => false } ) assert( msg_avatar(3) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) @@ -149,7 +151,7 @@ class PlayerControlHealSelfTest extends ActorTest { val msg_avatar1 = avatarProbe.receiveN(2, 500 milliseconds) assert( msg_avatar1.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) @@ -160,7 +162,7 @@ class PlayerControlHealSelfTest extends ActorTest { ) assert( msg_avatar1(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true case _ => false } ) @@ -173,7 +175,7 @@ class PlayerControlHealSelfTest extends ActorTest { val msg_avatar2 = avatarProbe.receiveN(2, 500 milliseconds) assert( msg_avatar2.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) @@ -184,7 +186,7 @@ class PlayerControlHealSelfTest extends ActorTest { ) assert( msg_avatar2(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true case _ => false } ) @@ -234,7 +236,7 @@ class PlayerControlRepairTest extends ActorTest { val msg_avatar = avatarProbe.receiveN(5, 1000 milliseconds) assert( msg_avatar.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) @@ -245,23 +247,24 @@ class PlayerControlRepairTest extends ActorTest { ) assert( msg_avatar(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 4, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 4, _)) => true case _ => false } ) assert( msg_avatar(2) match { - case AvatarServiceMessage( - "TestCharacter2", - AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 56, 1) - ) => + case MessageEnvelope( + "TestCharacter2", + _, + PlanetsideAttribute(PlanetSideGUID(2), 56, 1) + ) => true case _ => false } ) assert( msg_avatar(3) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) @@ -272,9 +275,10 @@ class PlayerControlRepairTest extends ActorTest { ) assert( msg_avatar(4) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", - AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 56, 1) + _, + PlanetsideAttribute(PlanetSideGUID(2), 56, 1) ) => true case _ => false @@ -326,7 +330,7 @@ class PlayerControlRepairSelfTest extends ActorTest { val msg_avatar1 = avatarProbe.receiveN(2, 500 milliseconds) assert( msg_avatar1.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) @@ -337,7 +341,7 @@ class PlayerControlRepairSelfTest extends ActorTest { ) assert( msg_avatar1(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 4, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 4, _)) => true case _ => false } ) @@ -350,7 +354,7 @@ class PlayerControlRepairSelfTest extends ActorTest { val msg_avatar2 = avatarProbe.receiveN(2, 500 milliseconds) assert( msg_avatar2.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) @@ -361,7 +365,7 @@ class PlayerControlRepairSelfTest extends ActorTest { ) assert( msg_avatar2(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 4, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 4, _)) => true case _ => false } ) @@ -434,7 +438,7 @@ class PlayerControlDamageTest extends ActorTest { val msg_activity = activityProbe.receiveOne(200 milliseconds) assert( msg_avatar.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 4, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 4, _)) => true case _ => false } ) @@ -446,7 +450,7 @@ class PlayerControlDamageTest extends ActorTest { ) assert( msg_avatar(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -461,7 +465,7 @@ class PlayerControlDamageTest extends ActorTest { ) assert( msg_avatar(2) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", PlanetSideGUID(1), HintsAtAttacker(PlanetSideGUID(2)) @@ -547,7 +551,7 @@ class PlayerControlDeathStandingTest extends ActorTest { activityProbe.expectNoMessage(200 milliseconds) assert( msg_avatar.head match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 4, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 4, _)) => true case _ => false } ) @@ -559,26 +563,26 @@ class PlayerControlDeathStandingTest extends ActorTest { ) assert( msg_avatar(1) match { - case AvatarServiceMessage("TestCharacter2", AvatarAction.Killed(PlanetSideGUID(2), _, None)) => true + case MessageEnvelope("TestCharacter2", _, AvatarAction.Killed(PlanetSideGUID(2), _, None)) => true case _ => false } ) assert( msg_avatar(2) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg_avatar(3) match { - case AvatarServiceMessage("TestCharacter2", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 7, _)) => + case MessageEnvelope("TestCharacter2", _, PlanetsideAttribute(PlanetSideGUID(2), 7, _)) => true case _ => false } ) assert( msg_avatar(4) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter2", _, SendResponse(Seq(DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _))) @@ -674,8 +678,9 @@ class PlayerControlDeathStandingTest extends ActorTest { // ) // assert( // msg_avatar.head match { -// case AvatarServiceMessage( +// case MessageEnvelope( // "TestCharacter2", +// _, // AvatarAction.Killed(PlanetSideGUID(2), _, Some(PlanetSideGUID(7))) // ) => // true @@ -684,13 +689,13 @@ class PlayerControlDeathStandingTest extends ActorTest { // ) // assert( // msg_avatar(1) match { -// case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true +// case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true // case _ => false // } // ) // assert( // msg_avatar(2) match { -// case AvatarServiceMessage( +// case MessageEnvelope( // "TestCharacter2", // _, // SendResponse(DestroyMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _)) @@ -743,8 +748,9 @@ class PlayerControlDeathStandingTest extends ActorTest { // val msg_drown = avatarProbe.receiveOne(250 milliseconds) // assert( // msg_drown match { -// case AvatarServiceMessage( +// case MessageEnvelope( // "TestCharacter1", +// _, // AvatarAction.OxygenState(OxygenStateTarget(PlanetSideGUID(1), _, OxygenState.Suffocation, 100f), _) // ) => true // case _ => false @@ -797,8 +803,9 @@ class PlayerControlDeathStandingTest extends ActorTest { // val msg_drown = avatarProbe.receiveOne(250 milliseconds) // assert( // msg_drown match { -// case AvatarServiceMessage( +// case MessageEnvelope( // "TestCharacter1", +// _, // AvatarAction.OxygenState(OxygenStateTarget(PlanetSideGUID(1), _, OxygenState.Suffocation, 100f), _) // ) => true // case _ => false @@ -810,8 +817,9 @@ class PlayerControlDeathStandingTest extends ActorTest { // val msg_recover = avatarProbe.receiveOne(250 milliseconds) // assert( // msg_recover match { -// case AvatarServiceMessage( +// case MessageEnvelope( // "TestCharacter1", +// _, // AvatarAction.OxygenState(OxygenStateTarget(PlanetSideGUID(1), _, OxygenState.Recovery, _), _) // ) => true // case _ => false @@ -863,19 +871,19 @@ class PlayerControlInteractWithLavaTest extends ActorTest { val msg_burn = avatarProbe.receiveN(3, 1 seconds) assert( msg_burn.head match { - case AvatarServiceMessage("test-map", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true + case MessageEnvelope("test-map", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true case _ => false } ) assert( msg_burn(1) match { - case AvatarServiceMessage("TestCharacter1", AvatarAction.EnvironmentalDamage(PlanetSideGUID(1), _, _)) => true + case MessageEnvelope("TestCharacter1", _, AvatarAction.EnvironmentalDamage(PlanetSideGUID(1), _, _)) => true case _ => false } ) assert( msg_burn(2) match { - case AvatarServiceMessage("test-map", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 54, _)) => true + case MessageEnvelope("test-map", _, PlanetsideAttribute(PlanetSideGUID(1), 54, _)) => true case _ => false } ) diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index b3a416422..6589e7d8a 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -17,9 +17,10 @@ import net.psforever.objects.vehicles.control.VehicleControl import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.SendResponse -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.duration._ @@ -71,7 +72,7 @@ class RepairableEntityRepairTest extends ActorTest { val msg123 = avatarProbe.receiveN(3, 500 milliseconds) assert( msg123.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _))) @@ -82,13 +83,13 @@ class RepairableEntityRepairTest extends ActorTest { ) assert( msg123(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg123(2) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) @@ -189,7 +190,7 @@ class RepairableAmenityTest extends ActorTest { val msg12345 = avatarProbe.receiveN(5, 500 milliseconds) assert( msg12345.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(5), _, PlanetSideGUID(4), _))) @@ -200,25 +201,25 @@ class RepairableAmenityTest extends ActorTest { ) assert( msg12345(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) assert( msg12345(2) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 50, 0)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 50, 0)) => true case _ => false } ) assert( msg12345(3) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 51, 0)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 51, 0)) => true case _ => false } ) assert( msg12345(4) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) @@ -288,7 +289,7 @@ class RepairableTurretWeapon extends ActorTest { val msg4 = vehicleProbe.receiveOne(500 milliseconds) assert( msg12345.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(8), _, PlanetSideGUID(7), _))) @@ -299,14 +300,14 @@ class RepairableTurretWeapon extends ActorTest { ) assert( msg12345(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) //msg12345(2) and msg12345(3) are related to RepairableAmenity assert( msg12345(4) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(2), _))) @@ -317,7 +318,7 @@ class RepairableTurretWeapon extends ActorTest { ) assert( msg4 match { - case VehicleServiceMessage("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) + case MessageEnvelope("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true case _ => false @@ -370,7 +371,7 @@ class RepairableVehicleRepair extends ActorTest { val msg123 = avatarProbe.receiveN(3, 500 milliseconds) assert( msg123.head match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(InventoryStateMessage(PlanetSideGUID(6), _, PlanetSideGUID(5), _))) @@ -381,13 +382,13 @@ class RepairableVehicleRepair extends ActorTest { ) assert( msg123(1) match { - case AvatarServiceMessage("test", AvatarAction.PlanetsideAttributeToAll(PlanetSideGUID(1), 0, _)) => true + case MessageEnvelope("test", _, PlanetsideAttribute(PlanetSideGUID(1), 0, _)) => true case _ => false } ) assert( msg123(2) match { - case AvatarServiceMessage( + case MessageEnvelope( "TestCharacter1", _, SendResponse(Seq(RepairMessage(PlanetSideGUID(1), _))) diff --git a/src/test/scala/objects/ResourceSiloTest.scala b/src/test/scala/objects/ResourceSiloTest.scala index 4404ab2a3..5fb433118 100644 --- a/src/test/scala/objects/ResourceSiloTest.scala +++ b/src/test/scala/objects/ResourceSiloTest.scala @@ -16,8 +16,8 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.UseItemMessage import net.psforever.types._ import org.specs2.mutable.Specification -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.objects.avatar.Avatar +import net.psforever.services.base.MessageEnvelope import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.{InterstellarClusterService, Service, ServiceManager} import net.psforever.services.galaxy.GalaxyService @@ -236,7 +236,7 @@ class ResourceSiloControlNtuWarningTest extends ActorTest { val reply = zoneEvents.receiveOne(5000 milliseconds) reply match { - case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; + case MessageEnvelope("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; case _ => assert(ResourceSiloTest.fail, s"$reply is wrong") } assert(!obj.LowNtuWarningOn) @@ -275,12 +275,12 @@ class ResourceSiloControlUpdate1Test extends ActorTest { assert(obj.NtuCapacitor == 305) assert(obj.CapacitorDisplay == 3) reply1.head match { - case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(1), 45, 3)) => ; + case MessageEnvelope("nowhere", _, PlanetsideAttribute(PlanetSideGUID(1), 45, 3)) => ; case _ => assert(ResourceSiloTest.fail, s"$reply1 is wrong") } assert(reply2.isInstanceOf[BuildingActor.MapUpdate], s"$reply2 is wrong") reply1(1) match { - case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; + case MessageEnvelope("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; case _ => assert(ResourceSiloTest.fail, s"${reply1(1)} is wrong") } assert(!obj.LowNtuWarningOn) @@ -319,12 +319,12 @@ class ResourceSiloControlUpdate2Test extends ActorTest { assert(obj.NtuCapacitor == 205) assert(obj.CapacitorDisplay == 2) reply1.head match { - case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(1), 45, 2)) => ; + case MessageEnvelope("nowhere", _, PlanetsideAttribute(PlanetSideGUID(1), 45, 2)) => ; case _ => assert(ResourceSiloTest.fail, s"$reply1 is wrong") } assert(reply2.isInstanceOf[BuildingActor.MapUpdate]) reply1(1) match { - case AvatarServiceMessage("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; + case MessageEnvelope("nowhere", _, PlanetsideAttribute(PlanetSideGUID(6), 47, 0)) => ; case _ => assert(ResourceSiloTest.fail, s"${reply1(1)} is wrong") } assert(!obj.LowNtuWarningOn) diff --git a/src/test/scala/objects/TelepadRouterTest.scala b/src/test/scala/objects/TelepadRouterTest.scala index 0af8ff646..056f4be58 100644 --- a/src/test/scala/objects/TelepadRouterTest.scala +++ b/src/test/scala/objects/TelepadRouterTest.scala @@ -15,8 +15,9 @@ import net.psforever.objects.vehicles.{Utility, UtilityType} import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game._ +import net.psforever.services.base.MessageEnvelope import net.psforever.services.base.messages.SendResponse -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.{DriveState, PlanetSideGUID, Vector3} import scala.collection.mutable @@ -48,14 +49,15 @@ class TelepadDeployableNoRouterTest extends ActorTest { val eventsMsgs = eventsProbe.receiveN(4, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", LocalAction.DeployItem(obj)) => + case MessageEnvelope("test", _, LocalAction.DeployItem(obj)) => assert(obj eq telepad, "no-router telepad deployable testt - not same telepad") case _ => assert( false, "no-router telepad deployable test - wrong deploy message") } eventsMsgs(1) match { - case LocalServiceMessage( + case MessageEnvelope( "NEUTRAL", + _, LocalAction.DeployableMapIcon( PlanetSideGUID(0), DeploymentAction.Build, @@ -65,12 +67,13 @@ class TelepadDeployableNoRouterTest extends ActorTest { case _ => assert(false, "no-router telepad deployable test - no icon or wrong icon") } eventsMsgs(2) match { - case LocalServiceMessage("test", LocalAction.EliminateDeployable(`telepad`, PlanetSideGUID(1), Vector3.Zero, 2)) => ; + case MessageEnvelope("test", _, LocalAction.EliminateDeployable(`telepad`, PlanetSideGUID(1), Vector3.Zero, 2)) => ; case _ => assert(false, "no-router telepad deployable test - not eliminating deployable") } eventsMsgs(3) match { - case LocalServiceMessage( + case MessageEnvelope( "NEUTRAL", + _, LocalAction.DeployableMapIcon( PlanetSideGUID(0), DeploymentAction.Dismiss, @@ -117,14 +120,15 @@ class TelepadDeployableNoActivationTest extends ActorTest { val eventsMsgs = eventsProbe.receiveN(4, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", LocalAction.DeployItem(obj)) => + case MessageEnvelope("test", _, LocalAction.DeployItem(obj)) => assert(obj eq telepad, "no-activate telepad deployable testt - not same telepad") case _ => assert( false, "no-activate telepad deployable test - wrong deploy message") } eventsMsgs(1) match { - case LocalServiceMessage( + case MessageEnvelope( "NEUTRAL", + _, LocalAction.DeployableMapIcon( PlanetSideGUID(0), DeploymentAction.Build, @@ -135,12 +139,13 @@ class TelepadDeployableNoActivationTest extends ActorTest { assert( false, "no-activate telepad deployable test - no icon or wrong icon") } eventsMsgs(2) match { - case LocalServiceMessage("test", LocalAction.EliminateDeployable(`telepad`, PlanetSideGUID(1), Vector3.Zero, 2)) => ; + case MessageEnvelope("test", _, LocalAction.EliminateDeployable(`telepad`, PlanetSideGUID(1), Vector3.Zero, 2)) => ; case _ => assert(false, "no-activate telepad deployable test - not eliminating deployable") } eventsMsgs(3) match { - case LocalServiceMessage( + case MessageEnvelope( "NEUTRAL", + _, LocalAction.DeployableMapIcon( PlanetSideGUID(0), DeploymentAction.Dismiss, @@ -190,14 +195,15 @@ class TelepadDeployableAttemptTest extends ActorTest { val eventsMsgs = eventsProbe.receiveN(2, 10.seconds) val routerMsgs = routerProbe.receiveN(1, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", LocalAction.DeployItem(obj)) => + case MessageEnvelope("test", _, LocalAction.DeployItem(obj)) => assert(obj eq telepad, "link attempt telepad deployable testt - not same telepad") case _ => assert( false, "link attempt telepad deployable test - wrong deploy message") } eventsMsgs(1) match { - case LocalServiceMessage( + case MessageEnvelope( "NEUTRAL", + _, LocalAction.DeployableMapIcon( PlanetSideGUID(0), DeploymentAction.Build, @@ -263,14 +269,15 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { val eventsMsgs = eventsProbe.receiveN(9, 10.seconds) eventsMsgs.head match { - case LocalServiceMessage("test", LocalAction.DeployItem(obj)) => + case MessageEnvelope("test", _, LocalAction.DeployItem(obj)) => assert(obj eq telepad, "link to router test - not same telepad") case _ => assert( false, "link to router test - wrong deploy message") } eventsMsgs(1) match { - case LocalServiceMessage( + case MessageEnvelope( "NEUTRAL", + _, LocalAction.DeployableMapIcon( PlanetSideGUID(0), DeploymentAction.Build, @@ -280,7 +287,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - no icon or wrong icon") } eventsMsgs(2) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq( @@ -290,7 +297,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - did not create the internal router telepad (1)") } eventsMsgs(3) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 27))) @@ -298,7 +305,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - did not create the internal router telepad (2)") } eventsMsgs(4) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 30))) @@ -306,7 +313,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - did not create the internal router telepad (3)") } eventsMsgs(5) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 27))) @@ -314,7 +321,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - did not link the internal telepad (1)") } eventsMsgs(6) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(3), 28))) @@ -322,7 +329,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - did not link the internal telepad (2)") } eventsMsgs(7) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(1), 27))) @@ -330,7 +337,7 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { case _ => assert(false, "link to router test - did not link the telepad (1)") } eventsMsgs(8) match { - case LocalServiceMessage( + case MessageEnvelope( "test", _, SendResponse(Seq(GenericObjectActionMessage(PlanetSideGUID(1), 28))) diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index fb723f6ad..b6ced134c 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -25,8 +25,9 @@ import net.psforever.objects.vital.{ShieldCharge, SpawningActivity, Vitality} import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game._ import net.psforever.services.ServiceManager +import net.psforever.services.base.MessageEnvelope import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types._ import scala.concurrent.duration._ @@ -73,7 +74,7 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest { val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds) vehicle_msg.head match { - case VehicleServiceMessage("test", _, VehicleAction.KickPassenger(PlanetSideGUID(2), 4, true, PlanetSideGUID(1))) => ; + case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(2), 4, true, PlanetSideGUID(1))) => ; case _ => assert(false, s"VehicleControlPrepareForDeletionPassengerTest: ${vehicle_msg.head}") } @@ -137,32 +138,32 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest { // val vehicle_msg = vehicleProbe.receiveN(6, 1 minute) // //dismounting as cargo messages // vehicle_msg.head match { -// case VehicleServiceMessage("test", _, VehicleAction.KickPassenger(PlanetSideGUID(3), 4, true, PlanetSideGUID(1))) => ; +// case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(3), 4, true, PlanetSideGUID(1))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-1: ${vehicle_msg.head}") // } // vehicle_msg(1) match { -// case VehicleServiceMessage(_, _, SendResponse(PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => ; +// case MessageEnvelope(_, _, SendResponse(PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-2: ${vehicle_msg(1)}") // } // vehicle_msg(2) match { -// case VehicleServiceMessage(_, _, SendResponse(PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => ; +// case MessageEnvelope(_, _, SendResponse(PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-3: ${vehicle_msg(2)}") // } // vehicle_msg(3) match { -// case VehicleServiceMessage("test", _, SendResponse(CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; +// case MessageEnvelope("test", _, SendResponse(CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-4: ${vehicle_msg(3)}") // } // vehicle_msg(4) match { -// case VehicleServiceMessage("test", _, SendResponse(ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => ; +// case MessageEnvelope("test", _, SendResponse(ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-5: ${vehicle_msg(4)}") // } // vehicle_msg(5) match { -// case VehicleServiceMessage("test", _, SendResponse(CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => ; +// case MessageEnvelope("test", _, SendResponse(CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0))) => ; // case _ => // assert(false, s"VehicleControlPrepareForDeletionMountedInTest-6: ${vehicle_msg(5)}") // } @@ -225,7 +226,7 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor val vehicleMsgs = eventsProbe.receiveN(6, 10.seconds) val cargoMsgs = cargoProbe.receiveN(1, 1.seconds) vehicleMsgs.head match { - case VehicleServiceMessage("test", _, VehicleAction.KickPassenger(PlanetSideGUID(4), 4, true, PlanetSideGUID(2))) => () + case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(4), 4, true, PlanetSideGUID(2))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-1: ${vehicleMsgs.head}") } @@ -233,27 +234,27 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor assert(lodestar.Seats(0).occupant.isEmpty) //cargo dismounting messages vehicleMsgs(1) match { - case VehicleServiceMessage(_, _, SendResponse(Seq(PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _)))) => () + case MessageEnvelope(_, _, SendResponse(Seq(PlanetsideAttributeMessage(PlanetSideGUID(1), 0, _)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-2: ${vehicleMsgs(1)}") } vehicleMsgs(2) match { - case VehicleServiceMessage(_, _, SendResponse(Seq(PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _)))) => () + case MessageEnvelope(_, _, SendResponse(Seq(PlanetsideAttributeMessage(PlanetSideGUID(1), 68, _)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-3: ${vehicleMsgs(2)}") } vehicleMsgs(3) match { - case VehicleServiceMessage("test", _, SendResponse(Seq(CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0)))) => ; + case MessageEnvelope("test", _, SendResponse(Seq(CargoMountPointStatusMessage(PlanetSideGUID(2), _, PlanetSideGUID(1), _, 1, CargoStatus.InProgress, 0)))) => ; case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-4: ${vehicleMsgs(3)}") } vehicleMsgs(4) match { - case VehicleServiceMessage("test", _, SendResponse(Seq(ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _)))) => () + case MessageEnvelope("test", _, SendResponse(Seq(ObjectDetachMessage(PlanetSideGUID(2), PlanetSideGUID(1), _, _, _, _)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-5: ${vehicleMsgs(4)}") } vehicleMsgs(5) match { - case VehicleServiceMessage("test", _, SendResponse(Seq(CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0)))) => () + case MessageEnvelope("test", _, SendResponse(Seq(CargoMountPointStatusMessage(PlanetSideGUID(2), _, _, PlanetSideGUID(1), 1, CargoStatus.Empty, 0)))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-6: ${vehicleMsgs(5)}") } @@ -545,7 +546,7 @@ class VehicleControlShieldsNotChargingTooEarlyTest extends ActorTest { val msg = probe.receiveOne(200 milliseconds) //assert(msg.isInstanceOf[Vehicle.UpdateShieldsCharge]) assert(msg match { - case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true + case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true case _ => false }) assert(vehicle.Shields == 15) @@ -1005,7 +1006,7 @@ class VehicleControlInteractWithLavaTest extends ActorTest { msg_burn.foreach { msg => assert( msg match { - case VehicleServiceMessage("test-zone", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true + case MessageEnvelope("test-zone", _, PlanetsideAttribute(PlanetSideGUID(2), 0, _)) => true case _ => false } ) @@ -1103,7 +1104,7 @@ class ApcControlCanChargeCapacitor extends FreedContextActorTest { do { val msg = vehicleProbe.receiveOne(3.seconds) msg match { - case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 113, capacitance)) => + case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(1), 113, capacitance)) => assert(capacitance > 0) case _ => assert(false) @@ -1177,11 +1178,11 @@ class ApcControlCanEmp extends FreedContextActorTest { apc.Actor ! SpecialEmp.Burst() val vehicleMsgs = vehicleProbe.receiveN(2, 500.milliseconds) vehicleMsgs.head match { - case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(1), 113, 0)) => ; + case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(1), 113, 0)) => ; case _ => assert(false) } vehicleMsgs(1) match { - case VehicleServiceMessage( + case MessageEnvelope( "test-zone", _, SendResponse(Seq( diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index 600d748bf..1a5848c51 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -14,11 +14,12 @@ import net.psforever.objects.{GlobalDefinitions, Player} import net.psforever.types.{CharacterSex, CharacterVoice, PlanetSideEmpire, PlanetSideGUID} import org.specs2.mutable.Specification import net.psforever.services.Service -import net.psforever.services.local.{LocalService, LocalServiceMessage} +import net.psforever.services.local.LocalService import scala.concurrent.duration._ import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.avatar.Avatar +import net.psforever.services.base.MessageEnvelope class ProximityTest extends Specification { @@ -200,7 +201,7 @@ class ProximityTerminalControlStartTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) + probe1.expectMsgClass(1 second, classOf[MessageEnvelope]) probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action]) assert(terminal.NumberUsers == 1) } @@ -270,7 +271,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) + probe1.expectMsgClass(1 second, classOf[MessageEnvelope]) probe2.expectMsgClass(5 second, classOf[ProximityUnit.Action]) terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref) @@ -328,7 +329,7 @@ class ProximityTerminalControlStopTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) + probe1.expectMsgClass(1 second, classOf[MessageEnvelope]) probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action]) terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar)) @@ -340,7 +341,7 @@ class ProximityTerminalControlStopTest extends ActorTest { case out => assert(false, s"last message $out is not StopAction") } //probe2.expectMsgClass(1 second, classOf[ProximityUnit.StopAction]) - probe1.expectMsgClass(1 second, classOf[LocalServiceMessage]) + probe1.expectMsgClass(1 second, classOf[MessageEnvelope]) assert(terminal.NumberUsers == 0) } } @@ -406,7 +407,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest { assert(terminal.Owner.Continent.equals("test")) terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref) - probe1.expectMsgClass(100 millisecond, classOf[LocalServiceMessage]) + probe1.expectMsgClass(100 millisecond, classOf[MessageEnvelope]) assert(terminal.NumberUsers == 1) terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref) @@ -418,7 +419,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest { assert(terminal.NumberUsers == 1) terminal.Actor ! CommonMessages.Unuse(avatar2, Some(avatar2)) - probe1.expectMsgClass(100 millisecond, classOf[LocalServiceMessage]) + probe1.expectMsgClass(100 millisecond, classOf[MessageEnvelope]) assert(terminal.NumberUsers == 0) } } From 775d9dca5e9241520ca8a516cac0bc2670dcb802 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 9 Feb 2026 14:18:15 -0500 Subject: [PATCH 10/32] cached messages on avatar and vehicle message systems --- .../actors/session/csr/VehicleLogic.scala | 9 +- .../actors/session/normal/GeneralLogic.scala | 3 +- .../actors/session/normal/VehicleLogic.scala | 9 +- .../session/spectator/GeneralLogic.scala | 3 +- .../session/spectator/VehicleLogic.scala | 3 +- .../support/SessionMountHandlers.scala | 3 +- .../WeaponAndProjectileOperations.scala | 3 +- .../services/avatar/AvatarService.scala | 10 +- .../services/base/GenericEventService.scala | 10 +- ...nericEventServiceWithCacheAndSupport.scala | 113 ++++++++++++++++++ .../services/vehicle/VehicleService.scala | 4 +- 11 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala diff --git a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala index d544f6dcf..2c7bb30dc 100644 --- a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala @@ -13,6 +13,7 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage} import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.CachedMessage import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{DriveState, Vector3} @@ -94,7 +95,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex is_decelerating, obj.Cloaked ) - ) + ) //todo CachedMessage sessionLogic.squad.updateSquad() case (None, _) => //log.error(s"VehicleState: no vehicle $vehicle_guid found in zone") @@ -170,7 +171,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex continent.id, player.GUID, VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA) - ) + ) //todo CachedMessage sessionLogic.squad.updateSquad() case (None, _) => //log.error(s"VehicleState: no vehicle $vehicle_guid found in zone") @@ -225,7 +226,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex continent.id, player.GUID, VehicleAction.ChildObjectState(object_guid, pitch, yaw) - ) + ) //todo CachedMessage } //TODO status condition of "playing getting out of vehicle to allow for late packets without warning if (player.death_by == -1) { @@ -244,7 +245,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Velocity = vel sessionLogic.updateBlockMap(obj, pos) obj.zoneInteractions() - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! CachedMessage( continent.id, player.GUID, VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index 14ac88743..e7004f6cc 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -43,6 +43,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.CachedMessage import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -196,7 +197,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex isNotVisible, eagleEye ) - ) + ) //todo CachedMessage sessionLogic.squad.updateSquad() if (player.death_by == -1) { sessionLogic.kickedByAdministration() diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala index ed6e4171e..59fd325c9 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala @@ -12,6 +12,7 @@ import net.psforever.objects.vehicles.control.BfrFlight import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} +import net.psforever.services.base.CachedMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{ChatMessageType, DriveState, Vector3} @@ -75,7 +76,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Position = position obj.Orientation = angle // - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! CachedMessage( continent.id, player.GUID, VehicleAction.VehicleState( @@ -166,7 +167,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex continent.id, player.GUID, VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA) - ) + ) //todo CachedMessage sessionLogic.squad.updateSquad() case (None, _) => //log.error(s"VehicleState: no vehicle $vehicle_guid found in zone") @@ -219,7 +220,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex continent.id, player.GUID, VehicleAction.ChildObjectState(object_guid, pitch, yaw) - ) + ) //todo CachedMessage } //TODO status condition of "playing getting out of vehicle to allow for late packets without warning if (player.death_by == -1) { @@ -238,7 +239,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Velocity = vel sessionLogic.updateBlockMap(obj, pos) obj.zoneInteractions() - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! CachedMessage( continent.id, player.GUID, VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala index 836538004..7755718c4 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala @@ -17,6 +17,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.AccountPersistenceService import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.CachedMessage import net.psforever.services.base.messages.PlanetsideAttribute import net.psforever.types.{ExoSuitType, Vector3} @@ -75,7 +76,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.Crouching = isCrouching player.Jumping = isJumping player.Cloaked = player.ExoSuit == ExoSuitType.Infiltration && isCloaking - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! CachedMessage( "spectator", avatarGuid, AvatarAction.PlayerState( diff --git a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala index ec7b4d4b4..af51a9628 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala @@ -7,6 +7,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.Vehicle import net.psforever.objects.serverobject.deploy.Deployment import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} +import net.psforever.services.base.CachedMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{DriveState, Vector3} @@ -39,7 +40,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Velocity = vel sessionLogic.updateBlockMap(obj, pos) obj.zoneInteractions() - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! CachedMessage( continent.id, player.GUID, VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index 443ac5f85..12c448913 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -8,6 +8,7 @@ import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle} import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} +import net.psforever.services.base.CachedMessage import net.psforever.services.base.messages.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} @@ -224,7 +225,7 @@ class SessionMountHandlers( sessionLogic.vehicles.ServerVehicleOverrideStop(v) }*/ v.Velocity = Vector3.Zero - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! CachedMessage( continent.id, tplayer.GUID, VehicleAction.VehicleState(v.GUID, unk1 = 0, tplayer.Position, v.Orientation, v.Velocity, v.Flying, unk3 = 0, unk4 = 0, wheel_direction = 15, unk5 = false, unk6 = v.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index ca6fb0509..c9ac61149 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -28,6 +28,7 @@ import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest import net.psforever.services.Service +import net.psforever.services.base.CachedMessage import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3} @@ -493,7 +494,7 @@ class WeaponAndProjectileOperations( projectile.Position = shot_pos projectile.Orientation = shot_orient projectile.Velocity = shot_vel - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! CachedMessage( continent.id, player.GUID, AvatarAction.ProjectileState( diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index dad3e9070..5056236cb 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -4,7 +4,7 @@ package net.psforever.services.avatar import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.zones.Zone import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover} -import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericMessageEnvelope} +import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericMessageEnvelope} case object CorpseRemovalSupport extends EventServiceSupport { @@ -14,18 +14,18 @@ case object CorpseRemovalSupport } } -case object ItemRemoverSupport +case object LitterRemovalSupport extends EventServiceSupport { def label: String = "janitor" def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[DroppedItemRemover](), name = "ItemRemover") + context.actorOf(Props[DroppedItemRemover](), name = "DroppedItemRemover") } } class AvatarService(zone: Zone) - extends GenericEventServiceWithSupport[AvatarServiceResponse]( + extends GenericEventServiceWithCacheAndSupport[AvatarServiceResponse]( busName = "Avatar", - eventSupportServices = List(CorpseRemovalSupport, ItemRemoverSupport) + eventSupportServices = List(CorpseRemovalSupport, LitterRemovalSupport) ) { protected def composeResponseEnvelope(msg: GenericMessageEnvelope): AvatarServiceResponse = { AvatarServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 913914b2c..9274b8ad9 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -45,12 +45,16 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri eventBus.unsubscribe(sender()) } + protected def commonBehavior: Receive = { + case msg: GenericMessageEnvelope => + handleMessage(msg) + } + def receive: Receive = commonJoinBehavior .orElse(commonLeaveBehavior) + .orElse(commonBehavior) .orElse { - case msg: GenericMessageEnvelope => - handleMessage(msg) - case msg => () + case msg => log.warn(s"Unhandled message $msg from ${sender()}") } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala new file mode 100644 index 000000000..3c563ab39 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -0,0 +1,113 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base + +import net.psforever.services.Service +import net.psforever.types.PlanetSideGUID + +import scala.collection.concurrent.{Map => CMap} +import scala.jdk.CollectionConverters._ +import java.util.concurrent.ConcurrentHashMap +import scala.concurrent.ExecutionContext.Implicits.global + +/* +Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission + */ + +trait CachedGenericEventMessageEnvelope + extends GenericMessageEnvelope { + def guid: PlanetSideGUID +} + +final case class CachedMessage(guid: PlanetSideGUID, channel: String, filter: PlanetSideGUID, msg: EventMessage) + extends CachedGenericEventMessageEnvelope + +object CachedMessage { + def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { + if (filter == Service.defaultPlayerGUID) { + MessageEnvelope(channel, filter, msg) + } else { + CachedMessage(filter, channel, filter, msg) + } + } +} + +object CachedGenericEventMessageEnvelope { + def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { + if (filter == Service.defaultPlayerGUID) { + MessageEnvelope(channel, filter, msg) + } else { + CachedMessage(filter, channel, filter, msg) + } + } + + def apply(guid: PlanetSideGUID, channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { + if (guid == Service.defaultPlayerGUID) { + MessageEnvelope(channel, filter, msg) + } else { + CachedMessage(guid, channel, filter, msg) + } + } +} + +private case object FlushCachedMessages + +abstract class GenericEventServiceWithCacheAndSupport[OUT <: GenericResponseEnvelope] +( + busName: String, + eventSupportServices: List[EventServiceSupport] +) extends GenericEventServiceWithSupport[OUT](busName, eventSupportServices) { + private val flushCacheWait: Long = 50 //milliseconds + private var hasCachedMessages: Boolean = false + private var nextTimeToFlushCache: Long = 0L + private val cache: CMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]] = + new ConcurrentHashMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]]().asScala + + override def postStop(): Unit = { + flushCache() + super.postStop() + } + + private def tryRetimeFlushCache(): Unit = { + if (!hasCachedMessages) { + hasCachedMessages = true + nextTimeToFlushCache = System.currentTimeMillis() + flushCacheWait + } + } + + private def pushToCache(event: CachedGenericEventMessageEnvelope): Unit = { + val eventClassName = event.msg.getClass.getName + val updateBranch = cache + .getOrElseUpdate(event.channel, new ConcurrentHashMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]().asScala) + .getOrElseUpdate(eventClassName, new ConcurrentHashMap[PlanetSideGUID, GenericMessageEnvelope]().asScala) + updateBranch.updateWith(event.guid) { _ => Some(event) } + tryRetimeFlushCache() + } + + private def tryFlushCache(): Unit = { + if (hasCachedMessages && nextTimeToFlushCache < System.currentTimeMillis()) { + flushCache() + } + } + + private def flushCache(): Unit = { + cache.foreachEntry { (_, map) => + map.foreachEntry { (_, map) => + map.foreachEntry { (_, event) => + super.handleMessage(event) + } + map.clear() + } + } + hasCachedMessages = false + } + + override protected def handleMessage(event: GenericMessageEnvelope): Unit = { + event match { + case envelope: CachedGenericEventMessageEnvelope => + pushToCache(envelope) + case _ => + super.handleMessage(event) + } + tryFlushCache() + } +} diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 47af9487a..213c7ac55 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -3,7 +3,7 @@ package net.psforever.services.vehicle import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.zones.Zone -import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericMessageEnvelope} +import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericMessageEnvelope} import net.psforever.services.vehicle.support.TurretUpgrader case object TurretUpgradeSupport @@ -15,7 +15,7 @@ case object TurretUpgradeSupport } class VehicleService(zone: Zone) - extends GenericEventServiceWithSupport[VehicleServiceResponse]( + extends GenericEventServiceWithCacheAndSupport[VehicleServiceResponse]( busName = "Vehicle", eventSupportServices = List(TurretUpgradeSupport) ) { From 4dc5d7f01ee03bc53db05f107239f5878ef344cf Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 16 Feb 2026 16:57:12 -0500 Subject: [PATCH 11/32] reorganized the services.base classes; streamlined the class inheritance structure and param requirements for certain classes; messed up all imports --- .../actor/service/AvatarServiceTest.scala | 56 +++++----- .../actors/session/AvatarActor.scala | 2 +- .../actors/session/SessionActor.scala | 40 ++++--- .../session/csr/AvatarHandlerLogic.scala | 8 +- .../actors/session/csr/ChatLogic.scala | 2 +- .../CustomerServiceRepresentativeMode.scala | 2 +- .../actors/session/csr/GeneralLogic.scala | 2 +- .../session/csr/MountHandlerLogic.scala | 2 +- ...eAsCustomerServiceRepresentativeMode.scala | 2 +- .../actors/session/csr/VehicleLogic.scala | 2 +- .../session/normal/AvatarHandlerLogic.scala | 8 +- .../session/normal/GalaxyHandlerLogic.scala | 3 +- .../actors/session/normal/GeneralLogic.scala | 2 +- .../session/normal/LocalHandlerLogic.scala | 6 +- .../session/normal/MountHandlerLogic.scala | 2 +- .../session/normal/VehicleHandlerLogic.scala | 3 +- .../spectator/AvatarHandlerLogic.scala | 8 +- .../session/spectator/GeneralLogic.scala | 2 +- .../session/spectator/MountHandlerLogic.scala | 2 +- .../session/spectator/SpectatorMode.scala | 2 +- .../spectator/VehicleHandlerLogic.scala | 3 +- .../session/support/GeneralOperations.scala | 2 +- .../support/SessionAvatarHandlers.scala | 3 +- .../support/SessionGalaxyHandlers.scala | 2 +- .../support/SessionLocalHandlers.scala | 2 +- .../support/SessionMountHandlers.scala | 2 +- .../support/SessionOutfitHandlers.scala | 2 +- .../support/SessionSquadHandlers.scala | 2 +- .../support/SessionVehicleHandlers.scala | 2 +- .../WeaponAndProjectileOperations.scala | 2 +- .../session/support/ZoningOperations.scala | 2 +- .../psforever/actors/zone/BuildingActor.scala | 2 +- .../net/psforever/actors/zone/ZoneActor.scala | 2 +- .../zone/building/MajorFacilityLogic.scala | 2 +- .../net/psforever/login/WorldSession.scala | 2 +- .../psforever/objects/BoomerDeployable.scala | 2 +- .../objects/FieldTurretDeployable.scala | 2 +- .../scala/net/psforever/objects/Players.scala | 2 +- .../psforever/objects/SensorDeployable.scala | 2 +- .../objects/ShieldGeneratorDeployable.scala | 2 +- .../scala/net/psforever/objects/Tools.scala | 2 +- .../net/psforever/objects/Vehicles.scala | 2 +- .../objects/avatar/CorpseControl.scala | 2 +- .../objects/avatar/PlayerControl.scala | 3 +- .../avatar/interaction/WithEntrance.scala | 2 +- .../avatar/interaction/WithGantry.scala | 2 +- .../objects/ce/DeployableBehavior.scala | 2 +- .../psforever/objects/ce/TelepadLike.scala | 2 +- .../equipment/ArmorSiphonBehavior.scala | 2 +- .../objects/equipment/JammingUnit.scala | 2 +- .../locker/LockerContainerControl.scala | 2 +- .../damage/DamageableAmenity.scala | 2 +- .../damage/DamageableEntity.scala | 2 +- .../damage/DamageableMountable.scala | 2 +- .../damage/DamageableVehicle.scala | 2 +- .../damage/DamageableWeaponTurret.scala | 2 +- .../generator/GeneratorControl.scala | 2 +- .../hackable/GenericHackables.scala | 2 +- .../serverobject/pad/VehicleSpawnPad.scala | 2 +- .../repair/RepairableAmenity.scala | 2 +- .../repair/RepairableEntity.scala | 2 +- .../resourcesilo/ResourceSiloControl.scala | 2 +- .../shuttle/OrbitalShuttlePadControl.scala | 2 +- .../FacilityHackParticipation.scala | 2 +- .../MajorFacilityHackParticipation.scala | 2 +- .../terminals/ProximityTerminalControl.scala | 2 +- .../implant/ImplantTerminalMechControl.scala | 2 +- .../turret/FacilityTurretControl.scala | 2 +- .../serverobject/turret/TurretControl.scala | 2 +- .../serverobject/turret/WeaponTurrets.scala | 2 +- .../turret/auto/AutomatedTurretBehavior.scala | 2 +- .../vehicles/AntTransferBehavior.scala | 4 +- .../objects/vehicles/CarrierBehavior.scala | 2 +- .../objects/vehicles/control/AmsControl.scala | 2 +- .../objects/vehicles/control/ApcControl.scala | 2 +- .../objects/vehicles/control/BfrControl.scala | 2 +- .../vehicles/control/VehicleCapacitance.scala | 2 +- .../vehicles/control/VehicleControl.scala | 2 +- .../interaction/WithEntranceInVehicle.scala | 2 +- .../net/psforever/objects/zones/MapInfo.scala | 10 +- .../net/psforever/objects/zones/Zone.scala | 2 +- .../objects/zones/ZoneDeployableActor.scala | 2 +- .../objects/zones/ZoneProjectileActor.scala | 2 +- .../objects/zones/ZoneVehicleActor.scala | 2 +- .../services/CavernRotationService.scala | 2 +- .../account/AccountPersistenceService.scala | 2 +- .../services/avatar/AvatarAction.scala | 8 +- .../services/avatar/AvatarService.scala | 17 ++- .../avatar/AvatarServiceMessage.scala | 20 ++-- .../avatar/AvatarServiceResponse.scala | 8 +- .../avatar/support/CorpseRemovalActor.scala | 2 +- .../avatar/support/DroppedItemRemover.scala | 2 +- .../services/base/GenericEventService.scala | 29 ++--- ...nericEventServiceWithCacheAndSupport.scala | 39 +++---- .../base/GenericEventServiceWithSupport.scala | 42 +++++-- .../services/base/MessageEnvelope.scala | 7 -- .../services/base/bus/GenericEventBus.scala | 14 +-- .../base/bus/GenericGuidEventBus.scala | 105 ------------------ .../services/base/envelope/AllEnvelopes.scala | 9 ++ .../envelope/GenericMessageEnvelope.scala | 19 ++++ .../envelope/GenericResponseEnvelope.scala | 22 ++++ .../base/envelope/MessageEnvelope.scala | 37 ++++++ .../{messages => message}/ChangeAmmo.scala | 3 +- .../ChangeFireState_Start.scala | 3 +- .../ChangeFireState_Stop.scala | 3 +- .../services/base/message/ConcealPlayer.scala | 6 + .../base/{ => message}/EventExchange.scala | 8 +- .../GenericObjectAction.scala | 3 +- .../HintsAtAttacker.scala | 3 +- .../{messages => message}/ObjectDelete.scala | 3 +- .../PlanetsideAttribute.scala | 3 +- .../{messages => message}/ReloadTool.scala | 3 +- .../{messages => message}/SendResponse.scala | 3 +- .../{messages => message}/SetEmpire.scala | 3 +- .../{messages => message}/WeaponDryFire.scala | 3 +- .../psforever/services/chat/ChatService.scala | 2 +- .../services/galaxy/GalaxyAction.scala | 2 +- .../services/galaxy/GalaxyService.scala | 16 ++- .../galaxy/GalaxyServiceMessage.scala | 3 +- .../galaxy/GalaxyServiceResponse.scala | 6 +- .../psforever/services/hart/HartTimer.scala | 17 ++- .../services/local/LocalAction.scala | 7 +- .../services/local/LocalService.scala | 14 +-- .../services/local/LocalServiceMessage.scala | 18 +-- .../services/local/LocalServiceResponse.scala | 8 +- .../local/support/CaptureFlagManager.scala | 4 +- .../local/support/HackCaptureActor.scala | 2 +- .../local/support/HackClearActor.scala | 2 +- .../teamwork/SquadServiceMessage.scala | 2 +- .../teamwork/SquadServiceResponse.scala | 10 +- .../teamwork/SquadSubscriptionEntity.scala | 2 +- .../services/vehicle/VehicleAction.scala | 6 +- .../services/vehicle/VehicleService.scala | 19 ++-- .../vehicle/VehicleServiceMessage.scala | 6 +- .../vehicle/VehicleServiceResponse.scala | 8 +- src/test/scala/objects/DamageableTest.scala | 4 +- .../objects/DeployableBehaviorTest.scala | 4 +- src/test/scala/objects/DeployableTest.scala | 4 +- src/test/scala/objects/DeploymentTest.scala | 2 +- .../scala/objects/FacilityTurretTest.scala | 4 +- src/test/scala/objects/GeneratorTest.scala | 4 +- .../scala/objects/PlayerControlTest.scala | 4 +- src/test/scala/objects/RepairableTest.scala | 4 +- src/test/scala/objects/ResourceSiloTest.scala | 4 +- .../scala/objects/TelepadRouterTest.scala | 4 +- .../scala/objects/VehicleControlTest.scala | 4 +- .../objects/terminal/ProximityTest.scala | 2 +- src/test/scala/service/LocalServiceTest.scala | 2 +- .../scala/service/VehicleServiceTest.scala | 38 +++---- 149 files changed, 460 insertions(+), 506 deletions(-) delete mode 100644 src/main/scala/net/psforever/services/base/MessageEnvelope.scala delete mode 100644 src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala create mode 100644 src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala create mode 100644 src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala create mode 100644 src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala create mode 100644 src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala rename src/main/scala/net/psforever/services/base/{messages => message}/ChangeAmmo.scala (84%) rename src/main/scala/net/psforever/services/base/{messages => message}/ChangeFireState_Start.scala (63%) rename src/main/scala/net/psforever/services/base/{messages => message}/ChangeFireState_Stop.scala (63%) create mode 100644 src/main/scala/net/psforever/services/base/message/ConcealPlayer.scala rename src/main/scala/net/psforever/services/base/{ => message}/EventExchange.scala (56%) rename src/main/scala/net/psforever/services/base/{messages => message}/GenericObjectAction.scala (65%) rename src/main/scala/net/psforever/services/base/{messages => message}/HintsAtAttacker.scala (65%) rename src/main/scala/net/psforever/services/base/{messages => message}/ObjectDelete.scala (63%) rename src/main/scala/net/psforever/services/base/{messages => message}/PlanetsideAttribute.scala (78%) rename src/main/scala/net/psforever/services/base/{messages => message}/ReloadTool.scala (61%) rename src/main/scala/net/psforever/services/base/{messages => message}/SendResponse.scala (73%) rename src/main/scala/net/psforever/services/base/{messages => message}/SetEmpire.scala (68%) rename src/main/scala/net/psforever/services/base/{messages => message}/WeaponDryFire.scala (62%) diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala index 8b437a173..eb33c2ab7 100644 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ b/server/src/test/scala/actor/service/AvatarServiceTest.scala @@ -16,13 +16,13 @@ import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstrea import net.psforever.types._ import net.psforever.services.{RemoverActor, Service, ServiceManager} import net.psforever.services.avatar._ -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ObjectDelete, PlanetsideAttribute, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire} class AvatarService1Test extends ActorTest { "AvatarService" should { "construct" in { ServiceManager.boot(system) - system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) assert(true) } } @@ -32,7 +32,7 @@ class AvatarService2Test extends ActorTest { "AvatarService" should { "subscribe" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") assert(true) } @@ -43,7 +43,7 @@ class AvatarService3Test extends ActorTest { "AvatarService" should { ServiceManager.boot(system) "subscribe to a specific channel" in { - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! Service.Leave() assert(true) @@ -55,7 +55,7 @@ class AvatarService4Test extends ActorTest { "AvatarService" should { "subscribe" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! Service.LeaveAll() assert(true) @@ -67,7 +67,7 @@ class AvatarService5Test extends ActorTest { "AvatarService" should { "pass an unhandled message" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! "hello" expectNoMessage() @@ -79,7 +79,7 @@ class ArmorChangedTest extends ActorTest { "AvatarService" should { "pass ArmorChanged" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ArmorChanged(ExoSuitType.Reinforced, 0)) expectMsg( @@ -97,17 +97,17 @@ class ConcealPlayerTest extends ActorTest { "AvatarService" should { "pass ConcealPlayer" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.ConcealPlayer(PlanetSideGUID(10))) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ConcealPlayer(PlanetSideGUID(10)))) + service ! AvatarServiceMessage("test", ConcealPlayer(PlanetSideGUID(10))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ConcealPlayer(PlanetSideGUID(10)))) } } } class EquipmentInHandTest extends ActorTest { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service") + val service = system.actorOf(Props(classOf[AvatarService]), "release-test-service") val toolDef = GlobalDefinitions.beamer val tool = Tool(toolDef) tool.GUID = PlanetSideGUID(40) @@ -134,7 +134,7 @@ class EquipmentInHandTest extends ActorTest { class DroptItemTest extends ActorTest { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service") + val service = system.actorOf(Props(classOf[AvatarService]), "release-test-service") val toolDef = GlobalDefinitions.beamer val tool = Tool(toolDef) tool.Position = Vector3(1, 2, 3) @@ -173,7 +173,7 @@ class LoadPlayerTest extends ActorTest { "AvatarService" should { "pass LoadPlayer" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") //no parent data service ! AvatarServiceMessage( @@ -197,7 +197,7 @@ class ObjectDeleteTest extends ActorTest { "AvatarService" should { "pass ObjectDelete" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11))) expectMsg( @@ -216,7 +216,7 @@ class ObjectHeldTest extends ActorTest { "AvatarService" should { "pass ObjectHeld" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2)) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2))) @@ -228,7 +228,7 @@ class PutDownFDUTest extends ActorTest { "AvatarService" should { "pass PutDownFDU" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10))) expectMsg( @@ -242,7 +242,7 @@ class PlanetsideAttributeTest extends ActorTest { "AvatarService" should { "pass PlanetsideAttribute" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L)) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))) @@ -271,7 +271,7 @@ class PlayerStateTest extends ActorTest { "AvatarService" should { "pass PlayerState" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage( "test", @@ -322,7 +322,7 @@ class PickupItemTest extends ActorTest { "pass PickUpItem" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! PickupItemMessage("test", AvatarAction.PickupItem(tool), Zone.Nowhere) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0))) @@ -333,10 +333,10 @@ class ReloadTest extends ActorTest { "AvatarService" should { "pass Reload" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.Reload(PlanetSideGUID(40))) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.Reload(PlanetSideGUID(40)))) + service ! AvatarServiceMessage("test", PlanetSideGUID(10), ReloadTool(PlanetSideGUID(40))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ReloadTool(PlanetSideGUID(40)))) } } } @@ -348,7 +348,7 @@ class ChangeAmmoTest extends ActorTest { "AvatarService" should { "pass ChangeAmmo" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage( "test", @@ -387,7 +387,7 @@ class ChangeFireModeTest extends ActorTest { "AvatarService" should { "pass ChangeFireMode" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireMode(PlanetSideGUID(40), 0)) expectMsg( @@ -401,7 +401,7 @@ class ChangeFireStateStartTest extends ActorTest { "AvatarService" should { "pass ChangeFireState_Start" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Start(PlanetSideGUID(40))) expectMsg( @@ -419,7 +419,7 @@ class ChangeFireStateStopTest extends ActorTest { "AvatarService" should { "pass ChangeFireState_Stop" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Stop(PlanetSideGUID(40))) expectMsg( @@ -437,7 +437,7 @@ class WeaponDryFireTest extends ActorTest { "AvatarService" should { "pass WeaponDryFire" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), WeaponDryFire(PlanetSideGUID(40))) expectMsg( @@ -453,7 +453,7 @@ class AvatarStowEquipmentTest extends ActorTest { "AvatarService" should { "pass StowEquipment" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName) + val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage( "test", diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 931c2ee0b..6bad7620e 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -49,7 +49,7 @@ import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingAc import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars} import net.psforever.packet.game.{Friend => GameFriend, _} import net.psforever.persistence -import net.psforever.services.base.messages.{SendResponse, PlanetsideAttribute} +import net.psforever.services.base.message.{SendResponse, PlanetsideAttribute} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.types.{ CharacterSex, diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index aaec38df4..578381968 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -18,12 +18,13 @@ import net.psforever.services.CavernRotationService import net.psforever.services.CavernRotationService.SendCavernRotationUpdates import net.psforever.services.ServiceManager.LookupResult import net.psforever.services.account.{PlayerToken, ReceiveAccountData} -import net.psforever.services.avatar.AvatarServiceResponse +import net.psforever.services.avatar.AvatarStamp +import net.psforever.services.base.envelope.{GenericResponseEnvelope, Undelivered} import net.psforever.services.chat.ChatService -import net.psforever.services.galaxy.GalaxyServiceResponse -import net.psforever.services.local.LocalServiceResponse +import net.psforever.services.galaxy.GalaxyStamp +import net.psforever.services.local.LocalStamp import net.psforever.services.teamwork.SquadServiceResponse -import net.psforever.services.vehicle.VehicleServiceResponse +import net.psforever.services.vehicle.VehicleStamp import org.joda.time.LocalDateTime import org.log4s.MDC @@ -170,27 +171,32 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con case packet: PlanetSideGamePacket => handleGamePkt(packet) - case AvatarServiceResponse(toChannel, guid, reply) => - logic.avatarResponse.handle(toChannel, guid, reply) + case SquadServiceResponse(_, excluded, reply) => + logic.squad.handle(reply, excluded) - case GalaxyServiceResponse(_, reply) => - logic.galaxy.handle(reply) - - case LocalServiceResponse(toChannel, guid, reply) => - logic.local.handle(toChannel, guid, reply) + case envelope: GenericResponseEnvelope => + val GenericResponseEnvelope(toChannel, guid, reply) = envelope + envelope.stamp match { + case AvatarStamp => + logic.avatarResponse.handle(toChannel, guid, reply) + case LocalStamp => + logic.local.handle(toChannel, guid, reply) + case VehicleStamp => + logic.vehicleResponse.handle(toChannel, guid, reply) + case GalaxyStamp => + logic.galaxy.handle(reply) + case Undelivered => + log.error(s"received a message's response that was not delivered by an event system - $reply") + case unknownStamp => + log.error(s"received a message's response from an unknown event system - stamp: $unknownStamp") + } case Mountable.MountMessages(tplayer, reply) => logic.mountResponse.handle(tplayer, reply) - case SquadServiceResponse(_, excluded, response) => - logic.squad.handle(response, excluded) - case Terminal.TerminalMessage(tplayer, msg, order) => logic.terminals.handle(tplayer, msg, order) - case VehicleServiceResponse(toChannel, guid, reply) => - logic.vehicleResponse.handle(toChannel, guid, reply) - case ChatService.MessageResponse(fromSession, message, _) => logic.chat.handleIncomingMessage(message, fromSession) 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 5b6306f24..01b88bf05 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -13,8 +13,7 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vital.RevivingActivity import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, HitHint, ImplantAction} import net.psforever.services.avatar.{AvatarAction, AvatarServiceResponse} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import net.psforever.types.ImplantType // @@ -430,9 +429,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case SendResponse(msgs) => msgs.foreach(sendResponse) - case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => - sendResponse(msg) - /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => @@ -505,7 +501,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) - case AvatarAction.ConcealPlayer(_) => + case ConcealPlayer(_) => sendResponse(GenericObjectActionMessage(guid, code=9)) case AvatarAction.EnvironmentalDamage(_, _, _) => diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index 313cb6b62..2825c0554 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -17,7 +17,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{ObjectDelete, SetEmpire} +import net.psforever.services.base.message.{ObjectDelete, SetEmpire} import net.psforever.services.chat.{ChatChannel, DefaultChannel, SpectatorChannel, SquadChannel} import net.psforever.types.ChatMessageType.{CMT_TOGGLESPECTATORMODE, CMT_TOGGLE_GM} import net.psforever.types.{ChatMessageType, PlanetSideEmpire} diff --git a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala index bedddfaf2..e8a15ba1f 100644 --- a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala @@ -11,7 +11,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage, PlanetsideAttributeMessage} import net.psforever.packet.game.objectcreate.RibbonBars import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.chat.{CustomerServiceChannel, SpectatorChannel} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{ChatMessageType, MeritCommendation, PlanetSideGUID} diff --git a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala index 65fc5b052..5aa14d2f6 100644 --- a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala @@ -35,7 +35,7 @@ import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitR import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.RemoverActor import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, CorpseEnvelope} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala index 33dfbf483..1527495ba 100644 --- a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala @@ -15,7 +15,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} diff --git a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala index 4f5158ef4..c5d4eee32 100644 --- a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala @@ -8,7 +8,7 @@ import net.psforever.objects.{Player, Session, Vehicle} import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSidePacket import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import net.psforever.services.chat.SpectatorChannel import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} import net.psforever.types.{ChatMessageType, SquadRequestType} diff --git a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala index 2c7bb30dc..78ba0e05f 100644 --- a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala @@ -14,7 +14,7 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage} import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.CachedMessage -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{DriveState, Vector3} 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 1ff0bdde2..2fcfe4f3f 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -13,8 +13,7 @@ import net.psforever.objects.vital.RevivingActivity import net.psforever.objects.vital.interaction.Adversarial import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction, PlanetsideStringAttributeMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import net.psforever.types.ImplantType import scala.concurrent.duration._ @@ -484,9 +483,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case SendResponse(msgs) => msgs.foreach(sendResponse) - case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => - sendResponse(msg) - /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => @@ -613,7 +609,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) - case AvatarAction.ConcealPlayer(_) => + case ConcealPlayer(_) => sendResponse(GenericObjectActionMessage(guid, code=9)) case AvatarAction.EnvironmentalDamage(_, _, _) => diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index 8ef281b1d..d3980e8ba 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -5,8 +5,7 @@ import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers} import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.{EventResponse, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.types.{MemberAction, PlanetSideEmpire} diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index e7004f6cc..ee784c3c6 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -44,7 +44,7 @@ import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, Avat import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.base.CachedMessage -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.util.Config 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 173e76393..93421ec75 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -9,8 +9,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, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse, SetEmpire} +import net.psforever.services.base.message.{EventResponse, GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse, SetEmpire} import net.psforever.services.{InterstellarClusterService, Service} import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideGUID, SpawnGroup} @@ -154,9 +153,6 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act case LocalAction.GenericActionMessage(actionNumber) => sendResponse(GenericActionMessage(actionNumber)) - case LocalAction.ChatMessage(msg) => - sendResponse(msg) - case LocalAction.LluSpawned(llu) => // Create LLU on client sendResponse(ObjectCreateMessage( diff --git a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala index 163ac36fd..c17a7a884 100644 --- a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala @@ -16,7 +16,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} 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 54bef7716..821625483 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -14,8 +14,7 @@ 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.services.Service -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.local.support.CaptureFlagManager import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3} 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 d1a957407..b393c0847 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -8,8 +8,7 @@ import net.psforever.objects.Players import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.{AvatarImplantMessage, ImplantAction} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import scala.concurrent.duration._ // @@ -416,9 +415,6 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(msg) } - case AvatarAction.SendResponseTargeted(targetGuid, msg) if resolvedPlayerGuid == targetGuid => - sendResponse(msg) - /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => @@ -504,7 +500,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) - case AvatarAction.ConcealPlayer(_) => + case ConcealPlayer(_) => sendResponse(GenericObjectActionMessage(guid, code=9)) case AvatarAction.EnvironmentalDamage(_, _, _) => diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala index 7755718c4..0a89abf82 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala @@ -18,7 +18,7 @@ import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessa import net.psforever.services.account.AccountPersistenceService import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.base.CachedMessage -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.{ExoSuitType, Vector3} import scala.concurrent.duration.DurationInt diff --git a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala index 5b9d41beb..a5f3213a4 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala @@ -12,7 +12,7 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} diff --git a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala index 1cb2618d2..993735e1d 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala @@ -12,7 +12,7 @@ import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage, import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars} import net.psforever.services.Service import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import net.psforever.services.chat.SpectatorChannel import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} import net.psforever.types.{CapacitorStateType, ChatMessageType, ExoSuitType, MeritCommendation, SquadRequestType} 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 674e39f54..bee65c613 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -8,8 +8,7 @@ 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.services.base.EventResponse -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, GenericObjectAction, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 1f259043b..483b03306 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -19,7 +19,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.RemoverActor import net.psforever.services.avatar.GroundEnvelope -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.local.support.HackCaptureActor import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index 575a8a587..f8214d24b 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -9,8 +9,7 @@ import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.objects.zones.exp import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, AvatarServiceResponse} -import net.psforever.services.base.EventResponse -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.{EventResponse, SendResponse} import net.psforever.services.chat.OutfitChannel import scala.collection.mutable diff --git a/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala index 3f01a8ce6..adc4d742c 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala @@ -3,7 +3,7 @@ package net.psforever.actors.session.support import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.packet.game.FriendsResponse -import net.psforever.services.base.EventResponse +import net.psforever.services.base.message.EventResponse import scala.annotation.unused // diff --git a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala index b911ffdd1..527636d03 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala @@ -7,7 +7,7 @@ import net.psforever.objects.ce.Deployable import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.packet.game.{GenericObjectActionMessage, ObjectDeleteMessage, PlanetsideAttributeMessage, TriggerEffectMessage} -import net.psforever.services.base.EventResponse +import net.psforever.services.base.message.EventResponse import net.psforever.types.{PlanetSideGUID, Vector3} trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality { diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index 12c448913..c7adf3df8 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -9,7 +9,7 @@ import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} import net.psforever.services.base.CachedMessage -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} // diff --git a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala index 53c2e0b2d..a7d5f4bd9 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala @@ -9,7 +9,7 @@ import net.psforever.packet.game.OutfitEventAction.{Initial, Leaving, OutfitInfo import net.psforever.packet.game.OutfitMembershipResponse.PacketType.CreateResponse import net.psforever.packet.game._ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.chat.OutfitChannel import net.psforever.types.ChatMessageType import net.psforever.util.Config diff --git a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala index 25469f213..3645b91a2 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala @@ -2,7 +2,7 @@ package net.psforever.actors.session.support import akka.actor.{ActorContext, ActorRef, typed} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.teamwork.SquadServiceResponse import scala.collection.mutable diff --git a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala index 03d0f0df2..a3d1d6cad 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala @@ -5,7 +5,7 @@ import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.objects.Vehicle import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.EventResponse +import net.psforever.services.base.message.EventResponse import net.psforever.types.{ChatMessageType, DriveState, PlanetSideGUID} trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality { diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index c9ac61149..a895ab087 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -29,7 +29,7 @@ import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest import net.psforever.services.Service import net.psforever.services.base.CachedMessage -import net.psforever.services.base.messages.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3} import net.psforever.util.Config diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 79767068c..68d3f3a58 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -23,7 +23,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage} import net.psforever.services.avatar.{CorpseEnvelope, ReleaseMessage} -import net.psforever.services.base.messages.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.chat.DefaultChannel import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala index 79c51dd6f..48cff7c6d 100644 --- a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala +++ b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala @@ -11,7 +11,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.ContinentalLockUpdateMessage import net.psforever.persistence -import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.LocalServiceMessage import net.psforever.services.{InterstellarClusterService, ServiceManager} diff --git a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala index 8d8a6ef75..a6d7206cd 100644 --- a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala +++ b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala @@ -20,7 +20,7 @@ import net.psforever.objects.zones.exp.{ExperienceCalculator, SupportExperienceC import net.psforever.packet.game.{BuildingInfoUpdateMessage, PlanetsideAttributeMessage} import net.psforever.util.Database._ import net.psforever.persistence -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalServiceMessage import scala.collection.mutable diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index caeb3cf33..dbef18ddc 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -16,7 +16,7 @@ import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.PlanetsideAttributeMessage import net.psforever.services.InterstellarClusterService import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{GenericObjectAction, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.{CaptureMessage, HackClearMessage, LocalServiceMessage} import net.psforever.services.local.support.{HackCaptureActor, HackClearActor} diff --git a/src/main/scala/net/psforever/login/WorldSession.scala b/src/main/scala/net/psforever/login/WorldSession.scala index ccc0d4860..dd9a137c0 100644 --- a/src/main/scala/net/psforever/login/WorldSession.scala +++ b/src/main/scala/net/psforever/login/WorldSession.scala @@ -16,7 +16,7 @@ import net.psforever.objects.vital.TerminalUsedActivity import net.psforever.objects.zones.Zone import net.psforever.types.{ExoSuitType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/src/main/scala/net/psforever/objects/BoomerDeployable.scala index 3d9c9ade7..4e9f4cf3e 100644 --- a/src/main/scala/net/psforever/objects/BoomerDeployable.scala +++ b/src/main/scala/net/psforever/objects/BoomerDeployable.scala @@ -12,7 +12,7 @@ import net.psforever.objects.vital.etc.TriggerUsedReason import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.zones.Zone import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideEmpire diff --git a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala index 1e7f1835c..b098e17f0 100644 --- a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala @@ -12,7 +12,7 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, TurretSource} import net.psforever.objects.vital.{DismountingActivity, InGameActivity, MountingActivity, ShieldCharge} import net.psforever.packet.game.HackState1 -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.vehicle.VehicleServiceMessage import scala.annotation.unused diff --git a/src/main/scala/net/psforever/objects/Players.scala b/src/main/scala/net/psforever/objects/Players.scala index 85a3301a6..337491e3d 100644 --- a/src/main/scala/net/psforever/objects/Players.scala +++ b/src/main/scala/net/psforever/objects/Players.scala @@ -21,7 +21,7 @@ import net.psforever.packet.game._ import net.psforever.types.{ChatMessageType, ExoSuitType, PlanetSideGUID, Vector3} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{ObjectDelete, SendResponse} +import net.psforever.services.base.message.{ObjectDelete, SendResponse} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import scala.annotation.tailrec diff --git a/src/main/scala/net/psforever/objects/SensorDeployable.scala b/src/main/scala/net/psforever/objects/SensorDeployable.scala index 113aad232..ce7fd8a74 100644 --- a/src/main/scala/net/psforever/objects/SensorDeployable.scala +++ b/src/main/scala/net/psforever/objects/SensorDeployable.scala @@ -13,7 +13,7 @@ import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.SimpleResolutions import net.psforever.objects.vital.interaction.DamageResult import net.psforever.types.{PlanetSideGUID, Vector3} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.VehicleServiceMessage diff --git a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala index 3d84b6df9..96a80ef25 100644 --- a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala +++ b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala @@ -13,7 +13,7 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.resolution.ResolutionCalculations -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.PlanetSideGUID import net.psforever.services.vehicle.VehicleServiceMessage diff --git a/src/main/scala/net/psforever/objects/Tools.scala b/src/main/scala/net/psforever/objects/Tools.scala index 846e9089a..4c4ca573c 100644 --- a/src/main/scala/net/psforever/objects/Tools.scala +++ b/src/main/scala/net/psforever/objects/Tools.scala @@ -4,7 +4,7 @@ package net.psforever.objects import net.psforever.objects.equipment.ChargeFireModeDefinition import net.psforever.packet.game.QuantityUpdateMessage import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse object Tools { /** diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 8ae8ce14f..6c21b1bf3 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -14,7 +14,7 @@ import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObje import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.Service import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire} +import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} diff --git a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala index 99d1d38ba..aad190d15 100644 --- a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala @@ -9,7 +9,7 @@ import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessa import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{ObjectDelete, SendResponse} +import net.psforever.services.base.message.{ObjectDelete, SendResponse} class CorpseControl(player: Player) extends Actor with ContainableBehavior { def ContainerObject = player diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 2bfb19697..156deb8c9 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -36,8 +36,7 @@ import net.psforever.objects.vital.collision.CollisionReason import net.psforever.objects.vital.etc.{PainboxReason, SuicideReason} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.PlanetSideGamePacket -import net.psforever.services.base.EventMessage -import net.psforever.services.base.messages.{HintsAtAttacker, ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{EventMessage, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, SendResponse} import org.joda.time.{LocalDateTime, Seconds} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala index 8e453f38e..7fc2c8aaa 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala @@ -6,7 +6,7 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.serverobject.environment.interaction.{InteractionWith, RespondsToZoneEnvironment} import net.psforever.objects.serverobject.interior.{Sidedness, TraditionalInteriorAware} import net.psforever.objects.zones.interaction.InteractsWithZone -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.types.Vector3 import scala.annotation.unused diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala index 40d6a1a15..452cd5bf9 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, PlayerStateShiftMessage, ShiftState} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.hart.ShuttleState import net.psforever.types.ChatMessageType diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index 2bd35981d..fc8215fd0 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -8,7 +8,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.services.Service import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.SetEmpire +import net.psforever.services.base.message.SetEmpire import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideEmpire diff --git a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala index 8bf33f935..e730cfef8 100644 --- a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala +++ b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala @@ -9,7 +9,7 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.Zone import net.psforever.packet.game.{GenericObjectActionMessage, ObjectCreateMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID diff --git a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala index 259d2ca34..73355c951 100644 --- a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala +++ b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala @@ -10,7 +10,7 @@ import net.psforever.objects.vital.RepairFromArmorSiphon import net.psforever.objects.vital.etc.{ArmorSiphonModifiers, ArmorSiphonReason} import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.packet.game.QuantityUpdateMessage -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.PlanetSideGUID diff --git a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala index 727955fb6..126a44efb 100644 --- a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala +++ b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala @@ -8,7 +8,7 @@ import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.{Zone, ZoneAware} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.Vector3 import net.psforever.services.vehicle.VehicleServiceMessage diff --git a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala index fcab05d63..19a1e388f 100644 --- a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala +++ b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala @@ -7,7 +7,7 @@ import net.psforever.objects.serverobject.containable.{Containable, ContainableB import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{ObjectDelete, SendResponse} +import net.psforever.services.base.message.{ObjectDelete, SendResponse} import net.psforever.types.{PlanetSideEmpire, Vector3} /** diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala index ee7329f58..b0ba85a90 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala @@ -4,7 +4,7 @@ package net.psforever.objects.serverobject.damage import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.vital.interaction.DamageResult import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute /** * The "control" `Actor` mixin for damage-handling code diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala index e7aad04fb..b4dea9b97 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala @@ -9,7 +9,7 @@ import net.psforever.objects.zones.Zone import net.psforever.types.PlanetSideGUID import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute /** * The "control" `Actor` mixin for damage-handling code, diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala index 73fe52c68..6ae266790 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala @@ -8,7 +8,7 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{HintsAtAttacker, SendResponse} +import net.psforever.services.base.message.{HintsAtAttacker, SendResponse} /** * Functions to assist other damage-dealing code for objects that contain users. diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index 5ca796630..b948c0f80 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -13,7 +13,7 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.Service -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.Vector3 diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index 595d8eb40..2b10df5ac 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -10,7 +10,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types.Vector3 import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.base.support.SupportActor import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{TurretMessage, VehicleServiceMessage} diff --git a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala index 6d6e469a7..42e561f2c 100644 --- a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala @@ -14,7 +14,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.TriggerEffectMessage import net.psforever.types.{PlanetSideGeneratorState, Vector3} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index 07a3138ea..86c8f6774 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -12,7 +12,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.support.HackClearActor import net.psforever.services.local.{HackClearMessage, HackEntityMessage, LocalAction, LocalServiceMessage} diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala index a48d69cbd..340cb235d 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala @@ -5,7 +5,7 @@ import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.objects.{Player, Vehicle} import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.serverobject.terminals.Terminal -import net.psforever.services.base.SelfRespondingEvent +import net.psforever.services.base.message.SelfRespondingEvent import net.psforever.types.PlanetSideGUID /** diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala index 5971778e3..0a09a5251 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala @@ -6,7 +6,7 @@ import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.sourcing.{SourceEntry, SourceWithHealthEntry} import net.psforever.objects.vital.{DamagingActivity, RepairFromEquipment, SpawningActivity} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute /** * The "control" `Actor` mixin for repair-handling code diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index 0fe895f16..07b4fe238 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -9,7 +9,7 @@ import net.psforever.objects.{Player, Tool} import net.psforever.packet.game.{ChatMsg, InventoryStateMessage, RepairMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} /** * The "control" `Actor` mixin for repair-handling code, diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 6d6ce69e3..3427690d1 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -12,7 +12,7 @@ import net.psforever.objects.{GlobalDefinitions, Ntu, NtuContainer, NtuStorageBe import net.psforever.types.{ExperienceType, PlanetSideEmpire} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.util.Config diff --git a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala index c15e723c9..1814f3ec4 100644 --- a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala @@ -9,7 +9,7 @@ import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.base.support.SupportActor import net.psforever.services.local.{DoorMessage, LocalAction} import net.psforever.services.hart.{HartTimer, HartTimerActions} diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index 2680a70e1..0a6be53e7 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -4,7 +4,7 @@ package net.psforever.objects.serverobject.structures.participation import net.psforever.objects.Player import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.UniquePlayer -import net.psforever.services.base.messages.GenericObjectAction +import net.psforever.services.base.message.GenericObjectAction import net.psforever.types.{PlanetSideEmpire, Vector3} import scala.collection.mutable diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala index eea512207..73f1df132 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala @@ -15,7 +15,7 @@ import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalServiceMessage import scala.collection.mutable diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index 9c9188c27..2628d5d2f 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -6,7 +6,7 @@ import net.psforever.objects.serverobject.damage.Damageable import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.local.HackClearMessage import net.psforever.services.local.support.HackClearActor import org.log4s.Logger diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala index efddb12cb..5417d1d8b 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala @@ -16,7 +16,7 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.objects.{GlobalDefinitions, Player, SimpleItem} import net.psforever.packet.game.HackState1 -import net.psforever.services.base.messages.SetEmpire +import net.psforever.services.base.message.SetEmpire import net.psforever.services.local.LocalServiceMessage import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index c60458646..f7541edf9 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -13,7 +13,7 @@ import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.{ChangeFireModeMessage, HackState1} -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideEmpire, PlanetSideGUID} diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala index 150b1513e..d1ec9dbe4 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala @@ -9,7 +9,7 @@ import net.psforever.objects.serverobject.damage.{Damageable, DamageableWeaponTu import net.psforever.objects.serverobject.repair.RepairableWeaponTurret import net.psforever.objects.vital.interaction.DamageResult import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute trait TurretControl extends Actor diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index 186122128..75c13a4d2 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -6,7 +6,7 @@ import net.psforever.objects.ce.Deployable import net.psforever.objects.{Player, Tool, TurretDeployable} import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala index c8d073e4d..08e5fcabd 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala @@ -18,7 +18,7 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.objects.{Default, PlanetSideGameObject, Player} import net.psforever.packet.game.{ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ObjectDetectedMessage} import net.psforever.services.Service -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{PlanetSideGUID, Vector3} diff --git a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala index 16d74d1b8..fb78e30aa 100644 --- a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala @@ -8,12 +8,12 @@ import net.psforever.objects.serverobject.deploy.Deployment import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} -import net.psforever.objects.{NtuContainer, _} +import net.psforever.objects._ import net.psforever.types.DriveState import net.psforever.services.vehicle.VehicleServiceMessage import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.serverobject.transfer.TransferContainer.TransferMaterial -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala index 1ae3c28ec..10da95dc9 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala @@ -11,7 +11,7 @@ import net.psforever.packet.game.{CargoMountPointStatusMessage, ObjectAttachMess import net.psforever.types.{BailType, CargoStatus, PlanetSideGUID, Vector3} import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.Service -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala index d86ff43d5..5a24daec4 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala @@ -2,7 +2,7 @@ package net.psforever.objects.vehicles.control import net.psforever.objects._ -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.DriveState diff --git a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala index 034006cbe..3ec15a33c 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala @@ -11,7 +11,7 @@ import net.psforever.objects.vital.prop.DamageWithPosition import net.psforever.objects.zones.Zone import net.psforever.packet.game.{TriggerEffectMessage, TriggeredEffectLocation} import net.psforever.services.Service -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.PlanetSideGUID diff --git a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala index 47782dc74..1edfdadbe 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala @@ -17,7 +17,7 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.services.Service -import net.psforever.services.base.messages.{GenericObjectAction, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types._ diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala index 27201cb64..d0303d72e 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala @@ -3,7 +3,7 @@ package net.psforever.objects.vehicles.control import akka.actor.{Actor, Cancellable} import net.psforever.objects._ -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.vehicle.VehicleServiceMessage import scala.concurrent.ExecutionContext.Implicits.global diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index b1aed1796..3d3a6b0f2 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -37,7 +37,7 @@ import net.psforever.packet.game._ import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types._ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import scala.annotation.unused diff --git a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala index f8f807423..874438a84 100644 --- a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala +++ b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala @@ -6,7 +6,7 @@ import net.psforever.objects.avatar.interaction.WithEntrance import net.psforever.objects.serverobject.doors.InteriorDoorPassage import net.psforever.objects.serverobject.environment.PieceOfEnvironment import net.psforever.objects.zones.interaction.InteractsWithZone -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse class WithEntranceInVehicle extends WithEntrance() { diff --git a/src/main/scala/net/psforever/objects/zones/MapInfo.scala b/src/main/scala/net/psforever/objects/zones/MapInfo.scala index 3635eecbd..a005a2fb8 100644 --- a/src/main/scala/net/psforever/objects/zones/MapInfo.scala +++ b/src/main/scala/net/psforever/objects/zones/MapInfo.scala @@ -4,9 +4,8 @@ import enumeratum.values.{StringEnum, StringEnumEntry} import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle} import net.psforever.objects.serverobject.environment._ import net.psforever.packet.game.{ChatMsg, OffshoreVehicleMessage} -import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -690,10 +689,7 @@ object MapEnvironment { val warning = s"Do not travel any further $trespass of the battlefield or you$punishment" p.Zone.AvatarEvents ! AvatarServiceMessage( p.Name, - AvatarAction.SendResponseTargeted( - Service.defaultPlayerGUID, - ChatMsg(ChatMessageType.CMT_QUIT, warning) - ) + SendResponse(ChatMsg(ChatMessageType.CMT_QUIT, warning)) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/zones/Zone.scala b/src/main/scala/net/psforever/objects/zones/Zone.scala index c01c41f05..06a03638d 100644 --- a/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -1616,7 +1616,7 @@ object Zone { zone.avatarEvents = context.actorOf(Props(classOf[AvatarService], zone), s"$id-avatar-events") zone.localEvents = context.actorOf(Props(classOf[LocalService], zone), s"$id-local-events") - zone.vehicleEvents = context.actorOf(Props(classOf[VehicleService], zone), s"$id-vehicle-events") + zone.vehicleEvents = context.actorOf(Props(classOf[VehicleService]), s"$id-vehicle-events") zone.timeOfDayOrigin = System.currentTimeMillis() diff --git a/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala index b58e29a77..b840e2e02 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala @@ -10,7 +10,7 @@ import net.psforever.objects.sourcing.ObjectSource import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vital.SpawningActivity import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalServiceMessage import net.psforever.types.ChatMessageType diff --git a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala index cf0052e88..485915bd0 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala @@ -6,7 +6,7 @@ import net.psforever.objects.ballistics.Projectile import net.psforever.objects.guid.{GUIDTask, StraightforwardTask, TaskBundle, TaskWorkflow} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import net.psforever.types.PlanetSideGUID import scala.collection.mutable diff --git a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala index 8f1afb302..834f47e19 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala @@ -9,7 +9,7 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vital.InGameHistory import net.psforever.objects.{Default, GlobalDefinitions, Vehicle} import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, Vector3} diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index ddd46e693..7e3d76581 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -12,7 +12,7 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.message.SendResponse import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage, GalaxyServiceResponse} import net.psforever.types.ChatMessageType import net.psforever.util.Config diff --git a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala index 1fc186ab9..94274bfb0 100644 --- a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala +++ b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala @@ -16,7 +16,7 @@ import net.psforever.persistence import net.psforever.types.Vector3 import net.psforever.services.{Service, ServiceManager} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.zones.Zones diff --git a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala index 8be69ed6f..22e223e91 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala @@ -10,11 +10,9 @@ import net.psforever.objects.serverobject.environment.interaction.common.Watery. import net.psforever.objects.sourcing.{SourceEntry, UniquePlayer} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone -import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage} import net.psforever.packet.game.objectcreate.{ConstructorData, DroppedItemData, ObjectCreateMessageParent, PlacementData} -import net.psforever.services.base.messages.ObjectDelete -import net.psforever.services.base.{EventMessage, EventResponse, SelfRespondingEvent} +import net.psforever.services.base.message.{EventMessage, EventResponse, ObjectDelete, SelfRespondingEvent} import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideGUID, TransactionType, Vector3} import scala.concurrent.duration.FiniteDuration @@ -26,8 +24,6 @@ object AvatarAction { final case class ChangeFireMode(item_guid: PlanetSideGUID, mode: Int) extends SelfRespondingEvent - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent - final case class EnvironmentalDamage(player_guid: PlanetSideGUID, source_guid: PlanetSideGUID, amount: Int) extends SelfRespondingEvent final case class DeactivateImplantSlot(player_guid: PlanetSideGUID, slot: Int) extends SelfRespondingEvent @@ -153,8 +149,6 @@ object AvatarAction { final case class StowEquipment(target_guid: PlanetSideGUID, slot: Int, item: Equipment) extends SelfRespondingEvent - final case class SendResponseTargeted(target_guid: PlanetSideGUID, msg: PlanetSideGamePacket) extends SelfRespondingEvent - final case class TerminalOrderResult(terminal_guid: PlanetSideGUID, action: TransactionType.Value, result: Boolean) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index 5056236cb..df04c6196 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -2,9 +2,8 @@ package net.psforever.services.avatar import akka.actor.{ActorContext, ActorRef, Props} -import net.psforever.objects.zones.Zone import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover} -import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericMessageEnvelope} +import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericEventServiceWithCacheAndSupport} case object CorpseRemovalSupport extends EventServiceSupport { @@ -22,12 +21,10 @@ case object LitterRemovalSupport } } -class AvatarService(zone: Zone) - extends GenericEventServiceWithCacheAndSupport[AvatarServiceResponse]( - busName = "Avatar", +case object AvatarStamp extends EventSystemStamp + +class AvatarService + extends GenericEventServiceWithCacheAndSupport( + stamp = AvatarStamp, eventSupportServices = List(CorpseRemovalSupport, LitterRemovalSupport) - ) { - protected def composeResponseEnvelope(msg: GenericMessageEnvelope): AvatarServiceResponse = { - AvatarServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) - } -} + ) diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala index 951fd07c8..a8e7d530c 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala @@ -4,7 +4,9 @@ package net.psforever.services.avatar import net.psforever.objects.zones.Zone import net.psforever.services.{RemoverActor, Service} import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem, Release} -import net.psforever.services.base.{EventMessage, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly, MessageEnvelope} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.EventMessage +import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.types.PlanetSideGUID object AvatarServiceMessage { @@ -16,11 +18,11 @@ object AvatarServiceMessage { } final case class ReleaseMessage( - channel: String, + originalChannel: String, filter: PlanetSideGUID, msg: Release ) - extends GenericMessageToSupportEnvelope { + extends GenericSupportEnvelope { def supportLabel: String = "undertaker" def supportMessage: Any = { val Release(player, zone, time) = msg @@ -34,12 +36,12 @@ object ReleaseMessage { } final case class PickupItemMessage( - channel: String, + originalChannel: String, filter: PlanetSideGUID, msg: PickupItem, zone: Zone ) - extends GenericMessageToSupportEnvelope { + extends GenericSupportEnvelope { def supportLabel: String = "janitor" def supportMessage: Any = { val PickupItem(item, _) = msg @@ -53,12 +55,12 @@ object PickupItemMessage { } final case class DropItemMessage( - channel: String, + originalChannel: String, filter: PlanetSideGUID, msg: DropItem, zone: Zone ) - extends GenericMessageToSupportEnvelope { + extends GenericSupportEnvelope { def supportLabel: String = "janitor" def supportMessage: Any = { val DropItem(item) = msg @@ -72,11 +74,11 @@ object DropItemMessage { } final case class CorpseEnvelope(supportMessage: Any) - extends GenericMessageToSupportEnvelopeOnly { + extends GenericSupportEnvelopeOnly { def supportLabel: String = "undertaker" } final case class GroundEnvelope(supportMessage: Any) - extends GenericMessageToSupportEnvelopeOnly { + extends GenericSupportEnvelopeOnly { def supportLabel: String = "janitor" } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala index 3f523cb69..a40827b99 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala @@ -1,11 +1,15 @@ // Copyright (c) 2017 PSForever package net.psforever.services.avatar +import net.psforever.services.base.message.EventResponse import net.psforever.types.PlanetSideGUID -import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.envelope.GenericResponseEnvelope final case class AvatarServiceResponse( channel: String, filter: PlanetSideGUID, reply: EventResponse - ) extends GenericResponseEnvelope + ) extends GenericResponseEnvelope { + def stamp: EventSystemStamp = AvatarStamp +} diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 822afa1d9..e4d53dcb1 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -6,7 +6,7 @@ import net.psforever.objects.Player import net.psforever.types.ExoSuitType import net.psforever.services.RemoverActor import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index 8e4245e56..dbdf5d252 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -5,7 +5,7 @@ import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.services.RemoverActor import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.messages.ObjectDelete +import net.psforever.services.base.message.ObjectDelete import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 9274b8ad9..d294539ed 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -3,32 +3,23 @@ package net.psforever.services.base import akka.actor.Actor import net.psforever.services.Service -import net.psforever.services.base.bus.{AllGenericBusMsg, GenericEventBus, GenericEventBusResponse} +import net.psforever.services.base.bus.GenericEventBus +import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope} import org.log4s.Logger import scala.annotation.unused -trait GenericResponseEnvelope - extends GenericEventBusResponse { - def reply: EventResponse -} +trait EventSystemStamp -trait GenericMessageEnvelope - extends AllGenericBusMsg { - def msg: EventMessage -} - -abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: String) +abstract class GenericEventService(stamp: EventSystemStamp) extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) - protected val eventBus: GenericEventBus[OUT] = new GenericEventBus[OUT] - - def BusName: String = busName + protected val eventBus: GenericEventBus = new GenericEventBus private def commonJoinBehavior: Receive = { case Service.Join(channel) => - val path = formatChannelOnBusName(channel) + val path = formatChannel(channel) val who = sender() eventBus.subscribe(who, path) } @@ -38,7 +29,7 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri eventBus.unsubscribe(sender()) case Service.Leave(Some(channel)) => - val path = formatChannelOnBusName(channel) + val path = formatChannel(channel) eventBus.unsubscribe(sender(), path) case Service.LeaveAll() => @@ -62,7 +53,9 @@ abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: Stri eventBus.publish(composeResponseEnvelope(msg)) } - protected def composeResponseEnvelope(@unused msg: GenericMessageEnvelope): OUT + protected def composeResponseEnvelope(@unused msg: GenericMessageEnvelope): GenericResponseEnvelope = { + msg.response(stamp, formatChannel) + } - protected def formatChannelOnBusName(channel: String): String = s"/$channel/$busName" + protected def formatChannel(channel: String): String = s"/$channel" } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index 3c563ab39..abdb1b9f4 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -2,24 +2,31 @@ package net.psforever.services.base import net.psforever.services.Service +import net.psforever.services.base.envelope.{GenericMessageEnvelope, MessageEnvelope, MessageTransformationBehavior} +import net.psforever.services.base.message.EventMessage import net.psforever.types.PlanetSideGUID import scala.collection.concurrent.{Map => CMap} import scala.jdk.CollectionConverters._ import java.util.concurrent.ConcurrentHashMap -import scala.concurrent.ExecutionContext.Implicits.global /* Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission */ trait CachedGenericEventMessageEnvelope - extends GenericMessageEnvelope { + extends MessageTransformationBehavior { def guid: PlanetSideGUID } -final case class CachedMessage(guid: PlanetSideGUID, channel: String, filter: PlanetSideGUID, msg: EventMessage) - extends CachedGenericEventMessageEnvelope +final case class CachedMessage( + guid: PlanetSideGUID, + originalChannel: String, + override val filter: PlanetSideGUID, + override val msg: EventMessage + ) extends CachedGenericEventMessageEnvelope { + assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") +} object CachedMessage { def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { @@ -31,31 +38,13 @@ object CachedMessage { } } -object CachedGenericEventMessageEnvelope { - def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { - if (filter == Service.defaultPlayerGUID) { - MessageEnvelope(channel, filter, msg) - } else { - CachedMessage(filter, channel, filter, msg) - } - } - - def apply(guid: PlanetSideGUID, channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { - if (guid == Service.defaultPlayerGUID) { - MessageEnvelope(channel, filter, msg) - } else { - CachedMessage(guid, channel, filter, msg) - } - } -} - private case object FlushCachedMessages -abstract class GenericEventServiceWithCacheAndSupport[OUT <: GenericResponseEnvelope] +abstract class GenericEventServiceWithCacheAndSupport ( - busName: String, + stamp: EventSystemStamp, eventSupportServices: List[EventServiceSupport] -) extends GenericEventServiceWithSupport[OUT](busName, eventSupportServices) { +) extends GenericEventServiceWithSupport(stamp, eventSupportServices) { private val flushCacheWait: Long = 50 //milliseconds private var hasCachedMessages: Boolean = false private var nextTimeToFlushCache: Long = 0L diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index 508086d4b..0138898f5 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -3,40 +3,58 @@ package net.psforever.services.base import akka.actor.{ActorContext, ActorRef} import net.psforever.services.Service +import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageTransformationBehavior, NoReply, Undelivered} +import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent} import net.psforever.types.PlanetSideGUID import scala.annotation.unused +case object NoMessage extends SelfRespondingEvent + +case object NoResponseEnvelope extends GenericResponseEnvelope { + def reply: EventResponse = NoReply + def stamp: EventSystemStamp = Undelivered + def channel: String = "" + def filter: PlanetSideGUID = Service.defaultPlayerGUID +} + trait EventServiceSupport { def label: String def constructor(@unused context: ActorContext): ActorRef } -trait GenericMessageToSupportEnvelope - extends GenericMessageEnvelope { +sealed trait GenericMessageToSupport { def supportLabel: String def supportMessage: Any } -trait GenericMessageToSupportEnvelopeOnly - extends GenericMessageToSupportEnvelope { +trait GenericSupportEnvelope + extends GenericMessageToSupport + with MessageTransformationBehavior + +trait GenericSupportEnvelopeOnly + extends GenericMessageToSupport + with GenericMessageEnvelope { + def originalChannel: String = "" def channel: String = "" def filter: PlanetSideGUID = Service.defaultPlayerGUID - def msg: EventMessage = null + def msg: EventMessage = NoMessage + + def response(@unused stamp: EventSystemStamp, @unused sendToChannel: String => String): GenericResponseEnvelope = NoResponseEnvelope } -abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope] +abstract class GenericEventServiceWithSupport ( - busName: String, + stamp: EventSystemStamp, eventSupportServices: List[EventServiceSupport] -) extends GenericEventService[OUT](busName) { +) extends GenericEventService(stamp) { private val supportServices: Map[String, ActorRef] = eventSupportServices .map { supportService => (supportService.label, supportService.constructor(context)) } .toMap[String, ActorRef] - private def forwardToSupport(msg: GenericMessageToSupportEnvelope): Unit = { + private def forwardToSupport(msg: GenericMessageToSupport): Unit = { supportServices .get(msg.supportLabel) .map { support => @@ -50,12 +68,12 @@ abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope] override protected def handleMessage(event: GenericMessageEnvelope): Unit = { event match { - case msg: GenericMessageToSupportEnvelopeOnly => + case msg: GenericSupportEnvelopeOnly => forwardToSupport(msg) - case msg: GenericMessageToSupportEnvelope => + case msg: GenericSupportEnvelope => forwardToSupport(msg) eventBus.publish(composeResponseEnvelope(event)) - case _ => + case event => eventBus.publish(composeResponseEnvelope(event)) } } diff --git a/src/main/scala/net/psforever/services/base/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/MessageEnvelope.scala deleted file mode 100644 index faad6d0d1..000000000 --- a/src/main/scala/net/psforever/services/base/MessageEnvelope.scala +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2026 PSForever -package net.psforever.services.base - -import net.psforever.types.PlanetSideGUID - -case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) - extends GenericMessageEnvelope diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala index a025726d1..26274d04e 100644 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala @@ -3,19 +3,11 @@ package net.psforever.services.base.bus import akka.event.{ActorEventBus, SubchannelClassification} import akka.util.Subclassification -import net.psforever.types.PlanetSideGUID +import net.psforever.services.base.envelope.GenericResponseEnvelope -trait AllGenericBusMsg { - def channel: String - def filter: PlanetSideGUID -} - -trait GenericEventBusResponse - extends AllGenericBusMsg - -class GenericEventBus[A <: GenericEventBusResponse] +class GenericEventBus extends ActorEventBus with SubchannelClassification { - type Event = A + type Event = GenericResponseEnvelope type Classifier = String protected def classify(event: Event): Classifier = event.channel diff --git a/src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala deleted file mode 100644 index d583194e2..000000000 --- a/src/main/scala/net/psforever/services/base/bus/GenericGuidEventBus.scala +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2026 PSForever -package net.psforever.services.base.bus - -import net.psforever.types.PlanetSideGUID - -import java.util.concurrent.ConcurrentHashMap -import scala.annotation.unused -import scala.collection.concurrent.{Map => CMap} -import scala.jdk.CollectionConverters._ - -/* -Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission - */ - -trait GenericGuidEventBusResponse - extends GenericEventBusResponse { - def guid: PlanetSideGUID - def inner: Any -} - -class RateLimitScheduler[A <: GenericGuidEventBusResponse](eventBus: GenericEventBus[A], interval: Long) extends Thread { - private var hasWork: Boolean = false - private var working: Boolean = false - private var timeOfLastFlush: Long = 0L - private val buffer: CMap[String, CMap[String, CMap[PlanetSideGUID, A]]] = - new ConcurrentHashMap[String, CMap[String, CMap[PlanetSideGUID, A]]]().asScala - - override def run(): Unit = { - while (working) { - //originally, there was a Thread.sleep(interval) here, replaced by timeOfLastFlush logic - flushBuffer() - } - } - - def push(event: A): Unit = { - val eventClassName = event.inner.getClass.getName - val cache = - buffer - .getOrElseUpdate(event.channel, new ConcurrentHashMap[String, CMap[PlanetSideGUID, A]]().asScala) - .getOrElseUpdate(eventClassName, new ConcurrentHashMap[PlanetSideGUID, A]().asScala) - cache.updateWith(event.guid) { _ => Some(event) } - hasWork = true - } - - def flushBuffer(): Unit = { - val curr = System.currentTimeMillis() - if (hasWork && timeOfLastFlush + interval <= curr) { - flushBufferNow(curr) - } - } - - def flushBufferNow(curr: Long = System.currentTimeMillis()): Unit = { - buffer.foreachEntry { (_, map) => - map.foreachEntry { (_, map) => - map.foreachEntry { (_, event) => - eventBus.truePublish(event) - } - map.clear() - } - } - hasWork = false - timeOfLastFlush = curr - } - - override def start(): Unit = { - working = true - timeOfLastFlush = System.currentTimeMillis() - super.start() - } - - def isRunning: Boolean = { - working - } - - def stopRunning(): Unit = { - working = false - flushBufferNow() - } -} - -abstract class GenericGuidEventBus[A <: GenericGuidEventBusResponse](rateLimit: Double) - extends GenericEventBus[A] { - private val rateLimitedDispatch = new RateLimitScheduler[A]( - eventBus = this, - scala.math.floor(1000.0 / rateLimit).toInt - ) - rateLimitedDispatch.start() - - override def publish(event: Event): Unit = { - if (rateLimit > 0 && shouldRateLimit(event) && rateLimitedDispatch.isRunning) { - rateLimitedDispatch.push(event) - } else { - truePublish(event) - } - } - - def shouldRateLimit(@unused event: Event): Boolean - -// override protected def publish(event: Event, subscriber: Subscriber): Unit = { -// val trimmedEventClassName = -// event.inner.getClass().getName().stripPrefix(event.inner.getClass.getPackageName() + ".").stripSuffix("$") -// GenericGuidEventBus.genericGuidEventBusPublish.labels(event.channel, trimmedEventClassName).inc() -// subscriber ! event -// } -} diff --git a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala new file mode 100644 index 000000000..7ccf37fc2 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala @@ -0,0 +1,9 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.envelope + +import net.psforever.types.PlanetSideGUID + +trait AllEnvelopes { + def channel: String + def filter: PlanetSideGUID +} diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala new file mode 100644 index 000000000..8ca2f9995 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala @@ -0,0 +1,19 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.envelope + +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.message.EventMessage +import net.psforever.types.PlanetSideGUID + +trait GenericMessageEnvelope + extends AllEnvelopes { + def originalChannel: String + def msg: EventMessage + def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope +} + +object GenericMessageEnvelope { + def unapply(obj: GenericMessageEnvelope): Option[(String, PlanetSideGUID, EventMessage)] = { + Some((obj.originalChannel, obj.filter, obj.msg)) + } +} diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala new file mode 100644 index 000000000..e0abe44c1 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala @@ -0,0 +1,22 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.envelope + +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.message.{EventMessage, EventResponse} +import net.psforever.types.PlanetSideGUID + +trait GenericResponseEnvelope + extends AllEnvelopes { + def reply: EventResponse + def stamp: EventSystemStamp +} + +object GenericResponseEnvelope { + def apply(stamp: EventSystemStamp, channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericResponseEnvelope ={ + val envelope = MessageEnvelope(channel, filter, msg) + envelope.response(stamp, s => s) + } + + def unapply(obj: GenericResponseEnvelope): Option[(String, PlanetSideGUID, EventResponse)] = + Some((obj.channel, obj.filter, obj.reply)) +} diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala new file mode 100644 index 000000000..99c6aa7ca --- /dev/null +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.envelope + +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.message.{EventMessage, EventResponse} +import net.psforever.types.PlanetSideGUID + +case object NoReply extends EventResponse + +case object Undelivered extends EventSystemStamp + +trait MessageTransformationBehavior + extends GenericMessageEnvelope + with GenericResponseEnvelope { + private var outputStamp: EventSystemStamp = Undelivered + private var outputChannel: String = originalChannel + private var outputReply: EventResponse = NoReply + + // satisfies GenericMessageEnvelope2 (and GenericResponseEnvelope2) + def channel: String = outputChannel + + // satisfies GenericMessageEnvelope2 + def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope = { + outputStamp = stamp + outputChannel = sendToChannel(originalChannel) + outputReply = msg.response() + this + } + + // satisfies GenericResponseEnvelope2 + def stamp: EventSystemStamp = outputStamp + + def reply: EventResponse = outputReply +} + +case class MessageEnvelope(originalChannel: String, filter: PlanetSideGUID, msg: EventMessage) + extends MessageTransformationBehavior \ No newline at end of file diff --git a/src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala b/src/main/scala/net/psforever/services/base/message/ChangeAmmo.scala similarity index 84% rename from src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala rename to src/main/scala/net/psforever/services/base/message/ChangeAmmo.scala index 2b51767dd..101a37cc7 100644 --- a/src/main/scala/net/psforever/services/base/messages/ChangeAmmo.scala +++ b/src/main/scala/net/psforever/services/base/message/ChangeAmmo.scala @@ -1,8 +1,7 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message import net.psforever.packet.game.objectcreate.ConstructorData -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class ChangeAmmo( diff --git a/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala b/src/main/scala/net/psforever/services/base/message/ChangeFireState_Start.scala similarity index 63% rename from src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala rename to src/main/scala/net/psforever/services/base/message/ChangeFireState_Start.scala index b73e740b8..59d1bb142 100644 --- a/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Start.scala +++ b/src/main/scala/net/psforever/services/base/message/ChangeFireState_Start.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class ChangeFireState_Start(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala b/src/main/scala/net/psforever/services/base/message/ChangeFireState_Stop.scala similarity index 63% rename from src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala rename to src/main/scala/net/psforever/services/base/message/ChangeFireState_Stop.scala index fa6f1a7d6..5aeb30c11 100644 --- a/src/main/scala/net/psforever/services/base/messages/ChangeFireState_Stop.scala +++ b/src/main/scala/net/psforever/services/base/message/ChangeFireState_Stop.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class ChangeFireState_Stop(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/message/ConcealPlayer.scala b/src/main/scala/net/psforever/services/base/message/ConcealPlayer.scala new file mode 100644 index 000000000..1a642c72c --- /dev/null +++ b/src/main/scala/net/psforever/services/base/message/ConcealPlayer.scala @@ -0,0 +1,6 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.message + +import net.psforever.types.PlanetSideGUID + +final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/EventExchange.scala b/src/main/scala/net/psforever/services/base/message/EventExchange.scala similarity index 56% rename from src/main/scala/net/psforever/services/base/EventExchange.scala rename to src/main/scala/net/psforever/services/base/message/EventExchange.scala index eea7ac7b1..3331927cb 100644 --- a/src/main/scala/net/psforever/services/base/EventExchange.scala +++ b/src/main/scala/net/psforever/services/base/message/EventExchange.scala @@ -1,11 +1,9 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base +package net.psforever.services.base.message -trait EventExchange +trait EventResponse -trait EventResponse extends EventExchange - -trait EventMessage extends EventExchange { +trait EventMessage { def response(): EventResponse } diff --git a/src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala b/src/main/scala/net/psforever/services/base/message/GenericObjectAction.scala similarity index 65% rename from src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala rename to src/main/scala/net/psforever/services/base/message/GenericObjectAction.scala index 2bfe69b26..a62a467f6 100644 --- a/src/main/scala/net/psforever/services/base/messages/GenericObjectAction.scala +++ b/src/main/scala/net/psforever/services/base/message/GenericObjectAction.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class GenericObjectAction(object_guid: PlanetSideGUID, action_code: Int) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala b/src/main/scala/net/psforever/services/base/message/HintsAtAttacker.scala similarity index 65% rename from src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala rename to src/main/scala/net/psforever/services/base/message/HintsAtAttacker.scala index 8768fcb73..dbb835448 100644 --- a/src/main/scala/net/psforever/services/base/messages/HintsAtAttacker.scala +++ b/src/main/scala/net/psforever/services/base/message/HintsAtAttacker.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID //analogue for HitHint diff --git a/src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala b/src/main/scala/net/psforever/services/base/message/ObjectDelete.scala similarity index 63% rename from src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala rename to src/main/scala/net/psforever/services/base/message/ObjectDelete.scala index d8f3343bc..43fb1949e 100644 --- a/src/main/scala/net/psforever/services/base/messages/ObjectDelete.scala +++ b/src/main/scala/net/psforever/services/base/message/ObjectDelete.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class ObjectDelete(obj_guid: PlanetSideGUID, unk: Int = 0) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala b/src/main/scala/net/psforever/services/base/message/PlanetsideAttribute.scala similarity index 78% rename from src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala rename to src/main/scala/net/psforever/services/base/message/PlanetsideAttribute.scala index 0df0cfb3b..6bf3af0b4 100644 --- a/src/main/scala/net/psforever/services/base/messages/PlanetsideAttribute.scala +++ b/src/main/scala/net/psforever/services/base/message/PlanetsideAttribute.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class PlanetsideAttribute( diff --git a/src/main/scala/net/psforever/services/base/messages/ReloadTool.scala b/src/main/scala/net/psforever/services/base/message/ReloadTool.scala similarity index 61% rename from src/main/scala/net/psforever/services/base/messages/ReloadTool.scala rename to src/main/scala/net/psforever/services/base/message/ReloadTool.scala index 34e118391..e4b8aee48 100644 --- a/src/main/scala/net/psforever/services/base/messages/ReloadTool.scala +++ b/src/main/scala/net/psforever/services/base/message/ReloadTool.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class ReloadTool(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/SendResponse.scala b/src/main/scala/net/psforever/services/base/message/SendResponse.scala similarity index 73% rename from src/main/scala/net/psforever/services/base/messages/SendResponse.scala rename to src/main/scala/net/psforever/services/base/message/SendResponse.scala index 6de55c9d6..eca4f292a 100644 --- a/src/main/scala/net/psforever/services/base/messages/SendResponse.scala +++ b/src/main/scala/net/psforever/services/base/message/SendResponse.scala @@ -1,8 +1,7 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message import net.psforever.packet.PlanetSideGamePacket -import net.psforever.services.base.SelfRespondingEvent final case class SendResponse(pkts: Seq[PlanetSideGamePacket]) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/SetEmpire.scala b/src/main/scala/net/psforever/services/base/message/SetEmpire.scala similarity index 68% rename from src/main/scala/net/psforever/services/base/messages/SetEmpire.scala rename to src/main/scala/net/psforever/services/base/message/SetEmpire.scala index dc52a15e4..7e2315372 100644 --- a/src/main/scala/net/psforever/services/base/messages/SetEmpire.scala +++ b/src/main/scala/net/psforever/services/base/message/SetEmpire.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} final case class SetEmpire(object_guid: PlanetSideGUID, faction: PlanetSideEmpire.Value) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala b/src/main/scala/net/psforever/services/base/message/WeaponDryFire.scala similarity index 62% rename from src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala rename to src/main/scala/net/psforever/services/base/message/WeaponDryFire.scala index 9f2f0b8d1..a011bb209 100644 --- a/src/main/scala/net/psforever/services/base/messages/WeaponDryFire.scala +++ b/src/main/scala/net/psforever/services/base/message/WeaponDryFire.scala @@ -1,7 +1,6 @@ // Copyright (c) 2026 PSForever -package net.psforever.services.base.messages +package net.psforever.services.base.message -import net.psforever.services.base.SelfRespondingEvent import net.psforever.types.PlanetSideGUID final case class WeaponDryFire(weapon_guid: PlanetSideGUID) extends SelfRespondingEvent diff --git a/src/main/scala/net/psforever/services/chat/ChatService.scala b/src/main/scala/net/psforever/services/chat/ChatService.scala index e0e2d64f1..5d72ebf71 100644 --- a/src/main/scala/net/psforever/services/chat/ChatService.scala +++ b/src/main/scala/net/psforever/services/chat/ChatService.scala @@ -6,7 +6,7 @@ import akka.actor.typed.{ActorRef, Behavior} import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors} import net.psforever.objects.{Session, SessionSource} import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.{EventMessage, EventResponse} +import net.psforever.services.base.message.{EventMessage, EventResponse} import net.psforever.types.{ChatMessageType, PlanetSideEmpire} object ChatService { diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala index c23f6ec18..96015b6ad 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala @@ -5,7 +5,7 @@ import net.psforever.objects.Vehicle import net.psforever.objects.vehicles.VehicleManifest import net.psforever.objects.zones.{HotSpotInfo, Zone} import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage} -import net.psforever.services.base.SelfRespondingEvent +import net.psforever.services.base.message.SelfRespondingEvent import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} object GalaxyAction { diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index b38b68776..7ff320396 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -1,19 +1,17 @@ // Copyright (c) 2017-2026 PSForever package net.psforever.services.galaxy -import net.psforever.services.base.{GenericEventService, GenericMessageEnvelope} +import net.psforever.services.base.{EventSystemStamp, GenericEventService} + +case object GalaxyStamp extends EventSystemStamp class GalaxyService - extends GenericEventService[GalaxyServiceResponse](busName = "Galaxy") { - protected def composeResponseEnvelope(msg: GenericMessageEnvelope): GalaxyServiceResponse = { - GalaxyServiceResponse(formatChannelOnBusName(msg.channel), msg.msg.response()) - } - - override protected def formatChannelOnBusName(channel: String): String = { + extends GenericEventService(stamp = GalaxyStamp) { + override protected def formatChannel(channel: String): String = { if (channel.trim.isEmpty) { - s"/$BusName" + "/all" } else { - s"/$channel/$BusName" + s"/$channel" } } } diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala index 410053f8a..c0cc087fd 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala @@ -2,7 +2,8 @@ package net.psforever.services.galaxy import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, MessageEnvelope} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.EventMessage object GalaxyServiceMessage { def apply(msg: EventMessage): MessageEnvelope = MessageEnvelope("", Service.defaultPlayerGUID, msg) diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala index 3d68799f2..8cd9cbdee 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala @@ -3,9 +3,13 @@ package net.psforever.services.galaxy import net.psforever.types.PlanetSideGUID import net.psforever.services.Service -import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} +import net.psforever.services.base.message.EventResponse +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.envelope.GenericResponseEnvelope final case class GalaxyServiceResponse(channel: String, reply: EventResponse) extends GenericResponseEnvelope { def filter: PlanetSideGUID = Service.defaultPlayerGUID + + def stamp: EventSystemStamp = GalaxyStamp } diff --git a/src/main/scala/net/psforever/services/hart/HartTimer.scala b/src/main/scala/net/psforever/services/hart/HartTimer.scala index ab5d2d4d7..2086c43b1 100644 --- a/src/main/scala/net/psforever/services/hart/HartTimer.scala +++ b/src/main/scala/net/psforever/services/hart/HartTimer.scala @@ -5,8 +5,10 @@ import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Default import net.psforever.objects.zones.Zone import net.psforever.services.Service -import net.psforever.services.base.bus.{GenericEventBus, GenericEventBusResponse} -import net.psforever.services.base.EventResponse +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.bus.GenericEventBus +import net.psforever.services.base.envelope.{GenericResponseEnvelope, NoReply} +import net.psforever.services.base.message.EventResponse import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{HartSequence, PlanetSideGUID} @@ -45,7 +47,7 @@ class HartTimer(zone: Zone) extends Actor { var timer: Cancellable = Default.Cancellable /** a message bus to which all associated orbital shuttle pads are subscribed */ - val padEvents = new GenericEventBus[HartTimer.Command] + val padEvents = new GenericEventBus /** cache common messages */ val shuttleDockedInThisZone: HartTimer.ShuttleDocked = HartTimer.ShuttleDocked(zoneId) val shuttleFreeFromDockInThisZone: HartTimer.ShuttleFreeFromDock = HartTimer.ShuttleFreeFromDock(zoneId) @@ -256,17 +258,22 @@ object HartTimer { pairs: List[((PlanetSideGUID, PlanetSideGUID), Int)] ) + case object HartStamp extends EventSystemStamp + /** * Design for the envelop for the message bus * to relay instructions back to the individual facility amenity portions of this HART system. * The channel is blank because it does not need special designation. */ - trait Command extends EventResponse with GenericEventBusResponse { + trait Command extends GenericResponseEnvelope { + def originalChannel: String = "" def channel: String = "" def filter: PlanetSideGUID = Service.defaultPlayerGUID + def stamp: EventSystemStamp = HartStamp + def reply: EventResponse = NoReply } /** - * Forbid entry through the boartding gantry doors. + * Forbid entry through the boarding gantry doors. */ case object LockDoors extends Command /** diff --git a/src/main/scala/net/psforever/services/local/LocalAction.scala b/src/main/scala/net/psforever/services/local/LocalAction.scala index cb16c29c5..092b71776 100644 --- a/src/main/scala/net/psforever/services/local/LocalAction.scala +++ b/src/main/scala/net/psforever/services/local/LocalAction.scala @@ -8,9 +8,8 @@ import net.psforever.objects.serverobject.llu.CaptureFlag import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.vehicles.Utility import net.psforever.objects.zones.Zone -import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound} -import net.psforever.services.base.messages.SendResponse -import net.psforever.services.base.{EventMessage, EventResponse, SelfRespondingEvent} +import net.psforever.packet.game.{DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound} +import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent, SendResponse} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent import net.psforever.types.{PlanetSideGUID, Vector3} @@ -59,8 +58,6 @@ object LocalAction { position: Vector3 ) extends SelfRespondingEvent - final case class ChatMessage(msg: ChatMsg) extends SelfRespondingEvent - final case class GenericActionMessage(action_num: GenericAction) extends SelfRespondingEvent final case class ProximityTerminalAction( diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index 37f112cc5..6285bf434 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -5,7 +5,7 @@ import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.zones.Zone import net.psforever.services.local.support.CaptureFlagManager import net.psforever.services.local.support._ -import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericMessageEnvelope} +import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericEventServiceWithSupport} case object DoorCloserSupport extends EventServiceSupport { @@ -39,12 +39,10 @@ case class CaptureFlagSupport(zone: Zone) } } +case object LocalStamp extends EventSystemStamp + class LocalService(zone: Zone) - extends GenericEventServiceWithSupport[LocalServiceResponse]( - busName = "Local", + extends GenericEventServiceWithSupport( + stamp = LocalStamp, eventSupportServices = List(DoorCloserSupport, HackClearSupport, HackCaptureSupport, CaptureFlagSupport(zone)) - ) { - protected def composeResponseEnvelope(msg: GenericMessageEnvelope): LocalServiceResponse = { - LocalServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) - } -} + ) diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index 5bdaa5b93..ed9d3a094 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -2,7 +2,9 @@ package net.psforever.services.local import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, GenericMessageToSupportEnvelope, GenericMessageToSupportEnvelopeOnly, MessageEnvelope} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.EventMessage +import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.local.LocalAction.{IsADoorMessage, IsAHackMessage} import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.PlanetSideGUID @@ -16,34 +18,34 @@ object LocalServiceMessage { } final case class DoorMessage( - channel: String, + originalChannel: String, msg: IsADoorMessage, supportMessage: Any - ) extends GenericMessageToSupportEnvelope { + ) extends GenericSupportEnvelope { def filter: PlanetSideGUID = Service.defaultPlayerGUID def supportLabel: String = "doorCloser" } final case class HackEntityMessage( - channel: String, + originalChannel: String, filter: PlanetSideGUID, msg: IsAHackMessage, supportMessage: Any - ) extends GenericMessageToSupportEnvelope { + ) extends GenericSupportEnvelope { def supportLabel: String = "hackClearer" } final case class HackClearMessage(supportMessage: Any) - extends GenericMessageToSupportEnvelopeOnly { + extends GenericSupportEnvelopeOnly { def supportLabel: String = "hackClearer" } final case class CaptureMessage(supportMessage: Any) - extends GenericMessageToSupportEnvelopeOnly { + extends GenericSupportEnvelopeOnly { def supportLabel: String = "hackCapturer" } final case class FlagMessage(supportMessage: CaptureFlagManager.Command) - extends GenericMessageToSupportEnvelopeOnly { + extends GenericSupportEnvelopeOnly { def supportLabel: String = "captureFlagManager" } diff --git a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala index 7788471d2..dae9ab60b 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala @@ -1,11 +1,15 @@ // Copyright (c) 2017 PSForever package net.psforever.services.local +import net.psforever.services.base.message.EventResponse import net.psforever.types.PlanetSideGUID -import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.envelope.GenericResponseEnvelope final case class LocalServiceResponse( channel: String, filter: PlanetSideGUID, reply: EventResponse - ) extends GenericResponseEnvelope + ) extends GenericResponseEnvelope { + def stamp: EventSystemStamp = LocalStamp +} diff --git a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala index d79251944..4a3ea889b 100644 --- a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala +++ b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala @@ -15,7 +15,7 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.ServiceManager.{Lookup, LookupResult} -import net.psforever.services.base.messages.{GenericObjectAction, SendResponse} +import net.psforever.services.base.message.{GenericObjectAction, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -266,7 +266,7 @@ object CaptureFlagManager { zone.LocalEvents ! LocalServiceMessage( zone.id, PlanetSideGUID(-1), - LocalAction.ChatMessage(ChatMsg(messageType, wideContents = true, "", message, None)) + SendResponse(ChatMsg(messageType, wideContents = true, "", message, None)) ) } diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index cddd949a1..762eba15e 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -13,7 +13,7 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction import net.psforever.services.local.{FlagMessage, LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index b2b7fad37..396280233 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.HackState7 -import net.psforever.services.base.messages.GenericObjectAction +import net.psforever.services.base.message.GenericObjectAction import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID diff --git a/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala b/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala index 4f6548122..8cda11648 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala @@ -5,7 +5,7 @@ import net.psforever.objects.Player import net.psforever.objects.avatar.Certification import net.psforever.objects.zones.Zone import net.psforever.packet.game.{WaypointEventAction, WaypointInfo, SquadAction => PacketSquadAction} -import net.psforever.services.base.{EventMessage, EventResponse} +import net.psforever.services.base.message.{EventMessage, EventResponse} import net.psforever.types.{PlanetSideGUID, SquadRequestType, SquadWaypoint, Vector3} final case class SquadServiceMessage(tplayer: Player, zone: Zone, actionMessage: Any) diff --git a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala index af6b2f622..2482ffddd 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala @@ -6,12 +6,18 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.teamwork.Squad import net.psforever.packet.game.{SquadDetail, SquadInfo, WaypointEventAction, WaypointInfo} import net.psforever.services.Service +import net.psforever.services.base.message.EventResponse import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadResponseType, SquadWaypoint} -import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.envelope.GenericResponseEnvelope + +case object SquadStamp extends EventSystemStamp final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], reply: SquadResponse.Response) extends EventResponse with GenericResponseEnvelope { - override def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Service.defaultPlayerGUID + + def stamp: EventSystemStamp = SquadStamp } object SquadServiceResponse { diff --git a/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala b/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala index e1aca37d9..fe0537992 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadSubscriptionEntity.scala @@ -28,7 +28,7 @@ class SquadSubscriptionEntity { * @see `Service.Join` * @see `Service.Leave` */ - val SquadEvents = new GenericEventBus[SquadServiceResponse] + val SquadEvents = new GenericEventBus /** * This collection contains the message-sending contact reference for individuals. diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala index bd15519f0..6364e2cf5 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala @@ -8,14 +8,12 @@ import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.zones.Zone import net.psforever.packet.game.ObjectCreateMessage import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent} -import net.psforever.services.base.{EventMessage, EventResponse, SelfRespondingEvent} +import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent} import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3} object VehicleAction { final case class ChildObjectState(object_guid: PlanetSideGUID, pitch: Float, yaw: Float) extends SelfRespondingEvent - final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent - final case class DeployRequest( object_guid: PlanetSideGUID, state: DriveState.Value, @@ -82,8 +80,6 @@ object VehicleAction { final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends SelfRespondingEvent - final case class RevealPlayer(player_guid: PlanetSideGUID) extends EventResponse - final case class SeatPermissions(vehicle_guid: PlanetSideGUID, seat_group: Int, permission: Long) extends SelfRespondingEvent final case class StowCreatedEquipment( diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 213c7ac55..55bd0c25a 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -1,9 +1,8 @@ -// Copyright (c) 2017 PSForever +// Copyright (c) 2017-2026 PSForever package net.psforever.services.vehicle import akka.actor.{ActorContext, ActorRef, Props} -import net.psforever.objects.zones.Zone -import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericMessageEnvelope} +import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericEventServiceWithCacheAndSupport} import net.psforever.services.vehicle.support.TurretUpgrader case object TurretUpgradeSupport @@ -14,12 +13,10 @@ case object TurretUpgradeSupport } } -class VehicleService(zone: Zone) - extends GenericEventServiceWithCacheAndSupport[VehicleServiceResponse]( - busName = "Vehicle", +case object VehicleStamp extends EventSystemStamp + +class VehicleService + extends GenericEventServiceWithCacheAndSupport( + stamp = VehicleStamp, eventSupportServices = List(TurretUpgradeSupport) - ) { - protected def composeResponseEnvelope(msg: GenericMessageEnvelope): VehicleServiceResponse = { - VehicleServiceResponse(formatChannelOnBusName(msg.channel), msg.filter, msg.msg.response()) - } -} + ) diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala index af13af6cd..212e44638 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala @@ -2,7 +2,9 @@ package net.psforever.services.vehicle import net.psforever.services.Service -import net.psforever.services.base.{EventMessage, GenericMessageToSupportEnvelopeOnly, MessageEnvelope} +import net.psforever.services.base.message.EventMessage +import net.psforever.services.base.GenericSupportEnvelopeOnly +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.PlanetSideGUID object VehicleServiceMessage { @@ -14,6 +16,6 @@ object VehicleServiceMessage { } final case class TurretMessage(supportMessage: Any) - extends GenericMessageToSupportEnvelopeOnly { + extends GenericSupportEnvelopeOnly { def supportLabel: String = "turretUpgrader" } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala index f28b5652e..1b6652e2d 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala @@ -1,11 +1,15 @@ // Copyright (c) 2017 PSForever package net.psforever.services.vehicle +import net.psforever.services.base.message.EventResponse import net.psforever.types.PlanetSideGUID -import net.psforever.services.base.{EventResponse, GenericResponseEnvelope} +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.envelope.GenericResponseEnvelope final case class VehicleServiceResponse( channel: String, filter: PlanetSideGUID, reply: EventResponse - ) extends GenericResponseEnvelope + ) extends GenericResponseEnvelope { + def stamp: EventSystemStamp = VehicleStamp +} diff --git a/src/test/scala/objects/DamageableTest.scala b/src/test/scala/objects/DamageableTest.scala index 3d3538116..fbf3b9f3a 100644 --- a/src/test/scala/objects/DamageableTest.scala +++ b/src/test/scala/objects/DamageableTest.scala @@ -36,8 +36,8 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.base.DamageResolution import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.vital.resolution.ResolutionCalculations.Output -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.support.TurretUpgrader class DamageableTest extends Specification { diff --git a/src/test/scala/objects/DeployableBehaviorTest.scala b/src/test/scala/objects/DeployableBehaviorTest.scala index 8defcd389..77b74fc18 100644 --- a/src/test/scala/objects/DeployableBehaviorTest.scala +++ b/src/test/scala/objects/DeployableBehaviorTest.scala @@ -13,8 +13,8 @@ import net.psforever.objects.guid.NumberPoolHub import net.psforever.objects.guid.source.MaxNumberSource import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} import net.psforever.packet.game._ -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{ObjectDelete, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{ObjectDelete, SendResponse} import net.psforever.services.local.LocalAction import net.psforever.types._ diff --git a/src/test/scala/objects/DeployableTest.scala b/src/test/scala/objects/DeployableTest.scala index 033d1f2f5..bf97bd54e 100644 --- a/src/test/scala/objects/DeployableTest.scala +++ b/src/test/scala/objects/DeployableTest.scala @@ -12,7 +12,7 @@ import net.psforever.objects.guid.source.MaxNumberSource import net.psforever.objects.serverobject.mount.{MountInfo, Mountable, SeatDefinition} import net.psforever.objects.vital.Vitality import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} -import net.psforever.objects.{TurretDeployable, _} +import net.psforever.objects._ import net.psforever.packet.game.{DeployableIcon, DeployableInfo, DeploymentAction} import net.psforever.types._ import org.specs2.mutable.Specification @@ -25,7 +25,7 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.projectile.ProjectileReason import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} -import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.envelope.MessageEnvelope import scala.collection.mutable import scala.concurrent.duration._ diff --git a/src/test/scala/objects/DeploymentTest.scala b/src/test/scala/objects/DeploymentTest.scala index 62dc12583..c0d4702ec 100644 --- a/src/test/scala/objects/DeploymentTest.scala +++ b/src/test/scala/objects/DeploymentTest.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.{GlobalDefinitions, Vehicle} import net.psforever.objects.serverobject.deploy.{Deployment, DeploymentBehavior} import net.psforever.objects.zones.{Zone, ZoneMap} -import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import org.specs2.mutable.Specification import net.psforever.services.vehicle.VehicleAction diff --git a/src/test/scala/objects/FacilityTurretTest.scala b/src/test/scala/objects/FacilityTurretTest.scala index 26f12e8b9..bba0f9570 100644 --- a/src/test/scala/objects/FacilityTurretTest.scala +++ b/src/test/scala/objects/FacilityTurretTest.scala @@ -20,8 +20,8 @@ import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction import scala.collection.mutable diff --git a/src/test/scala/objects/GeneratorTest.scala b/src/test/scala/objects/GeneratorTest.scala index 9cb8ce8f4..feeea8c2e 100644 --- a/src/test/scala/objects/GeneratorTest.scala +++ b/src/test/scala/objects/GeneratorTest.scala @@ -25,8 +25,8 @@ import net.psforever.packet.game.{InventoryStateMessage, RepairMessage, TriggerE import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import scala.concurrent.duration._ diff --git a/src/test/scala/objects/PlayerControlTest.scala b/src/test/scala/objects/PlayerControlTest.scala index 50d734b75..514b35846 100644 --- a/src/test/scala/objects/PlayerControlTest.scala +++ b/src/test/scala/objects/PlayerControlTest.scala @@ -25,8 +25,8 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations.Output import net.psforever.packet.game._ import net.psforever.types._ import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{HintsAtAttacker, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{HintsAtAttacker, PlanetsideAttribute, SendResponse} import scala.concurrent.duration._ diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index 6589e7d8a..95c28f5ce 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -18,8 +18,8 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction import scala.concurrent.duration._ diff --git a/src/test/scala/objects/ResourceSiloTest.scala b/src/test/scala/objects/ResourceSiloTest.scala index 5fb433118..a652c10e8 100644 --- a/src/test/scala/objects/ResourceSiloTest.scala +++ b/src/test/scala/objects/ResourceSiloTest.scala @@ -17,8 +17,8 @@ import net.psforever.packet.game.UseItemMessage import net.psforever.types._ import org.specs2.mutable.Specification import net.psforever.objects.avatar.Avatar -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.PlanetsideAttribute +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.{InterstellarClusterService, Service, ServiceManager} import net.psforever.services.galaxy.GalaxyService diff --git a/src/test/scala/objects/TelepadRouterTest.scala b/src/test/scala/objects/TelepadRouterTest.scala index 056f4be58..a1c25b0cd 100644 --- a/src/test/scala/objects/TelepadRouterTest.scala +++ b/src/test/scala/objects/TelepadRouterTest.scala @@ -15,8 +15,8 @@ import net.psforever.objects.vehicles.{Utility, UtilityType} import net.psforever.objects.zones.{Zone, ZoneDeployableActor, ZoneMap} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game._ -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.SendResponse +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalAction import net.psforever.types.{DriveState, PlanetSideGUID, Vector3} diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index b6ced134c..14bf44040 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -25,8 +25,8 @@ import net.psforever.objects.vital.{ShieldCharge, SpawningActivity, Vitality} import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game._ import net.psforever.services.ServiceManager -import net.psforever.services.base.MessageEnvelope -import net.psforever.services.base.messages.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction import net.psforever.types._ diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index 1a5848c51..377aeb3b9 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -19,7 +19,7 @@ import net.psforever.services.local.LocalService import scala.concurrent.duration._ import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.avatar.Avatar -import net.psforever.services.base.MessageEnvelope +import net.psforever.services.base.envelope.MessageEnvelope class ProximityTest extends Specification { diff --git a/src/test/scala/service/LocalServiceTest.scala b/src/test/scala/service/LocalServiceTest.scala index 832f51a7a..8519962c1 100644 --- a/src/test/scala/service/LocalServiceTest.scala +++ b/src/test/scala/service/LocalServiceTest.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal import net.psforever.objects.vehicles.control.VehicleControl import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game._ -import net.psforever.services.base.messages.{SendResponse, SetEmpire} +import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.{Service, ServiceManager} import net.psforever.services.local._ diff --git a/src/test/scala/service/VehicleServiceTest.scala b/src/test/scala/service/VehicleServiceTest.scala index deeb05930..8bd56c628 100644 --- a/src/test/scala/service/VehicleServiceTest.scala +++ b/src/test/scala/service/VehicleServiceTest.scala @@ -15,7 +15,7 @@ class VehicleService1Test extends ActorTest { "VehicleService" should { "construct" in { - system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + system.actorOf(Props(classOf[VehicleService]), "v-service") assert(true) } } @@ -26,7 +26,7 @@ class VehicleService2Test extends ActorTest { "VehicleService" should { "subscribe" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") assert(true) } @@ -38,7 +38,7 @@ class VehicleService3Test extends ActorTest { "VehicleService" should { "subscribe to a specific channel" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! Service.Leave() assert(true) @@ -51,7 +51,7 @@ class VehicleService4Test extends ActorTest { "VehicleService" should { "subscribe" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! Service.LeaveAll() assert(true) @@ -64,7 +64,7 @@ class VehicleService5Test extends ActorTest { "VehicleService" should { "pass an unhandled message" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! "hello" expectNoMessage() @@ -77,7 +77,7 @@ class OwnershipTest extends ActorTest { "VehicleService" should { "pass Awareness" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11))) expectMsg( @@ -92,7 +92,7 @@ class ChildObjectStateTest extends ActorTest { "VehicleService" should { "pass ChildObjectState" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -115,7 +115,7 @@ class DeployRequestTest extends ActorTest { "VehicleService" should { "pass DeployRequest" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -138,7 +138,7 @@ class DismountVehicleTest extends ActorTest { "VehicleService" should { "pass DismountVehicle" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.DismountVehicle(BailType.Normal, false)) expectMsg( @@ -160,7 +160,7 @@ class InventoryStateTest extends ActorTest { "VehicleService" should { "pass InventoryState" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -186,7 +186,7 @@ class InventoryState2Test extends ActorTest { "VehicleService" should { "pass InventoryState2" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -209,7 +209,7 @@ class KickPassengerTest extends ActorTest { "VehicleService" should { "pass KickPassenger" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -235,7 +235,7 @@ class LoadVehicleTest extends ActorTest { "VehicleService" should { "pass LoadVehicle" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -258,7 +258,7 @@ class MountVehicleTest extends ActorTest { "VehicleService" should { "pass MountVehicle" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage("test", VehicleAction.MountVehicle(PlanetSideGUID(11), 0)) expectMsg( @@ -273,7 +273,7 @@ class SeatPermissionsTest extends ActorTest { "VehicleService" should { "pass SeatPermissions" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -300,7 +300,7 @@ class StowEquipmentTest extends ActorTest { "StowEquipment" should { "pass StowEquipment" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -323,7 +323,7 @@ class UnstowEquipmentTest extends ActorTest { "VehicleService" should { "pass UnstowEquipment" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11))) expectMsg( @@ -338,7 +338,7 @@ class VehicleStateTest extends ActorTest { "VehicleService" should { "pass VehicleState" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") service ! Service.Join("test") service ! VehicleServiceMessage( "test", @@ -372,7 +372,7 @@ class TransferPassengerChannelTest extends ActorTest { "VehicleService" should { "pass TransferPassengerChannel" in { - val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") + val service = system.actorOf(Props(classOf[VehicleService]), "v-service") val fury = Vehicle(GlobalDefinitions.fury) fury.Actor = system.actorOf(Props(classOf[VehicleControl], fury), "test-fury") service ! Service.Join("test") From de84e31547201a2b5bafc50fe593881eb3ed0c0b Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 1 Mar 2026 17:32:46 -0500 Subject: [PATCH 12/32] reorganized special envelopes from certain control agencies; wrote tests for primary event systems; fixed some other tests; knapsacking algorithm in grid inventory is less abusive --- .codecov.yml | 58 ++- .../actor/service/AvatarServiceTest.scala | 15 +- .../actors/session/csr/GeneralLogic.scala | 3 +- .../actors/session/csr/VehicleLogic.scala | 8 +- .../actors/session/normal/GeneralLogic.scala | 2 +- .../actors/session/normal/VehicleLogic.scala | 6 +- .../session/spectator/GeneralLogic.scala | 4 +- .../session/spectator/VehicleLogic.scala | 4 +- .../session/support/ChatOperations.scala | 5 +- .../session/support/GeneralOperations.scala | 8 +- .../support/SessionMountHandlers.scala | 4 +- .../WeaponAndProjectileOperations.scala | 4 +- .../session/support/ZoningOperations.scala | 4 +- .../zone/building/CavernFacilityLogic.scala | 5 +- .../actors/zone/building/FacilityLogic.scala | 5 +- .../zone/building/MajorFacilityLogic.scala | 8 +- .../objects/inventory/GridInventory.scala | 68 ++- .../damage/DamageableWeaponTurret.scala | 8 +- .../serverobject/doors/DoorControl.scala | 4 +- .../hackable/GenericHackables.scala | 22 +- .../objects/serverobject/locks/IFFLocks.scala | 5 +- .../shuttle/OrbitalShuttlePadControl.scala | 3 +- .../terminals/ProximityTerminalControl.scala | 7 +- .../terminals/TerminalControl.scala | 7 +- .../terminals/capture/CaptureTerminals.scala | 9 +- .../serverobject/turret/WeaponTurrets.scala | 8 +- .../net/psforever/objects/zones/Zone.scala | 11 + .../objects/zones/ZoneGroundActor.scala | 9 +- .../net/psforever/services/Service.scala | 11 +- .../avatar/AvatarServiceMessage.scala | 71 +-- .../avatar/support/CorpseRemovalActor.scala | 29 +- .../avatar/support/DroppedItemRemover.scala | 49 ++- .../services/base/GenericEventService.scala | 12 +- ...nericEventServiceWithCacheAndSupport.scala | 49 ++- .../base/GenericEventServiceWithSupport.scala | 2 +- .../services/local/LocalAction.scala | 3 +- .../services/local/LocalServiceMessage.scala | 36 -- .../local/support/CaptureFlagManager.scala | 10 +- .../local/support/DoorCloseActor.scala | 12 + .../local/support/HackCaptureActor.scala | 16 +- .../local/support/HackClearActor.scala | 16 + .../services/vehicle/VehicleAction.scala | 16 +- .../vehicle/VehicleServiceMessage.scala | 6 - .../vehicle/support/TurretUpgrader.scala | 6 + src/test/scala/objects/DamageableTest.scala | 6 +- src/test/scala/objects/DeploymentTest.scala | 16 +- src/test/scala/objects/DoorTest.scala | 3 +- .../scala/objects/PlayerControlTest.scala | 2 +- src/test/scala/objects/RepairableTest.scala | 2 +- .../scala/objects/TelepadRouterTest.scala | 6 - .../scala/objects/VehicleControlTest.scala | 10 +- src/test/scala/service/LocalServiceTest.scala | 376 ---------------- .../scala/service/VehicleServiceTest.scala | 410 ------------------ .../service/avatar/AvatarActionTest.scala | 215 +++++++++ .../scala/service/base/EnvelopeTest.scala | 89 ++++ .../scala/service/base/EventMessageTest.scala | 42 ++ .../base/EventServiceCacheSupportTest.scala | 221 ++++++++++ .../base/EventServiceSupportTest.scala | 133 ++++++ .../scala/service/base/EventServiceTest.scala | 199 +++++++++ .../service/base/EventServiceTestBase.scala | 39 ++ .../scala/service/local/LocalActionTest.scala | 73 ++++ .../service/vehicle/VehicleActionTest.scala | 102 +++++ 62 files changed, 1489 insertions(+), 1103 deletions(-) delete mode 100644 src/test/scala/service/LocalServiceTest.scala delete mode 100644 src/test/scala/service/VehicleServiceTest.scala create mode 100644 src/test/scala/service/avatar/AvatarActionTest.scala create mode 100644 src/test/scala/service/base/EnvelopeTest.scala create mode 100644 src/test/scala/service/base/EventMessageTest.scala create mode 100644 src/test/scala/service/base/EventServiceCacheSupportTest.scala create mode 100644 src/test/scala/service/base/EventServiceSupportTest.scala create mode 100644 src/test/scala/service/base/EventServiceTest.scala create mode 100644 src/test/scala/service/base/EventServiceTestBase.scala create mode 100644 src/test/scala/service/local/LocalActionTest.scala create mode 100644 src/test/scala/service/vehicle/VehicleActionTest.scala diff --git a/.codecov.yml b/.codecov.yml index 06eb9388a..80ad89238 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -9,6 +9,9 @@ coverage: threshold: 0.25% ignore: + - "src/main/java" + - "src/main/resources" + - "src/main/scala/akka" - "src/main/scala/net/psforever/objects/ObjectType.scala" - "src/main/scala/net/psforever/objects/avatar/Avatars.scala" - "src/main/scala/net/psforever/objects/ballistics/DamageResolution.scala" @@ -18,7 +21,12 @@ ignore: - "src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala" - "src/main/scala/net/psforever/objects/equipment/Kits.scala" - "src/main/scala/net/psforever/objects/equipment/SItem.scala" + - "src/main/scala/net/psforever/objects/global" - "src/main/scala/net/psforever/objects/guid/AvailabilityPolicy.scala" + - "src/main/scala/net/psforever/objects/loadouts/EquipmentLoadout.scala" + - "src/main/scala/net/psforever/objects/loadouts/InfantryLoadout.scala" + - "src/main/scala/net/psforever/objects/loadouts/SquadLoadout.scala" + - "src/main/scala/net/psforever/objects/loadouts/VehicleLoadout.scala" - "src/main/scala/net/psforever/objects/serverobject/pad/AutoDriveControls.scala" - "src/main/scala/net/psforever/objects/serverobject/structures/StructureType.scala" - "src/main/scala/net/psforever/objects/serverobject/shuttle/ShuttleAmenity.scala" @@ -56,24 +64,42 @@ ignore: - "src/main/scala/net/psforever/packet/ControlPacketOpcode.scala" - "src/main/scala/net/psforever/packet/CryptoPacketOpcode.scala" - "src/main/scala/net/psforever/packet/GamePacketOpcode.scala" - - "src/main/scala/net/psforever/types/Angular.scala" - - "src/main/scala/net/psforever/types/CertificationType.scala" - - "src/main/scala/net/psforever/types/ChatMessageType.scala" - - "src/main/scala/net/psforever/types/DriveState.scala" - - "src/main/scala/net/psforever/types/EmoteType.scala" - - "src/main/scala/net/psforever/types/ExoSuitType.scala" - - "src/main/scala/net/psforever/types/GrenadeState.scala" - - "src/main/scala/net/psforever/types/ImplantType.scala" - - "src/main/scala/net/psforever/types/MeritCommendation.scala" - - "src/main/scala/net/psforever/types/PlanetSideEmpire.scala" - - "src/main/scala/net/psforever/types/TransactionType.scala" + - "src/main/scala/net/psforever/packet/ResetSequenceOpcode.scala" + - "src/main/scala/net/psforever/persistence" + - "src/main/scala/net/psforever/services/account/IPAddress.scala" + - "src/main/scala/net/psforever/services/account/ReceiveAccountData.scala" + - "src/main/scala/net/psforever/services/account/ReceiveIPAddress.scala" + - "src/main/scala/net/psforever/services/account/RetrieveAccountData.scala" + - "src/main/scala/net/psforever/services/account/RetrieveIPAddress.scala" + - "src/main/scala/net/psforever/services/account/StoreAccountData.scala" + - "src/main/scala/net/psforever/services/account/StoreIPAddress.scala" - "src/main/scala/net/psforever/services/avatar/AvatarAction.scala" - - "src/main/scala/net/psforever/services/galaxy/AvatarServiceMessage.scala" - - "src/main/scala/net/psforever/services/galaxy/AvatarServiceResponse.scala" - - "src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala" + - "src/main/scala/net/psforever/services/avatar/AvatarService.scala" + - "src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala" + - "src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala" + - "src/main/scala/net/psforever/services/base/bus" + - "src/main/scala/net/psforever/services/base/envelope" + - "src/main/scala/net/psforever/services/chat/ChatChannel.scala" + - "src/main/scala/net/psforever/services/galaxy/GalaxyAction" + - "src/main/scala/net/psforever/services/galaxy/GalaxyService" - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala" - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala" - "src/main/scala/net/psforever/services/hart/HartEvent.scala" - "src/main/scala/net/psforever/services/hart/HartTimerActions.scala" - - "src/main/scala/net/psforever/services/local/LocalAction.scala" - - "src/main/scala/net/psforever/services/vehicle/VehicleAction.scala" + - "src/main/scala/net/psforever/services/local/LocalAction" + - "src/main/scala/net/psforever/services/local/LocalService" + - "src/main/scala/net/psforever/services/local/LocalServiceMessage.scala" + - "src/main/scala/net/psforever/services/local/LocalServiceResponse.scala" + - "src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala" + - "src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala" + - "src/main/scala/net/psforever/services/vehicle/VehicleAction" + - "src/main/scala/net/psforever/services/vehicle/VehicleService" + - "src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala" + - "src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala" + - "src/main/scala/net/psforever/services/Service.scala" + - "src/main/scala/net/psforever/types" + - "src/main/scala/net/psforever/util" + - "src/main/scala/net/psforever/zones" + - "src/main/scala/net/psforever/IFinalizable.scala" + - "src/main/scala/scodec" + - "src/test" diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala index eb33c2ab7..520398554 100644 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ b/server/src/test/scala/actor/service/AvatarServiceTest.scala @@ -16,6 +16,7 @@ import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstrea import net.psforever.types._ import net.psforever.services.{RemoverActor, Service, ServiceManager} import net.psforever.services.avatar._ +import net.psforever.services.avatar.support.{CorpseEnvelope, DropItemEnvelope, PickupItemEnvelope, ReleaseEnvelope} import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire} class AvatarService1Test extends ActorTest { @@ -153,7 +154,7 @@ class DroptItemTest extends ActorTest { "AvatarService" should { "pass DropItem" in { service ! Service.Join("test") - service ! DropItemMessage("test", PlanetSideGUID(10), AvatarAction.DropItem(tool), Zone.Nowhere) + service ! DropItemEnvelope("test", PlanetSideGUID(10), AvatarAction.DropItem(tool), Zone.Nowhere) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.DropCreatedItem(pkt))) } } @@ -324,7 +325,7 @@ class PickupItemTest extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! PickupItemMessage("test", AvatarAction.PickupItem(tool), Zone.Nowhere) + service ! PickupItemEnvelope("test", AvatarAction.PickupItem(tool), Zone.Nowhere) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0))) } } @@ -509,7 +510,7 @@ class AvatarReleaseTest extends FreedContextActorTest { assert(zone.Corpses.size == 1) assert(obj.HasGUID) val guid = obj.GUID - zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second + zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second val reply1 = subscriber.receiveOne(200 milliseconds) assert(reply1.isInstanceOf[AvatarServiceResponse]) @@ -560,7 +561,7 @@ class AvatarReleaseEarly1Test extends FreedContextActorTest { assert(zone.Corpses.size == 1) assert(obj.HasGUID) val guid = obj.GUID - zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes! + zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone)) //3+ minutes! val reply1 = subscriber.receiveOne(200 milliseconds) assert(reply1.isInstanceOf[AvatarServiceResponse]) @@ -576,8 +577,8 @@ class AvatarReleaseEarly1Test extends FreedContextActorTest { val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] assert(reply2msg.channel.equals("/test/Avatar")) assert(reply2msg.filter == Service.defaultPlayerGUID) - assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete]) - assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid) + assert(reply2msg.reply.isInstanceOf[ObjectDelete]) + assert(reply2msg.reply.asInstanceOf[ObjectDelete].obj_guid == guid) subscriber.expectNoMessage(1 seconds) assert(zone.Corpses.isEmpty) @@ -618,7 +619,7 @@ class AvatarReleaseEarly2Test extends FreedContextActorTest { assert(zone.Corpses.size == 1) assert(obj.HasGUID) val guid = obj.GUID - zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes! + zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone)) //3+ minutes! val reply1 = subscriber.receiveOne(200 milliseconds) assert(reply1.isInstanceOf[AvatarServiceResponse]) diff --git a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala index 5aa14d2f6..8d19e2ee2 100644 --- a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala @@ -34,7 +34,8 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1} import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.RemoverActor -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, CorpseEnvelope} +import net.psforever.services.avatar.support.CorpseEnvelope +import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3} diff --git a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala index 78ba0e05f..e345d40d6 100644 --- a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala @@ -11,10 +11,8 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vehicles.control.BfrFlight import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone -import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage} -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.CachedMessage -import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} +import net.psforever.services.base.CachedEnvelope import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{DriveState, Vector3} @@ -245,7 +243,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Velocity = vel sessionLogic.updateBlockMap(obj, pos) obj.zoneInteractions() - continent.VehicleEvents ! CachedMessage( + continent.VehicleEvents ! CachedEnvelope( continent.id, player.GUID, VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index ee784c3c6..e0495c652 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -43,7 +43,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.CachedMessage +import net.psforever.services.base.CachedEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3} diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala index 59fd325c9..21827dfbb 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala @@ -12,7 +12,7 @@ import net.psforever.objects.vehicles.control.BfrFlight import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} -import net.psforever.services.base.CachedMessage +import net.psforever.services.base.CachedEnvelope import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{ChatMessageType, DriveState, Vector3} @@ -76,7 +76,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Position = position obj.Orientation = angle // - continent.VehicleEvents ! CachedMessage( + continent.VehicleEvents ! CachedEnvelope( continent.id, player.GUID, VehicleAction.VehicleState( @@ -239,7 +239,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Velocity = vel sessionLogic.updateBlockMap(obj, pos) obj.zoneInteractions() - continent.VehicleEvents ! CachedMessage( + continent.VehicleEvents ! CachedEnvelope( continent.id, player.GUID, VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala index 0a89abf82..46c737541 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala @@ -17,7 +17,7 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.AccountPersistenceService import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.base.CachedMessage +import net.psforever.services.base.CachedEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.{ExoSuitType, Vector3} @@ -76,7 +76,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex player.Crouching = isCrouching player.Jumping = isJumping player.Cloaked = player.ExoSuit == ExoSuitType.Infiltration && isCloaking - continent.AvatarEvents ! CachedMessage( + continent.AvatarEvents ! CachedEnvelope( "spectator", avatarGuid, AvatarAction.PlayerState( diff --git a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala index af51a9628..d56536feb 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala @@ -7,7 +7,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.Vehicle import net.psforever.objects.serverobject.deploy.Deployment import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} -import net.psforever.services.base.CachedMessage +import net.psforever.services.base.CachedEnvelope import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{DriveState, Vector3} @@ -40,7 +40,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Velocity = vel sessionLogic.updateBlockMap(obj, pos) obj.zoneInteractions() - continent.VehicleEvents ! CachedMessage( + continent.VehicleEvents ! CachedEnvelope( continent.id, player.GUID, VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala index d53a0685f..10320bf40 100644 --- a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala @@ -20,8 +20,7 @@ import net.psforever.packet.game.{SetChatFilterMessage, TimeOfDayMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel} -import net.psforever.services.local.support.HackCaptureActor -import net.psforever.services.local.CaptureMessage +import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor} import net.psforever.services.teamwork.{SquadResponse, SquadService, SquadServiceResponse} import net.psforever.types.ChatMessageType.CMT_QUIT import org.log4s.Logger @@ -406,7 +405,7 @@ class ChatOperations( } else { if (building.CaptureTerminalIsHacked) { - zone.LocalEvents ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(terminal, zone, PlayerSource.Nobody)) + zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(terminal, zone, PlayerSource.Nobody)) } building.Actor ! BuildingActor.SetFaction(faction) building.Actor ! BuildingActor.AmenityStateChange(terminal, Some(false)) diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 483b03306..2b19df496 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -18,10 +18,10 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.RemoverActor -import net.psforever.services.avatar.GroundEnvelope +import net.psforever.services.avatar.support.GroundEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.local.support.HackCaptureActor -import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor} +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global @@ -1292,7 +1292,7 @@ class GeneralOperations( continent.GUID(specialItemSlotGuid) match { case Some(llu: CaptureFlag) => if (llu.Target.GUID == captureTerminal.Owner.GUID) { - continent.LocalEvents ! CaptureMessage(HackCaptureActor.FlagCaptured(llu)) + continent.LocalEvents ! CaptureEnvelope(HackCaptureActor.FlagCaptured(llu)) } else { log.info( s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}" diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index c7adf3df8..346a7f6bf 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -8,7 +8,7 @@ import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle} import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} -import net.psforever.services.base.CachedMessage +import net.psforever.services.base.CachedEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} @@ -225,7 +225,7 @@ class SessionMountHandlers( sessionLogic.vehicles.ServerVehicleOverrideStop(v) }*/ v.Velocity = Vector3.Zero - continent.VehicleEvents ! CachedMessage( + continent.VehicleEvents ! CachedEnvelope( continent.id, tplayer.GUID, VehicleAction.VehicleState(v.GUID, unk1 = 0, tplayer.Position, v.Orientation, v.Velocity, v.Flying, unk3 = 0, unk4 = 0, wheel_direction = 15, unk5 = false, unk6 = v.Cloaked) diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index a895ab087..15197b0f0 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -28,7 +28,7 @@ import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest import net.psforever.services.Service -import net.psforever.services.base.CachedMessage +import net.psforever.services.base.CachedEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3} @@ -494,7 +494,7 @@ class WeaponAndProjectileOperations( projectile.Position = shot_pos projectile.Orientation = shot_orient projectile.Velocity = shot_vel - continent.AvatarEvents ! CachedMessage( + continent.AvatarEvents ! CachedEnvelope( continent.id, player.GUID, AvatarAction.ProjectileState( diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 68d3f3a58..478704782 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -22,7 +22,7 @@ import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, Reconstr import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage} -import net.psforever.services.avatar.{CorpseEnvelope, ReleaseMessage} +import net.psforever.services.avatar.support.{CorpseEnvelope, ReleaseEnvelope} import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.chat.DefaultChannel @@ -2946,7 +2946,7 @@ class ZoningOperations( tplayer.Release DepictPlayerAsCorpse(tplayer) zone.Population ! Zone.Corpse.Add(tplayer) - zone.AvatarEvents ! ReleaseMessage(zone.id, AvatarAction.Release(tplayer, zone)) + zone.AvatarEvents ! ReleaseEnvelope(zone.id, AvatarAction.Release(tplayer, zone)) } /** diff --git a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala index 55ef7efd4..c6a0d0e1e 100644 --- a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala @@ -8,8 +8,7 @@ import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails, ZoneAct import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.HackClearMessage +import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import net.psforever.types.PlanetSideEmpire /** @@ -53,7 +52,7 @@ case object CavernFacilityLogic // When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state building.HackableAmenities.foreach(amenity => { if (amenity.HackedBy.isDefined) { - building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity)) + building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity)) } }) // No map update needed - will be sent by `HackCaptureActor` when required diff --git a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala index de48e4bc7..2998750a9 100644 --- a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala @@ -8,8 +8,7 @@ import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails} import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.HackClearMessage +import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import net.psforever.types.PlanetSideEmpire /** @@ -53,7 +52,7 @@ case object FacilityLogic // When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state building.HackableAmenities.foreach(amenity => { if (amenity.HackedBy.isDefined) { - building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity)) + building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity)) } }) // No map update needed - will be sent by `HackCaptureActor` when required diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index dbef18ddc..b12bf2ab9 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -18,8 +18,8 @@ import net.psforever.services.InterstellarClusterService import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{CaptureMessage, HackClearMessage, LocalServiceMessage} -import net.psforever.services.local.support.{HackCaptureActor, HackClearActor} +import net.psforever.services.local.LocalServiceMessage +import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor, HackClearActor, HackClearEnvelope} import net.psforever.types.PlanetSideEmpire /** @@ -103,7 +103,7 @@ case object MajorFacilityLogic hackedAmenities } amenitiesToClear.foreach { amenity => - building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity)) + building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity)) } // No map update needed - will be sent by `HackCaptureActor` when required case dome: ForceDomePhysics => @@ -282,7 +282,7 @@ case object MajorFacilityLogic (bldg.GetFlag, bldg.CaptureTerminal) match { case (Some(flag), Some(terminal)) if (flag.Target eq building) && flag.Faction != building.Faction => //our hack destination may have been compromised and the hack needs to be cancelled - bldg.Zone.LocalEvents ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(terminal, terminal.Zone, PlayerSource.Nobody)) + bldg.Zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(terminal, terminal.Zone, PlayerSource.Nobody)) case _ => () } Behaviors.same diff --git a/src/main/scala/net/psforever/objects/inventory/GridInventory.scala b/src/main/scala/net/psforever/objects/inventory/GridInventory.scala index eafc880bb..d77f30dd1 100644 --- a/src/main/scala/net/psforever/objects/inventory/GridInventory.scala +++ b/src/main/scala/net/psforever/objects/inventory/GridInventory.scala @@ -702,15 +702,18 @@ object GridInventory { */ private def sortKnapsack(list: List[InventoryItem], width: Int, height: Int): Unit = { val root = new KnapsackNode(0, 0, width, height) - list.foreach(item => { - findKnapsackSpace(root, item.obj.Tile.Width, item.obj.Tile.Height) match { + list.foreach { item => + val tile = item.obj.Tile + val twidth = tile.Width + val theight = tile.Height + findKnapsackSpace(root, twidth, theight) match { case Some(node) => - splitKnapsackSpace(node, item.obj.Tile.Width, item.obj.Tile.Height) + splitKnapsackSpace(node, twidth, theight) item.start = node.y * width + node.x - case _ => ; + case _ => item.start = -1 } - }) + } } /** @@ -720,42 +723,32 @@ object GridInventory { * Horizontal space for the `down` child is emphasized over vertical space for the `right` child. * By dividing and reducing a defined space like this, it can be tightly packed with a given number of elements.
*
- * Due to the nature of the knapsack problem and the naivette of the algorithm, small holes in the solution are bound to crop-up. + * Due to the nature of the knapsack problem and the naivete of the algorithm, small holes in the solution are bound to crop-up. * @param x the x-coordinate, upper left corner * @param y the y-coordinate, upper left corner * @param width the width * @param height the height */ - private class KnapsackNode(var x: Int, var y: Int, var width: Int, var height: Int) { - private var used: Boolean = false - var down: Option[KnapsackNode] = None - var right: Option[KnapsackNode] = None + private class KnapsackNode(val x: Int, val y: Int, val width: Int, val height: Int) { + private var used: Boolean = false + private var down: Option[KnapsackNode] = None + private var right: Option[KnapsackNode] = None def Used: Boolean = used - /** - * Initialize the `down` and `right` children of this node. - */ - def Split(): Unit = { - used = true - down = Some(new KnapsackNode(0, 0, 0, 0)) - right = Some(new KnapsackNode(0, 0, 0, 0)) - } + def Down: Option[KnapsackNode] = down + + def Right: Option[KnapsackNode] = right /** - * Change the dimensions of the node.
- *
- * Use: `{node}(nx, ny, nw, nh)` - * @param nx the new x-coordinate, upper left corner - * @param ny the new y-coordinate, upper left corner - * @param nw the new width - * @param nh the new height - */ - def apply(nx: Int, ny: Int, nw: Int, nh: Int): Unit = { - x = nx - y = ny - width = nw - height = nh + * Initialize the `down` and `right` children of this node. + * @param insertDown new "down" knapsack division + * @param insertRight new "right" knapsack division + */ + def Split(insertDown: KnapsackNode, insertRight: KnapsackNode): Unit = { + used = true + down = Some(insertDown) + right = Some(insertRight) } } @@ -768,7 +761,7 @@ object GridInventory { */ private def findKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Option[KnapsackNode] = { if (node.Used) { - findKnapsackSpace(node.right.get, width, height).orElse(findKnapsackSpace(node.down.get, width, height)) + findKnapsackSpace(node.Right.get, width, height).orElse(findKnapsackSpace(node.Down.get, width, height)) } else if (width <= node.width && height <= node.height) { Some(node) } else { @@ -787,13 +780,14 @@ object GridInventory { * @param height height of the element */ private def splitKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Unit = { - node.Split() - node.down.get(node.x, node.y + height, node.width, node.height - height) - node.right.get(node.x + width, node.y, node.width - width, height) + node.Split( + new KnapsackNode(node.x, node.y + height, node.width, node.height - height), + new KnapsackNode(node.x + width, node.y, node.width - width, height) + ) } def toPrintedList(inv: GridInventory): String = { - val list = new StringBuilder + val list = new mutable.StringBuilder list.append("\n") inv.Items.zipWithIndex.foreach { case (InventoryItem(obj, start), index) => @@ -803,6 +797,6 @@ object GridInventory { } def toPrintedGrid(inv: GridInventory): String = { - new StringBuilder().append("\n").append(inv.grid.toSeq.grouped(inv.width).mkString("\n")).toString + new mutable.StringBuilder().append("\n").append(inv.grid.toSeq.grouped(inv.width).mkString("\n")).toString } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index 2b10df5ac..1e172174f 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -12,8 +12,8 @@ import net.psforever.types.Vector3 import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.base.support.SupportActor -import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.services.vehicle.{TurretMessage, VehicleServiceMessage} +import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader} +import net.psforever.services.vehicle.VehicleServiceMessage /** * The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects. @@ -138,8 +138,8 @@ object DamageableWeaponTurret { case turret: WeaponTurret => if (turret.Upgrade != TurretUpgrade.None) { val vehicleEvents = zone.VehicleEvents - vehicleEvents ! TurretMessage(SupportActor.ClearSpecific(List(turret), zone)) - vehicleEvents ! TurretMessage(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None)) + vehicleEvents ! TurretEnvelope(SupportActor.ClearSpecific(List(turret), zone)) + vehicleEvents ! TurretEnvelope(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None)) } case _ => } diff --git a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala index e9997872e..cd8b6a599 100644 --- a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala @@ -9,8 +9,8 @@ import net.psforever.objects.serverobject.locks.IFFLock import net.psforever.objects.serverobject.structures.PoweredAmenityControl import net.psforever.services.Service import net.psforever.services.base.support.SupportActor -import net.psforever.services.local.support.DoorCloseActor -import net.psforever.services.local.{DoorMessage, LocalAction, LocalServiceResponse} +import net.psforever.services.local.support.{DoorCloseActor, DoorMessage} +import net.psforever.services.local.{LocalAction, LocalServiceResponse} /** * An `Actor` that handles messages being dispatched to a specific `Door`. diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index 86c8f6774..50ac0796a 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -13,8 +13,8 @@ import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackS import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.{HackClearMessage, HackEntityMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope, HackEntityEnvelope} +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import scala.annotation.unused import scala.util.{Failure, Success} @@ -177,7 +177,7 @@ object GenericHackables { LocalAction.TriggerSound(target.HackSound, tplayer.Position, 30, 0.49803925f) ) val duration = target.HackEffectDuration(user.avatar.hackingSkillLevel()) - zone.LocalEvents ! HackEntityMessage( + zone.LocalEvents ! HackEntityEnvelope( zoneId, pguid, LocalAction.HackObject(target.GUID, hackValue, HackState7.Unk8), @@ -206,7 +206,7 @@ object GenericHackables { val currVirus = building.virusId building.virusId = 8 building.virusInstalledBy = None - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(target)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(target)) zone.LocalEvents ! LocalServiceMessage( zone.id, SendResponse(GenericObjectActionMessage(target.GUID, 60)) @@ -214,11 +214,11 @@ object GenericHackables { currVirus match { case 0L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff => - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(iff)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(iff)) } case 4L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term => - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term)) } case _ => () } @@ -232,13 +232,13 @@ object GenericHackables { case 0L => if (virus != 0) { building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff => - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(iff)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(iff)) } } case 4L => if (virus != 4) { building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term => - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term)) } } case _ => () @@ -266,7 +266,7 @@ object GenericHackables { pguid, LocalAction.TriggerSound(TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f) ) - zone.LocalEvents ! HackEntityMessage( + zone.LocalEvents ! HackEntityEnvelope( zoneId, pguid, LocalAction.HackObject(target.GUID, installedVirusDuration.toLong, hackState), @@ -285,7 +285,7 @@ object GenericHackables { case 0L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach{ iff => iff.HackedBy = tplayer - zone.LocalEvents ! HackEntityMessage( + zone.LocalEvents ! HackEntityEnvelope( zoneId, pguid, LocalAction.HackObject(target.GUID, hackValue.toLong, HackState7.Unk8), @@ -295,7 +295,7 @@ object GenericHackables { case 4L => building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach{ term => term.HackedBy = tplayer - zone.LocalEvents ! HackEntityMessage( + zone.LocalEvents ! HackEntityEnvelope( zoneId, pguid, LocalAction.HackObject(term.GUID, hackValue.toLong, HackState7.Unk8), diff --git a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala index 6404445f4..da3516190 100644 --- a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala +++ b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLocks.scala @@ -1,8 +1,7 @@ // Copyright (c) 2020 PSForever package net.psforever.objects.serverobject.locks -import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.HackClearMessage +import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} object IFFLocks { @@ -14,6 +13,6 @@ object IFFLocks { */ def FinishResecuringIFFLock(lock: IFFLock)(): Unit = { val zone = lock.Zone - lock.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(lock)) + lock.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(lock)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala index 1814f3ec4..9f2002da2 100644 --- a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala @@ -11,8 +11,9 @@ import net.psforever.packet.game.ChatMsg import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.message.SendResponse import net.psforever.services.base.support.SupportActor -import net.psforever.services.local.{DoorMessage, LocalAction} +import net.psforever.services.local.LocalAction import net.psforever.services.hart.{HartTimer, HartTimerActions} +import net.psforever.services.local.support.DoorMessage import net.psforever.services.{Service, ServiceManager} import net.psforever.types.ChatMessageType diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index 2628d5d2f..f1b95da07 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -7,8 +7,7 @@ import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.local.HackClearMessage -import net.psforever.services.local.support.HackClearActor +import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import org.log4s.Logger import scala.annotation.unused @@ -149,7 +148,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) tryAutoRepair() if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term)) } super.DestructionAwareness(target, cause) } @@ -226,7 +225,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) //clear hack state if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala index 46d124b81..9b289caad 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala @@ -12,8 +12,7 @@ import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableA import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 -import net.psforever.services.local.support.HackClearActor -import net.psforever.services.local.HackClearMessage +import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} /** * An `Actor` that handles messages being dispatched to a specific `Terminal`. @@ -100,7 +99,7 @@ class TerminalControl(term: Terminal) tryAutoRepair() if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term)) } super.DestructionAwareness(target, cause) } @@ -122,7 +121,7 @@ class TerminalControl(term: Terminal) //clear hack state if (term.HackedBy.nonEmpty) { val zone = term.Zone - zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term)) + zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala index b1a233b72..2fcb492d5 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala @@ -6,9 +6,10 @@ import net.psforever.objects.serverobject.hackable.GenericHackables import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} -import net.psforever.types.PlanetSideEmpire +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.local.support.HackCaptureActor +import net.psforever.services.local.support.CaptureEnvelope +import net.psforever.types.PlanetSideEmpire import scala.concurrent.duration._ import scala.util.{Failure, Success} @@ -47,10 +48,10 @@ object CaptureTerminals { ) if (isResecured) { // Resecure the CC - events ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(target, zone, PlayerSource(hackingPlayer))) + events ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(target, zone, PlayerSource(hackingPlayer))) } else { // Start the CC hack timer - events ! CaptureMessage(HackCaptureActor.StartCaptureTerminalHack(target, zone, 0, 8L)) + events ! CaptureEnvelope(HackCaptureActor.StartCaptureTerminalHack(target, zone, 0, 8L)) } case Failure(_) => log.warn(s"Hack message failed on target guid: ${target.GUID}") diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index 75c13a4d2..c0aedc2e1 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -8,8 +8,8 @@ import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7 import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader} +import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.PlanetSideGUID object WeaponTurrets { @@ -53,8 +53,8 @@ object WeaponTurrets { log.info(s"Manned wall turret weapon being converted to $upgrade") val zone = target.Zone val events = zone.VehicleEvents - events ! TurretMessage(TurretUpgrader.ClearSpecific(List(target), zone)) - events ! TurretMessage(TurretUpgrader.AddTask(target, zone, upgrade)) + events ! TurretEnvelope(TurretUpgrader.ClearSpecific(List(target), zone)) + events ! TurretEnvelope(TurretUpgrader.AddTask(target, zone, upgrade)) } /** diff --git a/src/main/scala/net/psforever/objects/zones/Zone.scala b/src/main/scala/net/psforever/objects/zones/Zone.scala index 06a03638d..1c1336090 100644 --- a/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -1571,6 +1571,17 @@ object Zone { } } + def AmsSpawnPoints(zone: Zone): List[SpawnTube] = { + import net.psforever.objects.vehicles.UtilityType + import net.psforever.objects.GlobalDefinitions + zone.Vehicles + .filter(veh => + veh.Health > 0 && veh.Definition == GlobalDefinitions.ams && veh.DeploymentState == DriveState.Deployed + ) + .flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube)) + .map(util => util().asInstanceOf[SpawnTube]) + } + object Setup { /* zone setup code */ diff --git a/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala index 0d362a661..84f44a3d0 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala @@ -4,8 +4,9 @@ package net.psforever.objects.zones import akka.actor.Actor import net.psforever.actors.zone.ZoneActor import net.psforever.objects.equipment.Equipment +import net.psforever.services.avatar.support.{DropItemEnvelope, PickupItemEnvelope} import net.psforever.types.PlanetSideGUID -import net.psforever.services.avatar.{AvatarAction, DropItemMessage, PickupItemMessage} +import net.psforever.services.avatar.AvatarAction import scala.annotation.tailrec import scala.collection.mutable.ListBuffer @@ -30,7 +31,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte equipmentOnGround += item item.Position = pos item.Orientation = orient - zone.AvatarEvents ! DropItemMessage(zone.id, AvatarAction.DropItem(item), zone) + zone.AvatarEvents ! DropItemEnvelope(zone.id, AvatarAction.DropItem(item), zone) zone.actor ! ZoneActor.AddToBlockMap(item, pos) Zone.Ground.ItemOnGround(item, pos, orient) }) @@ -38,7 +39,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte case Zone.Ground.PickupItem(item_guid) => sender() ! (FindItemOnGround(item_guid) match { case Some(item) => - zone.AvatarEvents ! PickupItemMessage(zone.id, AvatarAction.PickupItem(item, 0), zone) + zone.AvatarEvents ! PickupItemEnvelope(zone.id, AvatarAction.PickupItem(item, 0), zone) zone.actor ! ZoneActor.RemoveFromBlockMap(item) Zone.Ground.ItemInHand(item) case None => @@ -50,7 +51,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte FindItemOnGround(item_guid) match { case Some(item) => zone.actor ! ZoneActor.RemoveFromBlockMap(item) - zone.AvatarEvents ! PickupItemMessage(zone.id, AvatarAction.PickupItem(item, 0), zone) + zone.AvatarEvents ! PickupItemEnvelope(zone.id, AvatarAction.PickupItem(item, 0), zone) case None => ; } diff --git a/src/main/scala/net/psforever/services/Service.scala b/src/main/scala/net/psforever/services/Service.scala index 19ae064aa..a8b9c9bbe 100644 --- a/src/main/scala/net/psforever/services/Service.scala +++ b/src/main/scala/net/psforever/services/Service.scala @@ -1,6 +1,7 @@ // Copyright (c) 2017 PSForever package net.psforever.services +import akka.actor.ActorRef import net.psforever.types.PlanetSideGUID object Service { @@ -8,7 +9,15 @@ object Service { final case class Startup() - final case class Join(channel: String) + final case class Join(channel: String, sendJoinConfirmation: Boolean) + + object Join { + def apply(channel: String): Join = Join(channel, sendJoinConfirmation = false) + } + + final case class JoinConfirmation(eventSystem: ActorRef, channel: String) + final case class Leave(channel: Option[String] = None) + final case class LeaveAll() } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala index a8e7d530c..d7415c59a 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala @@ -1,12 +1,9 @@ // Copyright (c) 2017-2026 PSForever package net.psforever.services.avatar -import net.psforever.objects.zones.Zone -import net.psforever.services.{RemoverActor, Service} -import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem, Release} +import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.EventMessage -import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.types.PlanetSideGUID object AvatarServiceMessage { @@ -16,69 +13,3 @@ object AvatarServiceMessage { def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = MessageEnvelope(channel, filter, msg) } - -final case class ReleaseMessage( - originalChannel: String, - filter: PlanetSideGUID, - msg: Release - ) - extends GenericSupportEnvelope { - def supportLabel: String = "undertaker" - def supportMessage: Any = { - val Release(player, zone, time) = msg - RemoverActor.AddTask(player, zone, time) - } -} - -object ReleaseMessage { - def apply(channel: String, actionMessage: Release): ReleaseMessage = - ReleaseMessage(channel, Service.defaultPlayerGUID, actionMessage) -} - -final case class PickupItemMessage( - originalChannel: String, - filter: PlanetSideGUID, - msg: PickupItem, - zone: Zone - ) - extends GenericSupportEnvelope { - def supportLabel: String = "janitor" - def supportMessage: Any = { - val PickupItem(item, _) = msg - RemoverActor.ClearSpecific(List(item), zone) - } -} - -object PickupItemMessage { - def apply(channel: String, actionMessage: PickupItem, zone: Zone): PickupItemMessage = - PickupItemMessage(channel, Service.defaultPlayerGUID, actionMessage, zone) -} - -final case class DropItemMessage( - originalChannel: String, - filter: PlanetSideGUID, - msg: DropItem, - zone: Zone - ) - extends GenericSupportEnvelope { - def supportLabel: String = "janitor" - def supportMessage: Any = { - val DropItem(item) = msg - RemoverActor.AddTask(item, zone) - } -} - -object DropItemMessage { - def apply(channel: String, actionMessage: DropItem, zone: Zone): DropItemMessage = - DropItemMessage(channel, Service.defaultPlayerGUID, actionMessage, zone) -} - -final case class CorpseEnvelope(supportMessage: Any) - extends GenericSupportEnvelopeOnly { - def supportLabel: String = "undertaker" -} - -final case class GroundEnvelope(supportMessage: Any) - extends GenericSupportEnvelopeOnly { - def supportLabel: String = "janitor" -} diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index e4d53dcb1..7a1f16e00 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -3,13 +3,38 @@ package net.psforever.services.avatar.support import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.Player -import net.psforever.types.ExoSuitType -import net.psforever.services.RemoverActor +import net.psforever.types.{ExoSuitType, PlanetSideGUID} +import net.psforever.services.{RemoverActor, Service} +import net.psforever.services.avatar.AvatarAction.Release import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.ObjectDelete import scala.concurrent.duration._ +final case class ReleaseEnvelope( + originalChannel: String, + filter: PlanetSideGUID, + msg: Release + ) + extends GenericSupportEnvelope { + def supportLabel: String = "undertaker" + def supportMessage: Any = { + val Release(player, zone, time) = msg + RemoverActor.AddTask(player, zone, time) + } +} + +object ReleaseEnvelope { + def apply(channel: String, actionMessage: Release): ReleaseEnvelope = + ReleaseEnvelope(channel, Service.defaultPlayerGUID, actionMessage) +} + +final case class CorpseEnvelope(supportMessage: Any) + extends GenericSupportEnvelopeOnly { + def supportLabel: String = "undertaker" +} + class CorpseRemovalActor extends RemoverActor() { final val FirstStandardDuration: FiniteDuration = 1 minute diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index dbdf5d252..8224c53af 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -3,12 +3,59 @@ package net.psforever.services.avatar.support import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.{GUIDTask, TaskBundle} -import net.psforever.services.RemoverActor +import net.psforever.objects.zones.Zone +import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem} +import net.psforever.services.{RemoverActor, Service} import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.ObjectDelete +import net.psforever.types.PlanetSideGUID import scala.concurrent.duration._ +final case class PickupItemEnvelope( + originalChannel: String, + filter: PlanetSideGUID, + msg: PickupItem, + zone: Zone + ) + extends GenericSupportEnvelope { + def supportLabel: String = "janitor" + def supportMessage: Any = { + val PickupItem(item, _) = msg + RemoverActor.ClearSpecific(List(item), zone) + } +} + +object PickupItemEnvelope { + def apply(channel: String, actionMessage: PickupItem, zone: Zone): PickupItemEnvelope = + PickupItemEnvelope(channel, Service.defaultPlayerGUID, actionMessage, zone) +} + +final case class DropItemEnvelope( + originalChannel: String, + filter: PlanetSideGUID, + msg: DropItem, + zone: Zone + ) + extends GenericSupportEnvelope { + def supportLabel: String = "janitor" + def supportMessage: Any = { + val DropItem(item) = msg + RemoverActor.AddTask(item, zone) + } +} + +object DropItemEnvelope { + def apply(channel: String, actionMessage: DropItem, zone: Zone): DropItemEnvelope = + DropItemEnvelope(channel, Service.defaultPlayerGUID, actionMessage, zone) +} + +final case class GroundEnvelope(supportMessage: Any) + extends GenericSupportEnvelopeOnly { + def supportLabel: String = "janitor" +} + class DroppedItemRemover extends RemoverActor() { final val FirstStandardDuration: FiniteDuration = 3 minutes diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index d294539ed..202f08d7c 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -7,8 +7,6 @@ import net.psforever.services.base.bus.GenericEventBus import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope} import org.log4s.Logger -import scala.annotation.unused - trait EventSystemStamp abstract class GenericEventService(stamp: EventSystemStamp) @@ -18,7 +16,13 @@ abstract class GenericEventService(stamp: EventSystemStamp) protected val eventBus: GenericEventBus = new GenericEventBus private def commonJoinBehavior: Receive = { - case Service.Join(channel) => + case Service.Join(channel, true) => + val path = formatChannel(channel) + val who = sender() + eventBus.subscribe(who, path) + who ! Service.JoinConfirmation(self, channel) + + case Service.Join(channel, _) => val path = formatChannel(channel) val who = sender() eventBus.subscribe(who, path) @@ -53,7 +57,7 @@ abstract class GenericEventService(stamp: EventSystemStamp) eventBus.publish(composeResponseEnvelope(msg)) } - protected def composeResponseEnvelope(@unused msg: GenericMessageEnvelope): GenericResponseEnvelope = { + protected def composeResponseEnvelope(msg: GenericMessageEnvelope): GenericResponseEnvelope = { msg.response(stamp, formatChannel) } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index abdb1b9f4..ce73b3d00 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -1,17 +1,21 @@ // Copyright (c) 2026 PSForever package net.psforever.services.base +import akka.actor.Cancellable +import net.psforever.objects.Default import net.psforever.services.Service -import net.psforever.services.base.envelope.{GenericMessageEnvelope, MessageEnvelope, MessageTransformationBehavior} +import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageEnvelope, MessageTransformationBehavior} import net.psforever.services.base.message.EventMessage import net.psforever.types.PlanetSideGUID import scala.collection.concurrent.{Map => CMap} import scala.jdk.CollectionConverters._ import java.util.concurrent.ConcurrentHashMap +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.duration.DurationInt /* -Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission +Adapted from the rating limiting code in PSForever fork https://github.com/Pinapse/giant with permission */ trait CachedGenericEventMessageEnvelope @@ -19,26 +23,42 @@ trait CachedGenericEventMessageEnvelope def guid: PlanetSideGUID } -final case class CachedMessage( - guid: PlanetSideGUID, - originalChannel: String, - override val filter: PlanetSideGUID, - override val msg: EventMessage - ) extends CachedGenericEventMessageEnvelope { +final case class CachedEnvelope( + guid: PlanetSideGUID, + originalChannel: String, + override val filter: PlanetSideGUID, + override val msg: EventMessage + ) extends CachedGenericEventMessageEnvelope { assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") } -object CachedMessage { +object CachedEnvelope { def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { if (filter == Service.defaultPlayerGUID) { + org.log4s.getLogger("CachedEnvelope").warn("(1) cached message envelope downgraded to normal message envelope") MessageEnvelope(channel, filter, msg) } else { - CachedMessage(filter, channel, filter, msg) + CachedEnvelope(filter, channel, filter, msg) + } + } + + def apply(guid: PlanetSideGUID, channel: String, msg: EventMessage): GenericMessageEnvelope = { + if (guid == Service.defaultPlayerGUID) { + org.log4s.getLogger("CachedEnvelope").warn("(2) cached message envelope downgraded to normal message envelope") + MessageEnvelope(channel, guid, msg) + } else { + CachedEnvelope(guid, channel, guid, msg) } } } -private case object FlushCachedMessages +private case object FlushCachedMessages extends GenericMessageEnvelope { + def originalChannel: String = "" + def msg: EventMessage = NoMessage + def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope = NoResponseEnvelope + def channel: String = "" + def filter: PlanetSideGUID = Service.defaultPlayerGUID +} abstract class GenericEventServiceWithCacheAndSupport ( @@ -48,6 +68,8 @@ abstract class GenericEventServiceWithCacheAndSupport private val flushCacheWait: Long = 50 //milliseconds private var hasCachedMessages: Boolean = false private var nextTimeToFlushCache: Long = 0L + private var emergencyFlush: Cancellable = Default.Cancellable + private val cache: CMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]] = new ConcurrentHashMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]]().asScala @@ -60,6 +82,7 @@ abstract class GenericEventServiceWithCacheAndSupport if (!hasCachedMessages) { hasCachedMessages = true nextTimeToFlushCache = System.currentTimeMillis() + flushCacheWait + emergencyFlush = context.system.scheduler.scheduleOnce(55 milliseconds, self, FlushCachedMessages) } } @@ -88,12 +111,16 @@ abstract class GenericEventServiceWithCacheAndSupport } } hasCachedMessages = false + emergencyFlush.cancel() + emergencyFlush = Default.Cancellable } override protected def handleMessage(event: GenericMessageEnvelope): Unit = { event match { case envelope: CachedGenericEventMessageEnvelope => pushToCache(envelope) + case FlushCachedMessages => + tryFlushCache() case _ => super.handleMessage(event) } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index 0138898f5..c875f1d82 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -23,7 +23,7 @@ trait EventServiceSupport { def constructor(@unused context: ActorContext): ActorRef } -sealed trait GenericMessageToSupport { +trait GenericMessageToSupport { def supportLabel: String def supportMessage: Any } diff --git a/src/main/scala/net/psforever/services/local/LocalAction.scala b/src/main/scala/net/psforever/services/local/LocalAction.scala index 092b71776..f10d33ea6 100644 --- a/src/main/scala/net/psforever/services/local/LocalAction.scala +++ b/src/main/scala/net/psforever/services/local/LocalAction.scala @@ -9,6 +9,7 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.vehicles.Utility import net.psforever.objects.zones.Zone import net.psforever.packet.game.{DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound} +import net.psforever.services.Service import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent, SendResponse} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent import net.psforever.types.{PlanetSideGUID, Vector3} @@ -126,7 +127,7 @@ object LocalAction { orient: Vector3 ) extends EventMessage { def response(): EventResponse = { - TriggerEffectAtLocation(PlanetSideGUID(0), effect, None, Some(TriggeredEffectLocation(pos, orient))) + TriggerEffectAtLocation(Service.defaultPlayerGUID, effect, None, Some(TriggeredEffectLocation(pos, orient))) } } diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index ed9d3a094..005610369 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -4,9 +4,6 @@ package net.psforever.services.local import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.EventMessage -import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} -import net.psforever.services.local.LocalAction.{IsADoorMessage, IsAHackMessage} -import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.PlanetSideGUID object LocalServiceMessage { @@ -16,36 +13,3 @@ object LocalServiceMessage { def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = MessageEnvelope(channel, filter, msg) } - -final case class DoorMessage( - originalChannel: String, - msg: IsADoorMessage, - supportMessage: Any - ) extends GenericSupportEnvelope { - def filter: PlanetSideGUID = Service.defaultPlayerGUID - def supportLabel: String = "doorCloser" -} - -final case class HackEntityMessage( - originalChannel: String, - filter: PlanetSideGUID, - msg: IsAHackMessage, - supportMessage: Any - ) extends GenericSupportEnvelope { - def supportLabel: String = "hackClearer" -} - -final case class HackClearMessage(supportMessage: Any) - extends GenericSupportEnvelopeOnly { - def supportLabel: String = "hackClearer" -} - -final case class CaptureMessage(supportMessage: Any) - extends GenericSupportEnvelopeOnly { - def supportLabel: String = "hackCapturer" -} - -final case class FlagMessage(supportMessage: CaptureFlagManager.Command) - extends GenericSupportEnvelopeOnly { - def supportLabel: String = "captureFlagManager" -} diff --git a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala index 4a3ea889b..d08d1e207 100644 --- a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala +++ b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala @@ -15,13 +15,19 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.ServiceManager.{Lookup, LookupResult} +import net.psforever.services.base.GenericSupportEnvelopeOnly import net.psforever.services.base.message.{GenericObjectAction, SendResponse} import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.duration.DurationInt +final case class FlagEnvelope(supportMessage: CaptureFlagManager.Command) + extends GenericSupportEnvelopeOnly { + def supportLabel: String = "captureFlagManager" +} + /** * Responsible for handling capture flag related lifecycles */ @@ -303,7 +309,7 @@ object CaptureFlagManager { if LoseFlagViolentlyToEnvironment(target, Set(EnvironmentAttribute.Water, EnvironmentAttribute.Lava, EnvironmentAttribute.Death)) /*|| LoseFlagViolentlyToWarpGateEnvelope(zone, target)*/ => flag.Destroyed = true - zone.LocalEvents ! CaptureMessage(HackCaptureActor.FlagLost(flag)) + zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.FlagLost(flag)) true } .getOrElse(false) diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index ef959035e..a8ad7e9ae 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -5,12 +5,24 @@ import akka.actor.{Actor, Cancellable} import net.psforever.objects.{Default, Doors} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone +import net.psforever.services.Service +import net.psforever.services.base.GenericSupportEnvelope +import net.psforever.services.local.LocalAction.IsADoorMessage import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec import scala.concurrent.duration._ +final case class DoorMessage( + originalChannel: String, + msg: IsADoorMessage, + supportMessage: Any + ) extends GenericSupportEnvelope { + def filter: PlanetSideGUID = Service.defaultPlayerGUID + def supportLabel: String = "doorCloser" +} + /** * Close an opened door after a certain amount of time has passed. * This `Actor` is intended to sit on top of the event system that handles broadcast messaging regarding doors opening. diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index 762eba15e..b6f825950 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -13,9 +13,10 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource +import net.psforever.services.base.GenericSupportEnvelopeOnly import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction -import net.psforever.services.local.{FlagMessage, LocalAction, LocalServiceMessage} +import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} import java.util.concurrent.{Executors, TimeUnit} @@ -23,6 +24,11 @@ import scala.collection.Seq import scala.concurrent.duration.{FiniteDuration, _} import scala.util.Random +final case class CaptureEnvelope(supportMessage: Any) + extends GenericSupportEnvelopeOnly { + def supportLabel: String = "hackCapturer" +} + /** * Responsible for handling the aspects related to hacking control consoles and capturing bases. */ @@ -168,7 +174,7 @@ class HackCaptureActor extends Actor { if (found.isEmpty) { log.warn(s"FlagLost: flag data does not match to an entry in the hacked objects list") } - owner.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.FlagLost)) + owner.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.FlagLost)) case _ => () } @@ -190,7 +196,7 @@ class HackCaptureActor extends Actor { true case Some((owner, Some(flag), Some(neighbours))) if neighbours.nonEmpty && hackingFaction != flag.Faction => log.info(s"$hackingFaction is overriding the ongoing LLU hack of facility ${owner.Name} by ${flag.Faction}") - terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended)) + terminal.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended)) NotifyHackStateChange(terminal, isResecured = false) RestartTimer() spawnCaptureFlag(neighbours, terminal, hackingFaction) @@ -204,7 +210,7 @@ class HackCaptureActor extends Actor { case Some((owner, Some(flag), _)) => log.warn(s"TrySpawnCaptureFlag: couldn't find any neighbouring $hackingFaction facilities of ${owner.Name} for LLU hack") owner.GetFlagSocket.foreach { _.clearOldFlagData() } - terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended)) + terminal.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended)) false case _ => log.error(s"TrySpawnCaptureFlag: expecting a terminal ${terminal.GUID.guid} with the ctf owning facility") @@ -220,7 +226,7 @@ class HackCaptureActor extends Actor { // Find a random neighbouring base matching the hacking faction val targetBase = neighbours.toVector((new Random).nextInt(neighbours.size)) // Request LLU is created by CaptureFlagActor via LocalService - terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.SpawnCaptureFlag(terminal, targetBase, hackingFaction)) + terminal.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.SpawnCaptureFlag(terminal, targetBase, hackingFaction)) } private def NotifyHackStateChange( diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index 396280233..5f6d964f6 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -8,13 +8,29 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.HackState7 +import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.GenericObjectAction +import net.psforever.services.local.LocalAction.IsAHackMessage import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec import scala.concurrent.duration._ +final case class HackEntityEnvelope( + originalChannel: String, + filter: PlanetSideGUID, + msg: IsAHackMessage, + supportMessage: Any + ) extends GenericSupportEnvelope { + def supportLabel: String = "hackClearer" +} + +final case class HackClearEnvelope(supportMessage: Any) + extends GenericSupportEnvelopeOnly { + def supportLabel: String = "hackClearer" +} + /** * Restore original functionality to an object that has been hacked after a certain amount of time has passed. * This `Actor` is intended to sit on top of the event system that handles broadcast messaging regarding hacking events. diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala index 6364e2cf5..dad025f86 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleAction.scala @@ -114,13 +114,13 @@ object VehicleAction { final case class UpdateAmsSpawnPoint(zone: Zone) extends EventMessage { override def response(): EventResponse = { - VehicleAction.UpdateAmsSpawnList(AmsSpawnPoints(zone)) + VehicleAction.UpdateAmsSpawnList(Zone.AmsSpawnPoints(zone)) } } final case class AMSDeploymentChange(zone: Zone) extends EventMessage { override def response(): EventResponse = { - VehicleAction.UpdateAmsSpawnList(AmsSpawnPoints(zone)) + VehicleAction.UpdateAmsSpawnList(Zone.AmsSpawnPoints(zone)) } } @@ -140,16 +140,4 @@ object VehicleAction { old_inventory: List[(Equipment, PlanetSideGUID)], new_inventory: List[InventoryItem] ) extends SelfRespondingEvent - - import net.psforever.objects.serverobject.tube.SpawnTube - private def AmsSpawnPoints(zone: Zone): List[SpawnTube] = { - import net.psforever.objects.vehicles.UtilityType - import net.psforever.objects.GlobalDefinitions - zone.Vehicles - .filter(veh => - veh.Health > 0 && veh.Definition == GlobalDefinitions.ams && veh.DeploymentState == DriveState.Deployed - ) - .flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube)) - .map(util => util().asInstanceOf[SpawnTube]) - } } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala index 212e44638..f6aae9a32 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala @@ -3,7 +3,6 @@ package net.psforever.services.vehicle import net.psforever.services.Service import net.psforever.services.base.message.EventMessage -import net.psforever.services.base.GenericSupportEnvelopeOnly import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.PlanetSideGUID @@ -14,8 +13,3 @@ object VehicleServiceMessage { def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = MessageEnvelope(channel, filter, msg) } - -final case class TurretMessage(supportMessage: Any) - extends GenericSupportEnvelopeOnly { - def supportLabel: String = "turretUpgrader" -} diff --git a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala index ac08220e4..1b81938c7 100644 --- a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala +++ b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala @@ -9,6 +9,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, WeaponTurret} import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.zones.Zone +import net.psforever.services.base.GenericSupportEnvelopeOnly import net.psforever.types.PlanetSideGUID import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -17,6 +18,11 @@ import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global +final case class TurretEnvelope(supportMessage: Any) + extends GenericSupportEnvelopeOnly { + def supportLabel: String = "turretUpgrader" +} + class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { var task: Cancellable = Default.Cancellable diff --git a/src/test/scala/objects/DamageableTest.scala b/src/test/scala/objects/DamageableTest.scala index fbf3b9f3a..8c3357fe4 100644 --- a/src/test/scala/objects/DamageableTest.scala +++ b/src/test/scala/objects/DamageableTest.scala @@ -24,7 +24,7 @@ import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types._ import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.support.SupportActor -import net.psforever.services.vehicle.TurretMessage +import net.psforever.services.vehicle.support.TurretEnvelope import org.specs2.mutable.Specification import scala.concurrent.duration._ @@ -1095,12 +1095,12 @@ class DamageableWeaponTurretDestructionTest extends ActorTest { assert(false, s"DamageableWeaponTurretDestructionTest-4: ${msg12_4(2)}") } msg56.head match { - case TurretMessage(SupportActor.ClearSpecific(List(t), _)) if turret eq t => ; + case TurretEnvelope(SupportActor.ClearSpecific(List(t), _)) if turret eq t => ; case _ => assert(false, s"DamageableWeaponTurretDestructionTest-5: ${msg56.head}") } msg56(1) match { - case TurretMessage(TurretUpgrader.AddTask(t, _, TurretUpgrade.None, _)) if t eq turret => () + case TurretEnvelope(TurretUpgrader.AddTask(t, _, TurretUpgrade.None, _)) if t eq turret => () case _ => assert(false, s"DamageableWeaponTurretDestructionTest-6: ${msg56(1)}") } assert(turret.Health <= turret.Definition.DamageDestroysAt) diff --git a/src/test/scala/objects/DeploymentTest.scala b/src/test/scala/objects/DeploymentTest.scala index c0d4702ec..685479768 100644 --- a/src/test/scala/objects/DeploymentTest.scala +++ b/src/test/scala/objects/DeploymentTest.scala @@ -76,7 +76,7 @@ class DeploymentBehavior2Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -89,7 +89,7 @@ class DeploymentBehavior2Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -106,7 +106,7 @@ class DeploymentBehavior2Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -119,7 +119,7 @@ class DeploymentBehavior2Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -148,7 +148,7 @@ class DeploymentBehavior3Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -161,7 +161,7 @@ class DeploymentBehavior3Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -178,7 +178,7 @@ class DeploymentBehavior3Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } @@ -191,7 +191,7 @@ class DeploymentBehavior3Test extends ActorTest { case MessageEnvelope( "test", _, - VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) + VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero) ) => () case _ => assert(false, "") } diff --git a/src/test/scala/objects/DoorTest.scala b/src/test/scala/objects/DoorTest.scala index 25010c2a7..2404e44ca 100644 --- a/src/test/scala/objects/DoorTest.scala +++ b/src/test/scala/objects/DoorTest.scala @@ -12,7 +12,8 @@ import net.psforever.objects.{Default, GlobalDefinitions, Player} import net.psforever.objects.serverobject.doors.{Door, DoorControl} import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.zones.{Zone, ZoneMap} -import net.psforever.services.local.{DoorMessage, LocalAction, LocalServiceResponse} +import net.psforever.services.local.support.DoorMessage +import net.psforever.services.local.{LocalAction, LocalServiceResponse} import net.psforever.types._ import org.specs2.mutable.Specification diff --git a/src/test/scala/objects/PlayerControlTest.scala b/src/test/scala/objects/PlayerControlTest.scala index 514b35846..eeee7f3b5 100644 --- a/src/test/scala/objects/PlayerControlTest.scala +++ b/src/test/scala/objects/PlayerControlTest.scala @@ -563,7 +563,7 @@ class PlayerControlDeathStandingTest extends ActorTest { ) assert( msg_avatar(1) match { - case MessageEnvelope("TestCharacter2", _, AvatarAction.Killed(PlanetSideGUID(2), _, None)) => true + case MessageEnvelope("TestCharacter2", _, AvatarAction.Killed(_, None)) => true case _ => false } ) diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index 95c28f5ce..a558b6487 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -318,7 +318,7 @@ class RepairableTurretWeapon extends ActorTest { ) assert( msg4 match { - case MessageEnvelope("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t)) + case MessageEnvelope("test", _, VehicleAction.EquipmentInSlot(PlanetSideGUID(2), 1, t)) if t eq turretWeapon => true case _ => false diff --git a/src/test/scala/objects/TelepadRouterTest.scala b/src/test/scala/objects/TelepadRouterTest.scala index a1c25b0cd..bc43ef10d 100644 --- a/src/test/scala/objects/TelepadRouterTest.scala +++ b/src/test/scala/objects/TelepadRouterTest.scala @@ -59,7 +59,6 @@ class TelepadDeployableNoRouterTest extends ActorTest { "NEUTRAL", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0)) ) @@ -75,7 +74,6 @@ class TelepadDeployableNoRouterTest extends ActorTest { "NEUTRAL", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0)) ) @@ -130,7 +128,6 @@ class TelepadDeployableNoActivationTest extends ActorTest { "NEUTRAL", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0)) ) @@ -147,7 +144,6 @@ class TelepadDeployableNoActivationTest extends ActorTest { "NEUTRAL", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Dismiss, DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0)) ) @@ -205,7 +201,6 @@ class TelepadDeployableAttemptTest extends ActorTest { "NEUTRAL", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0)) ) @@ -279,7 +274,6 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest { "NEUTRAL", _, LocalAction.DeployableMapIcon( - PlanetSideGUID(0), DeploymentAction.Build, DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0)) ) diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index 14bf44040..54306b8ae 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -27,7 +27,7 @@ import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.VehicleAction +import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types._ import scala.concurrent.duration._ @@ -74,7 +74,7 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest { val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds) vehicle_msg.head match { - case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(2), 4, true, PlanetSideGUID(1))) => ; + case MessageEnvelope("test", _, VehicleAction.KickPassenger(4, true, PlanetSideGUID(1))) => ; case _ => assert(false, s"VehicleControlPrepareForDeletionPassengerTest: ${vehicle_msg.head}") } @@ -226,7 +226,7 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor val vehicleMsgs = eventsProbe.receiveN(6, 10.seconds) val cargoMsgs = cargoProbe.receiveN(1, 1.seconds) vehicleMsgs.head match { - case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(4), 4, true, PlanetSideGUID(2))) => () + case MessageEnvelope("test", _, VehicleAction.KickPassenger(4, true, PlanetSideGUID(2))) => () case _ => assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-1: ${vehicleMsgs.head}") } @@ -478,8 +478,8 @@ class VehicleControlShieldsChargingTest extends ActorTest { vehicle.Actor ! CommonMessages.ChargeShields(15, None) val msg = probe.receiveOne(500 milliseconds) assert(msg match { - case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true - case _ => false + case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true + case _ => false }) assert(vehicle.Shields == 15) assert(vehicle.History.exists({ p => p.isInstanceOf[ShieldCharge] })) diff --git a/src/test/scala/service/LocalServiceTest.scala b/src/test/scala/service/LocalServiceTest.scala deleted file mode 100644 index 8519962c1..000000000 --- a/src/test/scala/service/LocalServiceTest.scala +++ /dev/null @@ -1,376 +0,0 @@ -// Copyright (c) 2017 PSForever -package service - -import akka.actor.Props -import akka.testkit.TestProbe -import base.{ActorTest, FreedContextActorTest} -import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle} -import net.psforever.objects.serverobject.PlanetSideServerObject -import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal} -import net.psforever.objects.vehicles.control.VehicleControl -import net.psforever.objects.zones.{Zone, ZoneMap} -import net.psforever.packet.game._ -import net.psforever.services.base.message.{SendResponse, SetEmpire} -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} -import net.psforever.services.{Service, ServiceManager} -import net.psforever.services.local._ - -import scala.concurrent.duration._ - -class LocalService1Test extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "construct" in { - system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - assert(true) - } - } -} - -class LocalService2Test extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "subscribe" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - assert(true) - } - } -} - -class LocalService3Test extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "subscribe to a specific channel" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! Service.Leave() - assert(true) - } - } -} - -class LocalService4Test extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "subscribe" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! Service.LeaveAll() - assert(true) - } - } -} - -class LocalService5Test extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass an unhandled message" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! "hello" - expectNoMessage() - } - } -} - - - -class DeployItemTest extends ActorTest { - ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "deploy-item-test-service") - val objDef = GlobalDefinitions.motionalarmsensor - val obj = new SensorDeployable(objDef) - obj.Position = Vector3(1, 2, 3) - obj.Orientation = Vector3(4, 5, 6) - obj.GUID = PlanetSideGUID(40) - val pkt = ObjectCreateMessage( - objDef.ObjectId, - obj.GUID, - objDef.Packet.ConstructorData(obj).get - ) - - "AvatarService" should { - "pass DeployItem" in { - service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.DeployItem(obj)) - expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), SendResponse(Seq(pkt)))) - } - } -} - -class DeployableMapIconTest extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass DeployableMapIcon" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage( - "test", - PlanetSideGUID(10), - LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11))) - ) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(10), - LocalAction.DeployableMapIcon( - DeploymentAction.Build, - DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11)) - ) - ) - ) - } - } -} - -class DoorClosesTest extends FreedContextActorTest { - val probe = new TestProbe(system) - val zone = new Zone("test", new ZoneMap("test-map"), 0) { - override def SetupNumberPools() : Unit = { } - } - zone.init(context) - expectNoMessage(500 milliseconds) - - "LocalService" should { - "pass DoorCloses" in { - zone.LocalEvents.tell(Service.Join("test"), probe.ref) - zone.LocalEvents ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.DoorCloses(PlanetSideGUID(40))) - probe.expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.DoorCloses(PlanetSideGUID(40)))) - } - } -} - -class HackClearTest extends ActorTest { - ServiceManager.boot(system) - val obj = new PlanetSideServerObject() { - def Faction = PlanetSideEmpire.NEUTRAL - def Definition = null - GUID = PlanetSideGUID(40) - } - - "LocalService" should { - "pass HackClear" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.HackClear(obj.GUID, 0L, HackState7.Unk8)) - expectMsg( - LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.HackClear(PlanetSideGUID(40), 0L, HackState7.Unk8)) - ) - } - } -} - -class ProximityTerminalEffectOnTest extends ActorTest { - ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal) - terminal.GUID = PlanetSideGUID(1) - - "LocalService" should { - "pass ProximityTerminalEffect (true)" in { - service ! Service.Join("nowhere") - service ! LocalServiceMessage("nowhere", LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), effectState = true)) - expectMsg( - LocalServiceResponse( - "/nowhere/Local", - PlanetSideGUID(0), - LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), true) - ) - ) - } - } -} - -class ProximityTerminalEffectOffTest extends ActorTest { - ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal) - terminal.GUID = PlanetSideGUID(1) - - "LocalService" should { - "pass ProximityTerminalEffect (false)" in { - service ! Service.Join("nowhere") - service ! LocalServiceMessage("nowhere", LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), effectState = false)) - expectMsg( - LocalServiceResponse( - "/nowhere/Local", - PlanetSideGUID(0), - LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), false) - ) - ) - } - } -} - -class RouterTelepadTransportTest extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass RouterTelepadTransport" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage( - "test", - PlanetSideGUID(10), - LocalAction.RouterTelepadTransport( - PlanetSideGUID(11), - PlanetSideGUID(12), - PlanetSideGUID(13) - ) - ) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(10), - LocalAction.RouterTelepadTransport(PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13)) - ) - ) - } - } -} - -class SetEmpireTest extends ActorTest { - ServiceManager.boot(system) - val obj = new SensorDeployable(GlobalDefinitions.motionalarmsensor) - - "LocalService" should { - "pass SetEmpire" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage("test", SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR)) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(0), - SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR) - ) - ) - } - } -} - -class ToggleTeleportSystemTest extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass ToggleTeleportSystem" in { - val router = Vehicle(GlobalDefinitions.router) - router.Actor = system.actorOf(Props(classOf[VehicleControl], router), "test-router") - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.ToggleTeleportSystem(router, None)) - expectMsg( - LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.ToggleTeleportSystem(router, None)) - ) - } - } -} - -class TriggerEffectTest extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass TriggerEffect (1)" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.TriggerEffect("on", PlanetSideGUID(40))) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(10), - LocalAction.TriggerEffectAtLocation(PlanetSideGUID(40), "on", None, None) - ) - ) - } - } -} - -class TriggerEffectInfoTest extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass TriggerEffect (2)" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage( - "test", - PlanetSideGUID(10), - LocalAction.TriggerEffectInfo(PlanetSideGUID(40), "on", true, 1000) - ) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(10), - LocalAction.TriggerEffectAtLocation(PlanetSideGUID(40), "on", Some(TriggeredEffect(true, 1000)), None) - ) - ) - } - } -} - -class TriggerEffectLocationTest extends ActorTest { - ServiceManager.boot(system) - - "LocalService" should { - "pass TriggerEffect (3)" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage( - "test", - PlanetSideGUID(10), - LocalAction.TriggerEffectLocation( - "spawn_object_failed_effect", - Vector3(1.1f, 2.2f, 3.3f), - Vector3(4.4f, 5.5f, 6.6f) - ) - ) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(10), - LocalAction.TriggerEffectAtLocation( - PlanetSideGUID(0), - "spawn_object_failed_effect", - None, - Some(TriggeredEffectLocation(Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f))) - ) - ) - ) - } - } -} - -class TriggerSoundTest extends ActorTest { - import net.psforever.packet.game.TriggeredSound - ServiceManager.boot(system) - - "LocalService" should { - "pass TriggerSound" in { - val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") - service ! Service.Join("test") - service ! LocalServiceMessage( - "test", - PlanetSideGUID(10), - LocalAction.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f) - ) - expectMsg( - LocalServiceResponse( - "/test/Local", - PlanetSideGUID(10), - LocalAction.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f) - ) - ) - } - } -} - -object LocalServiceTest { - //decoy -} diff --git a/src/test/scala/service/VehicleServiceTest.scala b/src/test/scala/service/VehicleServiceTest.scala deleted file mode 100644 index 8bd56c628..000000000 --- a/src/test/scala/service/VehicleServiceTest.scala +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright (c) 2017 PSForever -package service - -import akka.actor.Props -import base.ActorTest -import net.psforever.objects._ -import net.psforever.objects.vehicles.control.VehicleControl -import net.psforever.objects.zones.Zone -import net.psforever.types.{PlanetSideGUID, _} -import net.psforever.services.{Service, ServiceManager} -import net.psforever.services.vehicle._ - -class VehicleService1Test extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "construct" in { - system.actorOf(Props(classOf[VehicleService]), "v-service") - assert(true) - } - } -} - -class VehicleService2Test extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "subscribe" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - assert(true) - } - } -} - -class VehicleService3Test extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "subscribe to a specific channel" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! Service.Leave() - assert(true) - } - } -} - -class VehicleService4Test extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "subscribe" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! Service.LeaveAll() - assert(true) - } - } -} - -class VehicleService5Test extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass an unhandled message" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! "hello" - expectNoMessage() - } - } -} - -class OwnershipTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass Awareness" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11))) - expectMsg( - VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11))) - ) - } - } -} - -class ChildObjectStateTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass ChildObjectState" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f) - ) - ) - } - } -} - -class DeployRequestTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass DeployRequest" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f)) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f)) - ) - ) - } - } -} - -class DismountVehicleTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass DismountVehicle" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.DismountVehicle(BailType.Normal, false)) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.DismountVehicle(BailType.Normal, false) - ) - ) - } - } -} - -class InventoryStateTest extends ActorTest { - ServiceManager.boot(system) - val tool = Tool(GlobalDefinitions.beamer) - tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13) - val cdata = tool.Definition.Packet.ConstructorData(tool).get - - "VehicleService" should { - "pass InventoryState" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.InventoryState(tool, PlanetSideGUID(11), 0, cdata) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.InventoryState(tool, PlanetSideGUID(11), 0, cdata) - ) - ) - } - } -} - -class InventoryState2Test extends ActorTest { - ServiceManager.boot(system) - val tool = Tool(GlobalDefinitions.beamer) - tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13) - val cdata = tool.Definition.Packet.ConstructorData(tool).get - - "VehicleService" should { - "pass InventoryState2" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13) - ) - ) - } - } -} - -class KickPassengerTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass KickPassenger" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.KickPassenger(0, false, PlanetSideGUID(11)) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.KickPassenger(0, false, PlanetSideGUID(11)) - ) - ) - } - } -} - -class LoadVehicleTest extends ActorTest { - ServiceManager.boot(system) - val vehicle = Vehicle(GlobalDefinitions.quadstealth) - vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "test-vehicle") - val cdata = vehicle.Definition.Packet.ConstructorData(vehicle).get - - "VehicleService" should { - "pass LoadVehicle" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata) - ) - ) - } - } -} - -class MountVehicleTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass MountVehicle" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage("test", VehicleAction.MountVehicle(PlanetSideGUID(11), 0)) - expectMsg( - VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.MountVehicle(PlanetSideGUID(11), 0)) - ) - } - } -} - -class SeatPermissionsTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass SeatPermissions" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - VehicleAction.SeatPermissions(PlanetSideGUID(11), 0, 12L) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.SeatPermissions(PlanetSideGUID(11), 0, 12L) - ) - ) - } - } -} - -class StowEquipmentTest extends ActorTest { - ServiceManager.boot(system) - val tool = Tool(GlobalDefinitions.beamer) - tool.GUID = PlanetSideGUID(12) - tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13) - val toolDef = tool.Definition - val cdata = tool.Definition.Packet.DetailedConstructorData(tool).get - - "StowEquipment" should { - "pass StowEquipment" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.StowEquipment(PlanetSideGUID(11), 0, tool) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.StowEquipment(PlanetSideGUID(11), 0, toolDef.ObjectId, tool.GUID, cdata) - ) - ) - } - } -} - -class UnstowEquipmentTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass UnstowEquipment" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11))) - expectMsg( - VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11))) - ) - } - } -} - -class VehicleStateTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass VehicleState" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - VehicleAction.VehicleState(PlanetSideGUID(11), 0, Vector3(1.2f, 3.4f, 5.6f), Vector3(7.8f, 9.1f, 2.3f), Some(Vector3(4.5f, 6.7f, 8.9f)), Option(1), 2, 3, 4, false, true) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.VehicleState( - PlanetSideGUID(11), - 0, - Vector3(1.2f, 3.4f, 5.6f), - Vector3(7.8f, 9.1f, 2.3f), - Some(Vector3(4.5f, 6.7f, 8.9f)), - Option(1), - 2, - 3, - 4, - false, - true - ) - ) - ) - } - } -} - -class TransferPassengerChannelTest extends ActorTest { - ServiceManager.boot(system) - - "VehicleService" should { - "pass TransferPassengerChannel" in { - val service = system.actorOf(Props(classOf[VehicleService]), "v-service") - val fury = Vehicle(GlobalDefinitions.fury) - fury.Actor = system.actorOf(Props(classOf[VehicleControl], fury), "test-fury") - service ! Service.Join("test") - service ! VehicleServiceMessage( - "test", - PlanetSideGUID(10), - VehicleAction.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11)) - ) - expectMsg( - VehicleServiceResponse( - "/test/Vehicle", - PlanetSideGUID(10), - VehicleAction.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11)) - ) - ) - } - } -} - -//class TransferPassengerTest extends ActorTest { -// ServiceManager.boot(system) -// "VehicleService" should { -// "pass TransferPassenger" in { -// val fury = Vehicle(GlobalDefinitions.fury) -// val service = system.actorOf(Props[VehicleService], "v-service") -// service ! Service.Join("test") -// service ! VehicleServiceMessage("test", VehicleAction.TransferPassenger(PlanetSideGUID(10), "temp_channel", fury, PlanetSideGUID(11))) -// expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.TransferPassenger("temp_channel", fury, PlanetSideGUID(11)))) -// } -// } -//} - -object VehicleServiceTest { - //decoy -} diff --git a/src/test/scala/service/avatar/AvatarActionTest.scala b/src/test/scala/service/avatar/AvatarActionTest.scala new file mode 100644 index 000000000..f83658d50 --- /dev/null +++ b/src/test/scala/service/avatar/AvatarActionTest.scala @@ -0,0 +1,215 @@ +// Copyright (c) 2026 PSForever +package service.avatar + +import net.psforever.objects.avatar.Avatar +import net.psforever.objects.ballistics.Projectile +import net.psforever.objects.sourcing.SourceEntry +import net.psforever.objects.zones.{Zone, ZoneMap} +import net.psforever.objects.{GlobalDefinitions, Player, Tool} +import net.psforever.packet.game.ObjectCreateMessage +import net.psforever.packet.game.objectcreate.{BasicCharacterData, DroppedItemData, ObjectCreateMessageParent, PlacementData} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.message.ObjectDelete +import net.psforever.types._ +import org.specs2.mutable.Specification + +object AvatarActionTest { + assert(GlobalDefinitions.suppressor != null, "missing definition - suppressor does not exist") + assert(GlobalDefinitions.avatar != null, "missing definition - avatar does not exist") + + private var i: Int = 1 + val testSuppressor: Tool = { + val obj = new Tool(GlobalDefinitions.suppressor) + obj.Position = Vector3(1, 2, 3) + obj.Orientation = Vector3(4, 5, 6) + obj.GUID = PlanetSideGUID(i) + i += 1 + obj.AmmoSlots.map(_.Box).foreach { box => + box.GUID = PlanetSideGUID(i) + i += 1 + } + obj + } + + val testPlayer: Player = { + val avatar = new Avatar(id = 1, BasicCharacterData("testPlayer", PlanetSideEmpire.TR, CharacterSex.Male, 0, CharacterVoice.Mute)) + avatar.locker.GUID = PlanetSideGUID(i) + i += 1 + val obj = new Player(avatar) + obj.Position = Vector3(1, 2, 3) + obj.Orientation = Vector3(4, 5, 6) + obj.GUID = PlanetSideGUID(i) + obj.Spawn() + i += 1 + obj + } +} + +class AvatarActionTest extends Specification { + import AvatarActionTest._ + + "DropItem" should { + "respond" in { + val obj = testSuppressor + val msg = AvatarAction.DropItem(obj) + val definition = obj.Definition + val objectData = DroppedItemData( + PlacementData(obj.Position, obj.Orientation), + definition.Packet.ConstructorData(obj).get + ) + msg.response() match { + case AvatarAction.DropCreatedItem(pkt) => + pkt match { + case ObjectCreateMessage(_, oid, guid, _, data) => + oid mustEqual definition.ObjectId + guid mustEqual obj.GUID + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "EquipmentInHand" should { + "respond" in { + val obj = testSuppressor + val msg = AvatarAction.EquipmentInHand(PlanetSideGUID(100), 2, obj) + val definition = obj.Definition + val objectData = definition.Packet.ConstructorData(obj).get + msg.response() match { + case AvatarAction.EquipmentCreatedInHand(pkt) => + pkt match { + case ObjectCreateMessage(_, oid, guid, pdata, data) => + oid mustEqual definition.ObjectId + guid mustEqual obj.GUID + pdata.contains(ObjectCreateMessageParent(PlanetSideGUID(100), 2)) mustEqual true + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "LoadPlayer (1)" should { + "respond" in { + val obj = testPlayer + val definition = obj.Definition + val id = definition.ObjectId + val guid = obj.GUID + val objectData = definition.Packet.ConstructorData(obj).get + val msg = AvatarAction.LoadPlayer(id, guid, objectData, None) + msg.response() match { + case AvatarAction.LoadCreatedPlayer(pkt) => + pkt match { + case ObjectCreateMessage(_, oid, guid, _, data) => + oid mustEqual id + guid mustEqual guid + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "LoadPlayer (2)" should { + "respond" in { + val obj = testPlayer + val definition = obj.Definition + val id = definition.ObjectId + val guid = obj.GUID + val parentData = ObjectCreateMessageParent(PlanetSideGUID(100), 2) + val objectData = definition.Packet.ConstructorData(obj).get + val msg = AvatarAction.LoadPlayer(id, guid, objectData, Some(parentData)) + msg.response() match { + case AvatarAction.LoadCreatedPlayer(pkt) => + pkt match { + case ObjectCreateMessage(_, oid, guid, pdata, data) => + oid mustEqual id + guid mustEqual guid + pdata.contains(parentData) mustEqual true + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "LoadProjectile" should { + assert(GlobalDefinitions.wasp_rocket_projectile != null, "missing definition - wasp_rocket_projectile does not exist") + assert(GlobalDefinitions.wasp_weapon_system != null, "missing definition - wasp_weapon_system does not exist") + + "respond" in { + val obj = new Projectile( + GlobalDefinitions.wasp_rocket_projectile, + GlobalDefinitions.wasp_weapon_system, + GlobalDefinitions.wasp_weapon_system.FireModes.head, + Some((1, SourceEntry.None)), + SourceEntry.None, + GlobalDefinitions.wasp_weapon_system.ObjectId, + Vector3(1, 2, 3), + Vector3(4, 5, 6), + Some(Vector3(7, 8, 9)) + ) + obj.GUID = PlanetSideGUID(1) + val definition = obj.Definition + val id = definition.ObjectId + val guid = obj.GUID + val objectData = definition.Packet.ConstructorData(obj).get + val msg = AvatarAction.LoadProjectile(id, guid, objectData) + msg.response() match { + case AvatarAction.LoadCreatedProjectile(pkt) => + pkt match { + case ObjectCreateMessage(_, oid, guid, _, data) => + oid mustEqual id + guid mustEqual guid + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "PickupItem" should { + "respond" in { + val obj = testSuppressor + val msg = AvatarAction.PickupItem(obj, 2) + msg.response() match { + case ObjectDelete(guid, slot) => + guid mustEqual obj.GUID + slot mustEqual 2 + case _ => + ko + } + } + } + + "Release" should { + val testZone: Zone = new Zone(id = "test", new ZoneMap( name = "test"), zoneNumber = 1) + + "respond" in { + val obj = testPlayer + val msg = AvatarAction.Release(obj, testZone) + msg.response() match { + case AvatarAction.ReleasePlayer(player) => + (player == obj) mustEqual true + case _ => + ko + } + } + } +} diff --git a/src/test/scala/service/base/EnvelopeTest.scala b/src/test/scala/service/base/EnvelopeTest.scala new file mode 100644 index 000000000..85c1e7b3c --- /dev/null +++ b/src/test/scala/service/base/EnvelopeTest.scala @@ -0,0 +1,89 @@ +// Copyright (c) 2026 PSForever +package service.base + +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.envelope._ +import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent} +import net.psforever.types.PlanetSideGUID +import org.specs2.mutable.Specification + +object EnvelopeTest { + case object TestStamp extends EventSystemStamp + + val TestFilter: PlanetSideGUID = PlanetSideGUID(1) + + final def StringWithSlashes(str: String): String = s"/$str/" + + final case class TestMessage(value: Int) extends SelfRespondingEvent + + final case class TestOutputEvent(value: Int) extends EventResponse + + final case class TestInputMessage(value: Int) extends EventMessage { + def response(): EventResponse = TestOutputEvent(value + 2) + } +} + +class EnvelopeTest extends Specification { + import EnvelopeTest._ + + "MessageEnvelope" should { + "construct" in { + MessageEnvelope("test", TestFilter, TestMessage(5)) + ok + } + + "message match" in { + val input = MessageEnvelope("test", TestFilter, TestMessage(5)) + input match { + case GenericMessageEnvelope("test", TestFilter, TestMessage(5)) => + ok + case _ => + ko + } + } + + "response (no stamp)" in { + val input = MessageEnvelope("test", TestFilter, TestMessage(5)) + input match { + case reply @ GenericResponseEnvelope("test", TestFilter, NoReply) => + reply.stamp mustEqual Undelivered + case _ => + ko + } + } + + "response" in { + val input = MessageEnvelope("test", TestFilter, TestMessage(5)) + val output = input.response(TestStamp, StringWithSlashes) + output match { + case reply @ GenericResponseEnvelope("/test/", TestFilter, TestMessage(5)) => + reply.stamp mustEqual TestStamp + case _ => + ko + } + } + + "response (different from input)" in { + val input = MessageEnvelope("test", TestFilter, TestInputMessage(5)) + val output = input.response(TestStamp, StringWithSlashes) + output match { + case reply @ GenericResponseEnvelope("/test/", TestFilter, TestOutputEvent(7)) => + reply.stamp mustEqual TestStamp + case _ => + ko + } + } + } + + "GenericResponseEnvelope" should { + "construct (quick)" in { + val input = GenericResponseEnvelope(TestStamp, "test", TestFilter, TestMessage(5)) + input match { + case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) => + reply.stamp mustEqual TestStamp + case _ => + ko + } + } + } +} diff --git a/src/test/scala/service/base/EventMessageTest.scala b/src/test/scala/service/base/EventMessageTest.scala new file mode 100644 index 000000000..8b9b1bf50 --- /dev/null +++ b/src/test/scala/service/base/EventMessageTest.scala @@ -0,0 +1,42 @@ +// Copyright (c) 2026 PSForever +package service.base + +import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent} +import org.specs2.mutable.Specification + +object EventMessageTest { + final case class TestOutputEvent(value: Int) extends EventResponse + + final case class TestInputMessage(value: Int) extends EventMessage { + def response(): EventResponse = TestOutputEvent(value + 2) + } + + final case class TestMessage(value: Int) extends SelfRespondingEvent +} + +class EventMessageTest extends Specification { + import EventMessageTest._ + + "EventMessage" should { + "construct" in { + TestInputMessage(5) + ok + } + + "response" in { + TestInputMessage(5).response() mustEqual TestOutputEvent(7) + } + } + + "SelfResponseMessage" should { + "construct" in { + TestMessage(5) + ok + } + + "response (is same as self)" in { + val msg = TestMessage(5) + msg.response() mustEqual msg + } + } +} diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala new file mode 100644 index 000000000..2e7fc7610 --- /dev/null +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -0,0 +1,221 @@ +// Copyright (c) 2026 PSForever +package service.base + +import akka.actor.Props +import akka.testkit.TestProbe +import base.ActorTest +import net.psforever.services.Service +import net.psforever.services.base.message.EventMessage +import net.psforever.services.base.{CachedGenericEventMessageEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} +import net.psforever.types.PlanetSideGUID + +import scala.concurrent.duration._ + +object EventServiceCacheSupportTest { + class TestCacheService(eventSupportServices: List[EventServiceSupport]) + extends GenericEventServiceWithCacheAndSupport(EventServiceTestBase.TestStamp, eventSupportServices) + + final case class CachedSupportTestEnvelope( + guid: PlanetSideGUID, + originalChannel: String, + override val msg: EventMessage, + supportMessage: Any + ) extends CachedGenericEventMessageEnvelope with GenericSupportEnvelope { + assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") + def filter: PlanetSideGUID = Service.defaultPlayerGUID + def supportLabel: String = "supportActor" + } +} + +class EventServiceCacheSupportTestDefault extends ActorTest { + import EventServiceCacheSupportTest._ + "GenericEventServiceWithCacheAndSupport" should { + "construct" in { + system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.0") + } + } +} + +class EventServiceCacheSupportTestSupportNormally extends ActorTest { + import EventServiceCacheSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithCacheAndSupport" should { + "send a valid message to both subscribed channel and support class, like normal GenericEventServiceWithSupport" in { + val mainProbe = TestProbe("MainProbe") + val supportProbe = TestProbe("SupportProbe") + val events = system.actorOf(Props(classOf[TestCacheService], List(TestSupportActorLoader)), name = "EventServiceCacheSupportTest.1") + events.tell(Service.Join("test"), mainProbe.ref) + val originalMessage = TestSupportEnvelope("test", SupportActorRepliesWith("hello world", supportProbe.ref)) + events ! originalMessage + //main reply + val mainReply = mainProbe.receiveOne(250 milliseconds) + mainReply match { + case msg if msg == originalMessage => () + case badmsg => + assert(false, s"(1) expected delivery of test envelope, but received $badmsg instead") + } + //support reply + val supportReply = supportProbe.receiveOne(250 milliseconds) + supportReply match { + case msg: String if msg.equals("hello world") => () + case badmsg => + assert(false, s"(2) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead") + } + } + } +} + +class EventServiceCacheSupportTestCachedMessages extends ActorTest { + import EventServiceCacheSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithCacheAndSupport" should { + "wait on sending designated cache-able messages after a few milliseconds" in { + val mainProbe = TestProbe("MainProbe") + val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.2") + events.tell(Service.Join("test"), mainProbe.ref) + val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) + events ! firstMessage + mainProbe.expectNoMessage(50 milliseconds) + val reply = mainProbe.receiveOne(125 milliseconds) + reply match { + case msg if msg == firstMessage => () + case badmsg => + assert(false, s"(3) expected delivery of test envelope, but received $badmsg instead") + } + } + } +} + +class EventServiceCacheSupportTestMultipleCachedMessagesAtOnce extends ActorTest { + import EventServiceCacheSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithCacheAndSupport" should { + "send cache-able messages within a time span in bulk" in { + val mainProbe = TestProbe("MainProbe") + val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.3") + events.tell(Service.Join("test"), mainProbe.ref) + val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) + val secondMessage = CachedEnvelope(PlanetSideGUID(2), "test", TestMessage(2)) + val thirdMessage = CachedEnvelope(PlanetSideGUID(3), "test", TestMessage(3)) + events ! firstMessage + events ! secondMessage + events ! thirdMessage + mainProbe.expectNoMessage(50 milliseconds) + val reply = mainProbe.receiveN(3, 125 milliseconds) + reply.head match { + case msg if msg == firstMessage => () + case badmsg => + assert(false, s"(4) expected delivery of test envelope, but received $badmsg instead") + } + reply(1) match { + case msg if msg == secondMessage => () + case badmsg => + assert(false, s"(5) expected delivery of test envelope, but received $badmsg instead") + } + reply(2) match { + case msg if msg == thirdMessage => () + case badmsg => + assert(false, s"(6) expected delivery of test envelope, but received $badmsg instead") + } + mainProbe.expectNoMessage(65 milliseconds) + } + } +} + +class EventServiceCacheSupportTestMultipleCachedSameMessages extends ActorTest { + import EventServiceCacheSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithCacheAndSupport" should { + "only caches and dispatches the last message with a given filtering token" in { + val mainProbe = TestProbe("MainProbe") + val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.4") + events.tell(Service.Join("test"), mainProbe.ref) + val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) + val secondMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(2)) + val thirdMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(3)) //this one! + events ! firstMessage + events ! secondMessage + events ! thirdMessage + mainProbe.expectNoMessage(50 milliseconds) + val reply = mainProbe.receiveOne(125 milliseconds) + reply match { + case badmsg if badmsg == firstMessage => + assert(false, s"(1) received wrong message - $badmsg") + case badmsg if badmsg == secondMessage => + assert(false, s"(2) received wrong message - $badmsg") + case msg if msg == thirdMessage => () + case badmsg => + assert(false, s"(7) expected delivery of test envelope, but received $badmsg instead") + } + } + } +} + +class EventServiceCacheSupportTestMultipleCachedMessages extends ActorTest { + import EventServiceCacheSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithCacheAndSupport" should { + "send cache-able messages within a time span, separated if they are part of different caches" in { + val mainProbe = TestProbe("MainProbe") + val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.5") + events.tell(Service.Join("test"), mainProbe.ref) + val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) + //first cache flush + events ! firstMessage + mainProbe.expectNoMessage(50 milliseconds) + val firstReply = mainProbe.receiveOne(125 milliseconds) + firstReply match { + case msg if msg == firstMessage => () + case badmsg => + assert(false, s"(8) expected delivery of test envelope, but received $badmsg instead") + } + mainProbe.expectNoMessage(100 milliseconds) + //second cache flush + val secondMessage = CachedEnvelope(PlanetSideGUID(2), "test", TestMessage(2)) + events ! secondMessage + mainProbe.expectNoMessage(50 milliseconds) + val reply = mainProbe.receiveOne(125 milliseconds) + reply match { + case msg if msg == secondMessage => () + case badmsg => + assert(false, s"(9) expected delivery of test envelope, but received $badmsg instead") + } + } + } +} + +class EventServiceCacheSupportTestSupportDelayed extends ActorTest { + import EventServiceCacheSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithCacheAndSupport" should { + "cache a message for a support actor, but only dispatch that message to the support actor when flushing the cache" in { + val mainProbe = TestProbe("MainProbe") + val supportProbe = TestProbe("SupportProbe") + val events = system.actorOf(Props(classOf[TestCacheService], List(TestSupportActorLoader)), name = "EventServiceCacheSupportTest.6") + events.tell(Service.Join("test"), mainProbe.ref) + val originalMessage = CachedSupportTestEnvelope( + PlanetSideGUID(1), + "test", + TestMessage(1), + SupportActorRepliesWith("hello world", supportProbe.ref) + ) + events ! originalMessage + //main reply + supportProbe.expectNoMessage(50 milliseconds) + mainProbe.expectNoMessage(10 milliseconds) + val mainReply = mainProbe.receiveOne(125 milliseconds) + mainReply match { + case msg if msg == originalMessage => () + case badmsg => + assert(false, s"(10) expected delivery of test envelope, but received $badmsg instead") + } + //support reply + val supportReply = supportProbe.receiveOne(10 milliseconds) + supportReply match { + case msg: String if msg.equals("hello world") => () + case badmsg => + assert(false, s"(11) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead") + } + } + } +} diff --git a/src/test/scala/service/base/EventServiceSupportTest.scala b/src/test/scala/service/base/EventServiceSupportTest.scala new file mode 100644 index 000000000..1b61e6eaf --- /dev/null +++ b/src/test/scala/service/base/EventServiceSupportTest.scala @@ -0,0 +1,133 @@ +// Copyright (c) 2026 PSForever +package service.base + +import akka.actor.Props +import akka.testkit.TestProbe +import base.ActorTest +import net.psforever.services.Service +import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericSupportEnvelopeOnly} + +import scala.concurrent.duration._ + +object EventServiceSupportTest { + class TestSupportService(eventSupportServices: List[EventServiceSupport]) + extends GenericEventServiceWithSupport(EventServiceTestBase.TestStamp, eventSupportServices) + + final case class TestSupportOnlyEnvelope(supportLabel: String, supportMessage: EventServiceTestBase.SupportActorRepliesWith) + extends GenericSupportEnvelopeOnly +} + +class EventServiceSupportTestDefault extends ActorTest { + import EventServiceSupportTest._ + "GenericEventServiceWithSupport" should { + "construct" in { + system.actorOf(Props(classOf[TestSupportService], List()), name = "EventServiceSupportTest.0") + } + } +} + +class EventServiceSupportTestLoadSupportClass extends ActorTest { + import EventServiceSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithSupport" should { + "construct with setting up a test support class" in { + system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.1") + } + } +} + +class EventServiceSupportTestSendToSupportClass extends ActorTest { + import EventServiceSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithSupport" should { + "send a valid message to both subscribed channel and support class" in { + val mainProbe = TestProbe("MainProbe") + val supportProbe = TestProbe("SupportProbe") + val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.2") + events.tell(Service.Join("test"), mainProbe.ref) + val originalMessage = TestSupportEnvelope("test", SupportActorRepliesWith("hello world", supportProbe.ref)) + events ! originalMessage + //main reply + val mainReply = mainProbe.receiveOne(250 milliseconds) + mainReply match { + case msg if msg == originalMessage => () + case badmsg => + assert(false, s"(1) expected delivery of test envelope, but received $badmsg instead") + } + //support reply + val supportReply = supportProbe.receiveOne(250 milliseconds) + supportReply match { + case msg: String if msg.equals("hello world") => () + case badmsg => + assert(false, s"(2) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead") + } + } + } +} + +class EventServiceSupportTestSendToSupportClassOnly1 extends ActorTest { + import EventServiceSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithSupport" should { + "send a valid message to support class (but not to subscribed channel)" in { + val mainProbe = TestProbe("MainProbe") + val supportProbe = TestProbe("SupportProbe") + val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.3") + events.tell(Service.Join("test"), mainProbe.ref) + val originalMessage = TestSupportEnvelope("notatest", SupportActorRepliesWith("hello world", supportProbe.ref)) + events ! originalMessage + //main reply (no reply) + mainProbe.expectNoMessage(500 milliseconds) + //support reply + val supportReply = supportProbe.receiveOne(250 milliseconds) + supportReply match { + case msg: String if msg.equals("hello world") => () + case badmsg => + assert(false, s"(3) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead") + } + } + } +} + +class EventServiceSupportTestSendToSupportClassOnly2 extends ActorTest { + import EventServiceSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithSupport" should { + "send a valid message to support class (skip subscribed channel)" in { + val mainProbe = TestProbe("MainProbe") + val supportProbe = TestProbe("SupportProbe") + val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.4") + events.tell(Service.Join("test"), mainProbe.ref) + val originalMessage = TestSupportOnlyEnvelope("supportActor", SupportActorRepliesWith("hello world", supportProbe.ref)) + events ! originalMessage + //main reply (no reply) + mainProbe.expectNoMessage(500 milliseconds) + //support reply + val supportReply = supportProbe.receiveOne(250 milliseconds) + supportReply match { + case msg: String if msg.equals("hello world") => () + case badmsg => + assert(false, s"(4) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead") + } + } + } +} + +class EventServiceSupportTestSendToNoOne extends ActorTest { + import EventServiceSupportTest._ + import EventServiceTestBase._ + "GenericEventServiceWithSupport" should { + "send a valid message that neither support class nor subscribed channel handle" in { + val mainProbe = TestProbe("MainProbe") + val supportProbe = TestProbe("SupportProbe") + val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.5") + events.tell(Service.Join("test"), mainProbe.ref) + val originalMessage = TestSupportOnlyEnvelope("notASupportActor", SupportActorRepliesWith("hello world", supportProbe.ref)) + events ! originalMessage + //main reply (no reply) + mainProbe.expectNoMessage(500 milliseconds) + //support reply (no reply) + supportProbe.expectNoMessage(500 milliseconds) + } + } +} diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala new file mode 100644 index 000000000..91c60031d --- /dev/null +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -0,0 +1,199 @@ +// Copyright (c) 2026 PSForever +package service.base + +import akka.actor.Props +import akka.testkit.TestProbe +import base.ActorTest +import net.psforever.services.Service +import net.psforever.services.base.GenericEventService +import net.psforever.services.base.envelope.GenericResponseEnvelope + +import scala.concurrent.duration._ + +object EventServiceTest { + class TestService() extends GenericEventService(EventServiceTestBase.TestStamp) +} + +class EventServiceTestDefault extends ActorTest { + import EventServiceTest._ + "GenericEventSystem" should { + "construct" in { + system.actorOf(Props[TestService](), name = "EventServiceTest.0") + } + } +} + +class EventServiceTest1 extends ActorTest { + import EventServiceTest._ + "GenericEventSystem" should { + "be subscribed to by channel name" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.1") + events.tell(Service.Join("test"), probe.ref) + probe.expectNoMessage(100 milliseconds) + } + } +} + +class EventServiceTest2 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "receive messages from a subscribed channel" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.2") + events.tell(Service.Join("test"), probe.ref) + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + probe.receiveN(1, 100 milliseconds) + } + } +} + +class EventServiceTest3 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "receive messages that are responses to the original message from a subscribed channel" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.3") + val msg = MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + // s => "/$s" is the default channel manipulation of the event system + val formalReply = msg.response(EventServiceTestBase.TestStamp, s => "/$s") + events.tell(Service.Join("test"), probe.ref) + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + val reply = probe.receiveOne(100 milliseconds) + assert(reply == formalReply, "(1) message expected but not received format") + } + } +} + +class EventServiceTest4 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "not receive messages from an unsubscribed channel" in { + val probe = TestProbe("testProbe") + val missedProbe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.4") + events.tell(Service.Join("test"), probe.ref) + events.tell(Service.Join("notATest"), missedProbe.ref) + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + val reply = probe.receiveOne(100 milliseconds) + reply match { + case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case _ => assert(false, "(2) message expected but not received") + } + missedProbe.expectNoMessage(100 milliseconds) + } + } +} + +class EventServiceTest5 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "ignore unexpected messages" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.5") + events.tell(Service.Join("test"), probe.ref) + events ! TestMessage(5) + probe.expectNoMessage(250 milliseconds) + //the warn log should show something + } + } +} + +class EventServiceTest6 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "leave single channels" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.6") + events.tell(Service.Join("test"), probe.ref) + events.tell(Service.Join("anotherTest"), probe.ref) + + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(5)) + val reply1 = probe.receiveN(2, 100 milliseconds) + reply1.head match { + case GenericResponseEnvelope("/test", _, _) => () + case _ => assert(false, "(3) message expected but not received") + } + reply1(1) match { + case GenericResponseEnvelope("/anotherTest", _, _) => () + case _ => assert(false, "(4) message expected but not received") + } + + events.tell(Service.Leave(Some("anotherTest")), probe.ref) + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + val reply2 = probe.receiveOne(100 milliseconds) + reply2 match { + case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case _ => assert(false, "(5) message expected but not received") + } + probe.expectNoMessage(250 milliseconds) + } + } +} + +class EventServiceTest7 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "leave all channels (1)" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.7") + events.tell(Service.Join("test"), probe.ref) + events.tell(Service.Join("anotherTest"), probe.ref) + + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + val reply = probe.receiveN(2,100 milliseconds) + reply.head match { + case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case _ => assert(false, "(6) message expected but not received") + } + reply(1) match { + case GenericResponseEnvelope("/anotherTest", _, TestMessage(6)) => () + case _ => assert(false, "(7) message expected but not received") + } + + events.tell(Service.Leave(), probe.ref) + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + probe.expectNoMessage(250 milliseconds) + } + } +} + +class EventServiceTest8 extends ActorTest { + import EventServiceTest._ + import EventServiceTestBase._ + "GenericEventSystem" should { + "leave all channels" in { + val probe = TestProbe("testProbe") + val events = system.actorOf(Props[TestService](), name = "EventServiceTest.8") + events.tell(Service.Join("test"), probe.ref) + events.tell(Service.Join("anotherTest"), probe.ref) + + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + val reply = probe.receiveN(2,100 milliseconds) + reply.head match { + case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case _ => assert(false, "(6) message expected but not received") + } + reply(1) match { + case GenericResponseEnvelope("/anotherTest", _, TestMessage(6)) => () + case _ => assert(false, "(7) message expected but not received") + } + + events.tell(Service.LeaveAll(), probe.ref) + events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + probe.expectNoMessage(250 milliseconds) + } + } +} diff --git a/src/test/scala/service/base/EventServiceTestBase.scala b/src/test/scala/service/base/EventServiceTestBase.scala new file mode 100644 index 000000000..f5ac013d7 --- /dev/null +++ b/src/test/scala/service/base/EventServiceTestBase.scala @@ -0,0 +1,39 @@ +package service.base + +import akka.actor.{Actor, ActorContext, ActorRef, Props} +import net.psforever.services.Service +import net.psforever.services.base.message.SelfRespondingEvent +import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericSupportEnvelope} +import net.psforever.types.PlanetSideGUID + +object EventServiceTestBase { + case object TestStamp extends EventSystemStamp + + final case class TestMessage(value: Int) extends SelfRespondingEvent + + final case class SupportActorRepliesWith(msg: String, sendTo: ActorRef) extends SelfRespondingEvent + + class TestSupportActor extends Actor { + def receive: Receive = { + case SupportActorRepliesWith(msg, sendTo) => + sendTo ! msg + case _ => () + } + } + + case object TestSupportActorLoader extends EventServiceSupport { + def label: String = "supportActor" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[TestSupportActor](), name = "supportActor") + } + } + + final case class TestSupportEnvelope( + originalChannel: String, + msg: SupportActorRepliesWith + ) extends GenericSupportEnvelope { + def filter: PlanetSideGUID = Service.defaultPlayerGUID + def supportLabel: String = "supportActor" + def supportMessage: Any = msg + } +} diff --git a/src/test/scala/service/local/LocalActionTest.scala b/src/test/scala/service/local/LocalActionTest.scala new file mode 100644 index 000000000..a929bd485 --- /dev/null +++ b/src/test/scala/service/local/LocalActionTest.scala @@ -0,0 +1,73 @@ +// Copyright (c) 2026 PSForever +package service.local + +import net.psforever.objects.{ExplosiveDeployable, GlobalDefinitions} +import net.psforever.packet.game.{ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation} +import net.psforever.services.Service +import net.psforever.services.base.message.SendResponse +import net.psforever.services.local.LocalAction +import net.psforever.types.{PlanetSideGUID, Vector3} +import org.specs2.mutable.Specification + +class LocalActionTest extends Specification { + "DeployItem" should { + assert(GlobalDefinitions.boomer != null, "missing definition - Boomer does not exist") + + "respond" in { + val obj = new ExplosiveDeployable(GlobalDefinitions.boomer) + obj.GUID = PlanetSideGUID(1) + val msg = LocalAction.DeployItem(obj) + val definition = obj.Definition + val objectData = definition.Packet.ConstructorData(obj).get + msg.response() match { + case SendResponse(packets) => + packets.head match { + case ObjectCreateMessage(_, oid, guid, _, data) => + oid mustEqual definition.ObjectId + guid mustEqual obj.GUID + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "TriggerEffect" should { + "respond" in { + val msg = LocalAction.TriggerEffect("on", PlanetSideGUID(1)) + msg.response() match { + case LocalAction.TriggerEffectAtLocation(PlanetSideGUID(1), "on", None, None) => + ok + case _ => + ko + } + } + } + + "TriggerEffectInfo" should { + "respond" in { + val msg = LocalAction.TriggerEffectInfo(PlanetSideGUID(1), "on", unk1 = true, unk2 = 10L) + msg.response() match { + case LocalAction.TriggerEffectAtLocation(PlanetSideGUID(1), "on", Some(TriggeredEffect(true, 10L)), None) => + ok + case _ => + ko + } + } + } + + "TriggerEffectLocation" should { + "respond" in { + val msg = LocalAction.TriggerEffectLocation("on", Vector3(1, 2, 3), Vector3(4, 5, 6)) + msg.response() match { + case LocalAction.TriggerEffectAtLocation(Service.defaultPlayerGUID, "on", None, Some(TriggeredEffectLocation(Vector3(1, 2, 3), Vector3(4, 5, 6)))) => + ok + case _ => + ko + } + } + } +} diff --git a/src/test/scala/service/vehicle/VehicleActionTest.scala b/src/test/scala/service/vehicle/VehicleActionTest.scala new file mode 100644 index 000000000..f028ab38a --- /dev/null +++ b/src/test/scala/service/vehicle/VehicleActionTest.scala @@ -0,0 +1,102 @@ +// Copyright (c) 2026 PSForever +package service.vehicle + +import net.psforever.objects.zones.{Zone, ZoneMap} +import net.psforever.objects.{GlobalDefinitions, Tool, Vehicle} +import net.psforever.packet.game.ObjectCreateMessage +import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent +import net.psforever.services.vehicle.VehicleAction +import net.psforever.types.{DriveState, PlanetSideGUID} +import org.specs2.mutable.Specification + +object VehicleActionTest { + assert(GlobalDefinitions.quadstealth != null, "missing definition - quadstealth does not exist") + assert(GlobalDefinitions.ams_respawn_tube != null, "missing definition - ams_respawn_tube does not exist") + assert(GlobalDefinitions.ams != null, "missing definition - AMS does not exist") + + final val testZone: Zone = { + var i = 1 + val notAms = new Vehicle(GlobalDefinitions.quadstealth) + notAms.GUID = PlanetSideGUID(i) + notAms.Health = 1 + i += 1 + val ams = new Vehicle(GlobalDefinitions.ams) + ams.Health = 1 + ams.GUID = PlanetSideGUID(i) + i += 1 + ams.Utilities.values.foreach { utility => + utility.apply().GUID = PlanetSideGUID(i) + i += 1 + } + ams.DeploymentState = DriveState.Deployed + new Zone(id = "test", new ZoneMap( name = "test"), zoneNumber = 1) { + override def Vehicles: List[Vehicle] = List(notAms, ams) + } + } +} + +class VehicleActionTest extends Specification { + import VehicleActionTest._ + + "EquipmentInSlot" should { + assert(GlobalDefinitions.suppressor != null, "missing definition - Suppressor does not exist") + + "respond" in { + var i = 1 + val obj = new Tool(GlobalDefinitions.suppressor) + obj.GUID = PlanetSideGUID(i) + i += 1 + obj.AmmoSlots.map(_.Box).foreach { box => + box.GUID = PlanetSideGUID(i) + i += 1 + } + val msg = VehicleAction.EquipmentInSlot(PlanetSideGUID(1), 2, obj) + val definition = obj.Definition + val objectData = definition.Packet.ConstructorData(obj).get + msg.response() match { + case VehicleAction.EquipmentCreatedInSlot(packets) => + packets match { + case ObjectCreateMessage(_, oid, guid, pdata, data) => + oid mustEqual definition.ObjectId + guid mustEqual obj.GUID + pdata.contains(ObjectCreateMessageParent(PlanetSideGUID(1), 2)) mustEqual true + data mustEqual objectData + case _ => + ko + } + case _ => + ko + } + } + } + + "UpdateAmsSpawnPoint" should { + "respond" in { + testZone.Vehicles.size mustEqual 2 + val msg = VehicleAction.UpdateAmsSpawnPoint(testZone) + msg.response() match { + case VehicleAction.UpdateAmsSpawnList(list) => + list.size mustEqual 1 + list.head.Definition mustEqual GlobalDefinitions.ams_respawn_tube + list.head.Owner.Definition mustEqual GlobalDefinitions.ams + case _ => + ko + } + } + } + + "AMSDeploymentChange" should { + "respond" in { + testZone.Vehicles.size mustEqual 2 + val msg = VehicleAction.AMSDeploymentChange(testZone) + msg.response() match { + case VehicleAction.UpdateAmsSpawnList(list) => + list.size mustEqual 1 + list.head.Definition mustEqual GlobalDefinitions.ams_respawn_tube + list.head.Owner.Definition mustEqual GlobalDefinitions.ams + case _ => + ko + } + } + } +} From 40d5721914b41bfa2aa7745de7d505316beeeff2 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 2 Mar 2026 20:35:08 -0500 Subject: [PATCH 13/32] mostly, comments for the event system files; the event system stamp now determines how the out channel forms; some case class entities have become case object entities --- .../actor/service/AvatarServiceTest.scala | 4 +- .../actors/session/csr/ChatLogic.scala | 2 +- .../session/normal/LocalHandlerLogic.scala | 6 +- .../session/normal/VehicleHandlerLogic.scala | 2 +- .../session/support/GeneralOperations.scala | 2 +- .../actors/session/support/SessionData.scala | 10 +- .../session/support/ZoningOperations.scala | 16 ++-- .../serverobject/painbox/PainboxControl.scala | 2 +- .../resourcesilo/ResourceSiloControl.scala | 2 +- .../shuttle/OrbitalShuttlePadControl.scala | 2 +- .../terminals/ProximityTerminal.scala | 2 +- .../net/psforever/objects/zones/Zone.scala | 6 +- .../net/psforever/services/Service.scala | 6 +- .../account/AccountPersistenceService.scala | 2 +- .../services/base/GenericEventService.scala | 71 ++++++++++---- ...nericEventServiceWithCacheAndSupport.scala | 92 ++++++++++++++++--- .../base/GenericEventServiceWithSupport.scala | 54 ++++++++++- .../services/base/bus/GenericEventBus.scala | 27 ++++-- .../services/base/envelope/AllEnvelopes.scala | 6 ++ .../envelope/GenericMessageEnvelope.scala | 13 ++- .../envelope/GenericResponseEnvelope.scala | 25 ++++- .../base/envelope/MessageEnvelope.scala | 35 +++++-- .../services/galaxy/GalaxyService.scala | 14 +-- .../services/teamwork/SquadService.scala | 10 +- .../scala/objects/OrbitalShuttlePadTest.scala | 2 +- src/test/scala/objects/ResourceSiloTest.scala | 16 ++-- .../objects/terminal/ProximityTest.scala | 8 +- .../base/EventServiceCacheSupportTest.scala | 4 +- .../scala/service/base/EventServiceTest.scala | 6 +- 29 files changed, 331 insertions(+), 116 deletions(-) diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala index 520398554..2a4c47777 100644 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ b/server/src/test/scala/actor/service/AvatarServiceTest.scala @@ -46,7 +46,7 @@ class AvatarService3Test extends ActorTest { "subscribe to a specific channel" in { val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! Service.Leave() + service ! Service.LeaveAll assert(true) } } @@ -58,7 +58,7 @@ class AvatarService4Test extends ActorTest { ServiceManager.boot(system) val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) service ! Service.Join("test") - service ! Service.LeaveAll() + service ! Service.LeaveAll assert(true) } } diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index 2825c0554..eb02a7a29 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -332,7 +332,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext val channel = player.Name val events = continent.AvatarEvents seeSpectatorsIn = None - events ! Service.Leave(Some("spectator")) + events ! Service.Leave("spectator") continent .AllPlayers .filter(_.spectator) 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 93421ec75..23d34208f 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -250,9 +250,9 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act //todo we might be able to piggyback this for squad recalls later if(session.zone eq zone) { sessionLogic.zoning.zoneReload = true - zone.AvatarEvents ! Service.Leave() - zone.LocalEvents ! Service.Leave() - zone.VehicleEvents ! Service.Leave() + zone.AvatarEvents ! Service.LeaveAll + zone.LocalEvents ! Service.LeaveAll + zone.VehicleEvents ! Service.LeaveAll zone.AvatarEvents ! Service.Join(player.Name) //must manually restore this subscriptions sessionLogic.zoning.spawn.handleNewPlayerLoaded(player) //will restart subscriptions and dispatch a LoadMapMessage } else { 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 821625483..f40fc771a 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -232,7 +232,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget => sessionLogic.zoning.interstellarFerry = Some(vehicle) sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) - continent.VehicleEvents ! Service.Leave(Some(oldChannel)) //old vehicle-specific channel (was s"${vehicle.Actor}") + continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}") galaxyService ! Service.Join(tempChannel) //temporary vehicle-specific channel log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating") diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 2b19df496..01befe7c9 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -743,7 +743,7 @@ class GeneralOperations( * @param channel the channel name */ private def unaccessContainerChannel(events: ActorRef, channel: String): Unit = { - events ! Service.Leave(Some(channel)) + events ! Service.Leave(channel) } /** 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 cf17f9a4a..f5c8c95cc 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -616,12 +616,12 @@ class SessionData( squadResponseOpt.foreach(_.stop()) zoningOpt.foreach(_.stop()) chatOpt.foreach(_.stop()) - continent.AvatarEvents ! Service.Leave() - continent.LocalEvents ! Service.Leave() - continent.VehicleEvents ! Service.Leave() - galaxyService ! Service.Leave() + continent.AvatarEvents ! Service.LeaveAll + continent.LocalEvents ! Service.LeaveAll + continent.VehicleEvents ! Service.LeaveAll + galaxyService ! Service.LeaveAll if (avatar != null && squadService != Default.Actor) { - squadService ! Service.Leave() + squadService ! Service.LeaveAll } } } diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 478704782..00ffaf3e5 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -620,9 +620,9 @@ class ZoningOperations( //the only zone-level event system subscription necessary before BeginZoningMessage (for persistence purposes) zone.AvatarEvents ! Service.Join(player.Name) sessionLogic.persist() - oldZone.AvatarEvents ! Service.Leave() - oldZone.LocalEvents ! Service.Leave() - oldZone.VehicleEvents ! Service.Leave() + oldZone.AvatarEvents ! Service.LeaveAll + oldZone.LocalEvents ! Service.LeaveAll + oldZone.VehicleEvents ! Service.LeaveAll if (player.isAlive && zoningType != Zoning.Method.Reset) { if (player.HasGUID) { @@ -651,9 +651,9 @@ class ZoningOperations( val oldZone = session.zone session = session.copy(zone = foundZone) sessionLogic.persist() - oldZone.AvatarEvents ! Service.Leave() - oldZone.LocalEvents ! Service.Leave() - oldZone.VehicleEvents ! Service.Leave() + oldZone.AvatarEvents ! Service.LeaveAll + oldZone.LocalEvents ! Service.LeaveAll + oldZone.VehicleEvents ! Service.LeaveAll //the only zone-level event system subscription necessary before BeginZoningMessage (for persistence purposes) foundZone.AvatarEvents ! Service.Join(player.Name) foundZone.Population ! Zone.Population.Join(avatar) @@ -762,7 +762,7 @@ class ZoningOperations( case _ => interstellarFerry match { case None => - galaxyService ! Service.Leave(Some(temp_channel)) //no longer being transferred between zones + galaxyService ! Service.Leave(temp_channel) //no longer being transferred between zones interstellarFerryTopLevelGUID = None case Some(_) => () //wait patiently } @@ -770,7 +770,7 @@ class ZoningOperations( } private def handleTransferPassengerVehicle(vehicle: Vehicle, temporaryChannel: String): Unit = { - galaxyService ! Service.Leave(Some(temporaryChannel)) //temporary vehicle-specific channel (see above) + galaxyService ! Service.Leave(temporaryChannel) //temporary vehicle-specific channel (see above) spawn.deadState = DeadState.Release sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, player.Faction, unk5=true)) interstellarFerry = Some(vehicle) //on the other continent and registered to that continent's GUID system diff --git a/src/main/scala/net/psforever/objects/serverobject/painbox/PainboxControl.scala b/src/main/scala/net/psforever/objects/serverobject/painbox/PainboxControl.scala index 4e673d621..b246a6edb 100644 --- a/src/main/scala/net/psforever/objects/serverobject/painbox/PainboxControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/painbox/PainboxControl.scala @@ -59,7 +59,7 @@ class PainboxControl(painbox: Painbox) extends PoweredAmenityControl { } var commonBehavior: Receive = { - case Service.Startup() => + case Service.Startup => if (!disabled && domain.midpoint == Vector3.Zero) { initialStartup() } diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 3427690d1..c9a2104ff 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -40,7 +40,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) private var drainMultiplier: Float = 1.0f def receive: Receive = { - case Service.Startup() => + case Service.Startup => resourceSilo.Owner match { case building: Building => UpdateChargeLevel(amount = 0) diff --git a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala index 9f2002da2..2d9cc5e29 100644 --- a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala @@ -106,7 +106,7 @@ class OrbitalShuttlePadControl(pad: OrbitalShuttlePad) extends Actor { * register and add the shuttle as a common vehicle of the said zone */ val startUp: Receive = { - case Service.Startup() => + case Service.Startup => import net.psforever.types.Vector3 import net.psforever.types.Vector3.DistanceSquared import net.psforever.objects.GlobalDefinitions._ diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala index ad700fbbe..e4e33b2aa 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminal.scala @@ -83,7 +83,7 @@ object ProximityTerminal { if (obj.Actor == Default.Actor) { obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj)) - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup } } } diff --git a/src/main/scala/net/psforever/objects/zones/Zone.scala b/src/main/scala/net/psforever/objects/zones/Zone.scala index 1c1336090..fe31facf5 100644 --- a/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -1718,14 +1718,14 @@ object Zone { .flatMap(_.Amenities.filter(_.Definition == GlobalDefinitions.resource_silo)) .collect { case silo: ResourceSilo => - silo.Actor ! Service.Startup() + silo.Actor ! Service.Startup } //some painfields need to look for their closest door buildings.values .flatMap(_.Amenities.filter(_.Definition.isInstanceOf[PainboxDefinition])) .collect { case painbox: Painbox => - painbox.Actor ! Service.Startup() + painbox.Actor ! Service.Startup } //the orbital_buildings in sanctuary zones have to establish their shuttle routes map.shuttleBays @@ -1733,7 +1733,7 @@ object Zone { guid(_) } .collect { case Some(obj: OrbitalShuttlePad) => - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup } //allocate soi information zone.soi ! SOI.Build() diff --git a/src/main/scala/net/psforever/services/Service.scala b/src/main/scala/net/psforever/services/Service.scala index a8b9c9bbe..0bca3a02d 100644 --- a/src/main/scala/net/psforever/services/Service.scala +++ b/src/main/scala/net/psforever/services/Service.scala @@ -7,7 +7,7 @@ import net.psforever.types.PlanetSideGUID object Service { final val defaultPlayerGUID: PlanetSideGUID = PlanetSideGUID(0) - final case class Startup() + case object Startup final case class Join(channel: String, sendJoinConfirmation: Boolean) @@ -17,7 +17,7 @@ object Service { final case class JoinConfirmation(eventSystem: ActorRef, channel: String) - final case class Leave(channel: Option[String] = None) + final case class Leave(channel: String) - final case class LeaveAll() + case object LeaveAll } diff --git a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala index 94274bfb0..69b01c40d 100644 --- a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala +++ b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala @@ -453,7 +453,7 @@ class PersistenceMonitor( */ def AvatarLogout(avatar: Avatar): Unit = { LivePlayerList.Remove(avatar.id) - squadService.tell(Service.Leave(Some(avatar.id.toString)), context.parent) + squadService.tell(Service.Leave(avatar.id.toString), context.parent) galaxyService.tell(GalaxyServiceMessage(GalaxyAction.LogStatusChange(avatar.name)), context.parent) Deployables.Disown(inZone, avatar, context.parent) inZone.Population.tell(Zone.Population.Leave(avatar), context.parent) diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 202f08d7c..46ca88af6 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -4,42 +4,78 @@ package net.psforever.services.base import akka.actor.Actor import net.psforever.services.Service import net.psforever.services.base.bus.GenericEventBus -import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope} +import net.psforever.services.base.envelope.GenericMessageEnvelope import org.log4s.Logger -trait EventSystemStamp +/** + * A distinct tag associated with an event system. + * The stamp is intended to demonstrate that the input message has been interpreted into an output response + * through actual use of an event system + * and that the response has not been fabricated and is not fraudulent. + * While the word "stamp" more probably calls to mind the concept of a postage stamp, + * the purpose of this artifact is closer to that of the routing information + * stamped onto an envelope over the postage stamp area of a letter. + */ +trait EventSystemStamp { + /* + Example Classifiers: "foo", "foo.fizz", and "foo.buzz" + In general, Classifier channels will perform left-pattern matching. + "foo" will publish to "foo", "foo.fizz", and "foo.buzz" + To isolate "foo", one must distinguish it with a right-pattern. + "foo" is appended as "foo.bar" and no longer publishes to "foo.fizz.bar" or to "foo.buzz.bar" + */ + /** + * Take an input channel and produce the publishing output channel. + * @param channel publishing channel + * @return appended publishing channel + */ + def routing(channel: String): String = s"/$channel/out" +} +/** + * Basic opt-in event response relay system. + * Remembers "subscribers" (`ActorRef`) to "channels" (`String`); + * accepts "messages" (`GenericMessageEnvelope`) and interprets the message as a response (`GenericResponseEnvelope`); + * and, dispatches the response to all subscribers associated with the channel provided in the message. + * @param stamp distinct tag associated with an event system + */ abstract class GenericEventService(stamp: EventSystemStamp) extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) protected val eventBus: GenericEventBus = new GenericEventBus + /** + * Add subscription handling. + */ private def commonJoinBehavior: Receive = { case Service.Join(channel, true) => - val path = formatChannel(channel) + val path = stamp.routing(channel) val who = sender() eventBus.subscribe(who, path) who ! Service.JoinConfirmation(self, channel) case Service.Join(channel, _) => - val path = formatChannel(channel) + val path = stamp.routing(channel) val who = sender() eventBus.subscribe(who, path) } + /** + * Remove subscription handling. + */ private def commonLeaveBehavior: Receive = { - case Service.Leave(None) => + case Service.LeaveAll => eventBus.unsubscribe(sender()) - case Service.Leave(Some(channel)) => - val path = formatChannel(channel) + case Service.Leave(channel) => + val path = stamp.routing(channel) eventBus.unsubscribe(sender(), path) - - case Service.LeaveAll() => - eventBus.unsubscribe(sender()) } + /** + * Accept and handle designated messages. + */ protected def commonBehavior: Receive = { case msg: GenericMessageEnvelope => handleMessage(msg) @@ -53,13 +89,12 @@ abstract class GenericEventService(stamp: EventSystemStamp) log.warn(s"Unhandled message $msg from ${sender()}") } - protected def handleMessage(msg: GenericMessageEnvelope): Unit = { - eventBus.publish(composeResponseEnvelope(msg)) + /** + * Handle designated messages. + * Interpret the input message as an output response and publish that response. + * @param event event system message + */ + protected def handleMessage(event: GenericMessageEnvelope): Unit = { + eventBus.publish(event.response(stamp)) } - - protected def composeResponseEnvelope(msg: GenericMessageEnvelope): GenericResponseEnvelope = { - msg.response(stamp, formatChannel) - } - - protected def formatChannel(channel: String): String = s"/$channel" } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index ce73b3d00..89f2474f4 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -18,21 +18,36 @@ import scala.concurrent.duration.DurationInt Adapted from the rating limiting code in PSForever fork https://github.com/Pinapse/giant with permission */ -trait CachedGenericEventMessageEnvelope +/** + * A framework for flagged messages to be cached + * based on designation of a target globally unique identifier. + * Suggestion: this identifier be associated with the source. + */ +trait CachedGenericEventEnvelope extends MessageTransformationBehavior { + /** cache designator */ def guid: PlanetSideGUID } final case class CachedEnvelope( guid: PlanetSideGUID, originalChannel: String, - override val filter: PlanetSideGUID, - override val msg: EventMessage - ) extends CachedGenericEventMessageEnvelope { + filter: PlanetSideGUID, + msg: EventMessage + ) extends CachedGenericEventEnvelope { assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") } object CachedEnvelope { + /** + * If the filter is specified, but not the cache target, treat the filter like the cache target. + * Treat invalid values as a reason to downgrade from a cached message envelope to a traditional message envelope. + * Warn of this downgrade.e + * @param channel set of subscribers on an event system bus the envelope should reach + * @param filter specific subscriber endpoint to be excluded (the subscriber should filter themselves) + * @param msg input payload transported by this envelope + * @return either a `CacheEnvelope` or a `MessageEnvelope`, depending on cache-readiness of the `filter` value + */ def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { if (filter == Service.defaultPlayerGUID) { org.log4s.getLogger("CachedEnvelope").warn("(1) cached message envelope downgraded to normal message envelope") @@ -42,20 +57,37 @@ object CachedEnvelope { } } + /** + * If the cache target is specified, but is not valid, + * downgrade from a cached message envelope to a traditional message envelope. + * Warn of this downgrade. + * If valid, the filter becomes its defaulted value in the corresponding message + * @param guid cache designator + * @param channel set of subscribers on an event system bus the envelope should reach + * @param msg input payload transported by this envelope + * @return either a `CacheEnvelope` or a `MessageEnvelope`, depending on cache-readiness of the target + */ def apply(guid: PlanetSideGUID, channel: String, msg: EventMessage): GenericMessageEnvelope = { if (guid == Service.defaultPlayerGUID) { org.log4s.getLogger("CachedEnvelope").warn("(2) cached message envelope downgraded to normal message envelope") MessageEnvelope(channel, guid, msg) } else { - CachedEnvelope(guid, channel, guid, msg) + CachedEnvelope(guid, channel, Service.defaultPlayerGUID, msg) } } } +/** + * An internal message for the purpose of forcing cached messages to be flushed. + * All of it's fields default to harmless values because it is not intended to be processed by an event system + * but it must maintain the trappings of a message envelope to be processed. + * @see `NoMessage` + * @see `NoResponseEnvelope` + */ private case object FlushCachedMessages extends GenericMessageEnvelope { def originalChannel: String = "" def msg: EventMessage = NoMessage - def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope = NoResponseEnvelope + def response(stamp: EventSystemStamp): GenericResponseEnvelope = NoResponseEnvelope def channel: String = "" def filter: PlanetSideGUID = Service.defaultPlayerGUID } @@ -65,7 +97,7 @@ abstract class GenericEventServiceWithCacheAndSupport stamp: EventSystemStamp, eventSupportServices: List[EventServiceSupport] ) extends GenericEventServiceWithSupport(stamp, eventSupportServices) { - private val flushCacheWait: Long = 50 //milliseconds + private val flushCacheWait: Long = 50L //milliseconds private var hasCachedMessages: Boolean = false private var nextTimeToFlushCache: Long = 0L private var emergencyFlush: Cancellable = Default.Cancellable @@ -78,6 +110,12 @@ abstract class GenericEventServiceWithCacheAndSupport super.postStop() } + /** + * If there were previously no messages in the cache, + * prepare to flush the cache after the intended interval passes, + * whether the passing of that interval is detected by a new incoming message and the cache gets flushed naturally, + * or if a safety timer expires and the cache is flushed in precaution. + */ private def tryRetimeFlushCache(): Unit = { if (!hasCachedMessages) { hasCachedMessages = true @@ -86,7 +124,14 @@ abstract class GenericEventServiceWithCacheAndSupport } } - private def pushToCache(event: CachedGenericEventMessageEnvelope): Unit = { + /** + * Add messages to the cache based on their channel, then their type, then their cache target identifier. + * Messages that arrive with the same cache profile as a previous message, + * but before that previous message was dispatched, + * will overwrite the previous message without fanfare or warning. + * @param event event system message + */ + private def pushToCache(event: CachedGenericEventEnvelope): Unit = { val eventClassName = event.msg.getClass.getName val updateBranch = cache .getOrElseUpdate(event.channel, new ConcurrentHashMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]().asScala) @@ -95,12 +140,22 @@ abstract class GenericEventServiceWithCacheAndSupport tryRetimeFlushCache() } - private def tryFlushCache(): Unit = { - if (hasCachedMessages && nextTimeToFlushCache < System.currentTimeMillis()) { + /** + * If the cache has messages and the current time exceeds the anticipated flush time, + * flush the cache messages to the normal event system bus. + */ + private def tryFlushCache(): Boolean = { + val willFLush = hasCachedMessages && nextTimeToFlushCache < System.currentTimeMillis() + if (willFLush) { flushCache() } + willFLush } + /** + * Flush the cache messages to the normal event system bus. + * Clear old messages then reset all flags that would force the messages to be flushed. + */ private def flushCache(): Unit = { cache.foreachEntry { (_, map) => map.foreachEntry { (_, map) => @@ -115,15 +170,24 @@ abstract class GenericEventServiceWithCacheAndSupport emergencyFlush = Default.Cancellable } + /** + * If the cache will be flushed after this message, flush the cache and then pass the message for processing. + * If the cache will not be flushed, add the message to the cache. + * In any case, procedure should always be ready to flush the cache when a message is received. + * If there is a support actor involved with a cached message, it is resolved when the message is flushed. + * @param event event system message that may be cached + */ override protected def handleMessage(event: GenericMessageEnvelope): Unit = { event match { - case envelope: CachedGenericEventMessageEnvelope => - pushToCache(envelope) case FlushCachedMessages => - tryFlushCache() + flushCache() + case _: CachedGenericEventEnvelope if tryFlushCache() => + super.handleMessage(event) + case envelope: CachedGenericEventEnvelope => + pushToCache(envelope) case _ => + tryFlushCache() super.handleMessage(event) } - tryFlushCache() } } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index c875f1d82..e0077fa55 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -9,8 +9,18 @@ import net.psforever.types.PlanetSideGUID import scala.annotation.unused +/** + * A message when there should be none, but a message is required to be defined anyway. + * @see `GenericSupportEnvelopeOnly` + */ case object NoMessage extends SelfRespondingEvent +/** + * A response when there should be none, but a response is required to be defined anyway. + * @see `GenericSupportEnvelopeOnly` + * @see `NoReply` + * @see `Undelivered` + */ case object NoResponseEnvelope extends GenericResponseEnvelope { def reply: EventResponse = NoReply def stamp: EventSystemStamp = Undelivered @@ -18,20 +28,39 @@ case object NoResponseEnvelope extends GenericResponseEnvelope { def filter: PlanetSideGUID = Service.defaultPlayerGUID } +/** + * A framework for how support actors are to be submitted to an event system. + * The bare bones are a label by which the support actor is identified for message routing, + * and a function that constructs the support actor within the context of the event system. + * @see `ActorContext` + */ trait EventServiceSupport { def label: String def constructor(@unused context: ActorContext): ActorRef } +/** + * A framework for communicating messages to support actors within an event system. + * The bare bones are a label by which the support actor is identified for message routing, + * and the message payload for the support actor to process. + * @see `ActorContext` + */ trait GenericMessageToSupport { def supportLabel: String def supportMessage: Any } +/** + * An envelope framework for communicating messages to support actors within an event system + * and also interacting with the event system directly. + */ trait GenericSupportEnvelope extends GenericMessageToSupport with MessageTransformationBehavior +/** + * An envelope framework for communicating messages to support actors within an event system only. + */ trait GenericSupportEnvelopeOnly extends GenericMessageToSupport with GenericMessageEnvelope { @@ -40,9 +69,17 @@ trait GenericSupportEnvelopeOnly def filter: PlanetSideGUID = Service.defaultPlayerGUID def msg: EventMessage = NoMessage - def response(@unused stamp: EventSystemStamp, @unused sendToChannel: String => String): GenericResponseEnvelope = NoResponseEnvelope + def response(@unused stamp: EventSystemStamp): GenericResponseEnvelope = NoResponseEnvelope } +/** + * Advanced opt-in event response relay system. + * Includes a system of specialized child actors that serve specific repeatable operations + * whose behaviors are intentionally synchronized on this event pipeline + * or whose collective operational overhead can be streamlined by reliance on a singular pipeline. + * @param stamp distinct tag associated with an event system + * @param eventSupportServices list of support actors to initialize + */ abstract class GenericEventServiceWithSupport ( stamp: EventSystemStamp, @@ -54,6 +91,12 @@ abstract class GenericEventServiceWithSupport .map { supportService => (supportService.label, supportService.constructor(context)) } .toMap[String, ActorRef] + /** + * Use the label assigned to a support actor + * to locate that support actor on this event system + * and forward to it a payload message. + * @param msg event system message carrying an additional message for a support actor + */ private def forwardToSupport(msg: GenericMessageToSupport): Unit = { supportServices .get(msg.supportLabel) @@ -66,15 +109,20 @@ abstract class GenericEventServiceWithSupport } } + /** + * If the message involves the support actor subsystem, forward the message to it for additional processing. + * Afterwards, or if not, merely call up to previously-established message handling if warranted. + * @param event event system message that may be carrying an additional message for a support actor + */ override protected def handleMessage(event: GenericMessageEnvelope): Unit = { event match { case msg: GenericSupportEnvelopeOnly => forwardToSupport(msg) case msg: GenericSupportEnvelope => forwardToSupport(msg) - eventBus.publish(composeResponseEnvelope(event)) + super.handleMessage(event) case event => - eventBus.publish(composeResponseEnvelope(event)) + super.handleMessage(event) } } } diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala index 26274d04e..b130d8eff 100644 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala @@ -5,6 +5,16 @@ import akka.event.{ActorEventBus, SubchannelClassification} import akka.util.Subclassification import net.psforever.services.base.envelope.GenericResponseEnvelope +/** + * Maintain a list of endpoints that have subscribed to a specific perspective + * internally called a `Classifier` and externally referred to as a "channel". + * When an `Event` - externally referred colloquially as a "message" - is received, + * to be published, + * match the "channel" to a list of known `Classifier` endpoints. + * Each of these `Subscribers` should receive the message. + * @see `GenericResponseEnvelope` + * @see `ActorEventBus.Subscriber` + */ class GenericEventBus extends ActorEventBus with SubchannelClassification { type Event = GenericResponseEnvelope @@ -12,6 +22,11 @@ class GenericEventBus protected def classify(event: Event): Classifier = event.channel + /* + Example Classifiers: "foo", "foo.fizz", and "foo.buzz" + In general, Classifier channels will perform left-pattern matching. + "foo" will publish to "foo", "foo.fizz", and "foo.buzz" + */ protected def subclassification: Subclassification[String] = new Subclassification[Classifier] { def isEqual(x: Classifier, y: Classifier): Boolean = x == y @@ -19,15 +34,11 @@ class GenericEventBus def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y) } + override def publish(event: Event): Unit = { + super[SubchannelClassification].publish(event) + } + protected def publish(event: Event, subscriber: Subscriber): Unit = { subscriber ! event } - - override def publish(event: Event): Unit = { - truePublish(event) - } - - def truePublish(event: Event): Unit = { - super[SubchannelClassification].publish(event) - } } diff --git a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala index 7ccf37fc2..aa737c55d 100644 --- a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala +++ b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala @@ -3,7 +3,13 @@ package net.psforever.services.base.envelope import net.psforever.types.PlanetSideGUID +/** + * Base of all envelope classes. + * Defines a channel and a filter, both of which server the purpose of routing the message to its destination. + */ trait AllEnvelopes { + /** set of subscribers on an event system bus the envelope should reach */ def channel: String + /** specific subscriber endpoint to be excluded (the subscriber should filter themselves) */ def filter: PlanetSideGUID } diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala index 8ca2f9995..d792ce4ec 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala @@ -7,12 +7,23 @@ import net.psforever.types.PlanetSideGUID trait GenericMessageEnvelope extends AllEnvelopes { + /** channel information provided with the message */ def originalChannel: String + /** input payload transported by this envelope */ def msg: EventMessage - def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope + /** method that counts as "processing" the envelope by an event system; + * the event system supplies their stamp and converts the message envelope into a response envelope; + * the input message is converted into a response message */ + def response(stamp: EventSystemStamp): GenericResponseEnvelope } object GenericMessageEnvelope { + /** + * The `unapply`ed data from a message envelope resembles the data from includes the filter and the channel information. + * The original channel information. + * @param obj response envelope + * @return a tuple containing the channel, filter, and reply message + */ def unapply(obj: GenericMessageEnvelope): Option[(String, PlanetSideGUID, EventMessage)] = { Some((obj.originalChannel, obj.filter, obj.msg)) } diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala index e0abe44c1..5b77aeca6 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala @@ -5,18 +5,37 @@ import net.psforever.services.base.EventSystemStamp import net.psforever.services.base.message.{EventMessage, EventResponse} import net.psforever.types.PlanetSideGUID +/** + * The framework of an event system envelope that is treated as the processed complement of a message envelope. + */ trait GenericResponseEnvelope extends AllEnvelopes { + /** result of converting the message envelope input payload into output payload */ def reply: EventResponse + /** marker indicating the routing through which the original message was processed */ def stamp: EventSystemStamp } object GenericResponseEnvelope { - def apply(stamp: EventSystemStamp, channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericResponseEnvelope ={ + /** + * Fake a response envelope, as if processed by a specific event system. + * @param stamp marker indicating the routing through which the original message was processed + * @param channel set of subscribers on an event system bus the envelope should reach + * @param filter a specific subscriber endpoint to be excluded + * @param msg input payload transported by this envelope + * @return a faked but typically acceptable response envelope + */ + def apply(stamp: EventSystemStamp, channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericResponseEnvelope = { val envelope = MessageEnvelope(channel, filter, msg) - envelope.response(stamp, s => s) + envelope.response(stamp) } - def unapply(obj: GenericResponseEnvelope): Option[(String, PlanetSideGUID, EventResponse)] = + /** + * The `unapply`ed data from a response envelope resembles the data from includes the filter and the channel information. + * @param obj response envelope + * @return a tuple containing the channel, filter, and reply message + */ + def unapply(obj: GenericResponseEnvelope): Option[(String, PlanetSideGUID, EventResponse)] = { Some((obj.channel, obj.filter, obj.reply)) + } } diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala index 99c6aa7ca..db555c944 100644 --- a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -5,10 +5,29 @@ import net.psforever.services.base.EventSystemStamp import net.psforever.services.base.message.{EventMessage, EventResponse} import net.psforever.types.PlanetSideGUID +/** + * A response when there should be none, but a reply is required to be defined anyway. + */ case object NoReply extends EventResponse +/** + * A stamp that represents not having been processed by an event system. + * Should never been given out to an event system. + */ case object Undelivered extends EventSystemStamp +/** + * The mechanics of a proper event system envelope. + * The envelope has two forms: the input message envelope and the output response envelope. + * The event system uses its stamp to mark that the message form converts into the response form when being processed. + * In terms of proper metaphor, + * it makes no sense for a post office take a letter out of its original envelope, + * write a completely different envelope, + * write a completely different letter, + * package the new letter in the new envelope, + * and deliver it is place of the originals. + * That would be considered fraud. + */ trait MessageTransformationBehavior extends GenericMessageEnvelope with GenericResponseEnvelope { @@ -16,22 +35,24 @@ trait MessageTransformationBehavior private var outputChannel: String = originalChannel private var outputReply: EventResponse = NoReply - // satisfies GenericMessageEnvelope2 (and GenericResponseEnvelope2) + // satisfies GenericMessageEnvelope (and GenericResponseEnvelope) def channel: String = outputChannel - // satisfies GenericMessageEnvelope2 - def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope = { + // satisfies GenericMessageEnvelope + def response(stamp: EventSystemStamp): GenericResponseEnvelope = { outputStamp = stamp - outputChannel = sendToChannel(originalChannel) + outputChannel = stamp.routing(originalChannel) outputReply = msg.response() this } - // satisfies GenericResponseEnvelope2 + // satisfies GenericResponseEnvelope def stamp: EventSystemStamp = outputStamp def reply: EventResponse = outputReply } - +/** + * A proper event system envelope. + */ case class MessageEnvelope(originalChannel: String, filter: PlanetSideGUID, msg: EventMessage) - extends MessageTransformationBehavior \ No newline at end of file + extends MessageTransformationBehavior diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index 7ff320396..17156fc9a 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -3,15 +3,15 @@ package net.psforever.services.galaxy import net.psforever.services.base.{EventSystemStamp, GenericEventService} -case object GalaxyStamp extends EventSystemStamp - -class GalaxyService - extends GenericEventService(stamp = GalaxyStamp) { - override protected def formatChannel(channel: String): String = { +case object GalaxyStamp extends EventSystemStamp { + override def routing(channel: String): String = { if (channel.trim.isEmpty) { - "/all" + "/out" } else { - s"/$channel" + s"/$channel/out" } } } + +class GalaxyService + extends GenericEventService(stamp = GalaxyStamp) diff --git a/src/main/scala/net/psforever/services/teamwork/SquadService.scala b/src/main/scala/net/psforever/services/teamwork/SquadService.scala index 926dba54e..fcac21e2c 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadService.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadService.scala @@ -176,20 +176,20 @@ class SquadService extends Actor { def receive: Receive = { //subscribe to a faction's channel - necessary to receive updates about listed squads - case Service.Join(faction) if SquadService.FactionWordSalad.indexOf(faction) > -1 => + case Service.Join(faction, _) if SquadService.FactionWordSalad.indexOf(faction) > -1 => JoinByFaction(faction, sender()) //subscribe to the player's personal channel - necessary for future and previous squad information - case Service.Join(char_id) => + case Service.Join(char_id, _) => JoinByCharacterId(char_id, sender()) - case Service.Leave(Some(faction)) if SquadService.FactionWordSalad.indexOf(faction) > -1 => + case Service.Leave(faction) if SquadService.FactionWordSalad.indexOf(faction) > -1 => LeaveByFaction(faction, sender()) - case Service.Leave(Some(char_id)) => + case Service.Leave(char_id) => LeaveByCharacterId(char_id, sender()) - case Service.Leave(None) | Service.LeaveAll() => + case Service.LeaveAll => LeaveInGeneral(sender()) case Terminated(actorRef) => diff --git a/src/test/scala/objects/OrbitalShuttlePadTest.scala b/src/test/scala/objects/OrbitalShuttlePadTest.scala index 04eb3f252..37d0de27b 100644 --- a/src/test/scala/objects/OrbitalShuttlePadTest.scala +++ b/src/test/scala/objects/OrbitalShuttlePadTest.scala @@ -82,7 +82,7 @@ class OrbitalShuttlePadControlTest extends FreedContextActorTest { "startup and create the shuttle" in { assert(building.Amenities.size == 9) assert(vehicles.isEmpty) - pad.Actor ! Service.Startup() + pad.Actor ! Service.Startup expectNoMessage(max = 5 seconds) assert(building.Amenities.size == 10) assert(vehicles.size == 1) diff --git a/src/test/scala/objects/ResourceSiloTest.scala b/src/test/scala/objects/ResourceSiloTest.scala index a652c10e8..c55288091 100644 --- a/src/test/scala/objects/ResourceSiloTest.scala +++ b/src/test/scala/objects/ResourceSiloTest.scala @@ -91,7 +91,7 @@ class ResourceSiloControlStartupTest extends ActorTest { "Resource silo" should { "startup properly" in { - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup expectNoMessage(max = 1000 milliseconds) } } @@ -113,7 +113,7 @@ class ResourceSiloControlStartupMessageNoneTest extends ActorTest { "report if it has no NTU on startup" in { obj.NtuCapacitor = 0 assert(obj.NtuCapacitor == 0) - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup val ownerMsg = buildingEvents.receiveOne(200 milliseconds) assert(ownerMsg match { case BuildingActor.NtuDepleted() => true @@ -139,7 +139,7 @@ class ResourceSiloControlStartupMessageSomeTest extends ActorTest { "report if it has any NTU on startup" in { obj.NtuCapacitor = 1 assert(obj.NtuCapacitor == 1) - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup val ownerMsg = buildingEvents.receiveOne(200 milliseconds) assert(ownerMsg match { case BuildingActor.SuppliedWithNtu() => true @@ -197,7 +197,7 @@ class ResourceSiloControlUseTest extends FreedContextActorTest { ant.DeploymentState = DriveState.Deployed building.Amenities = silo silo.Actor = system.actorOf(Props(classOf[ResourceSiloControl], silo), "test-silo") - silo.Actor ! Service.Startup() + silo.Actor ! Service.Startup "Resource silo" should { "respond when being used" in { @@ -225,7 +225,7 @@ class ResourceSiloControlNtuWarningTest extends ActorTest { val zoneEvents: TestProbe = TestProbe("zone-events") zone.AvatarEvents = zoneEvents.ref - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup obj.Actor ! ResourceSilo.UpdateChargeLevel(-obj.NtuCapacitor) zoneEvents.receiveN(3, 500.milliseconds) //events from setup @@ -257,7 +257,7 @@ class ResourceSiloControlUpdate1Test extends ActorTest { val buildingEvents: TestProbe = TestProbe("building-events") zone.AvatarEvents = zoneEvents.ref bldg.Actor = buildingEvents.ref - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup buildingEvents.receiveOne(500 milliseconds) //message caused by "startup" obj.Actor ! ResourceSilo.UpdateChargeLevel(-obj.NtuCapacitor) zoneEvents.receiveN(3, 500.milliseconds) //events from setup @@ -301,7 +301,7 @@ class ResourceSiloControlUpdate2Test extends ActorTest { val buildingEvents: TestProbe = TestProbe("building-events") zone.AvatarEvents = zoneEvents.ref bldg.Actor = buildingEvents.ref - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup buildingEvents.receiveOne(500 milliseconds) //message caused by "startup" obj.Actor ! ResourceSilo.UpdateChargeLevel(-obj.NtuCapacitor + 100) zoneEvents.receiveN(3, 500.milliseconds) //events from setup @@ -345,7 +345,7 @@ class ResourceSiloControlNoUpdateTest extends ActorTest { val buildingEvents: TestProbe = TestProbe("building-events") zone.AvatarEvents = zoneEvents.ref bldg.Actor = buildingEvents.ref - obj.Actor ! Service.Startup() + obj.Actor ! Service.Startup obj.NtuCapacitor = 0 "Resource silo" should { diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index 377aeb3b9..f7249152b 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -190,7 +190,7 @@ class ProximityTerminalControlStartTest extends ActorTest { avatar.GUID = PlanetSideGUID(1) terminal.GUID = PlanetSideGUID(2) - terminal.Actor ! Service.Startup() + terminal.Actor ! Service.Startup expectNoMessage(500 milliseconds) //spacer val probe1 = new TestProbe(system, "local-events") val probe2 = new TestProbe(system, "target-callback") @@ -258,7 +258,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest { avatar.GUID = PlanetSideGUID(1) avatar2.GUID = PlanetSideGUID(2) terminal.GUID = PlanetSideGUID(3) - terminal.Actor ! Service.Startup() + terminal.Actor ! Service.Startup expectNoMessage(500 milliseconds) //spacer val probe1 = new TestProbe(system, "local-events") val probe2 = new TestProbe(system, "target-callback-1") @@ -317,7 +317,7 @@ class ProximityTerminalControlStopTest extends ActorTest { avatar.GUID = PlanetSideGUID(1) terminal.GUID = PlanetSideGUID(2) - terminal.Actor ! Service.Startup() + terminal.Actor ! Service.Startup expectNoMessage(500 milliseconds) //spacer val probe1 = new TestProbe(system, "local-events") val probe2 = new TestProbe(system, "target-callback") @@ -395,7 +395,7 @@ class ProximityTerminalControlNotStopTest extends ActorTest { avatar.GUID = PlanetSideGUID(1) avatar2.GUID = PlanetSideGUID(2) terminal.GUID = PlanetSideGUID(3) - terminal.Actor ! Service.Startup() + terminal.Actor ! Service.Startup expectNoMessage(500 milliseconds) //spacer val probe1 = new TestProbe(system, "local-events") val probe2 = new TestProbe(system, "target-callback-1") diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala index 2e7fc7610..ae24bd796 100644 --- a/src/test/scala/service/base/EventServiceCacheSupportTest.scala +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -6,7 +6,7 @@ import akka.testkit.TestProbe import base.ActorTest import net.psforever.services.Service import net.psforever.services.base.message.EventMessage -import net.psforever.services.base.{CachedGenericEventMessageEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} +import net.psforever.services.base.{CachedGenericEventEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} import net.psforever.types.PlanetSideGUID import scala.concurrent.duration._ @@ -20,7 +20,7 @@ object EventServiceCacheSupportTest { originalChannel: String, override val msg: EventMessage, supportMessage: Any - ) extends CachedGenericEventMessageEnvelope with GenericSupportEnvelope { + ) extends CachedGenericEventEnvelope with GenericSupportEnvelope { assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") def filter: PlanetSideGUID = Service.defaultPlayerGUID def supportLabel: String = "supportActor" diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala index 91c60031d..022063dd1 100644 --- a/src/test/scala/service/base/EventServiceTest.scala +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -6,7 +6,7 @@ import akka.testkit.TestProbe import base.ActorTest import net.psforever.services.Service import net.psforever.services.base.GenericEventService -import net.psforever.services.base.envelope.GenericResponseEnvelope +import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} import scala.concurrent.duration._ @@ -160,7 +160,7 @@ class EventServiceTest7 extends ActorTest { case _ => assert(false, "(7) message expected but not received") } - events.tell(Service.Leave(), probe.ref) + events.tell(Service.LeaveAll, probe.ref) events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) probe.expectNoMessage(250 milliseconds) @@ -190,7 +190,7 @@ class EventServiceTest8 extends ActorTest { case _ => assert(false, "(7) message expected but not received") } - events.tell(Service.LeaveAll(), probe.ref) + events.tell(Service.LeaveAll, probe.ref) events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) probe.expectNoMessage(250 milliseconds) From 9564b209789ed6a59f8721f91d156efb2258454d Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 3 Mar 2026 15:33:29 -0500 Subject: [PATCH 14/32] added test for join confirmation message --- .../scala/service/base/EnvelopeTest.scala | 8 +-- .../base/EventServiceCacheSupportTest.scala | 36 +++++----- .../base/EventServiceSupportTest.scala | 27 ++++---- .../scala/service/base/EventServiceTest.scala | 66 +++++++++++-------- 4 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/test/scala/service/base/EnvelopeTest.scala b/src/test/scala/service/base/EnvelopeTest.scala index 85c1e7b3c..e62b036a7 100644 --- a/src/test/scala/service/base/EnvelopeTest.scala +++ b/src/test/scala/service/base/EnvelopeTest.scala @@ -54,9 +54,9 @@ class EnvelopeTest extends Specification { "response" in { val input = MessageEnvelope("test", TestFilter, TestMessage(5)) - val output = input.response(TestStamp, StringWithSlashes) + val output = input.response(TestStamp) output match { - case reply @ GenericResponseEnvelope("/test/", TestFilter, TestMessage(5)) => + case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestMessage(5)) => reply.stamp mustEqual TestStamp case _ => ko @@ -65,9 +65,9 @@ class EnvelopeTest extends Specification { "response (different from input)" in { val input = MessageEnvelope("test", TestFilter, TestInputMessage(5)) - val output = input.response(TestStamp, StringWithSlashes) + val output = input.response(TestStamp) output match { - case reply @ GenericResponseEnvelope("/test/", TestFilter, TestOutputEvent(7)) => + case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestOutputEvent(7)) => reply.stamp mustEqual TestStamp case _ => ko diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala index ae24bd796..860eccf49 100644 --- a/src/test/scala/service/base/EventServiceCacheSupportTest.scala +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -1,20 +1,18 @@ // Copyright (c) 2026 PSForever package service.base -import akka.actor.Props +import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.TestProbe import base.ActorTest import net.psforever.services.Service import net.psforever.services.base.message.EventMessage -import net.psforever.services.base.{CachedGenericEventEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} +import net.psforever.services.base.{CachedEnvelope, CachedGenericEventEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} import net.psforever.types.PlanetSideGUID +import service.base.EventServiceSupportTest.TestSupportService import scala.concurrent.duration._ object EventServiceCacheSupportTest { - class TestCacheService(eventSupportServices: List[EventServiceSupport]) - extends GenericEventServiceWithCacheAndSupport(EventServiceTestBase.TestStamp, eventSupportServices) - final case class CachedSupportTestEnvelope( guid: PlanetSideGUID, originalChannel: String, @@ -25,25 +23,31 @@ object EventServiceCacheSupportTest { def filter: PlanetSideGUID = Service.defaultPlayerGUID def supportLabel: String = "supportActor" } + + class TestCacheService(eventSupportServices: List[EventServiceSupport]) + extends GenericEventServiceWithCacheAndSupport(EventServiceTestBase.TestStamp, eventSupportServices) + + def SpawnTestSystem(eventSupportServices: List[EventServiceSupport])(implicit system: ActorSystem, self: ActorRef): ActorRef = { + val name = self.getClass.getSimpleName.replace("EventServiceCacheSupportTest", "") + system.actorOf(Props(classOf[TestSupportService], eventSupportServices), name = s"EventServiceCacheSupportTest.$name") + } } class EventServiceCacheSupportTestDefault extends ActorTest { - import EventServiceCacheSupportTest._ "GenericEventServiceWithCacheAndSupport" should { "construct" in { - system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.0") + EventServiceCacheSupportTest.SpawnTestSystem(List()) } } } class EventServiceCacheSupportTestSupportNormally extends ActorTest { - import EventServiceCacheSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithCacheAndSupport" should { "send a valid message to both subscribed channel and support class, like normal GenericEventServiceWithSupport" in { val mainProbe = TestProbe("MainProbe") val supportProbe = TestProbe("SupportProbe") - val events = system.actorOf(Props(classOf[TestCacheService], List(TestSupportActorLoader)), name = "EventServiceCacheSupportTest.1") + val events = EventServiceCacheSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) events.tell(Service.Join("test"), mainProbe.ref) val originalMessage = TestSupportEnvelope("test", SupportActorRepliesWith("hello world", supportProbe.ref)) events ! originalMessage @@ -66,12 +70,11 @@ class EventServiceCacheSupportTestSupportNormally extends ActorTest { } class EventServiceCacheSupportTestCachedMessages extends ActorTest { - import EventServiceCacheSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithCacheAndSupport" should { "wait on sending designated cache-able messages after a few milliseconds" in { val mainProbe = TestProbe("MainProbe") - val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.2") + val events = EventServiceCacheSupportTest.SpawnTestSystem(List()) events.tell(Service.Join("test"), mainProbe.ref) val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) events ! firstMessage @@ -87,12 +90,11 @@ class EventServiceCacheSupportTestCachedMessages extends ActorTest { } class EventServiceCacheSupportTestMultipleCachedMessagesAtOnce extends ActorTest { - import EventServiceCacheSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithCacheAndSupport" should { "send cache-able messages within a time span in bulk" in { val mainProbe = TestProbe("MainProbe") - val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.3") + val events = EventServiceCacheSupportTest.SpawnTestSystem(List()) events.tell(Service.Join("test"), mainProbe.ref) val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) val secondMessage = CachedEnvelope(PlanetSideGUID(2), "test", TestMessage(2)) @@ -123,12 +125,11 @@ class EventServiceCacheSupportTestMultipleCachedMessagesAtOnce extends ActorTest } class EventServiceCacheSupportTestMultipleCachedSameMessages extends ActorTest { - import EventServiceCacheSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithCacheAndSupport" should { "only caches and dispatches the last message with a given filtering token" in { val mainProbe = TestProbe("MainProbe") - val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.4") + val events = EventServiceCacheSupportTest.SpawnTestSystem(List()) events.tell(Service.Join("test"), mainProbe.ref) val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) val secondMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(2)) @@ -152,12 +153,11 @@ class EventServiceCacheSupportTestMultipleCachedSameMessages extends ActorTest { } class EventServiceCacheSupportTestMultipleCachedMessages extends ActorTest { - import EventServiceCacheSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithCacheAndSupport" should { "send cache-able messages within a time span, separated if they are part of different caches" in { val mainProbe = TestProbe("MainProbe") - val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.5") + val events = EventServiceCacheSupportTest.SpawnTestSystem(List()) events.tell(Service.Join("test"), mainProbe.ref) val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1)) //first cache flush @@ -191,7 +191,7 @@ class EventServiceCacheSupportTestSupportDelayed extends ActorTest { "cache a message for a support actor, but only dispatch that message to the support actor when flushing the cache" in { val mainProbe = TestProbe("MainProbe") val supportProbe = TestProbe("SupportProbe") - val events = system.actorOf(Props(classOf[TestCacheService], List(TestSupportActorLoader)), name = "EventServiceCacheSupportTest.6") + val events = EventServiceCacheSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) events.tell(Service.Join("test"), mainProbe.ref) val originalMessage = CachedSupportTestEnvelope( PlanetSideGUID(1), diff --git a/src/test/scala/service/base/EventServiceSupportTest.scala b/src/test/scala/service/base/EventServiceSupportTest.scala index 1b61e6eaf..53d96d3c7 100644 --- a/src/test/scala/service/base/EventServiceSupportTest.scala +++ b/src/test/scala/service/base/EventServiceSupportTest.scala @@ -1,7 +1,7 @@ // Copyright (c) 2026 PSForever package service.base -import akka.actor.Props +import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.TestProbe import base.ActorTest import net.psforever.services.Service @@ -10,40 +10,42 @@ import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWith import scala.concurrent.duration._ object EventServiceSupportTest { + final case class TestSupportOnlyEnvelope(supportLabel: String, supportMessage: EventServiceTestBase.SupportActorRepliesWith) + extends GenericSupportEnvelopeOnly + class TestSupportService(eventSupportServices: List[EventServiceSupport]) extends GenericEventServiceWithSupport(EventServiceTestBase.TestStamp, eventSupportServices) - final case class TestSupportOnlyEnvelope(supportLabel: String, supportMessage: EventServiceTestBase.SupportActorRepliesWith) - extends GenericSupportEnvelopeOnly + def SpawnTestSystem(eventSupportServices: List[EventServiceSupport])(implicit system: ActorSystem, self: ActorRef): ActorRef = { + val name = self.getClass.getSimpleName.replace("EventServiceSupportTest", "") + system.actorOf(Props(classOf[TestSupportService], eventSupportServices), name = s"EventServiceSupportTest.$name") + } } class EventServiceSupportTestDefault extends ActorTest { - import EventServiceSupportTest._ "GenericEventServiceWithSupport" should { "construct" in { - system.actorOf(Props(classOf[TestSupportService], List()), name = "EventServiceSupportTest.0") + EventServiceSupportTest.SpawnTestSystem(List()) } } } class EventServiceSupportTestLoadSupportClass extends ActorTest { - import EventServiceSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithSupport" should { "construct with setting up a test support class" in { - system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.1") + EventServiceSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) } } } class EventServiceSupportTestSendToSupportClass extends ActorTest { - import EventServiceSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithSupport" should { "send a valid message to both subscribed channel and support class" in { val mainProbe = TestProbe("MainProbe") val supportProbe = TestProbe("SupportProbe") - val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.2") + val events = EventServiceSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) events.tell(Service.Join("test"), mainProbe.ref) val originalMessage = TestSupportEnvelope("test", SupportActorRepliesWith("hello world", supportProbe.ref)) events ! originalMessage @@ -66,13 +68,12 @@ class EventServiceSupportTestSendToSupportClass extends ActorTest { } class EventServiceSupportTestSendToSupportClassOnly1 extends ActorTest { - import EventServiceSupportTest._ import EventServiceTestBase._ "GenericEventServiceWithSupport" should { "send a valid message to support class (but not to subscribed channel)" in { val mainProbe = TestProbe("MainProbe") val supportProbe = TestProbe("SupportProbe") - val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.3") + val events = EventServiceSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) events.tell(Service.Join("test"), mainProbe.ref) val originalMessage = TestSupportEnvelope("notatest", SupportActorRepliesWith("hello world", supportProbe.ref)) events ! originalMessage @@ -96,7 +97,7 @@ class EventServiceSupportTestSendToSupportClassOnly2 extends ActorTest { "send a valid message to support class (skip subscribed channel)" in { val mainProbe = TestProbe("MainProbe") val supportProbe = TestProbe("SupportProbe") - val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.4") + val events = EventServiceSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) events.tell(Service.Join("test"), mainProbe.ref) val originalMessage = TestSupportOnlyEnvelope("supportActor", SupportActorRepliesWith("hello world", supportProbe.ref)) events ! originalMessage @@ -120,7 +121,7 @@ class EventServiceSupportTestSendToNoOne extends ActorTest { "send a valid message that neither support class nor subscribed channel handle" in { val mainProbe = TestProbe("MainProbe") val supportProbe = TestProbe("SupportProbe") - val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.5") + val events = EventServiceSupportTest.SpawnTestSystem(List(TestSupportActorLoader)) events.tell(Service.Join("test"), mainProbe.ref) val originalMessage = TestSupportOnlyEnvelope("notASupportActor", SupportActorRepliesWith("hello world", supportProbe.ref)) events ! originalMessage diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala index 022063dd1..86f169dd0 100644 --- a/src/test/scala/service/base/EventServiceTest.scala +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -1,7 +1,7 @@ // Copyright (c) 2026 PSForever package service.base -import akka.actor.Props +import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.TestProbe import base.ActorTest import net.psforever.services.Service @@ -12,36 +12,50 @@ import scala.concurrent.duration._ object EventServiceTest { class TestService() extends GenericEventService(EventServiceTestBase.TestStamp) + + def SpawnTestSystem()(implicit system: ActorSystem, self: ActorRef): ActorRef = { + val name = self.getClass.getSimpleName.replace("EventServiceTest", "") + system.actorOf(Props[TestService](), name = s"EventServiceTest.$name") + } } class EventServiceTestDefault extends ActorTest { - import EventServiceTest._ "GenericEventSystem" should { "construct" in { - system.actorOf(Props[TestService](), name = "EventServiceTest.0") + EventServiceTest.SpawnTestSystem() } } } -class EventServiceTest1 extends ActorTest { - import EventServiceTest._ +class EventServiceTestSubscribe extends ActorTest { "GenericEventSystem" should { "be subscribed to by channel name" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.1") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) probe.expectNoMessage(100 milliseconds) } } } -class EventServiceTest2 extends ActorTest { - import EventServiceTest._ +class EventServiceTestSubscribeConfirm extends ActorTest { + "GenericEventSystem" should { + "be subscribed to by channel name and send a confirmation when prompted" in { + val probe = TestProbe("testProbe") + val events = EventServiceTest.SpawnTestSystem() + events.tell(Service.Join("test", sendJoinConfirmation = true), probe.ref) + val reply = probe.receiveOne(100 milliseconds) + assert(reply == Service.JoinConfirmation(events, "test"), "join confirmation expected but not received") + } + } +} + +class EventServiceTestSubscriptionMessage extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "receive messages from a subscribed channel" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.2") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) probe.receiveN(1, 100 milliseconds) @@ -49,16 +63,15 @@ class EventServiceTest2 extends ActorTest { } } -class EventServiceTest3 extends ActorTest { - import EventServiceTest._ +class EventServiceTestSubscriptionReply extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "receive messages that are responses to the original message from a subscribed channel" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.3") + val events = EventServiceTest.SpawnTestSystem() val msg = MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) // s => "/$s" is the default channel manipulation of the event system - val formalReply = msg.response(EventServiceTestBase.TestStamp, s => "/$s") + val formalReply = msg.response(EventServiceTestBase.TestStamp) events.tell(Service.Join("test"), probe.ref) events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) val reply = probe.receiveOne(100 milliseconds) @@ -67,14 +80,13 @@ class EventServiceTest3 extends ActorTest { } } -class EventServiceTest4 extends ActorTest { - import EventServiceTest._ +class EventServiceTestNotSubscribed extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "not receive messages from an unsubscribed channel" in { val probe = TestProbe("testProbe") val missedProbe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.4") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("notATest"), missedProbe.ref) events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) @@ -88,13 +100,12 @@ class EventServiceTest4 extends ActorTest { } } -class EventServiceTest5 extends ActorTest { - import EventServiceTest._ +class EventServiceTestUnexpectedMessages extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "ignore unexpected messages" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.5") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events ! TestMessage(5) probe.expectNoMessage(250 milliseconds) @@ -103,13 +114,12 @@ class EventServiceTest5 extends ActorTest { } } -class EventServiceTest6 extends ActorTest { - import EventServiceTest._ +class EventServiceTestLeave extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "leave single channels" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.6") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("anotherTest"), probe.ref) @@ -125,7 +135,7 @@ class EventServiceTest6 extends ActorTest { case _ => assert(false, "(4) message expected but not received") } - events.tell(Service.Leave(Some("anotherTest")), probe.ref) + events.tell(Service.Leave("anotherTest"), probe.ref) events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply2 = probe.receiveOne(100 milliseconds) @@ -138,13 +148,12 @@ class EventServiceTest6 extends ActorTest { } } -class EventServiceTest7 extends ActorTest { - import EventServiceTest._ +class EventServiceTestLeaveAll1 extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "leave all channels (1)" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.7") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("anotherTest"), probe.ref) @@ -168,13 +177,12 @@ class EventServiceTest7 extends ActorTest { } } -class EventServiceTest8 extends ActorTest { - import EventServiceTest._ +class EventServiceTestLeaveAll2 extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "leave all channels" in { val probe = TestProbe("testProbe") - val events = system.actorOf(Props[TestService](), name = "EventServiceTest.8") + val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("anotherTest"), probe.ref) From 14da36dabe86e3e025a7f3be5402596d2fd30dbd Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 3 Mar 2026 15:53:16 -0500 Subject: [PATCH 15/32] prefacing imports with _root_ to escape name conflict with nested package --- src/test/scala/service/HartServiceTest.scala | 2 +- src/test/scala/service/HartTimerTest.scala | 26 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/test/scala/service/HartServiceTest.scala b/src/test/scala/service/HartServiceTest.scala index 3952a8f7a..c0a4a33c3 100644 --- a/src/test/scala/service/HartServiceTest.scala +++ b/src/test/scala/service/HartServiceTest.scala @@ -3,7 +3,7 @@ package service import akka.actor.{ActorRef, Props} import akka.testkit.TestProbe -import base.ActorTest +import _root_.base.ActorTest import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.services.hart.{HartService, HartTimer} import net.psforever.types.PlanetSideGUID diff --git a/src/test/scala/service/HartTimerTest.scala b/src/test/scala/service/HartTimerTest.scala index 038909b17..486d88dd0 100644 --- a/src/test/scala/service/HartTimerTest.scala +++ b/src/test/scala/service/HartTimerTest.scala @@ -1,9 +1,9 @@ // Copyright (c) 2021 PSForever package service -import akka.actor.Props +import akka.actor.{ActorRef, Props} import akka.testkit.TestProbe -import base.ActorTest +import _root_.base.ActorTest import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.services.hart.HartTimer import net.psforever.types.PlanetSideGUID @@ -14,11 +14,11 @@ class HartTimerNotScheduled extends ActorTest { "HartTimer" should { val catchall = new TestProbe(system).ref val zone = new Zone("test", new ZoneMap("test"), 0) { - override def SetupNumberPools() = {} - override def AvatarEvents = catchall - override def LocalEvents = catchall - override def VehicleEvents = catchall - override def Activity = catchall + override def SetupNumberPools(): Unit = {} + override def AvatarEvents: ActorRef = catchall + override def LocalEvents: ActorRef = catchall + override def VehicleEvents: ActorRef = catchall + override def Activity: ActorRef = catchall } val timer = system.actorOf(Props(classOf[HartTimer], zone), "hart-timer") @@ -34,11 +34,11 @@ class HartTimerInitializedPairingScheduled extends ActorTest { "HartTimer" should { val catchall = new TestProbe(system).ref val zone = new Zone("test", new ZoneMap("test"), 0) { - override def SetupNumberPools() = {} - override def AvatarEvents = catchall - override def LocalEvents = catchall - override def VehicleEvents = catchall - override def Activity = catchall + override def SetupNumberPools(): Unit = {} + override def AvatarEvents: ActorRef = catchall + override def LocalEvents: ActorRef = catchall + override def VehicleEvents: ActorRef = catchall + override def Activity: ActorRef = catchall } val timer = system.actorOf(Props(classOf[HartTimer], zone), "hart-timer") @@ -54,4 +54,4 @@ class HartTimerInitializedPairingScheduled extends ActorTest { } } -object HartTimerTest { /* initially left empty */ } +object HartTimerTest { /* initially left empty */ } \ No newline at end of file From f05a0ab96ae061df6d992000250613f0037060fb Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Wed, 4 Mar 2026 18:11:04 -0500 Subject: [PATCH 16/32] sorted out some tests for the event systems --- .../scala/net/psforever/server/Server.scala | 2 +- .../objects/AutoRepairIntegrationTest.scala | 12 ++--- .../actor/objects/VehicleSpawnPadTest.scala | 49 ++++++++---------- .../actor/service/AvatarServiceTest.scala | 50 +++++++++---------- .../actors/session/AvatarActor.scala | 2 +- .../net/psforever/objects/zones/Zone.scala | 7 ++- .../services/avatar/AvatarService.scala | 14 ++++-- .../services/base/GenericEventService.scala | 2 +- ...nericEventServiceWithCacheAndSupport.scala | 2 +- .../base/GenericEventServiceWithSupport.scala | 2 +- .../services/galaxy/GalaxyService.scala | 8 ++- .../services/local/LocalService.scala | 14 ++++-- .../services/vehicle/VehicleService.scala | 14 ++++-- src/test/scala/objects/DamageModelTests.scala | 5 ++ .../scala/objects/OrbitalShuttlePadTest.scala | 2 +- src/test/scala/objects/ResourceSiloTest.scala | 2 +- .../objects/terminal/ProximityTest.scala | 5 -- .../scala/service/base/EnvelopeTest.scala | 2 +- .../base/EventServiceCacheSupportTest.scala | 6 +-- .../scala/service/base/EventServiceTest.scala | 43 +++------------- 20 files changed, 111 insertions(+), 132 deletions(-) diff --git a/server/src/main/scala/net/psforever/server/Server.scala b/server/src/main/scala/net/psforever/server/Server.scala index 2ec30a503..686e39953 100644 --- a/server/src/main/scala/net/psforever/server/Server.scala +++ b/server/src/main/scala/net/psforever/server/Server.scala @@ -101,7 +101,7 @@ object Server { val zones = Zones.zones :+ Zone.Nowhere val serviceManager = ServiceManager.boot serviceManager ! ServiceManager.Register(classic.Props[AccountIntermediaryService](), "accountIntermediary") - serviceManager ! ServiceManager.Register(classic.Props[GalaxyService](), "galaxy") + serviceManager ! ServiceManager.Register(GalaxyService(), "galaxy") serviceManager ! ServiceManager.Register(classic.Props[SquadService](), "squad") serviceManager ! ServiceManager.Register(classic.Props[AccountPersistenceService](), "accountPersistence") serviceManager ! ServiceManager.Register(classic.Props[PropertyOverrideManager](), "propertyOverrideManager") diff --git a/server/src/test/scala/actor/objects/AutoRepairIntegrationTest.scala b/server/src/test/scala/actor/objects/AutoRepairIntegrationTest.scala index 7742079e0..b1b939c67 100644 --- a/server/src/test/scala/actor/objects/AutoRepairIntegrationTest.scala +++ b/server/src/test/scala/actor/objects/AutoRepairIntegrationTest.scala @@ -32,7 +32,7 @@ import scala.concurrent.duration._ class AutoRepairFacilityIntegrationTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id) - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) val avatarProbe = new TestProbe(system) @@ -105,7 +105,7 @@ class AutoRepairFacilityIntegrationTest extends FreedContextActorTest { class AutoRepairFacilityIntegrationGiveNtuTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id) - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) val avatarProbe = new TestProbe(system) @@ -160,7 +160,7 @@ class AutoRepairFacilityIntegrationGiveNtuTest extends FreedContextActorTest { class AutoRepairFacilityIntegrationAntGiveNtuTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id) - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) var buildingMap = new TrieMap[Int, Building]() val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) @@ -251,7 +251,7 @@ class AutoRepairFacilityIntegrationAntGiveNtuTest extends FreedContextActorTest class AutoRepairFacilityIntegrationTerminalDestroyedTerminalAntTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id) - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) var buildingMap = new TrieMap[Int, Building]() val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) @@ -353,7 +353,7 @@ class AutoRepairFacilityIntegrationTerminalDestroyedTerminalAntTest extends Free class AutoRepairFacilityIntegrationTerminalIncompleteRepairTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id) - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) var buildingMap = new TrieMap[Int, Building]() val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) @@ -469,7 +469,7 @@ class AutoRepairFacilityIntegrationTerminalIncompleteRepairTest extends FreedCon class AutoRepairTowerIntegrationTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id) - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) val avatarProbe = new TestProbe(system) diff --git a/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala b/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala index 1691f6244..e847d5036 100644 --- a/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala +++ b/server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala @@ -9,11 +9,12 @@ import net.psforever.objects.serverobject.structures.StructureType import net.psforever.objects.{GlobalDefinitions, Player, Vehicle} import net.psforever.objects.zones.Zone import net.psforever.types.{PlanetSideGUID, _} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import akka.actor.typed.scaladsl.adapter._ import net.psforever.actors.zone.ZoneActor import net.psforever.objects.avatar.Avatar import net.psforever.objects.serverobject.terminals.Terminal +import net.psforever.services.base.envelope.GenericMessageEnvelope import scala.concurrent.duration._ @@ -37,7 +38,7 @@ class VehicleSpawnControl2Test extends ActorTest { pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer]) - probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage]) + probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle]) vehicle.Seats(0).mount(player) @@ -69,11 +70,11 @@ class VehicleSpawnControl3Test extends ActorTest { pad.Actor ! VehicleSpawnPad.VehicleOrder(player2, vehicle, terminal) //second order (vehicle shared) assert(probe.receiveOne(1 seconds) match { - case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Queue, _) => true - case _ => false + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, _) => true + case _ => false }) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer]) - probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage]) + probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle]) vehicle.Seats(0).mount(player) @@ -110,14 +111,6 @@ class VehicleSpawnControl4Test extends ActorTest { player.Continent = "problem" //problem pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order - - val msg = probe.receiveOne(1 minute) -// assert( -// msg match { -// case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v == vehicle) && (z == zone) -// case _ => false -// } -// ) probe.expectNoMessage(5 seconds) } } @@ -133,18 +126,18 @@ class VehicleSpawnControl5Test extends ActorTest() { pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer]) - probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage]) + probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope]) vehicle.Health = 0 //problem probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer]) assert(probe.receiveOne(1 minute) match { - case VehicleServiceMessage(_, _, VehicleAction.LoadVehicle(_, _, _, _, _)) => true - case _ => false + case GenericMessageEnvelope(_, _, VehicleAction.LoadVehicle(_, _, _, _)) => true + case _ => false }) assert(probe.receiveOne(1 minute) match { - case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true - case _ => false + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true + case _ => false }) } } @@ -160,18 +153,18 @@ class VehicleSpawnControl6Test extends ActorTest() { pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer]) - probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage]) + probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope]) player.Die probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer]) assert(probe.receiveOne(1 minute) match { - case VehicleServiceMessage(_, _, VehicleAction.LoadVehicle(_, _, _, _, _)) => true - case _ => false + case GenericMessageEnvelope(_, _, VehicleAction.LoadVehicle(_, _, _, _)) => true + case _ => false }) assert(probe.receiveOne(1 minute) match { - case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true - case _ => false + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true + case _ => false }) } } @@ -188,18 +181,18 @@ class VehicleSpawnControl7Test extends ActorTest { pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer]) - probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage]) + probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails]) probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer]) assert(probe.receiveOne(1 minute) match { - case VehicleServiceMessage(_, _, VehicleAction.LoadVehicle(_, _, _, _, _)) => true - case _ => false + case GenericMessageEnvelope(_, _, VehicleAction.LoadVehicle(_, _, _, _)) => true + case _ => false }) assert(probe.receiveOne(1 minute) match { - case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true - case _ => false + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true + case _ => false }) } } diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala index 2a4c47777..001d65d10 100644 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ b/server/src/test/scala/actor/service/AvatarServiceTest.scala @@ -23,7 +23,7 @@ class AvatarService1Test extends ActorTest { "AvatarService" should { "construct" in { ServiceManager.boot(system) - system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + system.actorOf(AvatarService(), AvatarServiceTest.TestName) assert(true) } } @@ -33,7 +33,7 @@ class AvatarService2Test extends ActorTest { "AvatarService" should { "subscribe" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") assert(true) } @@ -44,7 +44,7 @@ class AvatarService3Test extends ActorTest { "AvatarService" should { ServiceManager.boot(system) "subscribe to a specific channel" in { - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! Service.LeaveAll assert(true) @@ -56,7 +56,7 @@ class AvatarService4Test extends ActorTest { "AvatarService" should { "subscribe" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! Service.LeaveAll assert(true) @@ -68,7 +68,7 @@ class AvatarService5Test extends ActorTest { "AvatarService" should { "pass an unhandled message" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! "hello" expectNoMessage() @@ -80,7 +80,7 @@ class ArmorChangedTest extends ActorTest { "AvatarService" should { "pass ArmorChanged" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ArmorChanged(ExoSuitType.Reinforced, 0)) expectMsg( @@ -98,7 +98,7 @@ class ConcealPlayerTest extends ActorTest { "AvatarService" should { "pass ConcealPlayer" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", ConcealPlayer(PlanetSideGUID(10))) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ConcealPlayer(PlanetSideGUID(10)))) @@ -108,7 +108,7 @@ class ConcealPlayerTest extends ActorTest { class EquipmentInHandTest extends ActorTest { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), "release-test-service") + val service = system.actorOf(AvatarService(), "release-test-service") val toolDef = GlobalDefinitions.beamer val tool = Tool(toolDef) tool.GUID = PlanetSideGUID(40) @@ -135,7 +135,7 @@ class EquipmentInHandTest extends ActorTest { class DroptItemTest extends ActorTest { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), "release-test-service") + val service = system.actorOf(AvatarService(), "release-test-service") val toolDef = GlobalDefinitions.beamer val tool = Tool(toolDef) tool.Position = Vector3(1, 2, 3) @@ -174,7 +174,7 @@ class LoadPlayerTest extends ActorTest { "AvatarService" should { "pass LoadPlayer" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") //no parent data service ! AvatarServiceMessage( @@ -198,7 +198,7 @@ class ObjectDeleteTest extends ActorTest { "AvatarService" should { "pass ObjectDelete" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11))) expectMsg( @@ -217,7 +217,7 @@ class ObjectHeldTest extends ActorTest { "AvatarService" should { "pass ObjectHeld" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2)) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2))) @@ -229,7 +229,7 @@ class PutDownFDUTest extends ActorTest { "AvatarService" should { "pass PutDownFDU" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10))) expectMsg( @@ -243,7 +243,7 @@ class PlanetsideAttributeTest extends ActorTest { "AvatarService" should { "pass PlanetsideAttribute" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L)) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))) @@ -272,7 +272,7 @@ class PlayerStateTest extends ActorTest { "AvatarService" should { "pass PlayerState" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage( "test", @@ -323,7 +323,7 @@ class PickupItemTest extends ActorTest { "pass PickUpItem" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! PickupItemEnvelope("test", AvatarAction.PickupItem(tool), Zone.Nowhere) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0))) @@ -334,7 +334,7 @@ class ReloadTest extends ActorTest { "AvatarService" should { "pass Reload" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ReloadTool(PlanetSideGUID(40))) expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ReloadTool(PlanetSideGUID(40)))) @@ -349,7 +349,7 @@ class ChangeAmmoTest extends ActorTest { "AvatarService" should { "pass ChangeAmmo" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage( "test", @@ -388,7 +388,7 @@ class ChangeFireModeTest extends ActorTest { "AvatarService" should { "pass ChangeFireMode" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireMode(PlanetSideGUID(40), 0)) expectMsg( @@ -402,7 +402,7 @@ class ChangeFireStateStartTest extends ActorTest { "AvatarService" should { "pass ChangeFireState_Start" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Start(PlanetSideGUID(40))) expectMsg( @@ -420,7 +420,7 @@ class ChangeFireStateStopTest extends ActorTest { "AvatarService" should { "pass ChangeFireState_Stop" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Stop(PlanetSideGUID(40))) expectMsg( @@ -438,7 +438,7 @@ class WeaponDryFireTest extends ActorTest { "AvatarService" should { "pass WeaponDryFire" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage("test", PlanetSideGUID(10), WeaponDryFire(PlanetSideGUID(40))) expectMsg( @@ -454,7 +454,7 @@ class AvatarStowEquipmentTest extends ActorTest { "AvatarService" should { "pass StowEquipment" in { ServiceManager.boot(system) - val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName) + val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) service ! Service.Join("test") service ! AvatarServiceMessage( "test", @@ -525,8 +525,8 @@ class AvatarReleaseTest extends FreedContextActorTest { val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] assert(reply2msg.channel.equals("/test/Avatar")) assert(reply2msg.filter == Service.defaultPlayerGUID) - assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete]) - assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid) + assert(reply2msg.reply.isInstanceOf[ObjectDelete]) + assert(reply2msg.reply.asInstanceOf[ObjectDelete].obj_guid == guid) subscriber.expectNoMessage(1 seconds) assert(zone.Corpses.isEmpty) diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 6bad7620e..14d3b827e 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -12,7 +12,6 @@ import net.psforever.objects.avatar.ModePermissions import net.psforever.objects.avatar.scoring.{Assist, Death, EquipmentStat, KDAStat, Kill, Life, ScoreCard, SupportActivity} import net.psforever.objects.sourcing.{TurretSource, VehicleSource} import net.psforever.packet.game.ImplantAction -import net.psforever.services.avatar.AvatarServiceResponse import net.psforever.types.{ChatMessageType, StatisticalCategory, StatisticalElement} import net.psforever.zones.Zones import org.joda.time.{LocalDateTime, Seconds} @@ -3490,6 +3489,7 @@ class AvatarActor( value: Int ): Unit = { import akka.actor.typed.scaladsl.adapter.TypedActorRefOps + import net.psforever.services.avatar.AvatarServiceResponse sessionActor.toClassic ! AvatarServiceResponse("", guid, AvatarAction.AvatarImplant(action, index, value)) } diff --git a/src/main/scala/net/psforever/objects/zones/Zone.scala b/src/main/scala/net/psforever/objects/zones/Zone.scala index fe31facf5..4e237f06f 100644 --- a/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -1624,10 +1624,9 @@ object Zone { if (zone.id.startsWith("tzsh")) { zone.npcPopulation = context.actorOf(Props(classOf[ShootingRangeTargetSpawnerActor], zone), s"$id-npcs") } - - zone.avatarEvents = context.actorOf(Props(classOf[AvatarService], zone), s"$id-avatar-events") - zone.localEvents = context.actorOf(Props(classOf[LocalService], zone), s"$id-local-events") - zone.vehicleEvents = context.actorOf(Props(classOf[VehicleService]), s"$id-vehicle-events") + zone.avatarEvents = context.actorOf(AvatarService(), s"$id-avatar-events") + zone.localEvents = context.actorOf(LocalService(zone), s"$id-local-events") + zone.vehicleEvents = context.actorOf(VehicleService(), s"$id-vehicle-events") zone.timeOfDayOrigin = System.currentTimeMillis() diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index df04c6196..0aa2db81d 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -23,8 +23,12 @@ case object LitterRemovalSupport case object AvatarStamp extends EventSystemStamp -class AvatarService - extends GenericEventServiceWithCacheAndSupport( - stamp = AvatarStamp, - eventSupportServices = List(CorpseRemovalSupport, LitterRemovalSupport) - ) +object AvatarService { + def apply(): Props = { + Props( + classOf[GenericEventServiceWithCacheAndSupport], + AvatarStamp, + List(CorpseRemovalSupport, LitterRemovalSupport) + ) + } +} diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 46ca88af6..a9dee3312 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -39,7 +39,7 @@ trait EventSystemStamp { * and, dispatches the response to all subscribers associated with the channel provided in the message. * @param stamp distinct tag associated with an event system */ -abstract class GenericEventService(stamp: EventSystemStamp) +class GenericEventService(stamp: EventSystemStamp) extends Actor { protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName) diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index 89f2474f4..665d90b6e 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -92,7 +92,7 @@ private case object FlushCachedMessages extends GenericMessageEnvelope { def filter: PlanetSideGUID = Service.defaultPlayerGUID } -abstract class GenericEventServiceWithCacheAndSupport +class GenericEventServiceWithCacheAndSupport ( stamp: EventSystemStamp, eventSupportServices: List[EventServiceSupport] diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index e0077fa55..713cadcab 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -80,7 +80,7 @@ trait GenericSupportEnvelopeOnly * @param stamp distinct tag associated with an event system * @param eventSupportServices list of support actors to initialize */ -abstract class GenericEventServiceWithSupport +class GenericEventServiceWithSupport ( stamp: EventSystemStamp, eventSupportServices: List[EventServiceSupport] diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index 17156fc9a..b3d4c084e 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -1,6 +1,7 @@ // Copyright (c) 2017-2026 PSForever package net.psforever.services.galaxy +import akka.actor.Props import net.psforever.services.base.{EventSystemStamp, GenericEventService} case object GalaxyStamp extends EventSystemStamp { @@ -13,5 +14,8 @@ case object GalaxyStamp extends EventSystemStamp { } } -class GalaxyService - extends GenericEventService(stamp = GalaxyStamp) +object GalaxyService { + def apply(): Props = { + Props(classOf[GenericEventService], GalaxyStamp) + } +} diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index 6285bf434..395e5ec03 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -41,8 +41,12 @@ case class CaptureFlagSupport(zone: Zone) case object LocalStamp extends EventSystemStamp -class LocalService(zone: Zone) - extends GenericEventServiceWithSupport( - stamp = LocalStamp, - eventSupportServices = List(DoorCloserSupport, HackClearSupport, HackCaptureSupport, CaptureFlagSupport(zone)) - ) +object LocalService { + def apply(zone: Zone): Props = { + Props( + classOf[GenericEventServiceWithSupport], + LocalStamp, + List(DoorCloserSupport, HackClearSupport, HackCaptureSupport, CaptureFlagSupport(zone)) + ) + } +} diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 55bd0c25a..7ab4ccf0f 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -15,8 +15,12 @@ case object TurretUpgradeSupport case object VehicleStamp extends EventSystemStamp -class VehicleService - extends GenericEventServiceWithCacheAndSupport( - stamp = VehicleStamp, - eventSupportServices = List(TurretUpgradeSupport) - ) +object VehicleService { + def apply(): Props = { + Props( + classOf[GenericEventServiceWithCacheAndSupport], + VehicleStamp, + List(TurretUpgradeSupport) + ) + } +} diff --git a/src/test/scala/objects/DamageModelTests.scala b/src/test/scala/objects/DamageModelTests.scala index b19467e75..1dcd9757b 100644 --- a/src/test/scala/objects/DamageModelTests.scala +++ b/src/test/scala/objects/DamageModelTests.scala @@ -31,6 +31,9 @@ class DamageCalculationsTests extends Specification { val projectile = Projectile(proj, wep, wep_fmode, player, Vector3(2, 2, 0), Vector3.Zero) val target = Vehicle(GlobalDefinitions.fury) target.Position = Vector3(10, 0, 0) + player.GUID = PlanetSideGUID(1) + projectile.GUID = PlanetSideGUID(2) + target.GUID = PlanetSideGUID(3) val resprojectile = DamageInteraction( SourceEntry(target), ProjectileReason( @@ -271,6 +274,7 @@ class DamageCalculationsTests extends Specification { ) val minDamageBase = charge_weapon.Projectile.Charging.get.min.Damage0 val chargeBaseDamage = charge_weapon.Projectile.Damage0 + charge_projectile.GUID = PlanetSideGUID(1) "charge (none)" in { val cprojectile = charge_projectile.quality(ProjectileQuality.Modified(0)) @@ -329,6 +333,7 @@ class DamageCalculationsTests extends Specification { Vector3(2, 2, 0), Vector3.Zero ) + flak_projectile.GUID = PlanetSideGUID(1) "flak hit (resolution is splash, no degrade)" in { val resfprojectile = DamageInteraction( diff --git a/src/test/scala/objects/OrbitalShuttlePadTest.scala b/src/test/scala/objects/OrbitalShuttlePadTest.scala index 37d0de27b..170316a62 100644 --- a/src/test/scala/objects/OrbitalShuttlePadTest.scala +++ b/src/test/scala/objects/OrbitalShuttlePadTest.scala @@ -24,7 +24,7 @@ import scala.concurrent.duration._ class OrbitalShuttlePadControlTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ val services: ActorRef = ServiceManager.boot(system) - services ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + services ! ServiceManager.Register(GalaxyService(), "galaxy") services ! ServiceManager.Register(Props[HartService](), "hart") expectNoMessage(1000 milliseconds) var buildingMap = new TrieMap[Int, Building]() diff --git a/src/test/scala/objects/ResourceSiloTest.scala b/src/test/scala/objects/ResourceSiloTest.scala index c55288091..ef6683df6 100644 --- a/src/test/scala/objects/ResourceSiloTest.scala +++ b/src/test/scala/objects/ResourceSiloTest.scala @@ -151,7 +151,7 @@ class ResourceSiloControlStartupMessageSomeTest extends ActorTest { class ResourceSiloControlUseTest extends FreedContextActorTest { import akka.actor.typed.scaladsl.adapter._ - ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy") + ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy") expectNoMessage(1000 milliseconds) var buildingMap = new TrieMap[Int, Building]() val guid = new NumberPoolHub(new MaxNumberSource(max = 10)) diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index f7249152b..25b347acc 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -429,9 +429,4 @@ object ProximityTest { val avatarId = new AtomicInteger(0) class SampleTerminal extends Terminal(GlobalDefinitions.dropship_vehicle_terminal) with ProximityUnit - - class ProbedLocalService(probe: TestProbe, zone: Zone) extends LocalService(zone) { - self.tell(Service.Join("test"), probe.ref) - } - } diff --git a/src/test/scala/service/base/EnvelopeTest.scala b/src/test/scala/service/base/EnvelopeTest.scala index e62b036a7..4c760a117 100644 --- a/src/test/scala/service/base/EnvelopeTest.scala +++ b/src/test/scala/service/base/EnvelopeTest.scala @@ -79,7 +79,7 @@ class EnvelopeTest extends Specification { "construct (quick)" in { val input = GenericResponseEnvelope(TestStamp, "test", TestFilter, TestMessage(5)) input match { - case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) => + case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestMessage(5)) => reply.stamp mustEqual TestStamp case _ => ko diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala index 860eccf49..ad42c35e1 100644 --- a/src/test/scala/service/base/EventServiceCacheSupportTest.scala +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -8,7 +8,6 @@ import net.psforever.services.Service import net.psforever.services.base.message.EventMessage import net.psforever.services.base.{CachedEnvelope, CachedGenericEventEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} import net.psforever.types.PlanetSideGUID -import service.base.EventServiceSupportTest.TestSupportService import scala.concurrent.duration._ @@ -29,7 +28,7 @@ object EventServiceCacheSupportTest { def SpawnTestSystem(eventSupportServices: List[EventServiceSupport])(implicit system: ActorSystem, self: ActorRef): ActorRef = { val name = self.getClass.getSimpleName.replace("EventServiceCacheSupportTest", "") - system.actorOf(Props(classOf[TestSupportService], eventSupportServices), name = s"EventServiceCacheSupportTest.$name") + system.actorOf(Props(classOf[TestCacheService], eventSupportServices), name = s"EventServiceCacheSupportTest.$name") } } @@ -135,9 +134,9 @@ class EventServiceCacheSupportTestMultipleCachedSameMessages extends ActorTest { val secondMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(2)) val thirdMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(3)) //this one! events ! firstMessage + mainProbe.expectNoMessage(50 milliseconds) events ! secondMessage events ! thirdMessage - mainProbe.expectNoMessage(50 milliseconds) val reply = mainProbe.receiveOne(125 milliseconds) reply match { case badmsg if badmsg == firstMessage => @@ -148,6 +147,7 @@ class EventServiceCacheSupportTestMultipleCachedSameMessages extends ActorTest { case badmsg => assert(false, s"(7) expected delivery of test envelope, but received $badmsg instead") } + mainProbe.expectNoMessage(150 milliseconds) } } } diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala index 86f169dd0..0bde5e87f 100644 --- a/src/test/scala/service/base/EventServiceTest.scala +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -92,7 +92,7 @@ class EventServiceTestNotSubscribed extends ActorTest { events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) val reply = probe.receiveOne(100 milliseconds) reply match { - case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () case _ => assert(false, "(2) message expected but not received") } missedProbe.expectNoMessage(100 milliseconds) @@ -127,11 +127,11 @@ class EventServiceTestLeave extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(5)) val reply1 = probe.receiveN(2, 100 milliseconds) reply1.head match { - case GenericResponseEnvelope("/test", _, _) => () + case GenericResponseEnvelope("/test/out", _, _) => () case _ => assert(false, "(3) message expected but not received") } reply1(1) match { - case GenericResponseEnvelope("/anotherTest", _, _) => () + case GenericResponseEnvelope("/anotherTest/out", _, _) => () case _ => assert(false, "(4) message expected but not received") } @@ -140,7 +140,7 @@ class EventServiceTestLeave extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply2 = probe.receiveOne(100 milliseconds) reply2 match { - case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () case _ => assert(false, "(5) message expected but not received") } probe.expectNoMessage(250 milliseconds) @@ -148,7 +148,7 @@ class EventServiceTestLeave extends ActorTest { } } -class EventServiceTestLeaveAll1 extends ActorTest { +class EventServiceTestLeaveAll extends ActorTest { import EventServiceTestBase._ "GenericEventSystem" should { "leave all channels (1)" in { @@ -161,40 +161,11 @@ class EventServiceTestLeaveAll1 extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply = probe.receiveN(2,100 milliseconds) reply.head match { - case GenericResponseEnvelope("/test", _, TestMessage(5)) => () + case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () case _ => assert(false, "(6) message expected but not received") } reply(1) match { - case GenericResponseEnvelope("/anotherTest", _, TestMessage(6)) => () - case _ => assert(false, "(7) message expected but not received") - } - - events.tell(Service.LeaveAll, probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) - events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) - probe.expectNoMessage(250 milliseconds) - } - } -} - -class EventServiceTestLeaveAll2 extends ActorTest { - import EventServiceTestBase._ - "GenericEventSystem" should { - "leave all channels" in { - val probe = TestProbe("testProbe") - val events = EventServiceTest.SpawnTestSystem() - events.tell(Service.Join("test"), probe.ref) - events.tell(Service.Join("anotherTest"), probe.ref) - - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) - events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) - val reply = probe.receiveN(2,100 milliseconds) - reply.head match { - case GenericResponseEnvelope("/test", _, TestMessage(5)) => () - case _ => assert(false, "(6) message expected but not received") - } - reply(1) match { - case GenericResponseEnvelope("/anotherTest", _, TestMessage(6)) => () + case GenericResponseEnvelope("/anotherTest/out", _, TestMessage(6)) => () case _ => assert(false, "(7) message expected but not received") } From dbd90e6eb19142c9a8796560b443834e8532136c Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Thu, 5 Mar 2026 14:53:32 -0500 Subject: [PATCH 17/32] changing the reporting visibility of the event bus broadcast channel and removing the need to maintain an 'original channel' --- .../avatar/support/CorpseRemovalActor.scala | 2 +- .../avatar/support/DroppedItemRemover.scala | 4 ++-- .../services/base/GenericEventService.scala | 11 ++++++----- ...nericEventServiceWithCacheAndSupport.scala | 2 +- .../services/base/bus/GenericEventBus.scala | 19 ++++++++++--------- .../services/base/envelope/AllEnvelopes.scala | 4 ++-- .../envelope/GenericMessageEnvelope.scala | 4 +--- .../envelope/GenericResponseEnvelope.scala | 2 ++ .../base/envelope/MessageEnvelope.scala | 11 ++++------- .../services/galaxy/GalaxyService.scala | 2 +- .../local/support/DoorCloseActor.scala | 2 +- .../local/support/HackClearActor.scala | 2 +- .../scala/objects/FacilityTurretTest.scala | 1 - src/test/scala/objects/RepairableTest.scala | 1 - .../scala/objects/VehicleControlTest.scala | 2 +- .../objects/terminal/ProximityTest.scala | 1 - .../scala/service/base/EnvelopeTest.scala | 6 +++--- .../base/EventServiceCacheSupportTest.scala | 2 +- .../scala/service/base/EventServiceTest.scala | 12 ++++++------ .../service/base/EventServiceTestBase.scala | 2 +- 20 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 7a1f16e00..4f86597e8 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -13,7 +13,7 @@ import net.psforever.services.base.message.ObjectDelete import scala.concurrent.duration._ final case class ReleaseEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: Release ) diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index 8224c53af..bb74a68e6 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -14,7 +14,7 @@ import net.psforever.types.PlanetSideGUID import scala.concurrent.duration._ final case class PickupItemEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: PickupItem, zone: Zone @@ -33,7 +33,7 @@ object PickupItemEnvelope { } final case class DropItemEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: DropItem, zone: Zone diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index a9dee3312..183daf018 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -18,11 +18,12 @@ import org.log4s.Logger */ trait EventSystemStamp { /* - Example Classifiers: "foo", "foo.fizz", and "foo.buzz" - In general, Classifier channels will perform left-pattern matching. - "foo" will publish to "foo", "foo.fizz", and "foo.buzz" - To isolate "foo", one must distinguish it with a right-pattern. - "foo" is appended as "foo.bar" and no longer publishes to "foo.fizz.bar" or to "foo.buzz.bar" + Example: + The channels are "foo", "foo.fizz", and "foo.buzz" + In general, Classifier channels will perform left-pattern matching + Publishing to channel "foo" will allocate Classifiers "foo", "foo.fizz", and "foo.buzz" + To isolate "foo", one must distinguish it with a right-pattern such as "out" + Publishing to channel "foo.out" no longer publishes to "foo.fizz.out" or to "foo.buzz.out" */ /** * Take an input channel and produce the publishing output channel. diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index 665d90b6e..ee5a283ac 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -31,7 +31,7 @@ trait CachedGenericEventEnvelope final case class CachedEnvelope( guid: PlanetSideGUID, - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: EventMessage ) extends CachedGenericEventEnvelope { diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala index b130d8eff..57454399d 100644 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala @@ -20,19 +20,20 @@ class GenericEventBus type Event = GenericResponseEnvelope type Classifier = String - protected def classify(event: Event): Classifier = event.channel + protected def classify(event: Event): Classifier = event.outChannel /* - Example Classifiers: "foo", "foo.fizz", and "foo.buzz" - In general, Classifier channels will perform left-pattern matching. - "foo" will publish to "foo", "foo.fizz", and "foo.buzz" + Example: + The channels are "foo", "foo.fizz", and "foo.buzz" + In general, Classifier channels will perform left-pattern matching + Publishing to channel "foo" will allocate Classifiers "foo", "foo.fizz", and "foo.buzz" + See `GenericResponseEnvelope.outChannel` to determine how this is applied */ - protected def subclassification: Subclassification[String] = - new Subclassification[Classifier] { - def isEqual(x: Classifier, y: Classifier): Boolean = x == y + protected def subclassification: Subclassification[String] = new Subclassification[Classifier] { + def isEqual(x: Classifier, y: Classifier): Boolean = x.equals(y) - def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y) - } + def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y) + } override def publish(event: Event): Unit = { super[SubchannelClassification].publish(event) diff --git a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala index aa737c55d..7e067d5d5 100644 --- a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala +++ b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala @@ -8,8 +8,8 @@ import net.psforever.types.PlanetSideGUID * Defines a channel and a filter, both of which server the purpose of routing the message to its destination. */ trait AllEnvelopes { - /** set of subscribers on an event system bus the envelope should reach */ + /** set of subscribers on an event system bus that the envelope should reach */ def channel: String - /** specific subscriber endpoint to be excluded (the subscriber should filter themselves) */ + /** specific subscriber endpoint to be excluded (the subscriber should filter themselves upon receipt) */ def filter: PlanetSideGUID } diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala index d792ce4ec..eaa62e792 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala @@ -7,8 +7,6 @@ import net.psforever.types.PlanetSideGUID trait GenericMessageEnvelope extends AllEnvelopes { - /** channel information provided with the message */ - def originalChannel: String /** input payload transported by this envelope */ def msg: EventMessage /** method that counts as "processing" the envelope by an event system; @@ -25,6 +23,6 @@ object GenericMessageEnvelope { * @return a tuple containing the channel, filter, and reply message */ def unapply(obj: GenericMessageEnvelope): Option[(String, PlanetSideGUID, EventMessage)] = { - Some((obj.originalChannel, obj.filter, obj.msg)) + Some((obj.channel, obj.filter, obj.msg)) } } diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala index 5b77aeca6..001513b10 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala @@ -14,6 +14,8 @@ trait GenericResponseEnvelope def reply: EventResponse /** marker indicating the routing through which the original message was processed */ def stamp: EventSystemStamp + /** channel information tailored to the event system */ + def outChannel: String = stamp.routing(channel) } object GenericResponseEnvelope { diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala index db555c944..9ab7f8a09 100644 --- a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -14,7 +14,9 @@ case object NoReply extends EventResponse * A stamp that represents not having been processed by an event system. * Should never been given out to an event system. */ -case object Undelivered extends EventSystemStamp +case object Undelivered extends EventSystemStamp { + override def routing(channel: String): String = "" +} /** * The mechanics of a proper event system envelope. @@ -32,16 +34,11 @@ trait MessageTransformationBehavior extends GenericMessageEnvelope with GenericResponseEnvelope { private var outputStamp: EventSystemStamp = Undelivered - private var outputChannel: String = originalChannel private var outputReply: EventResponse = NoReply - // satisfies GenericMessageEnvelope (and GenericResponseEnvelope) - def channel: String = outputChannel - // satisfies GenericMessageEnvelope def response(stamp: EventSystemStamp): GenericResponseEnvelope = { outputStamp = stamp - outputChannel = stamp.routing(originalChannel) outputReply = msg.response() this } @@ -54,5 +51,5 @@ trait MessageTransformationBehavior /** * A proper event system envelope. */ -case class MessageEnvelope(originalChannel: String, filter: PlanetSideGUID, msg: EventMessage) +case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) extends MessageTransformationBehavior diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index b3d4c084e..79569a4e0 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -9,7 +9,7 @@ case object GalaxyStamp extends EventSystemStamp { if (channel.trim.isEmpty) { "/out" } else { - s"/$channel/out" + super.routing(channel) } } } diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index a8ad7e9ae..67387b6f7 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -15,7 +15,7 @@ import scala.annotation.tailrec import scala.concurrent.duration._ final case class DoorMessage( - originalChannel: String, + channel: String, msg: IsADoorMessage, supportMessage: Any ) extends GenericSupportEnvelope { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index 5f6d964f6..92b02dec2 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -18,7 +18,7 @@ import scala.annotation.tailrec import scala.concurrent.duration._ final case class HackEntityEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: IsAHackMessage, supportMessage: Any diff --git a/src/test/scala/objects/FacilityTurretTest.scala b/src/test/scala/objects/FacilityTurretTest.scala index bba0f9570..105652f08 100644 --- a/src/test/scala/objects/FacilityTurretTest.scala +++ b/src/test/scala/objects/FacilityTurretTest.scala @@ -19,7 +19,6 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import org.specs2.mutable.Specification -import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index a558b6487..20d49812f 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -17,7 +17,6 @@ import net.psforever.objects.vehicles.control.VehicleControl import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ -import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index 54306b8ae..e57ed428f 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -27,7 +27,7 @@ import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types._ import scala.concurrent.duration._ diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index 25b347acc..2d6334774 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -14,7 +14,6 @@ import net.psforever.objects.{GlobalDefinitions, Player} import net.psforever.types.{CharacterSex, CharacterVoice, PlanetSideEmpire, PlanetSideGUID} import org.specs2.mutable.Specification import net.psforever.services.Service -import net.psforever.services.local.LocalService import scala.concurrent.duration._ import akka.actor.typed.scaladsl.adapter._ diff --git a/src/test/scala/service/base/EnvelopeTest.scala b/src/test/scala/service/base/EnvelopeTest.scala index 4c760a117..b2f11c1f5 100644 --- a/src/test/scala/service/base/EnvelopeTest.scala +++ b/src/test/scala/service/base/EnvelopeTest.scala @@ -56,7 +56,7 @@ class EnvelopeTest extends Specification { val input = MessageEnvelope("test", TestFilter, TestMessage(5)) val output = input.response(TestStamp) output match { - case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestMessage(5)) => + case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) => reply.stamp mustEqual TestStamp case _ => ko @@ -67,7 +67,7 @@ class EnvelopeTest extends Specification { val input = MessageEnvelope("test", TestFilter, TestInputMessage(5)) val output = input.response(TestStamp) output match { - case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestOutputEvent(7)) => + case reply @ GenericResponseEnvelope("test", TestFilter, TestOutputEvent(7)) => reply.stamp mustEqual TestStamp case _ => ko @@ -79,7 +79,7 @@ class EnvelopeTest extends Specification { "construct (quick)" in { val input = GenericResponseEnvelope(TestStamp, "test", TestFilter, TestMessage(5)) input match { - case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestMessage(5)) => + case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) => reply.stamp mustEqual TestStamp case _ => ko diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala index ad42c35e1..6ff7932f5 100644 --- a/src/test/scala/service/base/EventServiceCacheSupportTest.scala +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -14,7 +14,7 @@ import scala.concurrent.duration._ object EventServiceCacheSupportTest { final case class CachedSupportTestEnvelope( guid: PlanetSideGUID, - originalChannel: String, + channel: String, override val msg: EventMessage, supportMessage: Any ) extends CachedGenericEventEnvelope with GenericSupportEnvelope { diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala index 0bde5e87f..8bfbf61dd 100644 --- a/src/test/scala/service/base/EventServiceTest.scala +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -92,7 +92,7 @@ class EventServiceTestNotSubscribed extends ActorTest { events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) val reply = probe.receiveOne(100 milliseconds) reply match { - case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () + case GenericResponseEnvelope("test", _, TestMessage(5)) => () case _ => assert(false, "(2) message expected but not received") } missedProbe.expectNoMessage(100 milliseconds) @@ -127,11 +127,11 @@ class EventServiceTestLeave extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(5)) val reply1 = probe.receiveN(2, 100 milliseconds) reply1.head match { - case GenericResponseEnvelope("/test/out", _, _) => () + case GenericResponseEnvelope("test", _, _) => () case _ => assert(false, "(3) message expected but not received") } reply1(1) match { - case GenericResponseEnvelope("/anotherTest/out", _, _) => () + case GenericResponseEnvelope("anotherTest", _, _) => () case _ => assert(false, "(4) message expected but not received") } @@ -140,7 +140,7 @@ class EventServiceTestLeave extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply2 = probe.receiveOne(100 milliseconds) reply2 match { - case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () + case GenericResponseEnvelope("test", _, TestMessage(5)) => () case _ => assert(false, "(5) message expected but not received") } probe.expectNoMessage(250 milliseconds) @@ -161,11 +161,11 @@ class EventServiceTestLeaveAll extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply = probe.receiveN(2,100 milliseconds) reply.head match { - case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () + case GenericResponseEnvelope("test", _, TestMessage(5)) => () case _ => assert(false, "(6) message expected but not received") } reply(1) match { - case GenericResponseEnvelope("/anotherTest/out", _, TestMessage(6)) => () + case GenericResponseEnvelope("anotherTest", _, TestMessage(6)) => () case _ => assert(false, "(7) message expected but not received") } diff --git a/src/test/scala/service/base/EventServiceTestBase.scala b/src/test/scala/service/base/EventServiceTestBase.scala index f5ac013d7..40718e204 100644 --- a/src/test/scala/service/base/EventServiceTestBase.scala +++ b/src/test/scala/service/base/EventServiceTestBase.scala @@ -29,7 +29,7 @@ object EventServiceTestBase { } final case class TestSupportEnvelope( - originalChannel: String, + channel: String, msg: SupportActorRepliesWith ) extends GenericSupportEnvelope { def filter: PlanetSideGUID = Service.defaultPlayerGUID From cbf6aa5ebb18452cfed2aebbb92b21da3ae24824 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 8 Mar 2026 14:27:25 -0400 Subject: [PATCH 18/32] removed event system implied instances of MessageEnvelope overloaded constructors and replaced them directly with MessageEnvelope; included additional places where SendResponse could combine dispatch; support actors have both constructor classes and custom envelopes stored in the same file as the actor itself for better readability --- .codecov.yml | 4 - .../actor/service/AvatarServiceTest.scala | 657 ------------------ .../actors/session/AvatarActor.scala | 33 +- .../actors/session/csr/ChatLogic.scala | 13 +- .../CustomerServiceRepresentativeMode.scala | 14 +- .../actors/session/csr/GeneralLogic.scala | 11 +- .../session/csr/MountHandlerLogic.scala | 16 +- ...eAsCustomerServiceRepresentativeMode.scala | 7 +- .../actors/session/csr/VehicleLogic.scala | 11 +- .../session/normal/AvatarHandlerLogic.scala | 11 +- .../session/normal/GalaxyHandlerLogic.scala | 5 +- .../actors/session/normal/GeneralLogic.scala | 9 +- .../session/normal/MountHandlerLogic.scala | 14 +- .../actors/session/normal/VehicleLogic.scala | 5 +- .../spectator/AvatarHandlerLogic.scala | 5 +- .../session/spectator/GeneralLogic.scala | 7 +- .../session/spectator/MountHandlerLogic.scala | 12 +- .../session/spectator/SpectatorMode.scala | 4 +- .../session/spectator/VehicleLogic.scala | 5 +- .../session/support/GeneralOperations.scala | 35 +- .../support/SessionAvatarHandlers.scala | 7 +- .../actors/session/support/SessionData.scala | 5 +- .../support/SessionMountHandlers.scala | 18 +- .../support/SessionOutfitHandlers.scala | 25 +- .../support/SessionSquadHandlers.scala | 6 +- .../WeaponAndProjectileOperations.scala | 46 +- .../session/support/ZoningOperations.scala | 71 +- .../psforever/actors/zone/BuildingActor.scala | 16 +- .../net/psforever/actors/zone/ZoneActor.scala | 10 +- .../zone/building/CavernFacilityLogic.scala | 5 +- .../actors/zone/building/FacilityLogic.scala | 5 +- .../zone/building/MajorFacilityLogic.scala | 54 +- .../actors/zone/building/WarpGateLogic.scala | 7 +- .../net/psforever/login/WorldSession.scala | 27 +- .../psforever/objects/BoomerDeployable.scala | 10 +- .../net/psforever/objects/Deployables.scala | 5 +- .../objects/ExplosiveDeployable.scala | 11 +- .../objects/FieldTurretDeployable.scala | 4 +- .../scala/net/psforever/objects/Players.scala | 21 +- .../psforever/objects/SensorDeployable.scala | 18 +- .../objects/ShieldGeneratorDeployable.scala | 8 +- .../psforever/objects/TelepadDeployable.scala | 5 +- .../scala/net/psforever/objects/Tools.scala | 4 +- .../psforever/objects/TurretDeployable.scala | 5 +- .../net/psforever/objects/Vehicles.scala | 38 +- .../objects/avatar/CorpseControl.scala | 10 +- .../objects/avatar/PlayerControl.scala | 104 +-- .../avatar/interaction/WithEntrance.scala | 8 +- .../avatar/interaction/WithGantry.scala | 6 +- .../avatar/interaction/WithWater.scala | 5 +- .../objects/avatar/scoring/Statistic.scala | 2 +- .../objects/ce/DeployableBehavior.scala | 18 +- .../psforever/objects/ce/TelepadLike.scala | 15 +- .../equipment/ArmorSiphonBehavior.scala | 8 +- .../objects/equipment/JammingUnit.scala | 9 +- .../locker/LockerContainerControl.scala | 10 +- .../damage/DamageableAmenity.scala | 12 +- .../damage/DamageableEntity.scala | 13 +- .../damage/DamageableMountable.scala | 8 +- .../damage/DamageableVehicle.scala | 21 +- .../damage/DamageableWeaponTurret.scala | 12 +- .../deploy/DeploymentBehavior.scala | 11 +- .../generator/GeneratorControl.scala | 4 +- .../hackable/GenericHackables.scala | 20 +- .../pad/VehicleSpawnControl.scala | 20 +- .../VehicleSpawnControlConcealPlayer.scala | 4 +- .../VehicleSpawnControlDriverControl.scala | 4 +- .../VehicleSpawnControlFinalClearance.scala | 7 +- .../VehicleSpawnControlLoadVehicle.scala | 5 +- .../process/VehicleSpawnControlRailJack.scala | 4 +- .../VehicleSpawnControlSeatDriver.scala | 6 +- ...cleSpawnControlServerVehicleOverride.scala | 8 +- .../repair/RepairableAmenity.scala | 12 +- .../repair/RepairableEntity.scala | 10 +- .../repair/RepairableWeaponTurret.scala | 8 +- .../resourcesilo/ResourceSiloControl.scala | 16 +- .../shuttle/OrbitalShuttlePadControl.scala | 5 +- .../FacilityHackParticipation.scala | 14 +- .../MajorFacilityHackParticipation.scala | 12 +- .../TowerHackParticipation.scala | 7 +- .../terminals/ProximityTerminalControl.scala | 23 +- .../terminals/capture/CaptureTerminals.scala | 5 +- .../implant/ImplantTerminalMechControl.scala | 14 +- .../turret/FacilityTurretControl.scala | 9 +- .../serverobject/turret/TurretControl.scala | 17 +- .../turret/VanuSentryControl.scala | 5 +- .../serverobject/turret/WeaponTurrets.scala | 16 +- .../turret/auto/AutomatedTurretBehavior.scala | 10 +- .../vehicles/AntTransferBehavior.scala | 25 +- .../vehicles/BfrTransferBehavior.scala | 5 +- .../objects/vehicles/CarrierBehavior.scala | 29 +- .../objects/vehicles/control/AmsControl.scala | 11 +- .../objects/vehicles/control/ApcControl.scala | 4 +- .../objects/vehicles/control/BfrControl.scala | 14 +- .../vehicles/control/VehicleCapacitance.scala | 4 +- .../vehicles/control/VehicleControl.scala | 37 +- .../interaction/WithEntranceInVehicle.scala | 4 +- .../net/psforever/objects/zones/MapInfo.scala | 7 +- .../objects/zones/ZoneDeployableActor.scala | 4 +- .../objects/zones/ZoneHotSpotProjector.scala | 5 +- .../objects/zones/ZoneProjectileActor.scala | 11 +- .../objects/zones/ZoneVehicleActor.scala | 4 +- .../objects/zones/exp/KillAssists.scala | 6 +- .../objects/zones/exp/KillContributions.scala | 7 +- .../services/CavernRotationService.scala | 13 +- .../account/AccountPersistenceService.scala | 16 +- .../services/avatar/AvatarService.scala | 22 +- .../avatar/AvatarServiceMessage.scala | 15 - .../avatar/support/CorpseRemovalActor.scala | 18 +- .../avatar/support/DroppedItemRemover.scala | 18 +- .../base/envelope/MessageEnvelope.scala | 9 + .../{ => base/support}/RemoverActor.scala | 3 +- .../galaxy/GalaxyServiceMessage.scala | 12 - .../psforever/services/hart/HartTimer.scala | 14 +- .../services/hart/HartTimerActions.scala | 9 +- .../services/local/LocalService.scala | 37 +- .../services/local/LocalServiceMessage.scala | 15 - .../local/support/CaptureFlagManager.scala | 37 +- .../local/support/DoorCloseActor.scala | 17 +- .../local/support/HackCaptureActor.scala | 21 +- .../local/support/HackClearActor.scala | 22 +- .../services/vehicle/VehicleService.scala | 14 +- .../vehicle/VehicleServiceMessage.scala | 15 - .../vehicle/support/TurretUpgrader.scala | 19 +- 124 files changed, 851 insertions(+), 1518 deletions(-) delete mode 100644 server/src/test/scala/actor/service/AvatarServiceTest.scala delete mode 100644 src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala rename src/main/scala/net/psforever/services/{ => base/support}/RemoverActor.scala (98%) delete mode 100644 src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala delete mode 100644 src/main/scala/net/psforever/services/local/LocalServiceMessage.scala delete mode 100644 src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala diff --git a/.codecov.yml b/.codecov.yml index 80ad89238..3c69d86ed 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -75,26 +75,22 @@ ignore: - "src/main/scala/net/psforever/services/account/StoreIPAddress.scala" - "src/main/scala/net/psforever/services/avatar/AvatarAction.scala" - "src/main/scala/net/psforever/services/avatar/AvatarService.scala" - - "src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala" - "src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala" - "src/main/scala/net/psforever/services/base/bus" - "src/main/scala/net/psforever/services/base/envelope" - "src/main/scala/net/psforever/services/chat/ChatChannel.scala" - "src/main/scala/net/psforever/services/galaxy/GalaxyAction" - "src/main/scala/net/psforever/services/galaxy/GalaxyService" - - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala" - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala" - "src/main/scala/net/psforever/services/hart/HartEvent.scala" - "src/main/scala/net/psforever/services/hart/HartTimerActions.scala" - "src/main/scala/net/psforever/services/local/LocalAction" - "src/main/scala/net/psforever/services/local/LocalService" - - "src/main/scala/net/psforever/services/local/LocalServiceMessage.scala" - "src/main/scala/net/psforever/services/local/LocalServiceResponse.scala" - "src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala" - "src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala" - "src/main/scala/net/psforever/services/vehicle/VehicleAction" - "src/main/scala/net/psforever/services/vehicle/VehicleService" - - "src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala" - "src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala" - "src/main/scala/net/psforever/services/Service.scala" - "src/main/scala/net/psforever/types" diff --git a/server/src/test/scala/actor/service/AvatarServiceTest.scala b/server/src/test/scala/actor/service/AvatarServiceTest.scala deleted file mode 100644 index 001d65d10..000000000 --- a/server/src/test/scala/actor/service/AvatarServiceTest.scala +++ /dev/null @@ -1,657 +0,0 @@ -// Copyright (c) 2017 PSForever -package actor.service - -import akka.actor.Props -import akka.testkit.TestProbe - -import scala.concurrent.duration._ -import actor.base.{ActorTest, FreedContextActorTest} -import net.psforever.objects._ -import net.psforever.objects.avatar.Avatar -import net.psforever.objects.guid.NumberPoolHub -import net.psforever.objects.guid.source.MaxNumberSource -import net.psforever.objects.zones.{Zone, ZoneMap} -import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectClass, ObjectCreateMessageParent, PlacementData} -import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstream} -import net.psforever.types._ -import net.psforever.services.{RemoverActor, Service, ServiceManager} -import net.psforever.services.avatar._ -import net.psforever.services.avatar.support.{CorpseEnvelope, DropItemEnvelope, PickupItemEnvelope, ReleaseEnvelope} -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire} - -class AvatarService1Test extends ActorTest { - "AvatarService" should { - "construct" in { - ServiceManager.boot(system) - system.actorOf(AvatarService(), AvatarServiceTest.TestName) - assert(true) - } - } -} - -class AvatarService2Test extends ActorTest { - "AvatarService" should { - "subscribe" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - assert(true) - } - } -} - -class AvatarService3Test extends ActorTest { - "AvatarService" should { - ServiceManager.boot(system) - "subscribe to a specific channel" in { - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! Service.LeaveAll - assert(true) - } - } -} - -class AvatarService4Test extends ActorTest { - "AvatarService" should { - "subscribe" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! Service.LeaveAll - assert(true) - } - } -} - -class AvatarService5Test extends ActorTest { - "AvatarService" should { - "pass an unhandled message" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! "hello" - expectNoMessage() - } - } -} - -class ArmorChangedTest extends ActorTest { - "AvatarService" should { - "pass ArmorChanged" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ArmorChanged(ExoSuitType.Reinforced, 0)) - expectMsg( - AvatarServiceResponse( - "/test/Avatar", - PlanetSideGUID(10), - AvatarAction.ArmorChanged(ExoSuitType.Reinforced, 0) - ) - ) - } - } -} - -class ConcealPlayerTest extends ActorTest { - "AvatarService" should { - "pass ConcealPlayer" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", ConcealPlayer(PlanetSideGUID(10))) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ConcealPlayer(PlanetSideGUID(10)))) - } - } -} - -class EquipmentInHandTest extends ActorTest { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), "release-test-service") - val toolDef = GlobalDefinitions.beamer - val tool = Tool(toolDef) - tool.GUID = PlanetSideGUID(40) - tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(41) - val pkt = ObjectCreateMessage( - toolDef.ObjectId, - tool.GUID, - ObjectCreateMessageParent(PlanetSideGUID(11), 2), - toolDef.Packet.ConstructorData(tool).get - ) - - "AvatarService" should { - "pass EquipmentInHand" in { - service ! Service.Join("test") - service ! AvatarServiceMessage( - "test", - PlanetSideGUID(10), - AvatarAction.EquipmentInHand(PlanetSideGUID(11), 2, tool) - ) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.EquipmentCreatedInHand(pkt))) - } - } -} - -class DroptItemTest extends ActorTest { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), "release-test-service") - val toolDef = GlobalDefinitions.beamer - val tool = Tool(toolDef) - tool.Position = Vector3(1, 2, 3) - tool.Orientation = Vector3(4, 5, 6) - tool.GUID = PlanetSideGUID(40) - tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(41) - val pkt = ObjectCreateMessage( - toolDef.ObjectId, - tool.GUID, - DroppedItemData( - PlacementData(tool.Position, tool.Orientation), - toolDef.Packet.ConstructorData(tool).get - ) - ) - - "AvatarService" should { - "pass DropItem" in { - service ! Service.Join("test") - service ! DropItemEnvelope("test", PlanetSideGUID(10), AvatarAction.DropItem(tool), Zone.Nowhere) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.DropCreatedItem(pkt))) - } - } -} - -class LoadPlayerTest extends ActorTest { - val obj = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1)) - obj.GUID = PlanetSideGUID(10) - obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(11) - val c1data = obj.Definition.Packet.DetailedConstructorData(obj).get - val pkt1 = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(10), c1data) - val parent = ObjectCreateMessageParent(PlanetSideGUID(12), 0) - obj.VehicleSeated = PlanetSideGUID(12) - val c2data = obj.Definition.Packet.DetailedConstructorData(obj).get - val pkt2 = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(10), parent, c2data) - - "AvatarService" should { - "pass LoadPlayer" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - //no parent data - service ! AvatarServiceMessage( - "test", - PlanetSideGUID(20), - AvatarAction.LoadPlayer(ObjectClass.avatar, PlanetSideGUID(10), c1data, None) - ) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarAction.LoadCreatedPlayer(pkt1))) - //parent data - service ! AvatarServiceMessage( - "test", - PlanetSideGUID(20), - AvatarAction.LoadPlayer(ObjectClass.avatar, PlanetSideGUID(10), c2data, Some(parent)) - ) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarAction.LoadCreatedPlayer(pkt2))) - } - } -} - -class ObjectDeleteTest extends ActorTest { - "AvatarService" should { - "pass ObjectDelete" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11))) - expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11), 0)) - ) - - service ! AvatarServiceMessage("test", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11), 55)) - expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(PlanetSideGUID(11), 55)) - ) - } - } -} - -class ObjectHeldTest extends ActorTest { - "AvatarService" should { - "pass ObjectHeld" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ObjectHeld(1, 2))) - } - } -} - -class PutDownFDUTest extends ActorTest { - "AvatarService" should { - "pass PutDownFDU" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10))) - expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.PutDownFDU(PlanetSideGUID(10))) - ) - } - } -} - -class PlanetsideAttributeTest extends ActorTest { - "AvatarService" should { - "pass PlanetsideAttribute" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L)) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))) - } - } -} - -class PlayerStateTest extends ActorTest { - val msg = PlayerStateMessageUpstream( - PlanetSideGUID(75), - Vector3(3694.1094f, 2735.4531f, 90.84375f), - Some(Vector3(4.375f, 2.59375f, 0.0f)), - 61.875f, - 351.5625f, - 0.0f, - 136, - 0, - false, - false, - false, - false, - 112, - 0 - ) - - "AvatarService" should { - "pass PlayerState" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage( - "test", - PlanetSideGUID(10), - AvatarAction.PlayerState( - Vector3(3694.1094f, 2735.4531f, 90.84375f), - Some(Vector3(4.375f, 2.59375f, 0.0f)), - 61.875f, - 351.5625f, - 0.0f, - 136, - false, - false, - false, - false, - false, - false - ) - ) - expectMsg( - AvatarServiceResponse( - "/test/Avatar", - PlanetSideGUID(10), - AvatarAction.PlayerState( - Vector3(3694.1094f, 2735.4531f, 90.84375f), - Some(Vector3(4.375f, 2.59375f, 0.0f)), - 61.875f, - 351.5625f, - 0.0f, - 136, - false, - false, - false, - false, - false, - false - ) - ) - ) - } - } -} - -class PickupItemTest extends ActorTest { - val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1)) - val tool = Tool(GlobalDefinitions.beamer) - tool.GUID = PlanetSideGUID(40) - - "pass PickUpItem" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! PickupItemEnvelope("test", AvatarAction.PickupItem(tool), Zone.Nowhere) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0))) - } -} - -class ReloadTest extends ActorTest { - "AvatarService" should { - "pass Reload" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), ReloadTool(PlanetSideGUID(40))) - expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ReloadTool(PlanetSideGUID(40)))) - } - } -} - -class ChangeAmmoTest extends ActorTest { - val ammoDef = GlobalDefinitions.energy_cell - val ammoBox = AmmoBox(ammoDef) - - "AvatarService" should { - "pass ChangeAmmo" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage( - "test", - PlanetSideGUID(10), - ChangeAmmo( - PlanetSideGUID(40), - 0, - PlanetSideGUID(40), - ammoDef.ObjectId, - PlanetSideGUID(41), - ammoDef.Packet.ConstructorData(ammoBox).get - ) - ) - expectMsg( - AvatarServiceResponse( - "/test/Avatar", - PlanetSideGUID(10), - ChangeAmmo( - PlanetSideGUID(40), - 0, - PlanetSideGUID(40), - ammoDef.ObjectId, - PlanetSideGUID(41), - ammoDef.Packet.ConstructorData(ammoBox).get - ) - ) - ) - } - } -} - -class ChangeFireModeTest extends ActorTest { - val ammoDef = GlobalDefinitions.energy_cell - val ammoBox = AmmoBox(ammoDef) - - "AvatarService" should { - "pass ChangeFireMode" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), AvatarAction.ChangeFireMode(PlanetSideGUID(40), 0)) - expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.ChangeFireMode(PlanetSideGUID(40), 0)) - ) - } - } -} - -class ChangeFireStateStartTest extends ActorTest { - "AvatarService" should { - "pass ChangeFireState_Start" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Start(PlanetSideGUID(40))) - expectMsg( - AvatarServiceResponse( - "/test/Avatar", - PlanetSideGUID(10), - ChangeFireState_Start(PlanetSideGUID(40)) - ) - ) - } - } -} - -class ChangeFireStateStopTest extends ActorTest { - "AvatarService" should { - "pass ChangeFireState_Stop" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), ChangeFireState_Stop(PlanetSideGUID(40))) - expectMsg( - AvatarServiceResponse( - "/test/Avatar", - PlanetSideGUID(10), - ChangeFireState_Stop(PlanetSideGUID(40)) - ) - ) - } - } -} - -class WeaponDryFireTest extends ActorTest { - "AvatarService" should { - "pass WeaponDryFire" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage("test", PlanetSideGUID(10), WeaponDryFire(PlanetSideGUID(40))) - expectMsg( - AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), WeaponDryFire(PlanetSideGUID(40))) - ) - } - } -} - -class AvatarStowEquipmentTest extends ActorTest { - val tool = Tool(GlobalDefinitions.beamer) - - "AvatarService" should { - "pass StowEquipment" in { - ServiceManager.boot(system) - val service = system.actorOf(AvatarService(), AvatarServiceTest.TestName) - service ! Service.Join("test") - service ! AvatarServiceMessage( - "test", - PlanetSideGUID(10), - AvatarAction.StowEquipment(PlanetSideGUID(11), 2, tool) - ) - expectMsg( - AvatarServiceResponse( - "/test/Avatar", - PlanetSideGUID(10), - AvatarAction.StowEquipment(PlanetSideGUID(11), 2, tool) - ) - ) - } - } -} - -/* -Preparation for these three Release tests is involved. -The ServiceManager must be set up correctly. -The Zone needs to be set up and initialized properly with a ZoneActor. -The ZoneActor builds the GUID Actor and the ZonePopulationActor. - -ALL of these Actors will talk to each other. -The lines of communication can short circuit if the next Actor does not have the correct information. -Putting Actor startup in the main class, outside of the body of the test, helps. -Frequent pauses to allow everything to sort their messages also helps. -Even with all this work, the tests have a high chance of failure just due to being asynchronous. - */ -class AvatarReleaseTest extends FreedContextActorTest { - val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(15)) - val zone = new Zone("test", new ZoneMap("test-map"), 0) { - override def SetupNumberPools() : Unit = { } - GUID(guid) - } - zone.init(context) - val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1)) - guid.register(obj) - guid.register(obj.Slot(5).Equipment.get) - obj.Zone = zone - obj.Release - val subscriber = new TestProbe(system) - - "AvatarService" should { - "pass Release" in { - expectNoMessage(100 milliseconds) //spacer - - zone.AvatarEvents.tell(Service.Join("test"), subscriber.ref) - assert(zone.Corpses.isEmpty) - zone.Population ! Zone.Corpse.Add(obj) - subscriber.expectNoMessage(200 milliseconds) //spacer - - assert(zone.Corpses.size == 1) - assert(obj.HasGUID) - val guid = obj.GUID - zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second - - val reply1 = subscriber.receiveOne(200 milliseconds) - assert(reply1.isInstanceOf[AvatarServiceResponse]) - val reply1msg = reply1.asInstanceOf[AvatarServiceResponse] - assert(reply1msg.channel == "/test/Avatar") - assert(reply1msg.filter == guid) - assert(reply1msg.reply.isInstanceOf[AvatarAction.Release]) - assert(reply1msg.reply.asInstanceOf[AvatarAction.Release].player == obj) - - val reply2 = subscriber.receiveOne(2 seconds) - assert(reply2.isInstanceOf[AvatarServiceResponse]) - val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] - assert(reply2msg.channel.equals("/test/Avatar")) - assert(reply2msg.filter == Service.defaultPlayerGUID) - assert(reply2msg.reply.isInstanceOf[ObjectDelete]) - assert(reply2msg.reply.asInstanceOf[ObjectDelete].obj_guid == guid) - - subscriber.expectNoMessage(1 seconds) - assert(zone.Corpses.isEmpty) - assert(!obj.HasGUID) - } - } -} - -class AvatarReleaseEarly1Test extends FreedContextActorTest { - val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(15)) - val zone = new Zone("test", new ZoneMap("test-map"), 0) { - override def SetupNumberPools() : Unit = { } - GUID(guid) - } - zone.init(context) - val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1)) - guid.register(obj) - guid.register(obj.Slot(5).Equipment.get) - obj.Zone = zone - obj.Release - val subscriber = new TestProbe(system) - - "AvatarService" should { - "pass Release" in { - expectNoMessage(100 milliseconds) //spacer - - zone.AvatarEvents.tell(Service.Join("test"), subscriber.ref) - assert(zone.Corpses.isEmpty) - zone.Population ! Zone.Corpse.Add(obj) - subscriber.expectNoMessage(200 milliseconds) //spacer - - assert(zone.Corpses.size == 1) - assert(obj.HasGUID) - val guid = obj.GUID - zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone)) //3+ minutes! - - val reply1 = subscriber.receiveOne(200 milliseconds) - assert(reply1.isInstanceOf[AvatarServiceResponse]) - val reply1msg = reply1.asInstanceOf[AvatarServiceResponse] - assert(reply1msg.channel == "/test/Avatar") - assert(reply1msg.filter == guid) - assert(reply1msg.reply.isInstanceOf[AvatarAction.Release]) - assert(reply1msg.reply.asInstanceOf[AvatarAction.Release].player == obj) - - zone.AvatarEvents ! CorpseEnvelope(RemoverActor.HurrySpecific(List(obj), zone)) //IMPORTANT: ONE ENTRY - val reply2 = subscriber.receiveOne(200 milliseconds) - assert(reply2.isInstanceOf[AvatarServiceResponse]) - val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] - assert(reply2msg.channel.equals("/test/Avatar")) - assert(reply2msg.filter == Service.defaultPlayerGUID) - assert(reply2msg.reply.isInstanceOf[ObjectDelete]) - assert(reply2msg.reply.asInstanceOf[ObjectDelete].obj_guid == guid) - - subscriber.expectNoMessage(1 seconds) - assert(zone.Corpses.isEmpty) - assert(!obj.HasGUID) - } - } -} - -class AvatarReleaseEarly2Test extends FreedContextActorTest { - val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(15)) - val zone = new Zone("test", new ZoneMap("test-map"), 0) { - override def SetupNumberPools() : Unit = { } - GUID(guid) - } - zone.init(context) - val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1)) - guid.register(obj) - guid.register(obj.Slot(5).Equipment.get) - obj.Zone = zone - obj.Release - val objAlt = Player( - Avatar(0, "TestCharacter2", PlanetSideEmpire.NC, CharacterSex.Male, 1, CharacterVoice.Voice1) - ) //necessary clutter - objAlt.GUID = PlanetSideGUID(3) - objAlt.Slot(5).Equipment.get.GUID = PlanetSideGUID(4) - objAlt.Zone = zone - val subscriber = new TestProbe(system) - - "AvatarService" should { - "pass Release" in { - expectNoMessage(100 milliseconds) //spacer - - zone.AvatarEvents.tell(Service.Join("test"), subscriber.ref) - assert(zone.Corpses.isEmpty) - zone.Population ! Zone.Corpse.Add(obj) - subscriber.expectNoMessage(200 milliseconds) //spacer - - assert(zone.Corpses.size == 1) - assert(obj.HasGUID) - val guid = obj.GUID - zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone)) //3+ minutes! - - val reply1 = subscriber.receiveOne(200 milliseconds) - assert(reply1.isInstanceOf[AvatarServiceResponse]) - val reply1msg = reply1.asInstanceOf[AvatarServiceResponse] - assert(reply1msg.channel == "/test/Avatar") - assert(reply1msg.filter == guid) - assert(reply1msg.reply.isInstanceOf[AvatarAction.Release]) - assert(reply1msg.reply.asInstanceOf[AvatarAction.Release].player == obj) - - zone.AvatarEvents ! CorpseEnvelope( - RemoverActor.HurrySpecific(List(objAlt, obj), zone) - ) //IMPORTANT: TWO ENTRIES - val reply2 = subscriber.receiveOne(100 milliseconds) - assert(reply2.isInstanceOf[AvatarServiceResponse]) - val reply2msg = reply2.asInstanceOf[AvatarServiceResponse] - assert(reply2msg.channel.equals("/test/Avatar")) - assert(reply2msg.filter == Service.defaultPlayerGUID) - assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete]) - assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid) - - subscriber.expectNoMessage(1 seconds) - assert(zone.Corpses.isEmpty) - assert(!obj.HasGUID) - } - } -} - -object AvatarServiceTest { - import java.util.concurrent.atomic.AtomicInteger - private val number = new AtomicInteger(1) - - def TestName: String = { - s"service${number.getAndIncrement()}" - } -} diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 14d3b827e..96113546a 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -48,8 +48,9 @@ import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingAc import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars} import net.psforever.packet.game.{Friend => GameFriend, _} import net.psforever.persistence +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{SendResponse, PlanetsideAttribute} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.types.{ CharacterSex, CharacterVoice, @@ -584,7 +585,7 @@ object AvatarActor { def displayLookingForSquad(session: Session, state: Int): Unit = { val player = session.player - session.zone.AvatarEvents ! AvatarServiceMessage( + session.zone.AvatarEvents ! MessageEnvelope( player.Faction.toString, player.GUID, PlanetsideAttribute(player.GUID, 53, state) @@ -1383,7 +1384,7 @@ class AvatarActor( case SetLookingForSquad(lfs) => avatarCopy(avatar.copy(lookingForSquad = lfs)) sessionActor ! SessionActor.SendResponse(PlanetsideAttributeMessage(session.get.player.GUID, 53, 0)) - session.get.zone.AvatarEvents ! AvatarServiceMessage( + session.get.zone.AvatarEvents ! MessageEnvelope( avatar.faction.toString, session.get.player.GUID, PlanetsideAttribute(session.get.player.GUID, 53, if (lfs) 1 else 0) @@ -1795,7 +1796,7 @@ class AvatarActor( ) val player = session.get.player val zone = player.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, SendResponse(DisplayedAwardMessage(player.GUID, ribbon, bar)) ) @@ -2074,7 +2075,7 @@ class AvatarActor( case Success(_) => val zone = session.get.zone avatarCopy(avatar.copy(decoration = avatar.decoration.copy(cosmetics = Some(cosmetics)))) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute( session.get.player.GUID, @@ -3001,13 +3002,13 @@ class AvatarActor( val next = BattleRank.withExperience(newBep).value val br24 = BattleRank.BR24.value sessionActor ! SessionActor.SendResponse(BattleExperienceMessage(pguid, newBep, localModifier)) - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(pguid, 17, newBep)) + events ! MessageEnvelope(zoneId, PlanetsideAttribute(pguid, 17, newBep)) if (current < br24 && next >= br24 || current >= br24 && next < br24) { setCosmetics(Set()).onComplete { _ => val evts = events val name = player.Name val guid = pguid - evts ! AvatarServiceMessage(name, PlanetsideAttribute(guid, 106, 1)) //set to no helmet + evts ! MessageEnvelope(name, PlanetsideAttribute(guid, 106, 1)) //set to no helmet } } // when the level is reduced, take away any implants over the implant slot limit @@ -3052,7 +3053,7 @@ class AvatarActor( val sess = session.get val zone = sess.zone avatar = avatar.copy(cep = cep) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, PlanetsideAttribute(sess.player.GUID, 18, cep)) + zone.AvatarEvents ! MessageEnvelope(zone.id, PlanetsideAttribute(sess.player.GUID, 18, cep)) case Failure(exception) => log.error(exception)("db failure") } @@ -3150,7 +3151,7 @@ class AvatarActor( if (exp > 0L) { setBep(exp, msg) zone.actor ! ZoneActor.RewardOurSupporters(playerSource, historyTranscript, killStat, exp) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.ShareKillExperienceWithSquad(player, exp)) } } @@ -3161,7 +3162,7 @@ class AvatarActor( val _session = session.get val zone = _session.zone val player = _session.player - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( player.Name, SendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))) ) @@ -3649,7 +3650,7 @@ class AvatarActor( // Start client-side initialization timer, visible on the character screen // Progress accumulates according to the client's knowledge of the implant initialization time // What is normally a 60s timer that is set to 120s on the server will still visually update as if 60s - session.get.zone.AvatarEvents ! AvatarServiceMessage( + session.get.zone.AvatarEvents ! MessageEnvelope( avatar.name, SendResponse(ActionProgressMessage(slot + 6, actionProgress)) ) @@ -3698,7 +3699,7 @@ class AvatarActor( def stopImplantInitializationTimer(implant: Implant, slot: Int): Implant = { cancelImplantInitializedTimer(slot) //can not formally stop the initialization time on the character information window; set it to 100 to make it look blank - session.get.zone.AvatarEvents ! AvatarServiceMessage( + session.get.zone.AvatarEvents ! MessageEnvelope( avatar.name, SendResponse(ActionProgressMessage(slot + 6, 100)) ) @@ -3768,7 +3769,7 @@ class AvatarActor( private def deactivateImplant(implant: Implant, slot: Int): Implant = { cancelImplantInitializedTimer(slot) // Deactivation sound / effect - session.get.zone.AvatarEvents ! AvatarServiceMessage( + session.get.zone.AvatarEvents ! MessageEnvelope( session.get.zone.id, session.get.player.GUID, PlanetsideAttribute(session.get.player.GUID, 28, implant.definition.implantType.value * 2) @@ -3848,7 +3849,7 @@ class AvatarActor( val newHealth = player.Health = originalHealth + 1 val events = zone.AvatarEvents player.LogActivity(HealFromImplant(implant.definition.implantType, 1)) - events ! AvatarServiceMessage(zone.id, PlanetsideAttribute(guid, 0, newHealth)) + events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 0, newHealth)) false } else { !aliveAndWounded @@ -3860,7 +3861,7 @@ class AvatarActor( // Activation sound / effect val sess = session.get val zone = sess.zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, sess.player.GUID, PlanetsideAttribute( @@ -3886,7 +3887,7 @@ class AvatarActor( case (implantOpt @ Some(implant), slot) => //update ongoing progress val actionProgress = calculateImplantTimerStats(implant, AvatarActor.initializationTime(implant))._3 - session.get.zone.AvatarEvents ! AvatarServiceMessage( + session.get.zone.AvatarEvents ! MessageEnvelope( avatar.name, SendResponse(ActionProgressMessage(slot + 6, actionProgress)) ) diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index eb02a7a29..71b67bf80 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -16,7 +16,8 @@ import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage} import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, SetEmpire} import net.psforever.services.chat.{ChatChannel, DefaultChannel, SpectatorChannel, SquadChannel} import net.psforever.types.ChatMessageType.{CMT_TOGGLESPECTATORMODE, CMT_TOGGLE_GM} @@ -319,7 +320,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext .foreach { spectator => val guid = spectator.GUID val definition = spectator.Definition - events ! AvatarServiceMessage( + events ! MessageEnvelope( channel, guid, AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None) @@ -338,7 +339,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext .filter(_.spectator) .foreach { spectator => val guid = spectator.GUID - events ! AvatarServiceMessage(channel, guid, ObjectDelete(guid)) + events ! MessageEnvelope(channel, guid, ObjectDelete(guid)) } true } @@ -391,7 +392,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext true case o: Deployable => o.Faction = foundFaction - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, SetEmpire(o.GUID, foundFaction) ) @@ -404,7 +405,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext true case o: PlanetSideGameObject with FactionAffinity => o.Faction = foundFaction - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, SetEmpire(o.GUID, foundFaction) ) @@ -511,7 +512,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext .foreach { case (_, false, _) => () case (faction, true, _) => - //events ! AvatarServiceMessage(s"$faction", reloadZoneMsg) + //events ! MessageEnvelope(s"$faction", reloadZoneMsg) } } } diff --git a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala index e8a15ba1f..0ab1782fc 100644 --- a/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/CustomerServiceRepresentativeMode.scala @@ -10,10 +10,10 @@ import net.psforever.objects.vital.Vitality import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage, PlanetsideAttributeMessage} import net.psforever.packet.game.objectcreate.RibbonBars -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.chat.{CustomerServiceChannel, SpectatorChannel} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{ChatMessageType, MeritCommendation, PlanetSideGUID} class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic { @@ -149,7 +149,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { packet.DetailedConstructorData(player).get )) data.zoning.spawn.HandleSetCurrentAvatar(player) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, pguid, AvatarAction.LoadPlayer( @@ -182,14 +182,14 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { player.Health = maxHealthOfPlayer.toInt player.LogActivity(player.ClearHistory().head) data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOfPlayer)) - data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, PlanetsideAttribute(guid, 0, maxHealthOfPlayer)) + data.continent.AvatarEvents ! MessageEnvelope(zoneid, PlanetsideAttribute(guid, 0, maxHealthOfPlayer)) } //below half armor, full armor val maxArmor = player.MaxArmor.toLong if (player.Armor < maxArmor) { player.Armor = maxArmor.toInt data.sendResponse(PlanetsideAttributeMessage(guid, 4, maxArmor)) - data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, PlanetsideAttribute(guid, 4, maxArmor)) + data.continent.AvatarEvents ! MessageEnvelope(zoneid, PlanetsideAttribute(guid, 4, maxArmor)) } } @@ -202,7 +202,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { val guid = vehicle.GUID vehicle.Shields = maxShieldsOfVehicle.toInt data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle)) - data.continent.VehicleEvents ! VehicleServiceMessage( + data.continent.VehicleEvents ! MessageEnvelope( data.continent.id, PlanetsideAttribute(guid, shieldsUi, maxShieldsOfVehicle) ) @@ -216,7 +216,7 @@ case object CustomerServiceRepresentativeMode extends PlayerMode { if (obj.Health < maxHealthOf) { obj.Health = maxHealthOf.toInt data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf)) - data.continent.VehicleEvents ! VehicleServiceMessage( + data.continent.VehicleEvents ! MessageEnvelope( data.continent.id, PlanetsideAttribute(guid, 0, maxHealthOf) ) diff --git a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala index 8d19e2ee2..b795a07b4 100644 --- a/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/GeneralLogic.scala @@ -33,10 +33,11 @@ import net.psforever.objects.zones.{ZoneProjectile, Zoning} import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1} import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} -import net.psforever.services.RemoverActor import net.psforever.services.avatar.support.CorpseEnvelope -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.services.base.support.RemoverActor import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.duration._ @@ -133,7 +134,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex val eagleEye: Boolean = ops.canSeeReallyFar val isNotVisible: Boolean = sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing || (player.isAlive && sessionLogic.zoning.spawn.deadState == DeadState.RespawnTime) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( channel, avatarGuid, AvatarAction.PlayerState( @@ -433,7 +434,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex ops.dropSpecialSlotItem() case GenericAction.MaxAnchorsExtend_RCV => player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player.GUID, PlanetsideAttribute(player.GUID, 19, 1) @@ -454,7 +455,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex } case GenericAction.MaxAnchorsRelease_RCV => player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player.GUID, PlanetsideAttribute(player.GUID, 19, 0) diff --git a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala index 1527495ba..255930467 100644 --- a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala @@ -15,9 +15,9 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{SendResponse, SetEmpire} -import net.psforever.services.local.LocalServiceMessage -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} object MountHandlerLogic { @@ -160,7 +160,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act case Mountable.CanMount(obj: FacilityTurret, seatNumber, _) if obj.Definition == GlobalDefinitions.vanu_sentry_turret => sessionLogic.zoning.CancelZoningProcess() - obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, SetEmpire(obj.GUID, player.Faction)) + obj.Zone.LocalEvents ! MessageEnvelope(obj.Zone.id, SetEmpire(obj.GUID, player.Faction)) sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health)) ops.updateWeaponAtSeatPosition(obj, seatNumber) ops.MountingAction(tplayer, obj, seatNumber) @@ -199,7 +199,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act val (pos, zang) = Vehicles.dismountShuttle(obj, mountPoint) tplayer.Position = pos sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true)) - continent.LocalEvents ! LocalServiceMessage( + continent.LocalEvents ! MessageEnvelope( continent.id, SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) ) @@ -213,7 +213,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountAction(tplayer, obj, seatNum) continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages - events ! VehicleServiceMessage( + events ! MessageEnvelope( player.Name, SendResponse(PlayerStasisMessage(pguid)) //the stasis message ) @@ -221,11 +221,11 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! VehicleServiceMessage( + events ! MessageEnvelope( player.Name, SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) ) - events ! VehicleServiceMessage( + events ! MessageEnvelope( continent.id, pguid, SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player @@ -254,7 +254,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountVehicleAction(tplayer, obj, seatNum) case Mountable.CanDismount(obj: Vehicle, seat_num, _) => - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, tplayer.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID) diff --git a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala index c5d4eee32..9e6510812 100644 --- a/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala +++ b/src/main/scala/net/psforever/actors/session/csr/SpectateAsCustomerServiceRepresentativeMode.scala @@ -7,7 +7,8 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.{Player, Session, Vehicle} import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSidePacket -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete import net.psforever.services.chat.SpectatorChannel import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} @@ -46,7 +47,7 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic { // player.spectator = true data.chat.JoinChannel(SpectatorChannel) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, ObjectDelete(pguid)) + continent.AvatarEvents ! MessageEnvelope(continent.id, pguid, ObjectDelete(pguid)) sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "on")) sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR SPECTATOR MODE ON")) } @@ -60,7 +61,7 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic { // player.spectator = false data.chat.LeaveChannel(SpectatorChannel) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, pguid, AvatarAction.LoadPlayer(avatarId, pguid, player.Definition.Packet.ConstructorData(player).get, None) diff --git a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala index e345d40d6..f49f3ad01 100644 --- a/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/VehicleLogic.scala @@ -13,7 +13,8 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} import net.psforever.services.base.CachedEnvelope -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{DriveState, Vector3} object VehicleLogic { @@ -77,7 +78,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Position = position obj.Orientation = angle // - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.VehicleState( @@ -165,7 +166,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Position = position obj.Orientation = angle obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA) @@ -220,7 +221,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex val angle = Vector3(0f, pitch, yaw) tool.Orientation = angle player.Orientation = angle - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.ChildObjectState(object_guid, pitch, yaw) @@ -303,7 +304,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex if (obj.DeploymentState != DriveState.Mobile) { obj.DeploymentState = DriveState.Mobile sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero)) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) 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 2fcfe4f3f..b5f188066 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -12,7 +12,8 @@ import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.vital.RevivingActivity import net.psforever.objects.vital.interaction.Adversarial import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction, PlanetsideStringAttributeMessage} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import net.psforever.types.ImplantType @@ -506,12 +507,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A }.flatten } match { case Some(adversarial) => - events ! AvatarServiceMessage( + events ! MessageEnvelope( zoneChannel, AvatarAction.DestroyDisplay(adversarial.attacker, pentry, adversarial.implement) ) case _ => - events ! AvatarServiceMessage(zoneChannel, AvatarAction.DestroyDisplay(pentry, pentry, 0)) + events ! MessageEnvelope(zoneChannel, AvatarAction.DestroyDisplay(pentry, pentry, 0)) } //events chat and log val excuse = player.LastDamage.flatMap { damage => @@ -689,8 +690,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val events = continent.AvatarEvents ops.killedWhileMounted(obj, playerGuid) //make player invisible on client - events ! AvatarServiceMessage(player.Name, PlanetsideAttribute(playerGuid, 29, 1)) + events ! MessageEnvelope(player.Name, PlanetsideAttribute(playerGuid, 29, 1)) //only the dead player should "see" their own body, so that the death camera has something to focus on - events ! AvatarServiceMessage(continent.id, playerGuid, ObjectDelete(playerGuid)) + events ! MessageEnvelope(continent.id, playerGuid, ObjectDelete(playerGuid)) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index d3980e8ba..6e87ee521 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -5,8 +5,9 @@ import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers} import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{EventResponse, SendResponse} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.galaxy.GalaxyAction import net.psforever.types.{MemberAction, PlanetSideEmpire} object GalaxyHandlerLogic { @@ -27,7 +28,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit = { sendResponse(pkt) pkt.friends.foreach { f => - galaxyService ! GalaxyServiceMessage(GalaxyAction.LogStatusChange(f.name)) + galaxyService ! MessageEnvelope("", GalaxyAction.LogStatusChange(f.name)) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index e0495c652..4227b15aa 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -42,8 +42,9 @@ import net.psforever.objects.zones.{ZoneProjectile, Zoning} import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.CachedEnvelope +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.CaptureFlagManager import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -180,7 +181,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex case _ => false }) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, avatarGuid, AvatarAction.PlayerState( @@ -519,7 +520,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex case GenericAction.MaxAnchorsExtend_RCV => log.info(s"${player.Name} has anchored ${player.Sex.pronounObject}self to the ground") player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player.GUID, PlanetsideAttribute(player.GUID, 19, 1) @@ -541,7 +542,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex case GenericAction.MaxAnchorsRelease_RCV => log.info(s"${player.Name} has released the anchors") player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player.GUID, PlanetsideAttribute(player.GUID, 19, 0) diff --git a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala index c17a7a884..4efc44ecd 100644 --- a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala @@ -16,9 +16,9 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{SendResponse, SetEmpire} -import net.psforever.services.local.LocalServiceMessage -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} object MountHandlerLogic { @@ -191,7 +191,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act if obj.Definition == GlobalDefinitions.vanu_sentry_turret => log.info(s"${player.Name} mounts the ${obj.Definition.Name}") sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_mount") - obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, SetEmpire(obj.GUID, player.Faction)) + obj.Zone.LocalEvents ! MessageEnvelope(obj.Zone.id, SetEmpire(obj.GUID, player.Faction)) sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health)) ops.updateWeaponAtSeatPosition(obj, seatNumber) ops.MountingAction(tplayer, obj, seatNumber) @@ -234,7 +234,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act val (pos, zang) = Vehicles.dismountShuttle(obj, mountPoint) tplayer.Position = pos sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true)) - continent.LocalEvents ! LocalServiceMessage( + continent.LocalEvents ! MessageEnvelope( continent.id, SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) ) @@ -253,11 +253,11 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! VehicleServiceMessage(player.Name, SendResponse(Seq( + events ! MessageEnvelope(player.Name, SendResponse(Seq( PlayerStasisMessage(pguid), PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) ))) - events ! VehicleServiceMessage( + events ! MessageEnvelope( continent.id, pguid, SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player @@ -287,7 +287,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountVehicleAction(tplayer, obj, seatNum) case Mountable.CanDismount(obj: Vehicle, seat_num, _) => - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, tplayer.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID) diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala index 21827dfbb..ac91bc4ca 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala @@ -13,7 +13,8 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} import net.psforever.services.base.CachedEnvelope -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{ChatMessageType, DriveState, Vector3} object VehicleLogic { @@ -321,7 +322,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex val mobileShift: String = if (obj.DeploymentState != DriveState.Mobile) { obj.DeploymentState = DriveState.Mobile sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero)) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) 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 b393c0847..6e4b94518 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -8,6 +8,7 @@ import net.psforever.objects.Players import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.{AvatarImplantMessage, ImplantAction} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import scala.concurrent.duration._ @@ -24,7 +25,7 @@ import net.psforever.objects.vital.etc.ExplodingEntityReason import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -482,7 +483,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val health = player.Health sendResponse(PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health)) sendResponse(AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, PlanetsideAttribute(revivalTargetGuid, attribute_type=0, health) ) diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala index 46c737541..ebcf68ba3 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala @@ -16,8 +16,9 @@ import net.psforever.objects.zones.ZoneProjectile import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.AccountPersistenceService -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.CachedEnvelope +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.{ExoSuitType, Vector3} @@ -229,7 +230,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex case GenericAction.MaxAnchorsExtend_RCV => log.info(s"${player.Name} has anchored ${player.Sex.pronounObject}self to the ground") player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player.GUID, PlanetsideAttribute(player.GUID, 19, 1) @@ -251,7 +252,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex case GenericAction.MaxAnchorsRelease_RCV => log.info(s"${player.Name} has released the anchors") player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player.GUID, PlanetsideAttribute(player.GUID, 19, 0) diff --git a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala index a5f3213a4..89ca48498 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala @@ -12,9 +12,9 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.LocalServiceMessage -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction object MountHandlerLogic { def apply(ops: SessionMountHandlers): MountHandlerLogic = { @@ -61,7 +61,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act val (pos, zang) = Vehicles.dismountShuttle(obj, mountPoint) tplayer.Position = pos sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true)) - continent.LocalEvents ! LocalServiceMessage( + continent.LocalEvents ! MessageEnvelope( continent.id, SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang)) ) @@ -80,11 +80,11 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! VehicleServiceMessage(player.Name, SendResponse(Seq( + events ! MessageEnvelope(player.Name, SendResponse(Seq( PlayerStasisMessage(pguid), PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) ))) - events ! VehicleServiceMessage( + events ! MessageEnvelope( continent.id, pguid, SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player @@ -105,7 +105,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountVehicleAction(tplayer, obj, seatNum) case Mountable.CanDismount(obj: Vehicle, seat_num, _) => - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, tplayer.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID) diff --git a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala index 993735e1d..f30b0d80e 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala @@ -11,7 +11,7 @@ import net.psforever.packet.PlanetSidePacket import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage, DeploymentAction, ObjectCreateDetailedMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars} import net.psforever.services.Service -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete import net.psforever.services.chat.SpectatorChannel import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} @@ -69,7 +69,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic { player.Inventory.Items .foreach { entry => sendResponse(ObjectDeleteMessage(entry.GUID, 0)) } sendResponse(ObjectDeleteMessage(player.avatar.locker.GUID, 0)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, pguid, ObjectDelete(pguid)) + continent.AvatarEvents ! MessageEnvelope(continent.id, pguid, ObjectDelete(pguid)) player.Holsters() .collect { case slot if slot.Equipment.nonEmpty => sendResponse(ObjectDeleteMessage(slot.Equipment.get.GUID, 0)) } val vehicleAndSeat = data.vehicles.GetMountableAndSeat(None, player, continent) match { diff --git a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala index d56536feb..d20548bd3 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala @@ -8,7 +8,8 @@ import net.psforever.objects.Vehicle import net.psforever.objects.serverobject.deploy.Deployment import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage} import net.psforever.services.base.CachedEnvelope -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{DriveState, Vector3} object VehicleLogic { @@ -81,7 +82,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex val mobileShift: String = if (obj.DeploymentState != DriveState.Mobile) { obj.DeploymentState = DriveState.Mobile sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero)) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero) diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 01befe7c9..a3e046ae5 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -17,11 +17,12 @@ import net.psforever.objects.sourcing.{DeployableSource, PlayerSource, VehicleSo import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase -import net.psforever.services.RemoverActor import net.psforever.services.avatar.support.GroundEnvelope -import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.support.RemoverActor import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global @@ -51,9 +52,9 @@ import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum import net.psforever.packet.game.objectcreate._ import net.psforever.packet.game._ import net.psforever.services.account.AccountPersistenceService -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.services.local.support.CaptureFlagManager -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.services.Service import net.psforever.types._ import net.psforever.util.Config @@ -206,7 +207,7 @@ class GeneralOperations( .livePlayerList .filter(_.GUID != guid) .foreach { p => - events ! LocalServiceMessage(p.Name, msg) + events ! MessageEnvelope(p.Name, msg) } //todo better way to collect csr players while utilizing the aforementioned benefit of localSector val position = player.Position @@ -218,7 +219,7 @@ class GeneralOperations( .AllPlayers .filter { p => !p.allowInteraction && p.GUID != guid && Vector3.DistanceSquared(p.Position, position) < rangeSq } .foreach { p => - events ! LocalServiceMessage(p.Name, msg) + events ! MessageEnvelope(p.Name, msg) } } @@ -405,7 +406,7 @@ class GeneralOperations( val detectedTargets = sessionLogic.shooting.FindDetectedProjectileTargets(targets) val mode = 7 + (if (weapon.Projectile == GlobalDefinitions.wasp_rocket_projectile) 1 else 0) detectedTargets.foreach { target => - continent.AvatarEvents ! AvatarServiceMessage(target, AvatarAction.ProjectileAutoLockAwareness(mode)) + continent.AvatarEvents ! MessageEnvelope(target, AvatarAction.ProjectileAutoLockAwareness(mode)) } case _ => () } @@ -485,7 +486,7 @@ class GeneralOperations( case attacker if attacker.Faction != player.Faction && System.currentTimeMillis() - llu.LastCollectionTime >= Config.app.game.experience.cep.lluSlayerCreditDuration.toMillis => - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( attacker.Name, AvatarAction.AwardCep(attacker.CharId, Config.app.game.experience.cep.lluSlayerCredit) ) @@ -1028,7 +1029,7 @@ class GeneralOperations( sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOff")) } player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, PlanetsideAttribute(player.GUID, 8, 0) ) @@ -1037,7 +1038,7 @@ class GeneralOperations( } private def activateMaxSpecialStateMessage(): Unit = { - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, PlanetsideAttribute(player.GUID, 8, 1) ) @@ -1052,7 +1053,7 @@ class GeneralOperations( case (Some(obj), Some(seatNum)) => tplayer.VehicleSeated = None obj.Seats(seatNum).unmount(tplayer) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, tplayer.GUID, VehicleAction.KickPassenger(seatNum, unk2=false, obj.GUID) @@ -1475,19 +1476,19 @@ class GeneralOperations( val events = continent.AvatarEvents val zoneid = continent.id val destinationPosition = dest.Position - events ! AvatarServiceMessage(zoneid, pguid, AvatarAction.ObjectDelete(pguid)) - events ! AvatarServiceMessage(player.Name, - AvatarAction.SendResponse(PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z))) + events ! MessageEnvelope(zoneid, pguid, ObjectDelete(pguid)) + events ! MessageEnvelope(player.Name, + SendResponse(PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z))) ) player.Position = destinationPosition - events ! AvatarServiceMessage(zoneid, pguid, AvatarAction.LoadPlayer( + events ! MessageEnvelope(zoneid, pguid, AvatarAction.LoadPlayer( player.Definition.ObjectId, pguid, player.Definition.Packet.ConstructorData(player).get, None )) useRouterTelepadEffect(pguid, sguid, dguid) - continent.LocalEvents ! LocalServiceMessage( + events ! MessageEnvelope( continent.id, pguid, LocalAction.RouterTelepadTransport(pguid, sguid, dguid) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index f8214d24b..88298edc1 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -8,7 +8,8 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, UniquePlayer} import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.objects.zones.exp import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, AvatarServiceResponse} +import net.psforever.services.avatar.{AvatarAction, AvatarServiceResponse} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{EventResponse, SendResponse} import net.psforever.services.chat.OutfitChannel @@ -140,7 +141,7 @@ class SessionAvatarHandlers( val playersInZone = killer.Zone.Players.map { avatar => (avatar.id, avatar.basic.name) } val squadMembersHere = playersInZone.filter(member => squadMembers.contains(member._2)) squadMembersHere.foreach { member => - killer.Zone.AvatarEvents ! AvatarServiceMessage( + killer.Zone.AvatarEvents ! MessageEnvelope( member._2, AvatarAction.AwardBep(member._1, expSplit, ExperienceType.Normal)) } @@ -155,7 +156,7 @@ class SessionAvatarHandlers( val playersInZone = vehicle.Zone.Players.map { avatar => (avatar.id, avatar.basic.name) } val squadMembersHere = playersInZone.filter(member => squadMembers.contains(member._2)) squadMembersHere.foreach { member => - vehicle.Zone.AvatarEvents ! AvatarServiceMessage( + vehicle.Zone.AvatarEvents ! MessageEnvelope( member._2, AvatarAction.AwardBep(member._1, exp, ExperienceType.Normal)) } 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 f5c8c95cc..0d43257a8 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -4,6 +4,7 @@ package net.psforever.actors.session.support import akka.actor.typed.receptionist.Receptionist import akka.actor.typed.scaladsl.adapter._ import akka.actor.{ActorContext, ActorRef, typed} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.chat.ChatService import scala.collection.mutable @@ -31,7 +32,7 @@ import net.psforever.packet._ import net.psforever.packet.game._ import net.psforever.services.account.AccountPersistenceService import net.psforever.services.ServiceManager.LookupResult -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.services.{Service, InterstellarClusterService => ICS} import net.psforever.types._ import net.psforever.util.Config @@ -567,7 +568,7 @@ class SessionData( case (Some(obj), Some(seatNum)) => tplayer.VehicleSeated = None obj.Seats(seatNum).unmount(tplayer) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, tplayer.GUID, VehicleAction.KickPassenger(seatNum, unk2=false, obj.GUID) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index 346a7f6bf..e8896a491 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -9,8 +9,9 @@ import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} import net.psforever.services.base.CachedEnvelope +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{BailType, PlanetSideGUID, Vector3} // import net.psforever.actors.session.AvatarActor @@ -186,7 +187,7 @@ class SessionMountHandlers( avatarActor ! AvatarActor.DeactivateActiveImplants avatarActor ! AvatarActor.SuspendStaminaRegeneration(3.seconds) sendResponse(ObjectAttachMessage(objGuid, playerGuid, seatNum)) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, playerGuid, VehicleAction.MountVehicle(objGuid, seatNum) @@ -204,13 +205,12 @@ class SessionMountHandlers( if (tplayer.BailProtection) { tplayer.ContributionFrom(obj) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, - SendResponse(PlanetsideAttributeMessage(obj.GUID, 81, 1)) - ) - continent.VehicleEvents ! VehicleServiceMessage( - continent.id, - SendResponse(ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) + SendResponse(List( + PlanetsideAttributeMessage(obj.GUID, 81, 1), + ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) + ) ) } else { @@ -250,7 +250,7 @@ class SessionMountHandlers( BailType.Normal } sendResponse(DismountVehicleMsg(playerGuid, bailType, wasKickedByDriver = false)) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, playerGuid, VehicleAction.DismountVehicle(bailType, unk2 = false) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala index a7d5f4bd9..25abda4c5 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala @@ -8,7 +8,8 @@ import net.psforever.objects.Player import net.psforever.packet.game.OutfitEventAction.{Initial, Leaving, OutfitInfo, OutfitRankNames, Unk1, Update, UpdateMemberCount} import net.psforever.packet.game.OutfitMembershipResponse.PacketType.CreateResponse import net.psforever.packet.game._ -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.chat.OutfitChannel import net.psforever.types.ChatMessageType @@ -84,12 +85,12 @@ object SessionOutfitHandlers { player.outfit_id = outfit.id player.outfit_name = outfit.name - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Zone.id, PlanetsideAttribute(player.GUID, 39, outfit.id) ) - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Zone.id, player.GUID, AvatarAction.PlanetsideStringAttribute(0, outfit.name) @@ -174,12 +175,12 @@ object SessionOutfitHandlers { invited.outfit_id = outfit.id invited.outfit_name = outfit.name - invited.Zone.AvatarEvents ! AvatarServiceMessage( + invited.Zone.AvatarEvents ! MessageEnvelope( invited.Zone.id, PlanetsideAttribute(invited.GUID, 39, outfit.id) ) - invited.Zone.AvatarEvents ! AvatarServiceMessage( + invited.Zone.AvatarEvents ! MessageEnvelope( invited.Zone.id, invited.GUID, AvatarAction.PlanetsideStringAttribute(0, outfit.name) @@ -241,12 +242,12 @@ object SessionOutfitHandlers { OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked())) ) - kickedBy.Zone.AvatarEvents ! AvatarServiceMessage( + kickedBy.Zone.AvatarEvents ! MessageEnvelope( kickedBy.Zone.id, PlanetsideAttribute(kickedBy.GUID, 39, 0) ) - kickedBy.Zone.AvatarEvents ! AvatarServiceMessage( + kickedBy.Zone.AvatarEvents ! MessageEnvelope( kickedBy.Zone.id, kickedBy.GUID, AvatarAction.PlanetsideStringAttribute(0, "") @@ -270,18 +271,18 @@ object SessionOutfitHandlers { OutfitMembershipResponse(OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1, kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false)) - kicked.Zone.AvatarEvents ! AvatarServiceMessage( + kicked.Zone.AvatarEvents ! MessageEnvelope( kicked.Zone.id, PlanetsideAttribute(kicked.GUID, 39, 0) ) - kicked.Zone.AvatarEvents ! AvatarServiceMessage( + kicked.Zone.AvatarEvents ! MessageEnvelope( kicked.Zone.id, kicked.GUID, AvatarAction.PlanetsideStringAttribute(0, "") ) - kicked.Zone.AvatarEvents ! AvatarServiceMessage( + kicked.Zone.AvatarEvents ! MessageEnvelope( kicked.Name, AvatarAction.RemoveFromOutfitChat(kickedBy.outfit_id)) kicked.outfit_id = 0 @@ -634,12 +635,12 @@ object SessionOutfitHandlers { player.outfit_id = outfit.id player.outfit_name = outfit.name - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Zone.id, PlanetsideAttribute(player.GUID, 39, outfit.id) ) - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Zone.id, player.GUID, AvatarAction.PlanetsideStringAttribute(0, outfit.name) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala index 3645b91a2..fa9da51e7 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala @@ -2,6 +2,7 @@ package net.psforever.actors.session.support import akka.actor.{ActorContext, ActorRef, typed} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.teamwork.SquadServiceResponse @@ -11,7 +12,6 @@ import net.psforever.actors.session.AvatarActor import net.psforever.objects.teamwork.Squad import net.psforever.objects.{Default, Player} import net.psforever.packet.game._ -import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.teamwork.{SquadResponse, SquadServiceMessage, SquadAction => SquadServiceAction} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -106,7 +106,7 @@ class SessionSquadHandlers( squadUI.get(player.CharId) match { case Some(elem) => sendResponse(PlanetsideAttributeMessage(player.GUID, 31, squad_supplement_id)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( s"${player.Faction}", player.GUID, PlanetsideAttribute(player.GUID, 31, squad_supplement_id) @@ -288,7 +288,7 @@ class SessionSquadHandlers( * @param value value to associate the player */ def GiveSquadColorsForOthers(guid: PlanetSideGUID, factionChannel: String, value: Long): Unit = { - continent.AvatarEvents ! AvatarServiceMessage(factionChannel, guid, PlanetsideAttribute(guid, 31, value)) + continent.AvatarEvents ! MessageEnvelope(factionChannel, guid, PlanetsideAttribute(guid, 31, value)) } /** diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index 15197b0f0..0fcfef466 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -29,8 +29,8 @@ import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest import net.psforever.services.Service import net.psforever.services.base.CachedEnvelope +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} -import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3} import net.psforever.util.Config @@ -48,8 +48,8 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.turret.FacilityTurret import net.psforever.objects._ import net.psforever.packet.game._ -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{ExoSuitType, PlanetSideGUID} trait WeaponAndProjectileFunctions extends CommonSessionInterfacingFunctionality { @@ -284,9 +284,9 @@ class WeaponAndProjectileOperations( .orElse { continent.GUID(weapon_guid) } .collect { case _: Equipment if containerOpt.exists(_.isInstanceOf[Player]) => - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, WeaponDryFire(weapon_guid)) + continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, WeaponDryFire(weapon_guid)) case _: Equipment => - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, WeaponDryFire(weapon_guid) @@ -349,7 +349,7 @@ class WeaponAndProjectileOperations( sendResponse(UplinkResponse(code.value, 0)) sendResponse(PlanetsideAttributeMessage(player.GUID, 59, 1200000)) avatarActor ! AvatarActor.UpdateCUDTime("emp_blast") - player.Zone.LocalEvents ! LocalServiceMessage( + player.Zone.LocalEvents ! MessageEnvelope( s"${player.Zone.id}", PlanetSideGUID(-1), SendResponse(TriggerEffectMessage(Service.defaultPlayerGUID, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))) @@ -359,7 +359,7 @@ class WeaponAndProjectileOperations( ExplosiveDeployableControl.detectionForExplosiveSource(player), Zone.findAllTargets) } case UplinkRequestType.OrbitalStrike => - player.Zone.LocalEvents ! LocalServiceMessage( + player.Zone.LocalEvents ! MessageEnvelope( s"$playerFaction", PlanetSideGUID(-1), SendResponse(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y)) @@ -388,12 +388,12 @@ class WeaponAndProjectileOperations( sendResponse(PlanetsideAttributeMessage(player.GUID, 60, 10800000)) avatarActor ! AvatarActor.UpdateCUDTime("orbital_strike") context.system.scheduler.scheduleOnce(delay = 5 seconds) { - player.Zone.LocalEvents ! LocalServiceMessage( + player.Zone.LocalEvents ! MessageEnvelope( s"${player.Zone.id}", PlanetSideGUID(-1), SendResponse(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90))))) ) - player.Zone.LocalEvents ! LocalServiceMessage( + player.Zone.LocalEvents ! MessageEnvelope( s"$playerFaction", PlanetSideGUID(-1), SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) @@ -472,7 +472,7 @@ class WeaponAndProjectileOperations( log.info(s"${player.Name} changed ${player.Sex.possessive} ${obj.Definition.Name}'s fire mode to #$modeIndex") } sendResponse(ChangeFireModeMessage(item_guid, modeIndex)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( sessionLogic.zoning.zoneChannel, player.GUID, AvatarAction.ChangeFireMode(item_guid, modeIndex) @@ -758,7 +758,7 @@ class WeaponAndProjectileOperations( (target.GUID, (target, proxyCopy, proxyCopy.shot_origin, target.Position)) }.unzip //chain lash effect - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, SendResponse(ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList)) ) @@ -944,9 +944,9 @@ class WeaponAndProjectileOperations( tool.Magazine = 0 sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, weapon_guid, 0)) sendResponse(ChangeFireStateMessage_Stop(weapon_guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, ChangeFireState_Stop(weapon_guid)) + continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, ChangeFireState_Stop(weapon_guid)) sendResponse(WeaponDryFireMessage(weapon_guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, WeaponDryFire(weapon_guid)) + continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, WeaponDryFire(weapon_guid)) } /** @@ -962,7 +962,7 @@ class WeaponAndProjectileOperations( .map { sessionLogic.validObject(_, decorator="FindDetectedProjectileTargets") } .flatMap { case Some(obj: Vehicle) if !obj.Cloaked => - //TODO hint: vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.ProjectileAutoLockAwareness(mode)) + //TODO hint: vehicleService ! MessageEnvelope(s"${obj.Actor}", VehicleAction.ProjectileAutoLockAwareness(mode)) obj.Seats.values.flatMap { seat => seat.occupants.map(_.Name) } case Some(obj: Mountable) => obj.Seats.values.flatMap { seat => seat.occupants.map(_.Name) } @@ -1087,7 +1087,7 @@ class WeaponAndProjectileOperations( } def fireStateStartPlayerMessages(itemGuid: PlanetSideGUID): Unit = { - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( sessionLogic.zoning.zoneChannel, player.GUID, ChangeFireState_Start(itemGuid) @@ -1099,7 +1099,7 @@ class WeaponAndProjectileOperations( case turret: FacilityTurret if continent.map.cavern => turret.Actor ! VanuSentry.ChangeFireStart } - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, ChangeFireState_Start(itemGuid) @@ -1128,7 +1128,7 @@ class WeaponAndProjectileOperations( } def fireStateStopPlayerMessages(itemGuid: PlanetSideGUID): Unit = { - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( sessionLogic.zoning.zoneChannel, player.GUID, ChangeFireState_Stop(itemGuid) @@ -1140,7 +1140,7 @@ class WeaponAndProjectileOperations( case turret: FacilityTurret if continent.map.cavern => turret.Actor ! VanuSentry.ChangeFireStop } - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, ChangeFireState_Stop(itemGuid) @@ -1200,11 +1200,11 @@ class WeaponAndProjectileOperations( used by ReloadMessage handling */ def reloadPlayerMessages(itemGuid: PlanetSideGUID): Unit = { - continent.AvatarEvents ! AvatarServiceMessage(sessionLogic.zoning.zoneChannel, player.GUID, ReloadTool(itemGuid)) + continent.AvatarEvents ! MessageEnvelope(sessionLogic.zoning.zoneChannel, player.GUID, ReloadTool(itemGuid)) } def reloadVehicleMessages(itemGuid: PlanetSideGUID): Unit = { - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, ReloadTool(itemGuid) @@ -1381,7 +1381,7 @@ class WeaponAndProjectileOperations( val previous_box_guid = previousBox.GUID val boxDef = box.Definition sendResponse(ChangeAmmoMessage(tool_guid, box.Capacity)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( sessionLogic.zoning.zoneChannel, player.GUID, ChangeAmmo( @@ -1482,7 +1482,7 @@ class WeaponAndProjectileOperations( def modifyAmmunitionInMountable(obj: PlanetSideServerObject with Container)(box: AmmoBox, reloadValue: Int): Unit = { modifyAmmunition(obj)(box, reloadValue) obj.Find(box).collect { index => - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( s"${obj.Actor}", player.GUID, VehicleAction.InventoryState(box, obj.GUID, index, box.Definition.Packet.DetailedConstructorData(box).get) @@ -1589,7 +1589,7 @@ class WeaponAndProjectileOperations( shootingStop.clear() (prefire ++ shooting).foreach { guid => sendResponse(ChangeFireStateMessage_Stop(guid)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, player.GUID, ChangeFireState_Stop(guid)) + continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, ChangeFireState_Stop(guid)) } prefire.clear() shooting.clear() diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 00ffaf3e5..900d88600 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -23,6 +23,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage} import net.psforever.services.avatar.support.{CorpseEnvelope, ReleaseEnvelope} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.chat.DefaultChannel @@ -64,16 +65,16 @@ import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMess import net.psforever.packet.game.objectcreate.ObjectClass import net.psforever.packet.{PlanetSideGamePacket, game} import net.psforever.persistence.Savedplayer -import net.psforever.services.RemoverActor import net.psforever.services.ServiceManager.{Lookup, LookupResult} import net.psforever.services.account.{AccountPersistenceService, PlayerToken} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.support.RemoverActor +import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.hart.HartTimer import net.psforever.services.local.support.HackCaptureActor -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.services.properties.PropertyOverrideManager -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.services.{CavernRotationService, Service, ServiceManager, InterstellarClusterService => ICS} import net.psforever.types._ import net.psforever.util.{Config, DefinitionUtil} @@ -128,7 +129,7 @@ object ZoningOperations { .filter(p => Sidedness.equals(side, p.WhichSide)) .map(_.Name) ++ additionalChannels) .foreach { target => - events ! LocalServiceMessage(target, effectMessage) + events ! MessageEnvelope(target, effectMessage) } } @@ -156,11 +157,11 @@ object ZoningOperations { } val effectMessage = LocalAction.TriggerEffectLocation(s"respawn_$faction", position, orientation) (effectTargets.map(_.Name) ++ additionalChannels).foreach { target => - events ! LocalServiceMessage(target, effectMessage) + events ! MessageEnvelope(target, effectMessage) } val soundMessage = LocalAction.TriggerSound(TriggeredSound.SpawnInTube, position, 50, 0.69803923f) (soundTargets.map(_.Name) ++ additionalChannels).foreach { target => - events ! LocalServiceMessage(target, soundMessage) + events ! MessageEnvelope(target, soundMessage) } } @@ -549,7 +550,7 @@ class ZoningOperations( sendResponse(OCM.apply(projectile)) } //spawn point update request - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( player.Name, VehicleAction.UpdateAmsSpawnPoint(continent) ) @@ -597,7 +598,7 @@ class ZoningOperations( context.self ) LivePlayerList.Add(avatar.id, avatar) - galaxyService.tell(GalaxyServiceMessage(GalaxyAction.LogStatusChange(avatar.name)), context.parent) + galaxyService.tell(MessageEnvelope("", GalaxyAction.LogStatusChange(avatar.name)), context.parent) //PropertyOverrideMessage ServiceManager.serviceManager ! Lookup("propertyOverrideManager") sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 112, 0)) // disable festive backpacks @@ -853,7 +854,7 @@ class ZoningOperations( case None => spawn.deadState = DeadState.Release // cancel movement updates player.Position = position - // continent.AvatarEvents ! AvatarServiceMessage(continent.Id, ObjectDelete(player.GUID, player.GUID)) + // continent.AvatarEvents ! MessageEnvelope(continent.Id, ObjectDelete(player.GUID, player.GUID)) spawn.LoadZonePhysicalSpawnPoint(zoneId, position, Vector3.Zero, 0 seconds, None) case _ => // seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move } @@ -1207,7 +1208,7 @@ class ZoningOperations( sendResponse(OCM.apply(llu)) // Attach it to a player if it has a carrier if (llu.Carrier.nonEmpty) { - continent.LocalEvents ! LocalServiceMessage( + continent.LocalEvents ! MessageEnvelope( continent.id, PlanetSideGUID(-1), SendResponse(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252)) @@ -1352,7 +1353,7 @@ class ZoningOperations( val pguid = player.GUID val toChannel = manifest.file val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID) - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( s"${vehicle.Actor}", pguid, VehicleAction.TransferPassengerChannel(s"${vehicle.Actor}", toChannel, vehicle, topLevel) @@ -1366,7 +1367,7 @@ class ZoningOperations( cargo.Actor ! CargoBehavior.StartCargoDismounting(bailed = false) case entry => val cargo = vehicle.CargoHolds(entry.mount).occupant.get - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( entry.name, pguid, VehicleAction.TransferPassengerChannel(s"${cargo.Actor}", toChannel, cargo, topLevel) @@ -1398,7 +1399,7 @@ class ZoningOperations( interstellarFerryTopLevelGUID = if (manifest.passengers.isEmpty && manifest.cargo.count { !_.name.equals("MISSING_DRIVER") } == 0) { //do not delete if vehicle has passengers or cargo - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, pguid, VehicleAction.UnloadVehicle(vehicle, topLevel) @@ -1476,14 +1477,14 @@ class ZoningOperations( case Some(manifest) => val toChannel = manifest.file val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID) - galaxyService ! GalaxyServiceMessage(toChannel, GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)) + galaxyService ! MessageEnvelope(toChannel, GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)) vehicle.CargoHolds.values .collect { case hold if hold.isOccupied => val cargo = hold.occupant.get cargo.Continent = toZoneId //point to the cargo vehicle to instigate cargo vehicle driver transportation - // galaxyService ! GalaxyServiceMessage( + // galaxyService ! MesdsageEnvelope( // toChannel, // GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest) // ) @@ -2194,7 +2195,7 @@ class ZoningOperations( log.info(s"RestoreInfo: player $name is already logged in zone ${inZone.id}; rejoining that character") sessionLogic.persistFunc = UpdatePersistence(from) //tell the old WorldSessionActor to kill itself by using its own subscriptions against itself - inZone.AvatarEvents ! AvatarServiceMessage(name, AvatarAction.TeardownConnection()) + inZone.AvatarEvents ! MessageEnvelope(name, AvatarAction.TeardownConnection()) spawn.switchAvatarStatisticsFieldToRefreshAfterRespawn() //find and reload previous player ( @@ -2597,7 +2598,7 @@ class ZoningOperations( vehicle.CargoHolds.values .collect { case hold if hold.isOccupied => hold.occupant.get } .foreach { _.MountedIn = vguid } - events ! VehicleServiceMessage( + events ! MessageEnvelope( zoneid, player.GUID, VehicleAction.LoadVehicle(vehicle, vObjectId, vguid, data) @@ -2625,7 +2626,7 @@ class ZoningOperations( //do not dispatch delete action if any hierarchical occupant has not gotten this far through the summoning process val vehicleToDelete = interstellarFerryTopLevelGUID.orElse(originalSeated).getOrElse(PlanetSideGUID(0)) val zone = vehicle.PreviousGatingManifest().get.origin - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, player.GUID, VehicleAction.UnloadVehicle(vehicle, vehicleToDelete) @@ -2643,7 +2644,7 @@ class ZoningOperations( val definition = player.avatar.definition val guid = player.GUID sendResponse(OCM.detailed(player)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( s"spectator", guid, AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None) @@ -2655,7 +2656,7 @@ class ZoningOperations( val guid = player.GUID usingSpawnTubeAnimation() sendResponse(OCM.detailed(player)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( zoneid, guid, AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None) @@ -2728,7 +2729,7 @@ class ZoningOperations( interimUngunnedVehicle = Some(vguid) interimUngunnedVehicleSeat = Some(seat) } - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, pguid, AvatarAction.LoadPlayer( @@ -2887,7 +2888,7 @@ class ZoningOperations( case _ => () } if (player.VisibleSlots.contains(index)) { - events ! AvatarServiceMessage( + events ! MessageEnvelope( zoneId, ObjectDelete(obj.GUID) ) @@ -2905,7 +2906,6 @@ class ZoningOperations( * To the game, that is a backpack (or some pastry, festive graphical modification allowing). * @see `AvatarAction.ObjectDelete` * @see `AvatarAction.Release` - * @see `AvatarServiceMessage` * @see `FriskDeadBody` * @see `GUIDTask.unregisterPlayer` * @see `ObjectDeleteMessage` @@ -2923,7 +2923,7 @@ class ZoningOperations( val pguid = tplayer.GUID zone.Population ! Zone.Population.Release(avatar) sendResponse(ObjectDeleteMessage(pguid, 0)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, pguid, ObjectDelete(pguid)) + zone.AvatarEvents ! MessageEnvelope(zone.id, pguid, ObjectDelete(pguid)) TaskWorkflow.execute(GUIDTask.unregisterPlayer(zone.GUID, tplayer)) } } @@ -2933,7 +2933,6 @@ class ZoningOperations( * To the game, that is a backpack (or some pastry, festive graphical modification allowing). * A player who has been kicked may not turn into a corpse. * @see `AvatarAction.Release` - * @see `AvatarServiceMessage` * @see `CorpseConverter.converter` * @see `DepictPlayerAsCorpse` * @see `Player.Release` @@ -3179,7 +3178,7 @@ class ZoningOperations( // entering or exiting VR zones uses a fade-out effect for the player instead of the usual green cloud deconstruction effect val effect = if (player.IsInVRZone || zoneId.startsWith("tz")) 2 else 1 sendResponse(ObjectDeleteMessage(player_guid, unk1=effect)) - continent.AvatarEvents ! AvatarServiceMessage( + continent.AvatarEvents ! MessageEnvelope( continent.id, player_guid, ObjectDelete(player_guid, unk=effect) @@ -3346,7 +3345,7 @@ class ZoningOperations( //looking for squad (members) if (tplayer.avatar.lookingForSquad) { sendResponse(PlanetsideAttributeMessage(guid, 53, 1)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, guid, PlanetsideAttribute(guid, 53, 1)) + continent.AvatarEvents ! MessageEnvelope(continent.id, guid, PlanetsideAttribute(guid, 53, 1)) } sendResponse(AvatarSearchCriteriaMessage(guid, List(0, 0, 0, 0, 0, 0))) //these are facilities and towers and bunkers in the zone, but not necessarily all of them for some reason @@ -3372,7 +3371,7 @@ class ZoningOperations( if (tplayer.ExoSuit == ExoSuitType.MAX) { sendResponse(PlanetsideAttributeMessage(guid, 7, tplayer.Capacitor.toLong)) sendResponse(PlanetsideAttributeMessage(guid, 4, tplayer.Armor)) - continent.AvatarEvents ! AvatarServiceMessage(continent.id, PlanetsideAttribute(guid, 4, tplayer.Armor)) + continent.AvatarEvents ! MessageEnvelope(continent.id, PlanetsideAttribute(guid, 4, tplayer.Armor)) } // for issue #1269 continent.AllPlayers.filter(_.ExoSuit == ExoSuitType.MAX).foreach(max => sendResponse(PlanetsideAttributeMessage(max.GUID, 4, max.Armor))) @@ -3396,7 +3395,7 @@ class ZoningOperations( continent.GUID(tplayer.avatar.vehicle) match { case Some(vehicle: Vehicle) if vehicle.OwnerName.contains(tplayer.Name) => vehicle.OwnerGuid = guid - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( s"${tplayer.Faction}", guid, VehicleAction.Ownership(vehicle.GUID) @@ -3500,8 +3499,10 @@ class ZoningOperations( val zone = tplayer.Zone val channel = zone.id val events = zone.AvatarEvents - events ! AvatarServiceMessage(channel, PlanetsideAttribute(guid, 0, 120)) - events ! AvatarServiceMessage(channel, PlanetsideAttribute(guid, 1, 120)) + events ! MessageEnvelope( + channel, + SendResponse(List(PlanetsideAttributeMessage(guid, 0, 120), PlanetsideAttributeMessage(guid, 1, 120))) + ) case _ => () } doorsThatShouldBeOpenInRange(pos, range = 100f) @@ -4005,14 +4006,14 @@ class ZoningOperations( val pZone = player.Zone sendResponse(GenericActionMessage(FirstPersonViewWithEffect)) pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID => - pZone.LocalEvents ! LocalServiceMessage( + pZone.LocalEvents ! MessageEnvelope( t.Name, t.GUID, GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) ) } pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction => - pZone.LocalEvents ! LocalServiceMessage( + pZone.LocalEvents ! MessageEnvelope( t.Name, t.GUID, GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) diff --git a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala index 48cff7c6d..9afecac87 100644 --- a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala +++ b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala @@ -11,9 +11,9 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.ContinentalLockUpdateMessage import net.psforever.persistence +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{SendResponse, SetEmpire} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.LocalServiceMessage +import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.{InterstellarClusterService, ServiceManager} import net.psforever.types.PlanetSideEmpire import net.psforever.util.Database.ctx @@ -168,7 +168,7 @@ object BuildingActor { val building = details.building val zone = building.Zone building.Faction = faction - zone.LocalEvents ! LocalServiceMessage(zone.id, SetEmpire(building.GUID, faction)) + zone.LocalEvents ! MessageEnvelope(zone.id, SetEmpire(building.GUID, faction)) } } @@ -232,8 +232,8 @@ class BuildingActor( Behaviors.same case MapUpdate() => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) - details.galaxyService ! GalaxyServiceMessage(SendResponse(details.building.densityLevelUpdateMessage(building))) + details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) + details.galaxyService ! MessageEnvelope("", SendResponse(details.building.densityLevelUpdateMessage(building))) Behaviors.same case AmenityStateChange(amenity, data) => @@ -255,15 +255,15 @@ class BuildingActor( logic.ntu(details, msg) case DensityLevelUpdate(building) => - details.galaxyService ! GalaxyServiceMessage(SendResponse(details.building.densityLevelUpdateMessage(building))) + details.galaxyService ! MessageEnvelope("", SendResponse(details.building.densityLevelUpdateMessage(building))) Behaviors.same case ContinentalLock(zone) => - details.galaxyService ! GalaxyServiceMessage(SendResponse(ContinentalLockUpdateMessage(zone.Number, zone.lockedBy))) + details.galaxyService ! MessageEnvelope("", SendResponse(ContinentalLockUpdateMessage(zone.Number, zone.lockedBy))) Behaviors.same case HomeLockBenefits(msg) => - details.galaxyService ! GalaxyServiceMessage(SendResponse(msg)) + details.galaxyService ! MessageEnvelope("", SendResponse(msg)) Behaviors.same } } diff --git a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala index a6d7206cd..f781db5c5 100644 --- a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala +++ b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala @@ -20,8 +20,8 @@ import net.psforever.objects.zones.exp.{ExperienceCalculator, SupportExperienceC import net.psforever.packet.game.{BuildingInfoUpdateMessage, PlanetsideAttributeMessage} import net.psforever.util.Database._ import net.psforever.persistence +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.LocalServiceMessage import scala.collection.mutable import scala.util.{Failure, Success} @@ -235,24 +235,24 @@ class ZoneActor( } buildingOpt.foreach { building => if (msg.generator_state == PlanetSideGeneratorState.Normal && building.hasCavernLockBenefit) { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1)) ) } msg.is_hacked match { case true if building.BuildingType == StructureType.Facility && !zone.map.cavern => - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) ) case false if building.hasCavernLockBenefit => - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1)) ) case false if building.BuildingType == StructureType.Facility && !zone.map.cavern && !building.hasCavernLockBenefit => - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) ) diff --git a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala index c6a0d0e1e..b09d15dea 100644 --- a/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/CavernFacilityLogic.scala @@ -7,7 +7,8 @@ import net.psforever.actors.commands.NtuCommand import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails, ZoneActor} import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import net.psforever.types.PlanetSideEmpire @@ -57,7 +58,7 @@ case object CavernFacilityLogic }) // No map update needed - will be sent by `HackCaptureActor` when required case _ => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) + details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) } Behaviors.same } diff --git a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala index 2998750a9..db12a7555 100644 --- a/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/FacilityLogic.scala @@ -7,7 +7,8 @@ import net.psforever.actors.commands.NtuCommand import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails} import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import net.psforever.types.PlanetSideEmpire @@ -57,7 +58,7 @@ case object FacilityLogic }) // No map update needed - will be sent by `HackCaptureActor` when required case _ => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) + details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) } Behaviors.same } diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index b12bf2ab9..c53f8406d 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -13,14 +13,14 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSiloControl import net.psforever.objects.serverobject.structures.{Amenity, Building} import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.packet.game.PlanetsideAttributeMessage +import net.psforever.packet.game.{GenericObjectActionMessage, PlanetsideAttributeMessage} import net.psforever.services.InterstellarClusterService -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.LocalServiceMessage +import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor, HackClearActor, HackClearEnvelope} -import net.psforever.types.PlanetSideEmpire +import net.psforever.services.local.LocalAction +import net.psforever.types.{PlanetSideEmpire, PlanetSideGeneratorState} /** * A package class that conveys the important information for handling facility updates. @@ -119,7 +119,7 @@ case object MajorFacilityLogic .filter(amenity => applicable.contains(amenity.Definition)) .foreach { _.Actor ! msg } case _ => - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) + details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) } Behaviors.same } @@ -206,7 +206,7 @@ case object MajorFacilityLogic val guid = building.GUID val msg = GenericObjectAction(guid, 15) building.PlayersInSOI.foreach { player => - events ! AvatarServiceMessage(player.Name, msg) + events ! MessageEnvelope(player.Name, msg) } false case Some(GeneratorControl.Event.Critical) => @@ -214,7 +214,7 @@ case object MajorFacilityLogic val guid = building.GUID val msg = PlanetsideAttribute(guid, 46, 1) building.PlayersInSOI.foreach { player => - events ! AvatarServiceMessage(player.Name, msg) + events ! MessageEnvelope(player.Name, msg) } true case Some(GeneratorControl.Event.Destabilized) => @@ -222,10 +222,10 @@ case object MajorFacilityLogic val guid = building.GUID val msg = GenericObjectAction(guid, 16) building.PlayersInSOI.foreach { player => - events ! AvatarServiceMessage(player.Name, msg) + events ! MessageEnvelope(player.Name, msg) } if (building.hasCavernLockBenefit) { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0)) ) @@ -238,7 +238,7 @@ case object MajorFacilityLogic val zone = building.Zone val msg = PlanetsideAttribute(building.GUID, 46, 2) building.PlayersInSOI.foreach { player => - zone.AvatarEvents ! AvatarServiceMessage(player.Name, msg) + zone.AvatarEvents ! MessageEnvelope(player.Name, msg) } //??? true case Some(GeneratorControl.Event.Normal) => @@ -248,12 +248,14 @@ case object MajorFacilityLogic powerRestored(details) val events = zone.AvatarEvents val guid = building.GUID - val msg1 = PlanetsideAttribute(guid, 46, 0) - val msg2 = GenericObjectAction(guid, 17) + //1. reset ???; might be global? + //2. This facility's generator is back on line + val list = SendResponse(List( + PlanetsideAttributeMessage(guid, 46, 0), + GenericObjectActionMessage(guid, 17) + )) building.PlayersInSOI.foreach { player => - val name = player.Name - events ! AvatarServiceMessage(name, msg1) //reset ???; might be global? - events ! AvatarServiceMessage(name, msg2) //This facility's generator is back on line + events ! MessageEnvelope(player.Name, list) } true case _ => @@ -304,10 +306,12 @@ case object MajorFacilityLogic building.Amenities.foreach { amenity => amenity.Actor ! powerMsg } - //amenities disabled; red warning lights - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 48, 1)) - //disable spawn target on deployment map - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 38, 0)) + //1. amenities disabled; red warning lights + //2 .disable spawn target on deployment map + events ! MessageEnvelope( + zoneId, + SendResponse(List(PlanetsideAttributeMessage(guid, 48, 1), PlanetsideAttributeMessage(guid, 38, 0))) + ) Behaviors.same } @@ -327,10 +331,12 @@ case object MajorFacilityLogic building.Amenities.foreach { amenity => amenity.Actor ! powerMsg } - //amenities enabled; normal lights - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 48, 0)) - //enable spawn target on deployment map - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(guid, 38, 1)) + //1. amenities enabled; normal lights + //2. enable spawn target on deployment map + events ! MessageEnvelope( + zoneId, + SendResponse(List(PlanetsideAttributeMessage(guid, 48, 0), PlanetsideAttributeMessage(guid, 38, 1))) + ) Behaviors.same } diff --git a/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala b/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala index 05cad4278..2553a30fd 100644 --- a/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala @@ -6,7 +6,8 @@ import akka.actor.typed.scaladsl.Behaviors import net.psforever.actors.commands.NtuCommand import net.psforever.actors.zone.BuildingActor import net.psforever.objects.serverobject.structures.{Amenity, Building, WarpGate} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.galaxy.GalaxyAction import net.psforever.types.PlanetSideEmpire import net.psforever.util.Config @@ -182,7 +183,7 @@ case object WarpGateLogic val pairedWgFaction = pairedWg.Faction if (pairedWgFaction != terminalWgFaction) { pairedWg.Faction = terminalWgFaction - details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(pairedWg.infoUpdateMessage())) + details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(pairedWg.infoUpdateMessage())) } //the terminal warpgate can not be considered broadcast for other faction if (terminalWg.AllowBroadcastFor.contains(pairedWgFaction)) { @@ -209,7 +210,7 @@ case object WarpGateLogic ) warpgate.AllowBroadcastFor = setBroadcastTo (setBroadcastTo ++ previousAllowances).foreach { faction => - events ! GalaxyServiceMessage(faction.toString, msg) + events ! MessageEnvelope(faction.toString, msg) } } diff --git a/src/main/scala/net/psforever/login/WorldSession.scala b/src/main/scala/net/psforever/login/WorldSession.scala index dd9a137c0..25ebec529 100644 --- a/src/main/scala/net/psforever/login/WorldSession.scala +++ b/src/main/scala/net/psforever/login/WorldSession.scala @@ -15,7 +15,8 @@ import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.TerminalUsedActivity import net.psforever.objects.zones.Zone import net.psforever.types.{ExoSuitType, PlanetSideGUID, TransactionType, Vector3} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete import scala.concurrent.ExecutionContext.Implicits.global @@ -326,7 +327,7 @@ object WorldSession { case _ => forcedTolowerRaisedArm(localPlayer, localPlayer.GUID, localZone) localPlayer.DrawnSlot = localSlot - localZone.AvatarEvents ! AvatarServiceMessage(localZone.id, localGUID, AvatarAction.ObjectHeld(localSlot, localSlot)) + localZone.AvatarEvents ! MessageEnvelope(localZone.id, localGUID, AvatarAction.ObjectHeld(localSlot, localSlot)) } Future(this) } @@ -367,7 +368,7 @@ object WorldSession { localZone.GUID(item_guid) match { case Some(_) => () case None => //acting on old data? - localZone.AvatarEvents ! AvatarServiceMessage(localZone.id, ObjectDelete(item_guid)) + localZone.AvatarEvents ! MessageEnvelope(localZone.id, ObjectDelete(item_guid)) } case _ => () } @@ -526,7 +527,6 @@ object WorldSession { * Failure of this process is not supported and may lead to irregular behavior. * @see `ActorRef` * @see `AvatarAction.ObjectDelete` - * @see `AvatarServiceMessage` * @see `Containable.MoveItem` * @see `Container` * @see `Equipment` @@ -591,7 +591,7 @@ object WorldSession { localGUID match { case Some(guid) => //see LockerContainerControl.RemoveItemFromSlotCallback - localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, ObjectDelete(guid)) + localSource.Zone.AvatarEvents ! MessageEnvelope(localChannel, ObjectDelete(guid)) case None => () } val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot))) @@ -616,8 +616,7 @@ object WorldSession { * Remove an item from a player's locker inventory. * Failure of this process is not supported and may lead to irregular behavior. * @see `ActorRef` - * @see `AvatarAction.ObjectDelete` - * @see `AvatarServiceMessage` + * @see `ObjectDelete` * @see `Containable.MoveItem` * @see `Container` * @see `Equipment` @@ -693,7 +692,7 @@ object WorldSession { localGUID match { case Some(guid) => //see LockerContainerControl.RemoveItemFromSlotCallback - localSource.Zone.AvatarEvents ! AvatarServiceMessage(localChannel, ObjectDelete(guid)) + localSource.Zone.AvatarEvents ! MessageEnvelope(localChannel, ObjectDelete(guid)) case None => () } val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot))) @@ -730,8 +729,7 @@ object WorldSession { * If the player's already-drawn hand is the same as the one that will hold the grenade (first sidearm holster), * treat it like the sidearm occupier rather than the already-drawn weapon - * the old weapon goes into the backpack or onto the ground. - * @see `AvatarAction.ObjectHeld` - * @see `AvatarServiceMessage` + * @see `ObjectHeld` * @see `Containable.RemoveItemFromSlot` * @see `countRestrictAttempts` * @see `forcedTolowerRaisedArm` @@ -783,7 +781,7 @@ object WorldSession { } //put up hand with grenade in it tplayer.DrawnSlot = slotNum - zone.AvatarEvents ! AvatarServiceMessage(zone.id, guid, AvatarAction.ObjectHeld(slotNum, slotNum)) + zone.AvatarEvents ! MessageEnvelope(zone.id, guid, AvatarAction.ObjectHeld(slotNum, slotNum)) log.info(s"${tplayer.Name} has quickly drawn a ${grenade.Definition.Name}") None case None => @@ -857,8 +855,7 @@ object WorldSession { /** * If the player has a raised arm, lower it. * Do it manually, bypassing the checks in the normal procedure. - * @see `AvatarAction.ObjectHeld` - * @see `AvatarServiceMessage` + * @see `ObjectHeld` * @see `Player.DrawnSlot` * @see `Player.HandsDownSlot` * @param tplayer the player @@ -870,7 +867,7 @@ object WorldSession { val slot = tplayer.DrawnSlot if (slot != Player.HandsDownSlot) { tplayer.DrawnSlot = Player.HandsDownSlot - zone.AvatarEvents ! AvatarServiceMessage(zone.id, guid, AvatarAction.ObjectHeld(Player.HandsDownSlot, slot)) + zone.AvatarEvents ! MessageEnvelope(zone.id, guid, AvatarAction.ObjectHeld(Player.HandsDownSlot, slot)) true } else { false @@ -933,7 +930,7 @@ object WorldSession { player.ContributionFrom(term) } } - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.TerminalOrderResult(guid, transaction, result) ) diff --git a/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/src/main/scala/net/psforever/objects/BoomerDeployable.scala index 4e9f4cf3e..84285db2c 100644 --- a/src/main/scala/net/psforever/objects/BoomerDeployable.scala +++ b/src/main/scala/net/psforever/objects/BoomerDeployable.scala @@ -11,9 +11,9 @@ import net.psforever.objects.vital.Vitality import net.psforever.objects.vital.etc.TriggerUsedReason import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.zones.Zone -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideEmpire import scala.annotation.unused @@ -87,9 +87,9 @@ class BoomerDeployableControl(mine: BoomerDeployable) val events = mine.Zone.LocalEvents val msg = LocalAction.DeployItem(mine) originalOwner.collect { name => - events ! LocalServiceMessage(name, msg) + events ! MessageEnvelope(name, msg) } - events ! LocalServiceMessage(player.Name, msg) + events ! MessageEnvelope(player.Name, msg) } override def dismissDeployable() : Unit = { @@ -107,7 +107,7 @@ class BoomerDeployableControl(mine: BoomerDeployable) zone.Ground ! Zone.Ground.RemoveItem(guid) case _ => () } - zone.AvatarEvents! AvatarServiceMessage( + zone.AvatarEvents! MessageEnvelope( zone.id, ObjectDelete(guid) ) diff --git a/src/main/scala/net/psforever/objects/Deployables.scala b/src/main/scala/net/psforever/objects/Deployables.scala index 961ba941d..6fa64bd33 100644 --- a/src/main/scala/net/psforever/objects/Deployables.scala +++ b/src/main/scala/net/psforever/objects/Deployables.scala @@ -9,8 +9,9 @@ import net.psforever.objects.ce.{Deployable, DeployedItem} import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.zones.Zone import net.psforever.packet.game._ +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.PlanetSideGUID -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction object Deployables { //private val log = org.log4s.getLogger("Deployables") @@ -92,7 +93,7 @@ object Deployables { } target.AssignOwnership(None) } - events ! LocalServiceMessage( + events ! MessageEnvelope( s"${target.Faction}", LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, DeployableInfo(target.GUID, Deployable.Icon(item), target.Position, PlanetSideGUID(0))) ) diff --git a/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala b/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala index adf103058..91f3883f1 100644 --- a/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala +++ b/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala @@ -18,8 +18,9 @@ import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.Zone import net.psforever.types.Vector3 import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.local.LocalAction import scala.annotation.unused import scala.concurrent.duration._ @@ -182,7 +183,7 @@ object ExplosiveDeployableControl { target.Health = 1 // short-circuit logic in DestructionAwareness val zone = target.Zone zone.Activity ! Zone.HotSpot.Activity(cause) - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.Detonate(target.GUID, target)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.Detonate(target.GUID, target)) Zone.serverSideDamage( zone, target, @@ -210,12 +211,12 @@ object ExplosiveDeployableControl { Some(if (target.Jammed || target.Destroyed) 0 seconds else 500 milliseconds) ) target.Destroyed = true - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, AvatarAction.Destroy(target.GUID, attribution, Service.defaultPlayerGUID, target.Position) ) if (target.Health == 0) { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.TriggerEffect("detonate_damaged_mine", target.GUID) ) diff --git a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala index b098e17f0..2ebf81e88 100644 --- a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala @@ -12,8 +12,8 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, TurretSource} import net.psforever.objects.vital.{DismountingActivity, InGameActivity, MountingActivity, ShieldCharge} import net.psforever.packet.game.HackState1 +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute -import net.psforever.services.vehicle.VehicleServiceMessage import scala.annotation.unused @@ -98,7 +98,7 @@ class FieldTurretControl(turret: TurretDeployable) if (canChargeShields) { turret.LogActivity(ShieldCharge(amount, motivator)) turret.Shields = turret.Shields + amount - turret.Zone.VehicleEvents ! VehicleServiceMessage( + turret.Zone.VehicleEvents ! MessageEnvelope( s"${turret.Actor}", PlanetsideAttribute(turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields) ) diff --git a/src/main/scala/net/psforever/objects/Players.scala b/src/main/scala/net/psforever/objects/Players.scala index 337491e3d..c5df2a0cb 100644 --- a/src/main/scala/net/psforever/objects/Players.scala +++ b/src/main/scala/net/psforever/objects/Players.scala @@ -20,9 +20,10 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.types.{ChatMessageType, ExoSuitType, PlanetSideGUID, Vector3} import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, SendResponse} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import scala.annotation.tailrec @@ -49,7 +50,7 @@ object Players { ) { val events = target.Zone.AvatarEvents val uname = user.Name - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, SendResponse(RepairMessage(target.GUID, progress.toInt)) ) @@ -317,7 +318,7 @@ object Players { ): Boolean = { if (player.Zone == obj.Zone && addFunc(obj)) { obj.Actor ! Deployable.Ownership(player) - player.Zone.LocalEvents ! LocalServiceMessage(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) + player.Zone.LocalEvents ! MessageEnvelope(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) true } else { false @@ -334,7 +335,7 @@ object Players { //sent to avatar event bus to preempt additional tool management buildCooldownReset(zone, channel, obj.GUID) //sent to local event bus to cooperate with deployable management - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( channel, LocalAction.DeployableUIFor(obj.Definition.Item) ) @@ -348,7 +349,7 @@ object Players { */ def buildCooldownReset(zone: Zone, channel: String, guid: PlanetSideGUID): Unit = { //sent to avatar event bus to preempt additional tool management - zone.AvatarEvents ! AvatarServiceMessage(channel, SendResponse(GenericObjectActionMessage(guid, 21))) + zone.AvatarEvents ! MessageEnvelope(channel, SendResponse(GenericObjectActionMessage(guid, 21))) } /** @@ -404,7 +405,7 @@ object Players { } }) { val zone = player.Zone - zone.AvatarEvents ! AvatarServiceMessage(zone.id, ObjectDelete(tool.GUID)) + zone.AvatarEvents ! MessageEnvelope(zone.id, ObjectDelete(tool.GUID)) true } else { false @@ -442,20 +443,20 @@ object Players { player.Inventory -= x.start obj.FireModeIndex = fireMode //TODO any penalty for being handed an OCM version of the tool? - events ! AvatarServiceMessage( + events ! MessageEnvelope( zone.id, AvatarAction.EquipmentInHand(pguid, index, obj) ) if (obj.AmmoTypeIndex != ammoType) { obj.AmmoTypeIndex = ammoType - events ! AvatarServiceMessage( + events ! MessageEnvelope( name, SendResponse(ChangeAmmoMessage(obj.GUID, ammoType)) ) } if (player.DrawnSlot == Player.HandsDownSlot) { player.DrawnSlot = index - events ! AvatarServiceMessage(zone.id, pguid, AvatarAction.ObjectHeld(index, index)) + events ! MessageEnvelope(zone.id, pguid, AvatarAction.ObjectHeld(index, index)) } } case Nil => ; //no replacements found diff --git a/src/main/scala/net/psforever/objects/SensorDeployable.scala b/src/main/scala/net/psforever/objects/SensorDeployable.scala index ce7fd8a74..77e812a23 100644 --- a/src/main/scala/net/psforever/objects/SensorDeployable.scala +++ b/src/main/scala/net/psforever/objects/SensorDeployable.scala @@ -12,10 +12,10 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.SimpleResolutions import net.psforever.objects.vital.interaction.DamageResult +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{PlanetSideGUID, Vector3} import net.psforever.services.base.message.PlanetsideAttribute -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.local.LocalAction import scala.annotation.unused import scala.concurrent.duration._ @@ -75,7 +75,7 @@ class SensorDeployableControl(sensor: SensorDeployable) override def StartJammeredSound(target: Any, dur: Int): Unit = target match { case obj: PlanetSideServerObject if !jammedSound => - obj.Zone.VehicleEvents ! VehicleServiceMessage( + obj.Zone.VehicleEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 54, 1) ) @@ -87,7 +87,7 @@ class SensorDeployableControl(sensor: SensorDeployable) target match { case obj: PlanetSideServerObject with JammableUnit => val zone = obj.Zone - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.TriggerEffectInfo(obj.GUID, "on", unk1=false, 1000) ) @@ -99,7 +99,7 @@ class SensorDeployableControl(sensor: SensorDeployable) target match { case obj: PlanetSideServerObject if jammedSound => val zone = obj.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(obj.GUID, 54, 0) ) @@ -112,7 +112,7 @@ class SensorDeployableControl(sensor: SensorDeployable) target match { case obj: PlanetSideServerObject with JammableUnit if obj.Jammed => val zone = sensor.Zone - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.TriggerEffectInfo(obj.GUID, "on", unk1=true, 1000) ) @@ -124,7 +124,7 @@ class SensorDeployableControl(sensor: SensorDeployable) override def finalizeDeployable(callback: ActorRef) : Unit = { super.finalizeDeployable(callback) val zone = sensor.Zone - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.TriggerEffectInfo(sensor.GUID, "on", unk1=true, 1000) ) @@ -141,7 +141,7 @@ object SensorDeployableControl { def DestructionAwareness(target: Deployable, attribution: PlanetSideGUID): Unit = { Deployables.AnnounceDestroyDeployable(target, Some(1 seconds)) val zone = target.Zone - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.TriggerEffectInfo(target.GUID, "on", unk1=false, 1000) ) @@ -157,7 +157,7 @@ object SensorDeployableControl { pos.z + math.cos(yRadians).toFloat * 0.875f ) } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.TriggerEffectLocation("motion_sensor_destroyed", explosionPos, ang) ) diff --git a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala index 96a80ef25..42282ca57 100644 --- a/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala +++ b/src/main/scala/net/psforever/objects/ShieldGeneratorDeployable.scala @@ -13,9 +13,9 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.repair.RepairableEntity import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.resolution.ResolutionCalculations +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.PlanetSideGUID -import net.psforever.services.vehicle.VehicleServiceMessage class ShieldGeneratorDeployable(cdef: ShieldGeneratorDefinition) extends Deployable(cdef) @@ -125,7 +125,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) override def StartJammeredStatus(target: Any, dur: Int): Unit = target match { case obj: PlanetSideServerObject with JammableUnit => - obj.Zone.VehicleEvents ! VehicleServiceMessage( + obj.Zone.VehicleEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 27, 1) ) @@ -138,7 +138,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable) override def CancelJammeredStatus(target: Any): Unit = { target match { case obj: PlanetSideServerObject with JammableUnit if obj.Jammed => - obj.Zone.VehicleEvents ! VehicleServiceMessage( + obj.Zone.VehicleEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 27, 0) ) @@ -160,7 +160,7 @@ object ShieldGeneratorControl { //shields if (damageToShields) { val zone = target.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 68, target.Shields) ) diff --git a/src/main/scala/net/psforever/objects/TelepadDeployable.scala b/src/main/scala/net/psforever/objects/TelepadDeployable.scala index a0cfa954a..c524f7f24 100644 --- a/src/main/scala/net/psforever/objects/TelepadDeployable.scala +++ b/src/main/scala/net/psforever/objects/TelepadDeployable.scala @@ -11,7 +11,8 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.vital.SimpleResolutions import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.local.LocalAction import scala.concurrent.duration._ @@ -133,6 +134,6 @@ object TelepadControl { } def TelepadError(zone: Zone, channel: String, msg: String): Unit = { - zone.LocalEvents ! LocalServiceMessage(channel, LocalAction.RouterTelepadMessage(msg)) + zone.LocalEvents ! MessageEnvelope(channel, LocalAction.RouterTelepadMessage(msg)) } } diff --git a/src/main/scala/net/psforever/objects/Tools.scala b/src/main/scala/net/psforever/objects/Tools.scala index 4c4ca573c..459e4f4ce 100644 --- a/src/main/scala/net/psforever/objects/Tools.scala +++ b/src/main/scala/net/psforever/objects/Tools.scala @@ -3,7 +3,7 @@ package net.psforever.objects import net.psforever.objects.equipment.ChargeFireModeDefinition import net.psforever.packet.game.QuantityUpdateMessage -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse object Tools { @@ -22,7 +22,7 @@ object Tools { tool.FireMode match { case mode: ChargeFireModeDefinition if tool.Magazine > 0 => val magazine = tool.Magazine -= mode.RoundsPerInterval - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Name, SendResponse(QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine)) ) diff --git a/src/main/scala/net/psforever/objects/TurretDeployable.scala b/src/main/scala/net/psforever/objects/TurretDeployable.scala index 576a1629c..7b0cc5f3e 100644 --- a/src/main/scala/net/psforever/objects/TurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/TurretDeployable.scala @@ -20,7 +20,8 @@ import net.psforever.objects.vital.resistance.StandardResistanceProfile import net.psforever.objects.vital.{SimpleResolutions, StandardVehicleResistance} import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.TriggeredSound -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.duration.FiniteDuration @@ -109,7 +110,7 @@ abstract class TurretDeployableControl case player: Player => seat.unmount(player) player.VehicleSeated = None - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, player.GUID, VehicleAction.KickPassenger(4, wasKickedByDriver, TurretObject.GUID) diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 6c21b1bf3..8b0a43f6b 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -13,10 +13,10 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.Service -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.local.LocalAction +import net.psforever.services.vehicle.VehicleAction //import scala.concurrent.duration._ @@ -46,7 +46,7 @@ object Vehicles { val locked = VehicleLockState.Locked.id Array(0, 3).foreach(group => vehicle.PermissionGroup(group, locked)) Vehicles.ReloadAccessPermissions(vehicle, tplayer.Faction.toString) - vehicle.Zone.VehicleEvents ! VehicleServiceMessage( + vehicle.Zone.VehicleEvents ! MessageEnvelope( vehicle.Zone.id, tplayer.GUID, VehicleAction.Ownership(vehicle.GUID) @@ -90,7 +90,7 @@ object Vehicles { val empire = VehicleLockState.Empire.id (0 to 2).foreach(group => vehicle.PermissionGroup(group, empire)) ReloadAccessPermissions(vehicle, vehicle.Faction.toString) - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, VehicleAction.LoseOwnership(ownerGuid.getOrElse(Service.defaultPlayerGUID), guid) ) @@ -140,12 +140,12 @@ object Vehicles { val pguid = player.GUID if (vehicle.OwnerGuid.contains(pguid)) { vehicle.AssignOwnership(None) - //vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, pguid, VehicleAction.Ownership(pguid, PlanetSideGUID(0))) + //vehicle.Zone.VehicleEvents ! MessageEnvelope(player.Name, pguid, VehicleAction.Ownership(pguid, PlanetSideGUID(0))) //val vguid = vehicle.GUID val empire = VehicleLockState.Empire.id (0 to 2).foreach(group => { vehicle.PermissionGroup(group, empire) - /*vehicle.Zone.VehicleEvents ! VehicleServiceMessage( + /*vehicle.Zone.VehicleEvents ! MessageEnvelope( s"${vehicle.Faction}", pguid, VehicleAction.SeatPermissions(pguid, vguid, group, empire) @@ -170,7 +170,7 @@ object Vehicles { def ReloadAccessPermissions(vehicle: Vehicle, toChannel: String): Unit = { val vehicle_guid = vehicle.GUID (0 to 3).foreach(group => { - vehicle.Zone.AvatarEvents ! AvatarServiceMessage( + vehicle.Zone.AvatarEvents ! MessageEnvelope( toChannel, PlanetsideAttribute(vehicle_guid, group + 10, vehicle.PermissionGroup(group).get.id) ) @@ -252,7 +252,7 @@ object Vehicles { val vehicleEvents = zone.VehicleEvents val localEvents = zone.LocalEvents val previousOwnerName = target.OwnerName.getOrElse("") - vehicleEvents ! VehicleServiceMessage( + vehicleEvents ! MessageEnvelope( zoneid, SendResponse(HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8)) ) @@ -269,7 +269,7 @@ object Vehicles { player: Player => seat.unmount(player) player.VehicleSeated = None - vehicleEvents ! VehicleServiceMessage( + vehicleEvents ! MessageEnvelope( zoneid, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, tGuid) @@ -277,16 +277,16 @@ object Vehicles { } // In case BFR is occupied and may or may not be crouched if (GlobalDefinitions.isBattleFrameVehicle(target.Definition) && target.Seat(0).isDefined) { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zoneid, PlanetSideGUID(-1), GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown.id) ) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zoneid, SendResponse( FrameVehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), unk2=false, 0, 0, is_crouched=true, is_airborne=false, ascending_flight=false, 10, 0, 0))) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zoneid, SendResponse( VehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), None, 0, 0, 15, is_decelerating=false, is_cloaked=false))) @@ -314,23 +314,23 @@ object Vehicles { Vehicles.Own(target, hacker) //todo: Send HackMessage -> HackCleared to vehicle? can be found in packet captures. Not sure if necessary. // And broadcast the faction change to other clients - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zoneid, SetEmpire(tGuid, hFaction) ) } - localEvents ! LocalServiceMessage( + localEvents ! MessageEnvelope( zoneid, hGuid, LocalAction.TriggerSound(TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f) ) if (zone.Players.exists(_.name.equals(previousOwnerName))) { - localEvents ! LocalServiceMessage( + localEvents ! MessageEnvelope( previousOwnerName, SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen")) ) } - localEvents ! LocalServiceMessage( + localEvents ! MessageEnvelope( hacker.Name, SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned")) ) @@ -345,10 +345,10 @@ object Vehicles { util.Actor ! TelepadLike.Activate(util) } case GlobalDefinitions.ams if target.DeploymentState == DriveState.Deployed => - vehicleEvents ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) + vehicleEvents ! MessageEnvelope(zone.id, VehicleAction.AMSDeploymentChange(zone)) case _ => () } - vehicleEvents ! VehicleServiceMessage( + vehicleEvents ! MessageEnvelope( zoneid, SendResponse(HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8)) ) diff --git a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala index aad190d15..3537cfbd7 100644 --- a/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/CorpseControl.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.containable.{Containable, ContainableB import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types.{PlanetSideEmpire, Vector3} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, SendResponse} class CorpseControl(player: Player) extends Actor with ContainableBehavior { @@ -25,7 +25,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val obj = ContainerObject obj.Find(item) match { case Some(slot) => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( player.Zone.id, SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) @@ -40,7 +40,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val zone = obj.Zone val events = zone.AvatarEvents item.Faction = PlanetSideEmpire.NEUTRAL - events ! AvatarServiceMessage(zone.id, ObjectDelete(item.GUID)) + events ! MessageEnvelope(zone.id, ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -48,7 +48,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { val zone = obj.Zone val events = zone.AvatarEvents val definition = item.Definition - events ! AvatarServiceMessage( + events ! MessageEnvelope( zone.id, SendResponse( ObjectCreateDetailedMessage( @@ -64,7 +64,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior { def SwapItemCallback(item: Equipment, fromSlot: Int): Unit = { val obj = ContainerObject val zone = obj.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, SendResponse(ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f)) ) diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 156deb8c9..f66ae7cab 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -26,8 +26,8 @@ import net.psforever.packet.game._ import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types._ import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.local.LocalAction import net.psforever.objects.locker.LockerContainerControl import net.psforever.objects.serverobject.environment.interaction.RespondsToZoneEnvironment import net.psforever.objects.serverobject.repair.Repairable @@ -36,6 +36,7 @@ import net.psforever.objects.vital.collision.CollisionReason import net.psforever.objects.vital.etc.{PainboxReason, SuicideReason} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.PlanetSideGamePacket +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{EventMessage, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, SendResponse} import org.joda.time.{LocalDateTime, Seconds} @@ -148,11 +149,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (!(player.isMoving || user.isMoving)) { //only allow stationary heals val newHealth = player.Health = originalHealth + 10 val magazine = item.Discharge() - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) - events ! AvatarServiceMessage(zone.id, PlanetsideAttribute(guid, 0, newHealth)) + events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 0, newHealth)) player.LogActivity( HealFromEquipment( PlayerSource(user), @@ -172,9 +173,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } if (player != user) { //"Someone is trying to heal you" - events ! AvatarServiceMessage(player.Name, PlanetsideAttribute(guid, 55, 1)) + events ! MessageEnvelope(player.Name, PlanetsideAttribute(guid, 55, 1)) //progress bar remains visible for all heal attempts - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, SendResponse(RepairMessage(guid, player.Health * 100 / definition.MaxHealth)) ) @@ -214,11 +215,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val newArmor = player.Armor = originalArmor + Repairable.applyLevelModifier(user, item, RepairToolValue(item)).toInt + definition.RepairMod val magazine = item.Discharge() - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) - events ! AvatarServiceMessage(zone.id, PlanetsideAttribute(guid, 4, player.Armor)) + events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 4, player.Armor)) player.LogActivity( RepairFromEquipment( PlayerSource(user), @@ -239,13 +240,13 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (player != user) { if (player.isAlive) { //"Someone is trying to repair you" gets strobed twice for visibility - val msg = AvatarServiceMessage(player.Name, PlanetsideAttribute(guid, 56, 1)) + val msg = MessageEnvelope(player.Name, PlanetsideAttribute(guid, 56, 1)) events ! msg import scala.concurrent.ExecutionContext.Implicits.global context.system.scheduler.scheduleOnce(250 milliseconds, events, msg) } //progress bar remains visible for all repair attempts - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, SendResponse(RepairMessage(guid, player.Armor * 100 / player.MaxArmor)) ) @@ -312,16 +313,16 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm avatarActor ! AvatarActor.UpdateUseTime(kdef) player.Slot(slot).Equipment = None //remove from slot immediately; must exist on client for now TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, kit)) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(player.GUID, attribute, value) ) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.UseKit(kguid, kdef.ObjectId) ) case _ => - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.KitNotUsed(kit.GUID, msg) ) @@ -335,14 +336,14 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val events = player.Zone.AvatarEvents val resistance = player.TestArmMotion(slot) if (resistance && !updateMyHolsterArm) { - events ! AvatarServiceMessage( + events ! MessageEnvelope( player.Name, player.GUID, AvatarAction.ObjectHeld(before, -1) ) } else if ((!resistance && before != slot && (player.DrawnSlot = slot) != before) && ItemSwapSlot != before) { val mySlot = if (updateMyHolsterArm) slot else -1 //use as a short-circuit - events ! AvatarServiceMessage( + events ! MessageEnvelope( Players.ZoneChannelIfSpectating(player), player.GUID, AvatarAction.ObjectHeld(mySlot, player.LastDrawnSlot) @@ -355,7 +356,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm log.info(s"${player.Name} has drawn a ${unholsteredItem.Definition.Name} from its holster") if (unholsteredItem.Definition == GlobalDefinitions.remote_electronics_kit) { //rek beam/icon colour must match the player's correct hack level - events ! AvatarServiceMessage( + events ! MessageEnvelope( Players.ZoneChannelIfSpectating(player), unholsteredItem.GUID, PlanetsideAttribute(unholsteredItem.GUID, 116, player.avatar.hackingSkillLevel()) @@ -370,7 +371,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //make sure the player didn't just initialte an orbital strike. If not (the if below is true), make sure waypoint is removed if (holsteredEquipment.Definition == GlobalDefinitions.command_detonater && player.avatar.cr.value > 3 && !player.avatar.cooldowns.purchase.exists(os => os._1 == "orbital_strike" && Seconds.secondsBetween(os._2, LocalDateTime.now()).getSeconds < 12)) { - player.Zone.LocalEvents ! LocalServiceMessage( + player.Zone.LocalEvents ! MessageEnvelope( s"${player.Faction}", PlanetSideGUID(-1), SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None)) @@ -398,7 +399,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (exosuit == ExoSuitType.MAX) { player.ResistArmMotion(PlayerControl.maxRestriction) } - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.TerminalOrderResult(msg.terminal_guid, msg.transaction_type, result) ) @@ -530,7 +531,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm Deployables.initializeConstructionItem(player.avatar.certifications, citem) } val zone = player.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( Players.ZoneChannelIfSpectating(player), AvatarAction.ChangeLoadout( player.GUID, @@ -546,7 +547,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm itemsToDrop ) ) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.TerminalOrderResult(msg.terminal_guid, msg.transaction_type, result=true) ) @@ -575,7 +576,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case Zone.Ground.CanNotPickupItem(_, item_guid, reason) => log.warn(s"${player.Name} failed to pick up an item ($item_guid) from the ground because $reason") if (reason.startsWith("@")) { - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( player.Name, SendResponse(ChatMsg(ChatMessageType.UNK_227, reason)) ) @@ -595,7 +596,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val trigger = new BoomerTrigger trigger.Companion = obj.GUID obj.Trigger = trigger - zone.AvatarEvents ! AvatarServiceMessage(zone.id, ObjectDelete(tool.GUID)) + zone.AvatarEvents ! MessageEnvelope(zone.id, ObjectDelete(tool.GUID)) TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, tool)) player.Find(tool) match { case Some(index) if player.VisibleSlots.contains(index) => @@ -647,7 +648,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case Player.LoseDeployable(obj) => if (player.avatar.deployables.Remove(obj)) { - player.Zone.LocalEvents ! LocalServiceMessage(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) + player.Zone.LocalEvents ! MessageEnvelope(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) } case _ => ; @@ -720,7 +721,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //insert afterHolsters.foreach(elem => player.Slot(elem.start).Equipment = elem.obj) afterInventory.foreach(elem => player.Inventory.InsertQuickly(elem.start, elem.obj)) - player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Zone.AvatarEvents ! MessageEnvelope( Players.ZoneChannelIfSpectating(player), AvatarAction.ChangeExosuit( player.GUID, @@ -746,7 +747,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm def loseDeployableOwnership(obj: Deployable): Boolean = { if (player.avatar.deployables.Remove(obj)) { obj.Actor ! Deployable.Ownership(None) - player.Zone.LocalEvents ! LocalServiceMessage(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) + player.Zone.LocalEvents ! MessageEnvelope(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) true } else { @@ -768,14 +769,14 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case GlobalDefinitions.ace if obj.Definition.deployAnimation == DeployAnimation.Standard => val ownerGuid = obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, ownerGuid, LocalAction.TriggerEffectLocation("spawn_object_effect", obj.Position, obj.Orientation) ) case GlobalDefinitions.advanced_ace if obj.Definition.deployAnimation == DeployAnimation.Fdu => - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PutDownFDU(player.GUID)) + zone.AvatarEvents ! MessageEnvelope(zone.id, AvatarAction.PutDownFDU(player.GUID)) case _ => org.log4s .getLogger(name = "Deployables") @@ -878,7 +879,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm //always do armor update if (damageToArmor > 0) { val zone = target.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 4, target.Armor) ) @@ -936,7 +937,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm target.LogActivity(cause) //stat changes if (damageToCapacitor > 0) { - events ! AvatarServiceMessage(target.Name, PlanetsideAttribute(targetGUID, 7, target.Capacitor.toLong)) + events ! MessageEnvelope(target.Name, PlanetsideAttribute(targetGUID, 7, target.Capacitor.toLong)) announceConfrontation = true //TODO should we? } if (damageToStamina > 0) { @@ -944,13 +945,13 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm announceConfrontation = true //TODO should we? } if (damageToHealth > 0) { - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 0, health)) + events ! MessageEnvelope(zoneId, PlanetsideAttribute(targetGUID, 0, health)) announceConfrontation = true } val countableDamage = damageToHealth + damageToArmor if(announceConfrontation) { if (aggravated) { - events ! AvatarServiceMessage( + events ! MessageEnvelope( zoneId, SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) ) @@ -965,19 +966,19 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val name = pSource.Name zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match { case Some(tplayer) => - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( target.Name, target.GUID, HintsAtAttacker(tplayer.GUID) ) case None => - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( target.Name, SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) ) } case source => - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( target.Name, SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) ) @@ -985,17 +986,17 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case None => cause.interaction.cause match { case o: PainboxReason => - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( target.Name, AvatarAction.EnvironmentalDamage(target.GUID, o.entity.GUID, countableDamage) ) case _: CollisionReason => - events ! AvatarServiceMessage( + events ! MessageEnvelope( zoneId, SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)) ) case _ => - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( target.Name, AvatarAction.EnvironmentalDamage(target.GUID, ValidPlanetSideGUID(0), countableDamage) ) @@ -1051,14 +1052,14 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm damageLog.info(s"${player.Name} killed ${player.Sex.pronounObject}self") } - events ! AvatarServiceMessage(nameChannel, player_guid, AvatarAction.Killed(cause, target.VehicleSeated)) //align client interface fields with state - events ! AvatarServiceMessage(zoneChannel, PlanetsideAttribute(player_guid, 0, 0)) //health + events ! MessageEnvelope(nameChannel, player_guid, AvatarAction.Killed(cause, target.VehicleSeated)) //align client interface fields with state + events ! MessageEnvelope(zoneChannel, PlanetsideAttribute(player_guid, 0, 0)) //health if (target.Capacitor > 0) { target.Capacitor = 0 - events ! AvatarServiceMessage(nameChannel, PlanetsideAttribute(player_guid, 7, 0)) // capacitor + events ! MessageEnvelope(nameChannel, PlanetsideAttribute(player_guid, 7, 0)) // capacitor } val attribute = DamageableEntity.attributionTo(cause, target.Zone, player_guid) - events ! AvatarServiceMessage( + events ! MessageEnvelope( nameChannel, SendResponse(DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos)) //how many players get this message? ) @@ -1089,7 +1090,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm override def StartJammeredSound(target: Any, dur: Int): Unit = target match { case obj: Player if !jammedSound => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 27, 1) ) @@ -1125,7 +1126,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm override def CancelJammeredSound(target: Any): Unit = target match { case obj: Player if jammedSound => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 27, 0) ) @@ -1172,7 +1173,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm if (slot == obj.DrawnSlot) { obj.DrawnSlot = Player.HandsDownSlot } - events ! AvatarServiceMessage(toChannel, ObjectDelete(item.GUID)) + events ! MessageEnvelope(toChannel, ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { @@ -1193,7 +1194,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case Some(obj: BoomerDeployable) => val deployables = player.avatar.deployables if (!deployables.Contains(obj) && deployables.Valid(obj)) { - events ! AvatarServiceMessage( + events ! MessageEnvelope( toChannel, SendResponse(GenericObjectAction2Message(1, player.GUID, trigger.GUID)) ) @@ -1212,12 +1213,12 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case _ => () } - events ! AvatarServiceMessage( + events ! MessageEnvelope( toChannel, SendResponse(OCM.detailed(item, ObjectCreateMessageParent(guid, slot))) ) if (!player.isBackpack && willBeVisible) { - events ! AvatarServiceMessage(zone.id, guid, AvatarAction.EquipmentInHand(guid, slot, item)) + events ! MessageEnvelope(zone.id, guid, AvatarAction.EquipmentInHand(guid, slot, item)) } } @@ -1231,17 +1232,16 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } else { player.Name } - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( toChannel, ObjectDelete(item.GUID) ) } def UpdateAuraEffect(target: AuraEffectBehavior.Target) : Unit = { - import net.psforever.services.avatar.AvatarServiceMessage val zone = target.Zone val value = target.Aura.foldLeft(0)(_ + PlayerControl.auraEffectToAttributeValue(_)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, PlanetsideAttribute(target.GUID, 54, value)) + zone.AvatarEvents ! MessageEnvelope(zone.id, PlanetsideAttribute(target.GUID, 54, value)) } } @@ -1271,11 +1271,11 @@ object PlayerControl { } def sendResponse(zone: Zone, channel: String, msg: PlanetSideGamePacket): Unit = { - zone.AvatarEvents ! AvatarServiceMessage(channel, SendResponse(msg)) + zone.AvatarEvents ! MessageEnvelope(channel, SendResponse(msg)) } def sendResponse(zone: Zone, channel: String, filter: PlanetSideGUID, msg: EventMessage): Unit = { - zone.AvatarEvents ! AvatarServiceMessage(channel, filter, msg) + zone.AvatarEvents ! MessageEnvelope(channel, filter, msg) } def maxRestriction(player: Player, slot: Int): Boolean = { diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala index 7fc2c8aaa..0e475b85f 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithEntrance.scala @@ -6,6 +6,7 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.serverobject.environment.interaction.{InteractionWith, RespondsToZoneEnvironment} import net.psforever.objects.serverobject.interior.{Sidedness, TraditionalInteriorAware} import net.psforever.objects.zones.interaction.InteractsWithZone +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.types.Vector3 @@ -91,7 +92,6 @@ class WithEntrance() ): Sidedness = { import net.psforever.objects.{Player, Vehicle} import net.psforever.packet.game.ChatMsg - import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.types.ChatMessageType val channel = obj match { case p: Player => p.Name @@ -99,7 +99,7 @@ class WithEntrance() case _ => "" } if (door.Outwards == Vector3.Zero) { - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( channel, SendResponse(ChatMsg(ChatMessageType.UNK_229, "Door not configured.")) ) @@ -108,14 +108,14 @@ class WithEntrance() val result = Vector3.DotProduct(Vector3.Unit(obj.Position - door.Position), door.Outwards) > 0f if (result && WhichSide != Sidedness.OutsideOf) { //outside - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( channel, SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now outside")) ) Sidedness.OutsideOf } else if (!result && WhichSide != Sidedness.InsideOf) { //inside - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( channel, SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now inside")) ) diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala index 452cd5bf9..dc20521f6 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithGantry.scala @@ -7,7 +7,7 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game.{ChatMsg, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.hart.ShuttleState import net.psforever.types.ChatMessageType @@ -35,10 +35,10 @@ class WithGantry(val channel: String) player.VehicleSeated.isEmpty => val (pos, ang) = Vehicles.dismountShuttle(shuttle, field.mountPoint) val events = shuttle.Zone.AvatarEvents - events ! AvatarServiceMessage( + events ! MessageEnvelope( channel, SendResponse(PlayerStateShiftMessage(ShiftState(0, pos, ang, None)))) - events ! AvatarServiceMessage( + events ! MessageEnvelope( channel, SendResponse(ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway")) ) diff --git a/src/main/scala/net/psforever/objects/avatar/interaction/WithWater.scala b/src/main/scala/net/psforever/objects/avatar/interaction/WithWater.scala index 73af2ad60..ae2ca54af 100644 --- a/src/main/scala/net/psforever/objects/avatar/interaction/WithWater.scala +++ b/src/main/scala/net/psforever/objects/avatar/interaction/WithWater.scala @@ -7,7 +7,8 @@ import net.psforever.objects.serverobject.environment.interaction.common.Watery import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget import net.psforever.objects.serverobject.environment.{EnvironmentTrait, PieceOfEnvironment, interaction} import net.psforever.objects.zones.interaction.InteractsWithZone -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.OxygenState import scala.concurrent.duration._ @@ -299,7 +300,7 @@ class WithWater(val channel: String) cond: OxygenStateTarget, data: Option[OxygenStateTarget] ): Unit = { - obj.Zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.OxygenState(cond, data)) + obj.Zone.AvatarEvents ! MessageEnvelope(channel, AvatarAction.OxygenState(cond, data)) } } diff --git a/src/main/scala/net/psforever/objects/avatar/scoring/Statistic.scala b/src/main/scala/net/psforever/objects/avatar/scoring/Statistic.scala index e6b5b03a3..10dcd36b9 100644 --- a/src/main/scala/net/psforever/objects/avatar/scoring/Statistic.scala +++ b/src/main/scala/net/psforever/objects/avatar/scoring/Statistic.scala @@ -2,7 +2,7 @@ package net.psforever.objects.avatar.scoring /** - * Organizes the eight fields one would find in an `AvatarServiceMessage` statistic field. + * Organizes the eight fields one would find in an statistic field. * The `_c` fields and the `_s` fields are paired when the values populate the packet * where `c` stands for "campaign" and `s` stands for "session". * "Session" values reflect on the UI as the K in K/D diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index fc8215fd0..f1bba9f3b 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -7,9 +7,9 @@ import net.psforever.objects._ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.services.Service -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SetEmpire -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideEmpire import scala.concurrent.duration._ @@ -199,9 +199,9 @@ trait DeployableBehavior { None } //zone build - localEvents ! LocalServiceMessage(zone.id, LocalAction.DeployItem(obj)) + localEvents ! MessageEnvelope(zone.id, LocalAction.DeployItem(obj)) //zone map icon - localEvents ! LocalServiceMessage( + localEvents ! MessageEnvelope( obj.Faction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID))) ) @@ -247,7 +247,7 @@ trait DeployableBehavior { //there's no special meaning behind directing any replies from from zone governance straight back to zone governance //this deployable control agency, however, will be expiring and can not be a recipient zone.Deployables ! Zone.Deployable.Dismiss(obj) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, LocalAction.EliminateDeployable(obj, obj.GUID, obj.Position, deletionType) ) @@ -283,12 +283,12 @@ object DeployableBehavior { if (originalFaction != toFaction) { obj.Faction = toFaction //visual tells in regards to ownership by faction - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, SetEmpire(dGuid, toFaction) ) //remove knowledge by the previous owner's faction - localEvents ! LocalServiceMessage( + localEvents ! MessageEnvelope( originalFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, info) ) @@ -296,10 +296,10 @@ object DeployableBehavior { zone.AllPlayers.filter(p => obj.OriginalOwnerName.contains(p.Name)) .foreach { originalOwner => originalOwner.avatar.deployables.Remove(obj) - originalOwner.Zone.LocalEvents ! LocalServiceMessage(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) + originalOwner.Zone.LocalEvents ! MessageEnvelope(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) } //display to the given faction - localEvents ! LocalServiceMessage( + localEvents ! MessageEnvelope( toFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Build, info) ) diff --git a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala index e730cfef8..3ac01cfb9 100644 --- a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala +++ b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala @@ -9,8 +9,9 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.Zone import net.psforever.packet.game.{GenericObjectActionMessage, ObjectCreateMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideGUID trait TelepadLike { @@ -114,7 +115,7 @@ object TelepadLike { normally dispatched while the Router is transitioned into its Deploying state it is safe, however, to perform these actions at any time during and after the Deploying state */ - events ! LocalServiceMessage( + events ! MessageEnvelope( zoneId, SendResponse( ObjectCreateMessage( @@ -125,7 +126,7 @@ object TelepadLike { ) ) ) - events ! LocalServiceMessage(zoneId, SendResponse(Seq( + events ! MessageEnvelope(zoneId, SendResponse(Seq( GenericObjectActionMessage(utilityGUID, 27), GenericObjectActionMessage(utilityGUID, 30) ))) @@ -135,7 +136,7 @@ object TelepadLike { def LinkTelepad(zone: Zone, telepadGUID: PlanetSideGUID): Unit = { val events = zone.LocalEvents val zoneId = zone.id - events ! LocalServiceMessage(zoneId, SendResponse(Seq( + events ! MessageEnvelope(zoneId, SendResponse(Seq( GenericObjectActionMessage(telepadGUID, 27), GenericObjectActionMessage(telepadGUID, 28) ))) @@ -168,7 +169,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor { oldTpad.Actor ! TelepadLike.SeverLink(obj) } obj.Telepad = None - zone.LocalEvents ! LocalServiceMessage(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0))) + zone.LocalEvents ! MessageEnvelope(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0))) case TelepadLike.RequestLink(tpad: TelepadDeployable) => val zone = obj.Zone @@ -189,7 +190,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor { } } else { val channel = obj.Owner.asInstanceOf[Vehicle].OwnerName.getOrElse("") - zone.LocalEvents ! LocalServiceMessage(channel, LocalAction.RouterTelepadMessage("@Teleport_NotDeployed")) + zone.LocalEvents ! MessageEnvelope(channel, LocalAction.RouterTelepadMessage("@Teleport_NotDeployed")) tpad.Actor ! TelepadLike.SeverLink(obj) } @@ -197,7 +198,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor { if (obj.Telepad.contains(tpad.GUID)) { obj.Telepad = None val zone = obj.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0))) + zone.LocalEvents ! MessageEnvelope(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0))) } case _ => () diff --git a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala index 73355c951..9341e324d 100644 --- a/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala +++ b/src/main/scala/net/psforever/objects/equipment/ArmorSiphonBehavior.scala @@ -10,8 +10,8 @@ import net.psforever.objects.vital.RepairFromArmorSiphon import net.psforever.objects.vital.etc.{ArmorSiphonModifiers, ArmorSiphonReason} import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.packet.game.QuantityUpdateMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.PlanetSideGUID import scala.collection.mutable @@ -78,7 +78,7 @@ object ArmorSiphonBehavior { if(before < after) { obj.LogActivity(RepairFromArmorSiphon(asr.siphon.Definition, VehicleSource(obj), before - after)) val zone = obj.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(obj.GUID, 0, after) ) @@ -97,7 +97,7 @@ object ArmorSiphonBehavior { val siphon = siphonSlot.Equipment.get.asInstanceOf[Tool] val zone = obj.Zone //update current charge level - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( obj.Actor.toString, SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine)) ) @@ -119,7 +119,7 @@ object ArmorSiphonBehavior { val before = siphon.Magazine val after = siphon.Magazine = before + 1 if (after > before) { - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( obj.Actor.toString, SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after)) ) diff --git a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala index 126a44efb..cd50540b2 100644 --- a/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala +++ b/src/main/scala/net/psforever/objects/equipment/JammingUnit.scala @@ -8,9 +8,9 @@ import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.{Zone, ZoneAware} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.types.Vector3 -import net.psforever.services.vehicle.VehicleServiceMessage import scala.collection.mutable import scala.concurrent.duration._ @@ -234,7 +234,6 @@ trait JammableBehavior { * @see `Service` * @see `VehicleAction` * @see `VehicleService` - * @see `VehicleServiceMessage` * @see `Zone.VehicleEvents` */ trait JammableMountedWeapons extends JammableBehavior { @@ -243,7 +242,7 @@ trait JammableMountedWeapons extends JammableBehavior { override def StartJammeredSound(target: Any, dur: Int): Unit = { target match { case obj: PlanetSideServerObject with MountedWeapons with JammableUnit if !jammedSound => - obj.Zone.VehicleEvents ! VehicleServiceMessage( + obj.Zone.VehicleEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 27, 1) ) @@ -264,7 +263,7 @@ trait JammableMountedWeapons extends JammableBehavior { override def CancelJammeredSound(target: Any): Unit = { target match { case obj: PlanetSideServerObject if jammedSound => - obj.Zone.VehicleEvents ! VehicleServiceMessage( + obj.Zone.VehicleEvents ! MessageEnvelope( obj.Zone.id, PlanetsideAttribute(obj.GUID, 27, 0) ) @@ -308,7 +307,7 @@ object JammableMountedWeapons { def JammedWeaponStatus(zone: Zone, target: Equipment with JammableUnit, statusCode: Int): Unit = { target.Jammed = statusCode == 1 - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 27, statusCode) ) diff --git a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala index 19a1e388f..bef430721 100644 --- a/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala +++ b/src/main/scala/net/psforever/objects/locker/LockerContainerControl.scala @@ -6,7 +6,7 @@ import net.psforever.objects.equipment.Equipment import net.psforever.objects.serverobject.containable.{Containable, ContainableBehavior} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, SendResponse} import net.psforever.types.{PlanetSideEmpire, Vector3} @@ -34,7 +34,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) val obj = ContainerObject obj.Find(item) match { case Some(slot) => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( toChannel, SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) @@ -46,14 +46,14 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) def RemoveItemFromSlotCallback(item: Equipment, slot: Int): Unit = { val zone = locker.Zone - zone.AvatarEvents ! AvatarServiceMessage(toChannel, ObjectDelete(item.GUID)) + zone.AvatarEvents ! MessageEnvelope(toChannel, ObjectDelete(item.GUID)) } def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = { val zone = locker.Zone val definition = item.Definition item.Faction = PlanetSideEmpire.NEUTRAL - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( toChannel, SendResponse( ObjectCreateDetailedMessage( @@ -68,7 +68,7 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String) def SwapItemCallback(item: Equipment, fromSlot: Int): Unit = { val zone = locker.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( toChannel, SendResponse(ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f)) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala index b0ba85a90..74cf26a10 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala @@ -3,8 +3,9 @@ package net.psforever.objects.serverobject.damage import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.packet.game.PlanetsideAttributeMessage +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse /** * The "control" `Actor` mixin for damage-handling code @@ -27,7 +28,6 @@ object DamageableAmenity { * The common manifestation is a sparking entity that will no longer report being accessible. * These `PlanetSideAttributeMessage` attributes are the same as reported during zone load client configuration. * @see `PlanetsideAttribute` - * @see `AvatarServiceMessage` * @see `Zone.AvatarEvents` * @param target the entity being destroyed * @param cause historical information about the damage @@ -37,7 +37,9 @@ object DamageableAmenity { val zoneId = zone.id val events = zone.AvatarEvents val targetGUID = target.GUID - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 50, 1)) - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 51, 1)) + events ! MessageEnvelope( + zoneId, + SendResponse(List(PlanetsideAttributeMessage(targetGUID, 50, 1), PlanetsideAttributeMessage(targetGUID, 51, 1))) + ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala index b4dea9b97..9209e5764 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala @@ -8,7 +8,8 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations import net.psforever.objects.zones.Zone import net.psforever.types.PlanetSideGUID import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute /** @@ -143,7 +144,6 @@ object DamageableEntity { * - provide a feedback message regarding the damage. * @see `PlanetsideAttribute` * @see `SendResponse` - * @see `AvatarServiceMessage` * @see `DamageFeedbackMessage` * @see `JammableUnit.Jammered` * @see `Service.defaultPlayerGUID` @@ -166,7 +166,7 @@ object DamageableEntity { def DamageToHealth(target: Damageable.Target, cause: DamageResult, amount: Int): Boolean = { if (amount > 0 && !target.Destroyed) { val zone = target.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 0, target.Health) ) @@ -182,8 +182,7 @@ object DamageableEntity { * - reports its adjusted its health; and, * - report about its destruction. * @see `AvatarAction.Destroy` - * @see `AvatarAction.PlanetsideAttribute` - * @see `AvatarServiceMessage` + * @see `PlanetsideAttribute` * @see `DamageFeedbackMessage` * @see `JammableUnit.ClearJammeredSound` * @see `JammableUnit.ClearJammeredStatus` @@ -200,10 +199,10 @@ object DamageableEntity { val zoneId = zone.id val tguid = target.GUID val attribution = attributionTo(cause, target.Zone) - zone.AvatarEvents ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 0, target.Health)) + zone.AvatarEvents ! MessageEnvelope(zoneId, PlanetsideAttribute(tguid, 0, target.Health)) if (target.isInstanceOf[SpawnTube]) {}//do nothing to prevent issue #1057 else { - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zoneId, AvatarAction.Destroy(tguid, attribution, Service.defaultPlayerGUID, target.Position) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala index 6ae266790..99c076071 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala @@ -7,7 +7,8 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{HintsAtAttacker, SendResponse} /** @@ -20,7 +21,6 @@ object DamageableMountable { * * @see `HitHint` * @see `SendResponse` - * @see `AvatarServiceMessage` * @see `DamageWithPositionMessage` * @see `Mountable.Seats` * @see `Service.defaultPlayerGUID` @@ -62,7 +62,7 @@ object DamageableMountable { List.empty }).foreach { case (channel, filter, msg) => - events ! AvatarServiceMessage(channel, filter, msg) + events ! MessageEnvelope(channel, filter, msg) } } @@ -79,7 +79,7 @@ object DamageableMountable { val targets = target.Seats.values.flatMap(_.occupant).filter(_.isAlive) targets.foreach { player => //make llu visible to others in zone if passenger is carrying one - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem()) + player.Zone.AvatarEvents ! MessageEnvelope(player.Name, AvatarAction.DropSpecialItem()) //player.LogActivity(cause) player.Actor ! Player.Die( DamageInteraction(interaction.resolution, SourceEntry(player), interaction.cause, interaction.hitPos) diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index b948c0f80..ced4764d0 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -13,8 +13,8 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.Service +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.Vector3 import scala.concurrent.duration._ @@ -105,8 +105,7 @@ trait DamageableVehicle * If this vehicle has shields that were affected by previous damage, that is also reported to the clients. * @see `Service.defaultPlayerGUID` * @see `Vehicle.CargoHolds` - * @see `VehicleAction.PlanetsideAttribute` - * @see `VehicleServiceMessage` + * @see `PlanetsideAttribute` * @param target the entity being destroyed * @param cause historical information about the damage * @param amount how much damage was performed @@ -143,14 +142,14 @@ trait DamageableVehicle } //stat changes if (damageToShields > 0) { - events ! VehicleServiceMessage( + events ! MessageEnvelope( shieldChannel, PlanetsideAttribute(targetGUID, obj.Definition.shieldUiAttribute, obj.Shields) ) announceConfrontation = true } if (damageToHealth > 0) { - events ! VehicleServiceMessage( + events ! MessageEnvelope( healthChannel, PlanetsideAttribute(targetGUID, 0, obj.Health) ) @@ -163,7 +162,7 @@ trait DamageableVehicle obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } .foreach { channel => - events ! VehicleServiceMessage(channel, msg) + events ! MessageEnvelope(channel, msg) } } else { @@ -183,11 +182,9 @@ trait DamageableVehicle * @see `DriveState.Undeploying` * @see `Service.defaultPlayerGUID` * @see `Vehicle.CargoHolds` - * @see `VehicleAction.PlanetsideAttribute` + * @see `PlanetsideAttribute` * @see `RemoverActor.AddTask` * @see `RemoverActor.ClearSpecific` - * @see `VehicleServiceMessage` - * @see `VehicleServiceMessage.Decon` * @see `Zone.VehicleEvents` * @param target the entity being destroyed * @param cause historical information about the damage @@ -218,7 +215,7 @@ trait DamageableVehicle //shields if (obj.Shields > 0) { obj.Shields = 0 - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, obj.Definition.shieldUiAttribute, 0) ) @@ -251,13 +248,13 @@ trait DamageableVehicle //health to 1, shields to 0 obj.Health = 1 val guid = obj.GUID - events ! VehicleServiceMessage( + events ! MessageEnvelope( zoneid, PlanetsideAttribute(guid, 0, 1) ) if (obj.Shields > 0) { obj.Shields = 0 - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(obj.GUID, obj.Definition.shieldUiAttribute, 0) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index 1e172174f..70dcae811 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -9,11 +9,10 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types.Vector3 -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.base.support.SupportActor import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader} -import net.psforever.services.vehicle.VehicleServiceMessage /** * The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects. @@ -63,7 +62,7 @@ trait DamageableWeaponTurret //TODO some turrets have shields if (damageToHealth > 0) { DamageableMountable.DamageAwareness(DamageableObject, cause, damageToHealth) - events ! VehicleServiceMessage( + events ! MessageEnvelope( zoneId, PlanetsideAttribute(targetGUID, 0, obj.Health) ) @@ -76,7 +75,7 @@ trait DamageableWeaponTurret obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } .foreach { channel => - events ! VehicleServiceMessage(channel, msg) + events ! MessageEnvelope(channel, msg) } } else { @@ -104,8 +103,7 @@ object DamageableWeaponTurret { * A destroyed target dispatches a message to conceal (delete) its weapons from users. * If affected by a jammer property, the jammer propoerty will be removed. * If the type of entity is a `WeaponTurret`, the weapons are converted to their "normal" upgrade state. - * @see `AvatarAction.DeleteObject` - * @see `AvatarServiceMessage` + * @see `DeleteObject` * @see `MountedWeapons` * @see `MountedWeapons.Weapons` * @see `Service.defaultPlayerGUID` @@ -132,7 +130,7 @@ object DamageableWeaponTurret { } .foreach(slot => { val wep = slot.Equipment.get - avatarEvents ! AvatarServiceMessage(zoneId, ObjectDelete(wep.GUID)) + avatarEvents ! MessageEnvelope(zoneId, ObjectDelete(wep.GUID)) }) target match { case turret: WeaponTurret => diff --git a/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala index 49df2465a..be644a067 100644 --- a/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala @@ -5,7 +5,8 @@ import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Default import net.psforever.types.{DriveState, Vector3} import net.psforever.services.Service -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -104,7 +105,7 @@ trait DeploymentBehavior { prevState } else if (state == DriveState.Deploying) { obj.Velocity = Some(Vector3.Zero) //no velocity - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zoneChannel, VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) @@ -115,7 +116,7 @@ trait DeploymentBehavior { state } else if (state == DriveState.Deployed) { obj.Velocity = Some(Vector3.Zero) //no velocity - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zoneChannel, VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) @@ -136,7 +137,7 @@ trait DeploymentBehavior { val zoneChannel = zone.id val GUID0 = Service.defaultPlayerGUID if (state == DriveState.Undeploying) { - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zoneChannel, VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) @@ -147,7 +148,7 @@ trait DeploymentBehavior { }) state } else if (state == DriveState.Mobile) { - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zoneChannel, VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala index 42e561f2c..223354272 100644 --- a/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/generator/GeneratorControl.scala @@ -12,8 +12,8 @@ import net.psforever.objects.serverobject.terminals.{GeneratorTerminalDefinition import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.TriggerEffectMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{PlanetSideGeneratorState, Vector3} -import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.base.message.SendResponse import scala.concurrent.duration._ @@ -111,7 +111,7 @@ class GeneratorControl(gen: Generator) super.DestructionAwareness(gen, gen.LastDamage.get) GeneratorControl.UpdateOwner(gen, Some(GeneratorControl.Event.Destroyed)) //kaboom - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, SendResponse(TriggerEffectMessage(gen.GUID, "explosion_generator", None, None)) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index 50ac0796a..bc957d9c4 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -11,10 +11,10 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope, HackEntityEnvelope} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import scala.annotation.unused import scala.util.{Failure, Success} @@ -89,7 +89,7 @@ object GenericHackables { } else { (HackState.Ongoing, progress.toInt) } - target.Zone.AvatarEvents ! AvatarServiceMessage( + target.Zone.AvatarEvents ! MessageEnvelope( hacker.Name, SendResponse( HackMessage(progressType, target.GUID, hacker.GUID, progressGrade, 0L, progressState, HackState7.Unk8) @@ -171,7 +171,7 @@ object GenericHackables { val zoneId = zone.id val pguid = tplayer.GUID log.info(s"${user.Name} hacked a ${target.Definition.Name}") - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zoneId, pguid, LocalAction.TriggerSound(target.HackSound, tplayer.Position, 30, 0.49803925f) @@ -207,7 +207,7 @@ object GenericHackables { building.virusId = 8 building.virusInstalledBy = None zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(target)) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, SendResponse(GenericObjectActionMessage(target.GUID, 60)) ) @@ -261,7 +261,7 @@ object GenericHackables { val hackState = hackStateMap.getOrElse(virus, HackState7.Unk8) building.virusId = virus building.virusInstalledBy = Some(tplayer.Faction.id) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zoneId, pguid, LocalAction.TriggerSound(TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f) @@ -272,13 +272,9 @@ object GenericHackables { LocalAction.HackObject(target.GUID, installedVirusDuration.toLong, hackState), HackClearActor.ObjectIsHacked(target, zone, hackClearValue, hackState, installedVirusDuration) ) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, - SendResponse(GenericObjectActionMessage(target.GUID, 61)) - ) - zone.LocalEvents ! LocalServiceMessage( - zone.id, - SendResponse(GenericObjectActionMessage(target.GUID, 58)) + SendResponse(List(GenericObjectActionMessage(target.GUID, 61), GenericObjectActionMessage(target.GUID, 58))) ) //amenities if applicable virus match { diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala index 4eb50c1e1..21a78ed9b 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala @@ -11,7 +11,7 @@ import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.TerminalUsedActivity import net.psforever.objects.zones.{Zone, ZoneAware, Zoning} import net.psforever.objects.{Default, PlanetSideGameObject, Player, Vehicle} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{PlanetSideGUID, TransactionType, Vector3} import scala.annotation.tailrec @@ -129,7 +129,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) } trackedOrder = None handleOrderFunc = NewTasking - pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) //cautious animation reset + pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) //cautious animation reset self ! akka.actor.Kill //should cause the actor to restart, which will abort any trapped messages case _ => () @@ -165,7 +165,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) //first queued order orders = List(order) queueManagementTask() - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^2~^2~")) ) @@ -173,7 +173,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) //new order orders = orders :+ order val size = orders.size + 1 - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^$size~^$size~")) ) @@ -184,7 +184,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) val originalVehicle = originalOrder.vehicle.Definition.Name orders = (orders.take(n) :+ order) ++ orders.drop(n+1) VehicleSpawnControl.DisposeVehicle(originalOrder.vehicle, zone) - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_ReplacedVehicleWithVehicle^@$originalVehicle~^@${order.vehicle.Definition.Name}~")) ) @@ -243,7 +243,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) val newOrder = VehicleSpawnControl.Order(driver, vehicle) recursiveOrderReminder(orders.iterator, size) trace(s"processing next order - a ${vehicle.Definition.Name} for $name") - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^1~^$size~")) ) @@ -321,7 +321,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) private def CancelOrder(vehicle: Vehicle, player: Player, msg: Option[String]): Unit = { if (vehicle.Seats.values.count(_.isOccupied) == 0) { VehicleSpawnControl.DisposeSpawnedVehicle(vehicle, player, pad.Zone) - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( player.Name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Cancelled, msg) ) @@ -451,7 +451,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) entry: VehicleSpawnPad.VehicleOrder, cause: Option[Any] ): Unit = { - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( entry.player.Name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, cause) ) @@ -464,7 +464,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad) ): Unit = { if (iter.hasNext) { val recipient = iter.next() - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( recipient.player.Name, VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^$position~^$size~")) ) @@ -562,7 +562,7 @@ object VehicleSpawnControl { */ private def DisposeSpawnedVehicle(vehicle: Vehicle, player: Player, zone: Zone): Unit = { DisposeVehicle(vehicle, zone) - zone.VehicleEvents ! VehicleServiceMessage(zone.id, VehicleSpawnPad.RevealPlayer(player.GUID)) + zone.VehicleEvents ! MessageEnvelope(zone.id, VehicleSpawnPad.RevealPlayer(player.GUID)) } /** diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala index 3f3813584..dc8391395 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlConcealPlayer.scala @@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Props import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -29,7 +29,7 @@ class VehicleSpawnControlConcealPlayer(pad: VehicleSpawnPad) extends VehicleSpaw case order @ VehicleSpawnControl.Order(driver, vehicle) => if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty) { trace(s"hiding ${driver.Name}") - pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.ConcealPlayer(driver.GUID)) + pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.ConcealPlayer(driver.GUID)) context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order) } else { trace(s"integral component lost; abort order fulfillment") diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala index d43d36a43..8632a10f9 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlDriverControl.scala @@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Props import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope /** * An `Actor` that handles vehicle spawning orders for a `VehicleSpawnPad`. @@ -25,7 +25,7 @@ class VehicleSpawnControlDriverControl(pad: VehicleSpawnPad) extends VehicleSpaw case order @ VehicleSpawnControl.Order(driver, vehicle) => trace(s"returning control of ${vehicle.Definition.Name} to its current driver") if (vehicle.PassengerInSeat(driver).nonEmpty) { - pad.Zone.VehicleEvents ! VehicleServiceMessage(driver.Name, VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(driver.Name, VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, pad)) } finalClear ! order diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala index d8ab0a7c5..d67eff488 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlFinalClearance.scala @@ -4,8 +4,9 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Cancellable import net.psforever.objects.Default import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.Vector3 -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -35,7 +36,7 @@ class VehicleSpawnControlFinalClearance(pad: VehicleSpawnPad) extends VehicleSpa //ensure the vacant vehicle is above the trench and the doors vehicle.Position = pad.Position + Vector3.z(pad.Definition.VehicleCreationZOffset) val definition = vehicle.Definition - pad.Zone.VehicleEvents ! VehicleServiceMessage( + pad.Zone.VehicleEvents ! MessageEnvelope( s"${pad.Continent}", VehicleAction.LoadVehicle(vehicle, definition.ObjectId, vehicle.GUID, definition.Packet.ConstructorData(vehicle).get) ) @@ -64,7 +65,7 @@ class VehicleSpawnControlFinalClearance(pad: VehicleSpawnPad) extends VehicleSpa } case VehicleSpawnControlFinalClearance.NextOrder => - pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder case _ => () diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala index bf2a90b48..3460b4fd8 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlLoadVehicle.scala @@ -7,7 +7,8 @@ import akka.util.Timeout import net.psforever.objects.GlobalDefinitions import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} import net.psforever.objects.zones.Zone -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.Vector3 import net.psforever.zones.Zones @@ -67,7 +68,7 @@ class VehicleSpawnControlLoadVehicle(pad: VehicleSpawnPad) extends VehicleSpawnC val vtype = definition.ObjectId val vguid = v.GUID val vdata = definition.Packet.ConstructorData(v).get - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, VehicleAction.LoadVehicle(v, vtype, vguid, vdata) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala index f3142039b..4dda6e120 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlRailJack.scala @@ -11,7 +11,7 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.objects.vital.prop.DamageProperties import net.psforever.objects.vital.Vitality import net.psforever.objects.zones.Zone -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -41,7 +41,7 @@ class VehicleSpawnControlRailJack(pad: VehicleSpawnPad) extends VehicleSpawnCont pad.Definition.killBox(pad, vehicle.Definition.CanFly), Zone.findAllTargets ) - pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.AttachToRails(vehicle, pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.AttachToRails(vehicle, pad)) context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, order) case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) => diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala index 92ca1f010..6c7218b17 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlSeatDriver.scala @@ -4,7 +4,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.{ActorRef, Props} import net.psforever.objects.{Default, Vehicle} import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -47,7 +47,7 @@ class VehicleSpawnControlSeatDriver(pad: VehicleSpawnPad) extends VehicleSpawnCo vehicle.Actor ! Vehicle.Deconstruct(Some(pad.Definition.VehicleCreationDeconstructTime.seconds)) if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty) { trace("driver to be made seated in vehicle") - pad.Zone.VehicleEvents ! VehicleServiceMessage(driver.Name, VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(driver.Name, VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, pad)) } else { trace("driver lost; vehicle stranded on pad") } @@ -59,7 +59,7 @@ class VehicleSpawnControlSeatDriver(pad: VehicleSpawnPad) extends VehicleSpawnCo if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty && entry.vehicle.PassengerInSeat(entry.driver).contains(0)) { trace(s"driver ${entry.driver.Name} has taken the wheel") - pad.Zone.VehicleEvents ! VehicleServiceMessage(entry.driver.Name, VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle, pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(entry.driver.Name, VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle, pad)) } else { trace("driver lost, but operations can continue") } diff --git a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala index 0dabf4807..496d06938 100644 --- a/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala +++ b/src/main/scala/net/psforever/objects/serverobject/pad/process/VehicleSpawnControlServerVehicleOverride.scala @@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.pad.process import akka.actor.Props import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.Vector3 import scala.concurrent.ExecutionContext.Implicits.global @@ -32,18 +32,18 @@ class VehicleSpawnControlServerVehicleOverride(pad: VehicleSpawnPad) extends Veh val driverFailState = !driver.isAlive || driver.Continent != pad.Continent || !vehicle.PassengerInSeat(driver).contains(0) vehicle.MountedIn = None - pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.DetachFromRails(vehicle, pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.DetachFromRails(vehicle, pad)) if (vehicleFailState || driverFailState) { if (vehicleFailState) { trace(s"vehicle was already destroyed") } else { trace(s"driver is not ready") } - pad.Zone.VehicleEvents ! VehicleServiceMessage(pad.Zone.id, VehicleSpawnPad.RevealPlayer(order.DriverGUID)) + pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.RevealPlayer(order.DriverGUID)) driverControl ! order } else { trace(s"telling ${driver.Name} that the server is assuming control of the ${vehicle.Definition.Name}") - pad.Zone.VehicleEvents ! VehicleServiceMessage(driver.Name, VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad)) + pad.Zone.VehicleEvents ! MessageEnvelope(driver.Name, VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad)) context.system.scheduler.scheduleOnce(4000 milliseconds, driverControl, order) } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala index 0a09a5251..14fde4811 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala @@ -5,8 +5,9 @@ import net.psforever.objects.Tool import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.sourcing.{SourceEntry, SourceWithHealthEntry} import net.psforever.objects.vital.{DamagingActivity, RepairFromEquipment, SpawningActivity} -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.packet.game.PlanetsideAttributeMessage +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse /** * The "control" `Actor` mixin for repair-handling code @@ -29,7 +30,6 @@ object RepairableAmenity { * A restored `Amenity` target dispatches two messages to chance its model and operational states. * These `PlanetSideAttributeMessage` attributes are the same as reported during zone load client configuration. * @see `PlanetsideAttribute` - * @see `AvatarServiceMessage` * @see `Zone.AvatarEvents` * @param target the entity being destroyed */ @@ -38,8 +38,10 @@ object RepairableAmenity { val zoneId = zone.id val events = zone.AvatarEvents val targetGUID = target.GUID - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 50, 0)) - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(targetGUID, 51, 0)) + events ! MessageEnvelope( + zoneId, + SendResponse(List(PlanetsideAttributeMessage(targetGUID, 50, 0), PlanetsideAttributeMessage(targetGUID, 51, 0))) + ) RestorationOfHistory(target) } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index 07b4fe238..a9f436a63 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -8,7 +8,7 @@ import net.psforever.objects.vital.RepairFromEquipment import net.psforever.objects.{Player, Tool} import net.psforever.packet.game.{ChatMsg, InventoryStateMessage, RepairMessage} import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} /** @@ -89,7 +89,7 @@ trait RepairableEntity extends Repairable { if (!(player.isMoving(test = 1f) || target.isMoving(test = 1f))) { //only allow stationary repairs within margin of error val repairValue = Repairable.applyLevelModifier(player, item, RepairToolValue(item)).toInt + target.Definition.RepairMod val magazine = item.Discharge() - events ! AvatarServiceMessage( + events ! MessageEnvelope( player.Name, SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)) ) @@ -105,7 +105,7 @@ trait RepairableEntity extends Repairable { originalHealth } //progress bar remains visible - events ! AvatarServiceMessage( + events ! MessageEnvelope( name, SendResponse(RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth)) ) @@ -140,11 +140,11 @@ trait RepairableEntity extends Repairable { val newHealth = target.Health = target.Health + amount if (target.Destroyed) { if (newHealth >= target.Definition.RepairRestoresAt) { - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 0, newHealth)) + events ! MessageEnvelope(zoneId, PlanetsideAttribute(tguid, 0, newHealth)) Restoration(target) } } else { - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 0, newHealth)) + events ! MessageEnvelope(zoneId, PlanetsideAttribute(tguid, 0, newHealth)) } newHealth } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala index 64e4b5ced..b712fb957 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala @@ -5,7 +5,8 @@ import net.psforever.objects.Tool import net.psforever.objects.equipment.EquipmentSlot import net.psforever.objects.serverobject.turret.WeaponTurret import net.psforever.objects.vehicles.MountedWeapons -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.vehicle.VehicleAction /** * The "control" `Actor` mixin for repair-handling code for `WeaponTurret` objects. @@ -29,8 +30,7 @@ object RepairableWeaponTurret { * @see `MountedWeapons.Weapons` * @see `Service.defaultPlayerGUID` * @see `WeaponTurret` - * @see `VehicleAction.EquipmentInSlot` - * @see `VehicleServiceMessage` + * @see `EquipmentInSlot` * @see `Zone.VehicleEvents` * @param target the entity being destroyed; * note: `MountedWeapons` is a parent of `WeaponTurret` @@ -45,7 +45,7 @@ object RepairableWeaponTurret { .map({ case (index, slot: EquipmentSlot) => (index, slot.Equipment) }) .collect { case (index: Int, Some(tool: Tool)) => - events ! VehicleServiceMessage( + events ! MessageEnvelope( zoneId, VehicleAction.EquipmentInSlot(tguid, index, tool) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index c9a2104ff..5b8f7d5b2 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -11,9 +11,9 @@ import net.psforever.objects.zones import net.psforever.objects.{GlobalDefinitions, Ntu, NtuContainer, NtuStorageBehavior, Vehicle} import net.psforever.types.{ExperienceType, PlanetSideEmpire} import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.util.Config import scala.concurrent.ExecutionContext.Implicits.global @@ -107,7 +107,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) log.trace(s"LowNtuWarning: Silo ${resourceSilo.GUID} low ntu warning set to $enabled") val building = resourceSilo.Owner val zone = building.Zone - building.Zone.AvatarEvents ! AvatarServiceMessage( + building.Zone.AvatarEvents ! MessageEnvelope( zone.id, building.GUID, PlanetsideAttribute(building.GUID, 47, if (resourceSilo.LowNtuWarningOn) 1 else 0) @@ -131,7 +131,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) log.trace( s"UpdateChargeLevel: silo ${resourceSilo.GUID} NTU bar level has changed from $siloDisplayBeforeChange to ${resourceSilo.CapacitorDisplay}" ) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, resourceSilo.GUID, PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay) @@ -205,11 +205,11 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) (Config.app.game.experience.sep.ntuSiloDepositReward.toFloat * amount * resourceSilo.Definition.ChargeTime.toSeconds.toFloat / resourceSilo.MaxNtuCapacitor ).toLong - vehicle.Zone.AvatarEvents ! AvatarServiceMessage( + vehicle.Zone.AvatarEvents ! MessageEnvelope( owner.name, AvatarAction.AwardBep(owner.charId, deposit, ExperienceType.Normal) ) - vehicle.Zone.AvatarEvents ! AvatarServiceMessage( + vehicle.Zone.AvatarEvents ! MessageEnvelope( owner.name, AvatarAction.ShareAntExperienceWithSquad(owner, deposit, vehicle)) zones.exp.ToDatabase.reportNtuActivity(owner.charId, resourceSilo.Zone.Number, resourceSilo.Owner.GUID.guid, deposit) } @@ -232,7 +232,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val amount = (if (trigger > 0) { // panel glow & orb particles on val zone = resourceSilo.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(resourceSilo.GUID, 49, 1) ) @@ -243,7 +243,7 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) } else { // panel glow & orb particles off val zone = resourceSilo.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(resourceSilo.GUID, 49, 0) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala index 2d9cc5e29..380d7b95c 100644 --- a/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/shuttle/OrbitalShuttlePadControl.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.base.support.SupportActor import net.psforever.services.local.LocalAction @@ -184,7 +184,6 @@ object OrbitalShuttlePadControl { * A message flashes onscreen to explain this reason. * The message will not flash if the door has no expectation of ever opening for a user. * @see `SendResponse` - * @see `AvatarServiceMessage` * @see `ChatMessageType` * @see `ChatMsg` * @see `Player` @@ -198,7 +197,7 @@ object OrbitalShuttlePadControl { val zone = door.Zone obj match { case p: Player if p.Faction == door.Faction => - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( p.Name, SendResponse( ChatMsg(ChatMessageType.UNK_225, wideContents=false, "", "@DoorWillOpenWhenShuttleReturns", None) diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index 0a6be53e7..27500e6ec 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -4,7 +4,9 @@ package net.psforever.objects.serverobject.structures.participation import net.psforever.objects.Player import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.UniquePlayer -import net.psforever.services.base.message.GenericObjectAction +import net.psforever.packet.game.GenericObjectActionMessage +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse import net.psforever.types.{PlanetSideEmpire, Vector3} import scala.collection.mutable @@ -107,14 +109,14 @@ trait FacilityHackParticipation extends ParticipationLogic { if (building.virusId != 8) { import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.objects.GlobalDefinitions - import net.psforever.services.avatar.AvatarServiceMessage val mainTerm = building.Amenities.filter(x => x.isInstanceOf[Terminal] && x.Definition == GlobalDefinitions.main_terminal).head.GUID - val msg1 = GenericObjectAction(mainTerm, 61) - val msg2 = GenericObjectAction(mainTerm, 58) + val pkts = SendResponse(List( + GenericObjectActionMessage(mainTerm, 61), + GenericObjectActionMessage(mainTerm, 58) + )) val events = building.Zone.AvatarEvents list.foreach { p => - events ! AvatarServiceMessage(p.Name, msg1) - events ! AvatarServiceMessage(p.Name, msg2) + events ! MessageEnvelope(p.Name, pkts) } } } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala index 73f1df132..47724f48c 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala @@ -4,7 +4,7 @@ package net.psforever.objects.serverobject.structures.participation import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.sourcing.{PlayerSource, UniquePlayer} import net.psforever.objects.zones.{HotSpotInfo, ZoneHotSpotProjector} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3} import net.psforever.util.Config import akka.pattern.ask @@ -15,8 +15,8 @@ import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.ChatMsg +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.LocalServiceMessage import scala.collection.mutable import scala.concurrent.duration._ @@ -304,7 +304,7 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci finalCep, expType = "cep" ) - events ! AvatarServiceMessage(hacker.Name, AvatarAction.AwardCep(hackerId, finalCep)) + events ! MessageEnvelope(hacker.Name, AvatarAction.AwardCep(hackerId, finalCep)) }*/ //bystanders (cep if squad leader, bep otherwise) contributingPlayers @@ -313,7 +313,7 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci val charId = player.CharId val contributionMultiplier = contributionPerPlayerByTime.getOrElse(charId, 1f) val outputValue = (finalCep * contributionMultiplier).toLong - events ! AvatarServiceMessage(player.Name, AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, outputValue)) + events ! MessageEnvelope(player.Name, AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, outputValue)) } //flag carrier (won't be in soi, but earns cep from capture) flagCarrier.collect { @@ -338,7 +338,7 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci finalModifiedCep, expType = "llu" ) - events ! AvatarServiceMessage(player.Name, AvatarAction.AwardCep(charId, finalModifiedCep)) + events ! MessageEnvelope(player.Name, AvatarAction.AwardCep(charId, finalModifiedCep)) } } else { //no need to calculate a fancy score @@ -441,7 +441,7 @@ object MajorFacilityHackParticipation { val events = building.Zone.LocalEvents val message = SendResponse(msg) targets.foreach { player => - events ! LocalServiceMessage(player.Name, message) + events ! MessageEnvelope(player.Name, message) } } } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala index 505c401ae..7c65c07bd 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala @@ -4,7 +4,8 @@ package net.psforever.objects.serverobject.structures.participation import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.zones.exp.ToDatabase -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.util.Config @@ -144,7 +145,7 @@ final case class TowerHackParticipation(building: Building) extends FacilityHack //7. reward participants //Classically, only players in the SOI are rewarded //terminal hacker (always cep) - events ! AvatarServiceMessage(hacker.Name, AvatarAction.AwardCep(hacker.CharId, finalCep)) + events ! MessageEnvelope(hacker.Name, AvatarAction.AwardCep(hacker.CharId, finalCep)) ToDatabase.reportFacilityCapture( hackerId, zoneNumber, @@ -160,7 +161,7 @@ final case class TowerHackParticipation(building: Building) extends FacilityHack val contributionTimeMultiplier = contributionPerPlayerByTime.getOrElse(charId, 0.5f) val contributionDistanceMultiplier = contributionPerPlayerByDistanceFromGoal.getOrElse(charId, 0.5f) val outputValue = (finalCep * contributionTimeMultiplier * contributionDistanceMultiplier).toLong - events ! AvatarServiceMessage( + events ! MessageEnvelope( player.Name, AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, outputValue) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index f1b95da07..a68ca6548 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -6,6 +6,7 @@ import net.psforever.objects.serverobject.damage.Damageable import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import org.log4s.Logger @@ -26,9 +27,7 @@ import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityCo import net.psforever.objects.vital.{HealFromTerminal, RepairFromTerminal, Vitality} import net.psforever.objects.zones.ZoneAware import net.psforever.packet.game.InventoryStateMessage -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.local.LocalAction /** * An `Actor` that handles messages being dispatched to a specific `ProximityTerminal`. @@ -183,7 +182,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) ProximityTerminalControl.TerminalAction() ) val zone = TerminalObject.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = true)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = true)) } } else { log.warn(s"ProximityTerminal.Use: $target was rejected by unit ${term.Definition.Name}@${term.GUID.guid}") @@ -204,7 +203,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) if (term.NumberUsers == 0 && hadUsers) { terminalAction.cancel() val zone = TerminalObject.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = false)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = false)) } } else { log.debug( @@ -220,7 +219,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) if (callbacks.nonEmpty) { callbacks.clear() val zone = TerminalObject.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = true)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.ProximityTerminalEffect(TerminalObject.GUID, effectState = true)) } //clear hack state if (term.HackedBy.nonEmpty) { @@ -351,7 +350,7 @@ object ProximityTerminalControl { if (oldMax < maxHealthCap) { target.MaxHealth = newMax - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 1, newMax) ) @@ -366,7 +365,7 @@ object ProximityTerminalControl { def PlayerHealthCallback(target: PlanetSideGameObject with Vitality with ZoneAware): Unit = { val zone = target.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 0, target.Health) ) @@ -374,7 +373,7 @@ object ProximityTerminalControl { def VehicleHealthCallback(target: PlanetSideGameObject with Vitality with ZoneAware): Unit = { val zone = target.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 0, target.Health) ) @@ -405,7 +404,7 @@ object ProximityTerminalControl { target.Armor = armor + finalRepairAmount target.LogActivity(RepairFromTerminal(AmenitySource(terminal), finalRepairAmount)) val zone = target.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(target.GUID, 4, target.Armor) ) @@ -434,7 +433,7 @@ object ProximityTerminalControl { val channel = target.Name ancient.foreach { case (weapon, slots) => slots.foreach { slot => - events ! AvatarServiceMessage( + events ! MessageEnvelope( channel, SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) @@ -460,7 +459,7 @@ object ProximityTerminalControl { val channel = target.Actor.toString result.foreach { case (weapon, slots) => slots.foreach { slot => - events ! VehicleServiceMessage( + events ! MessageEnvelope( channel, SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala index 2fcb492d5..d8cbe03f9 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala @@ -6,10 +6,11 @@ import net.psforever.objects.serverobject.hackable.GenericHackables import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.services.local.support.HackCaptureActor import net.psforever.services.local.support.CaptureEnvelope import net.psforever.types.PlanetSideEmpire +import net.psforever.services.base.envelope.MessageEnvelope import scala.concurrent.duration._ import scala.util.{Failure, Success} @@ -41,7 +42,7 @@ object CaptureTerminals { val zoneid = zone.id val events = zone.LocalEvents val isResecured = hackingPlayer.Faction == target.Faction - events ! LocalServiceMessage( + events ! MessageEnvelope( zoneid, hackingPlayer.GUID, LocalAction.TriggerSound(target.HackSound, hackingPlayer.Position, 30, 0.49803925f) diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala index 5417d1d8b..fe4096b29 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala @@ -16,9 +16,9 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.objects.{GlobalDefinitions, Player, SimpleItem} import net.psforever.packet.game.HackState1 +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SetEmpire -import net.psforever.services.local.LocalServiceMessage -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} import scala.annotation.unused @@ -150,7 +150,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) case player => seat.unmount(player) player.VehicleSeated = None - events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) + events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) } ) } @@ -174,7 +174,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) if (player.Faction == localFaction) { if (mech.Owner.asInstanceOf[Building].CaptureTerminalIsHacked) { //this is actually futile, as a hacked base does not grant access to the terminal - events ! LocalServiceMessage(localFaction.toString, SetEmpire(guid, localFaction)) + events ! MessageEnvelope(localFaction.toString, SetEmpire(guid, localFaction)) } kickAllOccupantsNotOfFaction(zone, guid, mech, localFaction) } else { @@ -226,7 +226,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) ): Unit = { val events = zone.LocalEvents opposingFactionsAre(setToFaction).foreach { faction => - events ! LocalServiceMessage(faction.toString, SetEmpire(guid, faction)) + events ! MessageEnvelope(faction.toString, SetEmpire(guid, faction)) } } @@ -237,7 +237,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) ): Unit = { val events = zone.LocalEvents opposingFactionsAre(setToFaction).foreach { faction => - events ! LocalServiceMessage(faction.toString, SetEmpire(guid, setToFaction)) + events ! MessageEnvelope(faction.toString, SetEmpire(guid, setToFaction)) } } @@ -278,7 +278,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) case player if test(player.Faction) => seat.unmount(player) player.VehicleSeated = None - events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, guid)) + events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, guid)) } ) } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index f7541edf9..54425f7e6 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -13,9 +13,10 @@ import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.{ChangeFireModeMessage, HackState1} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.support.TurretUpgrader -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{BailType, PlanetSideEmpire, PlanetSideGUID} /** @@ -179,7 +180,7 @@ class FacilityTurretControl(turret: FacilityTurret) seat.unmount(player) player.VehicleSeated = None if (player.HasGUID) { - events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) + events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) } case None => () } @@ -237,7 +238,7 @@ class FacilityTurretControl(turret: FacilityTurret) .flatMap(_.Equipment) .collect { case weapon: Tool if weapon.FireModeIndex > 0 => weapon.FireModeIndex = 0 - events ! VehicleServiceMessage( + events ! MessageEnvelope( zoneid, SendResponse(ChangeFireModeMessage(weapon.GUID, 0)) ) @@ -341,7 +342,7 @@ class FacilityTurretControl(turret: FacilityTurret) case player => seat.unmount(player) player.VehicleSeated = None - events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, guid)) + events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, guid)) } } captureTerminalChanges(terminal, super.captureTerminalIsHacked, actionDelays = 3000L) diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala index d1ec9dbe4..bd43ed550 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala @@ -8,8 +8,9 @@ import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior import net.psforever.objects.serverobject.damage.{Damageable, DamageableWeaponTurret} import net.psforever.objects.serverobject.repair.RepairableWeaponTurret import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.packet.game.PlanetsideAttributeMessage +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse trait TurretControl extends Actor @@ -40,8 +41,10 @@ trait TurretControl val zoneId = zone.id val events = zone.AvatarEvents val tguid = TurretObject.GUID - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 50, 0)) - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 51, 0)) + events ! MessageEnvelope( + zoneId, + SendResponse(List(PlanetsideAttributeMessage(tguid, 50, 0), PlanetsideAttributeMessage(tguid, 51, 0))) + ) } /** @@ -57,7 +60,9 @@ trait TurretControl val tguid = target.GUID CancelJammeredSound(target) CancelJammeredStatus(target) - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 50, 1)) - events ! AvatarServiceMessage(zoneId, PlanetsideAttribute(tguid, 51, 1)) + events ! MessageEnvelope( + zoneId, + SendResponse(List(PlanetsideAttributeMessage(tguid, 50, 1), PlanetsideAttributeMessage(tguid, 51, 1))) + ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala index ed408438e..89c661277 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala @@ -4,7 +4,8 @@ package net.psforever.objects.serverobject.turret import akka.actor.Cancellable import net.psforever.objects.serverobject.ServerObjectControl import net.psforever.objects.{Default, Player, Tool} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.local.LocalAction import net.psforever.types.Vector3 import scala.concurrent.ExecutionContext.Implicits.global @@ -51,7 +52,7 @@ class VanuSentryControl(turret: FacilityTurret) val seat = TurretObject.Seat(0).get seat.occupant.collect { case player: Player => - TurretObject.Zone.LocalEvents ! LocalServiceMessage( + TurretObject.Zone.LocalEvents ! MessageEnvelope( TurretObject.Zone.id, player.GUID, LocalAction.RechargeVehicleWeapon(TurretObject.GUID, weapon.GUID) diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index c0aedc2e1..a42ab78f2 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -5,11 +5,11 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.ce.Deployable import net.psforever.objects.{Player, Tool, TurretDeployable} import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{SendResponse, SetEmpire} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.PlanetSideGUID object WeaponTurrets { @@ -31,7 +31,7 @@ object WeaponTurrets { upgrade: TurretUpgrade.Value )(): Unit = { tool.Magazine = 0 - target.Zone.AvatarEvents ! AvatarServiceMessage( + target.Zone.AvatarEvents ! MessageEnvelope( user.Name, SendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0)) ) @@ -85,7 +85,7 @@ object WeaponTurrets { turret.UpdateTurretUpgradeTime() (HackState.Ongoing, progress.toInt) } - turret.Zone.AvatarEvents ! AvatarServiceMessage( + turret.Zone.AvatarEvents ! MessageEnvelope( tplayer.Name, SendResponse( HackMessage(progressType, turret.GUID, tplayer.GUID, progressGrade, -1f, progressState, HackState7.Unk8) @@ -105,7 +105,7 @@ object WeaponTurrets { player: Player => seat.unmount(player) player.VehicleSeated = None - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, target.GUID) @@ -116,11 +116,11 @@ object WeaponTurrets { target.OwnerGuid = None target.Actor ! Deployable.Ownership(hacker) //convert faction - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, SetEmpire(target.GUID, hacker.Faction) ) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, hacker.GUID, LocalAction.TriggerSound(target.HackSound, target.Position, 30, 0.49803925f) diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala index 08e5fcabd..53221f7b8 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala @@ -18,8 +18,8 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.objects.{Default, PlanetSideGameObject, Player} import net.psforever.packet.game.{ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ObjectDetectedMessage} import net.psforever.services.Service +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.LocalServiceMessage import net.psforever.types.{PlanetSideGUID, Vector3} import scala.concurrent.ExecutionContext.Implicits.global @@ -890,7 +890,7 @@ object AutomatedTurretBehavior { * @param list target's globally unique identifier, in list form */ def startTracking(zone: Zone, channel: String, turretGuid: PlanetSideGUID, list: List[PlanetSideGUID]): Unit = { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( channel, SendResponse(ObjectDetectedMessage(turretGuid, turretGuid, 0, list)) ) @@ -903,7 +903,7 @@ object AutomatedTurretBehavior { * @param turretGuid turret */ def stopTracking(zone: Zone, channel: String, turretGuid: PlanetSideGUID): Unit = { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( channel, SendResponse(ObjectDetectedMessage(turretGuid, turretGuid, 0, noTargets)) ) @@ -916,7 +916,7 @@ object AutomatedTurretBehavior { * @param weaponGuid turret's weapon */ def startShooting(zone: Zone, channel: String, weaponGuid: PlanetSideGUID): Unit = { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( channel, SendResponse(ChangeFireStateMessage_Start(weaponGuid)) ) @@ -929,7 +929,7 @@ object AutomatedTurretBehavior { * @param weaponGuid turret's weapon */ def stopShooting(zone: Zone, channel: String, weaponGuid: PlanetSideGUID): Unit = { - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( channel, SendResponse(ChangeFireStateMessage_Stop(weaponGuid)) ) diff --git a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala index fb78e30aa..353f7f062 100644 --- a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala @@ -10,10 +10,11 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} import net.psforever.objects._ import net.psforever.types.DriveState -import net.psforever.services.vehicle.VehicleServiceMessage import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.serverobject.transfer.TransferContainer.TransferMaterial -import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.packet.game.PlanetsideAttributeMessage +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -33,7 +34,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { def ActivatePanelsForChargingEvent(vehicle: NtuContainer): Unit = { val obj = ChargeTransferObject val zone = obj.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(vehicle.GUID, 52, 1L) ) // panel glow on @@ -43,7 +44,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { def StartNtuChargingEvent(vehicle: NtuContainer): Unit = { val obj = ChargeTransferObject val zone = obj.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(vehicle.GUID, 49, 1L) ) // orb particle effect on @@ -52,7 +53,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { def UpdateNtuUI(vehicle: Vehicle with NtuContainer): Unit = { if (vehicle.Seats.values.exists(_.isOccupied)) { val display = vehicle.NtuCapacitorScaled.toLong - vehicle.Zone.VehicleEvents ! VehicleServiceMessage( + vehicle.Zone.VehicleEvents ! MessageEnvelope( vehicle.Actor.toString, PlanetsideAttribute(vehicle.GUID, 45, display) ) @@ -158,16 +159,14 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { val zoneId = zone.id val events = zone.VehicleEvents if (transferEvent == TransferBehavior.Event.Charging) { - events ! VehicleServiceMessage( + //1. panel glow off + //2. orb particle effect off + events ! MessageEnvelope( zoneId, - PlanetsideAttribute(vguid, 52, 0L) - ) // panel glow off - events ! VehicleServiceMessage( - zoneId, - PlanetsideAttribute(vguid, 49, 0L) - ) // orb particle effect off + SendResponse(List(PlanetsideAttributeMessage(vguid, 52, 0L), PlanetsideAttributeMessage(vguid, 49, 0L))) + ) } else if (transferEvent == TransferBehavior.Event.Discharging) { - events ! VehicleServiceMessage( + events ! MessageEnvelope( zoneId, PlanetsideAttribute(vguid, 52, 0L) ) // panel glow off diff --git a/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala index 96bd4ed86..3a4ef01dd 100644 --- a/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala @@ -11,8 +11,9 @@ import net.psforever.objects.equipment.EquipmentSlot import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -116,7 +117,7 @@ trait BfrTransferBehavior def UpdateNtuUI(vehicle: Vehicle with NtuContainer, siphon: NtuContainer): Unit = { siphon match { case equip: NtuSiphon => - vehicle.Zone.VehicleEvents ! VehicleServiceMessage( + vehicle.Zone.VehicleEvents ! MessageEnvelope( vehicle.Actor.toString, VehicleAction.InventoryState2(equip.storageGUID, siphon.GUID, siphon.NtuCapacitor.toInt) ) diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala index 10da95dc9..84c96de5f 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala @@ -9,10 +9,10 @@ import net.psforever.objects.sourcing.VehicleSource import net.psforever.objects.vital.VehicleCargoMountActivity import net.psforever.packet.game.{CargoMountPointStatusMessage, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} import net.psforever.types.{BailType, CargoStatus, PlanetSideGUID, Vector3} -import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.services.Service +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.duration._ @@ -59,7 +59,7 @@ trait CarrierBehavior { ) { if (iteration == 0) { //open the cargo bay door - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( obj.Zone.id, SendResponse( CargoMountPointStatusMessage( @@ -206,7 +206,7 @@ object CarrierBehavior { log.debug(s"HandleCheckCargoMounting: mounting cargo vehicle in carrier at distance of $distance") CargoMountAction(carrier, cargo, hold, carrierGUID) cargo.Velocity = None - zone.VehicleEvents ! VehicleServiceMessage(s"${cargo.Actor}", SendResponse(Seq( + zone.VehicleEvents ! MessageEnvelope(s"${cargo.Actor}", SendResponse(Seq( PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health), PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields) ))) @@ -220,7 +220,7 @@ object CarrierBehavior { ) cargo.Actor ! CargoBehavior.EndCargoMounting(carrierGUID) val cargoDriverGUID = cargo.Seats(0).occupant.get.GUID - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, cargoDriverGUID, SendResponse(CargoMountPointStatusMessage( @@ -320,7 +320,7 @@ object CarrierBehavior { ) cargo.Actor ! CargoBehavior.EndCargoDismounting(carrierGUID) val cargoDriverGUID = cargo.Seats(0).occupant.get.GUID - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, cargoDriverGUID, SendResponse(CargoMountPointStatusMessage( @@ -444,7 +444,7 @@ object CarrierBehavior { val zoneId = zone.id val events = zone.VehicleEvents val cargoActor = cargo.Actor - events ! VehicleServiceMessage(s"$cargoActor", SendResponse(Seq( + events ! MessageEnvelope(s"$cargoActor", SendResponse(Seq( PlanetsideAttributeMessage(cargoGUID, 0, cargo.Health), PlanetsideAttributeMessage(cargoGUID, cargo.Definition.shieldUiAttribute, cargo.Shields) ))) @@ -456,7 +456,7 @@ object CarrierBehavior { val detachCargoMsg = ObjectDetachMessage(carrierGUID, cargoGUID, cargoHoldPosition - Vector3.z(1), rotation) val resetCargoMsg = CargoMountPointStatusMessage(carrierGUID, GUID0, GUID0, cargoGUID, mountPoint, CargoStatus.Empty, 0) - events ! VehicleServiceMessage(zoneId, SendResponse(Seq(ejectCargoMsg, detachCargoMsg, resetCargoMsg))) + events ! MessageEnvelope(zoneId, SendResponse(Seq(ejectCargoMsg, detachCargoMsg, resetCargoMsg))) log.debug(s"HandleVehicleCargoDismount: eject - $ejectCargoMsg, detach - $detachCargoMsg") if (driverOpt.isEmpty) { //TODO cargo should drop like a rock like normal; until then, deconstruct it @@ -469,17 +469,17 @@ object CarrierBehavior { CargoMountPointStatusMessage(carrierGUID, GUID0, cargoGUID, GUID0, mountPoint, CargoStatus.InProgress, 0) val cargoDetachMessage = ObjectDetachMessage(carrierGUID, cargoGUID, cargoHoldPosition + Vector3.z(1f), rotation) - events ! VehicleServiceMessage(zoneId, SendResponse(Seq(cargoStatusMessage, cargoDetachMessage))) + events ! MessageEnvelope(zoneId, SendResponse(Seq(cargoStatusMessage, cargoDetachMessage))) driverOpt match { case Some(driver) => - events ! VehicleServiceMessage( + events ! MessageEnvelope( s"${driver.Name}", VehicleAction.KickCargo(cargo, cargo.Definition.AutoPilotSpeed2, 2500) ) case None => val resetCargoMsg = CargoMountPointStatusMessage(carrierGUID, GUID0, GUID0, cargoGUID, mountPoint, CargoStatus.Empty, 0) - events ! VehicleServiceMessage(zoneId, SendResponse(resetCargoMsg)) //lazy + events ! MessageEnvelope(zoneId, SendResponse(resetCargoMsg)) //lazy //TODO cargo should back out like normal; until then, deconstruct it cargoActor ! Vehicle.Deconstruct() } @@ -595,7 +595,7 @@ object CarrierBehavior { attachMessage: ObjectAttachMessage, mountPointStatusMessage: CargoMountPointStatusMessage ): Unit = { - zone.VehicleEvents ! VehicleServiceMessage(zone.id, exclude, SendResponse(Seq(attachMessage, mountPointStatusMessage))) + zone.VehicleEvents ! MessageEnvelope(zone.id, exclude, SendResponse(Seq(attachMessage, mountPointStatusMessage))) } /** @@ -615,10 +615,7 @@ object CarrierBehavior { val zone = carrier.Zone val zoneId = zone.id val msgs @ (attachMessage, mountPointStatusMessage) = CargoMountMessages(carrier, cargo, mountPoint) - zone.VehicleEvents ! VehicleServiceMessage(zoneId, SendResponse(Seq( - attachMessage, - mountPointStatusMessage - ))) + zone.VehicleEvents ! MessageEnvelope(zoneId, SendResponse(Seq(attachMessage, mountPointStatusMessage))) msgs } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala index 5a24daec4..f30cddc14 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/AmsControl.scala @@ -2,8 +2,9 @@ package net.psforever.objects.vehicles.control import net.psforever.objects._ +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types.DriveState /** @@ -29,8 +30,8 @@ class AmsControl(vehicle: Vehicle) case None => "" } val events = zone.VehicleEvents - events ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) - events ! VehicleServiceMessage(driverChannel, PlanetsideAttribute(vehicle.GUID, 81, 1)) + events ! MessageEnvelope(zone.id, VehicleAction.AMSDeploymentChange(zone)) + events ! MessageEnvelope(driverChannel, PlanetsideAttribute(vehicle.GUID, 81, 1)) case _ => ; } } @@ -49,8 +50,8 @@ class AmsControl(vehicle: Vehicle) case None => "" } val events = zone.VehicleEvents - events ! VehicleServiceMessage(zone.id, VehicleAction.AMSDeploymentChange(zone)) - events ! VehicleServiceMessage(driverChannel, PlanetsideAttribute(vehicle.GUID, 81, 0)) + events ! MessageEnvelope(zone.id, VehicleAction.AMSDeploymentChange(zone)) + events ! MessageEnvelope(driverChannel, PlanetsideAttribute(vehicle.GUID, 81, 0)) case _ => ; } } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala index 3ec15a33c..1650d6657 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala @@ -11,8 +11,8 @@ import net.psforever.objects.vital.prop.DamageWithPosition import net.psforever.objects.zones.Zone import net.psforever.packet.game.{TriggerEffectMessage, TriggeredEffectLocation} import net.psforever.services.Service +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.PlanetSideGUID /** @@ -53,7 +53,7 @@ class ApcControl(vehicle: Vehicle) //drain the capacitor capacitorCharge(-vehicle.Capacitor) //cause the emp - events ! VehicleServiceMessage( + events ! MessageEnvelope( zone.id, SendResponse(TriggerEffectMessage( GUID0, diff --git a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala index 1edfdadbe..ff73708ab 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala @@ -17,8 +17,8 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.services.Service +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types._ import scala.annotation.unused @@ -270,7 +270,7 @@ class BfrControl(vehicle: Vehicle) def disableShield(): Unit = { val zone = vehicle.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( s"${zone.id}", SendResponse(GenericObjectActionMessage(vehicle.GUID, 45)) ) @@ -284,7 +284,7 @@ class BfrControl(vehicle: Vehicle) def enableShield(): Unit = { val zone = vehicle.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( s"${zone.id}", SendResponse(GenericObjectActionMessage(vehicle.GUID, 44)) ) @@ -335,7 +335,7 @@ class BfrControl(vehicle: Vehicle) val vguid = vehicle.GUID val zone = vehicle.Zone val shields = vehicle.Shields - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, PlanetsideAttribute(vguid, vehicle.Definition.shieldUiAttribute, shields) ) @@ -415,7 +415,7 @@ class BfrControl(vehicle: Vehicle) }) match { case Some(useThisGuid) => val zone = vehicle.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, doNotSendTo, GenericObjectAction(useThisGuid, action) @@ -565,7 +565,7 @@ class BfrControl(vehicle: Vehicle) //cause the emp siphon.equipment.lastDischarge = now //TODO this is the apc emp effect; is there an ntu siphon emp effect? - events ! VehicleServiceMessage( + events ! MessageEnvelope( zone.id, SendResponse(TriggerEffectMessage( GUID0, @@ -587,7 +587,7 @@ class BfrControl(vehicle: Vehicle) //the siphon is not ready to dispatch another emp; chat message borrowed from kit use logic //the client actually enforces a hard limit of 30s before it will react to use of the siphon emp mode //it does not even dispatch the packet before that, making it rare if this precautionary message is seen - events ! VehicleServiceMessage( + events ! MessageEnvelope( obj.Seats(0).occupant.get.Name, SendResponse(ChatMsg(ChatMessageType.UNK_225, wideContents = false, "", s"@TimeUntilNextUse^${30000 - elapsedWait}", None)) ) diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala index d0303d72e..42bb8a01b 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleCapacitance.scala @@ -3,8 +3,8 @@ package net.psforever.objects.vehicles.control import akka.actor.{Actor, Cancellable} import net.psforever.objects._ +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute -import net.psforever.services.vehicle.VehicleServiceMessage import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -59,7 +59,7 @@ trait VehicleCapacitance { protected def showCapacitorCharge(): Unit = { val obj = CapacitanceObject - obj.Zone.VehicleEvents ! VehicleServiceMessage( + obj.Zone.VehicleEvents ! MessageEnvelope( self.toString(), PlanetsideAttribute(obj.GUID, 113, obj.Capacitor) ) diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index 3d3a6b0f2..6940e3c27 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -36,9 +36,10 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game._ import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types._ -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import scala.annotation.unused import scala.concurrent.ExecutionContext.Implicits.global @@ -212,7 +213,7 @@ class VehicleControl(vehicle: Vehicle) }) .flatMap { _.getMessage(vehicle) } .foreach { pkt => - events ! VehicleServiceMessage(toChannel, SendResponse(pkt)) + events ! MessageEnvelope(toChannel, SendResponse(pkt)) } case FactionAffinity.ConvertFactionAffinity(faction) => @@ -243,11 +244,11 @@ class VehicleControl(vehicle: Vehicle) log.info(s"changing vehicle equipment loadout to ${player.Name}'s option #${msg.unk1 + 1}") val (oldWeapons, newWeapons, oldInventory, finalInventory) = handleTerminalMessageVehicleLoadout(player, definition, weapons, inventory) - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, VehicleAction.ChangeLoadout(vehicle.GUID, oldWeapons, newWeapons, oldInventory, finalInventory) ) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.TerminalOrderResult(msg.terminal_guid, msg.transaction_type, result = true) ) @@ -255,7 +256,7 @@ class VehicleControl(vehicle: Vehicle) case _ => () } } else { - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( player.Name, AvatarAction.TerminalOrderResult(msg.terminal_guid, msg.transaction_type, result = false) ) @@ -329,7 +330,7 @@ class VehicleControl(vehicle: Vehicle) .orElse { case VehicleControl.Deletion() => val zone = vehicle.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, VehicleAction.UnloadVehicle(vehicle, vehicle.GUID) ) @@ -450,7 +451,7 @@ class VehicleControl(vehicle: Vehicle) zone.actor ! ZoneActor.AddToBlockMap(player, vehicle.Position) } if (player.HasGUID) { - events ! VehicleServiceMessage(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = true, guid)) + events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = true, guid)) } } } @@ -520,7 +521,7 @@ class VehicleControl(vehicle: Vehicle) val obj = ContainerObject obj.Find(item) match { case Some(slot) => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( self.toString, SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot)) ) @@ -532,7 +533,7 @@ class VehicleControl(vehicle: Vehicle) def RemoveItemFromSlotCallback(item: Equipment, slot: Int): Unit = { val zone = ContainerObject.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( self.toString, VehicleAction.UnstowEquipment(item.GUID) ) @@ -546,20 +547,20 @@ class VehicleControl(vehicle: Vehicle) val events = zone.VehicleEvents val iguid = item.GUID item.Faction = obj.Faction - events ! VehicleServiceMessage( + events ! MessageEnvelope( //TODO when a new weapon, the equipment slot ui goes blank, but the weapon functions; remount vehicle to correct it if (obj.VisibleSlots.contains(slot)) zone.id else channel, SendResponse(OCM.detailed(item, ObjectCreateMessageParent(oguid, slot))) ) item match { case box: AmmoBox => - events ! VehicleServiceMessage( + events ! MessageEnvelope( channel, VehicleAction.InventoryState2(iguid, oguid, box.Capacity) ) case weapon: Tool => weapon.AmmoSlots.map { slot => slot.Box }.foreach { box => - events ! VehicleServiceMessage( + events ! MessageEnvelope( channel, VehicleAction.InventoryState2(box.GUID, iguid, box.Capacity) ) @@ -572,7 +573,7 @@ class VehicleControl(vehicle: Vehicle) val obj = ContainerObject val zone = obj.Zone val toChannel = if (obj.VisibleSlots.contains(fromSlot)) zone.id else self.toString - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( toChannel, ObjectDelete(item.GUID) ) @@ -635,7 +636,7 @@ class VehicleControl(vehicle: Vehicle) if (canChargeShields) { vehicle.LogActivity(ShieldCharge(amount, motivator)) vehicle.Shields = vehicle.Shields + amount - vehicle.Zone.VehicleEvents ! VehicleServiceMessage( + vehicle.Zone.VehicleEvents ! MessageEnvelope( s"${vehicle.Actor}", PlanetsideAttribute(vehicle.GUID, vehicle.Definition.shieldUiAttribute, vehicle.Shields) ) @@ -690,7 +691,7 @@ class VehicleControl(vehicle: Vehicle) case Some(allow) => val group = AccessPermissionGroup(attribute - 10) log.info(s"$dname changed ${vehicle.Definition.Name}'s access permission $group to $allow") - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, dguid, VehicleAction.SeatPermissions(vguid, attribute, value) @@ -704,7 +705,7 @@ class VehicleControl(vehicle: Vehicle) if (vehicle.SeatPermissionGroup(seatIndex).contains(group) && !tplayer.Name.equals(dname)) { //can not kick self seat.unmount(tplayer) tplayer.VehicleSeated = None - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, tplayer.GUID, VehicleAction.KickPassenger(4, unk2 = false, vguid) @@ -753,7 +754,7 @@ class VehicleControl(vehicle: Vehicle) def vehicleSubsystemMessages(messages: List[PlanetSideGamePacket]): Unit = { val zone = vehicle.Zone - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, SendResponse(messages) ) diff --git a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala index 874438a84..10009f7dd 100644 --- a/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala +++ b/src/main/scala/net/psforever/objects/vehicles/interaction/WithEntranceInVehicle.scala @@ -6,6 +6,7 @@ import net.psforever.objects.avatar.interaction.WithEntrance import net.psforever.objects.serverobject.doors.InteriorDoorPassage import net.psforever.objects.serverobject.environment.PieceOfEnvironment import net.psforever.objects.zones.interaction.InteractsWithZone +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse class WithEntranceInVehicle @@ -40,9 +41,8 @@ class WithEntranceInVehicle private def warnAboutProximity(obj: InteractsWithZone, msg: String): Unit = { import net.psforever.packet.game.ChatMsg - import net.psforever.services.avatar.AvatarServiceMessage import net.psforever.types.ChatMessageType - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( obj.Actor.toString(), SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) ) diff --git a/src/main/scala/net/psforever/objects/zones/MapInfo.scala b/src/main/scala/net/psforever/objects/zones/MapInfo.scala index a005a2fb8..2f85c696b 100644 --- a/src/main/scala/net/psforever/objects/zones/MapInfo.scala +++ b/src/main/scala/net/psforever/objects/zones/MapInfo.scala @@ -4,9 +4,8 @@ import enumeratum.values.{StringEnum, StringEnumEntry} import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle} import net.psforever.objects.serverobject.environment._ import net.psforever.packet.game.{ChatMsg, OffshoreVehicleMessage} -import net.psforever.services.avatar.AvatarServiceMessage +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} sealed abstract class MapInfo( @@ -687,7 +686,7 @@ object MapEnvironment { " will be executed for treason." //TODO for bops, eventually } val warning = s"Do not travel any further $trespass of the battlefield or you$punishment" - p.Zone.AvatarEvents ! AvatarServiceMessage( + p.Zone.AvatarEvents ! MessageEnvelope( p.Name, SendResponse(ChatMsg(ChatMessageType.CMT_QUIT, warning)) ) @@ -695,7 +694,7 @@ object MapEnvironment { } obj match { case v: Vehicle => - v.Zone.VehicleEvents ! VehicleServiceMessage( + v.Zone.VehicleEvents ! MessageEnvelope( v.Actor.toString(), SendResponse(OffshoreVehicleMessage(v.Seats(0).occupant.get.GUID, v.GUID, msg)) ) diff --git a/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala index b840e2e02..431f67e14 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneDeployableActor.scala @@ -10,8 +10,8 @@ import net.psforever.objects.sourcing.ObjectSource import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vital.SpawningActivity import net.psforever.packet.game.ChatMsg +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.local.LocalServiceMessage import net.psforever.types.ChatMessageType import scala.annotation.tailrec @@ -108,7 +108,7 @@ object ZoneDeployableActor { val position = obj.Position deployableList.find(_ eq obj) match { case _ if Interference.Test(zone, obj).nonEmpty => - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( obj.OwnerName.getOrElse(""), SendResponse(ChatMsg(ChatMessageType.UNK_227, "@nomove_intersecting")) ) //may not be the correct message but is sufficient at explaining why the deployable can not be built diff --git a/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala b/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala index 09c67d47b..5d4efe87d 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala @@ -5,7 +5,8 @@ import akka.actor.{Actor, ActorRef, Cancellable, Props} import net.psforever.objects.Default import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.services.ServiceManager -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.galaxy.GalaxyAction import scala.collection.mutable.ListBuffer import scala.concurrent.duration._ @@ -305,7 +306,7 @@ class ZoneHotSpotProjector(zone: Zone, hotspots: ListBuffer[HotSpotInfo], blanki val zoneNumber = zone.Number val hotSpotInfoList = hotSpotInfos.toList affectedFactions.foreach(faction => - galaxy ! GalaxyServiceMessage(faction.toString, GalaxyAction.HotSpotUpdate( + galaxy ! MessageEnvelope(faction.toString, GalaxyAction.HotSpotUpdate( zoneNumber, 1, ZoneHotSpotProjector.SpecificHotSpotInfo(faction, hotSpotInfoList) diff --git a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala index 485915bd0..cb6f751fb 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala @@ -5,7 +5,8 @@ import akka.actor.{Actor, Cancellable} import net.psforever.objects.ballistics.Projectile import net.psforever.objects.guid.{GUIDTask, StraightforwardTask, TaskBundle, TaskWorkflow} import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete import net.psforever.types.PlanetSideGUID @@ -157,7 +158,7 @@ class ZoneProjectileActor( projectileGuid, context.system.scheduler.scheduleOnce(duration, self, ZoneProjectile.Remove(projectileGuid)) ) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, clarifiedFilterGuid, AvatarAction.LoadProjectile( @@ -189,17 +190,17 @@ class ZoneProjectileActor( projectileList.remove(projectileList.indexOf(projectile)) if (projectile.Definition.radiation_cloud) { zone.blockMap.removeFrom(projectile) - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, ObjectDelete(projectile_guid, 2) ) } else if (projectile.Definition.RemoteClientData == (0,0)) { - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, ObjectDelete(projectile_guid, 2) ) } else { - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, AvatarAction.ProjectileExplodes(projectile_guid, projectile) ) diff --git a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala index 834f47e19..eba37613a 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala @@ -9,8 +9,8 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vital.InGameHistory import net.psforever.objects.{Default, GlobalDefinitions, Vehicle} import net.psforever.packet.game.ChatMsg +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.vehicle.VehicleServiceMessage import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, Vector3} import scala.annotation.tailrec @@ -204,7 +204,7 @@ object ZoneVehicleActor { else None } msgOpt.foreach { msg => - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse(""), SendResponse(ChatMsg(ChatMessageType.UNK_227, msg)) ) diff --git a/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala b/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala index 91a4d3a67..10a94effb 100644 --- a/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala +++ b/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala @@ -6,7 +6,8 @@ import net.psforever.objects.avatar.scoring.{Assist, Death, KDAStat, Kill} import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.vital.interaction.{Adversarial, DamageResult} import net.psforever.objects.vital.{DamagingActivity, HealingActivity, InGameActivity, RepairingActivity, RevivingActivity, SpawningActivity} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.PlanetSideEmpire import net.psforever.util.Config @@ -42,7 +43,6 @@ object KillAssists { * @param eventBus where to send the results of the experience determination(s) * @see `ActorRef` * @see `AvatarAction.UpdateKillsDeathsAssists` - * @see `AvatarServiceMessage` * @see `DamageResult` * @see `rewardThisPlayerDeath` */ @@ -53,7 +53,7 @@ object KillAssists { eventBus: ActorRef ): Unit = { rewardThisPlayerDeath(victim, lastDamage, history).foreach { case (p, kda) => - eventBus ! AvatarServiceMessage(p.Name, AvatarAction.UpdateKillsDeathsAssists(p.CharId, kda)) + eventBus ! MessageEnvelope(p.Name, AvatarAction.UpdateKillsDeathsAssists(p.CharId, kda)) } } diff --git a/src/main/scala/net/psforever/objects/zones/exp/KillContributions.scala b/src/main/scala/net/psforever/objects/zones/exp/KillContributions.scala index 441d28f8c..25e79e3bf 100644 --- a/src/main/scala/net/psforever/objects/zones/exp/KillContributions.scala +++ b/src/main/scala/net/psforever/objects/zones/exp/KillContributions.scala @@ -8,7 +8,8 @@ import net.psforever.objects.sourcing.{BuildingSource, MountableEntry, PlayerSou import net.psforever.objects.vital.{Contribution, InGameActivity, RevivingActivity, TelepadUseActivity, TerminalUsedActivity, VehicleCargoDismountActivity, VehicleCargoMountActivity, DismountingActivity, MountingActivity} import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.exp.rec.{CombinedHealthAndArmorContributionProcess, MachineRecoveryExperienceContributionProcess} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.util.Config @@ -73,7 +74,6 @@ object KillContributions { * @param eventBus where to send the results of the experience determination(s) * @see `ActorRef` * @see `AvatarAction.UpdateKillsDeathsAssists` - * @see `AvatarServiceMessage` * @see `rewardTheseSupporters` * @see `SupportActivity` */ @@ -88,7 +88,7 @@ object KillContributions { //take the output and transform that into contribution distribution data rewardTheseSupporters(target, history, kill, bep) .foreach { case (charId, ContributionStatsOutput(player, weapons, exp)) => - eventBus ! AvatarServiceMessage( + eventBus ! MessageEnvelope( player.Name, AvatarAction.UpdateKillsDeathsAssists(charId, SupportActivity(victim, weapons, exp.toLong)) ) @@ -108,7 +108,6 @@ object KillContributions { * @see `ActorRef` * @see `additionalContributionSources` * @see `AvatarAction.UpdateKillsDeathsAssists` - * @see `AvatarServiceMessage` * @see `CombinedHealthAndArmorContributionProcess` * @see `composeContributionOutput` * @see `initialScoring` diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index 7e3d76581..d912d427f 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -12,8 +12,9 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage, GalaxyServiceResponse} +import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceResponse} import net.psforever.types.ChatMessageType import net.psforever.util.Config import net.psforever.zones.Zones @@ -90,7 +91,7 @@ object CavernRotationService { */ private def closedCavernWarning(zone: ZoneMonitor, counter: Int, galaxyService: ActorRef): Boolean = { if (!zone.locked) { - galaxyService ! GalaxyServiceMessage(SendResponse( + galaxyService ! MessageEnvelope("", SendResponse( ChatMsg(ChatMessageType.UNK_229, s"@cavern_closing_warning^@${zone.zone.id}~^@$counter~") )) true @@ -573,14 +574,14 @@ class CavernRotationService( val curr = System.currentTimeMillis() val (lockedZones, unlockedZones) = managedZones.partition(_.locked) unlockedZones.foreach { z => - galaxyService ! GalaxyServiceMessage(GalaxyAction.UnlockedZoneUpdate(z.zone)) + galaxyService ! MessageEnvelope("", GalaxyAction.UnlockedZoneUpdate(z.zone)) } val sortedLocked = lockedZones.sortBy(z => z.start) sortedLocked.take(2).foreach { z => - galaxyService ! GalaxyServiceMessage(GalaxyAction.LockedZoneUpdate(z.zone, z.start + z.duration - curr)) + galaxyService ! MessageEnvelope("", GalaxyAction.LockedZoneUpdate(z.zone, z.start + z.duration - curr)) } sortedLocked.takeRight(2).foreach { z => - galaxyService ! GalaxyServiceMessage(GalaxyAction.LockedZoneUpdate(z.zone, 0L)) + galaxyService ! MessageEnvelope("", GalaxyAction.LockedZoneUpdate(z.zone, 0L)) } } @@ -665,7 +666,7 @@ class CavernRotationService( lockTimerToDisplayWarning(hoursBetweenRotationsAsHours - firstClosingWarningAtMinutes.minutes) //alert clients to change if (lockingZone ne unlockingZone) { - galaxyService ! GalaxyServiceMessage(SendResponse( + galaxyService ! MessageEnvelope("", SendResponse( ChatMsg(ChatMessageType.UNK_229, s"@cavern_switched^@${lockingZone.id}~^@${unlockingZone.id}") )) //change warp gate statuses to reflect zone lock state diff --git a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala index 69b01c40d..6c452e91d 100644 --- a/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala +++ b/src/main/scala/net/psforever/services/account/AccountPersistenceService.scala @@ -15,9 +15,10 @@ import net.psforever.objects.zones.Zone import net.psforever.persistence import net.psforever.types.Vector3 import net.psforever.services.{Service, ServiceManager} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} +import net.psforever.services.galaxy.GalaxyAction import net.psforever.zones.Zones import scala.util.Success @@ -368,7 +369,7 @@ class PersistenceMonitor( (inZone.Players.find(p => p.name == name), inZone.AllPlayers.find(p => p.Name == name)) match { case (Some(avatar), Some(player)) if player.VehicleSeated.nonEmpty => //in case the player is holding the llu and disconnects - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem()) + player.Zone.AvatarEvents ! MessageEnvelope(player.Name, AvatarAction.DropSpecialItem()) //alive or dead in a vehicle //if the avatar is dead while in a vehicle, they haven't released yet AvatarActor.saveAvatarData(avatar) @@ -386,7 +387,7 @@ class PersistenceMonitor( case (Some(avatar), Some(player)) => //in case the player is holding the llu and disconnects - player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem()) + player.Zone.AvatarEvents ! MessageEnvelope(player.Name, AvatarAction.DropSpecialItem()) //alive or dead, as standard Infantry AvatarActor.saveAvatarData(avatar) AvatarActor.finalSavePlayerData(player) @@ -415,8 +416,7 @@ class PersistenceMonitor( * As this persistence monitor is about to become invalid, * any messages sent in response to what we are sending are received by the monitor's parent. * @see `Avatar` - * @see `AvatarAction.ObjectDelete` - * @see `AvatarServiceMessage` + * @see `ObjectDelete` * @see `GUIDTask.UnregisterPlayer` * @see `Player` * @see `Zone.AvatarEvents` @@ -435,7 +435,7 @@ class PersistenceMonitor( case _ => ; } inZone.Population.tell(Zone.Population.Release(avatar), parent) - inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, pguid, ObjectDelete(pguid)), parent) + inZone.AvatarEvents.tell(MessageEnvelope(inZone.id, pguid, ObjectDelete(pguid)), parent) TaskWorkflow.execute(GUIDTask.unregisterPlayer(inZone.GUID, player)) //inZone.tasks.tell(GUIDTask.UnregisterPlayer(player)(inZone.GUID), parent) AvatarLogout(avatar) @@ -454,7 +454,7 @@ class PersistenceMonitor( def AvatarLogout(avatar: Avatar): Unit = { LivePlayerList.Remove(avatar.id) squadService.tell(Service.Leave(avatar.id.toString), context.parent) - galaxyService.tell(GalaxyServiceMessage(GalaxyAction.LogStatusChange(avatar.name)), context.parent) + galaxyService.tell(MessageEnvelope(GalaxyAction.LogStatusChange(avatar.name)), context.parent) Deployables.Disown(inZone, avatar, context.parent) inZone.Population.tell(Zone.Population.Leave(avatar), context.parent) TaskWorkflow.execute(GUIDTask.unregisterObject(inZone.GUID, avatar.locker)) diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index 0aa2db81d..9c56bf9c0 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -1,25 +1,9 @@ // Copyright (c) 2017 PSForever package net.psforever.services.avatar -import akka.actor.{ActorContext, ActorRef, Props} -import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover} -import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericEventServiceWithCacheAndSupport} - -case object CorpseRemovalSupport - extends EventServiceSupport { - def label: String = "undertaker" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[CorpseRemovalActor](), name = "CorpseRemoval") - } -} - -case object LitterRemovalSupport - extends EventServiceSupport { - def label: String = "janitor" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[DroppedItemRemover](), name = "DroppedItemRemover") - } -} +import akka.actor.Props +import net.psforever.services.avatar.support.{CorpseRemovalSupport, LitterRemovalSupport} +import net.psforever.services.base.{EventSystemStamp, GenericEventServiceWithCacheAndSupport} case object AvatarStamp extends EventSystemStamp diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala deleted file mode 100644 index d7415c59a..000000000 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017-2026 PSForever -package net.psforever.services.avatar - -import net.psforever.services.Service -import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.EventMessage -import net.psforever.types.PlanetSideGUID - -object AvatarServiceMessage { - def apply(channel: String, msg: EventMessage): MessageEnvelope = - MessageEnvelope(channel, Service.defaultPlayerGUID, msg) - - def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = - MessageEnvelope(channel, filter, msg) -} diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 4f86597e8..842ccdab4 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -1,17 +1,27 @@ // Copyright (c) 2017 PSForever package net.psforever.services.avatar.support +import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.Player import net.psforever.types.{ExoSuitType, PlanetSideGUID} -import net.psforever.services.{RemoverActor, Service} +import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction.Release -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.ObjectDelete +import net.psforever.services.base.support.RemoverActor import scala.concurrent.duration._ +case object CorpseRemovalSupport + extends EventServiceSupport { + def label: String = "undertaker" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[CorpseRemovalActor](), name = "CorpseRemoval") + } +} + final case class ReleaseEnvelope( channel: String, filter: PlanetSideGUID, @@ -49,7 +59,7 @@ class CorpseRemovalActor extends RemoverActor() { def FirstJob(entry: RemoverActor.Entry): Unit = { import net.psforever.objects.zones.Zone entry.zone.Population ! Zone.Corpse.Remove(entry.obj.asInstanceOf[Player]) - context.parent ! AvatarServiceMessage( + context.parent ! MessageEnvelope( entry.zone.id, ObjectDelete(entry.obj.GUID, unk=1) ) diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index bb74a68e6..d745a04dc 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -1,18 +1,28 @@ // Copyright (c) 2017 PSForever package net.psforever.services.avatar.support +import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.zones.Zone import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem} -import net.psforever.services.{RemoverActor, Service} -import net.psforever.services.avatar.AvatarServiceMessage -import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} +import net.psforever.services.Service +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.ObjectDelete +import net.psforever.services.base.support.RemoverActor import net.psforever.types.PlanetSideGUID import scala.concurrent.duration._ +case object LitterRemovalSupport + extends EventServiceSupport { + def label: String = "janitor" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[DroppedItemRemover](), name = "DroppedItemRemover") + } +} + final case class PickupItemEnvelope( channel: String, filter: PlanetSideGUID, @@ -70,7 +80,7 @@ class DroppedItemRemover extends RemoverActor() { def FirstJob(entry: RemoverActor.Entry): Unit = { import net.psforever.objects.zones.Zone entry.zone.Ground ! Zone.Ground.RemoveItem(entry.obj.GUID) - context.parent ! AvatarServiceMessage( + context.parent ! MessageEnvelope( entry.zone.id, ObjectDelete(entry.obj.GUID) ) diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala index 9ab7f8a09..398c752cf 100644 --- a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -1,6 +1,7 @@ // Copyright (c) 2026 PSForever package net.psforever.services.base.envelope +import net.psforever.services.Service import net.psforever.services.base.EventSystemStamp import net.psforever.services.base.message.{EventMessage, EventResponse} import net.psforever.types.PlanetSideGUID @@ -53,3 +54,11 @@ trait MessageTransformationBehavior */ case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) extends MessageTransformationBehavior + +object MessageEnvelope { + def apply(msg: EventMessage): MessageEnvelope = + MessageEnvelope("", Service.defaultPlayerGUID, msg) + + def apply(channel: String, msg: EventMessage): MessageEnvelope = + MessageEnvelope(channel, Service.defaultPlayerGUID, msg) +} diff --git a/src/main/scala/net/psforever/services/RemoverActor.scala b/src/main/scala/net/psforever/services/base/support/RemoverActor.scala similarity index 98% rename from src/main/scala/net/psforever/services/RemoverActor.scala rename to src/main/scala/net/psforever/services/base/support/RemoverActor.scala index 6b7ecb9a7..2de317768 100644 --- a/src/main/scala/net/psforever/services/RemoverActor.scala +++ b/src/main/scala/net/psforever/services/base/support/RemoverActor.scala @@ -1,11 +1,10 @@ // Copyright (c) 2017 PSForever -package net.psforever.services +package net.psforever.services.base.support import akka.actor.Cancellable import net.psforever.objects.guid.{StraightforwardTask, TaskBundle, TaskWorkflow} import net.psforever.objects.zones.Zone import net.psforever.objects.{Default, PlanetSideGameObject} -import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import net.psforever.types.Vector3 import scala.concurrent.Future diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala deleted file mode 100644 index c0cc087fd..000000000 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.galaxy - -import net.psforever.services.Service -import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.EventMessage - -object GalaxyServiceMessage { - def apply(msg: EventMessage): MessageEnvelope = MessageEnvelope("", Service.defaultPlayerGUID, msg) - - def apply(channel: String, msg: EventMessage): MessageEnvelope = MessageEnvelope(channel, Service.defaultPlayerGUID, msg) -} diff --git a/src/main/scala/net/psforever/services/hart/HartTimer.scala b/src/main/scala/net/psforever/services/hart/HartTimer.scala index 2086c43b1..67f9f63f8 100644 --- a/src/main/scala/net/psforever/services/hart/HartTimer.scala +++ b/src/main/scala/net/psforever/services/hart/HartTimer.scala @@ -7,9 +7,9 @@ import net.psforever.objects.zones.Zone import net.psforever.services.Service import net.psforever.services.base.EventSystemStamp import net.psforever.services.base.bus.GenericEventBus -import net.psforever.services.base.envelope.{GenericResponseEnvelope, NoReply} +import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope, NoReply} import net.psforever.services.base.message.EventResponse -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.{HartSequence, PlanetSideGUID} import scala.concurrent.duration._ @@ -109,7 +109,7 @@ class HartTimer(zone: Zone) extends Actor { event.prerequisiteUpdate match { case Some(fields) => val times = event.timeFields(time) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( forChannel, LocalAction.ShuttleEvent(HartTimer.OrbitalShuttleEvent( fields.u1, fields.u2, times.t1, times.t2, times.t3, padAndShuttlePairs zip Seq(20, 20, 20) @@ -117,7 +117,7 @@ class HartTimer(zone: Zone) extends Actor { ) case None => ; } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( forChannel, LocalAction.ShuttleEvent( HartTimer.analyzeEvent(event, padAndShuttlePairs, time) @@ -157,17 +157,17 @@ class HartTimer(zone: Zone) extends Actor { val evt = HartTimer.analyzeEvent(event, padAndShuttlePairs) event.docked match { case Some(true) if currEvent.docked.isEmpty => - zone.LocalEvents ! LocalServiceMessage(zoneId, LocalAction.ShuttleEvent(evt)) + zone.LocalEvents ! MessageEnvelope(zoneId, LocalAction.ShuttleEvent(evt)) padEvents.publish( shuttleDockedInThisZone ) case Some(false) if currEvent.docked.contains(true) => padEvents.publish( shuttleFreeFromDockInThisZone ) context.system.scheduler.scheduleOnce( delay = 10 milliseconds, zone.LocalEvents, - LocalServiceMessage(zoneId, LocalAction.ShuttleEvent(evt)) + MessageEnvelope(zoneId, LocalAction.ShuttleEvent(evt)) ) case _ => - zone.LocalEvents ! LocalServiceMessage(zoneId, LocalAction.ShuttleEvent(evt)) + zone.LocalEvents ! MessageEnvelope(zoneId, LocalAction.ShuttleEvent(evt)) } if (currEvent.lockedDoors != event.lockedDoors) { padEvents.publish( if(event.lockedDoors) HartTimer.LockDoors else HartTimer.UnlockDoors ) diff --git a/src/main/scala/net/psforever/services/hart/HartTimerActions.scala b/src/main/scala/net/psforever/services/hart/HartTimerActions.scala index 291c4bbc3..442f60c4b 100644 --- a/src/main/scala/net/psforever/services/hart/HartTimerActions.scala +++ b/src/main/scala/net/psforever/services/hart/HartTimerActions.scala @@ -3,7 +3,8 @@ package net.psforever.services.hart import net.psforever.objects.Vehicle import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.local.LocalAction object HartTimerActions { /** @@ -17,7 +18,7 @@ object HartTimerActions { if(toChannel.equals(zone.id)) { shuttle.MountedIn = pad.GUID } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( toChannel, LocalAction.ShuttleDock(pad.GUID, shuttle.GUID, 3) ) @@ -34,7 +35,7 @@ object HartTimerActions { if(toChannel.equals(zone.id)) { shuttle.MountedIn = None } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( toChannel, LocalAction.ShuttleUndock(pad.GUID, shuttle.GUID, shuttle.Position, shuttle.Orientation) ) @@ -51,7 +52,7 @@ object HartTimerActions { if(toChannel.equals(zone.id)) { shuttle.Flying = state } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( toChannel, LocalAction.ShuttleState(shuttle.GUID, shuttle.Position, shuttle.Orientation, state) ) diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index 395e5ec03..e6aad046f 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -1,43 +1,10 @@ // Copyright (c) 2017 PSForever package net.psforever.services.local -import akka.actor.{ActorContext, ActorRef, Props} +import akka.actor.Props import net.psforever.objects.zones.Zone -import net.psforever.services.local.support.CaptureFlagManager import net.psforever.services.local.support._ -import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericEventServiceWithSupport} - -case object DoorCloserSupport - extends EventServiceSupport { - def label: String = "doorCloser" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[DoorCloseActor](), name = "DoorCloser") - } -} - -case object HackClearSupport - extends EventServiceSupport { - def label: String = "hackClearer" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[HackClearActor](), name = "HackClearer") - } -} - -case object HackCaptureSupport - extends EventServiceSupport { - def label: String = "hackCapturer" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[HackCaptureActor](), name = "HackCapturer") - } -} - -case class CaptureFlagSupport(zone: Zone) - extends EventServiceSupport { - def label: String = "captureFlagManager" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props(classOf[CaptureFlagManager], zone), name = "CaptureFlagManager") - } -} +import net.psforever.services.base.{EventSystemStamp, GenericEventServiceWithSupport} case object LocalStamp extends EventSystemStamp diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala deleted file mode 100644 index 005610369..000000000 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.local - -import net.psforever.services.Service -import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.EventMessage -import net.psforever.types.PlanetSideGUID - -object LocalServiceMessage { - def apply(channel: String, localMessage: EventMessage): MessageEnvelope = - MessageEnvelope(channel, Service.defaultPlayerGUID, localMessage) - - def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = - MessageEnvelope(channel, filter, msg) -} diff --git a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala index d08d1e207..231ca3104 100644 --- a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala +++ b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala @@ -1,7 +1,7 @@ // Copyright (c) 2021 PSForever package net.psforever.services.local.support -import akka.actor.{Actor, ActorRef, Cancellable} +import akka.actor.{Actor, ActorContext, ActorRef, Cancellable, Props} import net.psforever.login.WorldSession import net.psforever.objects.{Default, PlanetSideGameObject, Player} import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} @@ -15,14 +15,23 @@ import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.ServiceManager.{Lookup, LookupResult} -import net.psforever.services.base.GenericSupportEnvelopeOnly +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelopeOnly} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, SendResponse} -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.galaxy.GalaxyAction +import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.duration.DurationInt +case class CaptureFlagSupport(zone: Zone) + extends EventServiceSupport { + def label: String = "captureFlagManager" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props(classOf[CaptureFlagManager], zone), name = "CaptureFlagManager") + } +} + final case class FlagEnvelope(supportMessage: CaptureFlagManager.Command) extends GenericSupportEnvelopeOnly { def supportLabel: String = "captureFlagManager" @@ -52,7 +61,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { case CaptureFlagManager.SpawnCaptureFlag(capture_terminal, target, hackingFaction) => val socket = capture_terminal.Owner.asInstanceOf[Building].GetFlagSocket.get // Override CC message when looked at - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, PlanetSideGUID(-1), GenericObjectAction( @@ -74,7 +83,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { TaskWorkflow.execute(WorldSession.CallBackForTask( GUIDTask.registerObject(zone.GUID, flag), zone.LocalEvents, - LocalServiceMessage( + MessageEnvelope( zone.id, LocalAction.LluSpawned(flag) ) @@ -89,7 +98,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { case None => "A soldier" } // Trigger Install sound - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, PlanetSideGUID(-1), LocalAction.TriggerSound(TriggeredSound.LLUInstall, flag.Target.CaptureTerminal.get.Position, 20, 0.8000001f) @@ -126,12 +135,12 @@ class CaptureFlagManager(zone: Zone) extends Actor { case CaptureFlagManager.PickupFlag(flag: CaptureFlag, player: Player) => flag.Carrier = Some(player) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, PlanetSideGUID(-1), SendResponse(ObjectAttachMessage(player.GUID, flag.GUID, 252)) ) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, PlanetSideGUID(-1), LocalAction.TriggerSound(TriggeredSound.LLUPickup, player.Position, 15, volume = 0.8f) @@ -151,7 +160,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { // Remove attached player from flag flag.Carrier = None // Send drop packet - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, PlanetSideGUID(-1), SendResponse(ObjectDetachMessage(player.GUID, flag.GUID, player.Position, 0, 0, 0)) @@ -178,7 +187,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { TaskWorkflow.execute(WorldSession.CallBackForTask( GUIDTask.registerObject(zone.GUID, replacementLlu), zone.LocalEvents, - LocalServiceMessage( + MessageEnvelope( zone.id, LocalAction.LluSpawned(replacementLlu) ) @@ -212,7 +221,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { is_monolith_unit = false ) } - galaxyService ! GalaxyServiceMessage(GalaxyAction.FlagMapUpdate(CaptureFlagUpdateMessage(zone.Number, flagInfo))) + galaxyService ! MessageEnvelope("", GalaxyAction.FlagMapUpdate(CaptureFlagUpdateMessage(zone.Number, flagInfo))) } private def TrackFlag(flag: CaptureFlag): Unit = { @@ -239,7 +248,7 @@ class CaptureFlagManager(zone: Zone) extends Actor { flag.Owner.asInstanceOf[Building].GetFlagSocket.get.captureFlag = None UntrackFlag(flag) // Unregister LLU from clients, - zone.LocalEvents ! LocalServiceMessage(zone.id, PlanetSideGUID(-1), LocalAction.LluDespawned(flag.GUID, flag.Position)) + zone.LocalEvents ! MessageEnvelope(zone.id, PlanetSideGUID(-1), LocalAction.LluDespawned(flag.GUID, flag.Position)) // Then unregister it from the GUID pool TaskWorkflow.execute(GUIDTask.unregisterObject(zone.GUID, flag)) } @@ -269,7 +278,7 @@ object CaptureFlagManager { } else { ChatMessageType.UNK_229 } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, PlanetSideGUID(-1), SendResponse(ChatMsg(messageType, wideContents = true, "", message, None)) diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index 67387b6f7..d99a134ac 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -1,19 +1,28 @@ // Copyright (c) 2017 PSForever package net.psforever.services.local.support -import akka.actor.{Actor, Cancellable} +import akka.actor.{Actor, ActorContext, ActorRef, Cancellable, Props} import net.psforever.objects.{Default, Doors} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone import net.psforever.services.Service -import net.psforever.services.base.GenericSupportEnvelope +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.local.LocalAction.IsADoorMessage -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec import scala.concurrent.duration._ +case object DoorCloserSupport + extends EventServiceSupport { + def label: String = "doorCloser" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[DoorCloseActor](), name = "DoorCloser") + } +} + final case class DoorMessage( channel: String, msg: IsADoorMessage, @@ -58,7 +67,7 @@ class DoorCloseActor() extends Actor { ).sortBy(_.time) doorsToClose2.foreach { case DoorCloseActor.DoorEntry(door, zone, _) => door.Open = None //permissible break from synchronization - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.DoorCloses(door.GUID)) //call up to the main event system + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.DoorCloses(door.GUID)) //call up to the main event system } if (openDoors.nonEmpty) { diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index b6f825950..06c606f30 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -1,7 +1,7 @@ // Copyright (c) 2021 PSForever package net.psforever.services.local.support -import akka.actor.{Actor, Cancellable} +import akka.actor.{Actor, ActorContext, ActorRef, Cancellable, Props} import net.psforever.actors.zone.{BuildingActor, ZoneActor} import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.hackable.Hackable @@ -13,10 +13,11 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource -import net.psforever.services.base.GenericSupportEnvelopeOnly +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelopeOnly} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} import java.util.concurrent.{Executors, TimeUnit} @@ -24,6 +25,14 @@ import scala.collection.Seq import scala.concurrent.duration.{FiniteDuration, _} import scala.util.Random +case object HackCaptureSupport + extends EventServiceSupport { + def label: String = "hackCapturer" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[HackCaptureActor](), name = "HackCapturer") + } +} + final case class CaptureEnvelope(supportMessage: Any) extends GenericSupportEnvelopeOnly { def supportLabel: String = "hackCapturer" @@ -235,7 +244,7 @@ class HackCaptureActor extends Actor { ): Unit = { val attributeValue = HackCaptureActor.GetHackUpdateAttributeValue(terminal, isResecured) // Notify all clients that CC has had its hack state changed - terminal.Zone.LocalEvents ! LocalServiceMessage( + terminal.Zone.LocalEvents ! MessageEnvelope( terminal.Zone.id, PlanetSideGUID(-1), PlanetsideAttribute( @@ -278,7 +287,7 @@ class HackCaptureActor extends Actor { building .PlayersInSOI .collect { case p if p.Faction == hackedByFaction => - events ! LocalServiceMessage(p.Name, msg) + events ! MessageEnvelope(p.Name, msg) } val buildings = building.Zone.Buildings.values val hackedBaseId = building.GUID @@ -314,7 +323,7 @@ class HackCaptureActor extends Actor { NotifyHackStateChange(terminal, isResecured = true) // todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. val zone = building.Zone - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.HackClear(building.GUID, 3212836864L, HackState7.Unk8)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.HackClear(building.GUID, 3212836864L, HackState7.Unk8)) } private def RestartTimer(): Unit = { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index 92b02dec2..1d7796984 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -2,21 +2,30 @@ package net.psforever.services.local.support import java.util.concurrent.TimeUnit -import akka.actor.{Actor, Cancellable} +import akka.actor.{Actor, ActorContext, ActorRef, Cancellable, Props} import net.psforever.objects.{Default, GlobalDefinitions} import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.HackState7 -import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.GenericObjectAction import net.psforever.services.local.LocalAction.IsAHackMessage -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec import scala.concurrent.duration._ +case object HackClearSupport + extends EventServiceSupport { + def label: String = "hackClearer" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[HackClearActor](), name = "HackClearer") + } +} + final case class HackEntityEnvelope( channel: String, filter: PlanetSideGUID, @@ -65,7 +74,7 @@ class HackClearActor() extends Actor { hackedObjects = stillHackedObjects unhackObjects.foreach { case HackClearActor.HackEntry(target, zone, unk1, unk2, _, _) => target.Actor ! CommonMessages.ClearHack() - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.HackClear(target.GUID, unk1, unk2)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.HackClear(target.GUID, unk1, unk2)) if (target.Definition == GlobalDefinitions.main_terminal) { ClearVirusFromBuilding(target) } @@ -78,7 +87,7 @@ class HackClearActor() extends Actor { case Some(HackClearActor.HackEntry(target, zone, unk1, unk2, _, _)) => hackedObjects = hackedObjects.filterNot(x => x.target == target) target.Actor ! CommonMessages.ClearHack() - zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.HackClear(target.GUID, 3212836864L, HackState7.Unk8)) + zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.HackClear(target.GUID, 3212836864L, HackState7.Unk8)) // Restart the timer in case the object we just removed was the next one scheduled RestartTimer() @@ -117,7 +126,6 @@ class HackClearActor() extends Actor { import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.actors.zone.BuildingActor - import net.psforever.services.avatar.AvatarServiceMessage val building = target.asInstanceOf[Terminal].Owner.asInstanceOf[Building] building.virusId = 8 @@ -125,7 +133,7 @@ class HackClearActor() extends Actor { val msg = GenericObjectAction(target.GUID, 60) val events = building.Zone.AvatarEvents building.PlayersInSOI.foreach { player => - events ! AvatarServiceMessage(player.Name, msg) + events ! MessageEnvelope(player.Name, msg) } building.Actor ! BuildingActor.MapUpdate() } diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala index 7ab4ccf0f..26f130f43 100644 --- a/src/main/scala/net/psforever/services/vehicle/VehicleService.scala +++ b/src/main/scala/net/psforever/services/vehicle/VehicleService.scala @@ -1,17 +1,9 @@ // Copyright (c) 2017-2026 PSForever package net.psforever.services.vehicle -import akka.actor.{ActorContext, ActorRef, Props} -import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericEventServiceWithCacheAndSupport} -import net.psforever.services.vehicle.support.TurretUpgrader - -case object TurretUpgradeSupport - extends EventServiceSupport { - def label: String = "turretUpgrader" - def constructor(context: ActorContext): ActorRef = { - context.actorOf(Props[TurretUpgrader](), name = "TurretUpgrader") - } -} +import akka.actor.Props +import net.psforever.services.base.{EventSystemStamp, GenericEventServiceWithCacheAndSupport} +import net.psforever.services.vehicle.support.TurretUpgradeSupport case object VehicleStamp extends EventSystemStamp diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala deleted file mode 100644 index f6aae9a32..000000000 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.vehicle - -import net.psforever.services.Service -import net.psforever.services.base.message.EventMessage -import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.types.PlanetSideGUID - -object VehicleServiceMessage { - def apply(channel: String, localMessage: EventMessage): MessageEnvelope = - MessageEnvelope(channel, Service.defaultPlayerGUID, localMessage) - - def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope = - MessageEnvelope(channel, filter, msg) -} diff --git a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala index 1b81938c7..df81cb0ff 100644 --- a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala +++ b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017 PSForever package net.psforever.services.vehicle.support -import akka.actor.Cancellable +import akka.actor.{ActorContext, ActorRef, Cancellable, Props} import net.psforever.objects.equipment.EquipmentSlot import net.psforever.objects.{AmmoBox, Default, PlanetSideGameObject, Tool} import net.psforever.objects.guid._ @@ -9,15 +9,24 @@ import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, WeaponTurret} import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.zones.Zone -import net.psforever.services.base.GenericSupportEnvelopeOnly +import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelopeOnly} +import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.types.PlanetSideGUID import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global +case object TurretUpgradeSupport + extends EventServiceSupport { + def label: String = "turretUpgrader" + def constructor(context: ActorContext): ActorRef = { + context.actorOf(Props[TurretUpgrader](), name = "TurretUpgrader") + } +} + final case class TurretEnvelope(supportMessage: Any) extends GenericSupportEnvelopeOnly { def supportLabel: String = "turretUpgrader" @@ -165,7 +174,7 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { seat.unmount(tplayer) tplayer.VehicleSeated = None if (tplayer.HasGUID) { - context.parent ! VehicleServiceMessage( + context.parent ! MessageEnvelope( zoneId, tplayer.GUID, VehicleAction.KickPassenger(4, unk2=false, turretGUID) @@ -240,7 +249,7 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { .map { case (index: Int, slot: EquipmentSlot) => (index, slot.Equipment) } .collect { case (index, Some(tool: Tool)) => - context.parent ! VehicleServiceMessage( + context.parent ! MessageEnvelope( zone.id, VehicleAction.EquipmentInSlot(targetGUID, index, tool) ) From 7e1e0e3016bd942549da8f40b3ec3ed292258b64 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 8 Mar 2026 17:09:02 -0400 Subject: [PATCH 19/32] replacing *ServiceResponse classes with GenericResponseEnvelope and an identifying stamp in all remaining cases such that the classes are unnecessary for the project and can be deleted; squad remaains untouched due to its difference --- .codecov.yml | 4 --- .../actors/session/AvatarActor.scala | 6 ++-- .../session/csr/AvatarHandlerLogic.scala | 7 ++-- .../session/normal/VehicleHandlerLogic.scala | 13 +++++--- .../spectator/VehicleHandlerLogic.scala | 13 +++++--- .../support/SessionAvatarHandlers.scala | 7 ++-- .../serverobject/doors/DoorControl.scala | 6 ++-- .../services/CavernRotationService.scala | 13 +++++--- .../avatar/AvatarServiceResponse.scala | 15 --------- .../envelope/GenericResponseEnvelope.scala | 33 +++++++++++++++++-- .../galaxy/GalaxyServiceResponse.scala | 15 --------- .../services/local/LocalServiceResponse.scala | 15 --------- .../vehicle/VehicleServiceResponse.scala | 15 --------- src/test/scala/objects/DoorTest.scala | 5 +-- 14 files changed, 74 insertions(+), 93 deletions(-) delete mode 100644 src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala delete mode 100644 src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala delete mode 100644 src/main/scala/net/psforever/services/local/LocalServiceResponse.scala delete mode 100644 src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala diff --git a/.codecov.yml b/.codecov.yml index 3c69d86ed..37159d819 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -75,23 +75,19 @@ ignore: - "src/main/scala/net/psforever/services/account/StoreIPAddress.scala" - "src/main/scala/net/psforever/services/avatar/AvatarAction.scala" - "src/main/scala/net/psforever/services/avatar/AvatarService.scala" - - "src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala" - "src/main/scala/net/psforever/services/base/bus" - "src/main/scala/net/psforever/services/base/envelope" - "src/main/scala/net/psforever/services/chat/ChatChannel.scala" - "src/main/scala/net/psforever/services/galaxy/GalaxyAction" - "src/main/scala/net/psforever/services/galaxy/GalaxyService" - - "src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala" - "src/main/scala/net/psforever/services/hart/HartEvent.scala" - "src/main/scala/net/psforever/services/hart/HartTimerActions.scala" - "src/main/scala/net/psforever/services/local/LocalAction" - "src/main/scala/net/psforever/services/local/LocalService" - - "src/main/scala/net/psforever/services/local/LocalServiceResponse.scala" - "src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala" - "src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala" - "src/main/scala/net/psforever/services/vehicle/VehicleAction" - "src/main/scala/net/psforever/services/vehicle/VehicleService" - - "src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala" - "src/main/scala/net/psforever/services/Service.scala" - "src/main/scala/net/psforever/types" - "src/main/scala/net/psforever/util" diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 96113546a..87c59aa42 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -12,6 +12,8 @@ import net.psforever.objects.avatar.ModePermissions import net.psforever.objects.avatar.scoring.{Assist, Death, EquipmentStat, KDAStat, Kill, Life, ScoreCard, SupportActivity} import net.psforever.objects.sourcing.{TurretSource, VehicleSource} import net.psforever.packet.game.ImplantAction +import net.psforever.services.avatar.AvatarStamp +import net.psforever.services.base.envelope.GenericResponseEnvelope import net.psforever.types.{ChatMessageType, StatisticalCategory, StatisticalElement} import net.psforever.zones.Zones import org.joda.time.{LocalDateTime, Seconds} @@ -3490,8 +3492,8 @@ class AvatarActor( value: Int ): Unit = { import akka.actor.typed.scaladsl.adapter.TypedActorRefOps - import net.psforever.services.avatar.AvatarServiceResponse - sessionActor.toClassic ! AvatarServiceResponse("", guid, AvatarAction.AvatarImplant(action, index, value)) + val resp = AvatarAction.AvatarImplant(action, index, value) + sessionActor.toClassic ! GenericResponseEnvelope(AvatarStamp, "", guid, resp) } private def buyImplantAction( 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 01b88bf05..1ef36f908 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -12,7 +12,8 @@ import net.psforever.objects.serverobject.containable.ContainableBehavior import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vital.RevivingActivity import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, HitHint, ImplantAction} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceResponse} +import net.psforever.services.avatar.{AvatarAction, AvatarStamp} +import net.psforever.services.base.envelope.GenericResponseEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} import net.psforever.types.ImplantType @@ -60,11 +61,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* special messages */ case AvatarAction.TeardownConnection() if player.spectator => context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) - context.self.forward(AvatarServiceResponse(toChannel, guid, reply)) + context.self.forward(GenericResponseEnvelope(AvatarStamp, toChannel, guid, reply)) case AvatarAction.TeardownConnection() => context.self ! SessionActor.SetMode(NormalMode) - context.self.forward(AvatarServiceResponse(toChannel, guid, reply)) + context.self.forward(GenericResponseEnvelope(AvatarStamp, toChannel, guid, reply)) /* really common messages (very frequently, every life) */ case pstate @ AvatarAction.PlayerState( 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 f40fc771a..62acd99c1 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -14,9 +14,10 @@ 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.services.Service +import net.psforever.services.base.envelope.GenericResponseEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.local.support.CaptureFlagManager -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} +import net.psforever.services.vehicle.{VehicleAction, VehicleStamp} import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3} object VehicleHandlerLogic { @@ -256,11 +257,13 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: ) import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ - context.system.scheduler.scheduleOnce( - delay milliseconds, - context.self, - VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleAction.KickCargo(vehicle, speed=0, delay)) + val resp = GenericResponseEnvelope( + VehicleStamp, + toChannel, + PlanetSideGUID(0), + VehicleAction.KickCargo(vehicle, speed=0, delay) ) + context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) case VehicleAction.KickCargo(cargo, _, _) if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => 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 bee65c613..182f32efe 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -8,8 +8,9 @@ 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.services.base.envelope.GenericResponseEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, GenericObjectAction, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceResponse} +import net.psforever.services.vehicle.{VehicleAction, VehicleStamp} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} object VehicleHandlerLogic { @@ -205,11 +206,13 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: ) import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ - context.system.scheduler.scheduleOnce( - delay milliseconds, - context.self, - VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleAction.KickCargo(vehicle, speed=0, delay)) + val resp = GenericResponseEnvelope( + VehicleStamp, + toChannel, + PlanetSideGUID(0), + VehicleAction.KickCargo(vehicle, speed=0, delay) ) + context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) case VehicleAction.KickCargo(cargo, _, _) if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index 88298edc1..2e613704b 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -8,8 +8,8 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, UniquePlayer} import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.objects.zones.exp import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceResponse} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.avatar.{AvatarAction, AvatarStamp} +import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} import net.psforever.services.base.message.{EventResponse, SendResponse} import net.psforever.services.chat.OutfitChannel @@ -213,7 +213,8 @@ class SessionAvatarHandlers( def killedWhileMounted(obj: PlanetSideGameObject with Mountable, playerGuid: PlanetSideGUID): Unit = { val playerName = player.Name //boot cadaver from mount on client - context.self ! AvatarServiceResponse( + context.self ! GenericResponseEnvelope( + AvatarStamp, playerName, Service.defaultPlayerGUID, SendResponse(ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero)) diff --git a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala index cd8b6a599..5f00c5d83 100644 --- a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala @@ -8,9 +8,10 @@ import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffi import net.psforever.objects.serverobject.locks.IFFLock import net.psforever.objects.serverobject.structures.PoweredAmenityControl import net.psforever.services.Service +import net.psforever.services.base.envelope.GenericResponseEnvelope import net.psforever.services.base.support.SupportActor import net.psforever.services.local.support.{DoorCloseActor, DoorMessage} -import net.psforever.services.local.{LocalAction, LocalServiceResponse} +import net.psforever.services.local.{LocalAction, LocalStamp} /** * An `Actor` that handles messages being dispatched to a specific `Door`. @@ -116,7 +117,8 @@ object DoorControl { ) } else { //the door should already open, but the requesting player does not see it as open - replyTo ! LocalServiceResponse( + replyTo ! GenericResponseEnvelope( + LocalStamp, player.Name, Service.defaultPlayerGUID, LocalAction.DoorOpens(door.Zone, door) diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index d912d427f..a337e5988 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -12,9 +12,9 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse -import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceResponse} +import net.psforever.services.galaxy.{GalaxyAction, GalaxyStamp} import net.psforever.types.ChatMessageType import net.psforever.util.Config import net.psforever.zones.Zones @@ -559,14 +559,17 @@ class CavernRotationService( val (lockedZones, unlockedZones) = managedZones.partition(_.locked) //borrow GalaxyService response structure, but send to the specific endpoint math.max(0, monitor.start + monitor.duration - curr) unlockedZones.foreach { monitor => - sendToSession ! GalaxyServiceResponse("", GalaxyAction.UnlockedZoneUpdate(monitor.zone)) + val resp = GalaxyAction.UnlockedZoneUpdate(monitor.zone) + sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Service.defaultPlayerGUID, resp) } val sortedLocked = lockedZones.sortBy(z => z.start) sortedLocked.take(2).foreach { monitor => - sendToSession ! GalaxyServiceResponse("", GalaxyAction.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr))) + val resp = GalaxyAction.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr)) + sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Service.defaultPlayerGUID, resp) } sortedLocked.takeRight(2).foreach { monitor => - sendToSession ! GalaxyServiceResponse("", GalaxyAction.LockedZoneUpdate(monitor.zone, 0L)) + val resp = GalaxyAction.LockedZoneUpdate(monitor.zone, 0L) + sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Service.defaultPlayerGUID, resp) } } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala deleted file mode 100644 index a40827b99..000000000 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.avatar - -import net.psforever.services.base.message.EventResponse -import net.psforever.types.PlanetSideGUID -import net.psforever.services.base.EventSystemStamp -import net.psforever.services.base.envelope.GenericResponseEnvelope - -final case class AvatarServiceResponse( - channel: String, - filter: PlanetSideGUID, - reply: EventResponse - ) extends GenericResponseEnvelope { - def stamp: EventSystemStamp = AvatarStamp -} diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala index 001513b10..752fc9385 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala @@ -2,7 +2,7 @@ package net.psforever.services.base.envelope import net.psforever.services.base.EventSystemStamp -import net.psforever.services.base.message.{EventMessage, EventResponse} +import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent} import net.psforever.types.PlanetSideGUID /** @@ -15,7 +15,7 @@ trait GenericResponseEnvelope /** marker indicating the routing through which the original message was processed */ def stamp: EventSystemStamp /** channel information tailored to the event system */ - def outChannel: String = stamp.routing(channel) + final def outChannel: String = stamp.routing(channel) } object GenericResponseEnvelope { @@ -32,6 +32,35 @@ object GenericResponseEnvelope { envelope.response(stamp) } + /** + * Fake a response envelope, as if processed by a specific event system. + * @param _stamp marker indicating the routing through which the original message was processed + * @param _channel set of subscribers on an event system bus the envelope should reach + * @param _filter a specific subscriber endpoint to be excluded + * @param _reply input payload transported by this envelope + * @return a faked but typically acceptable response envelope + */ + def apply(_stamp: EventSystemStamp, _channel: String, _filter: PlanetSideGUID, _reply: SelfRespondingEvent): GenericResponseEnvelope = { + apply(_stamp, _channel, _filter, _reply.asInstanceOf[EventResponse]) + } + + /** + * Fake a response envelope, as if processed by a specific event system. + * @param _stamp marker indicating the routing through which the original message was processed + * @param _channel set of subscribers on an event system bus the envelope should reach + * @param _filter a specific subscriber endpoint to be excluded + * @param _reply input payload transported by this envelope + * @return a faked but typically acceptable response envelope + */ + def apply(_stamp: EventSystemStamp, _channel: String, _filter: PlanetSideGUID, _reply: EventResponse): GenericResponseEnvelope = { + new GenericResponseEnvelope { + def channel: String = _channel + def filter: PlanetSideGUID = _filter + def reply: EventResponse = _reply + def stamp: EventSystemStamp = _stamp + } + } + /** * The `unapply`ed data from a response envelope resembles the data from includes the filter and the channel information. * @param obj response envelope diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala deleted file mode 100644 index 8cd9cbdee..000000000 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.galaxy - -import net.psforever.types.PlanetSideGUID -import net.psforever.services.Service -import net.psforever.services.base.message.EventResponse -import net.psforever.services.base.EventSystemStamp -import net.psforever.services.base.envelope.GenericResponseEnvelope - -final case class GalaxyServiceResponse(channel: String, reply: EventResponse) - extends GenericResponseEnvelope { - def filter: PlanetSideGUID = Service.defaultPlayerGUID - - def stamp: EventSystemStamp = GalaxyStamp -} diff --git a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala deleted file mode 100644 index dae9ab60b..000000000 --- a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.local - -import net.psforever.services.base.message.EventResponse -import net.psforever.types.PlanetSideGUID -import net.psforever.services.base.EventSystemStamp -import net.psforever.services.base.envelope.GenericResponseEnvelope - -final case class LocalServiceResponse( - channel: String, - filter: PlanetSideGUID, - reply: EventResponse - ) extends GenericResponseEnvelope { - def stamp: EventSystemStamp = LocalStamp -} diff --git a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala b/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala deleted file mode 100644 index 1b6652e2d..000000000 --- a/src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.services.vehicle - -import net.psforever.services.base.message.EventResponse -import net.psforever.types.PlanetSideGUID -import net.psforever.services.base.EventSystemStamp -import net.psforever.services.base.envelope.GenericResponseEnvelope - -final case class VehicleServiceResponse( - channel: String, - filter: PlanetSideGUID, - reply: EventResponse - ) extends GenericResponseEnvelope { - def stamp: EventSystemStamp = VehicleStamp -} diff --git a/src/test/scala/objects/DoorTest.scala b/src/test/scala/objects/DoorTest.scala index 2404e44ca..48191ec59 100644 --- a/src/test/scala/objects/DoorTest.scala +++ b/src/test/scala/objects/DoorTest.scala @@ -12,8 +12,9 @@ import net.psforever.objects.{Default, GlobalDefinitions, Player} import net.psforever.objects.serverobject.doors.{Door, DoorControl} import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.zones.{Zone, ZoneMap} +import net.psforever.services.base.envelope.GenericResponseEnvelope import net.psforever.services.local.support.DoorMessage -import net.psforever.services.local.{LocalAction, LocalServiceResponse} +import net.psforever.services.local.LocalAction import net.psforever.types._ import org.specs2.mutable.Specification @@ -106,7 +107,7 @@ class DoorControlAlreadyOpenTest extends ActorTest { door.Actor.tell(CommonMessages.Use(player), probe.ref) val reply = probe.receiveOne(1000 milliseconds) assert(reply match { - case LocalServiceResponse("test", _, LocalAction.DoorOpens(_, thisDoor)) => thisDoor eq door + case GenericResponseEnvelope("test", _, LocalAction.DoorOpens(_, thisDoor)) => thisDoor eq door case _ => false }) } From b39f95354a61946abe5ed009158c932add943692 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 24 Mar 2026 16:37:58 -0400 Subject: [PATCH 20/32] extract common messages into a common handler endpoint; created an interface for handlers thus that all handler endpoints can be polled if a specific handler endpoint does not support a message --- .../actors/session/SessionActor.scala | 70 +- .../session/csr/AvatarHandlerLogic.scala | 947 +++++++------- .../session/normal/AvatarHandlerLogic.scala | 1155 ++++++++--------- .../session/normal/GalaxyHandlerLogic.scala | 100 +- .../session/normal/LocalHandlerLogic.scala | 440 +++---- .../session/normal/VehicleHandlerLogic.scala | 639 +++++---- .../spectator/AvatarHandlerLogic.scala | 946 +++++++------- .../spectator/VehicleHandlerLogic.scala | 362 +++--- .../support/CommonHandlerFunctions.scala | 105 ++ .../session/support/CommonHandlerLogic.scala | 67 + .../support/SessionAvatarHandlers.scala | 10 +- .../support/SessionGalaxyHandlers.scala | 7 +- .../support/SessionLocalHandlers.scala | 5 +- .../support/SessionVehicleHandlers.scala | 5 +- .../session/support/ZoningOperations.scala | 2 +- .../net/psforever/objects/Vehicles.scala | 1 - .../resourcesilo/ResourceSiloControl.scala | 2 - .../services/avatar/AvatarAction.scala | 2 +- .../avatar/support/CorpseRemovalActor.scala | 3 +- .../local/support/CaptureFlagManager.scala | 1 - .../local/support/HackCaptureActor.scala | 2 +- 21 files changed, 2391 insertions(+), 2480 deletions(-) create mode 100644 src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala create mode 100644 src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 578381968..9b83a7789 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.ZoningOperations +import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerLogic, HandlerFilter, ZoningOperations} import net.psforever.objects.TurretDeployable import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.containable.Containable @@ -108,6 +108,21 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con private[this] var mode: PlayerMode = NormalMode private[this] var logic: ModeLogic = _ + private val commonHandlerLogic: CommonHandlerLogic = new CommonHandlerLogic(data, context) + private def listOfHandlers: Seq[CommonHandlerFunctions] = { + if (logic == null) { + List.empty + } else { + List( + logic.avatarResponse, + logic.local, + logic.vehicleResponse, + logic.galaxy, + commonHandlerLogic + ) + } + } + override def postStop(): Unit = { clientKeepAlive.cancel() data.stop() @@ -175,21 +190,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con logic.squad.handle(reply, excluded) case envelope: GenericResponseEnvelope => - val GenericResponseEnvelope(toChannel, guid, reply) = envelope - envelope.stamp match { - case AvatarStamp => - logic.avatarResponse.handle(toChannel, guid, reply) - case LocalStamp => - logic.local.handle(toChannel, guid, reply) - case VehicleStamp => - logic.vehicleResponse.handle(toChannel, guid, reply) - case GalaxyStamp => - logic.galaxy.handle(reply) - case Undelivered => - log.error(s"received a message's response that was not delivered by an event system - $reply") - case unknownStamp => - log.error(s"received a message's response from an unknown event system - stamp: $unknownStamp") - } + handleGenericResponseEnvelope(envelope) case Mountable.MountMessages(tplayer, reply) => logic.mountResponse.handle(tplayer, reply) @@ -375,6 +376,43 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con logic.general.handleReceiveDefaultMessage(default, sender) } + 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 { + case Undelivered => + log.error(s"received a message's response that was not processed by an event system - $reply") + CommonHandlerFunctions.HandleAnything + case AvatarStamp => + logic.avatarResponse + case LocalStamp => + logic.local + case VehicleStamp => + logic.vehicleResponse + case GalaxyStamp => + logic.galaxy + case unknownStamp => + log.error(s"received a message's response from an unknown event system - stamp: $unknownStamp") + CommonHandlerFunctions.HandleNothing + } + //try the handler on the input message + lazy val alwaysAllowFilter = HandlerFilter.Allow(guid) + if (primaryHandler.handleWith(guid).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(guid).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 handleGamePkt: PlanetSideGamePacket => Unit = { case packet: ConnectToWorldRequestMessage => logic.general.handleConnectToWorldRequest(packet) 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 1ef36f908..0b8cbc2fd 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -1,6 +1,7 @@ // Copyright (c) 2024 PSForever package net.psforever.actors.session.csr +import akka.actor.Actor.Receive import akka.actor.{ActorContext, typed} import net.psforever.actors.session.SessionActor import net.psforever.actors.session.normal.NormalMode @@ -11,10 +12,10 @@ import net.psforever.objects.inventory.Container import net.psforever.objects.serverobject.containable.ContainableBehavior import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.vital.RevivingActivity -import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, HitHint, ImplantAction} +import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction} import net.psforever.services.avatar.{AvatarAction, AvatarStamp} import net.psforever.services.base.envelope.GenericResponseEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, ReloadTool, WeaponDryFire} import net.psforever.types.ImplantType // @@ -27,7 +28,7 @@ import net.psforever.objects.inventory.InventoryItem import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.packet.game.{ArmorChangedMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} +import net.psforever.packet.game.{ArmorChangedMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, UseItemMessage, WeaponDryFireMessage} import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -43,538 +44,500 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor - /** - * na - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - val resolvedPlayerGuid = if (player != null && player.HasGUID) { - player.GUID - } else { - Service.defaultPlayerGUID - } - val isNotSameTarget = resolvedPlayerGuid != guid - val isSameTarget = !isNotSameTarget - reply match { - /* special messages */ - case AvatarAction.TeardownConnection() if player.spectator => - context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) - context.self.forward(GenericResponseEnvelope(AvatarStamp, toChannel, guid, reply)) + private var tempGuid: PlanetSideGUID = Service.defaultPlayerGUID - case AvatarAction.TeardownConnection() => - context.self ! SessionActor.SetMode(NormalMode) - context.self.forward(GenericResponseEnvelope(AvatarStamp, toChannel, guid, reply)) + override def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { + tempGuid = guid + super.handle(toChannel, guid, reply) + } - /* really common messages (very frequently, every life) */ - case pstate @ AvatarAction.PlayerState( - pos, - vel, - yaw, - pitch, - yawUpper, - _, - isCrouching, - isJumping, - jumpThrust, - isCloaking, - isNotRendered, - canSeeReallyFar - ) if isNotSameTarget => - val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(guid.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) - } - val drawConfig = Config.app.game.playerDraw //m - val maxRange = drawConfig.rangeMax * drawConfig.rangeMax //sq.m - val ourPosition = player.Position //xyz - val currentDistance = Vector3.DistanceSquared(ourPosition, pos) //sq.m - val inDrawableRange = currentDistance <= maxRange - val now = System.currentTimeMillis() //ms - if ( - sessionLogic.zoning.zoningStatus != Zoning.Status.Deconstructing && - !isNotRendered && inDrawableRange + override def handleWith(guid: PlanetSideGUID): Receive = { + tempGuid = guid + super.handleWith(guid) + } + + def receive: Receive = { + /* special messages */ + case AvatarAction.TeardownConnection if player.spectator => + context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) + context.self.forward(GenericResponseEnvelope(AvatarStamp, "", tempGuid, AvatarAction.TeardownConnection)) + + case AvatarAction.TeardownConnection => + context.self ! SessionActor.SetMode(NormalMode) + context.self.forward(GenericResponseEnvelope(AvatarStamp, "", tempGuid, AvatarAction.TeardownConnection)) + + /* really common messages (very frequently, every life) */ + case pstate @ AvatarAction.PlayerState( + pos, + vel, + yaw, + pitch, + yawUpper, + _, + isCrouching, + isJumping, + jumpThrust, + isCloaking, + isNotRendered, + canSeeReallyFar + ) if filter.isNotSameTarget => + val pstateToSave = pstate.copy(timestamp = 0) + val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.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) + } + val drawConfig = Config.app.game.playerDraw //m + val maxRange = drawConfig.rangeMax * drawConfig.rangeMax //sq.m + val ourPosition = player.Position //xyz + val currentDistance = Vector3.DistanceSquared(ourPosition, pos) //sq.m + val inDrawableRange = currentDistance <= maxRange + val now = System.currentTimeMillis() //ms + if ( + sessionLogic.zoning.zoningStatus != Zoning.Status.Deconstructing && + !isNotRendered && inDrawableRange + ) { + //conditions where visibility is assured + val durationSince = now - lastTime //ms + lazy val previouslyInDrawableRange = Vector3.DistanceSquared(ourPosition, lastPosition) <= maxRange + lazy val targetDelay = { + val populationOver = math.max( + 0, + sessionLogic.localSector.livePlayerList.size - drawConfig.populationThreshold + ) + val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m + val adjustedDistance = currentDistance + distanceAdjustment //sq.m + drawConfig.ranges.lastIndexWhere { dist => adjustedDistance > dist * dist } match { + case -1 => 1 + case index => drawConfig.delays(index) + } + } //ms + if (!wasVisible || + !previouslyInDrawableRange || + durationSince > drawConfig.delayMax || + (!lastMsg.contains(pstateToSave) && + (canSeeReallyFar || + currentDistance < drawConfig.rangeMin * drawConfig.rangeMin || + sessionLogic.general.canSeeReallyFar || + durationSince > targetDelay + ) + ) ) { - //conditions where visibility is assured - val durationSince = now - lastTime //ms - lazy val previouslyInDrawableRange = Vector3.DistanceSquared(ourPosition, lastPosition) <= maxRange - lazy val targetDelay = { - val populationOver = math.max( - 0, - sessionLogic.localSector.livePlayerList.size - drawConfig.populationThreshold + //must draw + sendResponse( + PlayerStateMessage( + filter.resolvedPlayerGuid, + pos, + vel, + yaw, + pitch, + yawUpper, + timestamp = 0, //is this okay? + isCrouching, + isJumping, + jumpThrust, + isCloaking ) - val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m - val adjustedDistance = currentDistance + distanceAdjustment //sq.m - drawConfig.ranges.lastIndexWhere { dist => adjustedDistance > dist * dist } match { - case -1 => 1 - case index => drawConfig.delays(index) - } - } //ms - if (!wasVisible || - !previouslyInDrawableRange || - durationSince > drawConfig.delayMax || - (!lastMsg.contains(pstateToSave) && - (canSeeReallyFar || - currentDistance < drawConfig.rangeMin * drawConfig.rangeMin || - sessionLogic.general.canSeeReallyFar || - durationSince > targetDelay - ) - ) - ) { - //must draw - sendResponse( - PlayerStateMessage( - guid, - pos, - vel, - yaw, - pitch, - yawUpper, - timestamp = 0, //is this okay? - isCrouching, - isJumping, - jumpThrust, - isCloaking - ) - ) - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) - } else { - //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) - } + ) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { - //conditions where the target is not currently visible - if (wasVisible) { - //the target was JUST PREVIOUSLY visible; one last draw to move target beyond a renderable distance - val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat - sendResponse( - PlayerStateMessage( - guid, - Vector3(1f, lat, 1f), - vel=None, - facingYaw=0f, - facingPitch=0f, - facingYawUpper=0f, - timestamp=0, //is this okay? - is_cloaked = isCloaking - ) + //is visible, but skip reinforcement + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + } + } else { + //conditions where the target is not currently visible + if (wasVisible) { + //the target was JUST PREVIOUSLY visible; one last draw to move target beyond a renderable distance + val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat + sendResponse( + PlayerStateMessage( + filter.resolvedPlayerGuid, + Vector3(1f, lat, 1f), + vel=None, + facingYaw=0f, + facingPitch=0f, + facingYawUpper=0f, + timestamp=0, //is this okay? + is_cloaked = isCloaking ) - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) - } else { - //skip drawing altogether - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) - } + ) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + } else { + //skip drawing altogether + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + } + } + + case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) + if value == ImplantType.SecondWind.value => + sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, ImplantAction.Add, implant_slot, 7)) + //second wind does not normally load its icon into the shortcut hotbar + avatar + .shortcuts + .zipWithIndex + .find { case (s, _) => s.isEmpty} + .foreach { case (_, index) => + sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } - case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) - if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Add, implant_slot, 7)) - //second wind does not normally load its icon into the shortcut hotbar - avatar - .shortcuts - .zipWithIndex - .find { case (s, _) => s.isEmpty} - .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) - } - - case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) - if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Remove, implant_slot, value)) - //second wind does not normally unload its icon from the shortcut hotbar - val shortcut = { - val imp = ImplantType.SecondWind.shortcut - net.psforever.objects.avatar.Shortcut(imp.code, imp.tile) //case class - } - avatar - .shortcuts - .zipWithIndex - .find { case (s, _) => s.contains(shortcut) } - .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, None)) - } - - case AvatarAction.AvatarImplant(action, implant_slot, value) => - sendResponse(AvatarImplantMessage(resolvedPlayerGuid, action, implant_slot, value)) - - case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(guid, 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) - } - if (sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing) { - sessionLogic.zoning.spawn.stopDeconstructing() + case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) + if value == ImplantType.SecondWind.value => + sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, ImplantAction.Remove, implant_slot, value)) + //second wind does not normally unload its icon from the shortcut hotbar + val shortcut = { + val imp = ImplantType.SecondWind.shortcut + net.psforever.objects.avatar.Shortcut(imp.code, imp.tile) //case class + } + avatar + .shortcuts + .zipWithIndex + .find { case (s, _) => s.contains(shortcut) } + .foreach { case (_, index) => + sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, None)) } - case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) + case AvatarAction.AvatarImplant(action, implant_slot, value) => + sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, action, implant_slot, value)) - case AvatarAction.ObjectHeld(_, _) - if isSameTarget => () + case AvatarAction.ObjectHeld(slot, _) + if filter.isSameTarget && player.VisibleSlots.contains(slot) => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, 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) + } + if (sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing) { + sessionLogic.zoning.spawn.stopDeconstructing() + } - case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) + case AvatarAction.ObjectHeld(slot, _) + if filter.isSameTarget && slot > -1 => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) - case ChangeFireState_Start(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(guid.guid) - ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) + case AvatarAction.ObjectHeld(_, _) + if filter.isSameTarget => () - case ChangeFireState_Start(weaponGuid) - if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + case AvatarAction.ObjectHeld(_, previousSlot) => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, previousSlot, unk1=false)) - case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(guid.guid) - ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) + case ChangeFireState_Start(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = Some(weaponGuid))) - case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + case ChangeFireState_Stop(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => - sendResponse(pkt) + case AvatarAction.LoadCreatedPlayer(pkt) if filter.isNotSameTarget => + sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => - sendResponse(pkt) + case AvatarAction.EquipmentCreatedInHand(pkt) if filter.isNotSameTarget => + sendResponse(pkt) - case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) + case AvatarAction.Destroy(victim, killer, weapon, pos) => + // guid = victim // killer = killer + sendResponse(DestroyMessage(victim, killer, weapon, pos)) - case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) + case AvatarAction.DestroyDisplay(killer, victim, method, unk) => + sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - case HintsAtAttacker(sourceGuid) if player.isAlive => - sendResponse(HitHint(sourceGuid, guid)) - sessionLogic.zoning.CancelZoningProcess() + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) + if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => + sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) + sessionLogic.terminals.lastTerminalOrderFulfillment = true + AvatarActor.savePlayerData(player) - case AvatarAction.Destroy(victim, killer, weapon, pos) => - // guid = victim // killer = killer - sendResponse(DestroyMessage(victim, killer, weapon, pos)) + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => + sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) + sessionLogic.terminals.lastTerminalOrderFulfillment = true - case AvatarAction.DestroyDisplay(killer, victim, method, unk) => - sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - - case AvatarAction.TerminalOrderResult(terminalGuid, action, result) - if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => - sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) - sessionLogic.terminals.lastTerminalOrderFulfillment = true - AvatarActor.savePlayerData(player) - - case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => - sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) - sessionLogic.terminals.lastTerminalOrderFulfillment = true - - case AvatarAction.ChangeExosuit( - target, - armor, - exosuit, - subtype, - _, - maxhand, - oldHolsters, - holsters, - oldInventory, - inventory, - drop, - delete - ) if resolvedPlayerGuid == target => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to this player - //cleanup - sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=false)) - (oldHolsters ++ oldInventory ++ delete).foreach { - case (_, dguid) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - } - //functionally delete - delete.foreach { case (obj, _) => TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } - //redraw - if (maxhand) { - TaskWorkflow.execute(HoldNewEquipmentUp(player)( - Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), - 0 - )) - } - //draw free hand - player.FreeHand.Equipment.foreach { obj => + case AvatarAction.ChangeExosuit( + target, + armor, + exosuit, + subtype, + _, + maxhand, + oldHolsters, + holsters, + oldInventory, + inventory, + drop, + delete + ) if filter.resolvedPlayerGuid == target => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to this player + //cleanup + sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=false)) + (oldHolsters ++ oldInventory ++ delete).foreach { + case (_, dguid) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + } + //functionally delete + delete.foreach { case (obj, _) => TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } + //redraw + if (maxhand) { + TaskWorkflow.execute(HoldNewEquipmentUp(player)( + Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), + 0 + )) + } + //draw free hand + player.FreeHand.Equipment.foreach { obj => + val definition = obj.Definition + sendResponse( + ObjectCreateDetailedMessage( + definition.ObjectId, + obj.GUID, + ObjectCreateMessageParent(target, Player.FreeHandSlot), + definition.Packet.DetailedConstructorData(obj).get + ) + ) + } + //draw holsters and inventory + (holsters ++ inventory).foreach { + case InventoryItem(obj, index) => val definition = obj.Definition sendResponse( ObjectCreateDetailedMessage( definition.ObjectId, obj.GUID, - ObjectCreateMessageParent(target, Player.FreeHandSlot), + ObjectCreateMessageParent(target, index), definition.Packet.DetailedConstructorData(obj).get ) ) - } - //draw holsters and inventory - (holsters ++ inventory).foreach { - case InventoryItem(obj, index) => - val definition = obj.Definition - sendResponse( - ObjectCreateDetailedMessage( - definition.ObjectId, - obj.GUID, - ObjectCreateMessageParent(target, index), - definition.Packet.DetailedConstructorData(obj).get - ) + } + DropLeftovers(player)(drop) + + case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to some other player + sendResponse(ObjectHeldMessage(target, slot, unk1 = false)) + //cleanup + val dropPred = ContainableBehavior.DropPredicate(player) + val deleteFromDrop = drop.filterNot(dropPred) + (oldHolsters ++ delete ++ deleteFromDrop.map(f =>(f.obj, f.GUID))) + .distinctBy(_._2) + .foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } + //draw holsters + holsters.foreach { + case InventoryItem(obj, index) => + val definition = obj.Definition + sendResponse( + ObjectCreateMessage( + definition.ObjectId, + obj.GUID, + ObjectCreateMessageParent(target, index), + definition.Packet.ConstructorData(obj).get ) - } - DropLeftovers(player)(drop) - - case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to some other player - sendResponse(ObjectHeldMessage(target, slot, unk1 = false)) - //cleanup - val dropPred = ContainableBehavior.DropPredicate(player) - val deleteFromDrop = drop.filterNot(dropPred) - (oldHolsters ++ delete ++ deleteFromDrop.map(f =>(f.obj, f.GUID))) - .distinctBy(_._2) - .foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - //draw holsters - holsters.foreach { - case InventoryItem(obj, index) => - val definition = obj.Definition - sendResponse( - ObjectCreateMessage( - definition.ObjectId, - obj.GUID, - ObjectCreateMessageParent(target, index), - definition.Packet.ConstructorData(obj).get - ) - ) - } - - case AvatarAction.ChangeLoadout( - target, - armor, - exosuit, - subtype, - _, - maxhand, - oldHolsters, - holsters, - oldInventory, - inventory, - drops - ) if resolvedPlayerGuid == target => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to this player - sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=true)) - //cleanup - (oldHolsters ++ oldInventory).foreach { - case (obj, objGuid) => - sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) - TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) - } - drops.foreach(item => sendResponse(ObjectDeleteMessage(item.obj.GUID, unk1=0))) - //redraw - if (maxhand) { - sendResponse(PlanetsideAttributeMessage(target, attribute_type=7, player.Capacitor.toLong)) - TaskWorkflow.execute(HoldNewEquipmentUp(player)( - Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), - slot = 0 - )) - } - (holsters ++ inventory).foreach { case InventoryItem(item, slot) => - TaskWorkflow.execute(PutLoadoutEquipmentInInventory(player)(item, slot)) - } - DropLeftovers(player)(drops) - - case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => - //redraw handled by callbacks - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to some other player - sendResponse(ObjectHeldMessage(target, slot, unk1=false)) - //cleanup - oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - - case AvatarAction.UseKit(kguid, kObjId) => - sendResponse( - UseItemMessage( - resolvedPlayerGuid, - kguid, - resolvedPlayerGuid, - unk2 = 4294967295L, - unk3 = false, - unk4 = Vector3.Zero, - unk5 = Vector3.Zero, - unk6 = 126, - unk7 = 0, //sequence time? - unk8 = 137, - kObjId ) - ) - sendResponse(ObjectDeleteMessage(kguid, unk1=0)) + } - case AvatarAction.KitNotUsed(_, "") => - sessionLogic.general.kitToBeUsed = None - - case AvatarAction.KitNotUsed(_, msg) => - sessionLogic.general.kitToBeUsed = None - sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - - case SendResponse(msgs) => - msgs.foreach(sendResponse) - - /* common messages (maybe once every respawn) */ - case ReloadTool(itemGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => - sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - - case AvatarAction.Killed(_, mount) => - //pure logic - sessionLogic.shooting.shotsWhileDead = 0 - sessionLogic.zoning.CancelZoningProcess() - sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive - sessionLogic.zoning.zoningStatus = Zoning.Status.None - continent.GUID(mount).collect { - case obj: Vehicle if obj.Destroyed => - ops.killedWhileMounted(obj, resolvedPlayerGuid) - sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) - sessionLogic.general.unaccessContainer(obj) - - case obj: Vehicle => - ops.killedWhileMounted(obj, resolvedPlayerGuid) - sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) - - case obj: PlanetSideGameObject with Mountable with Container if obj.Destroyed => - ops.killedWhileMounted(obj, resolvedPlayerGuid) - sessionLogic.general.unaccessContainer(obj) - - case obj: PlanetSideGameObject with Mountable with Container => - ops.killedWhileMounted(obj, resolvedPlayerGuid) - - case obj: PlanetSideGameObject with Mountable => - ops.killedWhileMounted(obj, resolvedPlayerGuid) - } - //player state changes - sessionLogic.general.dropSpecialSlotItem() - sessionLogic.general.toggleMaxSpecialState(enable = false) - player.FreeHand.Equipment.foreach(DropEquipmentFromInventory(player)(_)) - AvatarActor.updateToolDischargeFor(avatar) - AvatarActor.savePlayerLocation(player) - ops.revive() - avatarActor ! AvatarActor.InitializeImplants - //render - CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) - - case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => - sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - - case AvatarAction.Revive(revivalTargetGuid) - if resolvedPlayerGuid == revivalTargetGuid => - ops.revive() - player.Actor ! Player.Revive - player.History - .findLast { _.isInstanceOf[RevivingActivity] } - .map { - case activity: RevivingActivity - if System.currentTimeMillis() - activity.time < 5000L => - val reviveMessage = s"@YouHaveBeenMessage^revived~^${activity.user.unique.name}~" - sendResponse(ChatMsg(ChatMessageType.UNK_227, reviveMessage)) - None - } - - /* 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(guid.guid).exists { _.visible } => - ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - - case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if isNotSameTarget => - ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - - case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => - sendResponse(ChangeFireModeMessage(itemGuid, mode)) - - case ConcealPlayer(_) => - sendResponse(GenericObjectActionMessage(guid, code=9)) - - case AvatarAction.EnvironmentalDamage(_, _, _) => - //TODO damage marker? - sessionLogic.zoning.CancelZoningProcess() - - case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => - sendResponse(pkt) - - case ObjectDelete(itemGuid, unk) if isNotSameTarget => - sendResponse(ObjectDeleteMessage(itemGuid, unk)) - - /* rare messages */ - case SetEmpire(objectGuid, faction) if isNotSameTarget => - sendResponse(SetEmpireMessage(objectGuid, faction)) - - case AvatarAction.DropSpecialItem() => - sessionLogic.general.dropSpecialSlotItem() - - case AvatarAction.OxygenState(player, vehicle) => - sendResponse(OxygenStateMessage( - DrowningTarget(player.guid, player.progress, player.state), - vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } + case AvatarAction.ChangeLoadout( + target, + armor, + exosuit, + subtype, + _, + maxhand, + oldHolsters, + holsters, + oldInventory, + inventory, + drops + ) if filter.resolvedPlayerGuid == target => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to this player + sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=true)) + //cleanup + (oldHolsters ++ oldInventory).foreach { + case (obj, objGuid) => + sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) + TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) + } + drops.foreach(item => sendResponse(ObjectDeleteMessage(item.obj.GUID, unk1=0))) + //redraw + if (maxhand) { + sendResponse(PlanetsideAttributeMessage(target, attribute_type=7, player.Capacitor.toLong)) + TaskWorkflow.execute(HoldNewEquipmentUp(player)( + Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), + slot = 0 )) + } + (holsters ++ inventory).foreach { case InventoryItem(item, slot) => + TaskWorkflow.execute(PutLoadoutEquipmentInInventory(player)(item, slot)) + } + DropLeftovers(player)(drops) - case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => - sendResponse(pkt) + case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => + //redraw handled by callbacks + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to some other player + sendResponse(ObjectHeldMessage(target, slot, unk1=false)) + //cleanup + oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => - sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) - - case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => - sendResponse( - ProjectileStateMessage( - projectileGuid, - projectile.Position, - shot_vel = Vector3.Zero, - projectile.Orientation, - sequence_num=0, - end=true, - hit_target_guid=PlanetSideGUID(0) - ) + case AvatarAction.UseKit(kguid, kObjId) => + sendResponse( + UseItemMessage( + filter.resolvedPlayerGuid, + kguid, + filter.resolvedPlayerGuid, + unk2 = 4294967295L, + unk3 = false, + unk4 = Vector3.Zero, + unk5 = Vector3.Zero, + unk6 = 126, + unk7 = 0, //sequence time? + unk8 = 137, + kObjId ) - sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) + ) + sendResponse(ObjectDeleteMessage(kguid, unk1=0)) - case AvatarAction.ProjectileAutoLockAwareness(mode) => - sendResponse(GenericActionMessage(mode)) + case AvatarAction.KitNotUsed(_, "") => + sessionLogic.general.kitToBeUsed = None - case AvatarAction.PutDownFDU(target) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(target, code=53)) + case AvatarAction.KitNotUsed(_, msg) => + sessionLogic.general.kitToBeUsed = None + sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => - val definition = item.Definition - sendResponse( - ObjectCreateDetailedMessage( - definition.ObjectId, - item.GUID, - ObjectCreateMessageParent(target, slot), - definition.Packet.DetailedConstructorData(item).get - ) - ) - case WeaponDryFire(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.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)) + /* common messages (maybe once every respawn) */ + case ReloadTool(itemGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) + + case AvatarAction.Killed(_, mount) => + //pure logic + sessionLogic.shooting.shotsWhileDead = 0 + sessionLogic.zoning.CancelZoningProcess() + sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive + sessionLogic.zoning.zoningStatus = Zoning.Status.None + continent.GUID(mount).collect { + case obj: Vehicle if obj.Destroyed => + ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) + sessionLogic.general.unaccessContainer(obj) + + case obj: Vehicle => + ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) + + case obj: PlanetSideGameObject with Mountable with Container if obj.Destroyed => + ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + sessionLogic.general.unaccessContainer(obj) + + case obj: PlanetSideGameObject with Mountable with Container => + ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + + case obj: PlanetSideGameObject with Mountable => + ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + } + //player state changes + sessionLogic.general.dropSpecialSlotItem() + sessionLogic.general.toggleMaxSpecialState(enable = false) + player.FreeHand.Equipment.foreach(DropEquipmentFromInventory(player)(_)) + AvatarActor.updateToolDischargeFor(avatar) + AvatarActor.savePlayerLocation(player) + ops.revive() + avatarActor ! AvatarActor.InitializeImplants + //render + CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) + + case AvatarAction.ReleasePlayer(tplayer) if filter.isNotSameTarget => + sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) + + case AvatarAction.Revive(revivalTargetGuid) + if filter.resolvedPlayerGuid == revivalTargetGuid => + ops.revive() + player.Actor ! Player.Revive + player.History + .findLast { _.isInstanceOf[RevivingActivity] } + .map { + case activity: RevivingActivity + if System.currentTimeMillis() - activity.time < 5000L => + val reviveMessage = s"@YouHaveBeenMessage^revived~^${activity.user.unique.name}~" + sendResponse(ChatMsg(ChatMessageType.UNK_227, reviveMessage)) + None } - case _ => () - } + /* uncommon messages (utility, or once in a while) */ + case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + 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 filter.isNotSameTarget => + sendResponse(ChangeFireModeMessage(itemGuid, mode)) + + case AvatarAction.EnvironmentalDamage(_, _, _) => + //TODO damage marker? + sessionLogic.zoning.CancelZoningProcess() + + case AvatarAction.DropCreatedItem(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + /* rare messages */ + case AvatarAction.DropSpecialItem() => + sessionLogic.general.dropSpecialSlotItem() + + case AvatarAction.OxygenState(player, vehicle) => + sendResponse(OxygenStateMessage( + DrowningTarget(player.guid, player.progress, player.state), + vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } + )) + + case AvatarAction.LoadCreatedProjectile(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if filter.isNotSameTarget => + sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) + + case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => + sendResponse( + ProjectileStateMessage( + projectileGuid, + projectile.Position, + shot_vel = Vector3.Zero, + projectile.Orientation, + sequence_num=0, + end=true, + hit_target_guid=PlanetSideGUID(0) + ) + ) + sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) + + case AvatarAction.ProjectileAutoLockAwareness(mode) => + sendResponse(GenericActionMessage(mode)) + + case AvatarAction.PutDownFDU(target) if filter.isNotSameTarget => + sendResponse(GenericObjectActionMessage(target, code=53)) + + case AvatarAction.StowEquipment(target, slot, item) if filter.isNotSameTarget => + val definition = item.Definition + sendResponse( + ObjectCreateDetailedMessage( + definition.ObjectId, + item.GUID, + ObjectCreateMessageParent(target, slot), + definition.Packet.DetailedConstructorData(item).get + ) + ) + + case WeaponDryFire(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.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 b5f188066..25c318c3d 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -1,6 +1,7 @@ // Copyright (c) 2024 PSForever package net.psforever.actors.session.normal +import akka.actor.Actor.Receive import akka.actor.{ActorContext, typed} import net.psforever.actors.session.support.AvatarHandlerFunctions import net.psforever.actors.zone.ZoneActor @@ -14,7 +15,7 @@ import net.psforever.objects.vital.interaction.Adversarial import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction, PlanetsideStringAttributeMessage} import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire} import net.psforever.types.ImplantType import scala.concurrent.duration._ @@ -30,8 +31,7 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.vital.etc.ExplodingEntityReason import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} -import net.psforever.services.Service +import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, UseItemMessage, WeaponDryFireMessage} import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -46,644 +46,593 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor - /** - * na - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - val resolvedPlayerGuid = if (player != null && player.HasGUID) { - player.GUID - } else { - Service.defaultPlayerGUID - } - val isNotSameTarget = resolvedPlayerGuid != guid - val isSameTarget = !isNotSameTarget - reply match { - /* special messages */ - case AvatarAction.TeardownConnection() => - log.trace(s"ending ${player.Name}'s old session by event system request (relog)") - context.stop(context.self) + def receive: Receive = { + /* special messages */ + case AvatarAction.TeardownConnection => + log.trace(s"ending ${player.Name}'s old session by event system request (relog)") + context.stop(context.self) - /* really common messages (very frequently, every life) */ - case pstate @ AvatarAction.PlayerState( - pos, - vel, - yaw, - pitch, - yawUpper, - _, - isCrouching, - isJumping, - jumpThrust, - isCloaking, - isNotRendered, - canSeeReallyFar - ) if isNotSameTarget => - val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(guid.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) - } - val drawConfig = Config.app.game.playerDraw //m - val maxRange = drawConfig.rangeMax * drawConfig.rangeMax //sq.m - val ourPosition = player.Position //xyz - val currentDistance = Vector3.DistanceSquared(ourPosition, pos) //sq.m - val inDrawableRange = currentDistance <= maxRange - val now = System.currentTimeMillis() //ms - if ( - sessionLogic.zoning.zoningStatus != Zoning.Status.Deconstructing && - !isNotRendered && inDrawableRange + /* really common messages (very frequently, every life) */ + case pstate @ AvatarAction.PlayerState( + pos, + vel, + yaw, + pitch, + yawUpper, + _, + isCrouching, + isJumping, + jumpThrust, + isCloaking, + isNotRendered, + canSeeReallyFar + ) if filter.isNotSameTarget => + val pstateToSave = pstate.copy(timestamp = 0) + val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.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) + } + val drawConfig = Config.app.game.playerDraw //m + val maxRange = drawConfig.rangeMax * drawConfig.rangeMax //sq.m + val ourPosition = player.Position //xyz + val currentDistance = Vector3.DistanceSquared(ourPosition, pos) //sq.m + val inDrawableRange = currentDistance <= maxRange + val now = System.currentTimeMillis() //ms + if ( + sessionLogic.zoning.zoningStatus != Zoning.Status.Deconstructing && + !isNotRendered && inDrawableRange + ) { + //conditions where visibility is assured + val durationSince = now - lastTime //ms + lazy val previouslyInDrawableRange = Vector3.DistanceSquared(ourPosition, lastPosition) <= maxRange + lazy val targetDelay = { + val populationOver = math.max( + 0, + sessionLogic.localSector.livePlayerList.size - drawConfig.populationThreshold + ) + val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m + val adjustedDistance = currentDistance + distanceAdjustment //sq.m + drawConfig.ranges.lastIndexWhere { dist => adjustedDistance > dist * dist } match { + case -1 => 1 + case index => drawConfig.delays(index) + } + } //ms + if (!wasVisible || + !previouslyInDrawableRange || + durationSince > drawConfig.delayMax || + (!lastMsg.contains(pstateToSave) && + (canSeeReallyFar || + currentDistance < drawConfig.rangeMin * drawConfig.rangeMin || + sessionLogic.general.canSeeReallyFar || + durationSince > targetDelay + ) + ) ) { - //conditions where visibility is assured - val durationSince = now - lastTime //ms - lazy val previouslyInDrawableRange = Vector3.DistanceSquared(ourPosition, lastPosition) <= maxRange - lazy val targetDelay = { - val populationOver = math.max( - 0, - sessionLogic.localSector.livePlayerList.size - drawConfig.populationThreshold + //must draw + sendResponse( + PlayerStateMessage( + filter.resolvedPlayerGuid, + pos, + vel, + yaw, + pitch, + yawUpper, + timestamp = 0, //is this okay? + isCrouching, + isJumping, + jumpThrust, + isCloaking ) - val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m - val adjustedDistance = currentDistance + distanceAdjustment //sq.m - drawConfig.ranges.lastIndexWhere { dist => adjustedDistance > dist * dist } match { - case -1 => 1 - case index => drawConfig.delays(index) - } - } //ms - if (!wasVisible || - !previouslyInDrawableRange || - durationSince > drawConfig.delayMax || - (!lastMsg.contains(pstateToSave) && - (canSeeReallyFar || - currentDistance < drawConfig.rangeMin * drawConfig.rangeMin || - sessionLogic.general.canSeeReallyFar || - durationSince > targetDelay - ) - ) - ) { - //must draw - sendResponse( - PlayerStateMessage( - guid, - pos, - vel, - yaw, - pitch, - yawUpper, - timestamp = 0, //is this okay? - isCrouching, - isJumping, - jumpThrust, - isCloaking - ) - ) - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) - } else { - //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) - } + ) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { - //conditions where the target is not currently visible - if (wasVisible) { - //the target was JUST PREVIOUSLY visible; one last draw to move target beyond a renderable distance - val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat - sendResponse( - PlayerStateMessage( - guid, - Vector3(1f, lat, 1f), - vel=None, - facingYaw=0f, - facingPitch=0f, - facingYawUpper=0f, - timestamp=0, //is this okay? - is_cloaked = isCloaking - ) + //is visible, but skip reinforcement + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + } + } else { + //conditions where the target is not currently visible + if (wasVisible) { + //the target was JUST PREVIOUSLY visible; one last draw to move target beyond a renderable distance + val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat + sendResponse( + PlayerStateMessage( + filter.resolvedPlayerGuid, + Vector3(1f, lat, 1f), + vel=None, + facingYaw=0f, + facingPitch=0f, + facingYawUpper=0f, + timestamp=0, //is this okay? + is_cloaked = isCloaking ) - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) - } else { - //skip drawing altogether - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + } else { + //skip drawing altogether + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + } + } + + case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) + if value == ImplantType.SecondWind.value => + sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, ImplantAction.Add, implant_slot, 7)) + //second wind does not normally load its icon into the shortcut hotbar + avatar + .shortcuts + .zipWithIndex + .find { case (s, _) => s.isEmpty} + .foreach { case (_, index) => + sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) + } + + case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) + if value == ImplantType.SecondWind.value => + sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, ImplantAction.Remove, implant_slot, value)) + //second wind does not normally unload its icon from the shortcut hotbar + val shortcut = { + val imp = ImplantType.SecondWind.shortcut + net.psforever.objects.avatar.Shortcut(imp.code, imp.tile) //case class + } + avatar + .shortcuts + .zipWithIndex + .find { case (s, _) => s.contains(shortcut) } + .foreach { case (_, index) => + sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, None)) + } + + case AvatarAction.AvatarImplant(action, implant_slot, value) => + sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, action, implant_slot, value)) + + case AvatarAction.ObjectHeld(slot, _) + if filter.isSameTarget && player.VisibleSlots.contains(slot) => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, 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) + } + if (sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing) { + sessionLogic.zoning.spawn.stopDeconstructing() + } + + case AvatarAction.ObjectHeld(slot, _) + if filter.isSameTarget && slot > -1 => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + + case AvatarAction.ObjectHeld(_, _) + if filter.isSameTarget => () + + case AvatarAction.ObjectHeld(_, previousSlot) => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, previousSlot, unk1=false)) + + case ChangeFireState_Start(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = Some(weaponGuid))) + + case ChangeFireState_Stop(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = None)) + + case AvatarAction.LoadCreatedPlayer(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case AvatarAction.EquipmentCreatedInHand(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => + sendResponse(PlanetsideStringAttributeMessage(filter.resolvedPlayerGuid, attributeType, attributeValue)) + + case AvatarAction.Destroy(victim, killer, weapon, pos) => + // guid = victim // killer = killer + sendResponse(DestroyMessage(victim, killer, weapon, pos)) + + case AvatarAction.DestroyDisplay(killer, victim, method, unk) => + sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) + + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) + if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => + sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) + sessionLogic.terminals.lastTerminalOrderFulfillment = true + AvatarActor.savePlayerData(player) + sessionLogic.general.renewCharSavedTimer( + Config.app.game.savedMsg.interruptedByAction.fixed, + Config.app.game.savedMsg.interruptedByAction.variable + ) + + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => + sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) + sessionLogic.terminals.lastTerminalOrderFulfillment = true + + case AvatarAction.ChangeExosuit( + target, + armor, + exosuit, + subtype, + _, + maxhand, + oldHolsters, + holsters, + oldInventory, + inventory, + drop, + delete + ) if filter.resolvedPlayerGuid == target => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to this player + //cleanup + sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=false)) + (oldHolsters ++ oldInventory ++ delete).foreach { + case (_, dguid) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + } + //functionally delete + if (delete.size > 1 || delete.nonEmpty && !delete.exists { + case (e: Tool, _) => GlobalDefinitions.isMaxArms(e.Definition) + case _ => false + }) { + /* + if going x -> max, you will have enough space in max inventory for any displaced holster equipment + for max -> max, don't care about the max weapon arm being deleted (allow for 1) + for any other x -> x, any deleted equipment will raise this comment + */ + sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ItemsDeconstructed")) + } + delete.foreach { case (obj, _) => TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } + //redraw + if (maxhand) { + sendResponse(PlanetsideAttributeMessage(target, attribute_type=7, player.Capacitor.toLong)) + val maxArmDefinition = GlobalDefinitions.MAXArms(subtype, player.Faction) + TaskWorkflow.execute(HoldNewEquipmentUp(player)(Tool(maxArmDefinition), slot = 0)) + player.avatar.purchaseCooldown(maxArmDefinition) + .collect(a => a) + .getOrElse { + avatarActor ! AvatarActor.UpdatePurchaseTime(maxArmDefinition) + None } - } - - case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) - if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Add, implant_slot, 7)) - //second wind does not normally load its icon into the shortcut hotbar - avatar - .shortcuts - .zipWithIndex - .find { case (s, _) => s.isEmpty} - .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) - } - - case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) - if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(resolvedPlayerGuid, ImplantAction.Remove, implant_slot, value)) - //second wind does not normally unload its icon from the shortcut hotbar - val shortcut = { - val imp = ImplantType.SecondWind.shortcut - net.psforever.objects.avatar.Shortcut(imp.code, imp.tile) //case class - } - avatar - .shortcuts - .zipWithIndex - .find { case (s, _) => s.contains(shortcut) } - .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedPlayerGuid, index + 1, None)) - } - - case AvatarAction.AvatarImplant(action, implant_slot, value) => - sendResponse(AvatarImplantMessage(resolvedPlayerGuid, action, implant_slot, value)) - - case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(guid, 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) - } - if (sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing) { - sessionLogic.zoning.spawn.stopDeconstructing() - } - - case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) - - case AvatarAction.ObjectHeld(_, _) - if isSameTarget => () - - case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) - - case ChangeFireState_Start(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(guid.guid) - ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) - - case ChangeFireState_Start(weaponGuid) - if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - - case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(guid.guid) - ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) - - case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - - case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => - sendResponse(pkt) - - case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => - sendResponse(pkt) - - case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) - - case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => - sendResponse(PlanetsideStringAttributeMessage(guid, attributeType, attributeValue)) - - case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) - - case HintsAtAttacker(sourceGuid) if player.isAlive => - sendResponse(HitHint(sourceGuid, guid)) - sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") - - case AvatarAction.Destroy(victim, killer, weapon, pos) => - // guid = victim // killer = killer - sendResponse(DestroyMessage(victim, killer, weapon, pos)) - - case AvatarAction.DestroyDisplay(killer, victim, method, unk) => - sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - - case AvatarAction.TerminalOrderResult(terminalGuid, action, result) - if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => - sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) - sessionLogic.terminals.lastTerminalOrderFulfillment = true - AvatarActor.savePlayerData(player) - sessionLogic.general.renewCharSavedTimer( - Config.app.game.savedMsg.interruptedByAction.fixed, - Config.app.game.savedMsg.interruptedByAction.variable + } + //draw free hand + player.FreeHand.Equipment.foreach { obj => + val definition = obj.Definition + sendResponse( + ObjectCreateDetailedMessage( + definition.ObjectId, + obj.GUID, + ObjectCreateMessageParent(target, Player.FreeHandSlot), + definition.Packet.DetailedConstructorData(obj).get + ) ) - - case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => - sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) - sessionLogic.terminals.lastTerminalOrderFulfillment = true - - case AvatarAction.ChangeExosuit( - target, - armor, - exosuit, - subtype, - _, - maxhand, - oldHolsters, - holsters, - oldInventory, - inventory, - drop, - delete - ) if resolvedPlayerGuid == target => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to this player - //cleanup - sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=false)) - (oldHolsters ++ oldInventory ++ delete).foreach { - case (_, dguid) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - } - //functionally delete - if (delete.size > 1 || delete.nonEmpty && !delete.exists { - case (e: Tool, _) => GlobalDefinitions.isMaxArms(e.Definition) - case _ => false - }) { - /* - if going x -> max, you will have enough space in max inventory for any displaced holster equipment - for max -> max, don't care about the max weapon arm being deleted (allow for 1) - for any other x -> x, any deleted equipment will raise this comment - */ - sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ItemsDeconstructed")) - } - delete.foreach { case (obj, _) => TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } - //redraw - if (maxhand) { - sendResponse(PlanetsideAttributeMessage(target, attribute_type=7, player.Capacitor.toLong)) - val maxArmDefinition = GlobalDefinitions.MAXArms(subtype, player.Faction) - TaskWorkflow.execute(HoldNewEquipmentUp(player)(Tool(maxArmDefinition), slot = 0)) - player.avatar.purchaseCooldown(maxArmDefinition) - .collect(a => a) - .getOrElse { - avatarActor ! AvatarActor.UpdatePurchaseTime(maxArmDefinition) - None - } - } - //draw free hand - player.FreeHand.Equipment.foreach { obj => + } + //draw holsters and inventory + (holsters ++ inventory).foreach { + case InventoryItem(obj, index) => val definition = obj.Definition sendResponse( ObjectCreateDetailedMessage( definition.ObjectId, obj.GUID, - ObjectCreateMessageParent(target, Player.FreeHandSlot), + ObjectCreateMessageParent(target, index), definition.Packet.DetailedConstructorData(obj).get ) ) - } - //draw holsters and inventory - (holsters ++ inventory).foreach { - case InventoryItem(obj, index) => - val definition = obj.Definition - sendResponse( - ObjectCreateDetailedMessage( - definition.ObjectId, - obj.GUID, - ObjectCreateMessageParent(target, index), - definition.Packet.DetailedConstructorData(obj).get - ) + } + DropLeftovers(player)(drop) + //deactivate non-passive implants + avatarActor ! AvatarActor.DeactivateActiveImplants + + case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to some other player + sendResponse(ObjectHeldMessage(target, slot, unk1 = false)) + //cleanup + val dropPred = ContainableBehavior.DropPredicate(player) + val deleteFromDrop = drop.filterNot(dropPred) + (oldHolsters ++ delete ++ deleteFromDrop.map(f =>(f.obj, f.GUID))) + .distinctBy(_._2) + .foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } + //draw holsters + holsters.foreach { + case InventoryItem(obj, index) => + val definition = obj.Definition + sendResponse( + ObjectCreateMessage( + definition.ObjectId, + obj.GUID, + ObjectCreateMessageParent(target, index), + definition.Packet.ConstructorData(obj).get ) - } - DropLeftovers(player)(drop) - //deactivate non-passive implants - avatarActor ! AvatarActor.DeactivateActiveImplants - - case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, drop, delete) => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to some other player - sendResponse(ObjectHeldMessage(target, slot, unk1 = false)) - //cleanup - val dropPred = ContainableBehavior.DropPredicate(player) - val deleteFromDrop = drop.filterNot(dropPred) - (oldHolsters ++ delete ++ deleteFromDrop.map(f =>(f.obj, f.GUID))) - .distinctBy(_._2) - .foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - //draw holsters - holsters.foreach { - case InventoryItem(obj, index) => - val definition = obj.Definition - sendResponse( - ObjectCreateMessage( - definition.ObjectId, - obj.GUID, - ObjectCreateMessageParent(target, index), - definition.Packet.ConstructorData(obj).get - ) - ) - } - - case AvatarAction.ChangeLoadout( - target, - armor, - exosuit, - subtype, - _, - maxhand, - oldHolsters, - holsters, - oldInventory, - inventory, - drops - ) if resolvedPlayerGuid == target => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to this player - sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=true)) - //cleanup - (oldHolsters ++ oldInventory).foreach { - case (obj, objGuid) => - sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) - TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) - } - drops.foreach(item => sendResponse(ObjectDeleteMessage(item.obj.GUID, unk1=0))) - //redraw - if (maxhand) { - val maxArmWeapon = GlobalDefinitions.MAXArms(subtype, player.Faction) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=7, player.Capacitor.toLong)) - TaskWorkflow.execute(HoldNewEquipmentUp(player)(Tool(maxArmWeapon), slot = 0)) - player.avatar.purchaseCooldown(maxArmWeapon) - if (!oldHolsters.exists { case (e, _) => e.Definition == maxArmWeapon } && - player.avatar.purchaseCooldown(maxArmWeapon).isEmpty) { - avatarActor ! AvatarActor.UpdatePurchaseTime(maxArmWeapon) //switching for first time causes cooldown - } - } - sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, player, holsters ++ inventory) - DropLeftovers(player)(drops) - //deactivate non-passive implants - avatarActor ! AvatarActor.DeactivateActiveImplants - - case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => - //redraw handled by callbacks - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to some other player - sendResponse(ObjectHeldMessage(target, slot, unk1=false)) - //cleanup - oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - - case AvatarAction.UseKit(kguid, kObjId) => - sendResponse( - UseItemMessage( - resolvedPlayerGuid, - kguid, - resolvedPlayerGuid, - unk2 = 4294967295L, - unk3 = false, - unk4 = Vector3.Zero, - unk5 = Vector3.Zero, - unk6 = 126, - unk7 = 0, //sequence time? - unk8 = 137, - kObjId ) + } + + case AvatarAction.ChangeLoadout( + target, + armor, + exosuit, + subtype, + _, + maxhand, + oldHolsters, + holsters, + oldInventory, + inventory, + drops + ) if filter.resolvedPlayerGuid == target => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to this player + sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=true)) + //cleanup + (oldHolsters ++ oldInventory).foreach { + case (obj, objGuid) => + sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) + TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) + } + drops.foreach(item => sendResponse(ObjectDeleteMessage(item.obj.GUID, unk1=0))) + //redraw + if (maxhand) { + val maxArmWeapon = GlobalDefinitions.MAXArms(subtype, player.Faction) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=7, player.Capacitor.toLong)) + TaskWorkflow.execute(HoldNewEquipmentUp(player)(Tool(maxArmWeapon), slot = 0)) + player.avatar.purchaseCooldown(maxArmWeapon) + if (!oldHolsters.exists { case (e, _) => e.Definition == maxArmWeapon } && + player.avatar.purchaseCooldown(maxArmWeapon).isEmpty) { + avatarActor ! AvatarActor.UpdatePurchaseTime(maxArmWeapon) //switching for first time causes cooldown + } + } + sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, player, holsters ++ inventory) + DropLeftovers(player)(drops) + //deactivate non-passive implants + avatarActor ! AvatarActor.DeactivateActiveImplants + + case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => + //redraw handled by callbacks + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to some other player + sendResponse(ObjectHeldMessage(target, slot, unk1=false)) + //cleanup + oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } + + case AvatarAction.UseKit(kguid, kObjId) => + sendResponse( + UseItemMessage( + filter.resolvedPlayerGuid, + kguid, + filter.resolvedPlayerGuid, + unk2 = 4294967295L, + unk3 = false, + unk4 = Vector3.Zero, + unk5 = Vector3.Zero, + unk6 = 126, + unk7 = 0, //sequence time? + unk8 = 137, + kObjId ) - sendResponse(ObjectDeleteMessage(kguid, unk1=0)) + ) + sendResponse(ObjectDeleteMessage(kguid, unk1=0)) - case AvatarAction.KitNotUsed(_, "") => - sessionLogic.general.kitToBeUsed = None + case AvatarAction.KitNotUsed(_, "") => + sessionLogic.general.kitToBeUsed = None - case AvatarAction.KitNotUsed(_, msg) => - sessionLogic.general.kitToBeUsed = None - sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) + case AvatarAction.KitNotUsed(_, msg) => + sessionLogic.general.kitToBeUsed = None + sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarAction.UpdateKillsDeathsAssists(_, kda) => - avatarActor ! AvatarActor.UpdateKillsDeathsAssists(kda) + case AvatarAction.UpdateKillsDeathsAssists(_, kda) => + avatarActor ! AvatarActor.UpdateKillsDeathsAssists(kda) - case AvatarAction.AwardBep(charId, bep, expType) => - //if the target player, always award (some) BEP - if (charId == player.CharId) { - avatarActor ! AvatarActor.AwardBep(bep, expType) - } + case AvatarAction.AwardBep(charId, bep, expType) => + //if the target player, always award (some) BEP + if (charId == player.CharId) { + avatarActor ! AvatarActor.AwardBep(bep, expType) + } - case AvatarAction.AwardCep(charId, cep) => - //if the target player, always award (some) CEP - if (charId == player.CharId) { - avatarActor ! AvatarActor.AwardCep(cep) - } + case AvatarAction.AwardCep(charId, cep) => + //if the target player, always award (some) CEP + if (charId == player.CharId) { + avatarActor ! AvatarActor.AwardCep(cep) + } - case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => - ops.facilityCaptureRewards(buildingId, zoneNumber, cep) + case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => + ops.facilityCaptureRewards(buildingId, zoneNumber, cep) - case AvatarAction.ShareKillExperienceWithSquad(killer, exp) => - ops.shareKillExperienceWithSquad(killer, exp) + case AvatarAction.ShareKillExperienceWithSquad(killer, exp) => + ops.shareKillExperienceWithSquad(killer, exp) - case AvatarAction.ShareAntExperienceWithSquad(owner, exp, vehicle) => - ops.shareAntExperienceWithSquad(owner, exp, vehicle) + case AvatarAction.ShareAntExperienceWithSquad(owner, exp, vehicle) => + ops.shareAntExperienceWithSquad(owner, exp, vehicle) - case AvatarAction.RemoveFromOutfitChat(outfit_id) => - ops.removeFromOutfitChat(outfit_id) + case AvatarAction.RemoveFromOutfitChat(outfit_id) => + ops.removeFromOutfitChat(outfit_id) - case SendResponse(msgs) => - msgs.foreach(sendResponse) + /* common messages (maybe once every respawn) */ + case ReloadTool(itemGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - /* common messages (maybe once every respawn) */ - case ReloadTool(itemGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => - sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - - case AvatarAction.Killed(cause, mount) => - //log and chat messages - //destroy display - val zoneChannel = continent.id - val events = continent.AvatarEvents - val pentry = PlayerSource(player) - cause - .adversarial - .collect { case out @ Adversarial(attacker, _, _) if attacker != PlayerSource.Nobody => out } - .orElse { - player.LastDamage.collect { - case attack if System.currentTimeMillis() - attack.interaction.hitTime < (10 seconds).toMillis => - attack - .adversarial - .collect { case out @ Adversarial(attacker, _, _) if attacker != PlayerSource.Nobody => out } - }.flatten - } match { - case Some(adversarial) => - events ! MessageEnvelope( - zoneChannel, - AvatarAction.DestroyDisplay(adversarial.attacker, pentry, adversarial.implement) - ) - case _ => - events ! MessageEnvelope(zoneChannel, AvatarAction.DestroyDisplay(pentry, pentry, 0)) - } - //events chat and log - val excuse = player.LastDamage.flatMap { damage => - val interaction = damage.interaction - val reason = interaction.cause - val adversarial = interaction.adversarial.map { _.attacker } - reason match { - case r: ExplodingEntityReason if r.entity.isInstanceOf[VehicleSpawnPad] => - //also, @SVCP_Killed_TooCloseToPadOnCreate^n~ or "... within n meters of pad ..." - sendResponse(ChatMsg(ChatMessageType.UNK_227, "@SVCP_Killed_OnPadOnCreate")) - case _ => () - } - adversarial.map {_.Name }.orElse { Some(s"a ${reason.getClass.getSimpleName}") } - }.getOrElse { s"an unfortunate circumstance (probably ${player.Sex.pronounObject} own fault)" } - log.info(s"${player.Name} has died, killed by $excuse") - if (sessionLogic.shooting.shotsWhileDead > 0) { - log.warn( - s"SHOTS_WHILE_DEAD: client of ${avatar.name} fired ${sessionLogic.shooting.shotsWhileDead} rounds while character was dead on server" + case AvatarAction.Killed(cause, mount) => + //log and chat messages + //destroy display + val zoneChannel = continent.id + val events = continent.AvatarEvents + val pentry = PlayerSource(player) + cause + .adversarial + .collect { case out @ Adversarial(attacker, _, _) if attacker != PlayerSource.Nobody => out } + .orElse { + player.LastDamage.collect { + case attack if System.currentTimeMillis() - attack.interaction.hitTime < (10 seconds).toMillis => + attack + .adversarial + .collect { case out @ Adversarial(attacker, _, _) if attacker != PlayerSource.Nobody => out } + }.flatten + } match { + case Some(adversarial) => + events ! MessageEnvelope( + zoneChannel, + AvatarAction.DestroyDisplay(adversarial.attacker, pentry, adversarial.implement) ) - sessionLogic.shooting.shotsWhileDead = 0 + case _ => + events ! MessageEnvelope(zoneChannel, AvatarAction.DestroyDisplay(pentry, pentry, 0)) + } + //events chat and log + val excuse = player.LastDamage.flatMap { damage => + val interaction = damage.interaction + val reason = interaction.cause + val adversarial = interaction.adversarial.map { _.attacker } + reason match { + case r: ExplodingEntityReason if r.entity.isInstanceOf[VehicleSpawnPad] => + //also, @SVCP_Killed_TooCloseToPadOnCreate^n~ or "... within n meters of pad ..." + sendResponse(ChatMsg(ChatMessageType.UNK_227, "@SVCP_Killed_OnPadOnCreate")) + case _ => () } - //TODO other methods of death? - sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason(msg = "cancel") - sessionLogic.general.renewCharSavedTimer(fixedLen = 1800L, varLen = 0L) - continent.actor ! ZoneActor.RewardThisDeath(player) - - //player state changes - sessionLogic.zoning.spawn.avatarActive = false - AvatarActor.updateToolDischargeFor(avatar) - player.FreeHand.Equipment.foreach { item => - DropEquipmentFromInventory(player)(item) - } - sessionLogic.general.dropSpecialSlotItem() - sessionLogic.general.toggleMaxSpecialState(enable = false) - sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive - sessionLogic.zoning.zoningStatus = Zoning.Status.None - sessionLogic.zoning.spawn.deadState = DeadState.Dead - continent.GUID(mount).collect { - case obj: Vehicle => - killedWhileMounted(obj, resolvedPlayerGuid) - sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) - sessionLogic.general.unaccessContainer(obj) - - case obj: PlanetSideGameObject with Mountable with Container => - killedWhileMounted(obj, resolvedPlayerGuid) - sessionLogic.general.unaccessContainer(obj) - - case obj: PlanetSideGameObject with Mountable => - killedWhileMounted(obj, resolvedPlayerGuid) - } - sessionLogic.actionsToCancel() - sessionLogic.terminals.CancelAllProximityUnits() - AvatarActor.savePlayerLocation(player) - sessionLogic.zoning.spawn.ShiftPosition = Some(player.Position) - - //respawn - val respawnTimer = 300000 //milliseconds - sendResponse(AvatarDeadStateMessage(DeadState.Dead, respawnTimer, respawnTimer, player.Position, player.Faction, unk5=true)) - sessionLogic.zoning.spawn.reviveTimer.cancel() - sessionLogic.zoning.spawn.reviveTimer = Default.Cancellable - if (player.death_by == 0) { - sessionLogic.zoning.spawn.randomRespawn(300.seconds) - } else { - sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) - } - - case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => - sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - - case AvatarAction.Revive(revivalTargetGuid) - if resolvedPlayerGuid == revivalTargetGuid => - log.info(s"No time for rest, ${player.Name}. Back on your feet!") - ops.revive() - player.Actor ! Player.Revive - player.History - .findLast { _.isInstanceOf[RevivingActivity] } - .map { - case activity: RevivingActivity - if System.currentTimeMillis() - activity.time < 5000L => - val reviveMessage = s"@YouHaveBeenMessage^revived~^${activity.user.unique.name}~" - sendResponse(ChatMsg(ChatMessageType.UNK_227, reviveMessage)) - None - } - - /* 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(guid.guid).exists { _.visible } => - ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - - case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if isNotSameTarget => - ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - - case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => - sendResponse(ChangeFireModeMessage(itemGuid, mode)) - - case ConcealPlayer(_) => - sendResponse(GenericObjectActionMessage(guid, code=9)) - - case AvatarAction.EnvironmentalDamage(_, _, _) => - //TODO damage marker? - sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") - - case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => - sendResponse(pkt) - - case ObjectDelete(itemGuid, unk) if isNotSameTarget => - sendResponse(ObjectDeleteMessage(itemGuid, unk)) - - /* rare messages */ - case SetEmpire(objectGuid, faction) if isNotSameTarget => - sendResponse(SetEmpireMessage(objectGuid, faction)) - - case AvatarAction.DropSpecialItem() => - sessionLogic.general.dropSpecialSlotItem() - - case AvatarAction.OxygenState(player, vehicle) => - sendResponse(OxygenStateMessage( - DrowningTarget(player.guid, player.progress, player.state), - vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } - )) - - case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => - sendResponse(pkt) - - case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => - sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) - - case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => - sendResponse( - ProjectileStateMessage( - projectileGuid, - projectile.Position, - shot_vel = Vector3.Zero, - projectile.Orientation, - sequence_num=0, - end=true, - hit_target_guid=PlanetSideGUID(0) - ) + adversarial.map {_.Name }.orElse { Some(s"a ${reason.getClass.getSimpleName}") } + }.getOrElse { s"an unfortunate circumstance (probably ${player.Sex.pronounObject} own fault)" } + log.info(s"${player.Name} has died, killed by $excuse") + if (sessionLogic.shooting.shotsWhileDead > 0) { + log.warn( + s"SHOTS_WHILE_DEAD: client of ${avatar.name} fired ${sessionLogic.shooting.shotsWhileDead} rounds while character was dead on server" ) - sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) + sessionLogic.shooting.shotsWhileDead = 0 + } + //TODO other methods of death? + sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason(msg = "cancel") + sessionLogic.general.renewCharSavedTimer(fixedLen = 1800L, varLen = 0L) + continent.actor ! ZoneActor.RewardThisDeath(player) - case AvatarAction.ProjectileAutoLockAwareness(mode) => - sendResponse(GenericActionMessage(mode)) + //player state changes + sessionLogic.zoning.spawn.avatarActive = false + AvatarActor.updateToolDischargeFor(avatar) + player.FreeHand.Equipment.foreach { item => + DropEquipmentFromInventory(player)(item) + } + sessionLogic.general.dropSpecialSlotItem() + sessionLogic.general.toggleMaxSpecialState(enable = false) + sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive + sessionLogic.zoning.zoningStatus = Zoning.Status.None + sessionLogic.zoning.spawn.deadState = DeadState.Dead + continent.GUID(mount).collect { + case obj: Vehicle => + killedWhileMounted(obj, filter.resolvedPlayerGuid) + sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) + sessionLogic.general.unaccessContainer(obj) - case AvatarAction.PutDownFDU(target) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(target, code=53)) + case obj: PlanetSideGameObject with Mountable with Container => + killedWhileMounted(obj, filter.resolvedPlayerGuid) + sessionLogic.general.unaccessContainer(obj) - case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => - val definition = item.Definition - sendResponse( - ObjectCreateDetailedMessage( - definition.ObjectId, - item.GUID, - ObjectCreateMessageParent(target, slot), - definition.Packet.DetailedConstructorData(item).get - ) - ) + case obj: PlanetSideGameObject with Mountable => + killedWhileMounted(obj, filter.resolvedPlayerGuid) + } + sessionLogic.actionsToCancel() + sessionLogic.terminals.CancelAllProximityUnits() + AvatarActor.savePlayerLocation(player) + sessionLogic.zoning.spawn.ShiftPosition = Some(player.Position) - case WeaponDryFire(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.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)) + //respawn + val respawnTimer = 300000 //milliseconds + sendResponse(AvatarDeadStateMessage(DeadState.Dead, respawnTimer, respawnTimer, player.Position, player.Faction, unk5=true)) + sessionLogic.zoning.spawn.reviveTimer.cancel() + sessionLogic.zoning.spawn.reviveTimer = Default.Cancellable + if (player.death_by == 0) { + sessionLogic.zoning.spawn.randomRespawn(300.seconds) + } else { + sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) + } + + case AvatarAction.ReleasePlayer(tplayer) if filter.isNotSameTarget => + sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) + + case AvatarAction.Revive(revivalTargetGuid) + if filter.resolvedPlayerGuid == revivalTargetGuid => + log.info(s"No time for rest, ${player.Name}. Back on your feet!") + ops.revive() + player.Actor ! Player.Revive + player.History + .findLast { _.isInstanceOf[RevivingActivity] } + .map { + case activity: RevivingActivity + if System.currentTimeMillis() - activity.time < 5000L => + val reviveMessage = s"@YouHaveBeenMessage^revived~^${activity.user.unique.name}~" + sendResponse(ChatMsg(ChatMessageType.UNK_227, reviveMessage)) + None } - case _ => () - } + /* uncommon messages (utility, or once in a while) */ + case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + 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 filter.isNotSameTarget => + sendResponse(ChangeFireModeMessage(itemGuid, mode)) + + case AvatarAction.EnvironmentalDamage(_, _, _) => + //TODO damage marker? + sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") + + case AvatarAction.DropCreatedItem(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + /* rare messages */ + case AvatarAction.DropSpecialItem() => + sessionLogic.general.dropSpecialSlotItem() + + case AvatarAction.OxygenState(player, vehicle) => + sendResponse(OxygenStateMessage( + DrowningTarget(player.guid, player.progress, player.state), + vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } + )) + + case AvatarAction.LoadCreatedProjectile(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if filter.isNotSameTarget => + sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) + + case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => + sendResponse( + ProjectileStateMessage( + projectileGuid, + projectile.Position, + shot_vel = Vector3.Zero, + projectile.Orientation, + sequence_num=0, + end=true, + hit_target_guid=PlanetSideGUID(0) + ) + ) + sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) + + case AvatarAction.ProjectileAutoLockAwareness(mode) => + sendResponse(GenericActionMessage(mode)) + + case AvatarAction.PutDownFDU(target) if filter.isNotSameTarget => + sendResponse(GenericObjectActionMessage(target, code=53)) + + case AvatarAction.StowEquipment(target, slot, item) if filter.isNotSameTarget => + val definition = item.Definition + sendResponse( + ObjectCreateDetailedMessage( + definition.ObjectId, + item.GUID, + ObjectCreateMessageParent(target, slot), + definition.Packet.DetailedConstructorData(item).get + ) + ) + + case WeaponDryFire(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.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)) + } } def killedWhileMounted(obj: PlanetSideGameObject with Mountable, playerGuid: PlanetSideGUID): Unit = { diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index 6e87ee521..273ffe3b7 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -1,14 +1,15 @@ // Copyright (c) 2024 PSForever package net.psforever.actors.session.normal +import akka.actor.Actor.Receive import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers} import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo} import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.{EventResponse, SendResponse} +import net.psforever.services.base.message.EventResponse import net.psforever.services.galaxy.GalaxyAction -import net.psforever.types.{MemberAction, PlanetSideEmpire} +import net.psforever.types.{MemberAction, PlanetSideEmpire, PlanetSideGUID} object GalaxyHandlerLogic { def apply(ops: SessionGalaxyHandlers): GalaxyHandlerLogic = { @@ -34,62 +35,59 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A /* response handlers */ - def handle(reply: EventResponse): Unit = { - reply match { - case GalaxyAction.HotSpotUpdate(zone_index, priority, hot_spot_info) => - sendResponse( - HotSpotUpdateMessage( - zone_index, - priority, - hot_spot_info.map { spot => PacketHotSpotInfo(spot.DisplayLocation.x, spot.DisplayLocation.y, 40) } - ) + override def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { + receive.apply(reply) + } + + def receive: Receive = { + case GalaxyAction.HotSpotUpdate(zone_index, priority, hot_spot_info) => + sendResponse( + HotSpotUpdateMessage( + zone_index, + priority, + hot_spot_info.map { spot => PacketHotSpotInfo(spot.DisplayLocation.x, spot.DisplayLocation.y, 40) } ) + ) - case GalaxyAction.MapUpdate(msg) => - sendResponse(msg) - import net.psforever.actors.zone.ZoneActor - import net.psforever.zones.Zones - Zones.zones.find(_.Number == msg.continent_id) match { - case Some(zone) => - zone.actor ! ZoneActor.BuildingInfoState(msg) - case None => - } + case GalaxyAction.MapUpdate(msg) => + sendResponse(msg) + import net.psforever.actors.zone.ZoneActor + import net.psforever.zones.Zones + Zones.zones.find(_.Number == msg.continent_id) match { + case Some(zone) => + zone.actor ! ZoneActor.BuildingInfoState(msg) + case None => + } - case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) => - val faction = player.Faction - val from = fromFactions.contains(faction) - val to = toFactions.contains(faction) - if (from && !to) { - sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, PlanetSideEmpire.NEUTRAL)) - } else if (!from && to) { - sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction)) - } + case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) => + val faction = player.Faction + val from = fromFactions.contains(faction) + val to = toFactions.contains(faction) + if (from && !to) { + sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, PlanetSideEmpire.NEUTRAL)) + } else if (!from && to) { + sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction)) + } - case GalaxyAction.FlagMapUpdate(msg) => - sendResponse(msg) + case GalaxyAction.FlagMapUpdate(msg) => + sendResponse(msg) - case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, _, manifest) => - sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest) + case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, _, manifest) => + sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest) - case GalaxyAction.LockedZoneUpdate(zone, time) => - sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time)) + case GalaxyAction.LockedZoneUpdate(zone, time) => + sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time)) - case GalaxyAction.UnlockedZoneUpdate(zone) => - sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L)) - val popBO = 0 - val pop = zone.LivePlayers.distinctBy(_.CharId) - val popTR = pop.count(_.Faction == PlanetSideEmpire.TR) - val popNC = pop.count(_.Faction == PlanetSideEmpire.NC) - val popVS = pop.count(_.Faction == PlanetSideEmpire.VS) - sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO)) + case GalaxyAction.UnlockedZoneUpdate(zone) => + sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L)) + val popBO = 0 + val pop = zone.LivePlayers.distinctBy(_.CharId) + val popTR = pop.count(_.Faction == PlanetSideEmpire.TR) + val popNC = pop.count(_.Faction == PlanetSideEmpire.NC) + val popVS = pop.count(_.Faction == PlanetSideEmpire.VS) + 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)) => - avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name) - - case SendResponse(msgs) => - msgs.foreach(sendResponse) - - case _ => () - } + case GalaxyAction.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) => + avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name) } } 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 23d34208f..f8bb508ee 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -1,6 +1,7 @@ // Copyright (c) 2024 PSForever package net.psforever.actors.session.normal +import akka.actor.Actor.Receive import akka.actor.ActorContext import net.psforever.actors.session.support.SpawnOperations.ActivityQueuedTask import net.psforever.actors.session.support.{LocalHandlerFunctions, SessionData, SessionLocalHandlers, SpawnOperations} @@ -8,11 +9,11 @@ import net.psforever.objects.ce.Deployable 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, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} -import net.psforever.services.base.message.{EventResponse, GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse, SetEmpire} +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.{InterstellarClusterService, Service} import net.psforever.services.local.LocalAction -import net.psforever.types.{ChatMessageType, PlanetSideGUID, SpawnGroup} +import net.psforever.types.{ChatMessageType, SpawnGroup} object LocalHandlerLogic { def apply(ops: SessionLocalHandlers): LocalHandlerLogic = { @@ -35,238 +36,213 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act /* response handlers */ - /** - * na - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - val resolvedPlayerGuid = if (player.HasGUID) { - player.GUID - } else { - Service.defaultPlayerGUID - } - val isNotSameTarget = resolvedPlayerGuid != guid - reply match { - case LocalAction.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget => - sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) - - case LocalAction.DeployableUIFor(item) => - sessionLogic.general.updateDeployableUIElements(avatar.deployables.UpdateUIElement(item)) - - case LocalAction.Detonate(dguid, _: BoomerDeployable) => - sendResponse(TriggerEffectMessage(dguid, "detonate_boomer")) - sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1)) - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.Detonate(dguid, _: ExplosiveDeployable) => - sendResponse(GenericObjectActionMessage(dguid, code=19)) - sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1)) - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.Detonate(_, obj) => - log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly") - - case LocalAction.DoorOpens(_, door) if isNotSameTarget => - val doorGuid = door.GUID - val pos = player.Position.xy - val range = ops.doorLoadRange() - val foundDoor = continent - .blockMap - .sector(pos, range) - .amenityList - .collect { case door: Door => door } - .find(_.GUID == doorGuid) - val doorExistsInRange: Boolean = foundDoor.nonEmpty - if (doorExistsInRange) { - sendResponse(GenericObjectStateMsg(doorGuid, state=16)) - } - - case LocalAction.DoorCloses(doorGuid) => //door closes for everyone - sendResponse(GenericObjectStateMsg(doorGuid, state=17)) - - case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _) if obj.Destroyed => - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) => - obj.Destroyed = true - ops.DeconstructDeployable( - obj, - dguid, - pos, - obj.Orientation, - deletionType= if (obj.MountPoints.isEmpty) { 2 } else { 1 } - ) - - case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _) - if obj.Destroyed || obj.Jammed || obj.Health == 0 => - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => - obj.Destroyed = true - ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) - - case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Active && obj.Destroyed => - //if active, deactivate - obj.Active = false - ops.deactivateTelpadDeployableMessages(dguid) - //standard deployable elimination behavior - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) if obj.Active => - //if active, deactivate - obj.Active = false - ops.deactivateTelpadDeployableMessages(dguid) - //standard deployable elimination behavior - obj.Destroyed = true - ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) - - case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Destroyed => - //standard deployable elimination behavior - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) => - //standard deployable elimination behavior - obj.Destroyed = true - ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) - - case LocalAction.EliminateDeployable(obj, dguid, _, _) if obj.Destroyed => - sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - - case LocalAction.EliminateDeployable(obj, dguid, pos, effect) => - obj.Destroyed = true - ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) - - case LocalAction.HackClear(targetGuid, unk1, unk2) => - sendResponse(HackMessage(HackState1.Unk0, targetGuid, guid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) - - case LocalAction.HackObject(targetGuid, unk1, unk2) => - sessionLogic.general.hackObject(targetGuid, unk1, unk2) - - case PlanetsideAttribute(targetGuid, attributeType, attributeValue) => - sessionLogic.general.sendPlanetsideAttributeMessage(targetGuid, attributeType, attributeValue) - - case GenericObjectAction(targetGuid, actionNumber) => - sendResponse(GenericObjectActionMessage(targetGuid, actionNumber)) - - case LocalAction.GenericActionMessage(actionNumber) => - sendResponse(GenericActionMessage(actionNumber)) - - case LocalAction.LluSpawned(llu) => - // Create LLU on client - sendResponse(ObjectCreateMessage( - llu.Definition.ObjectId, - llu.GUID, - llu.Definition.Packet.ConstructorData(llu).get - )) - sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk=20, volume=0.8000001f)) - - case LocalAction.LluDespawned(lluGuid, position) => - sendResponse(TriggerSoundMessage(TriggeredSound.LLUDeconstruct, position, unk=20, volume=0.8000001f)) - sendResponse(ObjectDeleteMessage(lluGuid, unk1=0)) - // If the player was holding the LLU, remove it from their tracked special item slot - sessionLogic.general.specialItemSlotGuid.collect { case guid if guid == lluGuid => - sessionLogic.general.specialItemSlotGuid = None - player.Carrying = None - } - - case ObjectDelete(objectGuid, unk) if isNotSameTarget => - sendResponse(ObjectDeleteMessage(objectGuid, unk)) - - case LocalAction.ProximityTerminalEffect(object_guid, true) => - sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, object_guid, unk=true)) - - case LocalAction.ProximityTerminalEffect(objectGuid, false) => - sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, objectGuid, unk=false)) - sessionLogic.terminals.ForgetAllProximityTerminals(objectGuid) - - case LocalAction.RouterTelepadMessage(msg) => - sendResponse(ChatMsg(ChatMessageType.UNK_229, wideContents=false, recipient="", msg, note=None)) - - case LocalAction.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) => - sessionLogic.general.useRouterTelepadEffect(passengerGuid, srcGuid, destGuid) - - case SendResponse(msgs) => - msgs.foreach { - case msg @ (m: GenericObjectActionMessage) - if (m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages => - // delay building virus alert if player is dead/respawning - sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask( - SpawnOperations.delaySendGenericObjectActionMessage(msg), 1) - ) - case msg => - sendResponse(msg) - } - - case SetEmpire(objectGuid, empire) => - sendResponse(SetEmpireMessage(objectGuid, empire)) - - case LocalAction.ShuttleEvent(ev) => - val msg = OrbitalShuttleTimeMsg( - ev.u1, - ev.u2, - ev.t1, - ev.t2, - ev.t3, - pairs=ev.pairs.map { case ((a, b), c) => PadAndShuttlePair(a, b, c) } - ) - sendResponse(msg) - - case LocalAction.ShuttleDock(pguid, sguid, slot) => - sendResponse(ObjectAttachMessage(pguid, sguid, slot)) - - case LocalAction.ShuttleUndock(pguid, sguid, pos, orient) => - sendResponse(ObjectDetachMessage(pguid, sguid, pos, orient)) - - case LocalAction.ShuttleState(sguid, pos, orient, state) => - sendResponse(VehicleStateMessage(sguid, unk1=0, pos, orient, vel=None, Some(state), unk3=0, unk4=0, wheel_direction=15, is_decelerating=false, is_cloaked=false)) - - case LocalAction.ToggleTeleportSystem(router, systemPlan) => - sessionLogic.general.toggleTeleportSystem(router, systemPlan) - - case LocalAction.TriggerEffectAtLocation(targetGuid, effect, effectInfo, triggerLocation) => - sendResponse(TriggerEffectMessage(targetGuid, effect, effectInfo, triggerLocation)) - - case LocalAction.TriggerSound(sound, pos, unk, volume) => - sendResponse(TriggerSoundMessage(sound, pos, unk, volume)) - - case LocalAction.UpdateForceDomeStatus(buildingGuid, true) => - sendResponse(GenericObjectActionMessage(buildingGuid, 11)) - - case LocalAction.UpdateForceDomeStatus(buildingGuid, false) => - sendResponse(GenericObjectActionMessage(buildingGuid, 12)) - - case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if resolvedPlayerGuid == guid => - continent.GUID(vehicleGuid) - .collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) } - .collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) } - .getOrElse(Set.empty) - .collect { case weapon: Tool if weapon.GUID == weaponGuid => - sendResponse(InventoryStateMessage(weapon.AmmoSlot.Box.GUID, weapon.GUID, weapon.Magazine)) - } - - case LocalAction.ForceZoneChange(zone) => - //todo we might be able to piggyback this for squad recalls later - if(session.zone eq zone) { - sessionLogic.zoning.zoneReload = true - zone.AvatarEvents ! Service.LeaveAll - zone.LocalEvents ! Service.LeaveAll - zone.VehicleEvents ! Service.LeaveAll - zone.AvatarEvents ! Service.Join(player.Name) //must manually restore this subscriptions - sessionLogic.zoning.spawn.handleNewPlayerLoaded(player) //will restart subscriptions and dispatch a LoadMapMessage - } else { - import akka.actor.typed.scaladsl.adapter._ - sessionLogic.cluster ! InterstellarClusterService.GetRandomSpawnPoint( - zone.Number, - player.Faction, - Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS), - context.self + def receive: Receive = { + case SendResponse(msgs) => + msgs.foreach { + case msg @ (m: GenericObjectActionMessage) + if (m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages => + // delay building virus alert if player is dead/respawning + sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask( + SpawnOperations.delaySendGenericObjectActionMessage(msg), 1) ) + case msg => + sendResponse(msg) + } + + case LocalAction.DeployableMapIcon(behavior, deployInfo) if filter.isNotSameTarget => + sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) + + case LocalAction.DeployableUIFor(item) => + sessionLogic.general.updateDeployableUIElements(avatar.deployables.UpdateUIElement(item)) + + case LocalAction.Detonate(dguid, _: BoomerDeployable) => + sendResponse(TriggerEffectMessage(dguid, "detonate_boomer")) + sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1)) + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.Detonate(dguid, _: ExplosiveDeployable) => + sendResponse(GenericObjectActionMessage(dguid, code=19)) + sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1)) + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.Detonate(_, obj) => + log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly") + + case LocalAction.DoorOpens(_, door) if filter.isNotSameTarget => + val doorGuid = door.GUID + val pos = player.Position.xy + val range = ops.doorLoadRange() + val foundDoor = continent + .blockMap + .sector(pos, range) + .amenityList + .collect { case door: Door => door } + .find(_.GUID == doorGuid) + val doorExistsInRange: Boolean = foundDoor.nonEmpty + if (doorExistsInRange) { + sendResponse(GenericObjectStateMsg(doorGuid, state=16)) + } + + case LocalAction.DoorCloses(doorGuid) => //door closes for everyone + sendResponse(GenericObjectStateMsg(doorGuid, state=17)) + + case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _) if obj.Destroyed => + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) => + obj.Destroyed = true + ops.DeconstructDeployable( + obj, + dguid, + pos, + obj.Orientation, + deletionType= if (obj.MountPoints.isEmpty) { 2 } else { 1 } + ) + + case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _) + if obj.Destroyed || obj.Jammed || obj.Health == 0 => + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => + obj.Destroyed = true + ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) + + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Active && obj.Destroyed => + //if active, deactivate + obj.Active = false + ops.deactivateTelpadDeployableMessages(dguid) + //standard deployable elimination behavior + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) if obj.Active => + //if active, deactivate + obj.Active = false + ops.deactivateTelpadDeployableMessages(dguid) + //standard deployable elimination behavior + obj.Destroyed = true + ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) + + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Destroyed => + //standard deployable elimination behavior + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) => + //standard deployable elimination behavior + obj.Destroyed = true + ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) + + case LocalAction.EliminateDeployable(obj, dguid, _, _) if obj.Destroyed => + sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + + case LocalAction.EliminateDeployable(obj, dguid, pos, effect) => + obj.Destroyed = true + ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) + + case LocalAction.HackClear(targetGuid, unk1, unk2) => + sendResponse(HackMessage(HackState1.Unk0, targetGuid, filter.resolvedPlayerGuid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) + + case LocalAction.HackObject(targetGuid, unk1, unk2) => + sessionLogic.general.hackObject(targetGuid, unk1, unk2) + + case PlanetsideAttribute(targetGuid, attributeType, attributeValue) => + sessionLogic.general.sendPlanetsideAttributeMessage(targetGuid, attributeType, attributeValue) + + case LocalAction.GenericActionMessage(actionNumber) => + sendResponse(GenericActionMessage(actionNumber)) + + case LocalAction.LluSpawned(llu) => + // Create LLU on client + sendResponse(ObjectCreateMessage( + llu.Definition.ObjectId, + llu.GUID, + llu.Definition.Packet.ConstructorData(llu).get + )) + sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk=20, volume=0.8000001f)) + + case LocalAction.LluDespawned(lluGuid, position) => + sendResponse(TriggerSoundMessage(TriggeredSound.LLUDeconstruct, position, unk=20, volume=0.8000001f)) + sendResponse(ObjectDeleteMessage(lluGuid, unk1=0)) + // If the player was holding the LLU, remove it from their tracked special item slot + sessionLogic.general.specialItemSlotGuid.collect { case guid if guid == lluGuid => + sessionLogic.general.specialItemSlotGuid = None + player.Carrying = None + } + + case LocalAction.ProximityTerminalEffect(object_guid, true) => + sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, object_guid, unk=true)) + + case LocalAction.ProximityTerminalEffect(objectGuid, false) => + sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, objectGuid, unk=false)) + sessionLogic.terminals.ForgetAllProximityTerminals(objectGuid) + + case LocalAction.RouterTelepadMessage(msg) => + sendResponse(ChatMsg(ChatMessageType.UNK_229, wideContents=false, recipient="", msg, note=None)) + + case LocalAction.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) => + sessionLogic.general.useRouterTelepadEffect(passengerGuid, srcGuid, destGuid) + + case LocalAction.ShuttleEvent(ev) => + val msg = OrbitalShuttleTimeMsg( + ev.u1, + ev.u2, + ev.t1, + ev.t2, + ev.t3, + pairs=ev.pairs.map { case ((a, b), c) => PadAndShuttlePair(a, b, c) } + ) + sendResponse(msg) + + case LocalAction.ShuttleDock(pguid, sguid, slot) => + sendResponse(ObjectAttachMessage(pguid, sguid, slot)) + + case LocalAction.ShuttleUndock(pguid, sguid, pos, orient) => + sendResponse(ObjectDetachMessage(pguid, sguid, pos, orient)) + + case LocalAction.ShuttleState(sguid, pos, orient, state) => + sendResponse(VehicleStateMessage(sguid, unk1=0, pos, orient, vel=None, Some(state), unk3=0, unk4=0, wheel_direction=15, is_decelerating=false, is_cloaked=false)) + + case LocalAction.ToggleTeleportSystem(router, systemPlan) => + sessionLogic.general.toggleTeleportSystem(router, systemPlan) + + case LocalAction.TriggerEffectAtLocation(targetGuid, effect, effectInfo, triggerLocation) => + sendResponse(TriggerEffectMessage(targetGuid, effect, effectInfo, triggerLocation)) + + case LocalAction.TriggerSound(sound, pos, unk, volume) => + sendResponse(TriggerSoundMessage(sound, pos, unk, volume)) + + case LocalAction.UpdateForceDomeStatus(buildingGuid, true) => + sendResponse(GenericObjectActionMessage(buildingGuid, 11)) + + case LocalAction.UpdateForceDomeStatus(buildingGuid, false) => + sendResponse(GenericObjectActionMessage(buildingGuid, 12)) + + case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if filter.isSameTarget /*resolvedPlayerGuid == guid*/ => + continent.GUID(vehicleGuid) + .collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) } + .collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) } + .getOrElse(Set.empty) + .collect { case weapon: Tool if weapon.GUID == weaponGuid => + sendResponse(InventoryStateMessage(weapon.AmmoSlot.Box.GUID, weapon.GUID, weapon.Magazine)) } - case _ => () - } + case LocalAction.ForceZoneChange(zone) => + //todo we might be able to piggyback this for squad recalls later + if(session.zone eq zone) { + sessionLogic.zoning.zoneReload = true + zone.AvatarEvents ! Service.LeaveAll + zone.LocalEvents ! Service.LeaveAll + zone.VehicleEvents ! Service.LeaveAll + zone.AvatarEvents ! Service.Join(player.Name) //must manually restore this subscriptions + sessionLogic.zoning.spawn.handleNewPlayerLoaded(player) //will restart subscriptions and dispatch a LoadMapMessage + } else { + import akka.actor.typed.scaladsl.adapter._ + sessionLogic.cluster ! InterstellarClusterService.GetRandomSpawnPoint( + zone.Number, + player.Faction, + Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS), + context.self + ) + } } /* support functions */ 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 62acd99c1..9758c53d3 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -1,6 +1,7 @@ // Copyright (c) 2024 PSForever package net.psforever.actors.session.normal +import akka.actor.Actor.Receive import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{SessionData, SessionVehicleHandlers, VehicleHandlerFunctions} @@ -15,7 +16,7 @@ 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.services.Service import net.psforever.services.base.envelope.GenericResponseEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} +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} @@ -33,367 +34,305 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: private val galaxyService: ActorRef = ops.galaxyService - /** - * na - * - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - val resolvedPlayerGuid = if (player.HasGUID) { - player.GUID - } else { - PlanetSideGUID(-1) - } - val isNotSameTarget = resolvedPlayerGuid != guid - reply match { - case VehicleAction.VehicleState( - vehicleGuid, - unk1, - pos, - orient, - vel, - unk2, - unk3, - unk4, - wheelDirection, - unk5, - unk6 - ) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => - //player who is also in the vehicle (not driver) - sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - player.Position = pos - player.Orientation = orient - player.Velocity = vel - sessionLogic.updateLocalBlockMap(pos) - //llu destruction check - if (player.Carrying.contains(SpecialCarry.CaptureFlag)) { - continent - .GUID(player.VehicleSeated) - .collect { case vehicle: Vehicle => - CaptureFlagManager.ReasonToLoseFlagViolently(continent, sessionLogic.general.specialItemSlotGuid, vehicle) - } - } - - case VehicleAction.VehicleState( - vehicleGuid, - unk1, - pos, - ang, - vel, - unk2, - unk3, - unk4, - wheelDirection, - unk5, - unk6 - ) if isNotSameTarget => - //player who is watching the vehicle from the outside - sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - - case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => - sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) - - case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) - if isNotSameTarget => - sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - - case ChangeFireState_Start(weaponGuid) if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - - case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - - case ReloadTool(itemGuid) if isNotSameTarget => - sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - - case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => - sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0)) - //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) - sendResponse( - ObjectCreateMessage( - ammo_id, - ammo_guid, - ObjectCreateMessageParent(weapon_guid, weapon_slot), - ammo_data - ) - ) - sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - - case WeaponDryFire(weaponGuid) 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 VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => - sendResponse(DismountVehicleMsg(guid, bailType, wasKickedByDriver)) - - case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => - sendResponse(ObjectAttachMessage(vehicleGuid, guid, seat)) - - case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => - sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos)) - - case SendResponse(msgs) => - msgs.foreach(sendResponse) - - case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => - sendResponse(pkt) - - case GenericObjectAction(objectGuid, action) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(objectGuid, action)) - - case HintsAtAttacker(sourceGuid) if player.isAlive => - sendResponse(HitHint(sourceGuid, player.GUID)) - - case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => - //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? - val objGuid = obj.GUID - sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) - sendResponse(ObjectCreateDetailedMessage( - obj.Definition.ObjectId, - objGuid, - ObjectCreateMessageParent(parentGuid, start), - conData - )) - - case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid => - //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(guid, BailType.Kicked, wasKickedByDriver)) - val typeOfRide = continent.GUID(vehicleGuid) match { - case Some(obj: Vehicle) => - sessionLogic.general.unaccessContainer(obj) - s"the ${obj.Definition.Name}'s seat by ${obj.OwnerName.getOrElse("the pilot")}" - case _ => - s"${player.Sex.possessive} ride" - } - log.info(s"${player.Name} has been kicked from $typeOfRide!") - player.WhichSide = OutsideOf - - 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(guid, BailType.Kicked, wasKickedByDriver)) - - case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => - sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) - - case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => - //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)) - Vehicles.ReloadAccessPermissions(vehicle, player.Name) - - case ObjectDelete(itemGuid, _) if isNotSameTarget => - sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - - case VehicleAction.Ownership(vehicleGuid) if resolvedPlayerGuid == guid => - //Only the player that owns this vehicle needs the ownership packet - avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) - sendResponse(PlanetsideAttributeMessage(resolvedPlayerGuid, attribute_type=21, vehicleGuid)) - - case VehicleAction.LoseOwnership(_, vehicleGuid) => - ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") - - case PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue)) - - case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) - - case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if isNotSameTarget => - //TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly? - sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData)) - - case VehicleAction.UnloadVehicle(_, vehicleGuid) => - sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) - if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists { - case ams: Vehicle => - ams.GUID == vehicleGuid && - ams.OwnerGuid.isEmpty - case _ => - false - }) { - sessionLogic.zoning.spawn.prevSpawnPoint = None - sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed")) - } - - case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => - //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? - sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - - case VehicleAction.UpdateAmsSpawnList(list) => - sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) - sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() - - case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget => - sessionLogic.zoning.interstellarFerry = Some(vehicle) - sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) - continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}") - galaxyService ! Service.Join(tempChannel) //temporary vehicle-specific channel - log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating") - - case VehicleAction.KickCargo(vehicle, speed, delay) - if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => - val strafe = 1 + Vehicles.CargoOrientation(vehicle) - val reverseSpeed = if (strafe > 1) { 0 } else { speed } - //strafe or reverse, not both - sessionLogic.vehicles.ServerVehicleOverrideWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=true, - lock_wheel=true, - reverse=true, - unk4=false, - lock_vthrust=0, - strafe, - reverseSpeed, - unk8=Some(0) - ) - ) - import scala.concurrent.ExecutionContext.Implicits.global - import scala.concurrent.duration._ - val resp = GenericResponseEnvelope( - VehicleStamp, - toChannel, - PlanetSideGUID(0), - VehicleAction.KickCargo(vehicle, speed=0, delay) - ) - context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) - - case VehicleAction.KickCargo(cargo, _, _) - if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => - sessionLogic.vehicles.TotalDriverVehicleControl(cargo) - - case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory) - if player.avatar.vehicle.contains(target) => - //TODO when vehicle weapons can be changed without visual glitches, rewrite this - continent.GUID(target).collect { case vehicle: Vehicle => - import net.psforever.login.WorldSession.boolToInt - //owner: must unregister old equipment, and register and install new equipment - (oldWeapons ++ oldInventory).foreach { - case (obj, eguid) => - sendResponse(ObjectDeleteMessage(eguid, unk1=0)) - TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) + def receive: Receive = { + case VehicleAction.VehicleState( + vehicleGuid, + unk1, + pos, + orient, + vel, + unk2, + unk3, + unk4, + wheelDirection, + unk5, + unk6 + ) if filter.isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => + //player who is also in the vehicle (not driver) + sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) + player.Position = pos + player.Orientation = orient + player.Velocity = vel + sessionLogic.updateLocalBlockMap(pos) + //llu destruction check + if (player.Carrying.contains(SpecialCarry.CaptureFlag)) { + continent + .GUID(player.VehicleSeated) + .collect { case vehicle: Vehicle => + CaptureFlagManager.ReasonToLoseFlagViolently(continent, sessionLogic.general.specialItemSlotGuid, vehicle) } - sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, vehicle, addedWeapons ++ newInventory) - //jammer or unjamm new weapons based on vehicle status - val vehicleJammered = vehicle.Jammed - addedWeapons - .map { _.obj } - .collect { - case jamItem: JammableUnit if jamItem.Jammed != vehicleJammered => - jamItem.Jammed = vehicleJammered - JammableMountedWeapons.JammedWeaponStatus(vehicle.Zone, jamItem, vehicleJammered) - } - changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) - } + } - case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) - if sessionLogic.general.accessedContainer.map(_.GUID).contains(target) => - //TODO when vehicle weapons can be changed without visual glitches, rewrite this - continent.GUID(target).collect { case vehicle: Vehicle => - //external participant: observe changes to equipment - (oldWeapons ++ oldInventory).foreach { case (_, eguid) => sendResponse(ObjectDeleteMessage(eguid, unk1=0)) } - changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) - } + case VehicleAction.VehicleState( + vehicleGuid, + unk1, + pos, + ang, + vel, + unk2, + unk3, + unk4, + wheelDirection, + unk5, + unk6 + ) if filter.isNotSameTarget => + //player who is watching the vehicle from the outside + sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => - //TODO when vehicle weapons can be changed without visual glitches, rewrite this - continent.GUID(target).collect { case vehicle: Vehicle => - changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) - } + case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if filter.isNotSameTarget => + sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) - case VehicleSpawnPad.AttachToRails(vehicle, pad) => - sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3)) + case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) + if filter.isNotSameTarget => + sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleSpawnPad.ConcealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=9)) + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if filter.isNotSameTarget => + sendResponse(DismountVehicleMsg(filter.resolvedPlayerGuid, bailType, wasKickedByDriver)) - case VehicleSpawnPad.DetachFromRails(vehicle, pad) => - val padDefinition = pad.Definition - sendResponse( - ObjectDetachMessage( - pad.GUID, - vehicle.GUID, - pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset), - pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset - ) + case VehicleAction.MountVehicle(vehicleGuid, seat) if filter.isNotSameTarget => + sendResponse(ObjectAttachMessage(vehicleGuid, filter.resolvedPlayerGuid, seat)) + + case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if filter.isNotSameTarget => + sendResponse(DeployRequestMessage(filter.resolvedPlayerGuid, objectGuid, state, unk1, unk2, pos)) + + case VehicleAction.EquipmentCreatedInSlot(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case VehicleAction.InventoryState(obj, parentGuid, start, conData) if filter.isNotSameTarget => + //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? + val objGuid = obj.GUID + sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) + sendResponse(ObjectCreateDetailedMessage( + obj.Definition.ObjectId, + objGuid, + ObjectCreateMessageParent(parentGuid, start), + conData + )) + + case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if filter.isSameTarget /*resolvedPlayerGuid == guid*/ => + //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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + val typeOfRide = continent.GUID(vehicleGuid) match { + case Some(obj: Vehicle) => + sessionLogic.general.unaccessContainer(obj) + s"the ${obj.Definition.Name}'s seat by ${obj.OwnerName.getOrElse("the pilot")}" + case _ => + s"${player.Sex.possessive} ride" + } + log.info(s"${player.Name} has been kicked from $typeOfRide!") + player.WhichSide = OutsideOf + + 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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + + case VehicleAction.InventoryState2(objGuid, parentGuid, value) if filter.isNotSameTarget => + sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) + + case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if filter.isNotSameTarget => + //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)) + Vehicles.ReloadAccessPermissions(vehicle, player.Name) + + case VehicleAction.Ownership(vehicleGuid) if filter.isSameTarget /*resolvedPlayerGuid == guid*/ => + //Only the player that owns this vehicle needs the ownership packet + avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) + sendResponse(PlanetsideAttributeMessage(filter.resolvedPlayerGuid, attribute_type=21, vehicleGuid)) + + case VehicleAction.LoseOwnership(_, vehicleGuid) => + ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") + + case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if filter.isNotSameTarget => + sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) + + case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if filter.isNotSameTarget => + //TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly? + sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData)) + + case VehicleAction.UnloadVehicle(_, vehicleGuid) => + sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) + if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists { + case ams: Vehicle => + ams.GUID == vehicleGuid && + ams.OwnerGuid.isEmpty + case _ => + false + }) { + sessionLogic.zoning.spawn.prevSpawnPoint = None + sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed")) + } + + case VehicleAction.UnstowEquipment(itemGuid) if filter.isNotSameTarget => + //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? + sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) + + case VehicleAction.UpdateAmsSpawnList(list) => + sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) + sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() + + case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if filter.isNotSameTarget => + sessionLogic.zoning.interstellarFerry = Some(vehicle) + sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) + continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}") + galaxyService ! Service.Join(tempChannel) //temporary vehicle-specific channel + log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating") + + case VehicleAction.KickCargo(vehicle, speed, delay) + if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => + val strafe = 1 + Vehicles.CargoOrientation(vehicle) + val reverseSpeed = if (strafe > 1) { 0 } else { speed } + //strafe or reverse, not both + sessionLogic.vehicles.ServerVehicleOverrideWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=true, + lock_wheel=true, + reverse=true, + unk4=false, + lock_vthrust=0, + strafe, + reverseSpeed, + unk8=Some(0) ) + ) + import scala.concurrent.ExecutionContext.Implicits.global + import scala.concurrent.duration._ + val resp = GenericResponseEnvelope( + VehicleStamp, + "", + PlanetSideGUID(0), + VehicleAction.KickCargo(vehicle, speed=0, delay) + ) + context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) - case VehicleSpawnPad.ResetSpawnPad(pad) => - sendResponse(GenericObjectActionMessage(pad.GUID, code=23)) + case VehicleAction.KickCargo(cargo, _, _) + if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => + sessionLogic.vehicles.TotalDriverVehicleControl(cargo) - case VehicleSpawnPad.RevealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=10)) - - case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) - if player.VisibleSlots.contains(player.DrawnSlot) => - player.DrawnSlot = Player.HandsDownSlot - startPlayerSeatedInVehicle(vehicle) - - case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) => - startPlayerSeatedInVehicle(vehicle) - - case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle, _) => - Vehicles.ReloadAccessPermissions(vehicle, player.Name) - sessionLogic.vehicles.ServerVehicleOverrideWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=true, - lock_wheel=true, - reverse=true, - unk4=false, - lock_vthrust=1, - lock_strafe=0, - movement_speed=0, - unk8=Some(0) - ) - ) - sessionLogic.vehicles.serverVehicleControlVelocity = Some(0) - - case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, _) => - val vdef = vehicle.Definition - sessionLogic.vehicles.ServerVehicleOverrideWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=true, - lock_wheel=true, - reverse=false, - unk4=false, - lock_vthrust=if (GlobalDefinitions.isFlightVehicle(vdef)) { 1 } else { 0 }, - lock_strafe=0, - movement_speed=vdef.AutoPilotSpeed1, - unk8=Some(0) - ) - ) - - case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) => - sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) - - case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, data) => - val str = s"${data.getOrElse("The vehicle spawn pad where you placed your order is blocked.")}" - val msg = if (str.contains("@")) { - ChatMsg(ChatMessageType.UNK_229, str) - } else { - ChatMsg(ChatMessageType.CMT_OPEN, wideContents = true, recipient = "", str, note = None) + case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory) + if player.avatar.vehicle.contains(target) => + //TODO when vehicle weapons can be changed without visual glitches, rewrite this + continent.GUID(target).collect { case vehicle: Vehicle => + import net.psforever.login.WorldSession.boolToInt + //owner: must unregister old equipment, and register and install new equipment + (oldWeapons ++ oldInventory).foreach { + case (obj, eguid) => + sendResponse(ObjectDeleteMessage(eguid, unk1=0)) + TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } - sendResponse(msg) + sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, vehicle, addedWeapons ++ newInventory) + //jammer or unjamm new weapons based on vehicle status + val vehicleJammered = vehicle.Jammed + addedWeapons + .map { _.obj } + .collect { + case jamItem: JammableUnit if jamItem.Jammed != vehicleJammered => + jamItem.Jammed = vehicleJammered + JammableMountedWeapons.JammedWeaponStatus(vehicle.Zone, jamItem, vehicleJammered) + } + changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) + } - case VehicleSpawnPad.PeriodicReminder(_, data) => - val (isType, flag, msg): (ChatMessageType, Boolean, String) = data match { - case Some(msg: String) if msg.startsWith("@") => (ChatMessageType.UNK_227, false, msg) - case Some(msg: String) => (ChatMessageType.CMT_OPEN, true, msg) - case _ => (ChatMessageType.CMT_OPEN, true, "Your vehicle order has been cancelled.") - } - sendResponse(ChatMsg(isType, flag, recipient="", msg, None)) + case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) + if sessionLogic.general.accessedContainer.map(_.GUID).contains(target) => + //TODO when vehicle weapons can be changed without visual glitches, rewrite this + continent.GUID(target).collect { case vehicle: Vehicle => + //external participant: observe changes to equipment + (oldWeapons ++ oldInventory).foreach { case (_, eguid) => sendResponse(ObjectDeleteMessage(eguid, unk1=0)) } + changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) + } - case _ => () - } + case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => + //TODO when vehicle weapons can be changed without visual glitches, rewrite this + continent.GUID(target).collect { case vehicle: Vehicle => + changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) + } + + case VehicleSpawnPad.AttachToRails(vehicle, pad) => + sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3)) + + case VehicleSpawnPad.ConcealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=9)) + + case VehicleSpawnPad.DetachFromRails(vehicle, pad) => + val padDefinition = pad.Definition + sendResponse( + ObjectDetachMessage( + pad.GUID, + vehicle.GUID, + pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset), + pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset + ) + ) + + case VehicleSpawnPad.ResetSpawnPad(pad) => + sendResponse(GenericObjectActionMessage(pad.GUID, code=23)) + + case VehicleSpawnPad.RevealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=10)) + + case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) + if player.VisibleSlots.contains(player.DrawnSlot) => + player.DrawnSlot = Player.HandsDownSlot + startPlayerSeatedInVehicle(vehicle) + + case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) => + startPlayerSeatedInVehicle(vehicle) + + case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle, _) => + Vehicles.ReloadAccessPermissions(vehicle, player.Name) + sessionLogic.vehicles.ServerVehicleOverrideWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=true, + lock_wheel=true, + reverse=true, + unk4=false, + lock_vthrust=1, + lock_strafe=0, + movement_speed=0, + unk8=Some(0) + ) + ) + sessionLogic.vehicles.serverVehicleControlVelocity = Some(0) + + case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, _) => + val vdef = vehicle.Definition + sessionLogic.vehicles.ServerVehicleOverrideWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=true, + lock_wheel=true, + reverse=false, + unk4=false, + lock_vthrust=if (GlobalDefinitions.isFlightVehicle(vdef)) { 1 } else { 0 }, + lock_strafe=0, + movement_speed=vdef.AutoPilotSpeed1, + unk8=Some(0) + ) + ) + + case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) => + sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) + + case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, data) => + val str = s"${data.getOrElse("The vehicle spawn pad where you placed your order is blocked.")}" + val msg = if (str.contains("@")) { + ChatMsg(ChatMessageType.UNK_229, str) + } else { + ChatMsg(ChatMessageType.CMT_OPEN, wideContents = true, recipient = "", str, note = None) + } + sendResponse(msg) + + case VehicleSpawnPad.PeriodicReminder(_, data) => + val (isType, flag, msg): (ChatMessageType, Boolean, String) = data match { + case Some(msg: String) if msg.startsWith("@") => (ChatMessageType.UNK_227, false, msg) + case Some(msg: String) => (ChatMessageType.CMT_OPEN, true, msg) + case _ => (ChatMessageType.CMT_OPEN, true, "Your vehicle order has been cancelled.") + } + sendResponse(ChatMsg(isType, flag, recipient="", msg, None)) } private def changeLoadoutDeleteOldEquipment( 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 6e4b94518..d072f0069 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -1,6 +1,7 @@ // Copyright (c) 2024 PSForever package net.psforever.actors.session.spectator +import akka.actor.Actor.Receive import akka.actor.{ActorContext, typed} import net.psforever.actors.session.support.AvatarHandlerFunctions import net.psforever.actors.zone.ZoneActor @@ -9,7 +10,7 @@ import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.{AvatarImplantMessage, ImplantAction} import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, EventResponse, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import scala.concurrent.duration._ // @@ -24,9 +25,8 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.vital.etc.ExplodingEntityReason import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, HitHint, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, SetEmpireMessage, UseItemMessage, WeaponDryFireMessage} +import net.psforever.packet.game.{ArmorChangedMessage, AvatarDeadStateMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DeadState, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, UseItemMessage, WeaponDryFireMessage} import net.psforever.services.avatar.AvatarAction -import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -41,539 +41,491 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor - /** - * na - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - val resolvedPlayerGuid = if (player != null && player.HasGUID) { - player.GUID - } else { - Service.defaultPlayerGUID - } - val isNotSameTarget = resolvedPlayerGuid != guid - val isSameTarget = !isNotSameTarget - reply match { - /* special messages */ - case AvatarAction.TeardownConnection() => - log.trace(s"ending ${player.Name}'s old session by event system request (relog)") - context.stop(context.self) + def receive: Receive = { + /* special messages */ + case AvatarAction.TeardownConnection => + log.trace(s"ending ${player.Name}'s old session by event system request (relog)") + context.stop(context.self) - /* really common messages (very frequently, every life) */ - case pstate @ AvatarAction.PlayerState( - pos, - vel, - yaw, - pitch, - yawUpper, - _, - isCrouching, - isJumping, - jumpThrust, - isCloaking, - isNotRendered, - canSeeReallyFar - ) if isNotSameTarget => - val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(guid.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) - } - val drawConfig = Config.app.game.playerDraw //m - val maxRange = drawConfig.rangeMax * drawConfig.rangeMax //sq.m - val ourPosition = player.Position //xyz - val currentDistance = Vector3.DistanceSquared(ourPosition, pos) //sq.m - val inDrawableRange = currentDistance <= maxRange - val now = System.currentTimeMillis() //ms - if ( - sessionLogic.zoning.zoningStatus != Zoning.Status.Deconstructing && - !isNotRendered && inDrawableRange + /* really common messages (very frequently, every life) */ + case pstate @ AvatarAction.PlayerState( + pos, + vel, + yaw, + pitch, + yawUpper, + _, + isCrouching, + isJumping, + jumpThrust, + isCloaking, + isNotRendered, + canSeeReallyFar + ) if filter.isNotSameTarget => + val pstateToSave = pstate.copy(timestamp = 0) + val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.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) + } + val drawConfig = Config.app.game.playerDraw //m + val maxRange = drawConfig.rangeMax * drawConfig.rangeMax //sq.m + val ourPosition = player.Position //xyz + val currentDistance = Vector3.DistanceSquared(ourPosition, pos) //sq.m + val inDrawableRange = currentDistance <= maxRange + val now = System.currentTimeMillis() //ms + if ( + sessionLogic.zoning.zoningStatus != Zoning.Status.Deconstructing && + !isNotRendered && inDrawableRange + ) { + //conditions where visibility is assured + val durationSince = now - lastTime //ms + lazy val previouslyInDrawableRange = Vector3.DistanceSquared(ourPosition, lastPosition) <= maxRange + lazy val targetDelay = { + val populationOver = math.max( + 0, + sessionLogic.localSector.livePlayerList.size - drawConfig.populationThreshold + ) + val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m + val adjustedDistance = currentDistance + distanceAdjustment //sq.m + drawConfig.ranges.lastIndexWhere { dist => adjustedDistance > dist * dist } match { + case -1 => 1 + case index => drawConfig.delays(index) + } + } //ms + if (!wasVisible || + !previouslyInDrawableRange || + durationSince > drawConfig.delayMax || + (!lastMsg.contains(pstateToSave) && + (canSeeReallyFar || + currentDistance < drawConfig.rangeMin * drawConfig.rangeMin || + sessionLogic.general.canSeeReallyFar || + durationSince > targetDelay + ) + ) ) { - //conditions where visibility is assured - val durationSince = now - lastTime //ms - lazy val previouslyInDrawableRange = Vector3.DistanceSquared(ourPosition, lastPosition) <= maxRange - lazy val targetDelay = { - val populationOver = math.max( - 0, - sessionLogic.localSector.livePlayerList.size - drawConfig.populationThreshold + //must draw + sendResponse( + PlayerStateMessage( + filter.resolvedPlayerGuid, + pos, + vel, + yaw, + pitch, + yawUpper, + timestamp = 0, //is this okay? + isCrouching, + isJumping, + jumpThrust, + isCloaking ) - val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m - val adjustedDistance = currentDistance + distanceAdjustment //sq.m - drawConfig.ranges.lastIndexWhere { dist => adjustedDistance > dist * dist } match { - case -1 => 1 - case index => drawConfig.delays(index) - } - } //ms - if (!wasVisible || - !previouslyInDrawableRange || - durationSince > drawConfig.delayMax || - (!lastMsg.contains(pstateToSave) && - (canSeeReallyFar || - currentDistance < drawConfig.rangeMin * drawConfig.rangeMin || - sessionLogic.general.canSeeReallyFar || - durationSince > targetDelay - ) - ) - ) { - //must draw - sendResponse( - PlayerStateMessage( - guid, - pos, - vel, - yaw, - pitch, - yawUpper, - timestamp = 0, //is this okay? - isCrouching, - isJumping, - jumpThrust, - isCloaking - ) - ) - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) - } else { - //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) - } + ) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { - //conditions where the target is not currently visible - if (wasVisible) { - //the target was JUST PREVIOUSLY visible; one last draw to move target beyond a renderable distance - val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat - sendResponse( - PlayerStateMessage( - guid, - Vector3(1f, lat, 1f), - vel=None, - facingYaw=0f, - facingPitch=0f, - facingYawUpper=0f, - timestamp=0, //is this okay? - is_cloaked = isCloaking - ) + //is visible, but skip reinforcement + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + } + } else { + //conditions where the target is not currently visible + if (wasVisible) { + //the target was JUST PREVIOUSLY visible; one last draw to move target beyond a renderable distance + val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat + sendResponse( + PlayerStateMessage( + filter.resolvedPlayerGuid, + Vector3(1f, lat, 1f), + vel=None, + facingYaw=0f, + facingPitch=0f, + facingYawUpper=0f, + timestamp=0, //is this okay? + is_cloaked = isCloaking ) - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) - } else { - //skip drawing altogether - ops.lastSeenStreamMessage.put(guid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) - } + ) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + } else { + //skip drawing altogether + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } + } - case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(guid, 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) - } - if (sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing) { - sessionLogic.zoning.spawn.stopDeconstructing() - } + case AvatarAction.ObjectHeld(slot, _) + if filter.isSameTarget && player.VisibleSlots.contains(slot) => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, 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) + } + if (sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing) { + sessionLogic.zoning.spawn.stopDeconstructing() + } - case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(guid, slot, unk1=true)) + case AvatarAction.ObjectHeld(slot, _) + if filter.isSameTarget && slot > -1 => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) - case AvatarAction.ObjectHeld(_, _) - if isSameTarget => () + case AvatarAction.ObjectHeld(_, _) + if filter.isSameTarget => () - case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(guid, previousSlot, unk1=false)) + case AvatarAction.ObjectHeld(_, previousSlot) => + sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, previousSlot, unk1=false)) - case ChangeFireState_Start(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(guid.guid) - ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = Some(weaponGuid))) + case ChangeFireState_Start(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = Some(weaponGuid))) - case ChangeFireState_Start(weaponGuid) - if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + case ChangeFireState_Stop(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) + ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = None)) - case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(guid.guid) - ops.lastSeenStreamMessage.put(guid.guid, entry.copy(shooting = None)) + case AvatarAction.LoadCreatedPlayer(pkt) if filter.isNotSameTarget => + sendResponse(pkt) - case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + case AvatarAction.EquipmentCreatedInHand(pkt) if filter.isNotSameTarget => + sendResponse(pkt) - case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => - sendResponse(pkt) + case AvatarAction.Destroy(victim, killer, weapon, pos) => + // guid = victim // killer = killer + sendResponse(DestroyMessage(victim, killer, weapon, pos)) - case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => - sendResponse(pkt) + case AvatarAction.DestroyDisplay(killer, victim, method, unk) => + sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - case PlanetsideAttribute(target_guid, attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) + if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => + sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) + sessionLogic.terminals.lastTerminalOrderFulfillment = true + AvatarActor.savePlayerData(player) - case GenericObjectAction(objectGuid, actionCode) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) + case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => + sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) + sessionLogic.terminals.lastTerminalOrderFulfillment = true - case HintsAtAttacker(sourceGuid) if player.isAlive => - sendResponse(HitHint(sourceGuid, guid)) - sessionLogic.zoning.CancelZoningProcess() - - case AvatarAction.Destroy(victim, killer, weapon, pos) => - // guid = victim // killer = killer - sendResponse(DestroyMessage(victim, killer, weapon, pos)) - - case AvatarAction.DestroyDisplay(killer, victim, method, unk) => - sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) - - case AvatarAction.TerminalOrderResult(terminalGuid, action, result) - if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => - sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) - sessionLogic.terminals.lastTerminalOrderFulfillment = true - AvatarActor.savePlayerData(player) - - case AvatarAction.TerminalOrderResult(terminalGuid, action, result) => - sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) - sessionLogic.terminals.lastTerminalOrderFulfillment = true - - case AvatarAction.ChangeExosuit( - target, - armor, - exosuit, - subtype, - _, - maxhand, - oldHolsters, - holsters, - oldInventory, - inventory, - drop, - delete - ) if resolvedPlayerGuid == target => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to this player - //cleanup - sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=false)) - (oldHolsters ++ oldInventory ++ delete).foreach { - case (_, dguid) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) - } - //functionally delete - delete.foreach { case (obj, _) => TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } - //redraw - if (maxhand) { - TaskWorkflow.execute(HoldNewEquipmentUp(player)( - Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), - 0 - )) - } - //draw free hand - player.FreeHand.Equipment.foreach { obj => + case AvatarAction.ChangeExosuit( + target, + armor, + exosuit, + subtype, + _, + maxhand, + oldHolsters, + holsters, + oldInventory, + inventory, + drop, + delete + ) if filter.resolvedPlayerGuid == target => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to this player + //cleanup + sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=false)) + (oldHolsters ++ oldInventory ++ delete).foreach { + case (_, dguid) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) + } + //functionally delete + delete.foreach { case (obj, _) => TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) } + //redraw + if (maxhand) { + TaskWorkflow.execute(HoldNewEquipmentUp(player)( + Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), + 0 + )) + } + //draw free hand + player.FreeHand.Equipment.foreach { obj => + val definition = obj.Definition + sendResponse( + ObjectCreateDetailedMessage( + definition.ObjectId, + obj.GUID, + ObjectCreateMessageParent(target, Player.FreeHandSlot), + definition.Packet.DetailedConstructorData(obj).get + ) + ) + } + //draw holsters and inventory + (holsters ++ inventory).foreach { + case InventoryItem(obj, index) => val definition = obj.Definition sendResponse( ObjectCreateDetailedMessage( definition.ObjectId, obj.GUID, - ObjectCreateMessageParent(target, Player.FreeHandSlot), + ObjectCreateMessageParent(target, index), definition.Packet.DetailedConstructorData(obj).get ) ) - } - //draw holsters and inventory - (holsters ++ inventory).foreach { - case InventoryItem(obj, index) => - val definition = obj.Definition - sendResponse( - ObjectCreateDetailedMessage( - definition.ObjectId, - obj.GUID, - ObjectCreateMessageParent(target, index), - definition.Packet.DetailedConstructorData(obj).get - ) + } + DropLeftovers(player)(drop) + + case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, _, delete) => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to some other player + sendResponse(ObjectHeldMessage(target, slot, unk1 = false)) + //cleanup + (oldHolsters ++ delete).foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } + //draw holsters + holsters.foreach { + case InventoryItem(obj, index) => + val definition = obj.Definition + sendResponse( + ObjectCreateMessage( + definition.ObjectId, + obj.GUID, + ObjectCreateMessageParent(target, index), + definition.Packet.ConstructorData(obj).get ) - } - DropLeftovers(player)(drop) - - case AvatarAction.ChangeExosuit(target, armor, exosuit, subtype, slot, _, oldHolsters, holsters, _, _, _, delete) => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to some other player - sendResponse(ObjectHeldMessage(target, slot, unk1 = false)) - //cleanup - (oldHolsters ++ delete).foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - //draw holsters - holsters.foreach { - case InventoryItem(obj, index) => - val definition = obj.Definition - sendResponse( - ObjectCreateMessage( - definition.ObjectId, - obj.GUID, - ObjectCreateMessageParent(target, index), - definition.Packet.ConstructorData(obj).get - ) - ) - } - - case AvatarAction.ChangeLoadout( - target, - armor, - exosuit, - subtype, - _, - maxhand, - oldHolsters, - holsters, - oldInventory, - inventory, - drops - ) if resolvedPlayerGuid == target => - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor)) - //happening to this player - sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=true)) - //cleanup - (oldHolsters ++ oldInventory).foreach { - case (obj, objGuid) => - sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) - TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) - } - drops.foreach(item => sendResponse(ObjectDeleteMessage(item.obj.GUID, unk1=0))) - //redraw - if (maxhand) { - TaskWorkflow.execute(HoldNewEquipmentUp(player)( - Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), - slot = 0 - )) - } - sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, player, holsters ++ inventory) - DropLeftovers(player)(drops) - - case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => - //redraw handled by callbacks - sendResponse(ArmorChangedMessage(target, exosuit, subtype)) - sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) - //happening to some other player - sendResponse(ObjectHeldMessage(target, slot, unk1=false)) - //cleanup - oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - - case AvatarAction.UseKit(kguid, kObjId) => - sendResponse( - UseItemMessage( - resolvedPlayerGuid, - kguid, - resolvedPlayerGuid, - unk2 = 4294967295L, - unk3 = false, - unk4 = Vector3.Zero, - unk5 = Vector3.Zero, - unk6 = 126, - unk7 = 0, //sequence time? - unk8 = 137, - kObjId ) - ) - sendResponse(ObjectDeleteMessage(kguid, unk1=0)) + } - case AvatarAction.KitNotUsed(_, "") => - sessionLogic.general.kitToBeUsed = None - - case AvatarAction.KitNotUsed(_, msg) => - sessionLogic.general.kitToBeUsed = None - sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - - case AvatarAction.UpdateKillsDeathsAssists(_, kda: Kill) if kda.experienceEarned > 0 => - continent.actor ! ZoneActor.RewardOurSupporters( - PlayerSource(player), - Players.produceContributionTranscriptFromKill(continent, player, kda), - kda, - kda.experienceEarned - ) - - case AvatarAction.AwardBep(charId, bep, expType) => - //if the target player, always award (some) BEP - if (charId == player.CharId) { - avatarActor ! AvatarActor.AwardBep(bep, expType) - } - - case AvatarAction.AwardCep(charId, cep) => - //if the target player, always award (some) CEP - if (charId == player.CharId) { - avatarActor ! AvatarActor.AwardCep(cep) - } - - case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => - ops.facilityCaptureRewards(buildingId, zoneNumber, cep) - - case SendResponse(msgs) => - msgs.foreach { - case pkt: AvatarImplantMessage - if pkt.player_guid == player.GUID && pkt.action == ImplantAction.Initialization => - //special spectator implants stay initialized and do not deinitialize - () - case msg => - sendResponse(msg) - } - - /* common messages (maybe once every respawn) */ - case ReloadTool(itemGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.guid).exists { _.visible } => - sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) - - case AvatarAction.Killed(_, mount) => - //log and chat messages - val cause = player.LastDamage.flatMap { damage => - val interaction = damage.interaction - val reason = interaction.cause - val adversarial = interaction.adversarial.map { _.attacker } - reason match { - case r: ExplodingEntityReason if r.entity.isInstanceOf[VehicleSpawnPad] => - //also, @SVCP_Killed_TooCloseToPadOnCreate^n~ or "... within n meters of pad ..." - sendResponse(ChatMsg(ChatMessageType.UNK_227, "@SVCP_Killed_OnPadOnCreate")) - case _ => () - } - adversarial.map {_.Name }.orElse { Some(s"a ${reason.getClass.getSimpleName}") } - }.getOrElse { s"an unfortunate circumstance (probably ${player.Sex.pronounObject} own fault)" } - log.info(s"${player.Name} has died, killed by $cause") - if (sessionLogic.shooting.shotsWhileDead > 0) { - log.warn( - s"SHOTS_WHILE_DEAD: client of ${avatar.name} fired ${sessionLogic.shooting.shotsWhileDead} rounds while character was dead on server" - ) - sessionLogic.shooting.shotsWhileDead = 0 - } - sessionLogic.zoning.CancelZoningProcess() - - //player state changes - sessionLogic.zoning.spawn.avatarActive = false - AvatarActor.updateToolDischargeFor(avatar) - player.FreeHand.Equipment.foreach { item => - DropEquipmentFromInventory(player)(item) - } - sessionLogic.general.dropSpecialSlotItem() - sessionLogic.general.toggleMaxSpecialState(enable = false) - sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive - sessionLogic.zoning.zoningStatus = Zoning.Status.None - sessionLogic.zoning.spawn.deadState = DeadState.Dead - continent.GUID(mount).collect { case obj: Vehicle => - sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) - sessionLogic.general.unaccessContainer(obj) - } - sessionLogic.actionsToCancel() - sessionLogic.terminals.CancelAllProximityUnits() - AvatarActor.savePlayerLocation(player) - sessionLogic.zoning.spawn.ShiftPosition = Some(player.Position) - - //respawn - sessionLogic.zoning.spawn.reviveTimer.cancel() - if (player.death_by == 0) { - sessionLogic.zoning.spawn.randomRespawn(300.seconds) - } else { - sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) - } - - case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => - sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - - case AvatarAction.Revive(revivalTargetGuid) if resolvedPlayerGuid == revivalTargetGuid => - log.info(s"No time for rest, ${player.Name}. Back on your feet!") - sessionLogic.zoning.spawn.reviveTimer.cancel() - sessionLogic.zoning.spawn.deadState = DeadState.Alive - player.Revive - val health = player.Health - sendResponse(PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health)) - sendResponse(AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) - continent.AvatarEvents ! MessageEnvelope( - continent.id, - PlanetsideAttribute(revivalTargetGuid, attribute_type=0, health) - ) - - /* 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(guid.guid).exists { _.visible } => - ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - - case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if isNotSameTarget => - ops.changeAmmoProcedures(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) - - case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => - sendResponse(ChangeFireModeMessage(itemGuid, mode)) - - case ConcealPlayer(_) => - sendResponse(GenericObjectActionMessage(guid, code=9)) - - case AvatarAction.EnvironmentalDamage(_, _, _) => - //TODO damage marker? - sessionLogic.zoning.CancelZoningProcess() - - case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => - sendResponse(pkt) - - case ObjectDelete(itemGuid, unk) if isNotSameTarget => - sendResponse(ObjectDeleteMessage(itemGuid, unk)) - - /* rare messages */ - case SetEmpire(objectGuid, faction) if isNotSameTarget => - sendResponse(SetEmpireMessage(objectGuid, faction)) - - case AvatarAction.DropSpecialItem() => - sessionLogic.general.dropSpecialSlotItem() - - case AvatarAction.OxygenState(player, vehicle) => - sendResponse(OxygenStateMessage( - DrowningTarget(player.guid, player.progress, player.state), - vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } + case AvatarAction.ChangeLoadout( + target, + armor, + exosuit, + subtype, + _, + maxhand, + oldHolsters, + holsters, + oldInventory, + inventory, + drops + ) if filter.resolvedPlayerGuid == target => + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor)) + //happening to this player + sendResponse(ObjectHeldMessage(target, Player.HandsDownSlot, unk1=true)) + //cleanup + (oldHolsters ++ oldInventory).foreach { + case (obj, objGuid) => + sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) + TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj)) + } + drops.foreach(item => sendResponse(ObjectDeleteMessage(item.obj.GUID, unk1=0))) + //redraw + if (maxhand) { + TaskWorkflow.execute(HoldNewEquipmentUp(player)( + Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)), + slot = 0 )) + } + sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, player, holsters ++ inventory) + DropLeftovers(player)(drops) - case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => - sendResponse(pkt) + case AvatarAction.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) => + //redraw handled by callbacks + sendResponse(ArmorChangedMessage(target, exosuit, subtype)) + sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) + //happening to some other player + sendResponse(ObjectHeldMessage(target, slot, unk1=false)) + //cleanup + oldHolsters.foreach { case (_, guid) => sendResponse(ObjectDeleteMessage(guid, unk1=0)) } - case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => - sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) - - case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => - sendResponse( - ProjectileStateMessage( - projectileGuid, - projectile.Position, - shot_vel = Vector3.Zero, - projectile.Orientation, - sequence_num=0, - end=true, - hit_target_guid=PlanetSideGUID(0) - ) + case AvatarAction.UseKit(kguid, kObjId) => + sendResponse( + UseItemMessage( + filter.resolvedPlayerGuid, + kguid, + filter.resolvedPlayerGuid, + unk2 = 4294967295L, + unk3 = false, + unk4 = Vector3.Zero, + unk5 = Vector3.Zero, + unk6 = 126, + unk7 = 0, //sequence time? + unk8 = 137, + kObjId ) - sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) + ) + sendResponse(ObjectDeleteMessage(kguid, unk1=0)) - case AvatarAction.ProjectileAutoLockAwareness(mode) => - sendResponse(GenericActionMessage(mode)) + case AvatarAction.KitNotUsed(_, "") => + sessionLogic.general.kitToBeUsed = None - case AvatarAction.PutDownFDU(target) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(target, code=53)) + case AvatarAction.KitNotUsed(_, msg) => + sessionLogic.general.kitToBeUsed = None + sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) - case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => - val definition = item.Definition - sendResponse( - ObjectCreateDetailedMessage( - definition.ObjectId, - item.GUID, - ObjectCreateMessageParent(target, slot), - definition.Packet.DetailedConstructorData(item).get - ) - ) + case AvatarAction.UpdateKillsDeathsAssists(_, kda: Kill) if kda.experienceEarned > 0 => + continent.actor ! ZoneActor.RewardOurSupporters( + PlayerSource(player), + Players.produceContributionTranscriptFromKill(continent, player, kda), + kda, + kda.experienceEarned + ) - case WeaponDryFire(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(guid.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)) + case AvatarAction.AwardBep(charId, bep, expType) => + //if the target player, always award (some) BEP + if (charId == player.CharId) { + avatarActor ! AvatarActor.AwardBep(bep, expType) + } + + case AvatarAction.AwardCep(charId, cep) => + //if the target player, always award (some) CEP + if (charId == player.CharId) { + avatarActor ! AvatarActor.AwardCep(cep) + } + + case AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, cep) => + ops.facilityCaptureRewards(buildingId, zoneNumber, cep) + + case SendResponse(msgs) => + msgs.foreach { + case pkt: AvatarImplantMessage + if pkt.player_guid == player.GUID && pkt.action == ImplantAction.Initialization => + //special spectator implants stay initialized and do not deinitialize + () + case msg => + sendResponse(msg) + } + + /* common messages (maybe once every respawn) */ + case ReloadTool(itemGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) + + case AvatarAction.Killed(_, mount) => + //log and chat messages + val cause = player.LastDamage.flatMap { damage => + val interaction = damage.interaction + val reason = interaction.cause + val adversarial = interaction.adversarial.map { _.attacker } + reason match { + case r: ExplodingEntityReason if r.entity.isInstanceOf[VehicleSpawnPad] => + //also, @SVCP_Killed_TooCloseToPadOnCreate^n~ or "... within n meters of pad ..." + sendResponse(ChatMsg(ChatMessageType.UNK_227, "@SVCP_Killed_OnPadOnCreate")) + case _ => () } + adversarial.map {_.Name }.orElse { Some(s"a ${reason.getClass.getSimpleName}") } + }.getOrElse { s"an unfortunate circumstance (probably ${player.Sex.pronounObject} own fault)" } + log.info(s"${player.Name} has died, killed by $cause") + if (sessionLogic.shooting.shotsWhileDead > 0) { + log.warn( + s"SHOTS_WHILE_DEAD: client of ${avatar.name} fired ${sessionLogic.shooting.shotsWhileDead} rounds while character was dead on server" + ) + sessionLogic.shooting.shotsWhileDead = 0 + } + sessionLogic.zoning.CancelZoningProcess() - case _ => () - } + //player state changes + sessionLogic.zoning.spawn.avatarActive = false + AvatarActor.updateToolDischargeFor(avatar) + player.FreeHand.Equipment.foreach { item => + DropEquipmentFromInventory(player)(item) + } + sessionLogic.general.dropSpecialSlotItem() + sessionLogic.general.toggleMaxSpecialState(enable = false) + sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive + sessionLogic.zoning.zoningStatus = Zoning.Status.None + sessionLogic.zoning.spawn.deadState = DeadState.Dead + continent.GUID(mount).collect { case obj: Vehicle => + sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) + sessionLogic.general.unaccessContainer(obj) + } + sessionLogic.actionsToCancel() + sessionLogic.terminals.CancelAllProximityUnits() + AvatarActor.savePlayerLocation(player) + sessionLogic.zoning.spawn.ShiftPosition = Some(player.Position) + + //respawn + sessionLogic.zoning.spawn.reviveTimer.cancel() + if (player.death_by == 0) { + sessionLogic.zoning.spawn.randomRespawn(300.seconds) + } else { + sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) + } + + case AvatarAction.ReleasePlayer(tplayer) if filter.isNotSameTarget => + sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) + + case AvatarAction.Revive(revivalTargetGuid) if filter.resolvedPlayerGuid == revivalTargetGuid => + log.info(s"No time for rest, ${player.Name}. Back on your feet!") + sessionLogic.zoning.spawn.reviveTimer.cancel() + sessionLogic.zoning.spawn.deadState = DeadState.Alive + player.Revive + val health = player.Health + sendResponse(PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health)) + sendResponse(AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true)) + continent.AvatarEvents ! MessageEnvelope( + continent.id, + PlanetsideAttribute(revivalTargetGuid, attribute_type=0, health) + ) + + /* uncommon messages (utility, or once in a while) */ + case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + 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 filter.isNotSameTarget => + sendResponse(ChangeFireModeMessage(itemGuid, mode)) + + case AvatarAction.EnvironmentalDamage(_, _, _) => + //TODO damage marker? + sessionLogic.zoning.CancelZoningProcess() + + case AvatarAction.DropCreatedItem(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + /* rare messages */ + case AvatarAction.DropSpecialItem() => + sessionLogic.general.dropSpecialSlotItem() + + case AvatarAction.OxygenState(player, vehicle) => + sendResponse(OxygenStateMessage( + DrowningTarget(player.guid, player.progress, player.state), + vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } + )) + + case AvatarAction.LoadCreatedProjectile(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if filter.isNotSameTarget => + sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) + + case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => + sendResponse( + ProjectileStateMessage( + projectileGuid, + projectile.Position, + shot_vel = Vector3.Zero, + projectile.Orientation, + sequence_num=0, + end=true, + hit_target_guid=PlanetSideGUID(0) + ) + ) + sendResponse(ObjectDeleteMessage(projectileGuid, unk1=2)) + + case AvatarAction.ProjectileAutoLockAwareness(mode) => + sendResponse(GenericActionMessage(mode)) + + case AvatarAction.PutDownFDU(target) if filter.isNotSameTarget => + sendResponse(GenericObjectActionMessage(target, code=53)) + + case AvatarAction.StowEquipment(target, slot, item) if filter.isNotSameTarget => + val definition = item.Definition + sendResponse( + ObjectCreateDetailedMessage( + definition.ObjectId, + item.GUID, + ObjectCreateMessageParent(target, slot), + definition.Packet.DetailedConstructorData(item).get + ) + ) + + case WeaponDryFire(weaponGuid) + if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.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 182f32efe..3b6a1b96e 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -1,6 +1,7 @@ // Copyright (c) 2024 PSForever 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} @@ -9,7 +10,7 @@ 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.services.base.envelope.GenericResponseEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, GenericObjectAction, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} +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} @@ -26,232 +27,173 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: //private val galaxyService: ActorRef = ops.galaxyService - /** - * na - * - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - val resolvedPlayerGuid = if (player.HasGUID) { - player.GUID - } else { - PlanetSideGUID(-1) - } - val isNotSameTarget = resolvedPlayerGuid != guid - reply match { - case VehicleAction.VehicleState( - vehicleGuid, - unk1, - pos, - orient, - vel, - unk2, - unk3, - unk4, - wheelDirection, - unk5, - unk6 - ) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => - //player who is also in the vehicle (not driver) - sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - player.Position = pos - player.Orientation = orient - player.Velocity = vel - sessionLogic.updateLocalBlockMap(pos) + def receive: Receive = { + case VehicleAction.VehicleState( + vehicleGuid, + unk1, + pos, + orient, + vel, + unk2, + unk3, + unk4, + wheelDirection, + unk5, + unk6 + ) if filter.isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => + //player who is also in the vehicle (not driver) + sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) + player.Position = pos + player.Orientation = orient + player.Velocity = vel + sessionLogic.updateLocalBlockMap(pos) - case VehicleAction.VehicleState( - vehicleGuid, - unk1, - pos, - ang, - vel, - unk2, - unk3, - unk4, - wheelDirection, - unk5, - unk6 - ) if isNotSameTarget => - //player who is watching the vehicle from the outside - sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) + case VehicleAction.VehicleState( + vehicleGuid, + unk1, + pos, + ang, + vel, + unk2, + unk3, + unk4, + wheelDirection, + unk5, + unk6 + ) if filter.isNotSameTarget => + //player who is watching the vehicle from the outside + sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => - sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) + case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if filter.isNotSameTarget => + sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) - case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) - if isNotSameTarget => - sendResponse(FrameVehicleStateMessage(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 filter.isNotSameTarget => + sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case ChangeFireState_Start(weaponGuid) if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if filter.isNotSameTarget => + sendResponse(DismountVehicleMsg(filter.resolvedPlayerGuid, bailType, wasKickedByDriver)) - case ChangeFireState_Stop(weaponGuid) if isNotSameTarget => - sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + case VehicleAction.MountVehicle(vehicleGuid, seat) if filter.isNotSameTarget => + sendResponse(ObjectAttachMessage(vehicleGuid, filter.resolvedPlayerGuid, seat)) - case ReloadTool(itemGuid) if isNotSameTarget => - sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) + case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if filter.isNotSameTarget => + sendResponse(DeployRequestMessage(filter.resolvedPlayerGuid, objectGuid, state, unk1, unk2, pos)) - case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget => - sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0)) - //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) - sendResponse( - ObjectCreateMessage( - ammo_id, - ammo_guid, - ObjectCreateMessageParent(weapon_guid, weapon_slot), - ammo_data - ) + case VehicleAction.EquipmentCreatedInSlot(pkt) if filter.isNotSameTarget => + sendResponse(pkt) + + case VehicleAction.InventoryState(obj, parentGuid, start, conData) if filter.isNotSameTarget => + //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? + val objGuid = obj.GUID + sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) + sendResponse(ObjectCreateDetailedMessage( + obj.Definition.ObjectId, + objGuid, + ObjectCreateMessageParent(parentGuid, start), + conData + )) + + case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if filter.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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + continent.GUID(vehicleGuid) match { + case Some(obj: Vehicle) => + sessionLogic.general.unaccessContainer(obj) + case _ => () + } + + 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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + + case VehicleAction.InventoryState2(objGuid, parentGuid, value) if filter.isNotSameTarget => + sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) + + case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if filter.isNotSameTarget => + //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)) + Vehicles.ReloadAccessPermissions(vehicle, player.Name) + + case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if filter.isNotSameTarget => + sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) + + case VehicleAction.UnloadVehicle(_, vehicleGuid) => + sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) + + case VehicleAction.UnstowEquipment(itemGuid) if filter.isNotSameTarget => + //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? + sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) + + case VehicleAction.UpdateAmsSpawnList(list) => + sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) + sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() + + case VehicleAction.KickCargo(vehicle, speed, delay) + if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => + val strafe = 1 + Vehicles.CargoOrientation(vehicle) + val reverseSpeed = if (strafe > 1) { 0 } else { speed } + //strafe or reverse, not both + sessionLogic.vehicles.ServerVehicleOverrideWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=true, + lock_wheel=true, + reverse=true, + unk4=false, + lock_vthrust=0, + strafe, + reverseSpeed, + unk8=Some(0) ) - sendResponse(ChangeAmmoMessage(weapon_guid, 1)) + ) + import scala.concurrent.ExecutionContext.Implicits.global + import scala.concurrent.duration._ + val resp = GenericResponseEnvelope( + VehicleStamp, + "", + PlanetSideGUID(0), + VehicleAction.KickCargo(vehicle, speed=0, delay) + ) + context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) - case WeaponDryFire(weaponGuid) 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 VehicleAction.KickCargo(cargo, _, _) + if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => + sessionLogic.vehicles.TotalDriverVehicleControl(cargo) - case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => - sendResponse(DismountVehicleMsg(guid, bailType, wasKickedByDriver)) + case VehicleSpawnPad.AttachToRails(vehicle, pad) => + sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3)) - case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => - sendResponse(ObjectAttachMessage(vehicleGuid, guid, seat)) + case VehicleSpawnPad.ConcealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=9)) - case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => - sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos)) - - case SendResponse(msgs) => - msgs.foreach(sendResponse) - - case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => - sendResponse(pkt) - - case GenericObjectAction(objectGuid, action) if isNotSameTarget => - sendResponse(GenericObjectActionMessage(objectGuid, action)) - - case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => - //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? - val objGuid = obj.GUID - sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) - sendResponse(ObjectCreateDetailedMessage( - obj.Definition.ObjectId, - objGuid, - ObjectCreateMessageParent(parentGuid, start), - conData - )) - - case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid => - //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(guid, BailType.Kicked, wasKickedByDriver)) - continent.GUID(vehicleGuid) match { - case Some(obj: Vehicle) => - sessionLogic.general.unaccessContainer(obj) - case _ => () - } - - 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(guid, BailType.Kicked, wasKickedByDriver)) - - case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => - sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) - - case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => - //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)) - Vehicles.ReloadAccessPermissions(vehicle, player.Name) - - case ObjectDelete(itemGuid, _) if isNotSameTarget => - sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - - case PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue)) - - case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => - sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) - - case VehicleAction.UnloadVehicle(_, vehicleGuid) => - sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) - - case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => - //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? - sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) - - case VehicleAction.UpdateAmsSpawnList(list) => - sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) - sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() - - case VehicleAction.KickCargo(vehicle, speed, delay) - if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => - val strafe = 1 + Vehicles.CargoOrientation(vehicle) - val reverseSpeed = if (strafe > 1) { 0 } else { speed } - //strafe or reverse, not both - sessionLogic.vehicles.ServerVehicleOverrideWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=true, - lock_wheel=true, - reverse=true, - unk4=false, - lock_vthrust=0, - strafe, - reverseSpeed, - unk8=Some(0) - ) + case VehicleSpawnPad.DetachFromRails(vehicle, pad) => + val padDefinition = pad.Definition + sendResponse( + ObjectDetachMessage( + pad.GUID, + vehicle.GUID, + pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset), + pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset ) - import scala.concurrent.ExecutionContext.Implicits.global - import scala.concurrent.duration._ - val resp = GenericResponseEnvelope( - VehicleStamp, - toChannel, - PlanetSideGUID(0), - VehicleAction.KickCargo(vehicle, speed=0, delay) - ) - context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) + ) - case VehicleAction.KickCargo(cargo, _, _) - if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => - sessionLogic.vehicles.TotalDriverVehicleControl(cargo) + case VehicleSpawnPad.ResetSpawnPad(pad) => + sendResponse(GenericObjectActionMessage(pad.GUID, code=23)) - case VehicleSpawnPad.AttachToRails(vehicle, pad) => - sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3)) + case VehicleSpawnPad.RevealPlayer(playerGuid) => + sendResponse(GenericObjectActionMessage(playerGuid, code=10)) - case VehicleSpawnPad.ConcealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=9)) + case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) => + sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) - case VehicleSpawnPad.DetachFromRails(vehicle, pad) => - val padDefinition = pad.Definition - sendResponse( - ObjectDetachMessage( - pad.GUID, - vehicle.GUID, - pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset), - pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset - ) - ) - - case VehicleSpawnPad.ResetSpawnPad(pad) => - sendResponse(GenericObjectActionMessage(pad.GUID, code=23)) - - case VehicleSpawnPad.RevealPlayer(playerGuid) => - sendResponse(GenericObjectActionMessage(playerGuid, code=10)) - - case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) => - sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle) - - case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => - //TODO when vehicle weapons can be changed without visual glitches, rewrite this - continent.GUID(target).collect { case vehicle: Vehicle => - changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) - } - - case _ => () - } + case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) => + //TODO when vehicle weapons can be changed without visual glitches, rewrite this + continent.GUID(target).collect { case vehicle: Vehicle => + changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory) + } } private def changeLoadoutDeleteOldEquipment( diff --git a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala new file mode 100644 index 000000000..4dc165152 --- /dev/null +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -0,0 +1,105 @@ +// Copyright (c) 2026 PSForever +package net.psforever.actors.session.support + +import akka.actor.Actor.Receive +import net.psforever.objects.Player +import net.psforever.services.Service +import net.psforever.services.base.message.EventResponse +import net.psforever.types.PlanetSideGUID + +trait HandlerFilter { + def resolvedPlayerGuid: PlanetSideGUID + def isNotSameTarget: Boolean + def isSameTarget: Boolean = !isNotSameTarget +} + +class HandlerFilterClass(guid1: PlanetSideGUID, guid2: PlanetSideGUID) extends HandlerFilter { + val resolvedPlayerGuid: PlanetSideGUID = guid2 + val isNotSameTarget: Boolean = resolvedPlayerGuid != guid1 +} + +object HandlerFilter { + def apply(guid1: PlanetSideGUID, guid2: PlanetSideGUID): HandlerFilter = { + new HandlerFilterClass(guid1, guid2) + } + + def apply(guid: PlanetSideGUID, player: Player): HandlerFilter = { + this(guid, if (player != null && player.HasGUID) { + player.GUID + } else { + Service.defaultPlayerGUID + }) + } + + final val NeverAllow: HandlerFilter = new HandlerFilter { + def resolvedPlayerGuid: PlanetSideGUID = PlanetSideGUID(-1) + def isNotSameTarget: Boolean = false + override def isSameTarget: Boolean = false + } + + final def Allow(guid: PlanetSideGUID): HandlerFilter = new HandlerFilter { + def resolvedPlayerGuid: PlanetSideGUID = guid + def isNotSameTarget: Boolean = true + override def isSameTarget: Boolean = true + } +} + +trait CommonHandlerFunctionsBase { + /** + * na + * @param toChannel na + * @param guid na + * @param reply na + */ + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit + + def handleWith(guid: PlanetSideGUID): Receive + + def handleWith(filter: HandlerFilter): Receive + + def receive: Receive +} + +trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { + _: CommonSessionInterfacingFunctionality => + protected var filter: HandlerFilter = HandlerFilter.NeverAllow + + /** + * na + * @param toChannel na + * @param guid na + * @param reply na + */ + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { + filter = HandlerFilter(guid, player) + receive.apply(reply) + } + + def handleWith(guid: PlanetSideGUID): Receive = { + filter = HandlerFilter(guid, player) + receive + } + + def handleWith(giveFilter: HandlerFilter): Receive = { + filter = 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 new file mode 100644 index 000000000..e66a4e84c --- /dev/null +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala @@ -0,0 +1,67 @@ +// Copyright (c) 2026 PSForever +package net.psforever.actors.session.support + +import akka.actor.Actor.Receive +import akka.actor.ActorContext +import net.psforever.objects.Tool +import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, GenericObjectActionMessage, HitHint, ObjectDeleteMessage, PlanetsideAttributeMessage, ReloadMessage, SetEmpireMessage, WeaponDryFireMessage} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire} + +class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: ActorContext) + extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions { + + def receive: Receive = { + case PlanetsideAttribute(target_guid, attributeType, attributeValue) + if filter.isNotSameTarget => + sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) + + case GenericObjectAction(objectGuid, actionCode) + if filter.isNotSameTarget => + sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) + + case ObjectDelete(itemGuid, unk) + if filter.isNotSameTarget => + sendResponse(ObjectDeleteMessage(itemGuid, unk)) + + case ChangeFireState_Start(weaponGuid) + if filter.isNotSameTarget => + sendResponse(ChangeFireStateMessage_Start(weaponGuid)) + + case ChangeFireState_Stop(weaponGuid) + if filter.isNotSameTarget => + sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) + + case ReloadTool(itemGuid) + if filter.isNotSameTarget => + sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) + + case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) + if filter.isNotSameTarget => + sessionLogic.avatarResponse.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) + sendResponse(ChangeAmmoMessage(weapon_guid, 1)) + + case WeaponDryFire(weaponGuid) + if filter.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, filter.resolvedPlayerGuid)) + sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") + + case SetEmpire(objectGuid, faction) + if filter.isNotSameTarget => + sendResponse(SetEmpireMessage(objectGuid, faction)) + + case ConcealPlayer(_) => + sendResponse(GenericObjectActionMessage(filter.resolvedPlayerGuid, code=9)) + + case SendResponse(msgs) => + msgs.foreach(sendResponse) + } +} diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index 2e613704b..bf792a866 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -10,7 +10,7 @@ import net.psforever.objects.zones.exp import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarStamp} import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} -import net.psforever.services.base.message.{EventResponse, SendResponse} +import net.psforever.services.base.message.SendResponse import net.psforever.services.chat.OutfitChannel import scala.collection.mutable @@ -21,10 +21,8 @@ import net.psforever.packet.game._ import net.psforever.types._ import net.psforever.util.Config -trait AvatarHandlerFunctions extends CommonSessionInterfacingFunctionality { +trait AvatarHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions { val ops: SessionAvatarHandlers - - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit } class SessionAvatarHandlers( @@ -37,7 +35,7 @@ class SessionAvatarHandlers( mutable.LongMap[SessionAvatarHandlers.LastUpstream]() private[session] val hidingPlayerRandomizer = new scala.util.Random - def changeAmmoProcedures( + def changeAmmoProcedure( weaponGuid: PlanetSideGUID, previousAmmoGuid: PlanetSideGUID, ammoTypeId: Int, @@ -46,7 +44,7 @@ class SessionAvatarHandlers( ammoData: ConstructorData ): Unit = { sendResponse(ObjectDetachMessage(weaponGuid, previousAmmoGuid, Vector3.Zero, 0)) - //TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) + sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0)) sendResponse( ObjectCreateMessage( ammoTypeId, diff --git a/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala index adc4d742c..419c74c0d 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionGalaxyHandlers.scala @@ -3,18 +3,13 @@ package net.psforever.actors.session.support import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.packet.game.FriendsResponse -import net.psforever.services.base.message.EventResponse -import scala.annotation.unused -// import net.psforever.actors.session.AvatarActor -trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality { +trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions { def ops: SessionGalaxyHandlers def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit - - def handle(@unused reply: EventResponse): Unit } class SessionGalaxyHandlers( diff --git a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala index 527636d03..583a83f87 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala @@ -7,17 +7,14 @@ import net.psforever.objects.ce.Deployable import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.packet.game.{GenericObjectActionMessage, ObjectDeleteMessage, PlanetsideAttributeMessage, TriggerEffectMessage} -import net.psforever.services.base.message.EventResponse import net.psforever.types.{PlanetSideGUID, Vector3} -trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality { +trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions { def ops: SessionLocalHandlers def handleTurretDeployableIsDismissed(obj: TurretDeployable): Unit def handleDeployableIsDismissed(obj: Deployable): Unit - - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit } class SessionLocalHandlers( diff --git a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala index a3d1d6cad..3b46b874f 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala @@ -5,13 +5,10 @@ import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.objects.Vehicle import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.message.EventResponse import net.psforever.types.{ChatMessageType, DriveState, PlanetSideGUID} -trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality { +trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions { def ops: SessionVehicleHandlers - - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit } class SessionVehicleHandlers( diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 900d88600..4161addcd 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -2195,7 +2195,7 @@ class ZoningOperations( log.info(s"RestoreInfo: player $name is already logged in zone ${inZone.id}; rejoining that character") sessionLogic.persistFunc = UpdatePersistence(from) //tell the old WorldSessionActor to kill itself by using its own subscriptions against itself - inZone.AvatarEvents ! MessageEnvelope(name, AvatarAction.TeardownConnection()) + inZone.AvatarEvents ! MessageEnvelope(name, AvatarAction.TeardownConnection) spawn.switchAvatarStatisticsFieldToRefreshAfterRespawn() //find and reload previous player ( diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 8b0a43f6b..5729a8e7c 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -279,7 +279,6 @@ object Vehicles { if (GlobalDefinitions.isBattleFrameVehicle(target.Definition) && target.Seat(0).isDefined) { zone.LocalEvents ! MessageEnvelope( zoneid, - PlanetSideGUID(-1), GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown.id) ) zone.LocalEvents ! MessageEnvelope( diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 5b8f7d5b2..8ba360041 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -109,7 +109,6 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) val zone = building.Zone building.Zone.AvatarEvents ! MessageEnvelope( zone.id, - building.GUID, PlanetsideAttribute(building.GUID, 47, if (resourceSilo.LowNtuWarningOn) 1 else 0) ) } @@ -133,7 +132,6 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) ) zone.AvatarEvents ! MessageEnvelope( zone.id, - resourceSilo.GUID, PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay) ) building.Actor ! BuildingActor.MapUpdate() diff --git a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala index 22e223e91..593fd920d 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarAction.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarAction.scala @@ -201,5 +201,5 @@ object AvatarAction { final case class RemoveFromOutfitChat(outfit_id: Long) extends SelfRespondingEvent - final case class TeardownConnection() extends SelfRespondingEvent + final case object TeardownConnection extends SelfRespondingEvent } diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 842ccdab4..1f23e6022 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -5,7 +5,6 @@ import akka.actor.{ActorContext, ActorRef, Props} import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.Player import net.psforever.types.{ExoSuitType, PlanetSideGUID} -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction.Release import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope, GenericSupportEnvelopeOnly} @@ -37,7 +36,7 @@ final case class ReleaseEnvelope( object ReleaseEnvelope { def apply(channel: String, actionMessage: Release): ReleaseEnvelope = - ReleaseEnvelope(channel, Service.defaultPlayerGUID, actionMessage) + ReleaseEnvelope(channel, actionMessage.player.GUID, actionMessage) } final case class CorpseEnvelope(supportMessage: Any) diff --git a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala index 231ca3104..38616a0ea 100644 --- a/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala +++ b/src/main/scala/net/psforever/services/local/support/CaptureFlagManager.scala @@ -63,7 +63,6 @@ class CaptureFlagManager(zone: Zone) extends Actor { // Override CC message when looked at zone.LocalEvents ! MessageEnvelope( zone.id, - PlanetSideGUID(-1), GenericObjectAction( capture_terminal.GUID, GenericObjectActionEnum.FlagSpawned.id diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index 06c606f30..f0af48a72 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -246,7 +246,7 @@ class HackCaptureActor extends Actor { // Notify all clients that CC has had its hack state changed terminal.Zone.LocalEvents ! MessageEnvelope( terminal.Zone.id, - PlanetSideGUID(-1), + PlanetSideGUID(-1), /*what is this?, says the person who wrote it*/ PlanetsideAttribute( terminal.GUID, PlanetsideAttributeEnum.ControlConsoleHackUpdate.id, From d1cc964a4c84da4a5f52f5f3cb016d8b73ebd585 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 30 Mar 2026 11:43:49 -0400 Subject: [PATCH 21/32] the list of event system handlers and filters for those handlers are set up differently --- .../actors/session/SessionActor.scala | 26 +++-- .../session/csr/AvatarHandlerLogic.scala | 94 +++++++++---------- .../session/normal/AvatarHandlerLogic.scala | 92 +++++++++--------- .../session/normal/LocalHandlerLogic.scala | 8 +- .../session/normal/VehicleHandlerLogic.scala | 46 ++++----- .../spectator/AvatarHandlerLogic.scala | 74 +++++++-------- .../spectator/VehicleHandlerLogic.scala | 38 ++++---- .../support/CommonHandlerFunctions.scala | 39 ++++---- .../session/support/CommonHandlerLogic.scala | 22 ++--- 9 files changed, 220 insertions(+), 219 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 9b83a7789..7150759f1 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -107,21 +107,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con private[this] val data = new SessionData(middlewareActor, context) private[this] var mode: PlayerMode = NormalMode private[this] var logic: ModeLogic = _ + private[this] var listOfHandlers: Seq[CommonHandlerFunctions] = List.empty private val commonHandlerLogic: CommonHandlerLogic = new CommonHandlerLogic(data, context) - private def listOfHandlers: Seq[CommonHandlerFunctions] = { - if (logic == null) { - List.empty - } else { - List( - logic.avatarResponse, - logic.local, - logic.vehicleResponse, - logic.galaxy, - commonHandlerLogic - ) - } - } override def postStop(): Unit = { clientKeepAlive.cancel() @@ -177,6 +165,13 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con logic.switchFrom(data.session) mode = newMode logic = newMode.setup(data) + listOfHandlers = List( + logic.avatarResponse, + logic.local, + logic.vehicleResponse, + logic.galaxy, + commonHandlerLogic + ) } logic.switchTo(data.session) } @@ -396,15 +391,16 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con CommonHandlerFunctions.HandleNothing } //try the handler on the input message + val filter = HandlerFilter(guid, data.player) lazy val alwaysAllowFilter = HandlerFilter.Allow(guid) - if (primaryHandler.handleWith(guid).isDefinedAt(reply)) { + 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(guid).isDefinedAt(reply)) + .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 { 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 0b8cbc2fd..4ad3e6dc7 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -80,9 +80,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if filter.isNotSameTarget => + ) if isNotSameTarget => val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid) match { + val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(resolvedGuid.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( - filter.resolvedPlayerGuid, + resolvedGuid, pos, vel, yaw, @@ -138,10 +138,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(resolvedGuid.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( - filter.resolvedPlayerGuid, + resolvedGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -160,28 +160,28 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) } else { //skip drawing altogether - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, 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 avatar .shortcuts .zipWithIndex .find { case (s, _) => s.isEmpty} .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) + sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, 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 val shortcut = { val imp = ImplantType.SecondWind.shortcut @@ -192,15 +192,15 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A .zipWithIndex .find { case (s, _) => s.contains(shortcut) } .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, None)) + sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, None)) } case AvatarAction.AvatarImplant(action, implant_slot, value) => - sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, action, implant_slot, value)) + sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) case AvatarAction.ObjectHeld(slot, _) - if filter.isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + if isSameTarget && player.VisibleSlots.contains(slot) => + sendResponse(ObjectHeldMessage(resolvedGuid, 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) @@ -210,31 +210,31 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if filter.isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + if isSameTarget && slot > -1 => + sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if filter.isSameTarget => () + if isSameTarget => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(resolvedGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = Some(weaponGuid))) + val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = Some(weaponGuid))) case ChangeFireState_Stop(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = None)) + val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if filter.isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if filter.isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) case AvatarAction.Destroy(victim, killer, weapon, pos) => @@ -267,7 +267,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if filter.resolvedPlayerGuid == target => + ) if resolvedGuid == target => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -349,7 +349,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if filter.resolvedPlayerGuid == target => + ) if resolvedGuid == target => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -386,9 +386,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( - filter.resolvedPlayerGuid, + resolvedGuid, kguid, - filter.resolvedPlayerGuid, + resolvedGuid, unk2 = 4294967295L, unk3 = false, unk4 = Vector3.Zero, @@ -411,7 +411,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(_, mount) => @@ -422,23 +422,23 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.zoningStatus = Zoning.Status.None continent.GUID(mount).collect { case obj: Vehicle if obj.Destroyed => - ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + ops.killedWhileMounted(obj, resolvedGuid) sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) sessionLogic.general.unaccessContainer(obj) case obj: Vehicle => - ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + ops.killedWhileMounted(obj, resolvedGuid) sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) case obj: PlanetSideGameObject with Mountable with Container if obj.Destroyed => - ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + ops.killedWhileMounted(obj, resolvedGuid) sessionLogic.general.unaccessContainer(obj) case obj: PlanetSideGameObject with Mountable with Container => - ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + ops.killedWhileMounted(obj, resolvedGuid) case obj: PlanetSideGameObject with Mountable => - ops.killedWhileMounted(obj, filter.resolvedPlayerGuid) + ops.killedWhileMounted(obj, resolvedGuid) } //player state changes sessionLogic.general.dropSpecialSlotItem() @@ -451,11 +451,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //render CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) - case AvatarAction.ReleasePlayer(tplayer) if filter.isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if filter.resolvedPlayerGuid == revivalTargetGuid => + if resolvedGuid == revivalTargetGuid => ops.revive() player.Actor ! Player.Revive player.History @@ -470,18 +470,18 @@ 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 filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => 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 filter.isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcess() - case AvatarAction.DropCreatedItem(pkt) if filter.isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) /* rare messages */ @@ -494,10 +494,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } )) - case AvatarAction.LoadCreatedProjectile(pkt) if filter.isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if filter.isNotSameTarget => + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -517,10 +517,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarAction.PutDownFDU(target) if filter.isNotSameTarget => + case AvatarAction.PutDownFDU(target) if isNotSameTarget => sendResponse(GenericObjectActionMessage(target, code=53)) - case AvatarAction.StowEquipment(target, slot, item) if filter.isNotSameTarget => + case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -532,7 +532,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage 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 25c318c3d..66ebd97fe 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -66,9 +66,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if filter.isNotSameTarget => + ) if isNotSameTarget => val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid) match { + val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(resolvedGuid.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( - filter.resolvedPlayerGuid, + resolvedGuid, pos, vel, yaw, @@ -124,10 +124,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(resolvedGuid.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( - filter.resolvedPlayerGuid, + resolvedGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -146,28 +146,28 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) } else { //skip drawing altogether - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, 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 avatar .shortcuts .zipWithIndex .find { case (s, _) => s.isEmpty} .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) + sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) if value == ImplantType.SecondWind.value => - sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, 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 val shortcut = { val imp = ImplantType.SecondWind.shortcut @@ -178,15 +178,15 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A .zipWithIndex .find { case (s, _) => s.contains(shortcut) } .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(filter.resolvedPlayerGuid, index + 1, None)) + sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, None)) } case AvatarAction.AvatarImplant(action, implant_slot, value) => - sendResponse(AvatarImplantMessage(filter.resolvedPlayerGuid, action, implant_slot, value)) + sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) case AvatarAction.ObjectHeld(slot, _) - if filter.isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + if isSameTarget && player.VisibleSlots.contains(slot) => + sendResponse(ObjectHeldMessage(resolvedGuid, 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) @@ -196,35 +196,35 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if filter.isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + if isSameTarget && slot > -1 => + sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if filter.isSameTarget => () + if isSameTarget => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(resolvedGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = Some(weaponGuid))) + val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = Some(weaponGuid))) case ChangeFireState_Stop(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = None)) + val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if filter.isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if filter.isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => - sendResponse(PlanetsideStringAttributeMessage(filter.resolvedPlayerGuid, attributeType, attributeValue)) + sendResponse(PlanetsideStringAttributeMessage(resolvedGuid, attributeType, attributeValue)) case AvatarAction.Destroy(victim, killer, weapon, pos) => // guid = victim // killer = killer @@ -260,7 +260,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if filter.resolvedPlayerGuid == target => + ) if resolvedGuid == target => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -360,7 +360,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if filter.resolvedPlayerGuid == target => + ) if resolvedGuid == target => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -400,9 +400,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( - filter.resolvedPlayerGuid, + resolvedGuid, kguid, - filter.resolvedPlayerGuid, + resolvedGuid, unk2 = 4294967295L, unk3 = false, unk4 = Vector3.Zero, @@ -451,7 +451,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(cause, mount) => @@ -517,16 +517,16 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.deadState = DeadState.Dead continent.GUID(mount).collect { case obj: Vehicle => - killedWhileMounted(obj, filter.resolvedPlayerGuid) + killedWhileMounted(obj, resolvedGuid) sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) sessionLogic.general.unaccessContainer(obj) case obj: PlanetSideGameObject with Mountable with Container => - killedWhileMounted(obj, filter.resolvedPlayerGuid) + killedWhileMounted(obj, resolvedGuid) sessionLogic.general.unaccessContainer(obj) case obj: PlanetSideGameObject with Mountable => - killedWhileMounted(obj, filter.resolvedPlayerGuid) + killedWhileMounted(obj, resolvedGuid) } sessionLogic.actionsToCancel() sessionLogic.terminals.CancelAllProximityUnits() @@ -544,11 +544,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) } - case AvatarAction.ReleasePlayer(tplayer) if filter.isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if filter.resolvedPlayerGuid == revivalTargetGuid => + if resolvedGuid == revivalTargetGuid => log.info(s"No time for rest, ${player.Name}. Back on your feet!") ops.revive() player.Actor ! Player.Revive @@ -564,18 +564,18 @@ 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 filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => 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 filter.isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") - case AvatarAction.DropCreatedItem(pkt) if filter.isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) /* rare messages */ @@ -588,10 +588,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } )) - case AvatarAction.LoadCreatedProjectile(pkt) if filter.isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if filter.isNotSameTarget => + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -611,10 +611,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarAction.PutDownFDU(target) if filter.isNotSameTarget => + case AvatarAction.PutDownFDU(target) if isNotSameTarget => sendResponse(GenericObjectActionMessage(target, code=53)) - case AvatarAction.StowEquipment(target, slot, item) if filter.isNotSameTarget => + case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -626,7 +626,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage 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 f8bb508ee..1c108d951 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -49,7 +49,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(msg) } - case LocalAction.DeployableMapIcon(behavior, deployInfo) if filter.isNotSameTarget => + case LocalAction.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget => sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) case LocalAction.DeployableUIFor(item) => @@ -68,7 +68,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act case LocalAction.Detonate(_, obj) => log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly") - case LocalAction.DoorOpens(_, door) if filter.isNotSameTarget => + case LocalAction.DoorOpens(_, door) if isNotSameTarget => val doorGuid = door.GUID val pos = player.Position.xy val range = ops.doorLoadRange() @@ -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, filter.resolvedPlayerGuid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) + sendResponse(HackMessage(HackState1.Unk0, targetGuid, resolvedGuid, 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 filter.isSameTarget /*resolvedPlayerGuid == guid*/ => + case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if isSameTarget /*resolvedPlayerGuid == guid*/ => 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 9758c53d3..c392bda74 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -47,7 +47,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if filter.isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => + ) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => //player who is also in the vehicle (not driver) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) player.Position = pos @@ -75,30 +75,30 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if filter.isNotSameTarget => + ) if isNotSameTarget => //player who is watching the vehicle from the outside sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if filter.isNotSameTarget => + case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if filter.isNotSameTarget => - sendResponse(DismountVehicleMsg(filter.resolvedPlayerGuid, bailType, wasKickedByDriver)) + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => + sendResponse(DismountVehicleMsg(resolvedGuid, bailType, wasKickedByDriver)) - case VehicleAction.MountVehicle(vehicleGuid, seat) if filter.isNotSameTarget => - sendResponse(ObjectAttachMessage(vehicleGuid, filter.resolvedPlayerGuid, seat)) + case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => + sendResponse(ObjectAttachMessage(vehicleGuid, resolvedGuid, seat)) - case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if filter.isNotSameTarget => - sendResponse(DeployRequestMessage(filter.resolvedPlayerGuid, objectGuid, state, unk1, unk2, pos)) + case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => + sendResponse(DeployRequestMessage(resolvedGuid, objectGuid, state, unk1, unk2, pos)) - case VehicleAction.EquipmentCreatedInSlot(pkt) if filter.isNotSameTarget => + case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) - case VehicleAction.InventoryState(obj, parentGuid, start, conData) if filter.isNotSameTarget => + case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -109,10 +109,10 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: conData )) - case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if filter.isSameTarget /*resolvedPlayerGuid == guid*/ => + case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if isSameTarget /*resolvedPlayerGuid == guid*/ => //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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) val typeOfRide = continent.GUID(vehicleGuid) match { case Some(obj: Vehicle) => sessionLogic.general.unaccessContainer(obj) @@ -126,28 +126,28 @@ 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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) - case VehicleAction.InventoryState2(objGuid, parentGuid, value) if filter.isNotSameTarget => + case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) - case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if filter.isNotSameTarget => + case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => //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)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleAction.Ownership(vehicleGuid) if filter.isSameTarget /*resolvedPlayerGuid == guid*/ => + case VehicleAction.Ownership(vehicleGuid) if isSameTarget /*resolvedPlayerGuid == guid*/ => //Only the player that owns this vehicle needs the ownership packet avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) - sendResponse(PlanetsideAttributeMessage(filter.resolvedPlayerGuid, attribute_type=21, vehicleGuid)) + sendResponse(PlanetsideAttributeMessage(resolvedGuid, attribute_type=21, vehicleGuid)) case VehicleAction.LoseOwnership(_, vehicleGuid) => ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") - case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if filter.isNotSameTarget => + case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) - case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if filter.isNotSameTarget => + case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if isNotSameTarget => //TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly? sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData)) @@ -164,7 +164,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed")) } - case VehicleAction.UnstowEquipment(itemGuid) if filter.isNotSameTarget => + case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) @@ -172,7 +172,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() - case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if filter.isNotSameTarget => + case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget => sessionLogic.zoning.interstellarFerry = Some(vehicle) sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}") 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 d072f0069..1e4f0b3f6 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -61,9 +61,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if filter.isNotSameTarget => + ) if isNotSameTarget => val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid) match { + val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(resolvedGuid.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( - filter.resolvedPlayerGuid, + resolvedGuid, pos, vel, yaw, @@ -119,10 +119,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(resolvedGuid.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( - filter.resolvedPlayerGuid, + resolvedGuid, 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(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) } else { //skip drawing altogether - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } case AvatarAction.ObjectHeld(slot, _) - if filter.isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + if isSameTarget && player.VisibleSlots.contains(slot) => + sendResponse(ObjectHeldMessage(resolvedGuid, 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) @@ -160,31 +160,31 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if filter.isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, slot, unk1=true)) + if isSameTarget && slot > -1 => + sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if filter.isSameTarget => () + if isSameTarget => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(filter.resolvedPlayerGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(resolvedGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = Some(weaponGuid))) + val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = Some(weaponGuid))) case ChangeFireState_Stop(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filter.resolvedPlayerGuid.guid) - ops.lastSeenStreamMessage.put(filter.resolvedPlayerGuid.guid, entry.copy(shooting = None)) + val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) + ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if filter.isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if filter.isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => sendResponse(pkt) case AvatarAction.Destroy(victim, killer, weapon, pos) => @@ -217,7 +217,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if filter.resolvedPlayerGuid == target => + ) if resolvedGuid == target => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -295,7 +295,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if filter.resolvedPlayerGuid == target => + ) if resolvedGuid == target => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor)) //happening to this player @@ -329,9 +329,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( - filter.resolvedPlayerGuid, + resolvedGuid, kguid, - filter.resolvedPlayerGuid, + resolvedGuid, unk2 = 4294967295L, unk3 = false, unk4 = Vector3.Zero, @@ -386,7 +386,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(_, mount) => @@ -440,10 +440,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) } - case AvatarAction.ReleasePlayer(tplayer) if filter.isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) - case AvatarAction.Revive(revivalTargetGuid) if filter.resolvedPlayerGuid == revivalTargetGuid => + case AvatarAction.Revive(revivalTargetGuid) if resolvedGuid == revivalTargetGuid => log.info(s"No time for rest, ${player.Name}. Back on your feet!") sessionLogic.zoning.spawn.reviveTimer.cancel() sessionLogic.zoning.spawn.deadState = DeadState.Alive @@ -458,18 +458,18 @@ 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 filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => 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 filter.isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcess() - case AvatarAction.DropCreatedItem(pkt) if filter.isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => sendResponse(pkt) /* rare messages */ @@ -482,10 +482,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } )) - case AvatarAction.LoadCreatedProjectile(pkt) if filter.isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => sendResponse(pkt) - case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if filter.isNotSameTarget => + case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -505,10 +505,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarAction.PutDownFDU(target) if filter.isNotSameTarget => + case AvatarAction.PutDownFDU(target) if isNotSameTarget => sendResponse(GenericObjectActionMessage(target, code=53)) - case AvatarAction.StowEquipment(target, slot, item) if filter.isNotSameTarget => + case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -520,7 +520,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if filter.isNotSameTarget && ops.lastSeenStreamMessage.get(filter.resolvedPlayerGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage 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 3b6a1b96e..b1c1e4fbb 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -40,7 +40,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if filter.isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => + ) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => //player who is also in the vehicle (not driver) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) player.Position = pos @@ -60,30 +60,30 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if filter.isNotSameTarget => + ) if isNotSameTarget => //player who is watching the vehicle from the outside sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) - case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if filter.isNotSameTarget => + case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) - case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if filter.isNotSameTarget => - sendResponse(DismountVehicleMsg(filter.resolvedPlayerGuid, bailType, wasKickedByDriver)) + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => + sendResponse(DismountVehicleMsg(resolvedGuid, bailType, wasKickedByDriver)) - case VehicleAction.MountVehicle(vehicleGuid, seat) if filter.isNotSameTarget => - sendResponse(ObjectAttachMessage(vehicleGuid, filter.resolvedPlayerGuid, seat)) + case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => + sendResponse(ObjectAttachMessage(vehicleGuid, resolvedGuid, seat)) - case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if filter.isNotSameTarget => - sendResponse(DeployRequestMessage(filter.resolvedPlayerGuid, objectGuid, state, unk1, unk2, pos)) + case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => + sendResponse(DeployRequestMessage(resolvedGuid, objectGuid, state, unk1, unk2, pos)) - case VehicleAction.EquipmentCreatedInSlot(pkt) if filter.isNotSameTarget => + case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) - case VehicleAction.InventoryState(obj, parentGuid, start, conData) if filter.isNotSameTarget => + case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -94,10 +94,10 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: conData )) - case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if filter.isSameTarget => + 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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) continent.GUID(vehicleGuid) match { case Some(obj: Vehicle) => sessionLogic.general.unaccessContainer(obj) @@ -107,23 +107,23 @@ 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(filter.resolvedPlayerGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) - case VehicleAction.InventoryState2(objGuid, parentGuid, value) if filter.isNotSameTarget => + case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) - case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if filter.isNotSameTarget => + case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => //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)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if filter.isNotSameTarget => + case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) case VehicleAction.UnloadVehicle(_, vehicleGuid) => sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) - case VehicleAction.UnstowEquipment(itemGuid) if filter.isNotSameTarget => + case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) 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 4dc165152..5e2020e31 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -10,17 +10,24 @@ import net.psforever.types.PlanetSideGUID trait HandlerFilter { def resolvedPlayerGuid: PlanetSideGUID def isNotSameTarget: Boolean - def isSameTarget: Boolean = !isNotSameTarget + def isSameTarget: Boolean } -class HandlerFilterClass(guid1: PlanetSideGUID, guid2: PlanetSideGUID) extends HandlerFilter { - val resolvedPlayerGuid: PlanetSideGUID = guid2 - val isNotSameTarget: Boolean = resolvedPlayerGuid != guid1 -} +case class HandlerFilterRules( + resolvedPlayerGuid: PlanetSideGUID, + isNotSameTarget: Boolean, + isSameTarget: Boolean + ) extends HandlerFilter object HandlerFilter { + def apply(guid: PlanetSideGUID, isNotSameTarget: Boolean): HandlerFilter = { + HandlerFilterRules(guid, isNotSameTarget, !isNotSameTarget) + } + def apply(guid1: PlanetSideGUID, guid2: PlanetSideGUID): HandlerFilter = { - new HandlerFilterClass(guid1, guid2) + val resolvedPlayerGuid: PlanetSideGUID = guid2 + val isNotSameTarget: Boolean = resolvedPlayerGuid != guid1 + this(guid2, isNotSameTarget) } def apply(guid: PlanetSideGUID, player: Player): HandlerFilter = { @@ -31,17 +38,9 @@ object HandlerFilter { }) } - final val NeverAllow: HandlerFilter = new HandlerFilter { - def resolvedPlayerGuid: PlanetSideGUID = PlanetSideGUID(-1) - def isNotSameTarget: Boolean = false - override def isSameTarget: Boolean = false - } + final val NeverAllow: HandlerFilter = HandlerFilterRules(PlanetSideGUID(-1), isNotSameTarget = false, isSameTarget = false) - final def Allow(guid: PlanetSideGUID): HandlerFilter = new HandlerFilter { - def resolvedPlayerGuid: PlanetSideGUID = guid - def isNotSameTarget: Boolean = true - override def isSameTarget: Boolean = true - } + final def Allow(guid: PlanetSideGUID): HandlerFilter = HandlerFilterRules(guid, isNotSameTarget = true, isSameTarget = true) } trait CommonHandlerFunctionsBase { @@ -62,7 +61,13 @@ trait CommonHandlerFunctionsBase { trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { _: CommonSessionInterfacingFunctionality => - protected var filter: HandlerFilter = HandlerFilter.NeverAllow + private var filter: HandlerFilter = HandlerFilter.NeverAllow + + def resolvedGuid: PlanetSideGUID = filter.resolvedPlayerGuid + + def isNotSameTarget: Boolean = filter.isNotSameTarget + + def isSameTarget: Boolean = filter.isSameTarget /** * na 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 e66a4e84c..c0e5772b9 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala @@ -12,36 +12,36 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac def receive: Receive = { case PlanetsideAttribute(target_guid, attributeType, attributeValue) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) case GenericObjectAction(objectGuid, actionCode) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) case ObjectDelete(itemGuid, unk) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(ObjectDeleteMessage(itemGuid, unk)) case ChangeFireState_Start(weaponGuid) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) case ChangeFireState_Stop(weaponGuid) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) case ReloadTool(itemGuid) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if filter.isNotSameTarget => + if isNotSameTarget => sessionLogic.avatarResponse.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) case WeaponDryFire(weaponGuid) - if filter.isNotSameTarget => + if isNotSameTarget => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => // check that the magazine is still empty before sending WeaponDryFireMessage @@ -51,15 +51,15 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac case HintsAtAttacker(sourceGuid) if player.isAlive => - sendResponse(HitHint(sourceGuid, filter.resolvedPlayerGuid)) + sendResponse(HitHint(sourceGuid, resolvedGuid)) sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") case SetEmpire(objectGuid, faction) - if filter.isNotSameTarget => + if isNotSameTarget => sendResponse(SetEmpireMessage(objectGuid, faction)) case ConcealPlayer(_) => - sendResponse(GenericObjectActionMessage(filter.resolvedPlayerGuid, code=9)) + sendResponse(GenericObjectActionMessage(resolvedGuid, code=9)) case SendResponse(msgs) => msgs.foreach(sendResponse) From 1e34e8239c6bd8066bd924ad9f8ffff9c1356923 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 5 Apr 2026 14:13:13 -0400 Subject: [PATCH 22/32] 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 } /** From 67990ecb83a585f78ca8795f73c8babde759fb7e Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 5 Apr 2026 16:59:54 -0400 Subject: [PATCH 23/32] special applyOrElse and isDefinedAt and guards --- .../actors/session/SessionActor.scala | 8 ++------ .../support/CommonHandlerFunctions.scala | 20 ++++++------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index fed366a6f..c7ec95f48 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -401,18 +401,14 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con 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 { + if (!responseHandler.tryToApply(reply)) { //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)) + potentiallyValidHandlers.find(_.tryToApply(reply)) } else { log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") } 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 6669b3239..11d87db63 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -59,13 +59,15 @@ trait CommonHandlerFunctionsBase { */ def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit - def handleWith(guid: PlanetSideGUID): Receive - - def handleWith(filter: HandlerFilter): Receive - def receive: Receive def isDefinedAt(x: Any): Boolean = receive.isDefinedAt(x) + + def tryToApply(x: Any): Boolean = { + var passed = true + receive.applyOrElse(x, (_: Any) => { passed = false }) + passed + } } trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { @@ -89,15 +91,5 @@ trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { receive.apply(reply) } - def handleWith(guid: PlanetSideGUID): Receive = { - HandlerFilter.set(sessionLogic.handlerFilter, guid, player) - receive - } - - def handleWith(giveFilter: HandlerFilter): Receive = { - sessionLogic.handlerFilter = giveFilter - receive - } - def receive: Receive } From 980eacdd651a454e50559567a63a00ac060d8069 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 6 Apr 2026 13:12:16 -0400 Subject: [PATCH 24/32] when to handle versus when to trytoHandle --- .../actors/session/SessionActor.scala | 22 ++++++++++--------- .../session/csr/AvatarHandlerLogic.scala | 19 +++------------- .../session/normal/GalaxyHandlerLogic.scala | 7 +----- .../support/CommonHandlerFunctions.scala | 17 +++++++------- 4 files changed, 24 insertions(+), 41 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index c7ec95f48..b34d3965f 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, CommonHandlerFunctionsBase, CommonHandlerLogic, HandlerFilter, ZoningOperations} +import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerFunctionsBase, CommonHandlerLogic, ZoningOperations} import net.psforever.objects.TurretDeployable import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.containable.Containable @@ -398,19 +398,21 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con responseHandler: CommonHandlerFunctionsBase, envelope: GenericResponseEnvelope ): Unit = { - val GenericResponseEnvelope(_, guid, reply) = envelope + val GenericResponseEnvelope(toChannel, guid, reply) = envelope //try the expected handler with the input response - val filter = HandlerFilter.set(data.handlerFilter, guid, data.player) - if (!responseHandler.tryToApply(reply)) { + if (!responseHandler.handle(toChannel, guid, reply)) { //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(_.tryToApply(reply)) - } else { - log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") + listOfHandlers.filter(_.isDefinedAt(reply)) match { + case Nil => + log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") + case first :: Nil => + first.handle(toChannel, guid, reply) + case first :: others => + if (!first.handle(toChannel, guid, reply)) { + others.find(_.tryToHandle(reply)) + } } } } 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 8ab40b969..1932dae01 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -15,7 +15,7 @@ import net.psforever.objects.vital.RevivingActivity import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction} import net.psforever.services.avatar.{AvatarAction, AvatarStamp} import net.psforever.services.base.envelope.GenericResponseEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, EventResponse, ReloadTool, WeaponDryFire} +import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, WeaponDryFire} import net.psforever.types.ImplantType // @@ -29,7 +29,6 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.zones.Zoning import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.packet.game.{ArmorChangedMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, DestroyMessage, DrowningTarget, GenericActionMessage, GenericObjectActionMessage, ItemTransactionResultMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectHeldMessage, OxygenStateMessage, PlanetsideAttributeMessage, PlayerStateMessage, ProjectileStateMessage, ReloadMessage, UseItemMessage, WeaponDryFireMessage} -import net.psforever.services.Service import net.psforever.types.{ChatMessageType, PlanetSideGUID, TransactionType, Vector3} import net.psforever.util.Config @@ -44,27 +43,15 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor - private var tempGuid: PlanetSideGUID = Service.defaultPlayerGUID - - override def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - tempGuid = guid - super.handle(toChannel, guid, reply) - } - - override def handleWith(guid: PlanetSideGUID): Receive = { - tempGuid = guid - super.handleWith(guid) - } - def receive: Receive = { /* special messages */ case AvatarAction.TeardownConnection if player.spectator => context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) - context.self.forward(GenericResponseEnvelope(AvatarStamp, "", tempGuid, AvatarAction.TeardownConnection)) + context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection)) case AvatarAction.TeardownConnection => context.self ! SessionActor.SetMode(NormalMode) - context.self.forward(GenericResponseEnvelope(AvatarStamp, "", tempGuid, AvatarAction.TeardownConnection)) + context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection)) /* really common messages (very frequently, every life) */ case pstate @ AvatarAction.PlayerState( diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index 273ffe3b7..1797959c5 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -7,9 +7,8 @@ import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers} import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo} import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.EventResponse import net.psforever.services.galaxy.GalaxyAction -import net.psforever.types.{MemberAction, PlanetSideEmpire, PlanetSideGUID} +import net.psforever.types.{MemberAction, PlanetSideEmpire} object GalaxyHandlerLogic { def apply(ops: SessionGalaxyHandlers): GalaxyHandlerLogic = { @@ -35,10 +34,6 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A /* response handlers */ - override def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - receive.apply(reply) - } - def receive: Receive = { case GalaxyAction.HotSpotUpdate(zone_index, priority, hot_spot_info) => sendResponse( 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 11d87db63..7bbd490e1 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -13,8 +13,11 @@ trait HandlerFilter { def isNotSameTarget: Boolean def isSameTarget: Boolean + def set(filter: HandlerFilter): HandlerFilter = { + set(filter.resolvedPlayerGuid, filter.otherPlayerGuid, filter.isNotSameTarget, filter.isSameTarget) + } + def set(resolved: PlanetSideGUID, other: PlanetSideGUID, notSame: Boolean, same: Boolean): HandlerFilter - def set(filter: HandlerFilter): HandlerFilter } class HandlerFilterRules extends HandlerFilter { @@ -30,10 +33,6 @@ class HandlerFilterRules extends HandlerFilter { isSameTarget = same this } - - def set(filter: HandlerFilter): HandlerFilter = { - set(filter.resolvedPlayerGuid, filter.otherPlayerGuid, filter.isNotSameTarget, filter.isSameTarget) - } } object HandlerFilter { @@ -57,13 +56,13 @@ trait CommonHandlerFunctionsBase { * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean def receive: Receive def isDefinedAt(x: Any): Boolean = receive.isDefinedAt(x) - def tryToApply(x: Any): Boolean = { + final def tryToHandle(x: Any): Boolean = { var passed = true receive.applyOrElse(x, (_: Any) => { passed = false }) passed @@ -86,9 +85,9 @@ trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { * @param guid na * @param reply na */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { + def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean = { HandlerFilter.set(sessionLogic.handlerFilter, guid, player) - receive.apply(reply) + tryToHandle(reply) } def receive: Receive From 4127f28a01fef7075f5f17bbd67664533b76ae65 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 13 Apr 2026 13:11:40 -0400 Subject: [PATCH 25/32] added config options for cached event messages, shared by all cahced event systems --- src/main/resources/application.conf | 11 +++++++ .../actors/session/SessionActor.scala | 1 + ...nericEventServiceWithCacheAndSupport.scala | 32 +++++++++++++------ .../services/base/envelope/AllEnvelopes.scala | 2 ++ .../scala/net/psforever/util/Config.scala | 9 +++++- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 86ac54b7f..765c800fe 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -575,6 +575,17 @@ network { # before it is dropped. Can be used as a watchdog for hung server sessions. outbound-grace-time = 1 minute } + + event-caching { + # The minimum amount of time a cached message has to wait before being dispatched. (ms) + # Ideal circumstances are when message traffic is light. + flush-cache-delay = 15 + # The absolute maximum amount of time a cached message has to wait before being dispatched. (ms) + flush-cache-max-delay = 50 + # The numeric difference between light traffic and heavy traffic. + # In this case, the event system's traffic density and the message caching delay are numerically synonymous. + message-traffic-threshold = 12 + } } development { diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index b34d3965f..8138c56e9 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -392,6 +392,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con case 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") } private def handleEnvelopeWithResponseHandler( diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index 3f926e1ff..fb224b619 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -7,12 +7,13 @@ import net.psforever.services.Service import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageEnvelope, MessageTransformationBehavior} import net.psforever.services.base.message.EventMessage import net.psforever.types.PlanetSideGUID +import net.psforever.util.Config import scala.collection.concurrent.{Map => CMap} import scala.jdk.CollectionConverters._ import java.util.concurrent.ConcurrentHashMap import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.duration.DurationInt +import scala.concurrent.duration.DurationLong /* Adapted from the rating limiting code in PSForever fork https://github.com/Pinapse/giant with permission @@ -97,8 +98,11 @@ class GenericEventServiceWithCacheAndSupport stamp: EventSystemStamp, eventSupportServices: List[EventServiceSupport] ) extends GenericEventServiceWithSupport(stamp, eventSupportServices) { - private val flushCacheWait: Long = 50L //milliseconds - private var hasCachedMessages: Boolean = false + private val flushCacheDelay: Long = Config.app.network.eventCaching.flushCacheDelay + private val flushCacheMaxDelay: Long = Config.app.network.eventCaching.flushCacheMaxDelay + private var hasCachedMessages: Int = 0 + private var lastCachedMessages: Int = 0 + private val messageThreshold: Long = Config.app.network.eventCaching.messageTrafficThreshold private var nextTimeToFlushCache: Long = 0L private var emergencyFlush: Cancellable = Default.Cancellable @@ -110,6 +114,14 @@ class GenericEventServiceWithCacheAndSupport super.postStop() } + private def adjustedFlushDelay(): Long = { + // flushCacheWait <= t <= emergencyFlushMaxDelay + math.min( + flushCacheDelay + math.max(0, lastCachedMessages - messageThreshold), + flushCacheMaxDelay + ) + } + /** * If there were previously no messages in the cache, * prepare to flush the cache after the intended interval passes, @@ -117,10 +129,11 @@ class GenericEventServiceWithCacheAndSupport * or if a safety timer expires and the cache is flushed in precaution. */ private def tryRetimeFlushCache(): Unit = { - if (!hasCachedMessages) { - hasCachedMessages = true - nextTimeToFlushCache = System.currentTimeMillis() + flushCacheWait - emergencyFlush = context.system.scheduler.scheduleOnce(55 milliseconds, self, FlushCachedMessages) + hasCachedMessages += 1 + if (hasCachedMessages == 1) { + val flushDelay = adjustedFlushDelay() + nextTimeToFlushCache = System.currentTimeMillis() + flushDelay + emergencyFlush = context.system.scheduler.scheduleOnce(delay = (1.25f * flushDelay).toLong milliseconds, self, FlushCachedMessages) } } @@ -145,7 +158,7 @@ class GenericEventServiceWithCacheAndSupport * flush the cache messages to the normal event system bus. */ private def tryFlushCache(): Boolean = { - val willFlush = hasCachedMessages && nextTimeToFlushCache < System.currentTimeMillis() + val willFlush = hasCachedMessages > 0 && nextTimeToFlushCache < System.currentTimeMillis() if (willFlush) { flushCache() } @@ -165,7 +178,8 @@ class GenericEventServiceWithCacheAndSupport map.clear() } } - hasCachedMessages = false + lastCachedMessages = hasCachedMessages + hasCachedMessages = 0 emergencyFlush.cancel() emergencyFlush = Default.Cancellable } diff --git a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala index 7e067d5d5..d60860743 100644 --- a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala +++ b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala @@ -12,4 +12,6 @@ trait AllEnvelopes { def channel: String /** specific subscriber endpoint to be excluded (the subscriber should filter themselves upon receipt) */ def filter: PlanetSideGUID + + val time: Long = System.currentTimeMillis() } diff --git a/src/main/scala/net/psforever/util/Config.scala b/src/main/scala/net/psforever/util/Config.scala index c814904b6..f32c2adaf 100644 --- a/src/main/scala/net/psforever/util/Config.scala +++ b/src/main/scala/net/psforever/util/Config.scala @@ -131,7 +131,8 @@ case class AntiCheatConfig( case class NetworkConfig( session: SessionConfig, - middleware: MiddlewareConfig + middleware: MiddlewareConfig, + eventCaching: CachedMessagesConfig ) case class MiddlewareConfig( @@ -147,6 +148,12 @@ case class SessionConfig( outboundGraceTime: FiniteDuration ) +case class CachedMessagesConfig( + flushCacheDelay: Long, //milliseconds + flushCacheMaxDelay: Long, //milliseconds + messageTrafficThreshold: Long +) + case class GameConfig( instantAction: InstantActionConfig, amenityAutorepairRate: Float, From df3eb4636ef774f538ae3d8d020b6baae26ebe22 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 31 May 2026 15:08:21 -0400 Subject: [PATCH 26/32] rebase to master, after a while --- .../session/csr/MountHandlerLogic.scala | 1 - .../actors/session/normal/GeneralLogic.scala | 1 - .../actors/session/normal/VehicleLogic.scala | 4 +- .../session/support/ChatOperations.scala | 14 +-- .../ShootingRangeTargetSpawnerActor.scala | 15 ++-- .../zone/building/MajorFacilityLogic.scala | 3 +- .../objects/avatar/AvatarBotActor.scala | 86 ++++++++----------- .../serverobject/dome/ForceDomeControl.scala | 17 ++-- .../objects/zones/ZonePopulationActor.scala | 16 ++-- 9 files changed, 70 insertions(+), 87 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala index 255930467..32ef38de7 100644 --- a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala @@ -7,7 +7,6 @@ import net.psforever.actors.zone.ZoneActor import net.psforever.objects.{GlobalDefinitions, PlanetSideGameObject, Player, Vehicle, Vehicles} import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.environment.interaction.ResetAllEnvironmentInteractions -import net.psforever.objects.serverobject.hackable.GenericHackables import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index 4227b15aa..076df89ac 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -43,7 +43,6 @@ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage} import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData} import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.CachedEnvelope import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.CaptureFlagManager diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala index ac91bc4ca..53affd906 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala @@ -164,7 +164,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex obj.Position = position obj.Orientation = angle obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA) @@ -217,7 +217,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex val angle = Vector3(0f, pitch, yaw) tool.Orientation = angle player.Orientation = angle - continent.VehicleEvents ! VehicleServiceMessage( + continent.VehicleEvents ! MessageEnvelope( continent.id, player.GUID, VehicleAction.ChildObjectState(object_guid, pitch, yaw) diff --git a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala index 10320bf40..0294b7531 100644 --- a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala @@ -17,8 +17,8 @@ import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.zones.{Zone, ZoneInfo} import net.psforever.packet.game.TimeOfDayMessage.GetTimeOfDayValue import net.psforever.packet.game.{SetChatFilterMessage, TimeOfDayMessage} -import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel} import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor} import net.psforever.services.teamwork.{SquadResponse, SquadService, SquadServiceResponse} @@ -1441,10 +1441,7 @@ class ChatOperations( val msg = TimeOfDayMessage(zone.GetTimeOfDay(), zone.GetTimeOfDaySpeed()) // update players in zone - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.SendResponse(Service.defaultPlayerGUID, msg) - ) + zone.AvatarEvents ! MessageEnvelope(zone.id, SendResponse(msg)) sendResponse(ChatMsg(messageType = UNK_227, contents = f"@CMT_SETTIME_OK^$hh~^$mm%02d~")) case _ => @@ -1479,10 +1476,7 @@ class ChatOperations( val msg = TimeOfDayMessage(zone.GetTimeOfDay(), zone.GetTimeOfDaySpeed()) // update players in zone - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.SendResponse(Service.defaultPlayerGUID, msg) - ) + zone.AvatarEvents ! MessageEnvelope(zone.id, SendResponse(msg)) sendResponse(ChatMsg(messageType = UNK_227, contents = s"@CMT_SETTIMESPEED_OK^$timeSpeed~")) case _ => diff --git a/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala b/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala index 1325caf09..214d7b5be 100644 --- a/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala +++ b/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala @@ -6,9 +6,10 @@ import net.psforever.objects.{Default, GlobalDefinitions, Tool, Vehicle} import net.psforever.objects.avatar.{AvatarBot, AvatarBotActor} import net.psforever.objects.guid.{GUIDTask, StraightforwardTask, TaskBundle, TaskWorkflow} import net.psforever.objects.zones.Zone -import net.psforever.services.local.{LocalAction, LocalServiceMessage} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} -import net.psforever.types.{CharacterSex, CharacterVoice, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.local.LocalAction +import net.psforever.services.vehicle.VehicleAction +import net.psforever.types.{CharacterSex, CharacterVoice, ExoSuitType, PlanetSideEmpire, Vector3} import net.psforever.util.Config import scala.collection.mutable.ListBuffer @@ -282,7 +283,6 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { * @param bot the bot to remove */ private def RemoveBot(bot: AvatarBot): Boolean = { - import net.psforever.services.Service activeInfantryTargets.indexOf(bot) match { case -1 => log.warn(s"Failed to remove bot with GUID ${bot.GUID} from ${zone.id}'s active targets list! This shouldn't happen... and probably just caused a leak.") @@ -290,9 +290,9 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { case index => activeInfantryTargets.remove(index) } - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, - LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, "bot_destroyed_effect", bot.Position, bot.Orientation) + LocalAction.TriggerEffectLocation("bot_destroyed_effect", bot.Position, bot.Orientation) ) //spawn a replacement bot context.system.scheduler.scheduleOnce( @@ -356,10 +356,9 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { def action(): Future[Any] = { zone.Transport ! Zone.Vehicle.Spawn(localVehicle) - zone.VehicleEvents ! VehicleServiceMessage( + zone.VehicleEvents ! MessageEnvelope( zone.id, VehicleAction.LoadVehicle( - PlanetSideGUID(0), localVehicle, localVehicle.Definition.ObjectId, localVehicle.GUID, diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index c53f8406d..1045dcb23 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -19,8 +19,7 @@ import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor, HackClearActor, HackClearEnvelope} -import net.psforever.services.local.LocalAction -import net.psforever.types.{PlanetSideEmpire, PlanetSideGeneratorState} +import net.psforever.types.PlanetSideEmpire /** * A package class that conveys the important information for handling facility updates. diff --git a/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala b/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala index 486289d66..b388fa988 100644 --- a/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala +++ b/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala @@ -4,7 +4,6 @@ package net.psforever.objects.avatar import akka.actor.{Actor, ActorRef} import net.psforever.actors.zone.ShootingRangeTargetSpawner import net.psforever.objects.{GlobalDefinitions, Tool} -import net.psforever.objects.avatar.AvatarBot import net.psforever.objects.equipment._ import net.psforever.objects.serverobject.aura.{Aura, AuraEffectBehavior} import net.psforever.objects.serverobject.CommonMessages @@ -14,18 +13,17 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations.Output import net.psforever.objects.zones._ import net.psforever.packet.game._ import net.psforever.types._ -import net.psforever.services.Service -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.avatar.AvatarAction import net.psforever.objects.serverobject.environment.interaction.RespondsToZoneEnvironment import net.psforever.objects.serverobject.repair.Repairable import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.vital.{HealFromEquipment, RepairFromEquipment} import net.psforever.objects.vital.etc.SuicideReason import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import java.util.concurrent.{Executors, TimeUnit} - import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ import scala.util.Random @@ -53,7 +51,7 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) def InteractiveObject: AvatarBot = bot - private[this] val log = org.log4s.getLogger(bot.Name) + //private[this] val log = org.log4s.getLogger(bot.Name) private[this] val damageLog = org.log4s.getLogger(Damageable.LogChannel) private val scheduler = Executors.newScheduledThreadPool(2) /** suffocating, or regaining breath? */ @@ -107,14 +105,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) if (!(bot.isMoving || user.isMoving)) { //only allow stationary heals val newHealth = bot.Health = originalHealth + 10 val magazine = item.Discharge() - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, + SendResponse( InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong) ) ) - events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 0, newHealth)) + events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 0, newHealth)) bot.LogActivity( HealFromEquipment( PlayerSource(user), @@ -124,10 +121,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) ) } //progress bar remains visible for all heal attempts - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, + SendResponse( RepairMessage(guid, bot.Health * 100 / definition.MaxHealth) ) ) @@ -150,14 +146,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) val newArmor = bot.Armor = originalArmor + Repairable.applyLevelModifier(user, item, RepairToolValue(item)).toInt + definition.RepairMod val magazine = item.Discharge() - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, + SendResponse( InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong) ) ) - events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 4, bot.Armor)) + events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 4, bot.Armor)) bot.LogActivity( RepairFromEquipment( PlayerSource(user), @@ -167,10 +162,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) ) } //progress bar remains visible for all repair attempts - events ! AvatarServiceMessage( + events ! MessageEnvelope( uname, - AvatarAction - .SendResponse(Service.defaultPlayerGUID, RepairMessage(guid, bot.Armor * 100 / bot.MaxArmor)) + SendResponse(RepairMessage(guid, bot.Armor * 100 / bot.MaxArmor)) ) } @@ -231,9 +225,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) //always do armor update if (damageToArmor > 0) { val zone = target.Zone - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, - AvatarAction.PlanetsideAttributeToAll(target.GUID, 4, target.Armor) + PlanetsideAttribute(target.GUID, 4, target.Armor) ) } //choose @@ -280,16 +274,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) announceConfrontation = true //TODO should we? } if (damageToHealth > 0) { - events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 0, health)) + events ! MessageEnvelope(zoneId, PlanetsideAttribute(targetGUID, 0, health)) announceConfrontation = true } val countableDamage = damageToHealth + damageToArmor if(announceConfrontation) { if (aggravated) { - events ! AvatarServiceMessage( - zoneId, - AvatarAction.SendResponse(targetGUID, AggravatedDamageMessage(targetGUID, countableDamage)) - ) + events ! MessageEnvelope(zoneId, targetGUID, SendResponse(AggravatedDamageMessage(targetGUID, countableDamage))) } else { //activity on map zone.Activity ! Zone.HotSpot.Activity(cause) @@ -332,22 +323,22 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) cause.adversarial match { case Some(a) => damageLog.info(s"${a.defender.Name} was killed by ${a.attacker.Name}") - events ! AvatarServiceMessage( + events ! MessageEnvelope( zoneChannel, AvatarAction.DestroyDisplay(a.attacker, a.defender, a.implement) ) case _ => damageLog.info(s"${bot.Name} killed ${bot.Sex.pronounObject}self") - events ! AvatarServiceMessage(zoneChannel, AvatarAction.DestroyDisplay(cause.interaction.target, cause.interaction.target, 0)) + events ! MessageEnvelope(zoneChannel, AvatarAction.DestroyDisplay(cause.interaction.target, cause.interaction.target, 0)) } - events ! AvatarServiceMessage(nameChannel, AvatarAction.Killed(bot_guid, cause, None)) //align client interface fields with state - events ! AvatarServiceMessage(zoneChannel, AvatarAction.PlanetsideAttributeToAll(bot_guid, 0, 0)) //health + events ! MessageEnvelope(nameChannel, bot_guid, AvatarAction.Killed(cause, None)) //align client interface fields with state + events ! MessageEnvelope(zoneChannel, PlanetsideAttribute(bot_guid, 0, 0)) //health val attribute = DamageableEntity.attributionTo(cause, target.Zone, bot_guid) - events ! AvatarServiceMessage( + events ! MessageEnvelope( nameChannel, - AvatarAction.SendResponse( - bot_guid, + bot_guid, + SendResponse( DestroyMessage(bot_guid, attribute, bot_guid, pos) ) //how many players get this message? ) @@ -402,13 +393,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) private def performEmote(): Unit = { val zone = bot.Zone zone.blockMap.sector(bot).livePlayerList.collect { t => - zone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(TriggerBotAction(bot.GUID))) + zone.LocalEvents ! MessageEnvelope(t.Name, SendResponse(TriggerBotAction(bot.GUID))) } } private def tickLogic(): Unit = { val zone = bot.Zone - if (!bot.Destroyed && zone.AllPlayers.size > 0) { + if (!bot.Destroyed && zone.AllPlayers.nonEmpty) { bot.zoneInteractions() val rotateRNG = Random.nextDouble() if (canRotate) { @@ -424,10 +415,10 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) ) } } - zone.AvatarEvents ! AvatarServiceMessage( + zone.AvatarEvents ! MessageEnvelope( zone.id, + bot.GUID, AvatarAction.PlayerState( - bot.GUID, bot.Position, bot.Velocity, bot.Orientation.z, @@ -436,10 +427,10 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) 0, bot.Crouching, bot.Jumping, - false, - bot.Cloaked, - false, - false + jump_thrust = false, + is_cloaked = bot.Cloaked, + spectator = false, + weaponInHand = false ) ) if (canEmote) { @@ -469,9 +460,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) override def StartJammeredSound(target: Any, dur: Int): Unit = target match { case obj: AvatarBot if !jammedSound => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( obj.Zone.id, - AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 1) + PlanetsideAttribute(obj.GUID, 27, 1) ) super.StartJammeredSound(obj, 3000) case _ => ; @@ -502,9 +493,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) override def CancelJammeredSound(target: Any): Unit = target match { case obj: AvatarBot if jammedSound => - obj.Zone.AvatarEvents ! AvatarServiceMessage( + obj.Zone.AvatarEvents ! MessageEnvelope( obj.Zone.id, - AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 0) + PlanetsideAttribute(obj.GUID, 27, 0) ) super.CancelJammeredSound(obj) case _ => ; @@ -521,10 +512,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) } def UpdateAuraEffect(target: AuraEffectBehavior.Target) : Unit = { - import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} val zone = target.Zone val value = target.Aura.foldLeft(0)(_ + AvatarBotActor.auraEffectToAttributeValue(_)) - zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(target.GUID, 54, value)) + zone.AvatarEvents ! MessageEnvelope(zone.id, PlanetsideAttribute(target.GUID, 54, value)) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala b/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala index 802a6ed31..2e67095b5 100644 --- a/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala @@ -14,8 +14,9 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.prop.DamageWithPosition import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.Service -import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.SendResponse +import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGeneratorState, Vector3} import scala.annotation.unused @@ -45,9 +46,9 @@ object ForceDomeControl { val owner = dome.Owner val zone = owner.Zone owner.Actor ! BuildingActor.AmenityStateChange(dome) - zone.LocalEvents ! LocalServiceMessage( + zone.LocalEvents ! MessageEnvelope( zone.id, - LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, owner.GUID, activationState) + LocalAction.UpdateForceDomeStatus(owner.GUID, activationState) ) } @@ -124,11 +125,11 @@ object ForceDomeControl { state: Boolean ): Unit = { val zone = building.Zone - val message = LocalAction.SendResponse(ChatMsg( + val message = SendResponse(ChatMsg( ChatMessageType.UNK_229, s"The Capitol force dome at ${building.Name} will remain ${if (state) "activated" else "deactivated"}." )) - zone.LocalEvents ! LocalServiceMessage(zone.id, message) + zone.LocalEvents ! MessageEnvelope(zone.id, message) } /** @@ -138,12 +139,12 @@ object ForceDomeControl { */ def NormalDomeStateMessage(building: Building): Unit = { val events = building.Zone.LocalEvents - val message = LocalAction.SendResponse(ChatMsg( + val message = SendResponse(ChatMsg( ChatMessageType.UNK_227, "Expected capitol force dome state change will resume." )) building.PlayersInSOI.foreach { player => - events ! LocalServiceMessage(player.Name, message) + events ! MessageEnvelope(player.Name, message) } } diff --git a/src/main/scala/net/psforever/objects/zones/ZonePopulationActor.scala b/src/main/scala/net/psforever/objects/zones/ZonePopulationActor.scala index e972808d6..c276cf0c3 100644 --- a/src/main/scala/net/psforever/objects/zones/ZonePopulationActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZonePopulationActor.scala @@ -7,7 +7,9 @@ import net.psforever.objects.avatar.{AvatarBot, CorpseControl, PlayerControl} import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.vital.{InGameHistory, SpawningActivity} import net.psforever.objects.{Default, Player} -import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} +import net.psforever.services.avatar.AvatarAction +import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.message.ObjectDelete import net.psforever.types.Vector3 import scala.collection.concurrent.TrieMap @@ -88,9 +90,9 @@ class ZonePopulationActor(zone: Zone, playerMap: TrieMap[Int, Option[Player]], b if (BotSpawn(bot, botList)) { bot.Zone = zone zone.actor ! ZoneActor.AddToBlockMap(bot, bot.Position) - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.LoadPlayer(bot.GUID, bot.Definition.ObjectId, bot.GUID, bot.Definition.Packet.ConstructorData(bot).get, None) + zone.AvatarEvents ! MessageEnvelope( + zone.id, bot.GUID, + AvatarAction.LoadPlayer(bot.Definition.ObjectId, bot.GUID, bot.Definition.Packet.ConstructorData(bot).get, None) ) } @@ -99,9 +101,9 @@ class ZonePopulationActor(zone: Zone, playerMap: TrieMap[Int, Option[Player]], b if (bot.Actor != null) bot.Actor ! akka.actor.PoisonPill bot.Actor = Default.Actor zone.actor ! ZoneActor.RemoveFromBlockMap(bot) - zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.ObjectDelete(bot.GUID, bot.GUID, unk=0) + zone.AvatarEvents ! MessageEnvelope( + zone.id, bot.GUID, + ObjectDelete(bot.GUID, unk=0) ) } From f1b0d2e92042598f47fe2705898938ad7871d746 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 31 May 2026 16:21:12 -0400 Subject: [PATCH 27/32] moved the default guid-0 from service to default --- .../session/normal/LocalHandlerLogic.scala | 6 ++--- .../session/spectator/SpectatorMode.scala | 5 ++-- .../support/CommonHandlerFunctions.scala | 9 +++---- .../session/support/GeneralOperations.scala | 2 +- .../support/SessionAvatarHandlers.scala | 3 +-- .../WeaponAndProjectileOperations.scala | 3 +-- .../session/support/ZoningOperations.scala | 4 +-- .../net/psforever/login/WorldSession.scala | 2 +- .../scala/net/psforever/objects/Default.scala | 5 ++++ .../objects/ExplosiveDeployable.scala | 3 +-- .../scala/net/psforever/objects/Players.scala | 7 +++--- .../net/psforever/objects/Vehicles.scala | 3 +-- .../objects/avatar/PlayerControl.scala | 5 ++-- .../objects/ce/DeployableBehavior.scala | 5 ++-- .../damage/DamageableEntity.scala | 6 ++--- .../damage/DamageableMountable.scala | 9 +++---- .../damage/DamageableVehicle.scala | 9 +++---- .../damage/DamageableWeaponTurret.scala | 2 +- .../deploy/DeploymentBehavior.scala | 3 --- .../serverobject/doors/DoorControl.scala | 3 +-- .../repair/RepairableEntity.scala | 2 +- .../repair/RepairableWeaponTurret.scala | 2 +- .../turret/auto/AutomatedTurretBehavior.scala | 3 +-- .../objects/vehicles/CarrierBehavior.scala | 3 +-- .../objects/vehicles/control/ApcControl.scala | 3 +-- .../objects/vehicles/control/BfrControl.scala | 5 ++-- .../objects/zones/ZoneProjectileActor.scala | 8 +++--- .../services/CavernRotationService.scala | 6 ++--- .../net/psforever/services/Service.scala | 3 --- .../avatar/support/DroppedItemRemover.scala | 6 ++--- ...nericEventServiceWithCacheAndSupport.scala | 11 ++++---- .../base/GenericEventServiceWithSupport.scala | 6 ++--- .../base/envelope/MessageEnvelope.scala | 6 ++--- .../psforever/services/hart/HartTimer.scala | 3 +-- .../services/local/LocalAction.scala | 5 ++-- .../local/support/DoorCloseActor.scala | 3 +-- .../teamwork/SquadServiceResponse.scala | 4 +-- src/test/scala/objects/DeployableTest.scala | 2 +- .../base/EventServiceCacheSupportTest.scala | 5 ++-- .../scala/service/base/EventServiceTest.scala | 25 ++++++++++--------- .../service/base/EventServiceTestBase.scala | 4 +-- .../scala/service/local/LocalActionTest.scala | 2 +- 42 files changed, 96 insertions(+), 115 deletions(-) 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 11a6741ea..3a8258687 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -8,7 +8,7 @@ import net.psforever.actors.session.support.{LocalHandlerFunctions, SessionData, import net.psforever.objects.ce.Deployable 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.objects.{BoomerDeployable, Default, 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.{PlanetsideAttribute, SendResponse} import net.psforever.services.{InterstellarClusterService, Service} @@ -169,10 +169,10 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act } case LocalAction.ProximityTerminalEffect(object_guid, true) => - sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, object_guid, unk=true)) + sendResponse(ProximityTerminalUseMessage(Default.GUID0, object_guid, unk=true)) case LocalAction.ProximityTerminalEffect(objectGuid, false) => - sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, objectGuid, unk=false)) + sendResponse(ProximityTerminalUseMessage(Default.GUID0, objectGuid, unk=false)) sessionLogic.terminals.ForgetAllProximityTerminals(objectGuid) case LocalAction.RouterTelepadMessage(msg) => diff --git a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala index f30b0d80e..59d438d3b 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala @@ -6,11 +6,10 @@ import net.psforever.actors.zone.ZoneActor import net.psforever.objects.avatar.{BattleRank, CommandRank, DeployableToolbox, FirstTimeEvents, Implant, ProgressDecoration, Shortcut => AvatarShortcut} import net.psforever.objects.ce.Deployable import net.psforever.objects.serverobject.ServerObject -import net.psforever.objects.{GlobalDefinitions, Player, Session, SimpleItem, Vehicle} +import net.psforever.objects.{Default, GlobalDefinitions, Player, Session, SimpleItem, Vehicle} import net.psforever.packet.PlanetSidePacket import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage, DeploymentAction, ObjectCreateDetailedMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete import net.psforever.services.chat.SpectatorChannel @@ -112,7 +111,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic { .foreach { obj => sendResponse(DeployableObjectsInfoMessage( DeploymentAction.Dismiss, - DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Service.defaultPlayerGUID) + DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Default.GUID0) )) } if (player.silenced) { 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 7bbd490e1..6b330edc8 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -2,8 +2,7 @@ package net.psforever.actors.session.support import akka.actor.Actor.Receive -import net.psforever.objects.Player -import net.psforever.services.Service +import net.psforever.objects.{Default, Player} import net.psforever.services.base.message.EventResponse import net.psforever.types.PlanetSideGUID @@ -21,8 +20,8 @@ trait HandlerFilter { } class HandlerFilterRules extends HandlerFilter { - var resolvedPlayerGuid: PlanetSideGUID = Service.defaultPlayerGUID - var otherPlayerGuid: PlanetSideGUID = Service.defaultPlayerGUID + var resolvedPlayerGuid: PlanetSideGUID = Default.GUID0 + var otherPlayerGuid: PlanetSideGUID = Default.GUID0 var isNotSameTarget: Boolean = false var isSameTarget: Boolean = false @@ -41,7 +40,7 @@ object HandlerFilter { val pguid = player.GUID filter.set(pguid, guid, pguid != guid, pguid == guid) } else { - filter.set(Service.defaultPlayerGUID, guid, notSame = true, same = false) + filter.set(Default.GUID0, guid, notSame = true, same = false) } filter } diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index a3e046ae5..b11479e7f 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -906,7 +906,7 @@ class GeneralOperations( * @param unk2 na */ def hackObject(targetGuid: PlanetSideGUID, unk1: Long, unk2: HackState7): Unit = { - sendResponse(HackMessage(HackState1.Unk0, targetGuid, player_guid=Service.defaultPlayerGUID, progress=100, unk1.toFloat, HackState.Hacked, unk2)) + sendResponse(HackMessage(HackState1.Unk0, targetGuid, player_guid=Default.GUID0, progress=100, unk1.toFloat, HackState.Hacked, unk2)) } /** diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index bf792a866..2ac39d632 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -7,7 +7,6 @@ import net.psforever.objects.{Default, PlanetSideGameObject, Player, Vehicle} import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, UniquePlayer} import net.psforever.packet.game.objectcreate.ConstructorData import net.psforever.objects.zones.exp -import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarStamp} import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse @@ -214,7 +213,7 @@ class SessionAvatarHandlers( context.self ! GenericResponseEnvelope( AvatarStamp, playerName, - Service.defaultPlayerGUID, + Default.GUID0, SendResponse(ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero)) ) //player no longer seated diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index 0fcfef466..93dc18e4d 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -27,7 +27,6 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.UplinkRequest -import net.psforever.services.Service import net.psforever.services.base.CachedEnvelope import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire} @@ -352,7 +351,7 @@ class WeaponAndProjectileOperations( player.Zone.LocalEvents ! MessageEnvelope( s"${player.Zone.id}", PlanetSideGUID(-1), - SendResponse(TriggerEffectMessage(Service.defaultPlayerGUID, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))) + SendResponse(TriggerEffectMessage(Default.GUID0, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))) ) context.system.scheduler.scheduleOnce(delay = 1 seconds) { Zone.serverSideDamage(player.Zone, player, empSize, SpecialEmp.createEmpInteraction(empSize, player.Position), diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 4161addcd..9755017f0 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -1124,7 +1124,7 @@ class ZoningOperations( case obj if obj.Destroyed => configAmenityAsDestroyed(obj) case obj => configAmenityAsWorking(obj) } - //sendResponse(HackMessage(HackState1.Unk3, guid, Service.defaultPlayerGUID, progress=0, -1f, HackState.HackCleared, HackState7.Unk8)) + //sendResponse(HackMessage(HackState1.Unk3, guid, Default.GUID0, progress=0, -1f, HackState.HackCleared, HackState7.Unk8)) } } @@ -1976,7 +1976,7 @@ class ZoningOperations( guid, Deployable.Icon(obj.Definition.Item), obj.Position, - obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID) + obj.OwnerGuid.getOrElse(Default.GUID0) ))) } } diff --git a/src/main/scala/net/psforever/login/WorldSession.scala b/src/main/scala/net/psforever/login/WorldSession.scala index 25ebec529..d89c31765 100644 --- a/src/main/scala/net/psforever/login/WorldSession.scala +++ b/src/main/scala/net/psforever/login/WorldSession.scala @@ -290,7 +290,7 @@ object WorldSession { * @see `ObjectHeldMessage` * @see `Player.DrawnSlot` * @see `Player.LastDrawnSlot` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `TaskBundle` * @see `Zone.AvatarEvents` * @param player the player whose visible slot will be equipped and drawn diff --git a/src/main/scala/net/psforever/objects/Default.scala b/src/main/scala/net/psforever/objects/Default.scala index 09cd99b87..b94c2c8f2 100644 --- a/src/main/scala/net/psforever/objects/Default.scala +++ b/src/main/scala/net/psforever/objects/Default.scala @@ -1,7 +1,12 @@ // Copyright (c) 2017 PSForever package net.psforever.objects +import net.psforever.types.{PlanetSideGUID, ValidPlanetSideGUID} + object Default { + //'g'lobal 'u'nique 'id'entifier + final val GUID0: PlanetSideGUID = ValidPlanetSideGUID(0) + //cancellable import akka.actor.Cancellable protected class InternalCancellable extends Cancellable { diff --git a/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala b/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala index 91f3883f1..075f756d6 100644 --- a/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala +++ b/src/main/scala/net/psforever/objects/ExplosiveDeployable.scala @@ -17,7 +17,6 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.objects.vital.projectile.ProjectileReason import net.psforever.objects.zones.Zone import net.psforever.types.Vector3 -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.local.LocalAction @@ -213,7 +212,7 @@ object ExplosiveDeployableControl { target.Destroyed = true zone.AvatarEvents ! MessageEnvelope( zone.id, - AvatarAction.Destroy(target.GUID, attribution, Service.defaultPlayerGUID, target.Position) + AvatarAction.Destroy(target.GUID, attribution, Default.GUID0, target.Position) ) if (target.Health == 0) { zone.LocalEvents ! MessageEnvelope( diff --git a/src/main/scala/net/psforever/objects/Players.scala b/src/main/scala/net/psforever/objects/Players.scala index c5df2a0cb..30203cc70 100644 --- a/src/main/scala/net/psforever/objects/Players.scala +++ b/src/main/scala/net/psforever/objects/Players.scala @@ -19,7 +19,6 @@ import net.psforever.objects.vital.{InGameActivity, InGameHistory, RevivingActiv import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.types.{ChatMessageType, ExoSuitType, PlanetSideGUID, Vector3} -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{ObjectDelete, SendResponse} @@ -78,12 +77,12 @@ object Players { PlayerControl.sendResponse( target.Zone, medicName, - Service.defaultPlayerGUID, + Default.GUID0, SendResponse( InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine) ) ) - PlayerControl.sendResponse(target.Zone, name, Service.defaultPlayerGUID, AvatarAction.Revive(target.GUID)) + PlayerControl.sendResponse(target.Zone, name, Default.GUID0, AvatarAction.Revive(target.GUID)) } /** @@ -165,7 +164,7 @@ object Players { ExoSuitDefinition.Select(exosuit, player.Faction).Permissions match { case Nil => true - case permissions if player.IsInVRZone => + case _ if player.IsInVRZone => true case permissions if subtype != 0 => val certs = player.avatar.certifications diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 5729a8e7c..5cf4abbe8 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -12,7 +12,6 @@ import net.psforever.objects.vehicles._ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire} import net.psforever.services.local.LocalAction @@ -92,7 +91,7 @@ object Vehicles { ReloadAccessPermissions(vehicle, vehicle.Faction.toString) zone.VehicleEvents ! MessageEnvelope( zone.id, - VehicleAction.LoseOwnership(ownerGuid.getOrElse(Service.defaultPlayerGUID), guid) + VehicleAction.LoseOwnership(ownerGuid.getOrElse(Default.GUID0), guid) ) result } diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index f66ae7cab..b25803856 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -25,7 +25,6 @@ import net.psforever.objects.zones._ import net.psforever.packet.game._ import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent import net.psforever.types._ -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction import net.psforever.services.local.LocalAction import net.psforever.objects.locker.LockerContainerControl @@ -768,7 +767,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm case GlobalDefinitions.router_telepad => () /* no special animation */ case GlobalDefinitions.ace if obj.Definition.deployAnimation == DeployAnimation.Standard => - val ownerGuid = obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID) + val ownerGuid = obj.OwnerGuid.getOrElse(Default.GUID0) zone.LocalEvents ! MessageEnvelope( zone.id, ownerGuid, @@ -1061,7 +1060,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm val attribute = DamageableEntity.attributionTo(cause, target.Zone, player_guid) events ! MessageEnvelope( nameChannel, - SendResponse(DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos)) //how many players get this message? + SendResponse(DestroyMessage(player_guid, attribute, Default.GUID0, pos)) //how many players get this message? ) } diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index f1bba9f3b..7100c7580 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -6,7 +6,6 @@ import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects._ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SetEmpire import net.psforever.services.local.LocalAction @@ -112,7 +111,7 @@ trait DeployableBehavior { obj, toOwner = "", toFaction, - DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Service.defaultPlayerGUID) + DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Default.GUID0) ) startOwnerlessDecay() } @@ -203,7 +202,7 @@ trait DeployableBehavior { //zone map icon localEvents ! MessageEnvelope( obj.Faction.toString, - LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID))) + LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Default.GUID0))) ) //local build management callback ! Zone.Deployable.IsBuilt(obj) diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala index 9209e5764..1e5224f04 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableEntity.scala @@ -1,13 +1,13 @@ //Copyright (c) 2020 PSForever package net.psforever.objects.serverobject.damage +import net.psforever.objects.Default import net.psforever.objects.equipment.JammableUnit import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.resolution.ResolutionCalculations import net.psforever.objects.zones.Zone import net.psforever.types.PlanetSideGUID -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.PlanetsideAttribute @@ -146,7 +146,7 @@ object DamageableEntity { * @see `SendResponse` * @see `DamageFeedbackMessage` * @see `JammableUnit.Jammered` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `Zone.Activity` * @see `Zone.AvatarEvents` * @see `Zone.HotSpot.Activity` @@ -204,7 +204,7 @@ object DamageableEntity { else { zone.AvatarEvents ! MessageEnvelope( zoneId, - AvatarAction.Destroy(tguid, attribution, Service.defaultPlayerGUID, target.Position) + AvatarAction.Destroy(tguid, attribution, Default.GUID0, target.Position) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala index 99c076071..ec076c715 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala @@ -1,12 +1,11 @@ //Copyright (c) 2020 PSForever package net.psforever.objects.serverobject.damage -import net.psforever.objects.Player +import net.psforever.objects.{Default, Player} import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.game.DamageWithPositionMessage -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{HintsAtAttacker, SendResponse} @@ -23,7 +22,7 @@ object DamageableMountable { * @see `SendResponse` * @see `DamageWithPositionMessage` * @see `Mountable.Seats` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `Zone.AvatarEvents` * @see `Zone.LivePlayers` * @param target the entity being damaged @@ -53,11 +52,11 @@ object DamageableMountable { case msg @ HintsAtAttacker(guid) => occupants.map { tplayer => (tplayer.Name, guid, msg) } case msg => - occupants.map { tplayer => (tplayer.Name, Service.defaultPlayerGUID, msg) } + occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) } } case Some(source) => //object damage val msg = SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) - occupants.map { tplayer => (tplayer.Name, Service.defaultPlayerGUID, msg) } + occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) } case None => List.empty }).foreach { diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index ced4764d0..925484cab 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -2,7 +2,7 @@ package net.psforever.objects.serverobject.damage import akka.actor.{Actor, Cancellable} -import net.psforever.objects.{Vehicle, Vehicles} +import net.psforever.objects.{Default, Vehicle, Vehicles} import net.psforever.objects.equipment.JammableUnit import net.psforever.objects.serverobject.damage.Damageable.Target import net.psforever.objects.sourcing.VehicleSource @@ -12,7 +12,6 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations import net.psforever.objects.zones.Zone import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.DamageWithPositionMessage -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.types.Vector3 @@ -103,7 +102,7 @@ trait DamageableVehicle * Most all vehicles and the weapons mounted to them can jam * if the projectile that strikes (near) them has jammering properties. * If this vehicle has shields that were affected by previous damage, that is also reported to the clients. - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `Vehicle.CargoHolds` * @see `PlanetsideAttribute` * @param target the entity being destroyed @@ -180,7 +179,7 @@ trait DamageableVehicle * Finally, the vehicle is tasked for deconstruction. * @see `Deployment.TryDeploymentChange` * @see `DriveState.Undeploying` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `Vehicle.CargoHolds` * @see `PlanetsideAttribute` * @see `RemoverActor.AddTask` @@ -241,7 +240,7 @@ trait DamageableVehicle import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ val obj = DamageableObject - val guid0 = Service.defaultPlayerGUID + val guid0 = Default.GUID0 val zone = obj.Zone val zoneid = zone.id val events = zone.VehicleEvents diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index 70dcae811..7769ac6b8 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -106,7 +106,7 @@ object DamageableWeaponTurret { * @see `DeleteObject` * @see `MountedWeapons` * @see `MountedWeapons.Weapons` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `TurretUpgrade.None` * @see `TurretUpgrader.AddTask` * @see `TurretUpgrader.ClearSpecific` diff --git a/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala index be644a067..2544b2ded 100644 --- a/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/deploy/DeploymentBehavior.scala @@ -4,7 +4,6 @@ package net.psforever.objects.serverobject.deploy import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Default import net.psforever.types.{DriveState, Vector3} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.vehicle.VehicleAction @@ -98,7 +97,6 @@ trait DeploymentBehavior { val guid = obj.GUID val zone = obj.Zone val zoneChannel = zone.id - val GUID0 = Service.defaultPlayerGUID //TODO remove this arbitrary allowance angle when no longer helpful if (obj.Orientation.x > 30 && obj.Orientation.x < 330) { obj.DeploymentState = prevState @@ -135,7 +133,6 @@ trait DeploymentBehavior { val guid = obj.GUID val zone = obj.Zone val zoneChannel = zone.id - val GUID0 = Service.defaultPlayerGUID if (state == DriveState.Undeploying) { zone.VehicleEvents ! MessageEnvelope( zoneChannel, diff --git a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala index 5f00c5d83..056966621 100644 --- a/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/doors/DoorControl.scala @@ -7,7 +7,6 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} import net.psforever.objects.serverobject.locks.IFFLock import net.psforever.objects.serverobject.structures.PoweredAmenityControl -import net.psforever.services.Service import net.psforever.services.base.envelope.GenericResponseEnvelope import net.psforever.services.base.support.SupportActor import net.psforever.services.local.support.{DoorCloseActor, DoorMessage} @@ -120,7 +119,7 @@ object DoorControl { replyTo ! GenericResponseEnvelope( LocalStamp, player.Name, - Service.defaultPlayerGUID, + Default.GUID0, LocalAction.DoorOpens(door.Zone, door) ) } diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala index a9f436a63..53130db81 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableEntity.scala @@ -73,7 +73,7 @@ trait RepairableEntity extends Repairable { * @see `InventoryStateMessage` * @see `PlanetSideGameObject.isMoving` * @see `RepairMessage` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `Tool.Discharge` * @see `Zone.AvatarEvents` * @param target the entity being repaired diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala index b712fb957..19579139c 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala @@ -28,7 +28,7 @@ object RepairableWeaponTurret { * and may have been concealed/deleted when the target was destroyed. * @see `MountedWeapons` * @see `MountedWeapons.Weapons` - * @see `Service.defaultPlayerGUID` + * @see `Default.GUID0` * @see `WeaponTurret` * @see `EquipmentInSlot` * @see `Zone.VehicleEvents` diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala index 53221f7b8..0e3cd9add 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/auto/AutomatedTurretBehavior.scala @@ -17,7 +17,6 @@ import net.psforever.objects.zones.Zone import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.objects.{Default, PlanetSideGameObject, Player} import net.psforever.packet.game.{ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ObjectDetectedMessage} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.types.{PlanetSideGUID, Vector3} @@ -880,7 +879,7 @@ object AutomatedTurretBehavior { EffectTarget.Validation.AutoTurretBlankVehicleTarget ) - private val noTargets: List[PlanetSideGUID] = List(Service.defaultPlayerGUID) + private val noTargets: List[PlanetSideGUID] = List(Default.GUID0) /** * Are we tracking a target entity? diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala index 84c96de5f..36e254636 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala @@ -9,7 +9,6 @@ import net.psforever.objects.sourcing.VehicleSource import net.psforever.objects.vital.VehicleCargoMountActivity import net.psforever.packet.game.{CargoMountPointStatusMessage, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} import net.psforever.types.{BailType, CargoStatus, PlanetSideGUID, Vector3} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.VehicleAction @@ -440,7 +439,7 @@ object CarrierBehavior { //the lodestar's cargo hold is almost the center of the vehicle carrier.Position } - val GUID0 = Service.defaultPlayerGUID + val GUID0 = Default.GUID0 val zoneId = zone.id val events = zone.VehicleEvents val cargoActor = cargo.Actor diff --git a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala index 1650d6657..09236c8ae 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/ApcControl.scala @@ -10,7 +10,6 @@ import net.psforever.objects.vital.projectile.MaxDistanceCutoff import net.psforever.objects.vital.prop.DamageWithPosition import net.psforever.objects.zones.Zone import net.psforever.packet.game.{TriggerEffectMessage, TriggeredEffectLocation} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.types.PlanetSideGUID @@ -47,7 +46,7 @@ class ApcControl(vehicle: Vehicle) val zone = obj.Zone val events = zone.VehicleEvents val pos = obj.Position - val GUID0 = Service.defaultPlayerGUID + val GUID0 = Default.GUID0 val emp = ApcControl.apc_emp val faction = obj.Faction //drain the capacitor diff --git a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala index ff73708ab..af869a71f 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/BfrControl.scala @@ -16,7 +16,6 @@ import net.psforever.objects.vital.ShieldCharge import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game._ -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.types._ @@ -400,7 +399,7 @@ class BfrControl(vehicle: Vehicle) }) match { case (slot, Some(_)) => armManagementFunc(slot) - val guid0 = Service.defaultPlayerGUID + val guid0 = Default.GUID0 val doNotSendTo = other match { case Some(pguid: PlanetSideGUID) => pguid case _ => guid0 @@ -548,7 +547,7 @@ class BfrControl(vehicle: Vehicle) val obj = ChargeTransferObject val zone = obj.Zone val events = zone.VehicleEvents - val GUID0 = Service.defaultPlayerGUID + val GUID0 = Default.GUID0 getNtuContainer() match { case Some(siphon : NtuSiphon) if GlobalDefinitions.isBattleFrameNTUSiphon(siphon.equipment.Definition) && diff --git a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala index cb6f751fb..6d8e509e8 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneProjectileActor.scala @@ -2,9 +2,9 @@ package net.psforever.objects.zones import akka.actor.{Actor, Cancellable} +import net.psforever.objects.Default import net.psforever.objects.ballistics.Projectile import net.psforever.objects.guid.{GUIDTask, StraightforwardTask, TaskBundle, TaskWorkflow} -import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.ObjectDelete @@ -112,7 +112,7 @@ class ZoneProjectileActor( TaskBundle( reg.mainTask, TaskBundle( - reg.subTasks(0).mainTask, + reg.subTasks.head.mainTask, unregisterProjectile(obj) ) ) @@ -144,11 +144,11 @@ class ZoneProjectileActor( projectileList.addOne(projectile) val (clarifiedFilterGuid, duration) = if (definition.radiation_cloud) { zone.blockMap.addTo(projectile) - (Service.defaultPlayerGUID, projectile.profile.Lifespan seconds) + (Default.GUID0, projectile.profile.Lifespan seconds) } else if (definition.RemoteClientData == (0,0)) { //remote projectiles that are not radiation clouds have lifespans controlled by the controller (user) //this projectile has defaulted remote client data - (Service.defaultPlayerGUID, projectile.profile.Lifespan * 1.5f seconds) + (Default.GUID0, projectile.profile.Lifespan * 1.5f seconds) } else { //remote projectiles that are not radiation clouds have lifespans controlled by the controller (user) //if the controller fails, the projectile has a bit more than its normal lifespan before automatic clean up diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index a337e5988..4b33229d1 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -560,16 +560,16 @@ class CavernRotationService( //borrow GalaxyService response structure, but send to the specific endpoint math.max(0, monitor.start + monitor.duration - curr) unlockedZones.foreach { monitor => val resp = GalaxyAction.UnlockedZoneUpdate(monitor.zone) - sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Service.defaultPlayerGUID, resp) + sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Default.GUID0, resp) } val sortedLocked = lockedZones.sortBy(z => z.start) sortedLocked.take(2).foreach { monitor => val resp = GalaxyAction.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr)) - sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Service.defaultPlayerGUID, resp) + sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Default.GUID0, resp) } sortedLocked.takeRight(2).foreach { monitor => val resp = GalaxyAction.LockedZoneUpdate(monitor.zone, 0L) - sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Service.defaultPlayerGUID, resp) + sendToSession ! GenericResponseEnvelope(GalaxyStamp, "", Default.GUID0, resp) } } diff --git a/src/main/scala/net/psforever/services/Service.scala b/src/main/scala/net/psforever/services/Service.scala index 0bca3a02d..68e5779ea 100644 --- a/src/main/scala/net/psforever/services/Service.scala +++ b/src/main/scala/net/psforever/services/Service.scala @@ -2,11 +2,8 @@ package net.psforever.services import akka.actor.ActorRef -import net.psforever.types.PlanetSideGUID object Service { - final val defaultPlayerGUID: PlanetSideGUID = PlanetSideGUID(0) - case object Startup final case class Join(channel: String, sendJoinConfirmation: Boolean) diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index d745a04dc..32d12bd55 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -2,11 +2,11 @@ package net.psforever.services.avatar.support import akka.actor.{ActorContext, ActorRef, Props} +import net.psforever.objects.Default import net.psforever.objects.equipment.Equipment import net.psforever.objects.guid.{GUIDTask, TaskBundle} import net.psforever.objects.zones.Zone import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem} -import net.psforever.services.Service import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.ObjectDelete @@ -39,7 +39,7 @@ final case class PickupItemEnvelope( object PickupItemEnvelope { def apply(channel: String, actionMessage: PickupItem, zone: Zone): PickupItemEnvelope = - PickupItemEnvelope(channel, Service.defaultPlayerGUID, actionMessage, zone) + PickupItemEnvelope(channel, Default.GUID0, actionMessage, zone) } final case class DropItemEnvelope( @@ -58,7 +58,7 @@ final case class DropItemEnvelope( object DropItemEnvelope { def apply(channel: String, actionMessage: DropItem, zone: Zone): DropItemEnvelope = - DropItemEnvelope(channel, Service.defaultPlayerGUID, actionMessage, zone) + DropItemEnvelope(channel, Default.GUID0, actionMessage, zone) } final case class GroundEnvelope(supportMessage: Any) diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index fb224b619..47b34e8d8 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -3,7 +3,6 @@ package net.psforever.services.base import akka.actor.Cancellable import net.psforever.objects.Default -import net.psforever.services.Service import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageEnvelope, MessageTransformationBehavior} import net.psforever.services.base.message.EventMessage import net.psforever.types.PlanetSideGUID @@ -36,7 +35,7 @@ final case class CachedEnvelope( filter: PlanetSideGUID, msg: EventMessage ) extends CachedGenericEventEnvelope { - assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") + assert(guid != Default.GUID0, "can not cache message under default GUID") } object CachedEnvelope { @@ -50,7 +49,7 @@ object CachedEnvelope { * @return either a `CacheEnvelope` or a `MessageEnvelope`, depending on cache-readiness of the `filter` value */ def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = { - if (filter == Service.defaultPlayerGUID) { + if (filter == Default.GUID0) { org.log4s.getLogger("CachedEnvelope").warn("(1) cached message envelope downgraded to normal message envelope") MessageEnvelope(channel, filter, msg) } else { @@ -69,11 +68,11 @@ object CachedEnvelope { * @return either a `CacheEnvelope` or a `MessageEnvelope`, depending on cache-readiness of the target */ def apply(guid: PlanetSideGUID, channel: String, msg: EventMessage): GenericMessageEnvelope = { - if (guid == Service.defaultPlayerGUID) { + if (guid == Default.GUID0) { org.log4s.getLogger("CachedEnvelope").warn("(2) cached message envelope downgraded to normal message envelope") MessageEnvelope(channel, guid, msg) } else { - CachedEnvelope(guid, channel, Service.defaultPlayerGUID, msg) + CachedEnvelope(guid, channel, Default.GUID0, msg) } } } @@ -90,7 +89,7 @@ private case object FlushCachedMessages extends GenericMessageEnvelope { def msg: EventMessage = NoMessage def response(stamp: EventSystemStamp): GenericResponseEnvelope = NoResponseEnvelope def channel: String = "" - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 } class GenericEventServiceWithCacheAndSupport diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala index 713cadcab..e10b152f1 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithSupport.scala @@ -2,7 +2,7 @@ package net.psforever.services.base import akka.actor.{ActorContext, ActorRef} -import net.psforever.services.Service +import net.psforever.objects.Default import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageTransformationBehavior, NoReply, Undelivered} import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent} import net.psforever.types.PlanetSideGUID @@ -25,7 +25,7 @@ case object NoResponseEnvelope extends GenericResponseEnvelope { def reply: EventResponse = NoReply def stamp: EventSystemStamp = Undelivered def channel: String = "" - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 } /** @@ -66,7 +66,7 @@ trait GenericSupportEnvelopeOnly with GenericMessageEnvelope { def originalChannel: String = "" def channel: String = "" - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 def msg: EventMessage = NoMessage def response(@unused stamp: EventSystemStamp): GenericResponseEnvelope = NoResponseEnvelope diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala index 398c752cf..b93747d25 100644 --- a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -1,7 +1,7 @@ // Copyright (c) 2026 PSForever package net.psforever.services.base.envelope -import net.psforever.services.Service +import net.psforever.objects.Default import net.psforever.services.base.EventSystemStamp import net.psforever.services.base.message.{EventMessage, EventResponse} import net.psforever.types.PlanetSideGUID @@ -57,8 +57,8 @@ case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMe object MessageEnvelope { def apply(msg: EventMessage): MessageEnvelope = - MessageEnvelope("", Service.defaultPlayerGUID, msg) + MessageEnvelope("", Default.GUID0, msg) def apply(channel: String, msg: EventMessage): MessageEnvelope = - MessageEnvelope(channel, Service.defaultPlayerGUID, msg) + MessageEnvelope(channel, Default.GUID0, msg) } diff --git a/src/main/scala/net/psforever/services/hart/HartTimer.scala b/src/main/scala/net/psforever/services/hart/HartTimer.scala index 67f9f63f8..576eadcfe 100644 --- a/src/main/scala/net/psforever/services/hart/HartTimer.scala +++ b/src/main/scala/net/psforever/services/hart/HartTimer.scala @@ -4,7 +4,6 @@ package net.psforever.services.hart import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Default import net.psforever.objects.zones.Zone -import net.psforever.services.Service import net.psforever.services.base.EventSystemStamp import net.psforever.services.base.bus.GenericEventBus import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope, NoReply} @@ -268,7 +267,7 @@ object HartTimer { trait Command extends GenericResponseEnvelope { def originalChannel: String = "" def channel: String = "" - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 def stamp: EventSystemStamp = HartStamp def reply: EventResponse = NoReply } diff --git a/src/main/scala/net/psforever/services/local/LocalAction.scala b/src/main/scala/net/psforever/services/local/LocalAction.scala index f10d33ea6..4e42bca59 100644 --- a/src/main/scala/net/psforever/services/local/LocalAction.scala +++ b/src/main/scala/net/psforever/services/local/LocalAction.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017-2026 PSForever package net.psforever.services.local -import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle} +import net.psforever.objects.{Default, PlanetSideGameObject, TelepadDeployable, Vehicle} import net.psforever.objects.ce.{Deployable, DeployedItem} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.llu.CaptureFlag @@ -9,7 +9,6 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal} import net.psforever.objects.vehicles.Utility import net.psforever.objects.zones.Zone import net.psforever.packet.game.{DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound} -import net.psforever.services.Service import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent, SendResponse} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent import net.psforever.types.{PlanetSideGUID, Vector3} @@ -127,7 +126,7 @@ object LocalAction { orient: Vector3 ) extends EventMessage { def response(): EventResponse = { - TriggerEffectAtLocation(Service.defaultPlayerGUID, effect, None, Some(TriggeredEffectLocation(pos, orient))) + TriggerEffectAtLocation(Default.GUID0, effect, None, Some(TriggeredEffectLocation(pos, orient))) } } diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index d99a134ac..a8a189a86 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -5,7 +5,6 @@ import akka.actor.{Actor, ActorContext, ActorRef, Cancellable, Props} import net.psforever.objects.{Default, Doors} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone -import net.psforever.services.Service import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope} import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.local.LocalAction.IsADoorMessage @@ -28,7 +27,7 @@ final case class DoorMessage( msg: IsADoorMessage, supportMessage: Any ) extends GenericSupportEnvelope { - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 def supportLabel: String = "doorCloser" } diff --git a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala index 2482ffddd..a5281453c 100644 --- a/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala +++ b/src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala @@ -2,10 +2,10 @@ package net.psforever.services.teamwork import akka.actor.ActorRef +import net.psforever.objects.Default import net.psforever.objects.avatar.Certification import net.psforever.objects.teamwork.Squad import net.psforever.packet.game.{SquadDetail, SquadInfo, WaypointEventAction, WaypointInfo} -import net.psforever.services.Service import net.psforever.services.base.message.EventResponse import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadResponseType, SquadWaypoint} import net.psforever.services.base.EventSystemStamp @@ -15,7 +15,7 @@ case object SquadStamp extends EventSystemStamp final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], reply: SquadResponse.Response) extends EventResponse with GenericResponseEnvelope { - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 def stamp: EventSystemStamp = SquadStamp } diff --git a/src/test/scala/objects/DeployableTest.scala b/src/test/scala/objects/DeployableTest.scala index bf97bd54e..88536ee18 100644 --- a/src/test/scala/objects/DeployableTest.scala +++ b/src/test/scala/objects/DeployableTest.scala @@ -593,7 +593,7 @@ class ExplosiveDeployableDestructionTest extends ActorTest { eventMsgs(1) match { case MessageEnvelope( "test", _, - AvatarAction.Destroy(PlanetSideGUID(2), PlanetSideGUID(3), Service.defaultPlayerGUID, Vector3.Zero) + AvatarAction.Destroy(PlanetSideGUID(2), PlanetSideGUID(3), Default.GUID0, Vector3.Zero) ) => ; case _ => assert(false, "") } diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala index 6ff7932f5..7a10dfcdf 100644 --- a/src/test/scala/service/base/EventServiceCacheSupportTest.scala +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -4,6 +4,7 @@ package service.base import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.TestProbe import base.ActorTest +import net.psforever.objects.Default import net.psforever.services.Service import net.psforever.services.base.message.EventMessage import net.psforever.services.base.{CachedEnvelope, CachedGenericEventEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope} @@ -18,8 +19,8 @@ object EventServiceCacheSupportTest { override val msg: EventMessage, supportMessage: Any ) extends CachedGenericEventEnvelope with GenericSupportEnvelope { - assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID") - def filter: PlanetSideGUID = Service.defaultPlayerGUID + assert(guid != Default.GUID0, "can not cache message under default GUID") + def filter: PlanetSideGUID = Default.GUID0 def supportLabel: String = "supportActor" } diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala index 8bfbf61dd..1be95949a 100644 --- a/src/test/scala/service/base/EventServiceTest.scala +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -4,6 +4,7 @@ package service.base import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.TestProbe import base.ActorTest +import net.psforever.objects.Default import net.psforever.services.Service import net.psforever.services.base.GenericEventService import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} @@ -57,7 +58,7 @@ class EventServiceTestSubscriptionMessage extends ActorTest { val probe = TestProbe("testProbe") val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) probe.receiveN(1, 100 milliseconds) } } @@ -69,11 +70,11 @@ class EventServiceTestSubscriptionReply extends ActorTest { "receive messages that are responses to the original message from a subscribed channel" in { val probe = TestProbe("testProbe") val events = EventServiceTest.SpawnTestSystem() - val msg = MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + val msg = MessageEnvelope("test", Default.GUID0, TestMessage(5)) // s => "/$s" is the default channel manipulation of the event system val formalReply = msg.response(EventServiceTestBase.TestStamp) events.tell(Service.Join("test"), probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) val reply = probe.receiveOne(100 milliseconds) assert(reply == formalReply, "(1) message expected but not received format") } @@ -89,7 +90,7 @@ class EventServiceTestNotSubscribed extends ActorTest { val events = EventServiceTest.SpawnTestSystem() events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("notATest"), missedProbe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) val reply = probe.receiveOne(100 milliseconds) reply match { case GenericResponseEnvelope("test", _, TestMessage(5)) => () @@ -123,8 +124,8 @@ class EventServiceTestLeave extends ActorTest { events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("anotherTest"), probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) - events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(5)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Default.GUID0, TestMessage(5)) val reply1 = probe.receiveN(2, 100 milliseconds) reply1.head match { case GenericResponseEnvelope("test", _, _) => () @@ -136,8 +137,8 @@ class EventServiceTestLeave extends ActorTest { } events.tell(Service.Leave("anotherTest"), probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) - events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Default.GUID0, TestMessage(6)) val reply2 = probe.receiveOne(100 milliseconds) reply2 match { case GenericResponseEnvelope("test", _, TestMessage(5)) => () @@ -157,8 +158,8 @@ class EventServiceTestLeaveAll extends ActorTest { events.tell(Service.Join("test"), probe.ref) events.tell(Service.Join("anotherTest"), probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) - events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Default.GUID0, TestMessage(6)) val reply = probe.receiveN(2,100 milliseconds) reply.head match { case GenericResponseEnvelope("test", _, TestMessage(5)) => () @@ -170,8 +171,8 @@ class EventServiceTestLeaveAll extends ActorTest { } events.tell(Service.LeaveAll, probe.ref) - events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) - events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) + events ! MessageEnvelope("test", Default.GUID0, TestMessage(5)) + events ! MessageEnvelope("anotherTest", Default.GUID0, TestMessage(6)) probe.expectNoMessage(250 milliseconds) } } diff --git a/src/test/scala/service/base/EventServiceTestBase.scala b/src/test/scala/service/base/EventServiceTestBase.scala index 40718e204..81ec8b1be 100644 --- a/src/test/scala/service/base/EventServiceTestBase.scala +++ b/src/test/scala/service/base/EventServiceTestBase.scala @@ -1,7 +1,7 @@ package service.base import akka.actor.{Actor, ActorContext, ActorRef, Props} -import net.psforever.services.Service +import net.psforever.objects.Default import net.psforever.services.base.message.SelfRespondingEvent import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericSupportEnvelope} import net.psforever.types.PlanetSideGUID @@ -32,7 +32,7 @@ object EventServiceTestBase { channel: String, msg: SupportActorRepliesWith ) extends GenericSupportEnvelope { - def filter: PlanetSideGUID = Service.defaultPlayerGUID + def filter: PlanetSideGUID = Default.GUID0 def supportLabel: String = "supportActor" def supportMessage: Any = msg } diff --git a/src/test/scala/service/local/LocalActionTest.scala b/src/test/scala/service/local/LocalActionTest.scala index a929bd485..87d055260 100644 --- a/src/test/scala/service/local/LocalActionTest.scala +++ b/src/test/scala/service/local/LocalActionTest.scala @@ -63,7 +63,7 @@ class LocalActionTest extends Specification { "respond" in { val msg = LocalAction.TriggerEffectLocation("on", Vector3(1, 2, 3), Vector3(4, 5, 6)) msg.response() match { - case LocalAction.TriggerEffectAtLocation(Service.defaultPlayerGUID, "on", None, Some(TriggeredEffectLocation(Vector3(1, 2, 3), Vector3(4, 5, 6)))) => + case LocalAction.TriggerEffectAtLocation(Default.GUID0, "on", None, Some(TriggeredEffectLocation(Vector3(1, 2, 3), Vector3(4, 5, 6)))) => ok case _ => ko From f3fedaf55d245dac4b501735fdf9ea64f54e133f Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 2 Jun 2026 18:19:52 -0400 Subject: [PATCH 28/32] allowed bundling of event message envelopes to streamline event system communication --- .../psforever/actors/zone/BuildingActor.scala | 8 +- .../zone/building/MajorFacilityLogic.scala | 23 ++--- .../actors/zone/building/WarpGateLogic.scala | 6 +- .../psforever/objects/BoomerDeployable.scala | 5 +- .../scala/net/psforever/objects/Players.scala | 22 ++--- .../net/psforever/objects/Vehicles.scala | 70 ++++++++-------- .../objects/ce/DeployableBehavior.scala | 36 ++++---- .../psforever/objects/ce/TelepadLike.scala | 30 +++---- .../objects/zones/exp/KillAssists.scala | 8 +- .../services/base/GenericEventService.scala | 5 +- ...nericEventServiceWithCacheAndSupport.scala | 49 +++++++++-- .../base/envelope/BundledEnvelope.scala | 83 +++++++++++++++++++ .../local/support/DoorCloseActor.scala | 14 ++-- .../local/support/HackCaptureActor.scala | 19 +++-- .../local/support/HackClearActor.scala | 23 ++--- 15 files changed, 256 insertions(+), 145 deletions(-) create mode 100644 src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala diff --git a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala index 9afecac87..3aabbf12e 100644 --- a/src/main/scala/net/psforever/actors/zone/BuildingActor.scala +++ b/src/main/scala/net/psforever/actors/zone/BuildingActor.scala @@ -11,7 +11,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.ContinentalLockUpdateMessage import net.psforever.persistence -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.{InterstellarClusterService, ServiceManager} @@ -232,8 +232,10 @@ class BuildingActor( Behaviors.same case MapUpdate() => - details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())) - details.galaxyService ! MessageEnvelope("", SendResponse(details.building.densityLevelUpdateMessage(building))) + details.galaxyService ! BundledEnvelope( + MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())), + MessageEnvelope("", SendResponse(details.building.densityLevelUpdateMessage(building))) + ) Behaviors.same case AmenityStateChange(amenity, data) => diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index 1045dcb23..ba3f8bdc3 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -15,7 +15,7 @@ import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, Ca import net.psforever.objects.sourcing.PlayerSource import net.psforever.packet.game.{GenericObjectActionMessage, PlanetsideAttributeMessage} import net.psforever.services.InterstellarClusterService -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} import net.psforever.services.galaxy.GalaxyAction import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor, HackClearActor, HackClearEnvelope} @@ -204,25 +204,19 @@ case object MajorFacilityLogic val events = zone.AvatarEvents val guid = building.GUID val msg = GenericObjectAction(guid, 15) - building.PlayersInSOI.foreach { player => - events ! MessageEnvelope(player.Name, msg) - } + events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) }) false case Some(GeneratorControl.Event.Critical) => val events = zone.AvatarEvents val guid = building.GUID val msg = PlanetsideAttribute(guid, 46, 1) - building.PlayersInSOI.foreach { player => - events ! MessageEnvelope(player.Name, msg) - } + events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) }) true case Some(GeneratorControl.Event.Destabilized) => val events = zone.AvatarEvents val guid = building.GUID val msg = GenericObjectAction(guid, 16) - building.PlayersInSOI.foreach { player => - events ! MessageEnvelope(player.Name, msg) - } + events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) }) if (building.hasCavernLockBenefit) { zone.LocalEvents ! MessageEnvelope( zone.id, @@ -235,10 +229,9 @@ case object MajorFacilityLogic case Some(GeneratorControl.Event.Offline) => powerLost(details) val zone = building.Zone + val events = zone.AvatarEvents val msg = PlanetsideAttribute(building.GUID, 46, 2) - building.PlayersInSOI.foreach { player => - zone.AvatarEvents ! MessageEnvelope(player.Name, msg) - } //??? + events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) }) //??? true case Some(GeneratorControl.Event.Normal) => true @@ -253,9 +246,7 @@ case object MajorFacilityLogic PlanetsideAttributeMessage(guid, 46, 0), GenericObjectActionMessage(guid, 17) )) - building.PlayersInSOI.foreach { player => - events ! MessageEnvelope(player.Name, list) - } + events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, list) }) true case _ => false diff --git a/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala b/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala index 2553a30fd..ec60d2f8d 100644 --- a/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/WarpGateLogic.scala @@ -6,7 +6,7 @@ import akka.actor.typed.scaladsl.Behaviors import net.psforever.actors.commands.NtuCommand import net.psforever.actors.zone.BuildingActor import net.psforever.objects.serverobject.structures.{Amenity, Building, WarpGate} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.galaxy.GalaxyAction import net.psforever.types.PlanetSideEmpire import net.psforever.util.Config @@ -209,9 +209,7 @@ case object WarpGateLogic warpgate.Zone.Number, warpgate.MapId, previousAllowances, setBroadcastTo ) warpgate.AllowBroadcastFor = setBroadcastTo - (setBroadcastTo ++ previousAllowances).foreach { faction => - events ! MessageEnvelope(faction.toString, msg) - } + events ! BundledEnvelope((setBroadcastTo ++ previousAllowances).map { faction => MessageEnvelope(faction.toString, msg) }) } /** diff --git a/src/main/scala/net/psforever/objects/BoomerDeployable.scala b/src/main/scala/net/psforever/objects/BoomerDeployable.scala index 84285db2c..22ce1938d 100644 --- a/src/main/scala/net/psforever/objects/BoomerDeployable.scala +++ b/src/main/scala/net/psforever/objects/BoomerDeployable.scala @@ -107,10 +107,7 @@ class BoomerDeployableControl(mine: BoomerDeployable) zone.Ground ! Zone.Ground.RemoveItem(guid) case _ => () } - zone.AvatarEvents! MessageEnvelope( - zone.id, - ObjectDelete(guid) - ) + zone.AvatarEvents! MessageEnvelope(zone.id, ObjectDelete(guid)) TaskWorkflow.execute(GUIDTask.unregisterObject(zone.GUID, trigger)) case None => () } diff --git a/src/main/scala/net/psforever/objects/Players.scala b/src/main/scala/net/psforever/objects/Players.scala index 30203cc70..7aa3fee0d 100644 --- a/src/main/scala/net/psforever/objects/Players.scala +++ b/src/main/scala/net/psforever/objects/Players.scala @@ -20,11 +20,12 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ import net.psforever.types.{ChatMessageType, ExoSuitType, PlanetSideGUID, Vector3} import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{ObjectDelete, SendResponse} import net.psforever.services.local.LocalAction import scala.annotation.tailrec +import scala.collection.mutable.ArrayBuffer object Players { private val log = org.log4s.getLogger("Players") @@ -49,10 +50,7 @@ object Players { ) { val events = target.Zone.AvatarEvents val uname = user.Name - events ! MessageEnvelope( - uname, - SendResponse(RepairMessage(target.GUID, progress.toInt)) - ) + events ! MessageEnvelope(uname, SendResponse(RepairMessage(target.GUID, progress.toInt))) true } else { false @@ -439,24 +437,20 @@ object Players { if ((player.Slot(index).Equipment = obj).contains(obj)) { val fireMode = tool.FireModeIndex val ammoType = tool.AmmoTypeIndex + val list: ArrayBuffer[MessageEnvelope] = ArrayBuffer() player.Inventory -= x.start obj.FireModeIndex = fireMode //TODO any penalty for being handed an OCM version of the tool? - events ! MessageEnvelope( - zone.id, - AvatarAction.EquipmentInHand(pguid, index, obj) - ) + list.append(MessageEnvelope(zone.id, AvatarAction.EquipmentInHand(pguid, index, obj))) if (obj.AmmoTypeIndex != ammoType) { obj.AmmoTypeIndex = ammoType - events ! MessageEnvelope( - name, - SendResponse(ChangeAmmoMessage(obj.GUID, ammoType)) - ) + list.append(MessageEnvelope(name, SendResponse(ChangeAmmoMessage(obj.GUID, ammoType)))) } if (player.DrawnSlot == Player.HandsDownSlot) { player.DrawnSlot = index - events ! MessageEnvelope(zone.id, pguid, AvatarAction.ObjectHeld(index, index)) + list.append(MessageEnvelope(zone.id, pguid, AvatarAction.ObjectHeld(index, index))) } + events ! BundledEnvelope(list) } case Nil => ; //no replacements found } diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 5cf4abbe8..2ef24b137 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -12,11 +12,13 @@ import net.psforever.objects.vehicles._ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire} import net.psforever.services.local.LocalAction import net.psforever.services.vehicle.VehicleAction +import scala.collection.mutable.ArrayBuffer + //import scala.concurrent.duration._ object Vehicles { @@ -248,13 +250,15 @@ object Vehicles { val hFaction = hacker.Faction val zone = target.Zone val zoneid = zone.id + val avatarEvents = zone.AvatarEvents val vehicleEvents = zone.VehicleEvents - val localEvents = zone.LocalEvents val previousOwnerName = target.OwnerName.getOrElse("") - vehicleEvents ! MessageEnvelope( + val occupantMessages: ArrayBuffer[MessageEnvelope] = ArrayBuffer() + val vehicleMessages: ArrayBuffer[MessageEnvelope] = ArrayBuffer() + vehicleMessages.append(MessageEnvelope( zoneid, SendResponse(HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8)) - ) + )) target.Actor ! CommonMessages.Hack(hacker, target) // Forcefully dismount any cargo target.CargoHolds.foreach { case (_, cargoHold) => @@ -268,26 +272,29 @@ object Vehicles { player: Player => seat.unmount(player) player.VehicleSeated = None - vehicleEvents ! MessageEnvelope( + occupantMessages.append(MessageEnvelope( zoneid, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, tGuid) - ) + )) } // In case BFR is occupied and may or may not be crouched if (GlobalDefinitions.isBattleFrameVehicle(target.Definition) && target.Seat(0).isDefined) { - zone.LocalEvents ! MessageEnvelope( - zoneid, - GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown.id) - ) - zone.LocalEvents ! MessageEnvelope( - zoneid, - SendResponse( - FrameVehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), unk2=false, 0, 0, is_crouched=true, is_airborne=false, ascending_flight=false, 10, 0, 0))) - zone.LocalEvents ! MessageEnvelope( - zoneid, - SendResponse( - VehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), None, 0, 0, 15, is_decelerating=false, is_cloaked=false))) + vehicleMessages.appendAll(List( + MessageEnvelope(zoneid, + GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown.id) + ), + MessageEnvelope(zoneid, + SendResponse( + FrameVehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), unk2=false, 0, 0, is_crouched=true, is_airborne=false, ascending_flight=false, 10, 0, 0) + ) + ), + MessageEnvelope(zoneid, + SendResponse( + VehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), None, 0, 0, 15, is_decelerating=false, is_cloaked=false) + ) + ) + )) } }) // If the vehicle can fly and is flying: deconstruct it; and well played to whomever managed to hack a plane in mid air @@ -312,26 +319,17 @@ object Vehicles { Vehicles.Own(target, hacker) //todo: Send HackMessage -> HackCleared to vehicle? can be found in packet captures. Not sure if necessary. // And broadcast the faction change to other clients - zone.AvatarEvents ! MessageEnvelope( - zoneid, - SetEmpire(tGuid, hFaction) - ) + vehicleMessages.append(MessageEnvelope(zoneid, SetEmpire(tGuid, hFaction))) } - localEvents ! MessageEnvelope( + vehicleMessages.append(MessageEnvelope( zoneid, hGuid, LocalAction.TriggerSound(TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f) - ) + )) if (zone.Players.exists(_.name.equals(previousOwnerName))) { - localEvents ! MessageEnvelope( - previousOwnerName, - SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen")) - ) + vehicleMessages.append(MessageEnvelope(previousOwnerName, SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen")))) } - localEvents ! MessageEnvelope( - hacker.Name, - SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned")) - ) + occupantMessages.append(MessageEnvelope(hacker.Name, SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned")))) // Clean up after specific vehicles, e.g. remove router telepads // If AMS is deployed, swap it to the new faction target.Definition match { @@ -343,13 +341,15 @@ object Vehicles { util.Actor ! TelepadLike.Activate(util) } case GlobalDefinitions.ams if target.DeploymentState == DriveState.Deployed => - vehicleEvents ! MessageEnvelope(zone.id, VehicleAction.AMSDeploymentChange(zone)) + vehicleMessages.append(MessageEnvelope(zone.id, VehicleAction.AMSDeploymentChange(zone))) case _ => () } - vehicleEvents ! MessageEnvelope( + vehicleMessages.append(MessageEnvelope( zoneid, SendResponse(HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8)) - ) + )) + avatarEvents ! BundledEnvelope(occupantMessages) + vehicleEvents ! BundledEnvelope(vehicleMessages) target.Actor ! CommonMessages.ClearHack() } diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index 7100c7580..160776650 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -6,7 +6,7 @@ import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects._ import net.psforever.objects.zones.Zone import net.psforever.packet.game._ -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SetEmpire import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideEmpire @@ -198,11 +198,14 @@ trait DeployableBehavior { None } //zone build - localEvents ! MessageEnvelope(zone.id, LocalAction.DeployItem(obj)) - //zone map icon - localEvents ! MessageEnvelope( - obj.Faction.toString, - LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Default.GUID0))) + localEvents ! BundledEnvelope( + /* zone build */ + MessageEnvelope(zone.id, LocalAction.DeployItem(obj)), + /* zone map icon */ + MessageEnvelope( + obj.Faction.toString, + LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Default.GUID0))) + ) ) //local build management callback ! Zone.Deployable.IsBuilt(obj) @@ -281,15 +284,13 @@ object DeployableBehavior { val localEvents = zone.LocalEvents if (originalFaction != toFaction) { obj.Faction = toFaction - //visual tells in regards to ownership by faction - zone.AvatarEvents ! MessageEnvelope( - zone.id, - SetEmpire(dGuid, toFaction) - ) - //remove knowledge by the previous owner's faction - localEvents ! MessageEnvelope( - originalFaction.toString, - LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, info) + localEvents ! BundledEnvelope( + /* visual tells in regards to ownership by faction */ + MessageEnvelope(zone.id, SetEmpire(dGuid, toFaction)), + /* remove knowledge by the previous owner's faction */ + MessageEnvelope(originalFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, info)), + /* display to the given faction */ + MessageEnvelope(toFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Build, info)) ) //remove deployable from original owner's toolbox and UI counter zone.AllPlayers.filter(p => obj.OriginalOwnerName.contains(p.Name)) @@ -297,11 +298,6 @@ object DeployableBehavior { originalOwner.avatar.deployables.Remove(obj) originalOwner.Zone.LocalEvents ! MessageEnvelope(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) } - //display to the given faction - localEvents ! MessageEnvelope( - toFaction.toString, - LocalAction.DeployableMapIcon(DeploymentAction.Build, info) - ) } } } diff --git a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala index 3ac01cfb9..f90273a38 100644 --- a/src/main/scala/net/psforever/objects/ce/TelepadLike.scala +++ b/src/main/scala/net/psforever/objects/ce/TelepadLike.scala @@ -9,7 +9,7 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.Zone import net.psforever.packet.game.{GenericObjectActionMessage, ObjectCreateMessage, ObjectDeleteMessage} import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideGUID @@ -115,21 +115,23 @@ object TelepadLike { normally dispatched while the Router is transitioned into its Deploying state it is safe, however, to perform these actions at any time during and after the Deploying state */ - events ! MessageEnvelope( - zoneId, - SendResponse( - ObjectCreateMessage( - udef.ObjectId, - utilityGUID, - ObjectCreateMessageParent(routerGUID, 2), //TODO stop assuming slot number - udef.Packet.ConstructorData(obj).get + events ! BundledEnvelope( + MessageEnvelope( + zoneId, + SendResponse( + ObjectCreateMessage( + udef.ObjectId, + utilityGUID, + ObjectCreateMessageParent(routerGUID, 2), //TODO stop assuming slot number + udef.Packet.ConstructorData(obj).get + ) ) - ) + ), + MessageEnvelope(zoneId, SendResponse(Seq( + GenericObjectActionMessage(utilityGUID, 27), + GenericObjectActionMessage(utilityGUID, 30) + ))) ) - events ! MessageEnvelope(zoneId, SendResponse(Seq( - GenericObjectActionMessage(utilityGUID, 27), - GenericObjectActionMessage(utilityGUID, 30) - ))) LinkTelepad(zone, utilityGUID) } diff --git a/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala b/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala index 10a94effb..55b1b17be 100644 --- a/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala +++ b/src/main/scala/net/psforever/objects/zones/exp/KillAssists.scala @@ -7,7 +7,7 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.vital.interaction.{Adversarial, DamageResult} import net.psforever.objects.vital.{DamagingActivity, HealingActivity, InGameActivity, RepairingActivity, RevivingActivity, SpawningActivity} import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.types.PlanetSideEmpire import net.psforever.util.Config @@ -52,9 +52,9 @@ object KillAssists { history: Iterable[InGameActivity], eventBus: ActorRef ): Unit = { - rewardThisPlayerDeath(victim, lastDamage, history).foreach { case (p, kda) => - eventBus ! MessageEnvelope(p.Name, AvatarAction.UpdateKillsDeathsAssists(p.CharId, kda)) - } + eventBus ! BundledEnvelope(rewardThisPlayerDeath(victim, lastDamage, history).map { case (p, kda) => + MessageEnvelope(p.Name, AvatarAction.UpdateKillsDeathsAssists(p.CharId, kda)) + }) } /** diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index 183daf018..ac098ca68 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -4,7 +4,7 @@ package net.psforever.services.base import akka.actor.Actor import net.psforever.services.Service import net.psforever.services.base.bus.GenericEventBus -import net.psforever.services.base.envelope.GenericMessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, GenericMessageEnvelope} import org.log4s.Logger /** @@ -78,6 +78,9 @@ class GenericEventService(stamp: EventSystemStamp) * Accept and handle designated messages. */ protected def commonBehavior: Receive = { + case bundle: BundledEnvelope => + bundle.msgs.foreach(commonBehavior.apply) + case msg: GenericMessageEnvelope => handleMessage(msg) } diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index 47b34e8d8..1f284af76 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -3,7 +3,7 @@ package net.psforever.services.base import akka.actor.Cancellable import net.psforever.objects.Default -import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageEnvelope, MessageTransformationBehavior} +import net.psforever.services.base.envelope.{BundledEnvelope, GenericMessageEnvelope, GenericResponseEnvelope, MessageEnvelope, MessageTransformationBehavior} import net.psforever.services.base.message.EventMessage import net.psforever.types.PlanetSideGUID import net.psforever.util.Config @@ -137,18 +137,35 @@ class GenericEventServiceWithCacheAndSupport } /** - * Add messages to the cache based on their channel, then their type, then their cache target identifier. + * Add messages to the cache. + * @param event event system message + */ + private def pushToCache(event: CachedGenericEventEnvelope): Unit = { + pushToCache(event, event.msg.getClass.getName, event.guid) + } + /** + * Add messages to the cache. + * @param event event system message + * @param eventGuid event system message filter + */ + private def pushToCache(event: GenericMessageEnvelope, eventGuid: PlanetSideGUID): Unit = { + pushToCache(event, event.msg.getClass.getName, eventGuid) + } + /** + * Add messages to the cache + * based on their channel, then their type, then their cache target identifier. * Messages that arrive with the same cache profile as a previous message, * but before that previous message was dispatched, * will overwrite the previous message without fanfare or warning. * @param event event system message + * @param eventClassName event system message identifier + * @param eventGuid event system message filter */ - private def pushToCache(event: CachedGenericEventEnvelope): Unit = { - val eventClassName = event.msg.getClass.getName + private def pushToCache(event: GenericMessageEnvelope, eventClassName: String, eventGuid: PlanetSideGUID): Unit = { val updateBranch = cache .getOrElseUpdate(event.channel, new ConcurrentHashMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]().asScala) .getOrElseUpdate(eventClassName, new ConcurrentHashMap[PlanetSideGUID, GenericMessageEnvelope]().asScala) - updateBranch.updateWith(event.guid) { _ => Some(event) } + updateBranch.updateWith(eventGuid) { _ => Some(event) } tryRetimeFlushCache() } @@ -194,6 +211,8 @@ class GenericEventServiceWithCacheAndSupport event match { case FlushCachedMessages => flushCache() + case bundle: BundledEnvelope => + handleMessageBundled(bundle) case _: CachedGenericEventEnvelope if tryFlushCache() => super.handleMessage(event) case envelope: CachedGenericEventEnvelope => @@ -203,4 +222,24 @@ class GenericEventServiceWithCacheAndSupport super.handleMessage(event) } } + + /** + * If even one message in a bundle is to be cached, the contents of the whole bundle should be cached. + * Otherwise, just handle things normally. + * @param bundle event system message that may be cached + */ + private def handleMessageBundled(bundle: BundledEnvelope): Unit = { + val messages = bundle.msgs + messages.find(_.isInstanceOf[CachedGenericEventEnvelope]) match { + case Some(cache: CachedGenericEventEnvelope) if messages.size == 1 => + pushToCache(messages.head, cache.guid) + tryFlushCache() + case Some(cache: CachedGenericEventEnvelope) => + val guid = cache.guid + messages.foreach(msg => pushToCache(msg, guid)) + tryFlushCache() + case _ => + messages.foreach(handleMessage) + } + } } diff --git a/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala new file mode 100644 index 000000000..3c90c8fb8 --- /dev/null +++ b/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala @@ -0,0 +1,83 @@ +// Copyright (c) 2026 PSForever +package net.psforever.services.base.envelope + +import net.psforever.objects.Default +import net.psforever.services.base.EventSystemStamp +import net.psforever.services.base.message.{EventMessage, EventResponse} +import net.psforever.types.PlanetSideGUID + +import scala.annotation.tailrec + +/** + * A message when there should be none, but a message is required to be defined anyway. + */ +case object NoMessage extends EventMessage { + override def response(): EventResponse = NoReply +} + +/** + * A response envelope when there should be none, but an envelope for messaging product is required to be defined anyway. + */ +case object NoResponse extends GenericResponseEnvelope { + override def reply: EventResponse = NoReply + override def stamp: EventSystemStamp = Undelivered + override def channel: String = "" + override def filter: PlanetSideGUID = Default.GUID0 +} + +/** + * A collection of messaging envelopes to be dispatched to an event system at the same time + * within the conditions of event system synchronization between different messages. + * All messages contained within the bundling are to be processed at the time of processing by the bundling. + * The order of the bundled message envelopes should be considered important. + * @see `SendResponse(Seq[PlanetSideGamePacket])` + * @param msgs list of message envelopes + */ +final case class BundledEnvelope(msgs: Iterable[GenericMessageEnvelope]) + extends GenericMessageEnvelope { + assert(msgs.size == BundledEnvelope.unwind(msgs).size, "do not nest bundled event system envelopes") + + override def msg: EventMessage = NoMessage + override def response(stamp: EventSystemStamp): GenericResponseEnvelope = NoResponse + override def channel: String = "" + override def filter: PlanetSideGUID = Default.GUID0 +} + +object BundledEnvelope { + /** + * Overloaded constructor for `BundledEnvelope` objects. + * The entities are separated between "the first" and "any others" to distinguish from + * the `case class` constructor that accepts any number of message envelopes + * including no message envelopes at all. + * @param first single, required `GenericMessageEnvelope` entity for bundling + * @param msgs any other `GenericMessageEnvelope` entity for bundling + * @return a `BundledEnvelope` object + */ + def apply(first: GenericMessageEnvelope, msgs: GenericMessageEnvelope*): BundledEnvelope = { + new BundledEnvelope(unwind(first +: msgs)) + } + + /** + * Input sanitization method that unpacks `BundledEnvelope` message envelopes + * producing a single-dimensional list of `GenericMessageEnvelope` entities. + * An assertion in the constructor of `BundledEnvelope` aborts object creation + * if a `BundledEnvelope` entity is within that `BundledEnvelope` entity. + * @param in list of `GenericMessageEnvelope` entities to be processed + * @param out list of `GenericMessageEnvelope` entities that have been processed + * @return list of `GenericMessageEnvelope` entities that have been processed + */ + @tailrec + private def unwind(in: Iterable[GenericMessageEnvelope], out: List[GenericMessageEnvelope] = Nil): List[GenericMessageEnvelope] = { + if (in.isEmpty) { + out + } else { + val first :: remainder = in + first match { + case bundle: BundledEnvelope => + unwind(bundle.msgs ++ remainder, out) + case _ => + unwind(remainder, out :+ first) + } + } + } +} diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index a8a189a86..e3ca9a6e4 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -6,7 +6,7 @@ import net.psforever.objects.{Default, Doors} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.local.LocalAction.IsADoorMessage import net.psforever.services.local.LocalAction import net.psforever.types.PlanetSideGUID @@ -64,11 +64,13 @@ class DoorCloseActor() extends Actor { doorsLeftOpen1 ++ doorsLeftOpen2.map(entry => DoorCloseActor.DoorEntry(entry.door, entry.zone, now)) ).sortBy(_.time) - doorsToClose2.foreach { case DoorCloseActor.DoorEntry(door, zone, _) => - door.Open = None //permissible break from synchronization - zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.DoorCloses(door.GUID)) //call up to the main event system - } - + doorsToClose2 + .map { case DoorCloseActor.DoorEntry(door, zone, _) => + door.Open = None //permissible break from synchronization + (zone, MessageEnvelope(zone.id, LocalAction.DoorCloses(door.GUID))) //call up to the main event system + } + .groupBy(_._1) + .foreach { case (zone, list) => zone.LocalEvents ! BundledEnvelope(list.map(_._2)) } if (openDoors.nonEmpty) { val short_timeout: FiniteDuration = math.max(1, DoorCloseActor.timeout_time - (now - openDoors.head.time)).milliseconds import scala.concurrent.ExecutionContext.Implicits.global diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index f0af48a72..61c27ec6f 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -14,7 +14,7 @@ import net.psforever.objects.serverobject.structures.participation.MajorFacility import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelopeOnly} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction import net.psforever.services.local.LocalAction @@ -22,6 +22,7 @@ import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} import java.util.concurrent.{Executors, TimeUnit} import scala.collection.Seq +import scala.collection.mutable.ArrayBuffer import scala.concurrent.duration.{FiniteDuration, _} import scala.util.Random @@ -277,18 +278,18 @@ class HackCaptureActor extends Actor { private def HackCompleted(terminal: CaptureTerminal with Hackable, hackedByFaction: PlanetSideEmpire.Value): Unit = { val building = terminal.Owner.asInstanceOf[Building] + val zone = building.Zone + val events = zone.LocalEvents + val messages: ArrayBuffer[MessageEnvelope] = ArrayBuffer() if (building.NtuLevel > 0) { building.virusId = 8 building.virusInstalledBy = None log.info(s"Setting base ${building.GUID} / MapId: ${building.MapId} as owned by $hackedByFaction") //dispatch to players aligned with the capturing faction within the SOI - val events = building.Zone.LocalEvents val msg = LocalAction.GenericActionMessage(GenericAction.FacilityCaptureFanfare) - building - .PlayersInSOI - .collect { case p if p.Faction == hackedByFaction => - events ! MessageEnvelope(p.Name, msg) - } + messages.appendAll(building.PlayersInSOI.collect { case p if p.Faction == hackedByFaction => + MessageEnvelope(p.Name, msg) + }) val buildings = building.Zone.Buildings.values val hackedBaseId = building.GUID val facilities = if (building.Zone.id.startsWith("c")) { @@ -322,8 +323,8 @@ class HackCaptureActor extends Actor { } NotifyHackStateChange(terminal, isResecured = true) // todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. - val zone = building.Zone - zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.HackClear(building.GUID, 3212836864L, HackState7.Unk8)) + messages.append(MessageEnvelope(zone.id, LocalAction.HackClear(building.GUID, 3212836864L, HackState7.Unk8))) + events ! BundledEnvelope(messages) } private def RestartTimer(): Unit = { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index 1d7796984..429cb59c3 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -8,7 +8,7 @@ import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.HackState7 -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelope, GenericSupportEnvelopeOnly} import net.psforever.services.base.message.GenericObjectAction import net.psforever.services.local.LocalAction.IsAHackMessage @@ -72,13 +72,18 @@ class HackClearActor() extends Actor { //TODO we can just walk across the list of doors and extract only the first few entries val (unhackObjects, stillHackedObjects) = PartitionEntries(hackedObjects, now) hackedObjects = stillHackedObjects - unhackObjects.foreach { case HackClearActor.HackEntry(target, zone, unk1, unk2, _, _) => - target.Actor ! CommonMessages.ClearHack() - zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.HackClear(target.GUID, unk1, unk2)) - if (target.Definition == GlobalDefinitions.main_terminal) { - ClearVirusFromBuilding(target) + unhackObjects + .map { case HackClearActor.HackEntry(target, zone, unk1, unk2, _, _) => + target.Actor ! CommonMessages.ClearHack() + if (target.Definition == GlobalDefinitions.main_terminal) { + ClearVirusFromBuilding(target) + } + (zone, MessageEnvelope(zone.id, LocalAction.HackClear(target.GUID, unk1, unk2))) + } + .groupBy(_._1) + .foreach { case (zone, list) => + zone.LocalEvents ! BundledEnvelope(list.map(_._2)) } - } RestartTimer() @@ -132,9 +137,7 @@ class HackClearActor() extends Actor { building.virusInstalledBy = None val msg = GenericObjectAction(target.GUID, 60) val events = building.Zone.AvatarEvents - building.PlayersInSOI.foreach { player => - events ! MessageEnvelope(player.Name, msg) - } + events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) }) building.Actor ! BuildingActor.MapUpdate() } From 1507b91f5e19661c24d6da8fc50a4d05bbf1f07c Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 2 Jun 2026 19:27:41 -0400 Subject: [PATCH 29/32] not necessarily a part of the event bus generalization progress, just have wanted to move these files into this subdirectory for a long time --- .../support/SessionMountHandlers.scala | 3 ++- .../session/support/ZoningOperations.scala | 3 ++- .../net/psforever/objects/Vehicles.scala | 1 + .../{ => control}/AntTransferBehavior.scala | 25 +++++++++++-------- .../{ => control}/BfrTransferBehavior.scala | 7 +++--- .../{ => control}/CargoBehavior.scala | 2 +- .../control/CargoCarrierControl.scala | 2 +- .../{ => control}/CarrierBehavior.scala | 7 +++--- .../base/envelope/BundledEnvelope.scala | 9 +++---- 9 files changed, 33 insertions(+), 26 deletions(-) rename src/main/scala/net/psforever/objects/vehicles/{ => control}/AntTransferBehavior.scala (93%) rename src/main/scala/net/psforever/objects/vehicles/{ => control}/BfrTransferBehavior.scala (98%) rename src/main/scala/net/psforever/objects/vehicles/{ => control}/CargoBehavior.scala (98%) rename src/main/scala/net/psforever/objects/vehicles/{ => control}/CarrierBehavior.scala (99%) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index e8896a491..fe5a674b3 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -5,7 +5,8 @@ import akka.actor.{ActorContext, typed} import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.interior.Sidedness.OutsideOf import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle} -import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons} +import net.psforever.objects.vehicles.MountableWeapons +import net.psforever.objects.vehicles.control.CargoBehavior import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} import net.psforever.services.base.CachedEnvelope diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 9755017f0..f99843679 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -18,10 +18,11 @@ import net.psforever.objects.serverobject.mount.Seat import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.serverobject.turret.auto.AutomatedTurret import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource} +import net.psforever.objects.vehicles.control.{CargoBehavior, CarrierBehavior} import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, ReconstructionActivity, SpawningActivity} import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect -import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage} +import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TrainingZoneMessage, TriggeredSound, WeatherMessage} import net.psforever.services.avatar.support.{CorpseEnvelope, ReleaseEnvelope} import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index 2ef24b137..fbee9477c 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -9,6 +9,7 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.transfer.TransferContainer import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vehicles._ +import net.psforever.objects.vehicles.control.CargoBehavior import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage} import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} diff --git a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala similarity index 93% rename from src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala rename to src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala index 353f7f062..cb5f5fb02 100644 --- a/src/main/scala/net/psforever/objects/vehicles/AntTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala @@ -1,7 +1,8 @@ -// Copyright (c) 2020 PSForever -package net.psforever.objects.vehicles +package net.psforever.objects.vehicles.control import akka.actor.{ActorRef, Cancellable} +import akka.actor.typed.scaladsl.adapter._ + import net.psforever.actors.commands.NtuCommand import net.psforever.actors.zone.BuildingActor import net.psforever.objects.serverobject.deploy.Deployment @@ -10,7 +11,6 @@ import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} import net.psforever.objects._ import net.psforever.types.DriveState -import akka.actor.typed.scaladsl.adapter._ import net.psforever.objects.serverobject.transfer.TransferContainer.TransferMaterial import net.psforever.packet.game.PlanetsideAttributeMessage import net.psforever.services.base.envelope.MessageEnvelope @@ -21,8 +21,8 @@ import scala.concurrent.duration._ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { var panelAnimationFunc: () => Unit = NoCharge - var ntuChargingTick: Cancellable = Default.Cancellable - findChargeTargetFunc = Vehicles.FindANTChargingSource + var ntuChargingTick: Cancellable = Default.Cancellable + findChargeTargetFunc = Vehicles.FindANTChargingSource findDischargeTargetFunc = Vehicles.FindANTDischargingTarget def TransferMaterial: TransferMaterial = Ntu.Nanites @@ -32,7 +32,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { def antBehavior: Receive = storageBehavior.orElse(transferBehavior) def ActivatePanelsForChargingEvent(vehicle: NtuContainer): Unit = { - val obj = ChargeTransferObject + val obj = ChargeTransferObject val zone = obj.Zone zone.VehicleEvents ! MessageEnvelope( zone.id, @@ -42,7 +42,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { /** Charging */ def StartNtuChargingEvent(vehicle: NtuContainer): Unit = { - val obj = ChargeTransferObject + val obj = ChargeTransferObject val zone = obj.Zone zone.VehicleEvents ! MessageEnvelope( zone.id, @@ -188,7 +188,8 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { transferTarget match { case Some(silo: ResourceSilo) => scala.math.min( - scala.math.min(silo.MaxNtuCapacitor / silo.Definition.ChargeTime.toSeconds.toFloat, chargeable.NtuCapacitor), + scala.math + .min(silo.MaxNtuCapacitor / silo.Definition.ChargeTime.toSeconds.toFloat, chargeable.NtuCapacitor), max ) case _ => @@ -208,9 +209,11 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { def HandleNtuGrant(sender: ActorRef, src: NtuContainer, amount: Float): Unit = { val obj = ChargeTransferObject - if (obj.DeploymentState == DriveState.Deployed && - transferEvent == TransferBehavior.Event.Charging && - ReceiveAndDepositUntilFull(obj, amount)) { + if ( + obj.DeploymentState == DriveState.Deployed && + transferEvent == TransferBehavior.Event.Charging && + ReceiveAndDepositUntilFull(obj, amount) + ) { panelAnimationFunc() } else { TryStopChargingEvent(obj) diff --git a/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/control/BfrTransferBehavior.scala similarity index 98% rename from src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala rename to src/main/scala/net/psforever/objects/vehicles/control/BfrTransferBehavior.scala index 3a4ef01dd..db80c1c9a 100644 --- a/src/main/scala/net/psforever/objects/vehicles/BfrTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/BfrTransferBehavior.scala @@ -1,19 +1,20 @@ // Copyright (c) 2021 PSForever -package net.psforever.objects.vehicles +package net.psforever.objects.vehicles.control import akka.actor.ActorRef import akka.actor.typed.scaladsl.adapter._ import net.psforever.actors.commands.NtuCommand import net.psforever.actors.zone.BuildingActor -import net.psforever.objects.{NtuContainer, NtuContainerDefinition, _} +import net.psforever.objects._ import net.psforever.objects.definition.ObjectDefinition import net.psforever.objects.equipment.EquipmentSlot import net.psforever.objects.serverobject.resourcesilo.ResourceSilo import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.serverobject.transfer.{TransferBehavior, TransferContainer} +import net.psforever.objects.vehicles.VehicleSubsystem import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.vehicle.VehicleAction +import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/objects/vehicles/CargoBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/control/CargoBehavior.scala similarity index 98% rename from src/main/scala/net/psforever/objects/vehicles/CargoBehavior.scala rename to src/main/scala/net/psforever/objects/vehicles/control/CargoBehavior.scala index 2a9e9cd97..854adc71b 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CargoBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/CargoBehavior.scala @@ -1,5 +1,5 @@ // Copyright (c) 2020 PSForever -package net.psforever.objects.vehicles +package net.psforever.objects.vehicles.control import akka.actor.Actor import net.psforever.objects._ diff --git a/src/main/scala/net/psforever/objects/vehicles/control/CargoCarrierControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/CargoCarrierControl.scala index 5892d974f..3609f2775 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/CargoCarrierControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/CargoCarrierControl.scala @@ -3,7 +3,7 @@ package net.psforever.objects.vehicles.control import net.psforever.objects._ import net.psforever.objects.serverobject.damage.{Damageable, DamageableVehicle} -import net.psforever.objects.vehicles.{Cargo, CarrierBehavior} +import net.psforever.objects.vehicles.Cargo import net.psforever.objects.vital.interaction.DamageResult /** diff --git a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/control/CarrierBehavior.scala similarity index 99% rename from src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala rename to src/main/scala/net/psforever/objects/vehicles/control/CarrierBehavior.scala index 36e254636..bf3417ce9 100644 --- a/src/main/scala/net/psforever/objects/vehicles/CarrierBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/CarrierBehavior.scala @@ -1,17 +1,18 @@ // Copyright (c) 2021 PSForever -package net.psforever.objects.vehicles +package net.psforever.objects.vehicles.control import akka.actor.{Actor, Cancellable} import net.psforever.actors.zone.ZoneActor -import net.psforever.objects.zones.Zone import net.psforever.objects._ import net.psforever.objects.sourcing.VehicleSource +import net.psforever.objects.vehicles.Cargo import net.psforever.objects.vital.VehicleCargoMountActivity +import net.psforever.objects.zones.Zone import net.psforever.packet.game.{CargoMountPointStatusMessage, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage} -import net.psforever.types.{BailType, CargoStatus, PlanetSideGUID, Vector3} import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.VehicleAction +import net.psforever.types.{BailType, CargoStatus, PlanetSideGUID, Vector3} import scala.concurrent.duration._ diff --git a/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala index 3c90c8fb8..9c831b014 100644 --- a/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/BundledEnvelope.scala @@ -71,12 +71,11 @@ object BundledEnvelope { if (in.isEmpty) { out } else { - val first :: remainder = in - first match { + in.head match { case bundle: BundledEnvelope => - unwind(bundle.msgs ++ remainder, out) - case _ => - unwind(remainder, out :+ first) + unwind(bundle.msgs ++ in.tail, out) + case first => + unwind(in.tail, out :+ first) } } } From 9d2d1cae9f655f65d8b472d568249bf2c4673579 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 8 Jun 2026 19:49:05 -0400 Subject: [PATCH 30/32] a little over-zealous message bundling --- .../actors/session/csr/ChatLogic.scala | 44 +- .../session/csr/MountHandlerLogic.scala | 24 +- .../session/normal/AvatarHandlerLogic.scala | 13 +- .../session/normal/MountHandlerLogic.scala | 20 +- .../session/spectator/MountHandlerLogic.scala | 20 +- .../session/support/GeneralOperations.scala | 54 +- .../support/SessionOutfitHandlers.scala | 512 +++++++++--------- .../session/support/ZoningOperations.scala | 29 +- .../objects/ce/DeployableBehavior.scala | 9 +- .../damage/DamageableMountable.scala | 56 +- .../damage/DamageableVehicle.scala | 2 +- .../damage/DamageableWeaponTurret.scala | 21 +- .../serverobject/dome/ForceDomeControl.scala | 8 +- .../repair/RepairableWeaponTurret.scala | 7 +- .../resourcesilo/ResourceSiloControl.scala | 16 +- .../FacilityHackParticipation.scala | 8 +- .../MajorFacilityHackParticipation.scala | 15 +- .../TowerHackParticipation.scala | 9 +- .../terminals/ProximityTerminalControl.scala | 16 +- .../implant/ImplantTerminalMechControl.scala | 26 +- .../turret/FacilityTurretControl.scala | 8 +- .../turret/VanuSentryControl.scala | 8 +- .../serverobject/turret/WeaponTurrets.scala | 8 +- .../objects/zones/ZoneHotSpotProjector.scala | 8 +- .../services/CavernRotationService.scala | 22 +- .../local/support/HackCaptureActor.scala | 3 +- .../vehicle/support/TurretUpgrader.scala | 7 +- 27 files changed, 485 insertions(+), 488 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index 71b67bf80..13053039c 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -17,7 +17,7 @@ import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage} import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{ObjectDelete, SetEmpire} import net.psforever.services.chat.{ChatChannel, DefaultChannel, SpectatorChannel, SquadChannel} import net.psforever.types.ChatMessageType.{CMT_TOGGLESPECTATORMODE, CMT_TOGGLE_GM} @@ -314,18 +314,20 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext val events = continent.AvatarEvents seeSpectatorsIn = Some(continent) events ! Service.Join(s"spectator") - continent - .AllPlayers - .filter(_.spectator) - .foreach { spectator => - val guid = spectator.GUID - val definition = spectator.Definition - events ! MessageEnvelope( - channel, - guid, - AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None) - ) - } + events ! BundledEnvelope( + continent + .AllPlayers + .filter(_.spectator) + .map { spectator => + val guid = spectator.GUID + val definition = spectator.Definition + MessageEnvelope( + channel, + guid, + AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None) + ) + } + ) true } @@ -334,13 +336,15 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext val events = continent.AvatarEvents seeSpectatorsIn = None events ! Service.Leave("spectator") - continent - .AllPlayers - .filter(_.spectator) - .foreach { spectator => - val guid = spectator.GUID - events ! MessageEnvelope(channel, guid, ObjectDelete(guid)) - } + events ! BundledEnvelope( + continent + .AllPlayers + .filter(_.spectator) + .map { spectator => + val guid = spectator.GUID + MessageEnvelope(channel, guid, ObjectDelete(guid)) + } + ) true } diff --git a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala index 32ef38de7..e7a3b4494 100644 --- a/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/MountHandlerLogic.scala @@ -14,7 +14,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} @@ -212,22 +212,20 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act ops.DismountAction(tplayer, obj, seatNum) continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it //DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages - events ! MessageEnvelope( - player.Name, - SendResponse(PlayerStasisMessage(pguid)) //the stasis message - ) //when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! MessageEnvelope( - player.Name, - SendResponse(PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))) - ) - events ! MessageEnvelope( - continent.id, - pguid, - SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player + events ! BundledEnvelope( + MessageEnvelope(player.Name, + SendResponse(Seq( + PlayerStasisMessage(pguid), + PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) + )) + ), + MessageEnvelope(continent.id, pguid, + SendResponse(GenericObjectActionMessage(pguid, code=9)) /* conceal the player */ + ) ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive 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 1a22a3bd2..43b21255f 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -14,7 +14,7 @@ import net.psforever.objects.vital.RevivingActivity import net.psforever.objects.vital.interaction.Adversarial import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction, PlanetsideStringAttributeMessage} import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire} import net.psforever.types.ImplantType @@ -635,11 +635,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } def killedWhileMounted(obj: PlanetSideGameObject with Mountable, playerGuid: PlanetSideGUID): Unit = { - val events = continent.AvatarEvents ops.killedWhileMounted(obj, playerGuid) - //make player invisible on client - events ! MessageEnvelope(player.Name, PlanetsideAttribute(playerGuid, 29, 1)) - //only the dead player should "see" their own body, so that the death camera has something to focus on - events ! MessageEnvelope(continent.id, playerGuid, ObjectDelete(playerGuid)) + continent.AvatarEvents ! BundledEnvelope( + /* make player invisible on client */ + MessageEnvelope(player.Name, PlanetsideAttribute(playerGuid, 29, 1)), + /* only the dead player should "see" their own body, so that the death camera has something to focus on */ + MessageEnvelope(continent.id, playerGuid, ObjectDelete(playerGuid)) + ) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala index 4efc44ecd..aa0f86714 100644 --- a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala @@ -16,7 +16,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret} import net.psforever.objects.vehicles.AccessPermissionGroup import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3} @@ -253,14 +253,16 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! MessageEnvelope(player.Name, SendResponse(Seq( - PlayerStasisMessage(pguid), - PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) - ))) - events ! MessageEnvelope( - continent.id, - pguid, - SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player + events ! BundledEnvelope( + MessageEnvelope(player.Name, + SendResponse(Seq( + PlayerStasisMessage(pguid), + PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) + )) + ), + MessageEnvelope(continent.id, pguid, + SendResponse(GenericObjectActionMessage(pguid, code=9)) /* conceal the player */ + ) ) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive diff --git a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala index 89ca48498..c56699848 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala @@ -12,7 +12,7 @@ import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech import net.psforever.objects.vital.InGameHistory import net.psforever.packet.game.{DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.VehicleAction @@ -80,14 +80,16 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act //the player will fall to the ground and is perfectly vulnerable in this state //additionally, our player must exist in the current zone //having no in-game avatar target will throw us out of the map screen when deploying and cause softlock - events ! MessageEnvelope(player.Name, SendResponse(Seq( - PlayerStasisMessage(pguid), - PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) - ))) - events ! MessageEnvelope( - continent.id, - pguid, - SendResponse(GenericObjectActionMessage(pguid, code=9)) //conceal the player + events ! BundledEnvelope( + MessageEnvelope(player.Name, + SendResponse(Seq( + PlayerStasisMessage(pguid), + PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) + )) + ), + MessageEnvelope(continent.id, pguid, + SendResponse(GenericObjectActionMessage(pguid, code=9)) /* conceal the player */ + ) ) context.self ! SessionActor.SetMode(NormalMode) sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index b11479e7f..3d34e5071 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -18,7 +18,7 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.avatar.support.GroundEnvelope -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.base.support.RemoverActor import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor} @@ -201,26 +201,26 @@ class GeneralOperations( val guid = player.GUID val zone = player.Zone val events = zone.LocalEvents - val msg = SendResponse(pkt) - sessionLogic - .localSector - .livePlayerList - .filter(_.GUID != guid) - .foreach { p => - events ! MessageEnvelope(p.Name, msg) - } //todo better way to collect csr players while utilizing the aforementioned benefit of localSector val position = player.Position val rangeSq = { val range = math.sqrt(2 * math.pow(sessionLogic.localSector.rangeX.toDouble, 2)) range * range } - zone + val msg = SendResponse(pkt) + val (localRecipients, localRecipientMessages) = sessionLogic + .localSector + .livePlayerList + .filter(_.GUID != guid) + .map { p => (p.Name, MessageEnvelope(p.Name, msg)) } + .unzip + val otherRecipientMessages = zone .AllPlayers - .filter { p => !p.allowInteraction && p.GUID != guid && Vector3.DistanceSquared(p.Position, position) < rangeSq } - .foreach { p => - events ! MessageEnvelope(p.Name, msg) + .filter { p => + !p.allowInteraction && p.GUID != guid && !localRecipients.contains(p.Name) && Vector3.DistanceSquared(p.Position, position) < rangeSq } + .map(p => MessageEnvelope(p.Name, msg)) + events ! BundledEnvelope(localRecipientMessages ++ otherRecipientMessages) } def handleDropItem(pkt: DropItemMessage): GeneralOperations.ItemDropState.Behavior = { @@ -1476,23 +1476,21 @@ class GeneralOperations( val events = continent.AvatarEvents val zoneid = continent.id val destinationPosition = dest.Position - events ! MessageEnvelope(zoneid, pguid, ObjectDelete(pguid)) - events ! MessageEnvelope(player.Name, - SendResponse(PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z))) - ) player.Position = destinationPosition - events ! MessageEnvelope(zoneid, pguid, AvatarAction.LoadPlayer( - player.Definition.ObjectId, - pguid, - player.Definition.Packet.ConstructorData(player).get, - None - )) - useRouterTelepadEffect(pguid, sguid, dguid) - events ! MessageEnvelope( - continent.id, - pguid, - LocalAction.RouterTelepadTransport(pguid, sguid, dguid) + events ! BundledEnvelope( + MessageEnvelope(zoneid, pguid, ObjectDelete(pguid)), + MessageEnvelope(player.Name, + SendResponse(PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z))) + ), + MessageEnvelope(zoneid, pguid, AvatarAction.LoadPlayer( + player.Definition.ObjectId, + pguid, + player.Definition.Packet.ConstructorData(player).get, + None + )), + MessageEnvelope(zoneid, pguid, LocalAction.RouterTelepadTransport(pguid, sguid, dguid)) ) + useRouterTelepadEffect(pguid, sguid, dguid) sessionLogic.zoning.spawn.ShiftPosition = destinationPosition player.LogActivity(TelepadUseActivity(VehicleSource(router), DeployableSource(remoteTelepad), PlayerSource(player))) } else { diff --git a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala index 25abda4c5..a47103dad 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala @@ -9,8 +9,8 @@ import net.psforever.packet.game.OutfitEventAction.{Initial, Leaving, OutfitInfo import net.psforever.packet.game.OutfitMembershipResponse.PacketType.CreateResponse import net.psforever.packet.game._ import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope -import net.psforever.services.base.message.PlanetsideAttribute +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.chat.OutfitChannel import net.psforever.types.ChatMessageType import net.psforever.util.Config @@ -50,63 +50,62 @@ object SessionOutfitHandlers { import scala.concurrent.Future def HandleOutfitForm(outfitName: String, player: Player, session: SessionData): Unit = { + val zone = player.Zone + val zoneid = zone.id + val charid = player.CharId + val pname = player.Name val cleanedName = sanitizeOutfitName(outfitName) cleanedName match { case Some(validName) => ctx.run(findOutfitByName(validName)).flatMap { case existing if existing.nonEmpty => - PlayerControl.sendResponse(player.Zone, player.Name, - ChatMsg(ChatMessageType.UNK_227, "@OutfitErrorNameAlreadyTaken")) + PlayerControl.sendResponse(zone, pname, + ChatMsg(ChatMessageType.UNK_227, "@OutfitErrorNameAlreadyTaken") + ) Future.successful(()) case _ => - createNewOutfit(validName, player.Faction.id, player.CharId).map { outfit => - val seconds: Long = - outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 - - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitEvent(outfit.id, Update( - OutfitInfo( - outfit.name, 0, 0, 1, - OutfitRankNames("", "", "", "", "", "", "", ""), - "", - 14, unk11 = true, 0, seconds, 0, 0, 0)))) - - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitMemberUpdate(outfit.id, player.CharId, 7, flag = true)) - - PlayerControl.sendResponse(player.Zone, player.Name, - ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateSuccess")) - - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitMembershipResponse(CreateResponse, 0, 0, player.CharId, 0, "", "", flag = true)) - - player.outfit_id = outfit.id - player.outfit_name = outfit.name - - player.Zone.AvatarEvents ! MessageEnvelope( - player.Zone.id, - PlanetsideAttribute(player.GUID, 39, outfit.id) + createNewOutfit(validName, player.Faction.id, charid).map { outfit => + val outfitId = outfit.id + val outfitName = outfit.name + val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 + player.outfit_id = outfitId + player.outfit_name = outfitName + zone.AvatarEvents ! BundledEnvelope( + MessageEnvelope(pname, SendResponse(List( + OutfitEvent(outfitId, Update( + OutfitInfo( + outfitName, 0, 0, 1, + OutfitRankNames("", "", "", "", "", "", "", ""), + "", + 14, unk11 = true, 0, seconds, 0, 0, 0) + )), + OutfitMemberUpdate(outfitId, charid, 7, flag = true), + ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateSuccess"), + OutfitMembershipResponse(CreateResponse, 0, 0, charid, 0, "", "", flag = true), + ))), + MessageEnvelope( + zoneid, + PlanetsideAttribute(player.GUID, 39, outfitId) + ), + MessageEnvelope( + zoneid, + player.GUID, + AvatarAction.PlanetsideStringAttribute(0, outfitName) + ) ) - - player.Zone.AvatarEvents ! MessageEnvelope( - player.Zone.id, - player.GUID, - AvatarAction.PlanetsideStringAttribute(0, outfit.name) - ) - - session.chat.JoinChannel(OutfitChannel(player.outfit_id)) + session.chat.JoinChannel(OutfitChannel(outfitId)) } .recover { case e => e.printStackTrace() - PlayerControl.sendResponse(player.Zone, player.Name, - ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure")) + PlayerControl.sendResponse(zone, pname, + ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure") + ) } } case None => - PlayerControl.sendResponse(player.Zone, player.Name, - ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure")) + PlayerControl.sendResponse(zone, pname, ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure")) } } @@ -127,74 +126,80 @@ object SessionOutfitHandlers { } def HandleOutfitInviteAccept(invited: Player, session: SessionData): Unit = { - OutfitInviteManager.getOutfitInvite(invited.CharId) match { + val toName = invited.Name + val toCharId = invited.CharId + val toZone = invited.Zone + val toZoneId = toZone.id + val toGuid = invited.GUID + OutfitInviteManager.getOutfitInvite(toCharId) match { case Some(outfitInvite) => + val fromName = outfitInvite.sentFrom.Name + val fromCharId = outfitInvite.sentFrom.CharId + val fromZone = outfitInvite.sentFrom.Zone val outfitId = outfitInvite.sentFrom.outfit_id - (for { - _ <- addMemberToOutfit(outfitId, invited.CharId) + _ <- addMemberToOutfit(outfitId, toCharId) outfitOpt <- ctx.run(getOutfitById(outfitId)).map(_.headOption) memberCount <- ctx.run(getOutfitMemberCount(outfitId)) points <- ctx.run(getOutfitPoints(outfitId)).map(_.headOption.map(_.points).getOrElse(0L)) } yield (outfitOpt, memberCount, points)) .map { case (Some(outfit), memberCount, points) => - - PlayerControl.sendResponse(outfitInvite.sentFrom.Zone, outfitInvite.sentFrom.Name, - OutfitMembershipResponse( - OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0, - invited.CharId, outfitInvite.sentFrom.CharId, invited.Name, outfit.name, flag = false)) - - PlayerControl.sendResponse(invited.Zone, invited.Name, - OutfitMembershipResponse( - OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0, - invited.CharId, outfitInvite.sentFrom.CharId, invited.Name, outfit.name, flag = true)) - - PlayerControl.sendResponse(outfitInvite.sentFrom.Zone, outfitInvite.sentFrom.Name, - OutfitEvent(outfitId, UpdateMemberCount(memberCount))) - - PlayerControl.sendResponse(outfitInvite.sentFrom.Zone, outfitInvite.sentFrom.Name, - OutfitMemberEvent(outfitId, invited.CharId, - OutfitMemberEventAction.Update(invited.Name, 0, 0, 0, - OutfitMemberEventAction.PacketType.Padding, 0))) - + val outfitName = outfit.name val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 - PlayerControl.sendResponse(invited.Zone, invited.Name, - OutfitEvent(outfitId, Initial(OutfitInfo( - outfit.name, points, points, memberCount, - OutfitRankNames("", "", "", "", "", "", "", ""), - outfit.motd.getOrElse(""), - 14, unk11 = true, 0, seconds, 0, 0, 0)))) - - PlayerControl.sendResponse(invited.Zone, invited.Name, - OutfitMemberUpdate(outfit.id, invited.CharId, 0, flag=true)) - - OutfitInviteManager.removeOutfitInvite(invited.CharId) - - session.chat.JoinChannel(OutfitChannel(outfit.id)) - invited.outfit_id = outfit.id - invited.outfit_name = outfit.name - - invited.Zone.AvatarEvents ! MessageEnvelope( - invited.Zone.id, - PlanetsideAttribute(invited.GUID, 39, outfit.id) + fromZone.AvatarEvents ! BundledEnvelope( + MessageEnvelope(fromName, SendResponse(List( + OutfitMembershipResponse( + OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0, + toCharId, fromCharId, toName, outfitName, flag = false + ), + OutfitEvent(outfitId, UpdateMemberCount(memberCount)), + OutfitMemberEvent(outfitId, toCharId, + OutfitMemberEventAction.Update(toName, 0, 0, 0, + OutfitMemberEventAction.PacketType.Padding, 0 + ) + ) + ))) ) - - invited.Zone.AvatarEvents ! MessageEnvelope( - invited.Zone.id, - invited.GUID, - AvatarAction.PlanetsideStringAttribute(0, outfit.name) + toZone.AvatarEvents ! BundledEnvelope( + MessageEnvelope(toName, SendResponse(List( + OutfitMembershipResponse( + OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0, + toCharId, fromCharId, toName, outfitName, flag = true + ), + OutfitEvent(outfitId, Initial(OutfitInfo( + outfitName, points, points, memberCount, + OutfitRankNames("", "", "", "", "", "", "", ""), + outfit.motd.getOrElse(""), + 14, unk11 = true, 0, seconds, 0, 0, 0 + ))), + OutfitMemberUpdate(outfitId, toCharId, 0, flag=true) + ))), + MessageEnvelope( + toZoneId, + PlanetsideAttribute(toGuid, 39, outfitId) + ), + MessageEnvelope( + toZoneId, + toGuid, + AvatarAction.PlanetsideStringAttribute(0, outfitName) + ) + ) + OutfitInviteManager.removeOutfitInvite(toCharId) + session.chat.JoinChannel(OutfitChannel(outfitId)) + invited.outfit_id = outfitId + invited.outfit_name = outfitName + case (None, _, _) => () + PlayerControl.sendResponse(toZone, toName, + ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit") ) - case (None, _, _) => - - PlayerControl.sendResponse(invited.Zone, invited.Name, - ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit")) - } - .recover { case _ => - PlayerControl.sendResponse(invited.Zone, invited.Name, - ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit")) } - case None => + .recover { case _ => + PlayerControl.sendResponse(toZone, toName, + ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit") + ) + } + case None => () } } @@ -218,82 +223,76 @@ object SessionOutfitHandlers { } def HandleOutfitKick(zones: Seq[Zone], kickedId: Long, kickedBy: Player, session: SessionData): Unit = { + val outfit_id = kickedBy.outfit_id // if same id, player has left the outfit by their own choice if (kickedId == kickedBy.CharId) { - // store outfit_id since it will be nulled soon - val outfit_id = kickedBy.outfit_id - removeMemberFromOutfit(outfit_id, kickedId).map { case (deleted, _) => if (deleted > 0) { - - PlayerControl.sendResponse(kickedBy.Zone, kickedBy.Name, - OutfitEvent(outfit_id, Leaving()) + kickedBy.Zone.AvatarEvents ! BundledEnvelope( + MessageEnvelope(kickedBy.Name, SendResponse(OutfitEvent(outfit_id, Leaving()))), + MessageEnvelope( + kickedBy.Zone.id, + PlanetsideAttribute(kickedBy.GUID, 39, 0) + ), + MessageEnvelope( + kickedBy.Zone.id, + kickedBy.GUID, + AvatarAction.PlanetsideStringAttribute(0, "") + ) ) - session.chat.LeaveChannel(OutfitChannel(outfit_id)) kickedBy.outfit_name = "" kickedBy.outfit_id = 0 - zones.filter(z => z.AllPlayers.nonEmpty).flatMap(_.AllPlayers) - .filter(p => p.outfit_id == outfit_id).foreach(outfitMember => - PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name, - OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked())) - ) - - kickedBy.Zone.AvatarEvents ! MessageEnvelope( - kickedBy.Zone.id, - PlanetsideAttribute(kickedBy.GUID, 39, 0) - ) - - kickedBy.Zone.AvatarEvents ! MessageEnvelope( - kickedBy.Zone.id, - kickedBy.GUID, - AvatarAction.PlanetsideStringAttribute(0, "") - ) + zones + .filter(z => z.AllPlayers.nonEmpty) + .flatMap(_.AllPlayers) + .filter(p => p.outfit_id == outfit_id) + .foreach(outfitMember => + PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name, + OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked()) + ) + ) } }.recover { case e => e.printStackTrace() } } else { - removeMemberFromOutfit(kickedBy.outfit_id, kickedId).map { + removeMemberFromOutfit(outfit_id, kickedId).map { case (deleted, _) => if (deleted > 0) { findPlayerByIdForOutfitAction(zones, kickedId, kickedBy).foreach { kicked => - - PlayerControl.sendResponse(kicked.Zone, kicked.Name, - OutfitEvent(kickedBy.outfit_id, Leaving()) + kicked.Zone.AvatarEvents ! BundledEnvelope( + MessageEnvelope(kicked.Name, SendResponse(List( + OutfitEvent(outfit_id, Leaving()), + OutfitMembershipResponse( + OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1, + kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false + ) + ))), + MessageEnvelope(kicked.Zone.id, + PlanetsideAttribute(kicked.GUID, 39, 0) + ), + MessageEnvelope( + kicked.Zone.id, + kicked.GUID, + AvatarAction.PlanetsideStringAttribute(0, "") + ), + MessageEnvelope(kicked.Name, + AvatarAction.RemoveFromOutfitChat(outfit_id) + ), + MessageEnvelope(kicked.Name, SendResponse( + OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked()) + )) ) - - PlayerControl.sendResponse(kicked.Zone, kicked.Name, - OutfitMembershipResponse(OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1, - kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false)) - - kicked.Zone.AvatarEvents ! MessageEnvelope( - kicked.Zone.id, - PlanetsideAttribute(kicked.GUID, 39, 0) - ) - - kicked.Zone.AvatarEvents ! MessageEnvelope( - kicked.Zone.id, - kicked.GUID, - AvatarAction.PlanetsideStringAttribute(0, "") - ) - - kicked.Zone.AvatarEvents ! MessageEnvelope( - kicked.Name, AvatarAction.RemoveFromOutfitChat(kickedBy.outfit_id)) - kicked.outfit_id = 0 kicked.outfit_name = "" - PlayerControl.sendResponse(kicked.Zone, kicked.Name, - OutfitMemberEvent(kickedBy.outfit_id, kickedId, OutfitMemberEventAction.Kicked())) } val avatarName: Future[Option[String]] = - ctx.run( - quote { query[Avatar].filter(_.id == lift(kickedId)).map(_.name) } - ).map(_.headOption) + ctx.run(quote { query[Avatar].filter(_.id == lift(kickedId)).map(_.name) }).map(_.headOption) avatarName.foreach { case Some(name) => PlayerControl.sendResponse(kickedBy.Zone, kickedBy.Name, @@ -302,10 +301,14 @@ object SessionOutfitHandlers { case None => PlayerControl.sendResponse(kickedBy.Zone, kickedBy.Name, OutfitMembershipResponse(OutfitMembershipResponse.PacketType.YouKicked, 0, 1, kickedBy.CharId, kickedId, "NameNotFound", "", flag = true)) } - zones.filter(z => z.AllPlayers.nonEmpty).flatMap(_.AllPlayers) - .filter(p => p.outfit_id == kickedBy.outfit_id).foreach(outfitMember => - PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name, - OutfitMemberEvent(kickedBy.outfit_id, kickedId, OutfitMemberEventAction.Kicked())) + zones + .filter(z => z.AllPlayers.nonEmpty) + .flatMap(_.AllPlayers) + .filter(p => p.outfit_id == kickedBy.outfit_id) + .foreach(outfitMember => + PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name, + OutfitMemberEvent(kickedBy.outfit_id, kickedId, OutfitMemberEventAction.Kicked()) + ) ) // this needs to be the kicked player // session.chat.LeaveChannel(OutfitChannel(kickedBy.outfit_id)) @@ -319,18 +322,13 @@ object SessionOutfitHandlers { } def HandleOutfitPromote(zones: Seq[Zone], promotedId: Long, newRank: Int, promoter: Player): Unit = { - val outfit_id = promoter.outfit_id - findPlayerByIdForOutfitAction(zones, promotedId, promoter).foreach { promoted => - if (newRank == 7) { - // demote owner to rank 6 // promote promoted to rank 7 // update outfit updateOutfitOwner(outfit_id, promoter.avatar.id, promoted.avatar.id) - // TODO: does every member get the notification like this? getOutfitMemberPoints(outfit_id, promoter.avatar.id).map { owner_points => @@ -346,7 +344,6 @@ object SessionOutfitHandlers { }) }) } - // update promoter rank PlayerControl.sendResponse( promoter.Zone, promoter.Name, @@ -360,17 +357,19 @@ object SessionOutfitHandlers { // TODO: does every member get the notification like this? getOutfitMemberPoints(outfit_id, promoted.avatar.id).map { member_points => - // tell everyone about the new rank of the promoted member - zones.foreach(zone => { - zone.AllPlayers + zones.foreach { zone => + // tell everyone about the new rank of the promoted member + val messages = zone.AllPlayers .filter(_.outfit_id == outfit_id) - .foreach(player => { - PlayerControl.sendResponse( - zone, player.Name, + .map { player => + MessageEnvelope(player.Name, SendResponse( OutfitMemberEvent(outfit_id, promoted.avatar.id, - OutfitMemberEventAction.Update(promoted.Name, newRank, member_points, 0, OutfitMemberEventAction.PacketType.Padding, 0))) - }) - }) + OutfitMemberEventAction.Update(promoted.Name, newRank, member_points, 0, OutfitMemberEventAction.PacketType.Padding, 0) + ) + )) + } + zone.AvatarEvents ! BundledEnvelope(messages) + } } // update promoted rank @@ -386,7 +385,6 @@ object SessionOutfitHandlers { memberCount <- ctx.run(query[Outfitmember].filter(_.outfit_id == lift(outfitId)).size) pointsTotal <- ctx.run(querySchema[OutfitpointMv]("outfitpoint_mv").filter(_.outfit_id == lift(outfitId))) } yield (outfitOpt, memberCount, pointsTotal.headOption.map(_.points).getOrElse(0L)) - val membersF = ctx.run(getOutfitMembersWithDetails(outfitId)) for { @@ -395,43 +393,42 @@ object SessionOutfitHandlers { } yield { outfitOpt.foreach { outfit => val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 - - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitEvent(outfit.id, Initial(OutfitInfo( - outfit.name, - totalPoints, - totalPoints, - memberCount, - OutfitRankNames( - outfit.rank0.getOrElse(""), - outfit.rank1.getOrElse(""), - outfit.rank2.getOrElse(""), - outfit.rank3.getOrElse(""), - outfit.rank4.getOrElse(""), - outfit.rank5.getOrElse(""), - outfit.rank6.getOrElse(""), - outfit.rank7.getOrElse(""), - ), - outfit.motd.getOrElse(""), - 14, unk11 = true, 0, seconds, 0, 0, 0)))) - - members.foreach { case (avatarId, avatarName, points, rank, login) => + val outfitEventInitial = OutfitEvent(outfit.id, Initial(OutfitInfo( + outfit.name, + totalPoints, + totalPoints, + memberCount, + OutfitRankNames( + outfit.rank0.getOrElse(""), + outfit.rank1.getOrElse(""), + outfit.rank2.getOrElse(""), + outfit.rank3.getOrElse(""), + outfit.rank4.getOrElse(""), + outfit.rank5.getOrElse(""), + outfit.rank6.getOrElse(""), + outfit.rank7.getOrElse(""), + ), + outfit.motd.getOrElse(""), + 14, unk11 = true, 0, seconds, 0, 0, 0)) + ) + val memberEventList = members.map { case (avatarId, avatarName, points, rank, login) => val lastLogin = findPlayerByIdForOutfitAction(zones, avatarId, player) match { case Some(_) => 0L case None if player.Name == avatarName => 0L case None => (System.currentTimeMillis() - login.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli) / 1000 } - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitMemberEvent(outfit.id, avatarId, - OutfitMemberEventAction.Update( - avatarName, - rank, - points, - lastLogin, - OutfitMemberEventAction.PacketType.Padding, 0))) + OutfitMemberEvent(outfit.id, avatarId, + OutfitMemberEventAction.Update( + avatarName, + rank, + points, + lastLogin, + OutfitMemberEventAction.PacketType.Padding, 0) + ) } - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitEvent(outfit.id, Unk1())) + player.Zone.AvatarEvents ! MessageEnvelope(player.Name, SendResponse( + outfitEventInitial +: memberEventList :+ OutfitEvent(outfit.id, Unk1()) + )) } } } @@ -442,16 +439,13 @@ object SessionOutfitHandlers { futureResult.onComplete { case Success(rows) => - rows.foreach { case (outfitId, points, name, leaderName, memberCount) => - PlayerControl.sendResponse(player.Zone, player.Name, + player.Zone.AvatarEvents ! MessageEnvelope(player.Name, SendResponse( + rows.map { case (outfitId, points, name, leaderName, memberCount) => OutfitListEvent( - OutfitListEventAction.ListElementOutfit( - outfitId, - points, - memberCount, - name, - leaderName))) - } + OutfitListEventAction.ListElementOutfit(outfitId, points, memberCount, name, leaderName) + ) + } + )) case Failure(_) => PlayerControl.sendResponse(player.Zone, player.Name, @@ -461,9 +455,7 @@ object SessionOutfitHandlers { } def HandleOutfitMotd(zones: Seq[Zone], message: String, player: Player): Unit = { - val outfit_id = player.outfit_id - val outfitDetails = for { _ <- updateOutfitMotd(outfit_id, message) outfitOpt <- ctx.run(getOutfitById(outfit_id)).map(_.headOption) @@ -475,9 +467,8 @@ object SessionOutfitHandlers { (outfitOpt, memberCount, totalPoints) <- outfitDetails } yield { outfitOpt.foreach { outfit => - // send to all online players in outfit - val outfit_event = OutfitEvent( + val outfit_event = SendResponse(OutfitEvent( outfit_id, Update( OutfitInfo( @@ -505,19 +496,15 @@ object SessionOutfitHandlers { unk25 = 0 ) ) - ) + )) - zones.foreach(zone => { - zone.AllPlayers - .filter(_.outfit_id == outfit_id) - .filter(_.outfit_window_open) - .foreach(player => { - PlayerControl.sendResponse( - zone, player.Name, - outfit_event - ) - }) - }) + zones.foreach { zone => + zone.AvatarEvents ! BundledEnvelope( + zone.AllPlayers + .filter { p => p.outfit_id == outfit_id && p.outfit_window_open } + .map(p => MessageEnvelope(p.Name, outfit_event)) + ) + } } } @@ -526,9 +513,7 @@ object SessionOutfitHandlers { } def HandleOutfitRank(zones: Seq[Zone], list: List[Option[String]], player: Player): Unit = { - val outfit_id = player.outfit_id - val outfitDetails = for { _ <- updateOutfitRanks(outfit_id, list) outfitOpt <- ctx.run(getOutfitById(outfit_id)).map(_.headOption) @@ -540,9 +525,8 @@ object SessionOutfitHandlers { (outfitOpt, memberCount, totalPoints) <- outfitDetails } yield { outfitOpt.foreach { outfit => - // send to all online players in outfit with window open - val outfit_event = OutfitEvent( + val outfit_event = SendResponse(OutfitEvent( outfit_id, Update( OutfitInfo( @@ -570,19 +554,15 @@ object SessionOutfitHandlers { unk25 = 0 ) ) - ) + )) - zones.foreach(zone => { - zone.AllPlayers - .filter(_.outfit_id == outfit_id) - .filter(_.outfit_window_open) - .foreach(player => { - PlayerControl.sendResponse( - zone, player.Name, - outfit_event - ) - }) - }) + zones.foreach { zone => + zone.AvatarEvents ! BundledEnvelope( + zone.AllPlayers + .filter { p => p.outfit_id == outfit_id && p.outfit_window_open } + .map(p => MessageEnvelope(p.Name, outfit_event)) + ) + } } } } @@ -618,34 +598,34 @@ object SessionOutfitHandlers { .map { case (Some(outfit), memberCount, points) => val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 - - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitEvent(outfitId, Update(OutfitInfo( - outfit.name, points, points, memberCount, - OutfitRankNames(outfit.rank0.getOrElse(""), outfit.rank1.getOrElse(""), outfit.rank2.getOrElse(""), - outfit.rank3.getOrElse(""), outfit.rank4.getOrElse(""), outfit.rank5.getOrElse(""), - outfit.rank6.getOrElse(""), outfit.rank7.getOrElse("")), - outfit.motd.getOrElse(""), - 14, unk11 = true, 0, seconds, 0, 0, 0)))) - - PlayerControl.sendResponse(player.Zone, player.Name, - OutfitMemberUpdate(outfit.id, player.CharId, membership.rank, flag = true)) - + player.Zone.AvatarEvents ! BundledEnvelope( + MessageEnvelope(player.Name, SendResponse(List( + OutfitEvent(outfitId, Update(OutfitInfo( + outfit.name, points, points, memberCount, + OutfitRankNames( + outfit.rank0.getOrElse(""), outfit.rank1.getOrElse(""), outfit.rank2.getOrElse(""), + outfit.rank3.getOrElse(""), outfit.rank4.getOrElse(""), outfit.rank5.getOrElse(""), + outfit.rank6.getOrElse(""), outfit.rank7.getOrElse("") + ), + outfit.motd.getOrElse(""), + 14, unk11 = true, 0, seconds, 0, 0, 0 + ))), + OutfitMemberUpdate(outfit.id, player.CharId, membership.rank, flag = true) + ))), + MessageEnvelope( + player.Zone.id, + PlanetsideAttribute(player.GUID, 39, outfit.id) + ), + MessageEnvelope( + player.Zone.id, + player.GUID, + AvatarAction.PlanetsideStringAttribute(0, outfit.name) + ) + ) session.chat.JoinChannel(OutfitChannel(outfit.id)) player.outfit_id = outfit.id player.outfit_name = outfit.name - player.Zone.AvatarEvents ! MessageEnvelope( - player.Zone.id, - PlanetsideAttribute(player.GUID, 39, outfit.id) - ) - - player.Zone.AvatarEvents ! MessageEnvelope( - player.Zone.id, - player.GUID, - AvatarAction.PlanetsideStringAttribute(0, outfit.name) - ) - case (None, _, _) => PlayerControl.sendResponse(player.Zone, player.Name, ChatMsg(ChatMessageType.UNK_227, "Failed to load outfit")) @@ -876,7 +856,7 @@ object SessionOutfitHandlers { query[Outfit] .filter(_.id == lift(outfit_id)) .update( - _.rank0 -> lift(colorized(0)), + _.rank0 -> lift(colorized.head), _.rank1 -> lift(colorized(1)), _.rank2 -> lift(colorized(2)), _.rank3 -> lift(colorized(3)), diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index f99843679..3d2ab4e50 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -24,7 +24,7 @@ import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TrainingZoneMessage, TriggeredSound, WeatherMessage} import net.psforever.services.avatar.support.{CorpseEnvelope, ReleaseEnvelope} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.chat.DefaultChannel @@ -4005,21 +4005,20 @@ class ZoningOperations( } GoToDeploymentMap() val pZone = player.Zone + val msg = GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) sendResponse(GenericActionMessage(FirstPersonViewWithEffect)) - pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID => - pZone.LocalEvents ! MessageEnvelope( - t.Name, - t.GUID, - GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) - ) - } - pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction => - pZone.LocalEvents ! MessageEnvelope( - t.Name, - t.GUID, - GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id) - ) - } + val (localMessageRecipients, localMesages) = pZone.blockMap.sector(player).livePlayerList + .collect { + case t if t.GUID != player.GUID => + (t.Name, MessageEnvelope(t.Name, msg)) + } + .unzip + val otherMessages: Seq[MessageEnvelope] = pZone.AllPlayers + .collect { + case t if t.GUID != player.GUID && !t.allowInteraction && !localMessageRecipients.contains(t.Name) => + MessageEnvelope(t.Name, msg) + } + pZone.LocalEvents ! BundledEnvelope(localMesages ++ otherMessages) } def stopDeconstructing(): Unit = { diff --git a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala index 160776650..18a4585fa 100644 --- a/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala +++ b/src/main/scala/net/psforever/objects/ce/DeployableBehavior.scala @@ -293,11 +293,12 @@ object DeployableBehavior { MessageEnvelope(toFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Build, info)) ) //remove deployable from original owner's toolbox and UI counter - zone.AllPlayers.filter(p => obj.OriginalOwnerName.contains(p.Name)) - .foreach { originalOwner => + localEvents ! BundledEnvelope(zone.AllPlayers + .filter(p => obj.OriginalOwnerName.contains(p.Name)) + .map { originalOwner => originalOwner.avatar.deployables.Remove(obj) - originalOwner.Zone.LocalEvents ! MessageEnvelope(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) - } + MessageEnvelope(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item)) + }) } } } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala index ec076c715..90e859a9e 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableMountable.scala @@ -7,7 +7,7 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{HintsAtAttacker, SendResponse} /** @@ -37,32 +37,34 @@ object DamageableMountable { val zone = target.Zone val events = zone.AvatarEvents val occupants = target.Seats.values.toSeq.flatMap { seat => seat.occupants.filter(_.isAlive) } - ((cause.adversarial match { - case Some(adversarial) => Some(adversarial.attacker) - case None => None - }) match { - case Some(pSource: PlayerSource) => //player damage - val name = pSource.Name - (zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match { - case Some(player) => - HintsAtAttacker(player.GUID) - case None => - SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) - }) match { - case msg @ HintsAtAttacker(guid) => - occupants.map { tplayer => (tplayer.Name, guid, msg) } - case msg => - occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) } - } - case Some(source) => //object damage - val msg = SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) - occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) } - case None => - List.empty - }).foreach { - case (channel, filter, msg) => - events ! MessageEnvelope(channel, filter, msg) - } + events ! BundledEnvelope( + ((cause.adversarial match { + case Some(adversarial) => Some(adversarial.attacker) + case None => None + }) match { + case Some(pSource: PlayerSource) => //player damage + val name = pSource.Name + (zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match { + case Some(player) => + HintsAtAttacker(player.GUID) + case None => + SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position)) + }) match { + case msg @ HintsAtAttacker(guid) => + occupants.map { tplayer => (tplayer.Name, guid, msg) } + case msg => + occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) } + } + case Some(source) => //object damage + val msg = SendResponse(DamageWithPositionMessage(countableDamage, source.Position)) + occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) } + case None => + List.empty + }).map { + case (channel, filter, msg) => + MessageEnvelope(channel, filter, msg) + } + ) } /** diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index 925484cab..4d609076a 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -253,7 +253,7 @@ trait DamageableVehicle ) if (obj.Shields > 0) { obj.Shields = 0 - zone.VehicleEvents ! MessageEnvelope( + events ! MessageEnvelope( zone.id, PlanetsideAttribute(obj.GUID, obj.Definition.shieldUiAttribute, 0) ) diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala index 7769ac6b8..250aa61c2 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableWeaponTurret.scala @@ -9,7 +9,7 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.packet.game.DamageWithPositionMessage import net.psforever.types.Vector3 -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse} import net.psforever.services.base.support.SupportActor import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader} @@ -72,11 +72,12 @@ trait DamageableWeaponTurret if (announceConfrontation) { if (aggravated) { val msg = SendResponse(DamageWithPositionMessage(damageToHealth, Vector3.Zero)) - obj.Seats.values + events ! BundledEnvelope(obj.Seats.values .collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name } - .foreach { channel => - events ! MessageEnvelope(channel, msg) + .map { channel => + MessageEnvelope(channel, msg) } + ) } else { //activity on map @@ -124,14 +125,12 @@ object DamageableWeaponTurret { val zone = target.Zone val zoneId = zone.id val avatarEvents = zone.AvatarEvents - target.Weapons.values - .filter { - _.Equipment.nonEmpty + avatarEvents ! BundledEnvelope(target.Weapons.values + .filter(_.Equipment.nonEmpty) + .map { slot => + MessageEnvelope(zoneId, ObjectDelete(slot.Equipment.get.GUID)) } - .foreach(slot => { - val wep = slot.Equipment.get - avatarEvents ! MessageEnvelope(zoneId, ObjectDelete(wep.GUID)) - }) + ) target match { case turret: WeaponTurret => if (turret.Upgrade != TurretUpgrade.None) { diff --git a/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala b/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala index 2e67095b5..56a18b455 100644 --- a/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/dome/ForceDomeControl.scala @@ -14,7 +14,7 @@ import net.psforever.objects.vital.interaction.DamageInteraction import net.psforever.objects.vital.prop.DamageWithPosition import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGeneratorState, Vector3} @@ -143,9 +143,9 @@ object ForceDomeControl { ChatMessageType.UNK_227, "Expected capitol force dome state change will resume." )) - building.PlayersInSOI.foreach { player => - events ! MessageEnvelope(player.Name, message) - } + events ! BundledEnvelope(building.PlayersInSOI.map { player => + MessageEnvelope(player.Name, message) + }) } /** diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala index 19579139c..5c716411f 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableWeaponTurret.scala @@ -5,7 +5,7 @@ import net.psforever.objects.Tool import net.psforever.objects.equipment.EquipmentSlot import net.psforever.objects.serverobject.turret.WeaponTurret import net.psforever.objects.vehicles.MountedWeapons -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.vehicle.VehicleAction /** @@ -41,14 +41,15 @@ object RepairableWeaponTurret { val zoneId = zone.id val tguid = target.GUID val events = zone.VehicleEvents - target.Weapons + events ! BundledEnvelope(target.Weapons .map({ case (index, slot: EquipmentSlot) => (index, slot.Equipment) }) .collect { case (index: Int, Some(tool: Tool)) => - events ! MessageEnvelope( + MessageEnvelope( zoneId, VehicleAction.EquipmentInSlot(tguid, index, tool) ) } + ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 8ba360041..9f6b2b0ff 100644 --- a/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -12,7 +12,7 @@ import net.psforever.objects.{GlobalDefinitions, Ntu, NtuContainer, NtuStorageBe import net.psforever.types.{ExperienceType, PlanetSideEmpire} import net.psforever.services.Service import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.util.Config @@ -203,12 +203,16 @@ class ResourceSiloControl(resourceSilo: ResourceSilo) (Config.app.game.experience.sep.ntuSiloDepositReward.toFloat * amount * resourceSilo.Definition.ChargeTime.toSeconds.toFloat / resourceSilo.MaxNtuCapacitor ).toLong - vehicle.Zone.AvatarEvents ! MessageEnvelope( - owner.name, - AvatarAction.AwardBep(owner.charId, deposit, ExperienceType.Normal) + vehicle.Zone.AvatarEvents ! BundledEnvelope( + MessageEnvelope( + owner.name, + AvatarAction.AwardBep(owner.charId, deposit, ExperienceType.Normal) + ), + MessageEnvelope( + owner.name, + AvatarAction.ShareAntExperienceWithSquad(owner, deposit, vehicle) + ) ) - vehicle.Zone.AvatarEvents ! MessageEnvelope( - owner.name, AvatarAction.ShareAntExperienceWithSquad(owner, deposit, vehicle)) zones.exp.ToDatabase.reportNtuActivity(owner.charId, resourceSilo.Zone.Number, resourceSilo.Owner.GUID.guid, deposit) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index 27500e6ec..cb46bd630 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -5,7 +5,7 @@ import net.psforever.objects.Player import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.sourcing.UniquePlayer import net.psforever.packet.game.GenericObjectActionMessage -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import net.psforever.types.{PlanetSideEmpire, Vector3} @@ -115,9 +115,9 @@ trait FacilityHackParticipation extends ParticipationLogic { GenericObjectActionMessage(mainTerm, 58) )) val events = building.Zone.AvatarEvents - list.foreach { p => - events ! MessageEnvelope(p.Name, pkts) - } + events ! BundledEnvelope(list.map { p => + MessageEnvelope(p.Name, pkts) + }) } } } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala index 47724f48c..a30211873 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/MajorFacilityHackParticipation.scala @@ -15,7 +15,7 @@ import net.psforever.objects.avatar.scoring.Kill import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.zones.exp.ToDatabase import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import scala.collection.mutable @@ -307,14 +307,15 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci events ! MessageEnvelope(hacker.Name, AvatarAction.AwardCep(hackerId, finalCep)) }*/ //bystanders (cep if squad leader, bep otherwise) - contributingPlayers + events ! BundledEnvelope(contributingPlayers //.filterNot { _.CharId == hackerId } - .foreach { player => + .map { player => val charId = player.CharId val contributionMultiplier = contributionPerPlayerByTime.getOrElse(charId, 1f) val outputValue = (finalCep * contributionMultiplier).toLong - events ! MessageEnvelope(player.Name, AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, outputValue)) + MessageEnvelope(player.Name, AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, outputValue)) } + ) //flag carrier (won't be in soi, but earns cep from capture) flagCarrier.collect { case player if !isResecured => @@ -440,8 +441,8 @@ object MajorFacilityHackParticipation { ): Unit = { val events = building.Zone.LocalEvents val message = SendResponse(msg) - targets.foreach { player => - events ! MessageEnvelope(player.Name, message) - } + events ! BundledEnvelope(targets.map { player => + MessageEnvelope(player.Name, message) + }) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala index 7c65c07bd..08d2453da 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/TowerHackParticipation.scala @@ -5,7 +5,7 @@ import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.zones.exp.ToDatabase import net.psforever.services.avatar.AvatarAction -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.util.Config @@ -154,18 +154,19 @@ final case class TowerHackParticipation(building: Building) extends FacilityHack expType = "cep" ) //bystanders (cep if squad leader, bep otherwise) - soiPlayers + events ! BundledEnvelope(soiPlayers .filterNot(_.CharId == hackerId) - .foreach { player => + .map { player => val charId = player.CharId val contributionTimeMultiplier = contributionPerPlayerByTime.getOrElse(charId, 0.5f) val contributionDistanceMultiplier = contributionPerPlayerByDistanceFromGoal.getOrElse(charId, 0.5f) val outputValue = (finalCep * contributionTimeMultiplier * contributionDistanceMultiplier).toLong - events ! MessageEnvelope( + MessageEnvelope( player.Name, AvatarAction.FacilityCaptureRewards(buildingId, zoneNumber, outputValue) ) } + ) } else { //no need to calculate a fancy score ToDatabase.reportFacilityCaptureInBulk( diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index a68ca6548..c34eb6425 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -6,7 +6,7 @@ import net.psforever.objects.serverobject.damage.Damageable import net.psforever.objects.sourcing.AmenitySource import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.HackState1 -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope} import org.log4s.Logger @@ -432,12 +432,12 @@ object ProximityTerminalControl { val events = unit.Zone.AvatarEvents val channel = target.Name ancient.foreach { case (weapon, slots) => - slots.foreach { slot => - events ! MessageEnvelope( + events ! BundledEnvelope(slots.map { slot => + MessageEnvelope( channel, SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) - } + }) } !result.flatMap { _._2 }.exists { slot => slot.Magazine < slot.MaxMagazine() } } @@ -457,14 +457,14 @@ object ProximityTerminalControl { ) val events = unit.Zone.VehicleEvents val channel = target.Actor.toString - result.foreach { case (weapon, slots) => - slots.foreach { slot => - events ! MessageEnvelope( + events ! BundledEnvelope(result.flatMap { case (weapon, slots) => + slots.map { slot => + MessageEnvelope( channel, SendResponse(InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity)) ) } - } + }) !result.flatMap { _._2 }.exists { slot => slot.Magazine < slot.MaxMagazine() } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala index fe4096b29..f35249851 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala @@ -16,7 +16,7 @@ import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.objects.{GlobalDefinitions, Player, SimpleItem} import net.psforever.packet.game.HackState1 -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SetEmpire import net.psforever.services.vehicle.VehicleAction import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} @@ -145,14 +145,14 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) val zone = mech.Zone val zoneId = zone.id val events = zone.VehicleEvents - mech.Seats.values.foreach(seat => + events ! BundledEnvelope(mech.Seats.values.flatMap(seat => seat.occupant.collect { case player => seat.unmount(player) player.VehicleSeated = None - events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) + MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2=false, guid)) } - ) + )) } def powerTurnOnCallback(): Unit = { @@ -225,9 +225,9 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) setToFaction: PlanetSideEmpire.Value ): Unit = { val events = zone.LocalEvents - opposingFactionsAre(setToFaction).foreach { faction => - events ! MessageEnvelope(faction.toString, SetEmpire(guid, faction)) - } + events ! BundledEnvelope(opposingFactionsAre(setToFaction).toSeq.map { faction => + MessageEnvelope(faction.toString, SetEmpire(guid, faction)) + }) } private def noAccessByOpposingFactions( @@ -236,9 +236,9 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) setToFaction: PlanetSideEmpire.Value ): Unit = { val events = zone.LocalEvents - opposingFactionsAre(setToFaction).foreach { faction => - events ! MessageEnvelope(faction.toString, SetEmpire(guid, setToFaction)) - } + events ! BundledEnvelope(opposingFactionsAre(setToFaction).toSeq.map { faction => + MessageEnvelope(faction.toString, SetEmpire(guid, setToFaction)) + }) } private def opposingFactionsAre(faction: PlanetSideEmpire.Value): PlanetSideEmpire.ValueSet = { @@ -273,13 +273,13 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) ): Unit = { val zoneId = zone.id val events = zone.LocalEvents - obj.Seats.values.foreach(seat => + events ! BundledEnvelope(obj.Seats.values.flatMap(seat => seat.occupant.collect { case player if test(player.Faction) => seat.unmount(player) player.VehicleSeated = None - events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, guid)) + MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, guid)) } - ) + )) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index 54425f7e6..eaf927db0 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -13,7 +13,7 @@ import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} import net.psforever.objects.vital.interaction.DamageResult import net.psforever.packet.game.{ChangeFireModeMessage, HackState1} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.VehicleAction @@ -336,15 +336,15 @@ class FacilityTurretControl(turret: FacilityTurret) val zone = turret.Zone val zoneId = zone.id val events = zone.VehicleEvents - turret.Seats.values.zipWithIndex.foreach { + events ! BundledEnvelope(turret.Seats.values.zipWithIndex.flatMap { case (seat, seat_num) => seat.occupant.collect { case player => seat.unmount(player) player.VehicleSeated = None - events ! MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, guid)) + MessageEnvelope(zoneId, player.GUID, VehicleAction.KickPassenger(seat_num, unk2=true, guid)) } - } + }) captureTerminalChanges(terminal, super.captureTerminalIsHacked, actionDelays = 3000L) } diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala index 89c661277..38fbfb7ca 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/VanuSentryControl.scala @@ -4,7 +4,7 @@ package net.psforever.objects.serverobject.turret import akka.actor.Cancellable import net.psforever.objects.serverobject.ServerObjectControl import net.psforever.objects.{Default, Player, Tool} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.local.LocalAction import net.psforever.types.Vector3 @@ -50,14 +50,14 @@ class VanuSentryControl(turret: FacilityTurret) if (weapon.Magazine < weapon.MaxMagazine && System.currentTimeMillis() - weapon.LastDischarge > 3000L) { weapon.Magazine += 1 val seat = TurretObject.Seat(0).get - seat.occupant.collect { + TurretObject.Zone.LocalEvents ! BundledEnvelope(seat.occupant.collect { case player: Player => - TurretObject.Zone.LocalEvents ! MessageEnvelope( + MessageEnvelope( TurretObject.Zone.id, player.GUID, LocalAction.RechargeVehicleWeapon(TurretObject.GUID, weapon.GUID) ) - } + }) } else if (weapon.Magazine == weapon.MaxMagazine && weaponAmmoRechargeTimer != Default.Cancellable) { weaponAmmoRechargeTimer.cancel() diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index a42ab78f2..742a8c67c 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -5,7 +5,7 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.ce.Deployable import net.psforever.objects.{Player, Tool, TurretDeployable} import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.{SendResponse, SetEmpire} import net.psforever.services.local.LocalAction import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader} @@ -100,18 +100,18 @@ object WeaponTurrets { val certs = hacker.avatar.certifications if (certs.contains(Certification.ExpertHacking) || certs.contains(Certification.ElectronicsExpert)) { // Forcefully dismount all seated occupants from the turret - target.Seats.values.foreach { seat => + zone.VehicleEvents ! BundledEnvelope(target.Seats.values.flatMap { seat => seat.occupant.collect { player: Player => seat.unmount(player) player.VehicleSeated = None - zone.VehicleEvents ! MessageEnvelope( + MessageEnvelope( zone.id, player.GUID, VehicleAction.KickPassenger(4, unk2 = false, target.GUID) ) } - } + }) //hacker owns the deployable now target.OwnerGuid = None target.Actor ! Deployable.Ownership(hacker) diff --git a/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala b/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala index 5d4efe87d..eb4b69958 100644 --- a/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala +++ b/src/main/scala/net/psforever/objects/zones/ZoneHotSpotProjector.scala @@ -5,7 +5,7 @@ import akka.actor.{Actor, ActorRef, Cancellable, Props} import net.psforever.objects.Default import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.services.ServiceManager -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.galaxy.GalaxyAction import scala.collection.mutable.ListBuffer @@ -305,12 +305,14 @@ class ZoneHotSpotProjector(zone: Zone, hotspots: ListBuffer[HotSpotInfo], blanki def UpdateHotSpots(affectedFactions: Iterable[PlanetSideEmpire.Value], hotSpotInfos: Iterable[HotSpotInfo]): Unit = { val zoneNumber = zone.Number val hotSpotInfoList = hotSpotInfos.toList - affectedFactions.foreach(faction => - galaxy ! MessageEnvelope(faction.toString, GalaxyAction.HotSpotUpdate( + galaxy ! BundledEnvelope( + affectedFactions.map(faction => + MessageEnvelope(faction.toString, GalaxyAction.HotSpotUpdate( zoneNumber, 1, ZoneHotSpotProjector.SpecificHotSpotInfo(faction, hotSpotInfoList) )) + ) ) } } diff --git a/src/main/scala/net/psforever/services/CavernRotationService.scala b/src/main/scala/net/psforever/services/CavernRotationService.scala index 4b33229d1..ef3c83d3b 100644 --- a/src/main/scala/net/psforever/services/CavernRotationService.scala +++ b/src/main/scala/net/psforever/services/CavernRotationService.scala @@ -12,7 +12,7 @@ import net.psforever.objects.Default import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.Zone import net.psforever.packet.game.ChatMsg -import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope} +import net.psforever.services.base.envelope.{BundledEnvelope, GenericResponseEnvelope, MessageEnvelope} import net.psforever.services.base.message.SendResponse import net.psforever.services.galaxy.{GalaxyAction, GalaxyStamp} import net.psforever.types.ChatMessageType @@ -576,16 +576,18 @@ class CavernRotationService( def sendCavernRotationUpdatesToAll(galaxyService: ActorRef): Unit = { val curr = System.currentTimeMillis() val (lockedZones, unlockedZones) = managedZones.partition(_.locked) - unlockedZones.foreach { z => - galaxyService ! MessageEnvelope("", GalaxyAction.UnlockedZoneUpdate(z.zone)) - } val sortedLocked = lockedZones.sortBy(z => z.start) - sortedLocked.take(2).foreach { z => - galaxyService ! MessageEnvelope("", GalaxyAction.LockedZoneUpdate(z.zone, z.start + z.duration - curr)) - } - sortedLocked.takeRight(2).foreach { z => - galaxyService ! MessageEnvelope("", GalaxyAction.LockedZoneUpdate(z.zone, 0L)) - } + galaxyService ! BundledEnvelope( + unlockedZones.map { z => + MessageEnvelope("", GalaxyAction.UnlockedZoneUpdate(z.zone)) + } ++ + sortedLocked.take(2).map { z => + MessageEnvelope("", GalaxyAction.LockedZoneUpdate(z.zone, z.start + z.duration - curr)) + } ++ + sortedLocked.takeRight(2).map { z => + MessageEnvelope("", GalaxyAction.LockedZoneUpdate(z.zone, 0L)) + } + ) } /** diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index 61c27ec6f..dc579b915 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -18,7 +18,7 @@ import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.services.base.message.PlanetsideAttribute import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction import net.psforever.services.local.LocalAction -import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID} +import net.psforever.types.{ChatMessageType, PlanetSideEmpire} import java.util.concurrent.{Executors, TimeUnit} import scala.collection.Seq @@ -247,7 +247,6 @@ class HackCaptureActor extends Actor { // Notify all clients that CC has had its hack state changed terminal.Zone.LocalEvents ! MessageEnvelope( terminal.Zone.id, - PlanetSideGUID(-1), /*what is this?, says the person who wrote it*/ PlanetsideAttribute( terminal.GUID, PlanetsideAttributeEnum.ControlConsoleHackUpdate.id, diff --git a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala index df81cb0ff..ae2ce9d51 100644 --- a/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala +++ b/src/main/scala/net/psforever/services/vehicle/support/TurretUpgrader.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.zones.Zone import net.psforever.services.base.{EventServiceSupport, GenericSupportEnvelopeOnly} -import net.psforever.services.base.envelope.MessageEnvelope +import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope} import net.psforever.types.PlanetSideGUID import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import net.psforever.services.vehicle.VehicleAction @@ -245,15 +245,16 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { trace(s"Wall turret finished ${target.Upgrade} upgrade") val targetGUID = target.GUID if (target.Health > 0) { - target.Weapons + context.parent ! BundledEnvelope(target.Weapons .map { case (index: Int, slot: EquipmentSlot) => (index, slot.Equipment) } .collect { case (index, Some(tool: Tool)) => - context.parent ! MessageEnvelope( + MessageEnvelope( zone.id, VehicleAction.EquipmentInSlot(targetGUID, index, tool) ) } + ) } Finalize(target, entry.upgrade) } From 3937bb845542a797975cab7c2a9bfcaed99fdae9 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 15 Jun 2026 16:39:35 -0400 Subject: [PATCH 31/32] 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 --- .../actors/session/SessionActor.scala | 30 ++++-- .../session/csr/AvatarHandlerLogic.scala | 60 +++++++----- .../session/normal/AvatarHandlerLogic.scala | 54 ++++++----- .../session/normal/GalaxyHandlerLogic.scala | 3 +- .../session/normal/LocalHandlerLogic.scala | 26 ++++-- .../session/normal/VehicleHandlerLogic.scala | 58 +++++++----- .../spectator/AvatarHandlerLogic.scala | 57 +++++++----- .../spectator/VehicleHandlerLogic.scala | 43 +++++---- .../support/CommonHandlerFunctions.scala | 93 ++++++------------- .../session/support/CommonHandlerLogic.scala | 20 ++-- .../actors/session/support/SessionData.scala | 1 - 11 files changed, 242 insertions(+), 203 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 8138c56e9..45f07762d 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, CommonHandlerFunctionsBase, CommonHandlerLogic, ZoningOperations} +import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerLogic, ZoningOperations} import net.psforever.objects.TurretDeployable import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.containable.Containable @@ -95,6 +95,17 @@ object SessionActor { private final case object PokeClient 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) @@ -392,30 +403,31 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con case 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( - responseHandler: CommonHandlerFunctionsBase, + responseHandler: CommonHandlerFunctions, envelope: GenericResponseEnvelope ): Unit = { val GenericResponseEnvelope(toChannel, guid, reply) = envelope //try the expected handler with the input response if (!responseHandler.handle(toChannel, guid, reply)) { - //find any handler that might receive the response (ignore guard booleans during search) - data.handlerFilter.set(guid, guid, notSame = true, same = true) + //test the expected handler again, ignoring guard booleans; if it would have been handled, stop with this + responseHandler.IgnoreFilter = true 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 => log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") case first :: Nil => first.handle(toChannel, guid, reply) case first :: others => - if (!first.handle(toChannel, guid, reply)) { - others.find(_.tryToHandle(reply)) - } + first.handle(toChannel, guid, reply) || others.exists(_.handle(toChannel, guid, reply)) } } + responseHandler.IgnoreFilter = false } } 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 1932dae01..544d26306 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -45,7 +45,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A def receive: Receive = { /* special messages */ - case AvatarAction.TeardownConnection if player.spectator => + case AvatarAction.TeardownConnection + if TestFilter(_ => { player.spectator }) => context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection)) @@ -67,7 +68,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if isNotSameTarget => + ) if TestFilter(_ => isNotSameTarget) => val pstateToSave = pstate.copy(timestamp = 0) 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) @@ -155,7 +156,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } 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)) //second wind does not normally load its icon into the shortcut hotbar avatar @@ -167,7 +168,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } 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)) //second wind does not normally unload its icon from the shortcut hotbar val shortcut = { @@ -186,7 +187,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && player.VisibleSlots.contains(slot) => + if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) => sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { @@ -197,31 +198,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && slot > -1 => + if TestFilter(_ => {isSameTarget && slot > -1 }) => sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if isSameTarget => () + if TestFilter(_ => isSameTarget) => () case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) 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)) 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(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)) val entry = ops.lastSeenStreamMessage(filterGuid.guid) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) 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)) 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)) sessionLogic.terminals.lastTerminalOrderFulfillment = true AvatarActor.savePlayerData(player) @@ -254,7 +257,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if resolvedGuid == target => + ) if TestFilter(_ => {resolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -336,7 +339,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if resolvedGuid == target => + ) if TestFilter(_ => { resolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -398,7 +401,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ 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)) case AvatarAction.Killed(_, mount) => @@ -438,11 +441,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //render CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) - case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) + if TestFilter(_ => isNotSameTarget) => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if resolvedGuid == revivalTargetGuid => + if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) => ops.revive() player.Actor ! Player.Revive player.History @@ -457,18 +461,20 @@ 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 => + if TestFilter(_ => 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 TestFilter(_ => isNotSameTarget) => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcess() - case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) /* 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)) } )) - case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) + if TestFilter(_ => isNotSameTarget) => 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)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -504,10 +512,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarAction.PutDownFDU(target) if isNotSameTarget => + case AvatarAction.PutDownFDU(target) + if TestFilter(_ => isNotSameTarget) => 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 sendResponse( ObjectCreateDetailedMessage( @@ -519,7 +529,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) 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 { case tool: Tool if tool.Magazine == 0 => 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 43b21255f..0f41e7239 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -66,7 +66,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if isNotSameTarget => + ) if TestFilter(_ => isNotSameTarget) => val pstateToSave = pstate.copy(timestamp = 0) 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) @@ -154,7 +154,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } 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)) //second wind does not normally load its icon into the shortcut hotbar avatar @@ -166,7 +166,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } 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)) //second wind does not normally unload its icon from the shortcut hotbar val shortcut = { @@ -185,7 +185,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && player.VisibleSlots.contains(slot) => + if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) => sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { @@ -196,31 +196,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && slot > -1 => + if TestFilter(_ => { isSameTarget && slot > -1 }) => sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if isSameTarget => () + if TestFilter(_ => isSameTarget) => () case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) 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)) 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(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)) val entry = ops.lastSeenStreamMessage(filterGuid.guid) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => @@ -260,7 +262,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if resolvedGuid == target => + ) if TestFilter(_ => { resolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -360,7 +362,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if resolvedGuid == target => + ) if TestFilter(_ => { resolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -451,7 +453,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 TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(cause, mount) => @@ -544,11 +546,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) } - case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) + if TestFilter(_ => isNotSameTarget) => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if resolvedGuid == revivalTargetGuid => + if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) => log.info(s"No time for rest, ${player.Name}. Back on your feet!") ops.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) */ 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) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) case AvatarAction.ChangeFireMode(itemGuid, mode) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") - case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) /* 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)) } )) - case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) + if TestFilter(_ => isNotSameTarget) => 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)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -612,10 +618,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarAction.PutDownFDU(target) if isNotSameTarget => + case AvatarAction.PutDownFDU(target) + if TestFilter(_ => isNotSameTarget) => 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 sendResponse( ObjectCreateDetailedMessage( @@ -627,7 +635,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) 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 { case tool: Tool if tool.Magazine == 0 => sendResponse(WeaponDryFireMessage(weaponGuid)) diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index 1797959c5..b47dbf20d 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -82,7 +82,8 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A val popVS = pop.count(_.Faction == PlanetSideEmpire.VS) 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) } } 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 3a8258687..fb15bf50a 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -49,7 +49,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(msg) } - case LocalAction.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget => + case LocalAction.DeployableMapIcon(behavior, deployInfo) + if TestFilter(_ => isNotSameTarget) => sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) case LocalAction.DeployableUIFor(item) => @@ -68,7 +69,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act case LocalAction.Detonate(_, obj) => 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 pos = player.Position.xy 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 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)) 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, _, _) - if obj.Destroyed || obj.Jammed || obj.Health == 0 => + if TestFilter(_ => { obj.Destroyed || obj.Jammed || obj.Health == 0 }) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => obj.Destroyed = true 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 obj.Active = false ops.deactivateTelpadDeployableMessages(dguid) //standard deployable elimination behavior 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 obj.Active = false ops.deactivateTelpadDeployableMessages(dguid) @@ -122,7 +127,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act obj.Destroyed = true 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 sendResponse(ObjectDeleteMessage(dguid, unk1=0)) @@ -131,7 +137,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act obj.Destroyed = true 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)) 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) => sendResponse(GenericObjectActionMessage(buildingGuid, 12)) - case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if isSameTarget => + case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) + if TestFilter(_ => 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 55c46f01a..4771d2c42 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -46,7 +46,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => + ) if TestFilter(_ => { isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) => //player who is also in the vehicle (not driver) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) player.Position = pos @@ -74,30 +74,36 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if isNotSameTarget => + ) if TestFilter(_ => isNotSameTarget) => //player who is watching the vehicle from the outside 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)) 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)) - case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) + if TestFilter(_ => isNotSameTarget) => 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)) - 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)) - case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => + case VehicleAction.EquipmentCreatedInSlot(pkt) + if TestFilter(_ => isNotSameTarget) => 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? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -108,7 +114,8 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: 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 //but always seems to return 4 if user is kicked by mount permissions changing 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 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)) - 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) sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) 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 avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) sendResponse(PlanetsideAttributeMessage(resolvedGuid, attribute_type=21, vehicleGuid)) @@ -143,10 +153,12 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.LoseOwnership(_, vehicleGuid) => 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)) - 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? 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")) } - 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? 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.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.interstellarFerryTopLevelGUID = Some(vehicleToDelete) 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") 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 reverseSpeed = if (strafe > 1) { 0 } else { speed } //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) 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) 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 continent.GUID(target).collect { case vehicle: Vehicle => import net.psforever.login.WorldSession.boolToInt @@ -235,7 +249,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: } 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 continent.GUID(target).collect { case vehicle: Vehicle => //external participant: observe changes to equipment @@ -273,7 +287,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(GenericObjectActionMessage(playerGuid, code=10)) case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) - if player.VisibleSlots.contains(player.DrawnSlot) => + if TestFilter(_ => { player.VisibleSlots.contains(player.DrawnSlot) }) => player.DrawnSlot = Player.HandsDownSlot startPlayerSeatedInVehicle(vehicle) 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 f5db7b804..369fa3cc0 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -61,7 +61,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if isNotSameTarget => + ) if TestFilter(_ => isNotSameTarget) => val pstateToSave = pstate.copy(timestamp = 0) 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) @@ -149,7 +149,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && player.VisibleSlots.contains(slot) => + if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) => sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { @@ -160,31 +160,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if isSameTarget && slot > -1 => + if TestFilter(_ => { isSameTarget && slot > -1 }) => sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if isSameTarget => () + if TestFilter(_ => isSameTarget) => () case AvatarAction.ObjectHeld(_, previousSlot) => sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) 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)) 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(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)) val entry = ops.lastSeenStreamMessage(filterGuid.guid) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) - case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedPlayer(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) - case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => + case AvatarAction.EquipmentCreatedInHand(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) 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)) 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)) sessionLogic.terminals.lastTerminalOrderFulfillment = true AvatarActor.savePlayerData(player) @@ -217,7 +219,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if resolvedGuid == target => + ) if TestFilter(_ => { resolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -295,7 +297,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if resolvedGuid == target => + ) if TestFilter(_ => { resolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor)) //happening to this player @@ -351,7 +353,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.general.kitToBeUsed = None 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( PlayerSource(player), Players.produceContributionTranscriptFromKill(continent, player, kda), @@ -386,7 +389,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ 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)) case AvatarAction.Killed(_, mount) => @@ -440,10 +443,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) } - case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => + case AvatarAction.ReleasePlayer(tplayer) + if TestFilter(_ => isNotSameTarget) => 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!") sessionLogic.zoning.spawn.reviveTimer.cancel() 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) */ 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) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) + if TestFilter(_ => isNotSameTarget) => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => //TODO damage marker? sessionLogic.zoning.CancelZoningProcess() - case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => + case AvatarAction.DropCreatedItem(pkt) + if TestFilter(_ => isNotSameTarget) => sendResponse(pkt) /* 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)) } )) - case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => + case AvatarAction.LoadCreatedProjectile(pkt) + if TestFilter(_ => isNotSameTarget) => 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)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -505,10 +514,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ProjectileAutoLockAwareness(mode) => sendResponse(GenericActionMessage(mode)) - case AvatarAction.PutDownFDU(target) if isNotSameTarget => + case AvatarAction.PutDownFDU(target) + if TestFilter(_ => isNotSameTarget) => 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 sendResponse( ObjectCreateDetailedMessage( @@ -520,7 +531,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) 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 { case tool: Tool if tool.Magazine == 0 => 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 21ca3d946..10e56ec0a 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -39,7 +39,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => + ) if TestFilter(_ => { isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) => //player who is also in the vehicle (not driver) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) player.Position = pos @@ -59,30 +59,36 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if isNotSameTarget => + ) if TestFilter(_ => isNotSameTarget) => //player who is watching the vehicle from the outside 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)) 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)) - case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => + case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) + if TestFilter(_ => isNotSameTarget) => 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)) - 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)) - case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => + case VehicleAction.EquipmentCreatedInSlot(pkt) + if TestFilter(_ => isNotSameTarget) => 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? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -93,7 +99,8 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: 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 //but always seems to return 4 if user is kicked by mount permissions changing 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 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)) - 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) sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) 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)) case VehicleAction.UnloadVehicle(_, vehicleGuid) => 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? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) @@ -131,7 +142,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() 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 reverseSpeed = if (strafe > 1) { 0 } else { speed } //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) 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) case VehicleSpawnPad.AttachToRails(vehicle, pad) => 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 6b330edc8..aca6ba6d8 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -2,60 +2,45 @@ package net.psforever.actors.session.support 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.types.PlanetSideGUID -trait HandlerFilter { - def resolvedPlayerGuid: PlanetSideGUID - def otherPlayerGuid: PlanetSideGUID - def isNotSameTarget: Boolean - def isSameTarget: Boolean +trait CommonHandlerFunctions { + _: CommonSessionInterfacingFunctionality => + protected var resolvedGuid: PlanetSideGUID = Default.GUID0 + protected var filterGuid: PlanetSideGUID = Default.GUID0 + protected var isNotSameTarget: Boolean = false + protected var isSameTarget: Boolean = false - def set(filter: HandlerFilter): HandlerFilter = { - set(filter.resolvedPlayerGuid, filter.otherPlayerGuid, filter.isNotSameTarget, filter.isSameTarget) + private var ignoreFilter: Boolean = false + + 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 * @param toChannel na * @param guid 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 @@ -66,28 +51,8 @@ trait CommonHandlerFunctionsBase { receive.applyOrElse(x, (_: Any) => { passed = false }) passed } -} -trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { - _: CommonSessionInterfacingFunctionality => - 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 TestFilter(filter: Unit => Boolean): Boolean = { + ignoreFilter || filter() } - - def receive: Receive } 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 9eff6b114..d3b19b26c 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala @@ -12,48 +12,48 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac def receive: Receive = { case PlanetsideAttribute(target_guid, attributeType, attributeValue) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) case GenericObjectAction(objectGuid, actionCode) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) case ObjectDelete(itemGuid, unk) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(ObjectDeleteMessage(itemGuid, unk)) case ChangeFireState_Start(weaponGuid) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) case ReloadTool(itemGuid) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) 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) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) case WeaponDryFire(weaponGuid) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => sendResponse(WeaponDryFireMessage(weaponGuid)) } case HintsAtAttacker(sourceGuid) - if player.isAlive => + if TestFilter(_ => { player.isAlive }) => sendResponse(HitHint(sourceGuid, filterGuid)) sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") case SetEmpire(objectGuid, faction) - if isNotSameTarget => + if TestFilter(_ => isNotSameTarget) => sendResponse(SetEmpireMessage(objectGuid, faction)) case ConcealPlayer(_) => 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 2f193d205..0d43257a8 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -119,7 +119,6 @@ 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") From 4afe8550c094074e3f6883d93bf43a363ce62563 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Tue, 23 Jun 2026 12:03:17 -0400 Subject: [PATCH 32/32] modified cached guard tests; adjusted list mechanics for SendResponse contents --- .../actors/session/SessionActor.scala | 20 +++- .../session/csr/AvatarHandlerLogic.scala | 106 +++++++++--------- .../session/normal/AvatarHandlerLogic.scala | 96 ++++++++-------- .../session/normal/GalaxyHandlerLogic.scala | 2 +- .../session/normal/LocalHandlerLogic.scala | 23 ++-- .../session/normal/VehicleHandlerLogic.scala | 56 ++++----- .../spectator/AvatarHandlerLogic.scala | 78 ++++++------- .../spectator/VehicleHandlerLogic.scala | 42 +++---- .../support/CommonHandlerFunctions.scala | 94 +++++++++++----- .../session/support/CommonHandlerLogic.scala | 24 ++-- .../actors/session/support/SessionData.scala | 2 + .../support/SessionMountHandlers.scala | 4 +- .../support/SessionOutfitHandlers.scala | 20 ++-- .../session/support/ZoningOperations.scala | 2 +- .../zone/building/MajorFacilityLogic.scala | 8 +- .../damage/DamageableAmenity.scala | 2 +- .../hackable/GenericHackables.scala | 2 +- .../repair/RepairableAmenity.scala | 2 +- .../FacilityHackParticipation.scala | 4 +- .../serverobject/turret/TurretControl.scala | 4 +- .../control/AntTransferBehavior.scala | 2 +- .../envelope/GenericMessageEnvelope.scala | 4 +- .../envelope/GenericResponseEnvelope.scala | 2 +- .../base/envelope/MessageEnvelope.scala | 11 +- .../services/base/message/SendResponse.scala | 2 + 25 files changed, 333 insertions(+), 279 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 45f07762d..29bee0368 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -96,6 +96,15 @@ object SessionActor { final case class SetMode(mode: PlayerMode) extends Command + /** + * Determine if a response handler would process a given reply message, ignoring its guards. + * Treat handlers already ignoring their guards as "determined (will not pass)". + * @see `CommonHandlerFunctions.IgnoreFilter_=` + * @param reply message + * @param handler message handler + * @return `true`, if the response handler will process the response; + * `false`, if the handler is skipped or if it would not process + */ private def HandlerAcceptingMessageTest(reply: Any)(handler: CommonHandlerFunctions): Boolean = { if (handler.IgnoreFilter) { false @@ -417,14 +426,15 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con responseHandler.IgnoreFilter = true if (!responseHandler.isDefinedAt(reply)) { //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 { + //try each discovered handler against the input response until one works + val test: CommonHandlerFunctions => Boolean = SessionActor.HandlerAcceptingMessageTest(reply) + listOfHandlers.filter(test) match { case Nil => - log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") + log.error(s"received completely unhandled response message - $reply for ${envelope.stamp}:$toChannel") case first :: Nil => - first.handle(toChannel, guid, reply) + first.tryToHandle(reply) case first :: others => - first.handle(toChannel, guid, reply) || others.exists(_.handle(toChannel, guid, reply)) + first.tryToHandle(reply) || others.exists(_.tryToHandle(reply)) } } responseHandler.IgnoreFilter = false 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 544d26306..f1750d6c8 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -46,13 +46,13 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A def receive: Receive = { /* special messages */ case AvatarAction.TeardownConnection - if TestFilter(_ => { player.spectator }) => + if TestFilter(() => { player.spectator }) => context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) - context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection)) + context.self.forward(GenericResponseEnvelope(AvatarStamp, "", FilterGuid, AvatarAction.TeardownConnection)) case AvatarAction.TeardownConnection => context.self ! SessionActor.SetMode(NormalMode) - context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection)) + context.self.forward(GenericResponseEnvelope(AvatarStamp, "", FilterGuid, AvatarAction.TeardownConnection)) /* really common messages (very frequently, every life) */ case pstate @ AvatarAction.PlayerState( @@ -68,9 +68,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if TestFilter(_ => isNotSameTarget) => + ) if TestFilter(NotSameTargetTest) => 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 _ => (None, 0L, Vector3.Zero, false, None) } @@ -113,7 +113,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //must draw sendResponse( PlayerStateMessage( - filterGuid, + FilterGuid, pos, vel, yaw, @@ -126,10 +126,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(filterGuid.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(filterGuid.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 @@ -138,7 +138,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat sendResponse( PlayerStateMessage( - filterGuid, + FilterGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -148,28 +148,28 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(filterGuid.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(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(FilterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) - if TestFilter(_ => { value == ImplantType.SecondWind.value }) => - sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Add, implant_slot, 7)) + if TestFilter(() => { value == ImplantType.SecondWind.value }) => + sendResponse(AvatarImplantMessage(ResolvedGuid, ImplantAction.Add, implant_slot, 7)) //second wind does not normally load its icon into the shortcut hotbar avatar .shortcuts .zipWithIndex .find { case (s, _) => s.isEmpty} .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) + sendResponse(CreateShortcutMessage(ResolvedGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) - if TestFilter(_ => { value == ImplantType.SecondWind.value }) => - sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Remove, implant_slot, value)) + if TestFilter(() => { value == ImplantType.SecondWind.value }) => + sendResponse(AvatarImplantMessage(ResolvedGuid, ImplantAction.Remove, implant_slot, value)) //second wind does not normally unload its icon from the shortcut hotbar val shortcut = { val imp = ImplantType.SecondWind.shortcut @@ -180,15 +180,15 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A .zipWithIndex .find { case (s, _) => s.contains(shortcut) } .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, None)) + sendResponse(CreateShortcutMessage(ResolvedGuid, index + 1, None)) } case AvatarAction.AvatarImplant(action, implant_slot, value) => - sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) + sendResponse(AvatarImplantMessage(ResolvedGuid, action, implant_slot, value)) case AvatarAction.ObjectHeld(slot, _) - if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) => - sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) + if TestFilter(() => { SameTarget && player.VisibleSlots.contains(slot) }) => + 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) @@ -198,33 +198,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if TestFilter(_ => {isSameTarget && slot > -1 }) => - sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) + if TestFilter(() => {SameTarget && slot > -1 }) => + sendResponse(ObjectHeldMessage(FilterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if TestFilter(_ => isSameTarget) => () + if TestFilter(SameTargetTest) => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(FilterGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filterGuid.guid) - ops.lastSeenStreamMessage.put(filterGuid.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 TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filterGuid.guid) - ops.lastSeenStreamMessage.put(filterGuid.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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.EquipmentCreatedInHand(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.Destroy(victim, killer, weapon, pos) => @@ -235,7 +235,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) case AvatarAction.TerminalOrderResult(terminalGuid, action, result) - if TestFilter(_ => { result && (action == TransactionType.Buy || action == TransactionType.Loadout) }) => + if TestFilter(() => { result && (action == TransactionType.Buy || action == TransactionType.Loadout) }) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true AvatarActor.savePlayerData(player) @@ -257,7 +257,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if TestFilter(_ => {resolvedGuid == target }) => + ) if TestFilter(() => {ResolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -339,7 +339,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if TestFilter(_ => { resolvedGuid == target }) => + ) if TestFilter(() => { ResolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -376,9 +376,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( - resolvedGuid, + ResolvedGuid, kguid, - resolvedGuid, + ResolvedGuid, unk2 = 4294967295L, unk3 = false, unk4 = Vector3.Zero, @@ -401,7 +401,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(_, mount) => @@ -412,23 +412,23 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.zoningStatus = Zoning.Status.None continent.GUID(mount).collect { case obj: Vehicle if obj.Destroyed => - ops.killedWhileMounted(obj, resolvedGuid) + ops.killedWhileMounted(obj, ResolvedGuid) sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) sessionLogic.general.unaccessContainer(obj) case obj: Vehicle => - ops.killedWhileMounted(obj, resolvedGuid) + ops.killedWhileMounted(obj, ResolvedGuid) sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) case obj: PlanetSideGameObject with Mountable with Container if obj.Destroyed => - ops.killedWhileMounted(obj, resolvedGuid) + ops.killedWhileMounted(obj, ResolvedGuid) sessionLogic.general.unaccessContainer(obj) case obj: PlanetSideGameObject with Mountable with Container => - ops.killedWhileMounted(obj, resolvedGuid) + ops.killedWhileMounted(obj, ResolvedGuid) case obj: PlanetSideGameObject with Mountable => - ops.killedWhileMounted(obj, resolvedGuid) + ops.killedWhileMounted(obj, ResolvedGuid) } //player state changes sessionLogic.general.dropSpecialSlotItem() @@ -442,11 +442,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) case AvatarAction.ReleasePlayer(tplayer) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) => + if TestFilter(() => { ResolvedGuid == revivalTargetGuid }) => ops.revive() player.Actor ! Player.Revive player.History @@ -461,12 +461,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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => 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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => @@ -474,7 +474,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.CancelZoningProcess() case AvatarAction.DropCreatedItem(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) /* rare messages */ @@ -488,11 +488,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A )) case AvatarAction.LoadCreatedProjectile(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -513,11 +513,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(GenericActionMessage(mode)) case AvatarAction.PutDownFDU(target) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(GenericObjectActionMessage(target, code=53)) case AvatarAction.StowEquipment(target, slot, item) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -529,7 +529,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => 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 0f41e7239..4c5a324a1 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -66,9 +66,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if TestFilter(_ => isNotSameTarget) => + ) if TestFilter(NotSameTargetTest) => 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 _ => (None, 0L, Vector3.Zero, false, None) } @@ -111,7 +111,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //must draw sendResponse( PlayerStateMessage( - filterGuid, + FilterGuid, pos, vel, yaw, @@ -124,10 +124,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(filterGuid.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(filterGuid.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( - filterGuid, + FilterGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -146,28 +146,28 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(filterGuid.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(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(FilterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) - if TestFilter(_ => { value == ImplantType.SecondWind.value }) => - sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Add, implant_slot, 7)) + if TestFilter(() => { value == ImplantType.SecondWind.value }) => + sendResponse(AvatarImplantMessage(ResolvedGuid, ImplantAction.Add, implant_slot, 7)) //second wind does not normally load its icon into the shortcut hotbar avatar .shortcuts .zipWithIndex .find { case (s, _) => s.isEmpty} .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) + sendResponse(CreateShortcutMessage(ResolvedGuid, index + 1, Some(ImplantType.SecondWind.shortcut))) } case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) - if TestFilter(_ => { value == ImplantType.SecondWind.value }) => - sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Remove, implant_slot, value)) + if TestFilter(() => { value == ImplantType.SecondWind.value }) => + sendResponse(AvatarImplantMessage(ResolvedGuid, ImplantAction.Remove, implant_slot, value)) //second wind does not normally unload its icon from the shortcut hotbar val shortcut = { val imp = ImplantType.SecondWind.shortcut @@ -178,15 +178,15 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A .zipWithIndex .find { case (s, _) => s.contains(shortcut) } .foreach { case (_, index) => - sendResponse(CreateShortcutMessage(resolvedGuid, index + 1, None)) + sendResponse(CreateShortcutMessage(ResolvedGuid, index + 1, None)) } case AvatarAction.AvatarImplant(action, implant_slot, value) => - sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) + sendResponse(AvatarImplantMessage(ResolvedGuid, action, implant_slot, value)) case AvatarAction.ObjectHeld(slot, _) - if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) => - sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) + if TestFilter(() => { SameTarget && player.VisibleSlots.contains(slot) }) => + 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) @@ -196,37 +196,37 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if TestFilter(_ => { isSameTarget && slot > -1 }) => - sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) + if TestFilter(() => { SameTarget && slot > -1 }) => + sendResponse(ObjectHeldMessage(FilterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if TestFilter(_ => isSameTarget) => () + if TestFilter(SameTargetTest) => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(FilterGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filterGuid.guid) - ops.lastSeenStreamMessage.put(filterGuid.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 TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filterGuid.guid) - ops.lastSeenStreamMessage.put(filterGuid.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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.EquipmentCreatedInHand(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => - sendResponse(PlanetsideStringAttributeMessage(filterGuid, attributeType, attributeValue)) + sendResponse(PlanetsideStringAttributeMessage(FilterGuid, attributeType, attributeValue)) case AvatarAction.Destroy(victim, killer, weapon, pos) => // guid = victim // killer = killer @@ -262,7 +262,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if TestFilter(_ => { resolvedGuid == target }) => + ) if TestFilter(() => { ResolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -362,7 +362,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if TestFilter(_ => { resolvedGuid == target }) => + ) if TestFilter(() => { ResolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -402,9 +402,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( - resolvedGuid, + ResolvedGuid, kguid, - resolvedGuid, + ResolvedGuid, unk2 = 4294967295L, unk3 = false, unk4 = Vector3.Zero, @@ -453,7 +453,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(cause, mount) => @@ -519,16 +519,16 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.spawn.deadState = DeadState.Dead continent.GUID(mount).collect { case obj: Vehicle => - killedWhileMounted(obj, resolvedGuid) + killedWhileMounted(obj, ResolvedGuid) sessionLogic.vehicles.ConditionalDriverVehicleControl(obj) sessionLogic.general.unaccessContainer(obj) case obj: PlanetSideGameObject with Mountable with Container => - killedWhileMounted(obj, resolvedGuid) + killedWhileMounted(obj, ResolvedGuid) sessionLogic.general.unaccessContainer(obj) case obj: PlanetSideGameObject with Mountable => - killedWhileMounted(obj, resolvedGuid) + killedWhileMounted(obj, ResolvedGuid) } sessionLogic.actionsToCancel() sessionLogic.terminals.CancelAllProximityUnits() @@ -547,11 +547,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ReleasePlayer(tplayer) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) => + if TestFilter(() => { ResolvedGuid == revivalTargetGuid }) => log.info(s"No time for rest, ${player.Name}. Back on your feet!") ops.revive() player.Actor ! Player.Revive @@ -567,12 +567,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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => 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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => @@ -580,7 +580,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") case AvatarAction.DropCreatedItem(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) /* rare messages */ @@ -594,11 +594,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A )) case AvatarAction.LoadCreatedProjectile(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -619,11 +619,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(GenericActionMessage(mode)) case AvatarAction.PutDownFDU(target) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(GenericObjectActionMessage(target, code=53)) case AvatarAction.StowEquipment(target, slot, item) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -635,7 +635,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => sendResponse(WeaponDryFireMessage(weaponGuid)) diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala index b47dbf20d..5bc18cbf9 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala @@ -83,7 +83,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO)) case GalaxyAction.LogStatusChange(name) - if TestFilter(_ => avatar.people.friend.exists(_.name.equals(name))) => + if TestFilter(() => avatar.people.friend.exists(_.name.equals(name))) => avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name) } } 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 fb15bf50a..003a60b08 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -50,7 +50,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act } case LocalAction.DeployableMapIcon(behavior, deployInfo) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) case LocalAction.DeployableUIFor(item) => @@ -70,7 +70,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly") case LocalAction.DoorOpens(_, door) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => val doorGuid = door.GUID val pos = player.Position.xy val range = ops.doorLoadRange() @@ -89,7 +89,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(GenericObjectStateMsg(doorGuid, state=17)) case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _) - if TestFilter(_ => obj.Destroyed) => + if TestFilter(() => obj.Destroyed) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) => @@ -103,7 +103,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act ) case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _) - if TestFilter(_ => { obj.Destroyed || obj.Jammed || obj.Health == 0 }) => + if TestFilter(() => { obj.Destroyed || obj.Jammed || obj.Health == 0 }) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => @@ -111,7 +111,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) - if TestFilter(_ => { obj.Active && obj.Destroyed }) => + if TestFilter(() => { obj.Active && obj.Destroyed }) => //if active, deactivate obj.Active = false ops.deactivateTelpadDeployableMessages(dguid) @@ -119,7 +119,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(ObjectDeleteMessage(dguid, unk1=0)) case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) - if TestFilter(_ => obj.Active) => + if TestFilter(() => obj.Active) => //if active, deactivate obj.Active = false ops.deactivateTelpadDeployableMessages(dguid) @@ -128,7 +128,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) - if TestFilter(_ => obj.Destroyed) => + if TestFilter(() => obj.Destroyed) => //standard deployable elimination behavior sendResponse(ObjectDeleteMessage(dguid, unk1=0)) @@ -138,7 +138,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) case LocalAction.EliminateDeployable(obj, dguid, _, _) - if TestFilter(_ => obj.Destroyed) => + if TestFilter(() => obj.Destroyed) => sendResponse(ObjectDeleteMessage(dguid, unk1=0)) case LocalAction.EliminateDeployable(obj, dguid, pos, effect) => @@ -146,14 +146,11 @@ 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, filterGuid, 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) - case PlanetsideAttribute(targetGuid, attributeType, attributeValue) => - sessionLogic.general.sendPlanetsideAttributeMessage(targetGuid, attributeType, attributeValue) - case LocalAction.GenericActionMessage(actionNumber) => sendResponse(GenericActionMessage(actionNumber)) @@ -224,7 +221,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act sendResponse(GenericObjectActionMessage(buildingGuid, 12)) case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) - if TestFilter(_ => isSameTarget) => + if TestFilter(SameTargetTest) => 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 4771d2c42..da83bc6ed 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -46,7 +46,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if TestFilter(_ => { isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) => + ) if TestFilter(() => { NotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) => //player who is also in the vehicle (not driver) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) player.Position = pos @@ -74,36 +74,36 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if TestFilter(_ => isNotSameTarget) => + ) if TestFilter(NotSameTargetTest) => //player who is watching the vehicle from the outside sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) - if TestFilter(_ => isNotSameTarget) => - sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver)) + if TestFilter(NotSameTargetTest) => + sendResponse(DismountVehicleMsg(FilterGuid, bailType, wasKickedByDriver)) case VehicleAction.MountVehicle(vehicleGuid, seat) - if TestFilter(_ => isNotSameTarget) => - sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat)) + if TestFilter(NotSameTargetTest) => + sendResponse(ObjectAttachMessage(vehicleGuid, FilterGuid, seat)) case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) - if TestFilter(_ => isNotSameTarget) => - sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos)) + if TestFilter(NotSameTargetTest) => + sendResponse(DeployRequestMessage(FilterGuid, objectGuid, state, unk1, unk2, pos)) case VehicleAction.EquipmentCreatedInSlot(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case VehicleAction.InventoryState(obj, parentGuid, start, conData) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -115,10 +115,10 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: )) case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) - if TestFilter(_ => isSameTarget) => + if TestFilter(SameTargetTest) => //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(filterGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver)) val typeOfRide = continent.GUID(vehicleGuid) match { case Some(obj: Vehicle) => sessionLogic.general.unaccessContainer(obj) @@ -132,33 +132,33 @@ 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(filterGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver)) case VehicleAction.InventoryState2(objGuid, parentGuid, value) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //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)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) case VehicleAction.Ownership(vehicleGuid) - if TestFilter(_ => isSameTarget) => + if TestFilter(SameTargetTest) => //Only the player that owns this vehicle needs the ownership packet avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) - sendResponse(PlanetsideAttributeMessage(resolvedGuid, attribute_type=21, vehicleGuid)) + sendResponse(PlanetsideAttributeMessage(ResolvedGuid, attribute_type=21, vehicleGuid)) case VehicleAction.LoseOwnership(_, vehicleGuid) => ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly? sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData)) @@ -176,7 +176,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: } case VehicleAction.UnstowEquipment(itemGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) @@ -185,7 +185,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sessionLogic.zoning.interstellarFerry = Some(vehicle) sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}") @@ -193,7 +193,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating") case VehicleAction.KickCargo(vehicle, speed, delay) - if TestFilter(_ => { 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 reverseSpeed = if (strafe > 1) { 0 } else { speed } //strafe or reverse, not both @@ -221,11 +221,11 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) case VehicleAction.KickCargo(cargo, _, _) - if TestFilter(_ => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) => + if TestFilter(() => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) => sessionLogic.vehicles.TotalDriverVehicleControl(cargo) case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory) - if TestFilter(_ => { player.avatar.vehicle.contains(target) }) => + if TestFilter(() => { player.avatar.vehicle.contains(target) }) => //TODO when vehicle weapons can be changed without visual glitches, rewrite this continent.GUID(target).collect { case vehicle: Vehicle => import net.psforever.login.WorldSession.boolToInt @@ -249,7 +249,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: } case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) - if TestFilter(_ => { 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 continent.GUID(target).collect { case vehicle: Vehicle => //external participant: observe changes to equipment @@ -287,7 +287,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(GenericObjectActionMessage(playerGuid, code=10)) case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) - if TestFilter(_ => { player.VisibleSlots.contains(player.DrawnSlot) }) => + if TestFilter(() => { player.VisibleSlots.contains(player.DrawnSlot) }) => player.DrawnSlot = Player.HandsDownSlot startPlayerSeatedInVehicle(vehicle) 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 369fa3cc0..1f994d452 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -61,9 +61,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking, isNotRendered, canSeeReallyFar - ) if TestFilter(_ => isNotSameTarget) => + ) if TestFilter(NotSameTargetTest) => 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 _ => (None, 0L, Vector3.Zero, false, None) } @@ -106,7 +106,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //must draw sendResponse( PlayerStateMessage( - filterGuid, + FilterGuid, pos, vel, yaw, @@ -119,10 +119,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(filterGuid.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(filterGuid.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( - filterGuid, + 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(filterGuid.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(filterGuid.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 TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) => - sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) + if TestFilter(() => { SameTarget && player.VisibleSlots.contains(slot) }) => + 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) @@ -160,33 +160,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ObjectHeld(slot, _) - if TestFilter(_ => { isSameTarget && slot > -1 }) => - sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) + if TestFilter(() => { SameTarget && slot > -1 }) => + sendResponse(ObjectHeldMessage(FilterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) - if TestFilter(_ => isSameTarget) => () + if TestFilter(SameTargetTest) => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(FilterGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filterGuid.guid) - ops.lastSeenStreamMessage.put(filterGuid.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 TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(filterGuid.guid) - ops.lastSeenStreamMessage.put(filterGuid.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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.EquipmentCreatedInHand(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.Destroy(victim, killer, weapon, pos) => @@ -197,7 +197,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) case AvatarAction.TerminalOrderResult(terminalGuid, action, result) - if TestFilter(_ => { result && (action == TransactionType.Buy || action == TransactionType.Loadout) }) => + if TestFilter(() => { result && (action == TransactionType.Buy || action == TransactionType.Loadout) }) => sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sessionLogic.terminals.lastTerminalOrderFulfillment = true AvatarActor.savePlayerData(player) @@ -219,7 +219,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A inventory, drop, delete - ) if TestFilter(_ => { resolvedGuid == target }) => + ) if TestFilter(() => { ResolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) //happening to this player @@ -297,7 +297,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A oldInventory, inventory, drops - ) if TestFilter(_ => { resolvedGuid == target }) => + ) if TestFilter(() => { ResolvedGuid == target }) => sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor)) //happening to this player @@ -331,9 +331,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.UseKit(kguid, kObjId) => sendResponse( UseItemMessage( - resolvedGuid, + ResolvedGuid, kguid, - resolvedGuid, + ResolvedGuid, unk2 = 4294967295L, unk3 = false, unk4 = Vector3.Zero, @@ -354,7 +354,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) case AvatarAction.UpdateKillsDeathsAssists(_, kda: Kill) - if TestFilter(_ => kda.experienceEarned > 0) => + if TestFilter(() => kda.experienceEarned > 0) => continent.actor ! ZoneActor.RewardOurSupporters( PlayerSource(player), Players.produceContributionTranscriptFromKill(continent, player, kda), @@ -389,7 +389,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible }}) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible }}) => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(_, mount) => @@ -444,11 +444,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A } case AvatarAction.ReleasePlayer(tplayer) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) case AvatarAction.Revive(revivalTargetGuid) - if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) => + if TestFilter(() => { ResolvedGuid == revivalTargetGuid }) => log.info(s"No time for rest, ${player.Name}. Back on your feet!") sessionLogic.zoning.spawn.reviveTimer.cancel() sessionLogic.zoning.spawn.deadState = DeadState.Alive @@ -463,12 +463,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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => 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 TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => @@ -476,7 +476,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sessionLogic.zoning.CancelZoningProcess() case AvatarAction.DropCreatedItem(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) /* rare messages */ @@ -490,11 +490,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A )) case AvatarAction.LoadCreatedProjectile(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => @@ -515,11 +515,11 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(GenericActionMessage(mode)) case AvatarAction.PutDownFDU(target) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(GenericObjectActionMessage(target, code=53)) case AvatarAction.StowEquipment(target, slot, item) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => val definition = item.Definition sendResponse( ObjectCreateDetailedMessage( @@ -531,7 +531,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) => + if TestFilter(() => { NotSameTarget && ops.lastSeenStreamMessage.get(FilterGuid.guid).exists { _.visible } }) => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => 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 10e56ec0a..313254d87 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -39,7 +39,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if TestFilter(_ => { isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) => + ) if TestFilter(() => { NotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) => //player who is also in the vehicle (not driver) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) player.Position = pos @@ -59,36 +59,36 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: wheelDirection, unk5, unk6 - ) if TestFilter(_ => isNotSameTarget) => + ) if TestFilter(NotSameTargetTest) => //player who is watching the vehicle from the outside sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) - if TestFilter(_ => isNotSameTarget) => - sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver)) + if TestFilter(NotSameTargetTest) => + sendResponse(DismountVehicleMsg(FilterGuid, bailType, wasKickedByDriver)) case VehicleAction.MountVehicle(vehicleGuid, seat) - if TestFilter(_ => isNotSameTarget) => - sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat)) + if TestFilter(NotSameTargetTest) => + sendResponse(ObjectAttachMessage(vehicleGuid, FilterGuid, seat)) case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) - if TestFilter(_ => isNotSameTarget) => - sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos)) + if TestFilter(NotSameTargetTest) => + sendResponse(DeployRequestMessage(FilterGuid, objectGuid, state, unk1, unk2, pos)) case VehicleAction.EquipmentCreatedInSlot(pkt) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(pkt) case VehicleAction.InventoryState(obj, parentGuid, start, conData) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? val objGuid = obj.GUID sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) @@ -100,10 +100,10 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: )) case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //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(filterGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver)) continent.GUID(vehicleGuid) match { case Some(obj: Vehicle) => sessionLogic.general.unaccessContainer(obj) @@ -113,27 +113,27 @@ 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(filterGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver)) case VehicleAction.InventoryState2(objGuid, parentGuid, value) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //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)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) case VehicleAction.UnloadVehicle(_, vehicleGuid) => sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) case VehicleAction.UnstowEquipment(itemGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) @@ -142,7 +142,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() case VehicleAction.KickCargo(vehicle, speed, delay) - if TestFilter(_ => { 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 reverseSpeed = if (strafe > 1) { 0 } else { speed } //strafe or reverse, not both @@ -170,7 +170,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) case VehicleAction.KickCargo(cargo, _, _) - if TestFilter(_ => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) => + if TestFilter(() => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) => sessionLogic.vehicles.TotalDriverVehicleControl(cargo) case VehicleSpawnPad.AttachToRails(vehicle, pad) => 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 aca6ba6d8..488406c7f 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -2,33 +2,22 @@ package net.psforever.actors.session.support import akka.actor.Actor.Receive -import net.psforever.objects.Default +import net.psforever.objects.{Default, Player} import net.psforever.services.base.message.EventResponse import net.psforever.types.PlanetSideGUID -trait CommonHandlerFunctions { - _: CommonSessionInterfacingFunctionality => - protected var resolvedGuid: PlanetSideGUID = Default.GUID0 - protected var filterGuid: PlanetSideGUID = Default.GUID0 - protected var isNotSameTarget: Boolean = false - protected var isSameTarget: Boolean = false +/** + * A shared filter container utilized by all response handlers connected by a certain mode. + * It is expected that the filters are treated in a true-oriented context - + * always check `isNotSameTarget` and not `!isSameTarget`, etc.. + */ +protected[support] class CommonHandlerFilters { + var resolvedGuid: PlanetSideGUID = Default.GUID0 + var filterGuid: PlanetSideGUID = Default.GUID0 + var isNotSameTarget: Boolean = false + var isSameTarget: Boolean = false - private var ignoreFilter: Boolean = false - - def IgnoreFilter: Boolean = ignoreFilter - - def IgnoreFilter_=(state: Boolean): Boolean = { - ignoreFilter = state - IgnoreFilter - } - - /** - * na - * @param toChannel na - * @param guid na - * @param reply na - */ - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean = { + def Configure(player: Player, guid: PlanetSideGUID): Unit = { filterGuid = guid if (player != null && player.HasGUID) { resolvedGuid = player.GUID @@ -39,20 +28,73 @@ trait CommonHandlerFunctions { isNotSameTarget = false isSameTarget = false } + } +} + +trait CommonHandlerFunctions { + _: CommonSessionInterfacingFunctionality => + final def ResolvedGuid: PlanetSideGUID = sessionLogic.handlerFilters.resolvedGuid + final def FilterGuid: PlanetSideGUID = sessionLogic.handlerFilters.filterGuid + final def NotSameTarget: Boolean = sessionLogic.handlerFilters.isNotSameTarget + final def SameTarget: Boolean = sessionLogic.handlerFilters.isSameTarget + + val NotSameTargetTest: () => Boolean = () => NotSameTarget + + val SameTargetTest: () => Boolean = () => SameTarget + + private var ignoreFilter: Boolean = false + + final def IgnoreFilter: Boolean = ignoreFilter + + final def IgnoreFilter_=(state: Boolean): Boolean = { + ignoreFilter = state + IgnoreFilter + } + + /** + * Process the output of a received response envelope. + * Sets the response handler filter. + * @param toChannel set of subscribers on an event system bus the envelope should reach + * @param guid a specific subscriber endpoint to be excluded + * @param reply output payload transported by this envelope + * @return `true`, if the response was processed; `false`, otherwise + */ + final def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean = { + sessionLogic.handlerFilters.Configure(player, guid) tryToHandle(reply) } - def receive: Receive - + /** + * Can the response handler process this message (with the guard boolean permissions set as they currently are). + * @see `Actor.isDefinedAt` + * @param x payload for processing + * @return `true`, if the payload was processed; `false`, otherwise + */ def isDefinedAt(x: Any): Boolean = receive.isDefinedAt(x) + /** + * Process the output. + * @param x payload for processing + * @return `true`, if the payload was processed; `false`, otherwise + */ final def tryToHandle(x: Any): Boolean = { var passed = true receive.applyOrElse(x, (_: Any) => { passed = false }) passed } - def TestFilter(filter: Unit => Boolean): Boolean = { + /** + * If ignoring guard booleans (filters), always pass. + * If not, test filters using the provided function. + * @param filter contained guard booleans + * @return `true`. if ignoring filter tests or the filter test passed; `false`, otherwise + */ + final def TestFilter(filter: () => Boolean): Boolean = { ignoreFilter || filter() } + + /** + * @see `Actor.receive` + */ + def receive: Receive } 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 d3b19b26c..c66fff0f8 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala @@ -12,52 +12,52 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac def receive: Receive = { case PlanetsideAttribute(target_guid, attributeType, attributeValue) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) case GenericObjectAction(objectGuid, actionCode) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) case ObjectDelete(itemGuid, unk) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ObjectDeleteMessage(itemGuid, unk)) case ChangeFireState_Start(weaponGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) case ChangeFireState_Stop(weaponGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) case ReloadTool(itemGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sessionLogic.avatarResponse.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) case WeaponDryFire(weaponGuid) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => sendResponse(WeaponDryFireMessage(weaponGuid)) } case HintsAtAttacker(sourceGuid) - if TestFilter(_ => { player.isAlive }) => - sendResponse(HitHint(sourceGuid, filterGuid)) + if TestFilter(() => { player.isAlive }) => + sendResponse(HitHint(sourceGuid, FilterGuid)) sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") case SetEmpire(objectGuid, faction) - if TestFilter(_ => isNotSameTarget) => + if TestFilter(NotSameTargetTest) => sendResponse(SetEmpireMessage(objectGuid, faction)) case ConcealPlayer(_) => - sendResponse(GenericObjectActionMessage(filterGuid, 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..7368c358f 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -120,6 +120,8 @@ class SessionData( def zoning: ZoningOperations = zoningOpt.orNull def chat: ChatOperations = chatOpt.orNull + val handlerFilters: CommonHandlerFilters = new CommonHandlerFilters() + ServiceManager.serviceManager ! Lookup("accountIntermediary") ServiceManager.serviceManager ! Lookup("accountPersistence") ServiceManager.serviceManager ! Lookup("galaxy") diff --git a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala index fe5a674b3..67c410492 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionMountHandlers.scala @@ -208,9 +208,9 @@ class SessionMountHandlers( sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive continent.VehicleEvents ! MessageEnvelope( continent.id, - SendResponse(List( + SendResponse( PlanetsideAttributeMessage(obj.GUID, 81, 1), - ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)) + ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation) ) ) } diff --git a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala index a47103dad..8fc619912 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionOutfitHandlers.scala @@ -73,7 +73,7 @@ object SessionOutfitHandlers { player.outfit_id = outfitId player.outfit_name = outfitName zone.AvatarEvents ! BundledEnvelope( - MessageEnvelope(pname, SendResponse(List( + MessageEnvelope(pname, SendResponse( OutfitEvent(outfitId, Update( OutfitInfo( outfitName, 0, 0, 1, @@ -84,7 +84,7 @@ object SessionOutfitHandlers { OutfitMemberUpdate(outfitId, charid, 7, flag = true), ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateSuccess"), OutfitMembershipResponse(CreateResponse, 0, 0, charid, 0, "", "", flag = true), - ))), + )), MessageEnvelope( zoneid, PlanetsideAttribute(player.GUID, 39, outfitId) @@ -148,7 +148,7 @@ object SessionOutfitHandlers { val outfitName = outfit.name val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 fromZone.AvatarEvents ! BundledEnvelope( - MessageEnvelope(fromName, SendResponse(List( + MessageEnvelope(fromName, SendResponse( OutfitMembershipResponse( OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0, toCharId, fromCharId, toName, outfitName, flag = false @@ -159,10 +159,10 @@ object SessionOutfitHandlers { OutfitMemberEventAction.PacketType.Padding, 0 ) ) - ))) + )) ) toZone.AvatarEvents ! BundledEnvelope( - MessageEnvelope(toName, SendResponse(List( + MessageEnvelope(toName, SendResponse( OutfitMembershipResponse( OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0, toCharId, fromCharId, toName, outfitName, flag = true @@ -174,7 +174,7 @@ object SessionOutfitHandlers { 14, unk11 = true, 0, seconds, 0, 0, 0 ))), OutfitMemberUpdate(outfitId, toCharId, 0, flag=true) - ))), + )), MessageEnvelope( toZoneId, PlanetsideAttribute(toGuid, 39, outfitId) @@ -266,13 +266,13 @@ object SessionOutfitHandlers { if (deleted > 0) { findPlayerByIdForOutfitAction(zones, kickedId, kickedBy).foreach { kicked => kicked.Zone.AvatarEvents ! BundledEnvelope( - MessageEnvelope(kicked.Name, SendResponse(List( + MessageEnvelope(kicked.Name, SendResponse( OutfitEvent(outfit_id, Leaving()), OutfitMembershipResponse( OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1, kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false ) - ))), + )), MessageEnvelope(kicked.Zone.id, PlanetsideAttribute(kicked.GUID, 39, 0) ), @@ -599,7 +599,7 @@ object SessionOutfitHandlers { case (Some(outfit), memberCount, points) => val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000 player.Zone.AvatarEvents ! BundledEnvelope( - MessageEnvelope(player.Name, SendResponse(List( + MessageEnvelope(player.Name, SendResponse( OutfitEvent(outfitId, Update(OutfitInfo( outfit.name, points, points, memberCount, OutfitRankNames( @@ -611,7 +611,7 @@ object SessionOutfitHandlers { 14, unk11 = true, 0, seconds, 0, 0, 0 ))), OutfitMemberUpdate(outfit.id, player.CharId, membership.rank, flag = true) - ))), + )), MessageEnvelope( player.Zone.id, PlanetsideAttribute(player.GUID, 39, outfit.id) diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 3d2ab4e50..6ffe99ebb 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -3502,7 +3502,7 @@ class ZoningOperations( val events = zone.AvatarEvents events ! MessageEnvelope( channel, - SendResponse(List(PlanetsideAttributeMessage(guid, 0, 120), PlanetsideAttributeMessage(guid, 1, 120))) + SendResponse(PlanetsideAttributeMessage(guid, 0, 120), PlanetsideAttributeMessage(guid, 1, 120)) ) case _ => () } diff --git a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala index ba3f8bdc3..676838bcc 100644 --- a/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala +++ b/src/main/scala/net/psforever/actors/zone/building/MajorFacilityLogic.scala @@ -242,10 +242,10 @@ case object MajorFacilityLogic val guid = building.GUID //1. reset ???; might be global? //2. This facility's generator is back on line - val list = SendResponse(List( + val list = SendResponse( PlanetsideAttributeMessage(guid, 46, 0), GenericObjectActionMessage(guid, 17) - )) + ) events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, list) }) true case _ => @@ -300,7 +300,7 @@ case object MajorFacilityLogic //2 .disable spawn target on deployment map events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(guid, 48, 1), PlanetsideAttributeMessage(guid, 38, 0))) + SendResponse(PlanetsideAttributeMessage(guid, 48, 1), PlanetsideAttributeMessage(guid, 38, 0)) ) Behaviors.same } @@ -325,7 +325,7 @@ case object MajorFacilityLogic //2. enable spawn target on deployment map events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(guid, 48, 0), PlanetsideAttributeMessage(guid, 38, 1))) + SendResponse(PlanetsideAttributeMessage(guid, 48, 0), PlanetsideAttributeMessage(guid, 38, 1)) ) Behaviors.same } diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala index 74cf26a10..ec412e277 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableAmenity.scala @@ -39,7 +39,7 @@ object DamageableAmenity { val targetGUID = target.GUID events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(targetGUID, 50, 1), PlanetsideAttributeMessage(targetGUID, 51, 1))) + SendResponse(PlanetsideAttributeMessage(targetGUID, 50, 1), PlanetsideAttributeMessage(targetGUID, 51, 1)) ) } } diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index bc957d9c4..bc29ce162 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -274,7 +274,7 @@ object GenericHackables { ) zone.LocalEvents ! MessageEnvelope( zone.id, - SendResponse(List(GenericObjectActionMessage(target.GUID, 61), GenericObjectActionMessage(target.GUID, 58))) + SendResponse(GenericObjectActionMessage(target.GUID, 61), GenericObjectActionMessage(target.GUID, 58)) ) //amenities if applicable virus match { diff --git a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala index 14fde4811..88b8cbe25 100644 --- a/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala +++ b/src/main/scala/net/psforever/objects/serverobject/repair/RepairableAmenity.scala @@ -40,7 +40,7 @@ object RepairableAmenity { val targetGUID = target.GUID events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(targetGUID, 50, 0), PlanetsideAttributeMessage(targetGUID, 51, 0))) + SendResponse(PlanetsideAttributeMessage(targetGUID, 50, 0), PlanetsideAttributeMessage(targetGUID, 51, 0)) ) RestorationOfHistory(target) } diff --git a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala index cb46bd630..24da2b2a6 100644 --- a/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala +++ b/src/main/scala/net/psforever/objects/serverobject/structures/participation/FacilityHackParticipation.scala @@ -110,10 +110,10 @@ trait FacilityHackParticipation extends ParticipationLogic { import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.objects.GlobalDefinitions val mainTerm = building.Amenities.filter(x => x.isInstanceOf[Terminal] && x.Definition == GlobalDefinitions.main_terminal).head.GUID - val pkts = SendResponse(List( + val pkts = SendResponse( GenericObjectActionMessage(mainTerm, 61), GenericObjectActionMessage(mainTerm, 58) - )) + ) val events = building.Zone.AvatarEvents events ! BundledEnvelope(list.map { p => MessageEnvelope(p.Name, pkts) diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala index bd43ed550..9a6845e78 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/TurretControl.scala @@ -43,7 +43,7 @@ trait TurretControl val tguid = TurretObject.GUID events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(tguid, 50, 0), PlanetsideAttributeMessage(tguid, 51, 0))) + SendResponse(PlanetsideAttributeMessage(tguid, 50, 0), PlanetsideAttributeMessage(tguid, 51, 0)) ) } @@ -62,7 +62,7 @@ trait TurretControl CancelJammeredStatus(target) events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(tguid, 50, 1), PlanetsideAttributeMessage(tguid, 51, 1))) + SendResponse(PlanetsideAttributeMessage(tguid, 50, 1), PlanetsideAttributeMessage(tguid, 51, 1)) ) } } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala b/src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala index cb5f5fb02..edf37c040 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/AntTransferBehavior.scala @@ -163,7 +163,7 @@ trait AntTransferBehavior extends TransferBehavior with NtuStorageBehavior { //2. orb particle effect off events ! MessageEnvelope( zoneId, - SendResponse(List(PlanetsideAttributeMessage(vguid, 52, 0L), PlanetsideAttributeMessage(vguid, 49, 0L))) + SendResponse(PlanetsideAttributeMessage(vguid, 52, 0L), PlanetsideAttributeMessage(vguid, 49, 0L)) ) } else if (transferEvent == TransferBehavior.Event.Discharging) { events ! MessageEnvelope( diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala index eaa62e792..ae4c411e4 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala @@ -17,8 +17,8 @@ trait GenericMessageEnvelope object GenericMessageEnvelope { /** - * The `unapply`ed data from a message envelope resembles the data from includes the filter and the channel information. - * The original channel information. + * The extracted data from a message envelope resembles the data from, + * including the filter and the original channel information. * @param obj response envelope * @return a tuple containing the channel, filter, and reply message */ diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala index 752fc9385..5f5a39420 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala @@ -24,7 +24,7 @@ object GenericResponseEnvelope { * @param stamp marker indicating the routing through which the original message was processed * @param channel set of subscribers on an event system bus the envelope should reach * @param filter a specific subscriber endpoint to be excluded - * @param msg input payload transported by this envelope + * @param msg output payload transported by this envelope * @return a faked but typically acceptable response envelope */ def apply(stamp: EventSystemStamp, channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericResponseEnvelope = { diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala index b93747d25..58373b521 100644 --- a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -49,11 +49,6 @@ trait MessageTransformationBehavior def reply: EventResponse = outputReply } -/** - * A proper event system envelope. - */ -case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) - extends MessageTransformationBehavior object MessageEnvelope { def apply(msg: EventMessage): MessageEnvelope = @@ -62,3 +57,9 @@ object MessageEnvelope { def apply(channel: String, msg: EventMessage): MessageEnvelope = MessageEnvelope(channel, Default.GUID0, msg) } + +/** + * A proper event system envelope. + */ +case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) + extends MessageTransformationBehavior diff --git a/src/main/scala/net/psforever/services/base/message/SendResponse.scala b/src/main/scala/net/psforever/services/base/message/SendResponse.scala index eca4f292a..cb3f452a5 100644 --- a/src/main/scala/net/psforever/services/base/message/SendResponse.scala +++ b/src/main/scala/net/psforever/services/base/message/SendResponse.scala @@ -7,4 +7,6 @@ final case class SendResponse(pkts: Seq[PlanetSideGamePacket]) extends SelfRespo object SendResponse { def apply(pkt: PlanetSideGamePacket): SendResponse = SendResponse(Seq(pkt)) + + def apply(first: PlanetSideGamePacket, msgs: PlanetSideGamePacket*): SendResponse = SendResponse(first +: msgs) }