working LocalService based on GenericServiceEvent(WithSupport); manually corrected almost every message to LocalService to ensure channel and filters are preserved

This commit is contained in:
Fate-JH 2026-01-26 03:47:37 -05:00
parent d62dbfdd81
commit 1cbe1fa141
53 changed files with 629 additions and 929 deletions

View file

@ -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"

View file

@ -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,

View file

@ -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

View file

@ -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 = {

View file

@ -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))

View file

@ -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)))

View file

@ -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(

View file

@ -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) }

View file

@ -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)
)
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)))
)
}

View file

@ -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)
)
}
}

View file

@ -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)?
}

View file

@ -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 {

View file

@ -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(

View file

@ -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 {

View file

@ -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 =>

View file

@ -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()

View file

@ -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

View file

@ -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)
)
}
}

View file

@ -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

View file

@ -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)
)
}
}

View file

@ -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._

View file

@ -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 _ => ()
}

View file

@ -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))
}
}

View file

@ -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}
/**

View file

@ -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)

View file

@ -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))
}
}

View file

@ -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))
}
}

View file

@ -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}")

View file

@ -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)
)
}
}

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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._

View file

@ -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._

View file

@ -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
}

View file

@ -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())
}
}

View file

@ -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"
}

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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 = {

View file

@ -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]

View file

@ -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, "")
}

View file

@ -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 {

View file

@ -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
})
}

View file

@ -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)
}
}

View file

@ -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)
)
)
}