mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-15 08:24:42 +00:00
reorganized special envelopes from certain control agencies; wrote tests for primary event systems; fixed some other tests; knapsacking algorithm in grid inventory is less abusive
This commit is contained in:
parent
4dc5d7f01e
commit
de84e31547
62 changed files with 1489 additions and 1103 deletions
58
.codecov.yml
58
.codecov.yml
|
|
@ -9,6 +9,9 @@ coverage:
|
||||||
threshold: 0.25%
|
threshold: 0.25%
|
||||||
|
|
||||||
ignore:
|
ignore:
|
||||||
|
- "src/main/java"
|
||||||
|
- "src/main/resources"
|
||||||
|
- "src/main/scala/akka"
|
||||||
- "src/main/scala/net/psforever/objects/ObjectType.scala"
|
- "src/main/scala/net/psforever/objects/ObjectType.scala"
|
||||||
- "src/main/scala/net/psforever/objects/avatar/Avatars.scala"
|
- "src/main/scala/net/psforever/objects/avatar/Avatars.scala"
|
||||||
- "src/main/scala/net/psforever/objects/ballistics/DamageResolution.scala"
|
- "src/main/scala/net/psforever/objects/ballistics/DamageResolution.scala"
|
||||||
|
|
@ -18,7 +21,12 @@ ignore:
|
||||||
- "src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala"
|
- "src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala"
|
||||||
- "src/main/scala/net/psforever/objects/equipment/Kits.scala"
|
- "src/main/scala/net/psforever/objects/equipment/Kits.scala"
|
||||||
- "src/main/scala/net/psforever/objects/equipment/SItem.scala"
|
- "src/main/scala/net/psforever/objects/equipment/SItem.scala"
|
||||||
|
- "src/main/scala/net/psforever/objects/global"
|
||||||
- "src/main/scala/net/psforever/objects/guid/AvailabilityPolicy.scala"
|
- "src/main/scala/net/psforever/objects/guid/AvailabilityPolicy.scala"
|
||||||
|
- "src/main/scala/net/psforever/objects/loadouts/EquipmentLoadout.scala"
|
||||||
|
- "src/main/scala/net/psforever/objects/loadouts/InfantryLoadout.scala"
|
||||||
|
- "src/main/scala/net/psforever/objects/loadouts/SquadLoadout.scala"
|
||||||
|
- "src/main/scala/net/psforever/objects/loadouts/VehicleLoadout.scala"
|
||||||
- "src/main/scala/net/psforever/objects/serverobject/pad/AutoDriveControls.scala"
|
- "src/main/scala/net/psforever/objects/serverobject/pad/AutoDriveControls.scala"
|
||||||
- "src/main/scala/net/psforever/objects/serverobject/structures/StructureType.scala"
|
- "src/main/scala/net/psforever/objects/serverobject/structures/StructureType.scala"
|
||||||
- "src/main/scala/net/psforever/objects/serverobject/shuttle/ShuttleAmenity.scala"
|
- "src/main/scala/net/psforever/objects/serverobject/shuttle/ShuttleAmenity.scala"
|
||||||
|
|
@ -56,24 +64,42 @@ ignore:
|
||||||
- "src/main/scala/net/psforever/packet/ControlPacketOpcode.scala"
|
- "src/main/scala/net/psforever/packet/ControlPacketOpcode.scala"
|
||||||
- "src/main/scala/net/psforever/packet/CryptoPacketOpcode.scala"
|
- "src/main/scala/net/psforever/packet/CryptoPacketOpcode.scala"
|
||||||
- "src/main/scala/net/psforever/packet/GamePacketOpcode.scala"
|
- "src/main/scala/net/psforever/packet/GamePacketOpcode.scala"
|
||||||
- "src/main/scala/net/psforever/types/Angular.scala"
|
- "src/main/scala/net/psforever/packet/ResetSequenceOpcode.scala"
|
||||||
- "src/main/scala/net/psforever/types/CertificationType.scala"
|
- "src/main/scala/net/psforever/persistence"
|
||||||
- "src/main/scala/net/psforever/types/ChatMessageType.scala"
|
- "src/main/scala/net/psforever/services/account/IPAddress.scala"
|
||||||
- "src/main/scala/net/psforever/types/DriveState.scala"
|
- "src/main/scala/net/psforever/services/account/ReceiveAccountData.scala"
|
||||||
- "src/main/scala/net/psforever/types/EmoteType.scala"
|
- "src/main/scala/net/psforever/services/account/ReceiveIPAddress.scala"
|
||||||
- "src/main/scala/net/psforever/types/ExoSuitType.scala"
|
- "src/main/scala/net/psforever/services/account/RetrieveAccountData.scala"
|
||||||
- "src/main/scala/net/psforever/types/GrenadeState.scala"
|
- "src/main/scala/net/psforever/services/account/RetrieveIPAddress.scala"
|
||||||
- "src/main/scala/net/psforever/types/ImplantType.scala"
|
- "src/main/scala/net/psforever/services/account/StoreAccountData.scala"
|
||||||
- "src/main/scala/net/psforever/types/MeritCommendation.scala"
|
- "src/main/scala/net/psforever/services/account/StoreIPAddress.scala"
|
||||||
- "src/main/scala/net/psforever/types/PlanetSideEmpire.scala"
|
|
||||||
- "src/main/scala/net/psforever/types/TransactionType.scala"
|
|
||||||
- "src/main/scala/net/psforever/services/avatar/AvatarAction.scala"
|
- "src/main/scala/net/psforever/services/avatar/AvatarAction.scala"
|
||||||
- "src/main/scala/net/psforever/services/galaxy/AvatarServiceMessage.scala"
|
- "src/main/scala/net/psforever/services/avatar/AvatarService.scala"
|
||||||
- "src/main/scala/net/psforever/services/galaxy/AvatarServiceResponse.scala"
|
- "src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala"
|
||||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala"
|
- "src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/base/bus"
|
||||||
|
- "src/main/scala/net/psforever/services/base/envelope"
|
||||||
|
- "src/main/scala/net/psforever/services/chat/ChatChannel.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/galaxy/GalaxyAction"
|
||||||
|
- "src/main/scala/net/psforever/services/galaxy/GalaxyService"
|
||||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala"
|
- "src/main/scala/net/psforever/services/galaxy/GalaxyServiceMessage.scala"
|
||||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala"
|
- "src/main/scala/net/psforever/services/galaxy/GalaxyServiceResponse.scala"
|
||||||
- "src/main/scala/net/psforever/services/hart/HartEvent.scala"
|
- "src/main/scala/net/psforever/services/hart/HartEvent.scala"
|
||||||
- "src/main/scala/net/psforever/services/hart/HartTimerActions.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/LocalAction"
|
||||||
- "src/main/scala/net/psforever/services/vehicle/VehicleAction.scala"
|
- "src/main/scala/net/psforever/services/local/LocalService"
|
||||||
|
- "src/main/scala/net/psforever/services/local/LocalServiceMessage.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/local/LocalServiceResponse.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/vehicle/VehicleAction"
|
||||||
|
- "src/main/scala/net/psforever/services/vehicle/VehicleService"
|
||||||
|
- "src/main/scala/net/psforever/services/vehicle/VehicleServiceMessage.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/vehicle/VehicleServiceResponse.scala"
|
||||||
|
- "src/main/scala/net/psforever/services/Service.scala"
|
||||||
|
- "src/main/scala/net/psforever/types"
|
||||||
|
- "src/main/scala/net/psforever/util"
|
||||||
|
- "src/main/scala/net/psforever/zones"
|
||||||
|
- "src/main/scala/net/psforever/IFinalizable.scala"
|
||||||
|
- "src/main/scala/scodec"
|
||||||
|
- "src/test"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstrea
|
||||||
import net.psforever.types._
|
import net.psforever.types._
|
||||||
import net.psforever.services.{RemoverActor, Service, ServiceManager}
|
import net.psforever.services.{RemoverActor, Service, ServiceManager}
|
||||||
import net.psforever.services.avatar._
|
import net.psforever.services.avatar._
|
||||||
|
import net.psforever.services.avatar.support.{CorpseEnvelope, DropItemEnvelope, PickupItemEnvelope, ReleaseEnvelope}
|
||||||
import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire}
|
import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, ObjectDelete, PlanetsideAttribute, ReloadTool, WeaponDryFire}
|
||||||
|
|
||||||
class AvatarService1Test extends ActorTest {
|
class AvatarService1Test extends ActorTest {
|
||||||
|
|
@ -153,7 +154,7 @@ class DroptItemTest extends ActorTest {
|
||||||
"AvatarService" should {
|
"AvatarService" should {
|
||||||
"pass DropItem" in {
|
"pass DropItem" in {
|
||||||
service ! Service.Join("test")
|
service ! Service.Join("test")
|
||||||
service ! DropItemMessage("test", PlanetSideGUID(10), AvatarAction.DropItem(tool), Zone.Nowhere)
|
service ! DropItemEnvelope("test", PlanetSideGUID(10), AvatarAction.DropItem(tool), Zone.Nowhere)
|
||||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.DropCreatedItem(pkt)))
|
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarAction.DropCreatedItem(pkt)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -324,7 +325,7 @@ class PickupItemTest extends ActorTest {
|
||||||
ServiceManager.boot(system)
|
ServiceManager.boot(system)
|
||||||
val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName)
|
val service = system.actorOf(Props(classOf[AvatarService]), AvatarServiceTest.TestName)
|
||||||
service ! Service.Join("test")
|
service ! Service.Join("test")
|
||||||
service ! PickupItemMessage("test", AvatarAction.PickupItem(tool), Zone.Nowhere)
|
service ! PickupItemEnvelope("test", AvatarAction.PickupItem(tool), Zone.Nowhere)
|
||||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0)))
|
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), ObjectDelete(tool.GUID, 0)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -509,7 +510,7 @@ class AvatarReleaseTest extends FreedContextActorTest {
|
||||||
assert(zone.Corpses.size == 1)
|
assert(zone.Corpses.size == 1)
|
||||||
assert(obj.HasGUID)
|
assert(obj.HasGUID)
|
||||||
val guid = obj.GUID
|
val guid = obj.GUID
|
||||||
zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second
|
zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second
|
||||||
|
|
||||||
val reply1 = subscriber.receiveOne(200 milliseconds)
|
val reply1 = subscriber.receiveOne(200 milliseconds)
|
||||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||||
|
|
@ -560,7 +561,7 @@ class AvatarReleaseEarly1Test extends FreedContextActorTest {
|
||||||
assert(zone.Corpses.size == 1)
|
assert(zone.Corpses.size == 1)
|
||||||
assert(obj.HasGUID)
|
assert(obj.HasGUID)
|
||||||
val guid = obj.GUID
|
val guid = obj.GUID
|
||||||
zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
||||||
|
|
||||||
val reply1 = subscriber.receiveOne(200 milliseconds)
|
val reply1 = subscriber.receiveOne(200 milliseconds)
|
||||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||||
|
|
@ -576,8 +577,8 @@ class AvatarReleaseEarly1Test extends FreedContextActorTest {
|
||||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||||
assert(reply2msg.filter == Service.defaultPlayerGUID)
|
assert(reply2msg.filter == Service.defaultPlayerGUID)
|
||||||
assert(reply2msg.reply.isInstanceOf[AvatarAction.ObjectDelete])
|
assert(reply2msg.reply.isInstanceOf[ObjectDelete])
|
||||||
assert(reply2msg.reply.asInstanceOf[AvatarAction.ObjectDelete].item_guid == guid)
|
assert(reply2msg.reply.asInstanceOf[ObjectDelete].obj_guid == guid)
|
||||||
|
|
||||||
subscriber.expectNoMessage(1 seconds)
|
subscriber.expectNoMessage(1 seconds)
|
||||||
assert(zone.Corpses.isEmpty)
|
assert(zone.Corpses.isEmpty)
|
||||||
|
|
@ -618,7 +619,7 @@ class AvatarReleaseEarly2Test extends FreedContextActorTest {
|
||||||
assert(zone.Corpses.size == 1)
|
assert(zone.Corpses.size == 1)
|
||||||
assert(obj.HasGUID)
|
assert(obj.HasGUID)
|
||||||
val guid = obj.GUID
|
val guid = obj.GUID
|
||||||
zone.AvatarEvents ! ReleaseMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
zone.AvatarEvents ! ReleaseEnvelope("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
||||||
|
|
||||||
val reply1 = subscriber.receiveOne(200 milliseconds)
|
val reply1 = subscriber.receiveOne(200 milliseconds)
|
||||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1}
|
import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1}
|
||||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||||
import net.psforever.services.RemoverActor
|
import net.psforever.services.RemoverActor
|
||||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, CorpseEnvelope}
|
import net.psforever.services.avatar.support.CorpseEnvelope
|
||||||
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.services.base.message.PlanetsideAttribute
|
import net.psforever.services.base.message.PlanetsideAttribute
|
||||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ import net.psforever.objects.serverobject.mount.Mountable
|
||||||
import net.psforever.objects.vehicles.control.BfrFlight
|
import net.psforever.objects.vehicles.control.BfrFlight
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage}
|
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.base.CachedMessage
|
|
||||||
import net.psforever.services.base.message.PlanetsideAttribute
|
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types.{DriveState, Vector3}
|
import net.psforever.types.{DriveState, Vector3}
|
||||||
|
|
||||||
|
|
@ -245,7 +243,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
||||||
obj.Velocity = vel
|
obj.Velocity = vel
|
||||||
sessionLogic.updateBlockMap(obj, pos)
|
sessionLogic.updateBlockMap(obj, pos)
|
||||||
obj.zoneInteractions()
|
obj.zoneInteractions()
|
||||||
continent.VehicleEvents ! CachedMessage(
|
continent.VehicleEvents ! CachedEnvelope(
|
||||||
continent.id,
|
continent.id,
|
||||||
player.GUID,
|
player.GUID,
|
||||||
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||||
import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData}
|
import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData}
|
||||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.services.base.CachedMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.base.message.PlanetsideAttribute
|
import net.psforever.services.base.message.PlanetsideAttribute
|
||||||
import net.psforever.services.local.support.CaptureFlagManager
|
import net.psforever.services.local.support.CaptureFlagManager
|
||||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import net.psforever.objects.vehicles.control.BfrFlight
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||||
import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||||
import net.psforever.services.base.CachedMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types.{ChatMessageType, DriveState, Vector3}
|
import net.psforever.types.{ChatMessageType, DriveState, Vector3}
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
||||||
obj.Position = position
|
obj.Position = position
|
||||||
obj.Orientation = angle
|
obj.Orientation = angle
|
||||||
//
|
//
|
||||||
continent.VehicleEvents ! CachedMessage(
|
continent.VehicleEvents ! CachedEnvelope(
|
||||||
continent.id,
|
continent.id,
|
||||||
player.GUID,
|
player.GUID,
|
||||||
VehicleAction.VehicleState(
|
VehicleAction.VehicleState(
|
||||||
|
|
@ -239,7 +239,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
||||||
obj.Velocity = vel
|
obj.Velocity = vel
|
||||||
sessionLogic.updateBlockMap(obj, pos)
|
sessionLogic.updateBlockMap(obj, pos)
|
||||||
obj.zoneInteractions()
|
obj.zoneInteractions()
|
||||||
continent.VehicleEvents ! CachedMessage(
|
continent.VehicleEvents ! CachedEnvelope(
|
||||||
continent.id,
|
continent.id,
|
||||||
player.GUID,
|
player.GUID,
|
||||||
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||||
import net.psforever.services.account.AccountPersistenceService
|
import net.psforever.services.account.AccountPersistenceService
|
||||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.services.base.CachedMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.base.message.PlanetsideAttribute
|
import net.psforever.services.base.message.PlanetsideAttribute
|
||||||
import net.psforever.types.{ExoSuitType, Vector3}
|
import net.psforever.types.{ExoSuitType, Vector3}
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
||||||
player.Crouching = isCrouching
|
player.Crouching = isCrouching
|
||||||
player.Jumping = isJumping
|
player.Jumping = isJumping
|
||||||
player.Cloaked = player.ExoSuit == ExoSuitType.Infiltration && isCloaking
|
player.Cloaked = player.ExoSuit == ExoSuitType.Infiltration && isCloaking
|
||||||
continent.AvatarEvents ! CachedMessage(
|
continent.AvatarEvents ! CachedEnvelope(
|
||||||
"spectator",
|
"spectator",
|
||||||
avatarGuid,
|
avatarGuid,
|
||||||
AvatarAction.PlayerState(
|
AvatarAction.PlayerState(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||||
import net.psforever.objects.Vehicle
|
import net.psforever.objects.Vehicle
|
||||||
import net.psforever.objects.serverobject.deploy.Deployment
|
import net.psforever.objects.serverobject.deploy.Deployment
|
||||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||||
import net.psforever.services.base.CachedMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types.{DriveState, Vector3}
|
import net.psforever.types.{DriveState, Vector3}
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
||||||
obj.Velocity = vel
|
obj.Velocity = vel
|
||||||
sessionLogic.updateBlockMap(obj, pos)
|
sessionLogic.updateBlockMap(obj, pos)
|
||||||
obj.zoneInteractions()
|
obj.zoneInteractions()
|
||||||
continent.VehicleEvents ! CachedMessage(
|
continent.VehicleEvents ! CachedEnvelope(
|
||||||
continent.id,
|
continent.id,
|
||||||
player.GUID,
|
player.GUID,
|
||||||
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@ import net.psforever.packet.game.{SetChatFilterMessage, TimeOfDayMessage}
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel}
|
import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel}
|
||||||
import net.psforever.services.local.support.HackCaptureActor
|
import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor}
|
||||||
import net.psforever.services.local.CaptureMessage
|
|
||||||
import net.psforever.services.teamwork.{SquadResponse, SquadService, SquadServiceResponse}
|
import net.psforever.services.teamwork.{SquadResponse, SquadService, SquadServiceResponse}
|
||||||
import net.psforever.types.ChatMessageType.CMT_QUIT
|
import net.psforever.types.ChatMessageType.CMT_QUIT
|
||||||
import org.log4s.Logger
|
import org.log4s.Logger
|
||||||
|
|
@ -406,7 +405,7 @@ class ChatOperations(
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (building.CaptureTerminalIsHacked) {
|
if (building.CaptureTerminalIsHacked) {
|
||||||
zone.LocalEvents ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(terminal, zone, PlayerSource.Nobody))
|
zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(terminal, zone, PlayerSource.Nobody))
|
||||||
}
|
}
|
||||||
building.Actor ! BuildingActor.SetFaction(faction)
|
building.Actor ! BuildingActor.SetFaction(faction)
|
||||||
building.Actor ! BuildingActor.AmenityStateChange(terminal, Some(false))
|
building.Actor ! BuildingActor.AmenityStateChange(terminal, Some(false))
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad
|
||||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||||
import net.psforever.objects.zones.exp.ToDatabase
|
import net.psforever.objects.zones.exp.ToDatabase
|
||||||
import net.psforever.services.RemoverActor
|
import net.psforever.services.RemoverActor
|
||||||
import net.psforever.services.avatar.GroundEnvelope
|
import net.psforever.services.avatar.support.GroundEnvelope
|
||||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||||
import net.psforever.services.local.support.HackCaptureActor
|
import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor}
|
||||||
import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
|
|
@ -1292,7 +1292,7 @@ class GeneralOperations(
|
||||||
continent.GUID(specialItemSlotGuid) match {
|
continent.GUID(specialItemSlotGuid) match {
|
||||||
case Some(llu: CaptureFlag) =>
|
case Some(llu: CaptureFlag) =>
|
||||||
if (llu.Target.GUID == captureTerminal.Owner.GUID) {
|
if (llu.Target.GUID == captureTerminal.Owner.GUID) {
|
||||||
continent.LocalEvents ! CaptureMessage(HackCaptureActor.FlagCaptured(llu))
|
continent.LocalEvents ! CaptureEnvelope(HackCaptureActor.FlagCaptured(llu))
|
||||||
} else {
|
} else {
|
||||||
log.info(
|
log.info(
|
||||||
s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}"
|
s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle}
|
||||||
import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons}
|
import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons}
|
||||||
import net.psforever.objects.vital.InGameHistory
|
import net.psforever.objects.vital.InGameHistory
|
||||||
import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage}
|
import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage}
|
||||||
import net.psforever.services.base.CachedMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.base.message.SendResponse
|
import net.psforever.services.base.message.SendResponse
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types.{BailType, PlanetSideGUID, Vector3}
|
import net.psforever.types.{BailType, PlanetSideGUID, Vector3}
|
||||||
|
|
@ -225,7 +225,7 @@ class SessionMountHandlers(
|
||||||
sessionLogic.vehicles.ServerVehicleOverrideStop(v)
|
sessionLogic.vehicles.ServerVehicleOverrideStop(v)
|
||||||
}*/
|
}*/
|
||||||
v.Velocity = Vector3.Zero
|
v.Velocity = Vector3.Zero
|
||||||
continent.VehicleEvents ! CachedMessage(
|
continent.VehicleEvents ! CachedEnvelope(
|
||||||
continent.id,
|
continent.id,
|
||||||
tplayer.GUID,
|
tplayer.GUID,
|
||||||
VehicleAction.VehicleState(v.GUID, unk1 = 0, tplayer.Position, v.Orientation, v.Velocity, v.Flying, unk3 = 0, unk4 = 0, wheel_direction = 15, unk5 = false, unk6 = v.Cloaked)
|
VehicleAction.VehicleState(v.GUID, unk1 = 0, tplayer.Position, v.Orientation, v.Velocity, v.Flying, unk3 = 0, unk4 = 0, wheel_direction = 15, unk5 = false, unk6 = v.Cloaked)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import net.psforever.objects.vital.projectile.ProjectileReason
|
||||||
import net.psforever.objects.zones.exp.ToDatabase
|
import net.psforever.objects.zones.exp.ToDatabase
|
||||||
import net.psforever.packet.game.UplinkRequest
|
import net.psforever.packet.game.UplinkRequest
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.base.CachedMessage
|
import net.psforever.services.base.CachedEnvelope
|
||||||
import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire}
|
import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire}
|
||||||
import net.psforever.services.local.LocalServiceMessage
|
import net.psforever.services.local.LocalServiceMessage
|
||||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3}
|
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3}
|
||||||
|
|
@ -494,7 +494,7 @@ class WeaponAndProjectileOperations(
|
||||||
projectile.Position = shot_pos
|
projectile.Position = shot_pos
|
||||||
projectile.Orientation = shot_orient
|
projectile.Orientation = shot_orient
|
||||||
projectile.Velocity = shot_vel
|
projectile.Velocity = shot_vel
|
||||||
continent.AvatarEvents ! CachedMessage(
|
continent.AvatarEvents ! CachedEnvelope(
|
||||||
continent.id,
|
continent.id,
|
||||||
player.GUID,
|
player.GUID,
|
||||||
AvatarAction.ProjectileState(
|
AvatarAction.ProjectileState(
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, Reconstr
|
||||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||||
import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect
|
import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect
|
||||||
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage}
|
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage}
|
||||||
import net.psforever.services.avatar.{CorpseEnvelope, ReleaseMessage}
|
import net.psforever.services.avatar.support.{CorpseEnvelope, ReleaseEnvelope}
|
||||||
import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse}
|
import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse}
|
||||||
import net.psforever.services.chat.DefaultChannel
|
import net.psforever.services.chat.DefaultChannel
|
||||||
|
|
||||||
|
|
@ -2946,7 +2946,7 @@ class ZoningOperations(
|
||||||
tplayer.Release
|
tplayer.Release
|
||||||
DepictPlayerAsCorpse(tplayer)
|
DepictPlayerAsCorpse(tplayer)
|
||||||
zone.Population ! Zone.Corpse.Add(tplayer)
|
zone.Population ! Zone.Corpse.Add(tplayer)
|
||||||
zone.AvatarEvents ! ReleaseMessage(zone.id, AvatarAction.Release(tplayer, zone))
|
zone.AvatarEvents ! ReleaseEnvelope(zone.id, AvatarAction.Release(tplayer, zone))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails, ZoneAct
|
||||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType}
|
import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType}
|
||||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
||||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||||
import net.psforever.services.local.support.HackClearActor
|
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||||
import net.psforever.services.local.HackClearMessage
|
|
||||||
import net.psforever.types.PlanetSideEmpire
|
import net.psforever.types.PlanetSideEmpire
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,7 +52,7 @@ case object CavernFacilityLogic
|
||||||
// When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state
|
// 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 => {
|
building.HackableAmenities.foreach(amenity => {
|
||||||
if (amenity.HackedBy.isDefined) {
|
if (amenity.HackedBy.isDefined) {
|
||||||
building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity))
|
building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// No map update needed - will be sent by `HackCaptureActor` when required
|
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails}
|
||||||
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
||||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
||||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||||
import net.psforever.services.local.support.HackClearActor
|
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||||
import net.psforever.services.local.HackClearMessage
|
|
||||||
import net.psforever.types.PlanetSideEmpire
|
import net.psforever.types.PlanetSideEmpire
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,7 +52,7 @@ case object FacilityLogic
|
||||||
// When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state
|
// 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 => {
|
building.HackableAmenities.foreach(amenity => {
|
||||||
if (amenity.HackedBy.isDefined) {
|
if (amenity.HackedBy.isDefined) {
|
||||||
building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity))
|
building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// No map update needed - will be sent by `HackCaptureActor` when required
|
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ import net.psforever.services.InterstellarClusterService
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse}
|
import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse}
|
||||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||||
import net.psforever.services.local.{CaptureMessage, HackClearMessage, LocalServiceMessage}
|
import net.psforever.services.local.LocalServiceMessage
|
||||||
import net.psforever.services.local.support.{HackCaptureActor, HackClearActor}
|
import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor, HackClearActor, HackClearEnvelope}
|
||||||
import net.psforever.types.PlanetSideEmpire
|
import net.psforever.types.PlanetSideEmpire
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -103,7 +103,7 @@ case object MajorFacilityLogic
|
||||||
hackedAmenities
|
hackedAmenities
|
||||||
}
|
}
|
||||||
amenitiesToClear.foreach { amenity =>
|
amenitiesToClear.foreach { amenity =>
|
||||||
building.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(amenity))
|
building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity))
|
||||||
}
|
}
|
||||||
// No map update needed - will be sent by `HackCaptureActor` when required
|
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||||
case dome: ForceDomePhysics =>
|
case dome: ForceDomePhysics =>
|
||||||
|
|
@ -282,7 +282,7 @@ case object MajorFacilityLogic
|
||||||
(bldg.GetFlag, bldg.CaptureTerminal) match {
|
(bldg.GetFlag, bldg.CaptureTerminal) match {
|
||||||
case (Some(flag), Some(terminal)) if (flag.Target eq building) && flag.Faction != building.Faction =>
|
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
|
//our hack destination may have been compromised and the hack needs to be cancelled
|
||||||
bldg.Zone.LocalEvents ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(terminal, terminal.Zone, PlayerSource.Nobody))
|
bldg.Zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(terminal, terminal.Zone, PlayerSource.Nobody))
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
|
|
|
||||||
|
|
@ -702,15 +702,18 @@ object GridInventory {
|
||||||
*/
|
*/
|
||||||
private def sortKnapsack(list: List[InventoryItem], width: Int, height: Int): Unit = {
|
private def sortKnapsack(list: List[InventoryItem], width: Int, height: Int): Unit = {
|
||||||
val root = new KnapsackNode(0, 0, width, height)
|
val root = new KnapsackNode(0, 0, width, height)
|
||||||
list.foreach(item => {
|
list.foreach { item =>
|
||||||
findKnapsackSpace(root, item.obj.Tile.Width, item.obj.Tile.Height) match {
|
val tile = item.obj.Tile
|
||||||
|
val twidth = tile.Width
|
||||||
|
val theight = tile.Height
|
||||||
|
findKnapsackSpace(root, twidth, theight) match {
|
||||||
case Some(node) =>
|
case Some(node) =>
|
||||||
splitKnapsackSpace(node, item.obj.Tile.Width, item.obj.Tile.Height)
|
splitKnapsackSpace(node, twidth, theight)
|
||||||
item.start = node.y * width + node.x
|
item.start = node.y * width + node.x
|
||||||
case _ => ;
|
case _ =>
|
||||||
item.start = -1
|
item.start = -1
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -720,42 +723,32 @@ object GridInventory {
|
||||||
* Horizontal space for the `down` child is emphasized over vertical space for the `right` child.
|
* Horizontal space for the `down` child is emphasized over vertical space for the `right` child.
|
||||||
* By dividing and reducing a defined space like this, it can be tightly packed with a given number of elements.<br>
|
* By dividing and reducing a defined space like this, it can be tightly packed with a given number of elements.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* Due to the nature of the knapsack problem and the naivette of the algorithm, small holes in the solution are bound to crop-up.
|
* Due to the nature of the knapsack problem and the naivete of the algorithm, small holes in the solution are bound to crop-up.
|
||||||
* @param x the x-coordinate, upper left corner
|
* @param x the x-coordinate, upper left corner
|
||||||
* @param y the y-coordinate, upper left corner
|
* @param y the y-coordinate, upper left corner
|
||||||
* @param width the width
|
* @param width the width
|
||||||
* @param height the height
|
* @param height the height
|
||||||
*/
|
*/
|
||||||
private class KnapsackNode(var x: Int, var y: Int, var width: Int, var height: Int) {
|
private class KnapsackNode(val x: Int, val y: Int, val width: Int, val height: Int) {
|
||||||
private var used: Boolean = false
|
private var used: Boolean = false
|
||||||
var down: Option[KnapsackNode] = None
|
private var down: Option[KnapsackNode] = None
|
||||||
var right: Option[KnapsackNode] = None
|
private var right: Option[KnapsackNode] = None
|
||||||
|
|
||||||
def Used: Boolean = used
|
def Used: Boolean = used
|
||||||
|
|
||||||
/**
|
def Down: Option[KnapsackNode] = down
|
||||||
* Initialize the `down` and `right` children of this node.
|
|
||||||
*/
|
def Right: Option[KnapsackNode] = right
|
||||||
def Split(): Unit = {
|
|
||||||
used = true
|
|
||||||
down = Some(new KnapsackNode(0, 0, 0, 0))
|
|
||||||
right = Some(new KnapsackNode(0, 0, 0, 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the dimensions of the node.<br>
|
* Initialize the `down` and `right` children of this node.
|
||||||
* <br>
|
* @param insertDown new "down" knapsack division
|
||||||
* Use: `{node}(nx, ny, nw, nh)`
|
* @param insertRight new "right" knapsack division
|
||||||
* @param nx the new x-coordinate, upper left corner
|
*/
|
||||||
* @param ny the new y-coordinate, upper left corner
|
def Split(insertDown: KnapsackNode, insertRight: KnapsackNode): Unit = {
|
||||||
* @param nw the new width
|
used = true
|
||||||
* @param nh the new height
|
down = Some(insertDown)
|
||||||
*/
|
right = Some(insertRight)
|
||||||
def apply(nx: Int, ny: Int, nw: Int, nh: Int): Unit = {
|
|
||||||
x = nx
|
|
||||||
y = ny
|
|
||||||
width = nw
|
|
||||||
height = nh
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -768,7 +761,7 @@ object GridInventory {
|
||||||
*/
|
*/
|
||||||
private def findKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Option[KnapsackNode] = {
|
private def findKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Option[KnapsackNode] = {
|
||||||
if (node.Used) {
|
if (node.Used) {
|
||||||
findKnapsackSpace(node.right.get, width, height).orElse(findKnapsackSpace(node.down.get, width, height))
|
findKnapsackSpace(node.Right.get, width, height).orElse(findKnapsackSpace(node.Down.get, width, height))
|
||||||
} else if (width <= node.width && height <= node.height) {
|
} else if (width <= node.width && height <= node.height) {
|
||||||
Some(node)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -787,13 +780,14 @@ object GridInventory {
|
||||||
* @param height height of the element
|
* @param height height of the element
|
||||||
*/
|
*/
|
||||||
private def splitKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Unit = {
|
private def splitKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Unit = {
|
||||||
node.Split()
|
node.Split(
|
||||||
node.down.get(node.x, node.y + height, node.width, node.height - height)
|
new KnapsackNode(node.x, node.y + height, node.width, node.height - height),
|
||||||
node.right.get(node.x + width, node.y, node.width - width, height)
|
new KnapsackNode(node.x + width, node.y, node.width - width, height)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def toPrintedList(inv: GridInventory): String = {
|
def toPrintedList(inv: GridInventory): String = {
|
||||||
val list = new StringBuilder
|
val list = new mutable.StringBuilder
|
||||||
list.append("\n")
|
list.append("\n")
|
||||||
inv.Items.zipWithIndex.foreach {
|
inv.Items.zipWithIndex.foreach {
|
||||||
case (InventoryItem(obj, start), index) =>
|
case (InventoryItem(obj, start), index) =>
|
||||||
|
|
@ -803,6 +797,6 @@ object GridInventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
def toPrintedGrid(inv: GridInventory): String = {
|
def toPrintedGrid(inv: GridInventory): String = {
|
||||||
new StringBuilder().append("\n").append(inv.grid.toSeq.grouped(inv.width).mkString("\n")).toString
|
new mutable.StringBuilder().append("\n").append(inv.grid.toSeq.grouped(inv.width).mkString("\n")).toString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import net.psforever.types.Vector3
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse}
|
import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse}
|
||||||
import net.psforever.services.base.support.SupportActor
|
import net.psforever.services.base.support.SupportActor
|
||||||
import net.psforever.services.vehicle.support.TurretUpgrader
|
import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader}
|
||||||
import net.psforever.services.vehicle.{TurretMessage, VehicleServiceMessage}
|
import net.psforever.services.vehicle.VehicleServiceMessage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects.
|
* The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects.
|
||||||
|
|
@ -138,8 +138,8 @@ object DamageableWeaponTurret {
|
||||||
case turret: WeaponTurret =>
|
case turret: WeaponTurret =>
|
||||||
if (turret.Upgrade != TurretUpgrade.None) {
|
if (turret.Upgrade != TurretUpgrade.None) {
|
||||||
val vehicleEvents = zone.VehicleEvents
|
val vehicleEvents = zone.VehicleEvents
|
||||||
vehicleEvents ! TurretMessage(SupportActor.ClearSpecific(List(turret), zone))
|
vehicleEvents ! TurretEnvelope(SupportActor.ClearSpecific(List(turret), zone))
|
||||||
vehicleEvents ! TurretMessage(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None))
|
vehicleEvents ! TurretEnvelope(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None))
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import net.psforever.objects.serverobject.locks.IFFLock
|
||||||
import net.psforever.objects.serverobject.structures.PoweredAmenityControl
|
import net.psforever.objects.serverobject.structures.PoweredAmenityControl
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.base.support.SupportActor
|
import net.psforever.services.base.support.SupportActor
|
||||||
import net.psforever.services.local.support.DoorCloseActor
|
import net.psforever.services.local.support.{DoorCloseActor, DoorMessage}
|
||||||
import net.psforever.services.local.{DoorMessage, LocalAction, LocalServiceResponse}
|
import net.psforever.services.local.{LocalAction, LocalServiceResponse}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `Door`.
|
* An `Actor` that handles messages being dispatched to a specific `Door`.
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackS
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
import net.psforever.services.base.message.SendResponse
|
import net.psforever.services.base.message.SendResponse
|
||||||
import net.psforever.services.local.support.HackClearActor
|
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope, HackEntityEnvelope}
|
||||||
import net.psforever.services.local.{HackClearMessage, HackEntityMessage, LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
|
|
||||||
import scala.annotation.unused
|
import scala.annotation.unused
|
||||||
import scala.util.{Failure, Success}
|
import scala.util.{Failure, Success}
|
||||||
|
|
@ -177,7 +177,7 @@ object GenericHackables {
|
||||||
LocalAction.TriggerSound(target.HackSound, tplayer.Position, 30, 0.49803925f)
|
LocalAction.TriggerSound(target.HackSound, tplayer.Position, 30, 0.49803925f)
|
||||||
)
|
)
|
||||||
val duration = target.HackEffectDuration(user.avatar.hackingSkillLevel())
|
val duration = target.HackEffectDuration(user.avatar.hackingSkillLevel())
|
||||||
zone.LocalEvents ! HackEntityMessage(
|
zone.LocalEvents ! HackEntityEnvelope(
|
||||||
zoneId,
|
zoneId,
|
||||||
pguid,
|
pguid,
|
||||||
LocalAction.HackObject(target.GUID, hackValue, HackState7.Unk8),
|
LocalAction.HackObject(target.GUID, hackValue, HackState7.Unk8),
|
||||||
|
|
@ -206,7 +206,7 @@ object GenericHackables {
|
||||||
val currVirus = building.virusId
|
val currVirus = building.virusId
|
||||||
building.virusId = 8
|
building.virusId = 8
|
||||||
building.virusInstalledBy = None
|
building.virusInstalledBy = None
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(target))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(target))
|
||||||
zone.LocalEvents ! LocalServiceMessage(
|
zone.LocalEvents ! LocalServiceMessage(
|
||||||
zone.id,
|
zone.id,
|
||||||
SendResponse(GenericObjectActionMessage(target.GUID, 60))
|
SendResponse(GenericObjectActionMessage(target.GUID, 60))
|
||||||
|
|
@ -214,11 +214,11 @@ object GenericHackables {
|
||||||
currVirus match {
|
currVirus match {
|
||||||
case 0L =>
|
case 0L =>
|
||||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff =>
|
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff =>
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(iff))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(iff))
|
||||||
}
|
}
|
||||||
case 4L =>
|
case 4L =>
|
||||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term =>
|
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term =>
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||||
}
|
}
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
|
|
@ -232,13 +232,13 @@ object GenericHackables {
|
||||||
case 0L =>
|
case 0L =>
|
||||||
if (virus != 0) {
|
if (virus != 0) {
|
||||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff =>
|
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff =>
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(iff))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(iff))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 4L =>
|
case 4L =>
|
||||||
if (virus != 4) {
|
if (virus != 4) {
|
||||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term =>
|
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term =>
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case _ => ()
|
case _ => ()
|
||||||
|
|
@ -266,7 +266,7 @@ object GenericHackables {
|
||||||
pguid,
|
pguid,
|
||||||
LocalAction.TriggerSound(TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f)
|
LocalAction.TriggerSound(TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f)
|
||||||
)
|
)
|
||||||
zone.LocalEvents ! HackEntityMessage(
|
zone.LocalEvents ! HackEntityEnvelope(
|
||||||
zoneId,
|
zoneId,
|
||||||
pguid,
|
pguid,
|
||||||
LocalAction.HackObject(target.GUID, installedVirusDuration.toLong, hackState),
|
LocalAction.HackObject(target.GUID, installedVirusDuration.toLong, hackState),
|
||||||
|
|
@ -285,7 +285,7 @@ object GenericHackables {
|
||||||
case 0L =>
|
case 0L =>
|
||||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach{ iff =>
|
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach{ iff =>
|
||||||
iff.HackedBy = tplayer
|
iff.HackedBy = tplayer
|
||||||
zone.LocalEvents ! HackEntityMessage(
|
zone.LocalEvents ! HackEntityEnvelope(
|
||||||
zoneId,
|
zoneId,
|
||||||
pguid,
|
pguid,
|
||||||
LocalAction.HackObject(target.GUID, hackValue.toLong, HackState7.Unk8),
|
LocalAction.HackObject(target.GUID, hackValue.toLong, HackState7.Unk8),
|
||||||
|
|
@ -295,7 +295,7 @@ object GenericHackables {
|
||||||
case 4L =>
|
case 4L =>
|
||||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach{ term =>
|
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach{ term =>
|
||||||
term.HackedBy = tplayer
|
term.HackedBy = tplayer
|
||||||
zone.LocalEvents ! HackEntityMessage(
|
zone.LocalEvents ! HackEntityEnvelope(
|
||||||
zoneId,
|
zoneId,
|
||||||
pguid,
|
pguid,
|
||||||
LocalAction.HackObject(term.GUID, hackValue.toLong, HackState7.Unk8),
|
LocalAction.HackObject(term.GUID, hackValue.toLong, HackState7.Unk8),
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
// Copyright (c) 2020 PSForever
|
// Copyright (c) 2020 PSForever
|
||||||
package net.psforever.objects.serverobject.locks
|
package net.psforever.objects.serverobject.locks
|
||||||
|
|
||||||
import net.psforever.services.local.support.HackClearActor
|
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||||
import net.psforever.services.local.HackClearMessage
|
|
||||||
|
|
||||||
object IFFLocks {
|
object IFFLocks {
|
||||||
|
|
||||||
|
|
@ -14,6 +13,6 @@ object IFFLocks {
|
||||||
*/
|
*/
|
||||||
def FinishResecuringIFFLock(lock: IFFLock)(): Unit = {
|
def FinishResecuringIFFLock(lock: IFFLock)(): Unit = {
|
||||||
val zone = lock.Zone
|
val zone = lock.Zone
|
||||||
lock.Zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(lock))
|
lock.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(lock))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@ import net.psforever.packet.game.ChatMsg
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
import net.psforever.services.base.message.SendResponse
|
import net.psforever.services.base.message.SendResponse
|
||||||
import net.psforever.services.base.support.SupportActor
|
import net.psforever.services.base.support.SupportActor
|
||||||
import net.psforever.services.local.{DoorMessage, LocalAction}
|
import net.psforever.services.local.LocalAction
|
||||||
import net.psforever.services.hart.{HartTimer, HartTimerActions}
|
import net.psforever.services.hart.{HartTimer, HartTimerActions}
|
||||||
|
import net.psforever.services.local.support.DoorMessage
|
||||||
import net.psforever.services.{Service, ServiceManager}
|
import net.psforever.services.{Service, ServiceManager}
|
||||||
import net.psforever.types.ChatMessageType
|
import net.psforever.types.ChatMessageType
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,7 @@ import net.psforever.objects.sourcing.AmenitySource
|
||||||
import net.psforever.objects.vital.interaction.DamageResult
|
import net.psforever.objects.vital.interaction.DamageResult
|
||||||
import net.psforever.packet.game.HackState1
|
import net.psforever.packet.game.HackState1
|
||||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||||
import net.psforever.services.local.HackClearMessage
|
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||||
import net.psforever.services.local.support.HackClearActor
|
|
||||||
import org.log4s.Logger
|
import org.log4s.Logger
|
||||||
|
|
||||||
import scala.annotation.unused
|
import scala.annotation.unused
|
||||||
|
|
@ -149,7 +148,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit)
|
||||||
tryAutoRepair()
|
tryAutoRepair()
|
||||||
if (term.HackedBy.nonEmpty) {
|
if (term.HackedBy.nonEmpty) {
|
||||||
val zone = term.Zone
|
val zone = term.Zone
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||||
}
|
}
|
||||||
super.DestructionAwareness(target, cause)
|
super.DestructionAwareness(target, cause)
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +225,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit)
|
||||||
//clear hack state
|
//clear hack state
|
||||||
if (term.HackedBy.nonEmpty) {
|
if (term.HackedBy.nonEmpty) {
|
||||||
val zone = term.Zone
|
val zone = term.Zone
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableA
|
||||||
import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl}
|
import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl}
|
||||||
import net.psforever.objects.vital.interaction.DamageResult
|
import net.psforever.objects.vital.interaction.DamageResult
|
||||||
import net.psforever.packet.game.HackState1
|
import net.psforever.packet.game.HackState1
|
||||||
import net.psforever.services.local.support.HackClearActor
|
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||||
import net.psforever.services.local.HackClearMessage
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `Terminal`.
|
* An `Actor` that handles messages being dispatched to a specific `Terminal`.
|
||||||
|
|
@ -100,7 +99,7 @@ class TerminalControl(term: Terminal)
|
||||||
tryAutoRepair()
|
tryAutoRepair()
|
||||||
if (term.HackedBy.nonEmpty) {
|
if (term.HackedBy.nonEmpty) {
|
||||||
val zone = term.Zone
|
val zone = term.Zone
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||||
}
|
}
|
||||||
super.DestructionAwareness(target, cause)
|
super.DestructionAwareness(target, cause)
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +121,7 @@ class TerminalControl(term: Terminal)
|
||||||
//clear hack state
|
//clear hack state
|
||||||
if (term.HackedBy.nonEmpty) {
|
if (term.HackedBy.nonEmpty) {
|
||||||
val zone = term.Zone
|
val zone = term.Zone
|
||||||
zone.LocalEvents ! HackClearMessage(HackClearActor.ObjectIsResecured(term))
|
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,10 @@ import net.psforever.objects.serverobject.hackable.GenericHackables
|
||||||
import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate}
|
import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate}
|
||||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||||
import net.psforever.objects.sourcing.PlayerSource
|
import net.psforever.objects.sourcing.PlayerSource
|
||||||
import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.types.PlanetSideEmpire
|
|
||||||
import net.psforever.services.local.support.HackCaptureActor
|
import net.psforever.services.local.support.HackCaptureActor
|
||||||
|
import net.psforever.services.local.support.CaptureEnvelope
|
||||||
|
import net.psforever.types.PlanetSideEmpire
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.util.{Failure, Success}
|
import scala.util.{Failure, Success}
|
||||||
|
|
@ -47,10 +48,10 @@ object CaptureTerminals {
|
||||||
)
|
)
|
||||||
if (isResecured) {
|
if (isResecured) {
|
||||||
// Resecure the CC
|
// Resecure the CC
|
||||||
events ! CaptureMessage(HackCaptureActor.ResecureCaptureTerminal(target, zone, PlayerSource(hackingPlayer)))
|
events ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(target, zone, PlayerSource(hackingPlayer)))
|
||||||
} else {
|
} else {
|
||||||
// Start the CC hack timer
|
// Start the CC hack timer
|
||||||
events ! CaptureMessage(HackCaptureActor.StartCaptureTerminalHack(target, zone, 0, 8L))
|
events ! CaptureEnvelope(HackCaptureActor.StartCaptureTerminalHack(target, zone, 0, 8L))
|
||||||
}
|
}
|
||||||
case Failure(_) =>
|
case Failure(_) =>
|
||||||
log.warn(s"Hack message failed on target guid: ${target.GUID}")
|
log.warn(s"Hack message failed on target guid: ${target.GUID}")
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
import net.psforever.services.base.message.{SendResponse, SetEmpire}
|
import net.psforever.services.base.message.{SendResponse, SetEmpire}
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.services.vehicle.support.TurretUpgrader
|
import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader}
|
||||||
import net.psforever.services.vehicle.{TurretMessage, VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
object WeaponTurrets {
|
object WeaponTurrets {
|
||||||
|
|
@ -53,8 +53,8 @@ object WeaponTurrets {
|
||||||
log.info(s"Manned wall turret weapon being converted to $upgrade")
|
log.info(s"Manned wall turret weapon being converted to $upgrade")
|
||||||
val zone = target.Zone
|
val zone = target.Zone
|
||||||
val events = zone.VehicleEvents
|
val events = zone.VehicleEvents
|
||||||
events ! TurretMessage(TurretUpgrader.ClearSpecific(List(target), zone))
|
events ! TurretEnvelope(TurretUpgrader.ClearSpecific(List(target), zone))
|
||||||
events ! TurretMessage(TurretUpgrader.AddTask(target, zone, upgrade))
|
events ! TurretEnvelope(TurretUpgrader.AddTask(target, zone, upgrade))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1571,6 +1571,17 @@ object Zone {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def AmsSpawnPoints(zone: Zone): List[SpawnTube] = {
|
||||||
|
import net.psforever.objects.vehicles.UtilityType
|
||||||
|
import net.psforever.objects.GlobalDefinitions
|
||||||
|
zone.Vehicles
|
||||||
|
.filter(veh =>
|
||||||
|
veh.Health > 0 && veh.Definition == GlobalDefinitions.ams && veh.DeploymentState == DriveState.Deployed
|
||||||
|
)
|
||||||
|
.flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube))
|
||||||
|
.map(util => util().asInstanceOf[SpawnTube])
|
||||||
|
}
|
||||||
|
|
||||||
object Setup {
|
object Setup {
|
||||||
/* zone setup code */
|
/* zone setup code */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,9 @@ package net.psforever.objects.zones
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.actors.zone.ZoneActor
|
import net.psforever.actors.zone.ZoneActor
|
||||||
import net.psforever.objects.equipment.Equipment
|
import net.psforever.objects.equipment.Equipment
|
||||||
|
import net.psforever.services.avatar.support.{DropItemEnvelope, PickupItemEnvelope}
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
import net.psforever.services.avatar.{AvatarAction, DropItemMessage, PickupItemMessage}
|
import net.psforever.services.avatar.AvatarAction
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
@ -30,7 +31,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte
|
||||||
equipmentOnGround += item
|
equipmentOnGround += item
|
||||||
item.Position = pos
|
item.Position = pos
|
||||||
item.Orientation = orient
|
item.Orientation = orient
|
||||||
zone.AvatarEvents ! DropItemMessage(zone.id, AvatarAction.DropItem(item), zone)
|
zone.AvatarEvents ! DropItemEnvelope(zone.id, AvatarAction.DropItem(item), zone)
|
||||||
zone.actor ! ZoneActor.AddToBlockMap(item, pos)
|
zone.actor ! ZoneActor.AddToBlockMap(item, pos)
|
||||||
Zone.Ground.ItemOnGround(item, pos, orient)
|
Zone.Ground.ItemOnGround(item, pos, orient)
|
||||||
})
|
})
|
||||||
|
|
@ -38,7 +39,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte
|
||||||
case Zone.Ground.PickupItem(item_guid) =>
|
case Zone.Ground.PickupItem(item_guid) =>
|
||||||
sender() ! (FindItemOnGround(item_guid) match {
|
sender() ! (FindItemOnGround(item_guid) match {
|
||||||
case Some(item) =>
|
case Some(item) =>
|
||||||
zone.AvatarEvents ! PickupItemMessage(zone.id, AvatarAction.PickupItem(item, 0), zone)
|
zone.AvatarEvents ! PickupItemEnvelope(zone.id, AvatarAction.PickupItem(item, 0), zone)
|
||||||
zone.actor ! ZoneActor.RemoveFromBlockMap(item)
|
zone.actor ! ZoneActor.RemoveFromBlockMap(item)
|
||||||
Zone.Ground.ItemInHand(item)
|
Zone.Ground.ItemInHand(item)
|
||||||
case None =>
|
case None =>
|
||||||
|
|
@ -50,7 +51,7 @@ class ZoneGroundActor(zone: Zone, equipmentOnGround: ListBuffer[Equipment]) exte
|
||||||
FindItemOnGround(item_guid) match {
|
FindItemOnGround(item_guid) match {
|
||||||
case Some(item) =>
|
case Some(item) =>
|
||||||
zone.actor ! ZoneActor.RemoveFromBlockMap(item)
|
zone.actor ! ZoneActor.RemoveFromBlockMap(item)
|
||||||
zone.AvatarEvents ! PickupItemMessage(zone.id, AvatarAction.PickupItem(item, 0), zone)
|
zone.AvatarEvents ! PickupItemEnvelope(zone.id, AvatarAction.PickupItem(item, 0), zone)
|
||||||
case None => ;
|
case None => ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.services
|
package net.psforever.services
|
||||||
|
|
||||||
|
import akka.actor.ActorRef
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
object Service {
|
object Service {
|
||||||
|
|
@ -8,7 +9,15 @@ object Service {
|
||||||
|
|
||||||
final case class Startup()
|
final case class Startup()
|
||||||
|
|
||||||
final case class Join(channel: String)
|
final case class Join(channel: String, sendJoinConfirmation: Boolean)
|
||||||
|
|
||||||
|
object Join {
|
||||||
|
def apply(channel: String): Join = Join(channel, sendJoinConfirmation = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class JoinConfirmation(eventSystem: ActorRef, channel: String)
|
||||||
|
|
||||||
final case class Leave(channel: Option[String] = None)
|
final case class Leave(channel: Option[String] = None)
|
||||||
|
|
||||||
final case class LeaveAll()
|
final case class LeaveAll()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
// Copyright (c) 2017-2026 PSForever
|
// Copyright (c) 2017-2026 PSForever
|
||||||
package net.psforever.services.avatar
|
package net.psforever.services.avatar
|
||||||
|
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.{RemoverActor, Service}
|
|
||||||
import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem, Release}
|
|
||||||
import net.psforever.services.base.envelope.MessageEnvelope
|
import net.psforever.services.base.envelope.MessageEnvelope
|
||||||
import net.psforever.services.base.message.EventMessage
|
import net.psforever.services.base.message.EventMessage
|
||||||
import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly}
|
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
object AvatarServiceMessage {
|
object AvatarServiceMessage {
|
||||||
|
|
@ -16,69 +13,3 @@ object AvatarServiceMessage {
|
||||||
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope =
|
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope =
|
||||||
MessageEnvelope(channel, filter, msg)
|
MessageEnvelope(channel, filter, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class ReleaseMessage(
|
|
||||||
originalChannel: String,
|
|
||||||
filter: PlanetSideGUID,
|
|
||||||
msg: Release
|
|
||||||
)
|
|
||||||
extends GenericSupportEnvelope {
|
|
||||||
def supportLabel: String = "undertaker"
|
|
||||||
def supportMessage: Any = {
|
|
||||||
val Release(player, zone, time) = msg
|
|
||||||
RemoverActor.AddTask(player, zone, time)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object ReleaseMessage {
|
|
||||||
def apply(channel: String, actionMessage: Release): ReleaseMessage =
|
|
||||||
ReleaseMessage(channel, Service.defaultPlayerGUID, actionMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class PickupItemMessage(
|
|
||||||
originalChannel: String,
|
|
||||||
filter: PlanetSideGUID,
|
|
||||||
msg: PickupItem,
|
|
||||||
zone: Zone
|
|
||||||
)
|
|
||||||
extends GenericSupportEnvelope {
|
|
||||||
def supportLabel: String = "janitor"
|
|
||||||
def supportMessage: Any = {
|
|
||||||
val PickupItem(item, _) = msg
|
|
||||||
RemoverActor.ClearSpecific(List(item), zone)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object PickupItemMessage {
|
|
||||||
def apply(channel: String, actionMessage: PickupItem, zone: Zone): PickupItemMessage =
|
|
||||||
PickupItemMessage(channel, Service.defaultPlayerGUID, actionMessage, zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class DropItemMessage(
|
|
||||||
originalChannel: String,
|
|
||||||
filter: PlanetSideGUID,
|
|
||||||
msg: DropItem,
|
|
||||||
zone: Zone
|
|
||||||
)
|
|
||||||
extends GenericSupportEnvelope {
|
|
||||||
def supportLabel: String = "janitor"
|
|
||||||
def supportMessage: Any = {
|
|
||||||
val DropItem(item) = msg
|
|
||||||
RemoverActor.AddTask(item, zone)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object DropItemMessage {
|
|
||||||
def apply(channel: String, actionMessage: DropItem, zone: Zone): DropItemMessage =
|
|
||||||
DropItemMessage(channel, Service.defaultPlayerGUID, actionMessage, zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class CorpseEnvelope(supportMessage: Any)
|
|
||||||
extends GenericSupportEnvelopeOnly {
|
|
||||||
def supportLabel: String = "undertaker"
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class GroundEnvelope(supportMessage: Any)
|
|
||||||
extends GenericSupportEnvelopeOnly {
|
|
||||||
def supportLabel: String = "janitor"
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,38 @@ package net.psforever.services.avatar.support
|
||||||
|
|
||||||
import net.psforever.objects.guid.{GUIDTask, TaskBundle}
|
import net.psforever.objects.guid.{GUIDTask, TaskBundle}
|
||||||
import net.psforever.objects.Player
|
import net.psforever.objects.Player
|
||||||
import net.psforever.types.ExoSuitType
|
import net.psforever.types.{ExoSuitType, PlanetSideGUID}
|
||||||
import net.psforever.services.RemoverActor
|
import net.psforever.services.{RemoverActor, Service}
|
||||||
|
import net.psforever.services.avatar.AvatarAction.Release
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
|
import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly}
|
||||||
import net.psforever.services.base.message.ObjectDelete
|
import net.psforever.services.base.message.ObjectDelete
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
final case class ReleaseEnvelope(
|
||||||
|
originalChannel: String,
|
||||||
|
filter: PlanetSideGUID,
|
||||||
|
msg: Release
|
||||||
|
)
|
||||||
|
extends GenericSupportEnvelope {
|
||||||
|
def supportLabel: String = "undertaker"
|
||||||
|
def supportMessage: Any = {
|
||||||
|
val Release(player, zone, time) = msg
|
||||||
|
RemoverActor.AddTask(player, zone, time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ReleaseEnvelope {
|
||||||
|
def apply(channel: String, actionMessage: Release): ReleaseEnvelope =
|
||||||
|
ReleaseEnvelope(channel, Service.defaultPlayerGUID, actionMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class CorpseEnvelope(supportMessage: Any)
|
||||||
|
extends GenericSupportEnvelopeOnly {
|
||||||
|
def supportLabel: String = "undertaker"
|
||||||
|
}
|
||||||
|
|
||||||
class CorpseRemovalActor extends RemoverActor() {
|
class CorpseRemovalActor extends RemoverActor() {
|
||||||
final val FirstStandardDuration: FiniteDuration = 1 minute
|
final val FirstStandardDuration: FiniteDuration = 1 minute
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,59 @@ package net.psforever.services.avatar.support
|
||||||
|
|
||||||
import net.psforever.objects.equipment.Equipment
|
import net.psforever.objects.equipment.Equipment
|
||||||
import net.psforever.objects.guid.{GUIDTask, TaskBundle}
|
import net.psforever.objects.guid.{GUIDTask, TaskBundle}
|
||||||
import net.psforever.services.RemoverActor
|
import net.psforever.objects.zones.Zone
|
||||||
|
import net.psforever.services.avatar.AvatarAction.{DropItem, PickupItem}
|
||||||
|
import net.psforever.services.{RemoverActor, Service}
|
||||||
import net.psforever.services.avatar.AvatarServiceMessage
|
import net.psforever.services.avatar.AvatarServiceMessage
|
||||||
|
import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly}
|
||||||
import net.psforever.services.base.message.ObjectDelete
|
import net.psforever.services.base.message.ObjectDelete
|
||||||
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
final case class PickupItemEnvelope(
|
||||||
|
originalChannel: String,
|
||||||
|
filter: PlanetSideGUID,
|
||||||
|
msg: PickupItem,
|
||||||
|
zone: Zone
|
||||||
|
)
|
||||||
|
extends GenericSupportEnvelope {
|
||||||
|
def supportLabel: String = "janitor"
|
||||||
|
def supportMessage: Any = {
|
||||||
|
val PickupItem(item, _) = msg
|
||||||
|
RemoverActor.ClearSpecific(List(item), zone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object PickupItemEnvelope {
|
||||||
|
def apply(channel: String, actionMessage: PickupItem, zone: Zone): PickupItemEnvelope =
|
||||||
|
PickupItemEnvelope(channel, Service.defaultPlayerGUID, actionMessage, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class DropItemEnvelope(
|
||||||
|
originalChannel: String,
|
||||||
|
filter: PlanetSideGUID,
|
||||||
|
msg: DropItem,
|
||||||
|
zone: Zone
|
||||||
|
)
|
||||||
|
extends GenericSupportEnvelope {
|
||||||
|
def supportLabel: String = "janitor"
|
||||||
|
def supportMessage: Any = {
|
||||||
|
val DropItem(item) = msg
|
||||||
|
RemoverActor.AddTask(item, zone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object DropItemEnvelope {
|
||||||
|
def apply(channel: String, actionMessage: DropItem, zone: Zone): DropItemEnvelope =
|
||||||
|
DropItemEnvelope(channel, Service.defaultPlayerGUID, actionMessage, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class GroundEnvelope(supportMessage: Any)
|
||||||
|
extends GenericSupportEnvelopeOnly {
|
||||||
|
def supportLabel: String = "janitor"
|
||||||
|
}
|
||||||
|
|
||||||
class DroppedItemRemover extends RemoverActor() {
|
class DroppedItemRemover extends RemoverActor() {
|
||||||
final val FirstStandardDuration: FiniteDuration = 3 minutes
|
final val FirstStandardDuration: FiniteDuration = 3 minutes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import net.psforever.services.base.bus.GenericEventBus
|
||||||
import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope}
|
import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope}
|
||||||
import org.log4s.Logger
|
import org.log4s.Logger
|
||||||
|
|
||||||
import scala.annotation.unused
|
|
||||||
|
|
||||||
trait EventSystemStamp
|
trait EventSystemStamp
|
||||||
|
|
||||||
abstract class GenericEventService(stamp: EventSystemStamp)
|
abstract class GenericEventService(stamp: EventSystemStamp)
|
||||||
|
|
@ -18,7 +16,13 @@ abstract class GenericEventService(stamp: EventSystemStamp)
|
||||||
protected val eventBus: GenericEventBus = new GenericEventBus
|
protected val eventBus: GenericEventBus = new GenericEventBus
|
||||||
|
|
||||||
private def commonJoinBehavior: Receive = {
|
private def commonJoinBehavior: Receive = {
|
||||||
case Service.Join(channel) =>
|
case Service.Join(channel, true) =>
|
||||||
|
val path = formatChannel(channel)
|
||||||
|
val who = sender()
|
||||||
|
eventBus.subscribe(who, path)
|
||||||
|
who ! Service.JoinConfirmation(self, channel)
|
||||||
|
|
||||||
|
case Service.Join(channel, _) =>
|
||||||
val path = formatChannel(channel)
|
val path = formatChannel(channel)
|
||||||
val who = sender()
|
val who = sender()
|
||||||
eventBus.subscribe(who, path)
|
eventBus.subscribe(who, path)
|
||||||
|
|
@ -53,7 +57,7 @@ abstract class GenericEventService(stamp: EventSystemStamp)
|
||||||
eventBus.publish(composeResponseEnvelope(msg))
|
eventBus.publish(composeResponseEnvelope(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected def composeResponseEnvelope(@unused msg: GenericMessageEnvelope): GenericResponseEnvelope = {
|
protected def composeResponseEnvelope(msg: GenericMessageEnvelope): GenericResponseEnvelope = {
|
||||||
msg.response(stamp, formatChannel)
|
msg.response(stamp, formatChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
// Copyright (c) 2026 PSForever
|
// Copyright (c) 2026 PSForever
|
||||||
package net.psforever.services.base
|
package net.psforever.services.base
|
||||||
|
|
||||||
|
import akka.actor.Cancellable
|
||||||
|
import net.psforever.objects.Default
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.base.envelope.{GenericMessageEnvelope, MessageEnvelope, MessageTransformationBehavior}
|
import net.psforever.services.base.envelope.{GenericMessageEnvelope, GenericResponseEnvelope, MessageEnvelope, MessageTransformationBehavior}
|
||||||
import net.psforever.services.base.message.EventMessage
|
import net.psforever.services.base.message.EventMessage
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
import scala.collection.concurrent.{Map => CMap}
|
import scala.collection.concurrent.{Map => CMap}
|
||||||
import scala.jdk.CollectionConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
|
import scala.concurrent.duration.DurationInt
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Adapted from the rating limiting code in https://github.com/Pinapse/giant with permission
|
Adapted from the rating limiting code in PSForever fork https://github.com/Pinapse/giant with permission
|
||||||
*/
|
*/
|
||||||
|
|
||||||
trait CachedGenericEventMessageEnvelope
|
trait CachedGenericEventMessageEnvelope
|
||||||
|
|
@ -19,26 +23,42 @@ trait CachedGenericEventMessageEnvelope
|
||||||
def guid: PlanetSideGUID
|
def guid: PlanetSideGUID
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class CachedMessage(
|
final case class CachedEnvelope(
|
||||||
guid: PlanetSideGUID,
|
guid: PlanetSideGUID,
|
||||||
originalChannel: String,
|
originalChannel: String,
|
||||||
override val filter: PlanetSideGUID,
|
override val filter: PlanetSideGUID,
|
||||||
override val msg: EventMessage
|
override val msg: EventMessage
|
||||||
) extends CachedGenericEventMessageEnvelope {
|
) extends CachedGenericEventMessageEnvelope {
|
||||||
assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID")
|
assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID")
|
||||||
}
|
}
|
||||||
|
|
||||||
object CachedMessage {
|
object CachedEnvelope {
|
||||||
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = {
|
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): GenericMessageEnvelope = {
|
||||||
if (filter == Service.defaultPlayerGUID) {
|
if (filter == Service.defaultPlayerGUID) {
|
||||||
|
org.log4s.getLogger("CachedEnvelope").warn("(1) cached message envelope downgraded to normal message envelope")
|
||||||
MessageEnvelope(channel, filter, msg)
|
MessageEnvelope(channel, filter, msg)
|
||||||
} else {
|
} else {
|
||||||
CachedMessage(filter, channel, filter, msg)
|
CachedEnvelope(filter, channel, filter, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def apply(guid: PlanetSideGUID, channel: String, msg: EventMessage): GenericMessageEnvelope = {
|
||||||
|
if (guid == Service.defaultPlayerGUID) {
|
||||||
|
org.log4s.getLogger("CachedEnvelope").warn("(2) cached message envelope downgraded to normal message envelope")
|
||||||
|
MessageEnvelope(channel, guid, msg)
|
||||||
|
} else {
|
||||||
|
CachedEnvelope(guid, channel, guid, msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private case object FlushCachedMessages
|
private case object FlushCachedMessages extends GenericMessageEnvelope {
|
||||||
|
def originalChannel: String = ""
|
||||||
|
def msg: EventMessage = NoMessage
|
||||||
|
def response(stamp: EventSystemStamp, sendToChannel: String => String): GenericResponseEnvelope = NoResponseEnvelope
|
||||||
|
def channel: String = ""
|
||||||
|
def filter: PlanetSideGUID = Service.defaultPlayerGUID
|
||||||
|
}
|
||||||
|
|
||||||
abstract class GenericEventServiceWithCacheAndSupport
|
abstract class GenericEventServiceWithCacheAndSupport
|
||||||
(
|
(
|
||||||
|
|
@ -48,6 +68,8 @@ abstract class GenericEventServiceWithCacheAndSupport
|
||||||
private val flushCacheWait: Long = 50 //milliseconds
|
private val flushCacheWait: Long = 50 //milliseconds
|
||||||
private var hasCachedMessages: Boolean = false
|
private var hasCachedMessages: Boolean = false
|
||||||
private var nextTimeToFlushCache: Long = 0L
|
private var nextTimeToFlushCache: Long = 0L
|
||||||
|
private var emergencyFlush: Cancellable = Default.Cancellable
|
||||||
|
|
||||||
private val cache: CMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]] =
|
private val cache: CMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]] =
|
||||||
new ConcurrentHashMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]]().asScala
|
new ConcurrentHashMap[String, CMap[String, CMap[PlanetSideGUID, GenericMessageEnvelope]]]().asScala
|
||||||
|
|
||||||
|
|
@ -60,6 +82,7 @@ abstract class GenericEventServiceWithCacheAndSupport
|
||||||
if (!hasCachedMessages) {
|
if (!hasCachedMessages) {
|
||||||
hasCachedMessages = true
|
hasCachedMessages = true
|
||||||
nextTimeToFlushCache = System.currentTimeMillis() + flushCacheWait
|
nextTimeToFlushCache = System.currentTimeMillis() + flushCacheWait
|
||||||
|
emergencyFlush = context.system.scheduler.scheduleOnce(55 milliseconds, self, FlushCachedMessages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,12 +111,16 @@ abstract class GenericEventServiceWithCacheAndSupport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hasCachedMessages = false
|
hasCachedMessages = false
|
||||||
|
emergencyFlush.cancel()
|
||||||
|
emergencyFlush = Default.Cancellable
|
||||||
}
|
}
|
||||||
|
|
||||||
override protected def handleMessage(event: GenericMessageEnvelope): Unit = {
|
override protected def handleMessage(event: GenericMessageEnvelope): Unit = {
|
||||||
event match {
|
event match {
|
||||||
case envelope: CachedGenericEventMessageEnvelope =>
|
case envelope: CachedGenericEventMessageEnvelope =>
|
||||||
pushToCache(envelope)
|
pushToCache(envelope)
|
||||||
|
case FlushCachedMessages =>
|
||||||
|
tryFlushCache()
|
||||||
case _ =>
|
case _ =>
|
||||||
super.handleMessage(event)
|
super.handleMessage(event)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ trait EventServiceSupport {
|
||||||
def constructor(@unused context: ActorContext): ActorRef
|
def constructor(@unused context: ActorContext): ActorRef
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait GenericMessageToSupport {
|
trait GenericMessageToSupport {
|
||||||
def supportLabel: String
|
def supportLabel: String
|
||||||
def supportMessage: Any
|
def supportMessage: Any
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
|
||||||
import net.psforever.objects.vehicles.Utility
|
import net.psforever.objects.vehicles.Utility
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.game.{DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound}
|
import net.psforever.packet.game.{DeployableInfo, DeploymentAction, GenericAction, HackState7, ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation, TriggeredSound}
|
||||||
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent, SendResponse}
|
import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent, SendResponse}
|
||||||
import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent
|
import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent
|
||||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||||
|
|
@ -126,7 +127,7 @@ object LocalAction {
|
||||||
orient: Vector3
|
orient: Vector3
|
||||||
) extends EventMessage {
|
) extends EventMessage {
|
||||||
def response(): EventResponse = {
|
def response(): EventResponse = {
|
||||||
TriggerEffectAtLocation(PlanetSideGUID(0), effect, None, Some(TriggeredEffectLocation(pos, orient)))
|
TriggerEffectAtLocation(Service.defaultPlayerGUID, effect, None, Some(TriggeredEffectLocation(pos, orient)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ package net.psforever.services.local
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.base.envelope.MessageEnvelope
|
import net.psforever.services.base.envelope.MessageEnvelope
|
||||||
import net.psforever.services.base.message.EventMessage
|
import net.psforever.services.base.message.EventMessage
|
||||||
import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly}
|
|
||||||
import net.psforever.services.local.LocalAction.{IsADoorMessage, IsAHackMessage}
|
|
||||||
import net.psforever.services.local.support.CaptureFlagManager
|
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
object LocalServiceMessage {
|
object LocalServiceMessage {
|
||||||
|
|
@ -16,36 +13,3 @@ object LocalServiceMessage {
|
||||||
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope =
|
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope =
|
||||||
MessageEnvelope(channel, filter, msg)
|
MessageEnvelope(channel, filter, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class DoorMessage(
|
|
||||||
originalChannel: String,
|
|
||||||
msg: IsADoorMessage,
|
|
||||||
supportMessage: Any
|
|
||||||
) extends GenericSupportEnvelope {
|
|
||||||
def filter: PlanetSideGUID = Service.defaultPlayerGUID
|
|
||||||
def supportLabel: String = "doorCloser"
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class HackEntityMessage(
|
|
||||||
originalChannel: String,
|
|
||||||
filter: PlanetSideGUID,
|
|
||||||
msg: IsAHackMessage,
|
|
||||||
supportMessage: Any
|
|
||||||
) extends GenericSupportEnvelope {
|
|
||||||
def supportLabel: String = "hackClearer"
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class HackClearMessage(supportMessage: Any)
|
|
||||||
extends GenericSupportEnvelopeOnly {
|
|
||||||
def supportLabel: String = "hackClearer"
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class CaptureMessage(supportMessage: Any)
|
|
||||||
extends GenericSupportEnvelopeOnly {
|
|
||||||
def supportLabel: String = "hackCapturer"
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class FlagMessage(supportMessage: CaptureFlagManager.Command)
|
|
||||||
extends GenericSupportEnvelopeOnly {
|
|
||||||
def supportLabel: String = "captureFlagManager"
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,19 @@ import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
import net.psforever.services.ServiceManager
|
import net.psforever.services.ServiceManager
|
||||||
import net.psforever.services.ServiceManager.{Lookup, LookupResult}
|
import net.psforever.services.ServiceManager.{Lookup, LookupResult}
|
||||||
|
import net.psforever.services.base.GenericSupportEnvelopeOnly
|
||||||
import net.psforever.services.base.message.{GenericObjectAction, SendResponse}
|
import net.psforever.services.base.message.{GenericObjectAction, SendResponse}
|
||||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||||
import net.psforever.services.local.{CaptureMessage, LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
|
|
||||||
import scala.concurrent.duration.DurationInt
|
import scala.concurrent.duration.DurationInt
|
||||||
|
|
||||||
|
final case class FlagEnvelope(supportMessage: CaptureFlagManager.Command)
|
||||||
|
extends GenericSupportEnvelopeOnly {
|
||||||
|
def supportLabel: String = "captureFlagManager"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for handling capture flag related lifecycles
|
* Responsible for handling capture flag related lifecycles
|
||||||
*/
|
*/
|
||||||
|
|
@ -303,7 +309,7 @@ object CaptureFlagManager {
|
||||||
if LoseFlagViolentlyToEnvironment(target, Set(EnvironmentAttribute.Water, EnvironmentAttribute.Lava, EnvironmentAttribute.Death)) /*||
|
if LoseFlagViolentlyToEnvironment(target, Set(EnvironmentAttribute.Water, EnvironmentAttribute.Lava, EnvironmentAttribute.Death)) /*||
|
||||||
LoseFlagViolentlyToWarpGateEnvelope(zone, target)*/ =>
|
LoseFlagViolentlyToWarpGateEnvelope(zone, target)*/ =>
|
||||||
flag.Destroyed = true
|
flag.Destroyed = true
|
||||||
zone.LocalEvents ! CaptureMessage(HackCaptureActor.FlagLost(flag))
|
zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.FlagLost(flag))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
.getOrElse(false)
|
.getOrElse(false)
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,24 @@ import akka.actor.{Actor, Cancellable}
|
||||||
import net.psforever.objects.{Default, Doors}
|
import net.psforever.objects.{Default, Doors}
|
||||||
import net.psforever.objects.serverobject.doors.Door
|
import net.psforever.objects.serverobject.doors.Door
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.GenericSupportEnvelope
|
||||||
|
import net.psforever.services.local.LocalAction.IsADoorMessage
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
final case class DoorMessage(
|
||||||
|
originalChannel: String,
|
||||||
|
msg: IsADoorMessage,
|
||||||
|
supportMessage: Any
|
||||||
|
) extends GenericSupportEnvelope {
|
||||||
|
def filter: PlanetSideGUID = Service.defaultPlayerGUID
|
||||||
|
def supportLabel: String = "doorCloser"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close an opened door after a certain amount of time has passed.
|
* Close an opened door after a certain amount of time has passed.
|
||||||
* This `Actor` is intended to sit on top of the event system that handles broadcast messaging regarding doors opening.
|
* This `Actor` is intended to sit on top of the event system that handles broadcast messaging regarding doors opening.
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,10 @@ import net.psforever.objects.Default
|
||||||
import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation
|
import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation
|
||||||
import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum}
|
import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum}
|
||||||
import net.psforever.objects.sourcing.PlayerSource
|
import net.psforever.objects.sourcing.PlayerSource
|
||||||
|
import net.psforever.services.base.GenericSupportEnvelopeOnly
|
||||||
import net.psforever.services.base.message.PlanetsideAttribute
|
import net.psforever.services.base.message.PlanetsideAttribute
|
||||||
import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction
|
import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction
|
||||||
import net.psforever.services.local.{FlagMessage, LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID}
|
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID}
|
||||||
|
|
||||||
import java.util.concurrent.{Executors, TimeUnit}
|
import java.util.concurrent.{Executors, TimeUnit}
|
||||||
|
|
@ -23,6 +24,11 @@ import scala.collection.Seq
|
||||||
import scala.concurrent.duration.{FiniteDuration, _}
|
import scala.concurrent.duration.{FiniteDuration, _}
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
|
||||||
|
final case class CaptureEnvelope(supportMessage: Any)
|
||||||
|
extends GenericSupportEnvelopeOnly {
|
||||||
|
def supportLabel: String = "hackCapturer"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for handling the aspects related to hacking control consoles and capturing bases.
|
* Responsible for handling the aspects related to hacking control consoles and capturing bases.
|
||||||
*/
|
*/
|
||||||
|
|
@ -168,7 +174,7 @@ class HackCaptureActor extends Actor {
|
||||||
if (found.isEmpty) {
|
if (found.isEmpty) {
|
||||||
log.warn(s"FlagLost: flag data does not match to an entry in the hacked objects list")
|
log.warn(s"FlagLost: flag data does not match to an entry in the hacked objects list")
|
||||||
}
|
}
|
||||||
owner.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.FlagLost))
|
owner.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.FlagLost))
|
||||||
|
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +196,7 @@ class HackCaptureActor extends Actor {
|
||||||
true
|
true
|
||||||
case Some((owner, Some(flag), Some(neighbours))) if neighbours.nonEmpty && hackingFaction != flag.Faction =>
|
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}")
|
log.info(s"$hackingFaction is overriding the ongoing LLU hack of facility ${owner.Name} by ${flag.Faction}")
|
||||||
terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended))
|
terminal.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended))
|
||||||
NotifyHackStateChange(terminal, isResecured = false)
|
NotifyHackStateChange(terminal, isResecured = false)
|
||||||
RestartTimer()
|
RestartTimer()
|
||||||
spawnCaptureFlag(neighbours, terminal, hackingFaction)
|
spawnCaptureFlag(neighbours, terminal, hackingFaction)
|
||||||
|
|
@ -204,7 +210,7 @@ class HackCaptureActor extends Actor {
|
||||||
case Some((owner, Some(flag), _)) =>
|
case Some((owner, Some(flag), _)) =>
|
||||||
log.warn(s"TrySpawnCaptureFlag: couldn't find any neighbouring $hackingFaction facilities of ${owner.Name} for LLU hack")
|
log.warn(s"TrySpawnCaptureFlag: couldn't find any neighbouring $hackingFaction facilities of ${owner.Name} for LLU hack")
|
||||||
owner.GetFlagSocket.foreach { _.clearOldFlagData() }
|
owner.GetFlagSocket.foreach { _.clearOldFlagData() }
|
||||||
terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended))
|
terminal.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Ended))
|
||||||
false
|
false
|
||||||
case _ =>
|
case _ =>
|
||||||
log.error(s"TrySpawnCaptureFlag: expecting a terminal ${terminal.GUID.guid} with the ctf owning facility")
|
log.error(s"TrySpawnCaptureFlag: expecting a terminal ${terminal.GUID.guid} with the ctf owning facility")
|
||||||
|
|
@ -220,7 +226,7 @@ class HackCaptureActor extends Actor {
|
||||||
// Find a random neighbouring base matching the hacking faction
|
// Find a random neighbouring base matching the hacking faction
|
||||||
val targetBase = neighbours.toVector((new Random).nextInt(neighbours.size))
|
val targetBase = neighbours.toVector((new Random).nextInt(neighbours.size))
|
||||||
// Request LLU is created by CaptureFlagActor via LocalService
|
// Request LLU is created by CaptureFlagActor via LocalService
|
||||||
terminal.Zone.LocalEvents ! FlagMessage(CaptureFlagManager.SpawnCaptureFlag(terminal, targetBase, hackingFaction))
|
terminal.Zone.LocalEvents ! FlagEnvelope(CaptureFlagManager.SpawnCaptureFlag(terminal, targetBase, hackingFaction))
|
||||||
}
|
}
|
||||||
|
|
||||||
private def NotifyHackStateChange(
|
private def NotifyHackStateChange(
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,29 @@ import net.psforever.objects.serverobject.hackable.Hackable
|
||||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.game.HackState7
|
import net.psforever.packet.game.HackState7
|
||||||
|
import net.psforever.services.base.{GenericSupportEnvelope, GenericSupportEnvelopeOnly}
|
||||||
import net.psforever.services.base.message.GenericObjectAction
|
import net.psforever.services.base.message.GenericObjectAction
|
||||||
|
import net.psforever.services.local.LocalAction.IsAHackMessage
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
final case class HackEntityEnvelope(
|
||||||
|
originalChannel: String,
|
||||||
|
filter: PlanetSideGUID,
|
||||||
|
msg: IsAHackMessage,
|
||||||
|
supportMessage: Any
|
||||||
|
) extends GenericSupportEnvelope {
|
||||||
|
def supportLabel: String = "hackClearer"
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class HackClearEnvelope(supportMessage: Any)
|
||||||
|
extends GenericSupportEnvelopeOnly {
|
||||||
|
def supportLabel: String = "hackClearer"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore original functionality to an object that has been hacked after a certain amount of time has passed.
|
* Restore original functionality to an object that has been hacked after a certain amount of time has passed.
|
||||||
* This `Actor` is intended to sit on top of the event system that handles broadcast messaging regarding hacking events.
|
* This `Actor` is intended to sit on top of the event system that handles broadcast messaging regarding hacking events.
|
||||||
|
|
|
||||||
|
|
@ -114,13 +114,13 @@ object VehicleAction {
|
||||||
|
|
||||||
final case class UpdateAmsSpawnPoint(zone: Zone) extends EventMessage {
|
final case class UpdateAmsSpawnPoint(zone: Zone) extends EventMessage {
|
||||||
override def response(): EventResponse = {
|
override def response(): EventResponse = {
|
||||||
VehicleAction.UpdateAmsSpawnList(AmsSpawnPoints(zone))
|
VehicleAction.UpdateAmsSpawnList(Zone.AmsSpawnPoints(zone))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class AMSDeploymentChange(zone: Zone) extends EventMessage {
|
final case class AMSDeploymentChange(zone: Zone) extends EventMessage {
|
||||||
override def response(): EventResponse = {
|
override def response(): EventResponse = {
|
||||||
VehicleAction.UpdateAmsSpawnList(AmsSpawnPoints(zone))
|
VehicleAction.UpdateAmsSpawnList(Zone.AmsSpawnPoints(zone))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,16 +140,4 @@ object VehicleAction {
|
||||||
old_inventory: List[(Equipment, PlanetSideGUID)],
|
old_inventory: List[(Equipment, PlanetSideGUID)],
|
||||||
new_inventory: List[InventoryItem]
|
new_inventory: List[InventoryItem]
|
||||||
) extends SelfRespondingEvent
|
) extends SelfRespondingEvent
|
||||||
|
|
||||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
|
||||||
private def AmsSpawnPoints(zone: Zone): List[SpawnTube] = {
|
|
||||||
import net.psforever.objects.vehicles.UtilityType
|
|
||||||
import net.psforever.objects.GlobalDefinitions
|
|
||||||
zone.Vehicles
|
|
||||||
.filter(veh =>
|
|
||||||
veh.Health > 0 && veh.Definition == GlobalDefinitions.ams && veh.DeploymentState == DriveState.Deployed
|
|
||||||
)
|
|
||||||
.flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube))
|
|
||||||
.map(util => util().asInstanceOf[SpawnTube])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package net.psforever.services.vehicle
|
||||||
|
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.base.message.EventMessage
|
import net.psforever.services.base.message.EventMessage
|
||||||
import net.psforever.services.base.GenericSupportEnvelopeOnly
|
|
||||||
import net.psforever.services.base.envelope.MessageEnvelope
|
import net.psforever.services.base.envelope.MessageEnvelope
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
|
|
@ -14,8 +13,3 @@ object VehicleServiceMessage {
|
||||||
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope =
|
def apply(channel: String, filter: PlanetSideGUID, msg: EventMessage): MessageEnvelope =
|
||||||
MessageEnvelope(channel, filter, msg)
|
MessageEnvelope(channel, filter, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class TurretMessage(supportMessage: Any)
|
|
||||||
extends GenericSupportEnvelopeOnly {
|
|
||||||
def supportLabel: String = "turretUpgrader"
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||||
import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, WeaponTurret}
|
import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, WeaponTurret}
|
||||||
import net.psforever.objects.vehicles.MountedWeapons
|
import net.psforever.objects.vehicles.MountedWeapons
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
|
import net.psforever.services.base.GenericSupportEnvelopeOnly
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
|
import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
|
|
@ -17,6 +18,11 @@ import scala.concurrent.Future
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
|
|
||||||
|
final case class TurretEnvelope(supportMessage: Any)
|
||||||
|
extends GenericSupportEnvelopeOnly {
|
||||||
|
def supportLabel: String = "turretUpgrader"
|
||||||
|
}
|
||||||
|
|
||||||
class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
|
class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
|
||||||
var task: Cancellable = Default.Cancellable
|
var task: Cancellable = Default.Cancellable
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import net.psforever.packet.game.DamageWithPositionMessage
|
||||||
import net.psforever.types._
|
import net.psforever.types._
|
||||||
import net.psforever.services.avatar.AvatarAction
|
import net.psforever.services.avatar.AvatarAction
|
||||||
import net.psforever.services.base.support.SupportActor
|
import net.psforever.services.base.support.SupportActor
|
||||||
import net.psforever.services.vehicle.TurretMessage
|
import net.psforever.services.vehicle.support.TurretEnvelope
|
||||||
import org.specs2.mutable.Specification
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -1095,12 +1095,12 @@ class DamageableWeaponTurretDestructionTest extends ActorTest {
|
||||||
assert(false, s"DamageableWeaponTurretDestructionTest-4: ${msg12_4(2)}")
|
assert(false, s"DamageableWeaponTurretDestructionTest-4: ${msg12_4(2)}")
|
||||||
}
|
}
|
||||||
msg56.head match {
|
msg56.head match {
|
||||||
case TurretMessage(SupportActor.ClearSpecific(List(t), _)) if turret eq t => ;
|
case TurretEnvelope(SupportActor.ClearSpecific(List(t), _)) if turret eq t => ;
|
||||||
case _ =>
|
case _ =>
|
||||||
assert(false, s"DamageableWeaponTurretDestructionTest-5: ${msg56.head}")
|
assert(false, s"DamageableWeaponTurretDestructionTest-5: ${msg56.head}")
|
||||||
}
|
}
|
||||||
msg56(1) match {
|
msg56(1) match {
|
||||||
case TurretMessage(TurretUpgrader.AddTask(t, _, TurretUpgrade.None, _)) if t eq turret => ()
|
case TurretEnvelope(TurretUpgrader.AddTask(t, _, TurretUpgrade.None, _)) if t eq turret => ()
|
||||||
case _ => assert(false, s"DamageableWeaponTurretDestructionTest-6: ${msg56(1)}")
|
case _ => assert(false, s"DamageableWeaponTurretDestructionTest-6: ${msg56(1)}")
|
||||||
}
|
}
|
||||||
assert(turret.Health <= turret.Definition.DamageDestroysAt)
|
assert(turret.Health <= turret.Definition.DamageDestroysAt)
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class DeploymentBehavior2Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ class DeploymentBehavior2Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +106,7 @@ class DeploymentBehavior2Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +119,7 @@ class DeploymentBehavior2Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ class DeploymentBehavior3Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deploying, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +161,7 @@ class DeploymentBehavior3Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Deployed, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +178,7 @@ class DeploymentBehavior3Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Undeploying, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +191,7 @@ class DeploymentBehavior3Test extends ActorTest {
|
||||||
case MessageEnvelope(
|
case MessageEnvelope(
|
||||||
"test",
|
"test",
|
||||||
_,
|
_,
|
||||||
VehicleAction.DeployRequest(_, PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero)
|
VehicleAction.DeployRequest(PlanetSideGUID(1), DriveState.Mobile, 0, false, Vector3.Zero)
|
||||||
) => ()
|
) => ()
|
||||||
case _ => assert(false, "")
|
case _ => assert(false, "")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ import net.psforever.objects.{Default, GlobalDefinitions, Player}
|
||||||
import net.psforever.objects.serverobject.doors.{Door, DoorControl}
|
import net.psforever.objects.serverobject.doors.{Door, DoorControl}
|
||||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||||
import net.psforever.services.local.{DoorMessage, LocalAction, LocalServiceResponse}
|
import net.psforever.services.local.support.DoorMessage
|
||||||
|
import net.psforever.services.local.{LocalAction, LocalServiceResponse}
|
||||||
import net.psforever.types._
|
import net.psforever.types._
|
||||||
import org.specs2.mutable.Specification
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -563,7 +563,7 @@ class PlayerControlDeathStandingTest extends ActorTest {
|
||||||
)
|
)
|
||||||
assert(
|
assert(
|
||||||
msg_avatar(1) match {
|
msg_avatar(1) match {
|
||||||
case MessageEnvelope("TestCharacter2", _, AvatarAction.Killed(PlanetSideGUID(2), _, None)) => true
|
case MessageEnvelope("TestCharacter2", _, AvatarAction.Killed(_, None)) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ class RepairableTurretWeapon extends ActorTest {
|
||||||
)
|
)
|
||||||
assert(
|
assert(
|
||||||
msg4 match {
|
msg4 match {
|
||||||
case MessageEnvelope("test", _, VehicleAction.EquipmentInSlot(_, PlanetSideGUID(2), 1, t))
|
case MessageEnvelope("test", _, VehicleAction.EquipmentInSlot(PlanetSideGUID(2), 1, t))
|
||||||
if t eq turretWeapon =>
|
if t eq turretWeapon =>
|
||||||
true
|
true
|
||||||
case _ => false
|
case _ => false
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ class TelepadDeployableNoRouterTest extends ActorTest {
|
||||||
"NEUTRAL",
|
"NEUTRAL",
|
||||||
_,
|
_,
|
||||||
LocalAction.DeployableMapIcon(
|
LocalAction.DeployableMapIcon(
|
||||||
PlanetSideGUID(0),
|
|
||||||
DeploymentAction.Build,
|
DeploymentAction.Build,
|
||||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
||||||
)
|
)
|
||||||
|
|
@ -75,7 +74,6 @@ class TelepadDeployableNoRouterTest extends ActorTest {
|
||||||
"NEUTRAL",
|
"NEUTRAL",
|
||||||
_,
|
_,
|
||||||
LocalAction.DeployableMapIcon(
|
LocalAction.DeployableMapIcon(
|
||||||
PlanetSideGUID(0),
|
|
||||||
DeploymentAction.Dismiss,
|
DeploymentAction.Dismiss,
|
||||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
||||||
)
|
)
|
||||||
|
|
@ -130,7 +128,6 @@ class TelepadDeployableNoActivationTest extends ActorTest {
|
||||||
"NEUTRAL",
|
"NEUTRAL",
|
||||||
_,
|
_,
|
||||||
LocalAction.DeployableMapIcon(
|
LocalAction.DeployableMapIcon(
|
||||||
PlanetSideGUID(0),
|
|
||||||
DeploymentAction.Build,
|
DeploymentAction.Build,
|
||||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
||||||
)
|
)
|
||||||
|
|
@ -147,7 +144,6 @@ class TelepadDeployableNoActivationTest extends ActorTest {
|
||||||
"NEUTRAL",
|
"NEUTRAL",
|
||||||
_,
|
_,
|
||||||
LocalAction.DeployableMapIcon(
|
LocalAction.DeployableMapIcon(
|
||||||
PlanetSideGUID(0),
|
|
||||||
DeploymentAction.Dismiss,
|
DeploymentAction.Dismiss,
|
||||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
||||||
)
|
)
|
||||||
|
|
@ -205,7 +201,6 @@ class TelepadDeployableAttemptTest extends ActorTest {
|
||||||
"NEUTRAL",
|
"NEUTRAL",
|
||||||
_,
|
_,
|
||||||
LocalAction.DeployableMapIcon(
|
LocalAction.DeployableMapIcon(
|
||||||
PlanetSideGUID(0),
|
|
||||||
DeploymentAction.Build,
|
DeploymentAction.Build,
|
||||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
||||||
)
|
)
|
||||||
|
|
@ -279,7 +274,6 @@ class TelepadDeployableResponseFromRouterTest extends FreedContextActorTest {
|
||||||
"NEUTRAL",
|
"NEUTRAL",
|
||||||
_,
|
_,
|
||||||
LocalAction.DeployableMapIcon(
|
LocalAction.DeployableMapIcon(
|
||||||
PlanetSideGUID(0),
|
|
||||||
DeploymentAction.Build,
|
DeploymentAction.Build,
|
||||||
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
DeployableInfo(PlanetSideGUID(1), DeployableIcon.RouterTelepad, Vector3.Zero, PlanetSideGUID(0))
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import net.psforever.packet.game._
|
||||||
import net.psforever.services.ServiceManager
|
import net.psforever.services.ServiceManager
|
||||||
import net.psforever.services.base.envelope.MessageEnvelope
|
import net.psforever.services.base.envelope.MessageEnvelope
|
||||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||||
import net.psforever.services.vehicle.VehicleAction
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types._
|
import net.psforever.types._
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -74,7 +74,7 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest {
|
||||||
|
|
||||||
val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds)
|
val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds)
|
||||||
vehicle_msg.head match {
|
vehicle_msg.head match {
|
||||||
case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(2), 4, true, PlanetSideGUID(1))) => ;
|
case MessageEnvelope("test", _, VehicleAction.KickPassenger(4, true, PlanetSideGUID(1))) => ;
|
||||||
case _ =>
|
case _ =>
|
||||||
assert(false, s"VehicleControlPrepareForDeletionPassengerTest: ${vehicle_msg.head}")
|
assert(false, s"VehicleControlPrepareForDeletionPassengerTest: ${vehicle_msg.head}")
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +226,7 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor
|
||||||
val vehicleMsgs = eventsProbe.receiveN(6, 10.seconds)
|
val vehicleMsgs = eventsProbe.receiveN(6, 10.seconds)
|
||||||
val cargoMsgs = cargoProbe.receiveN(1, 1.seconds)
|
val cargoMsgs = cargoProbe.receiveN(1, 1.seconds)
|
||||||
vehicleMsgs.head match {
|
vehicleMsgs.head match {
|
||||||
case MessageEnvelope("test", _, VehicleAction.KickPassenger(PlanetSideGUID(4), 4, true, PlanetSideGUID(2))) => ()
|
case MessageEnvelope("test", _, VehicleAction.KickPassenger(4, true, PlanetSideGUID(2))) => ()
|
||||||
case _ =>
|
case _ =>
|
||||||
assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-1: ${vehicleMsgs.head}")
|
assert(false, s"VehicleControlPrepareForDeletionMountedCargoTest-1: ${vehicleMsgs.head}")
|
||||||
}
|
}
|
||||||
|
|
@ -478,8 +478,8 @@ class VehicleControlShieldsChargingTest extends ActorTest {
|
||||||
vehicle.Actor ! CommonMessages.ChargeShields(15, None)
|
vehicle.Actor ! CommonMessages.ChargeShields(15, None)
|
||||||
val msg = probe.receiveOne(500 milliseconds)
|
val msg = probe.receiveOne(500 milliseconds)
|
||||||
assert(msg match {
|
assert(msg match {
|
||||||
case VehicleServiceMessage(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true
|
case MessageEnvelope(_, _, PlanetsideAttribute(PlanetSideGUID(10), 68, 15)) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
})
|
})
|
||||||
assert(vehicle.Shields == 15)
|
assert(vehicle.Shields == 15)
|
||||||
assert(vehicle.History.exists({ p => p.isInstanceOf[ShieldCharge] }))
|
assert(vehicle.History.exists({ p => p.isInstanceOf[ShieldCharge] }))
|
||||||
|
|
|
||||||
|
|
@ -1,376 +0,0 @@
|
||||||
// Copyright (c) 2017 PSForever
|
|
||||||
package service
|
|
||||||
|
|
||||||
import akka.actor.Props
|
|
||||||
import akka.testkit.TestProbe
|
|
||||||
import base.{ActorTest, FreedContextActorTest}
|
|
||||||
import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle}
|
|
||||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
|
||||||
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
|
|
||||||
import net.psforever.objects.vehicles.control.VehicleControl
|
|
||||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
|
||||||
import net.psforever.packet.game._
|
|
||||||
import net.psforever.services.base.message.{SendResponse, SetEmpire}
|
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
|
||||||
import net.psforever.services.{Service, ServiceManager}
|
|
||||||
import net.psforever.services.local._
|
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
|
||||||
|
|
||||||
class LocalService1Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"construct" in {
|
|
||||||
system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalService2Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"subscribe" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalService3Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"subscribe to a specific channel" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! Service.Leave()
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalService4Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"subscribe" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! Service.LeaveAll()
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalService5Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass an unhandled message" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! "hello"
|
|
||||||
expectNoMessage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DeployItemTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "deploy-item-test-service")
|
|
||||||
val objDef = GlobalDefinitions.motionalarmsensor
|
|
||||||
val obj = new SensorDeployable(objDef)
|
|
||||||
obj.Position = Vector3(1, 2, 3)
|
|
||||||
obj.Orientation = Vector3(4, 5, 6)
|
|
||||||
obj.GUID = PlanetSideGUID(40)
|
|
||||||
val pkt = ObjectCreateMessage(
|
|
||||||
objDef.ObjectId,
|
|
||||||
obj.GUID,
|
|
||||||
objDef.Packet.ConstructorData(obj).get
|
|
||||||
)
|
|
||||||
|
|
||||||
"AvatarService" should {
|
|
||||||
"pass DeployItem" in {
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage("test", LocalAction.DeployItem(obj))
|
|
||||||
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(0), SendResponse(Seq(pkt))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeployableMapIconTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass DeployableMapIcon" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11)))
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.DeployableMapIcon(
|
|
||||||
DeploymentAction.Build,
|
|
||||||
DeployableInfo(PlanetSideGUID(40), DeployableIcon.Boomer, Vector3(1, 2, 3), PlanetSideGUID(11))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DoorClosesTest extends FreedContextActorTest {
|
|
||||||
val probe = new TestProbe(system)
|
|
||||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
|
||||||
override def SetupNumberPools() : Unit = { }
|
|
||||||
}
|
|
||||||
zone.init(context)
|
|
||||||
expectNoMessage(500 milliseconds)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass DoorCloses" in {
|
|
||||||
zone.LocalEvents.tell(Service.Join("test"), probe.ref)
|
|
||||||
zone.LocalEvents ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.DoorCloses(PlanetSideGUID(40)))
|
|
||||||
probe.expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.DoorCloses(PlanetSideGUID(40))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HackClearTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val obj = new PlanetSideServerObject() {
|
|
||||||
def Faction = PlanetSideEmpire.NEUTRAL
|
|
||||||
def Definition = null
|
|
||||||
GUID = PlanetSideGUID(40)
|
|
||||||
}
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass HackClear" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.HackClear(obj.GUID, 0L, HackState7.Unk8))
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.HackClear(PlanetSideGUID(40), 0L, HackState7.Unk8))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProximityTerminalEffectOnTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
|
||||||
terminal.GUID = PlanetSideGUID(1)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass ProximityTerminalEffect (true)" in {
|
|
||||||
service ! Service.Join("nowhere")
|
|
||||||
service ! LocalServiceMessage("nowhere", LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), effectState = true))
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/nowhere/Local",
|
|
||||||
PlanetSideGUID(0),
|
|
||||||
LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), true)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProximityTerminalEffectOffTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
val terminal = new ProximityTerminal(GlobalDefinitions.medical_terminal)
|
|
||||||
terminal.GUID = PlanetSideGUID(1)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass ProximityTerminalEffect (false)" in {
|
|
||||||
service ! Service.Join("nowhere")
|
|
||||||
service ! LocalServiceMessage("nowhere", LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), effectState = false))
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/nowhere/Local",
|
|
||||||
PlanetSideGUID(0),
|
|
||||||
LocalAction.ProximityTerminalEffect(PlanetSideGUID(1), false)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RouterTelepadTransportTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass RouterTelepadTransport" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.RouterTelepadTransport(
|
|
||||||
PlanetSideGUID(11),
|
|
||||||
PlanetSideGUID(12),
|
|
||||||
PlanetSideGUID(13)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.RouterTelepadTransport(PlanetSideGUID(11), PlanetSideGUID(12), PlanetSideGUID(13))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SetEmpireTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val obj = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass SetEmpire" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage("test", SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR))
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(0),
|
|
||||||
SetEmpire(PlanetSideGUID(10), PlanetSideEmpire.TR)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToggleTeleportSystemTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass ToggleTeleportSystem" in {
|
|
||||||
val router = Vehicle(GlobalDefinitions.router)
|
|
||||||
router.Actor = system.actorOf(Props(classOf[VehicleControl], router), "test-router")
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage("test", PlanetSideGUID(10), LocalAction.ToggleTeleportSystem(router, None))
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalAction.ToggleTeleportSystem(router, None))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TriggerEffectTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass TriggerEffect (1)" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage("test", LocalAction.TriggerEffect("on", PlanetSideGUID(40)))
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerEffectAtLocation(PlanetSideGUID(40), "on", None, None)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TriggerEffectInfoTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass TriggerEffect (2)" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerEffectInfo(PlanetSideGUID(40), "on", true, 1000)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerEffectAtLocation(PlanetSideGUID(40), "on", Some(TriggeredEffect(true, 1000)), None)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TriggerEffectLocationTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass TriggerEffect (3)" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerEffectLocation(
|
|
||||||
"spawn_object_failed_effect",
|
|
||||||
Vector3(1.1f, 2.2f, 3.3f),
|
|
||||||
Vector3(4.4f, 5.5f, 6.6f)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerEffectAtLocation(
|
|
||||||
PlanetSideGUID(0),
|
|
||||||
"spawn_object_failed_effect",
|
|
||||||
None,
|
|
||||||
Some(TriggeredEffectLocation(Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TriggerSoundTest extends ActorTest {
|
|
||||||
import net.psforever.packet.game.TriggeredSound
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"LocalService" should {
|
|
||||||
"pass TriggerSound" in {
|
|
||||||
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! LocalServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
LocalServiceResponse(
|
|
||||||
"/test/Local",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
LocalAction.TriggerSound(TriggeredSound.LockedOut, Vector3(1.1f, 2.2f, 3.3f), 0, 0.75f)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object LocalServiceTest {
|
|
||||||
//decoy
|
|
||||||
}
|
|
||||||
|
|
@ -1,410 +0,0 @@
|
||||||
// Copyright (c) 2017 PSForever
|
|
||||||
package service
|
|
||||||
|
|
||||||
import akka.actor.Props
|
|
||||||
import base.ActorTest
|
|
||||||
import net.psforever.objects._
|
|
||||||
import net.psforever.objects.vehicles.control.VehicleControl
|
|
||||||
import net.psforever.objects.zones.Zone
|
|
||||||
import net.psforever.types.{PlanetSideGUID, _}
|
|
||||||
import net.psforever.services.{Service, ServiceManager}
|
|
||||||
import net.psforever.services.vehicle._
|
|
||||||
|
|
||||||
class VehicleService1Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"construct" in {
|
|
||||||
system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VehicleService2Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"subscribe" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VehicleService3Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"subscribe to a specific channel" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! Service.Leave()
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VehicleService4Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"subscribe" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! Service.LeaveAll()
|
|
||||||
assert(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VehicleService5Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass an unhandled message" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! "hello"
|
|
||||||
expectNoMessage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class OwnershipTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass Awareness" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11)))
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.Ownership(PlanetSideGUID(11)))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChildObjectStateTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass ChildObjectState" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.ChildObjectState(PlanetSideGUID(11), 1.2f, 3.4f)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeployRequestTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass DeployRequest" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f))
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.DeployRequest(PlanetSideGUID(11), DriveState.Mobile, 0, false, Vector3(1.2f, 3.4f, 5.6f))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DismountVehicleTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass DismountVehicle" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.DismountVehicle(BailType.Normal, false))
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.DismountVehicle(BailType.Normal, false)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InventoryStateTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val tool = Tool(GlobalDefinitions.beamer)
|
|
||||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13)
|
|
||||||
val cdata = tool.Definition.Packet.ConstructorData(tool).get
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass InventoryState" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.InventoryState(tool, PlanetSideGUID(11), 0, cdata)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.InventoryState(tool, PlanetSideGUID(11), 0, cdata)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InventoryState2Test extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val tool = Tool(GlobalDefinitions.beamer)
|
|
||||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13)
|
|
||||||
val cdata = tool.Definition.Packet.ConstructorData(tool).get
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass InventoryState2" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.InventoryState2(PlanetSideGUID(11), PlanetSideGUID(12), 13)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class KickPassengerTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass KickPassenger" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.KickPassenger(0, false, PlanetSideGUID(11))
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.KickPassenger(0, false, PlanetSideGUID(11))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadVehicleTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val vehicle = Vehicle(GlobalDefinitions.quadstealth)
|
|
||||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "test-vehicle")
|
|
||||||
val cdata = vehicle.Definition.Packet.ConstructorData(vehicle).get
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass LoadVehicle" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.LoadVehicle(vehicle, 12, PlanetSideGUID(11), cdata)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MountVehicleTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass MountVehicle" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage("test", VehicleAction.MountVehicle(PlanetSideGUID(11), 0))
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.MountVehicle(PlanetSideGUID(11), 0))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SeatPermissionsTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass SeatPermissions" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
VehicleAction.SeatPermissions(PlanetSideGUID(11), 0, 12L)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.SeatPermissions(PlanetSideGUID(11), 0, 12L)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StowEquipmentTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
val tool = Tool(GlobalDefinitions.beamer)
|
|
||||||
tool.GUID = PlanetSideGUID(12)
|
|
||||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(13)
|
|
||||||
val toolDef = tool.Definition
|
|
||||||
val cdata = tool.Definition.Packet.DetailedConstructorData(tool).get
|
|
||||||
|
|
||||||
"StowEquipment" should {
|
|
||||||
"pass StowEquipment" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.StowEquipment(PlanetSideGUID(11), 0, tool)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.StowEquipment(PlanetSideGUID(11), 0, toolDef.ObjectId, tool.GUID, cdata)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UnstowEquipmentTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass UnstowEquipment" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage("test", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11)))
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.UnstowEquipment(PlanetSideGUID(11)))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VehicleStateTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass VehicleState" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
VehicleAction.VehicleState(PlanetSideGUID(11), 0, Vector3(1.2f, 3.4f, 5.6f), Vector3(7.8f, 9.1f, 2.3f), Some(Vector3(4.5f, 6.7f, 8.9f)), Option(1), 2, 3, 4, false, true)
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.VehicleState(
|
|
||||||
PlanetSideGUID(11),
|
|
||||||
0,
|
|
||||||
Vector3(1.2f, 3.4f, 5.6f),
|
|
||||||
Vector3(7.8f, 9.1f, 2.3f),
|
|
||||||
Some(Vector3(4.5f, 6.7f, 8.9f)),
|
|
||||||
Option(1),
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TransferPassengerChannelTest extends ActorTest {
|
|
||||||
ServiceManager.boot(system)
|
|
||||||
|
|
||||||
"VehicleService" should {
|
|
||||||
"pass TransferPassengerChannel" in {
|
|
||||||
val service = system.actorOf(Props(classOf[VehicleService]), "v-service")
|
|
||||||
val fury = Vehicle(GlobalDefinitions.fury)
|
|
||||||
fury.Actor = system.actorOf(Props(classOf[VehicleControl], fury), "test-fury")
|
|
||||||
service ! Service.Join("test")
|
|
||||||
service ! VehicleServiceMessage(
|
|
||||||
"test",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11))
|
|
||||||
)
|
|
||||||
expectMsg(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
"/test/Vehicle",
|
|
||||||
PlanetSideGUID(10),
|
|
||||||
VehicleAction.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//class TransferPassengerTest extends ActorTest {
|
|
||||||
// ServiceManager.boot(system)
|
|
||||||
// "VehicleService" should {
|
|
||||||
// "pass TransferPassenger" in {
|
|
||||||
// val fury = Vehicle(GlobalDefinitions.fury)
|
|
||||||
// val service = system.actorOf(Props[VehicleService], "v-service")
|
|
||||||
// service ! Service.Join("test")
|
|
||||||
// service ! VehicleServiceMessage("test", VehicleAction.TransferPassenger(PlanetSideGUID(10), "temp_channel", fury, PlanetSideGUID(11)))
|
|
||||||
// expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleAction.TransferPassenger("temp_channel", fury, PlanetSideGUID(11))))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
object VehicleServiceTest {
|
|
||||||
//decoy
|
|
||||||
}
|
|
||||||
215
src/test/scala/service/avatar/AvatarActionTest.scala
Normal file
215
src/test/scala/service/avatar/AvatarActionTest.scala
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.avatar
|
||||||
|
|
||||||
|
import net.psforever.objects.avatar.Avatar
|
||||||
|
import net.psforever.objects.ballistics.Projectile
|
||||||
|
import net.psforever.objects.sourcing.SourceEntry
|
||||||
|
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||||
|
import net.psforever.objects.{GlobalDefinitions, Player, Tool}
|
||||||
|
import net.psforever.packet.game.ObjectCreateMessage
|
||||||
|
import net.psforever.packet.game.objectcreate.{BasicCharacterData, DroppedItemData, ObjectCreateMessageParent, PlacementData}
|
||||||
|
import net.psforever.services.avatar.AvatarAction
|
||||||
|
import net.psforever.services.base.message.ObjectDelete
|
||||||
|
import net.psforever.types._
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
object AvatarActionTest {
|
||||||
|
assert(GlobalDefinitions.suppressor != null, "missing definition - suppressor does not exist")
|
||||||
|
assert(GlobalDefinitions.avatar != null, "missing definition - avatar does not exist")
|
||||||
|
|
||||||
|
private var i: Int = 1
|
||||||
|
val testSuppressor: Tool = {
|
||||||
|
val obj = new Tool(GlobalDefinitions.suppressor)
|
||||||
|
obj.Position = Vector3(1, 2, 3)
|
||||||
|
obj.Orientation = Vector3(4, 5, 6)
|
||||||
|
obj.GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
obj.AmmoSlots.map(_.Box).foreach { box =>
|
||||||
|
box.GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
obj
|
||||||
|
}
|
||||||
|
|
||||||
|
val testPlayer: Player = {
|
||||||
|
val avatar = new Avatar(id = 1, BasicCharacterData("testPlayer", PlanetSideEmpire.TR, CharacterSex.Male, 0, CharacterVoice.Mute))
|
||||||
|
avatar.locker.GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
val obj = new Player(avatar)
|
||||||
|
obj.Position = Vector3(1, 2, 3)
|
||||||
|
obj.Orientation = Vector3(4, 5, 6)
|
||||||
|
obj.GUID = PlanetSideGUID(i)
|
||||||
|
obj.Spawn()
|
||||||
|
i += 1
|
||||||
|
obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AvatarActionTest extends Specification {
|
||||||
|
import AvatarActionTest._
|
||||||
|
|
||||||
|
"DropItem" should {
|
||||||
|
"respond" in {
|
||||||
|
val obj = testSuppressor
|
||||||
|
val msg = AvatarAction.DropItem(obj)
|
||||||
|
val definition = obj.Definition
|
||||||
|
val objectData = DroppedItemData(
|
||||||
|
PlacementData(obj.Position, obj.Orientation),
|
||||||
|
definition.Packet.ConstructorData(obj).get
|
||||||
|
)
|
||||||
|
msg.response() match {
|
||||||
|
case AvatarAction.DropCreatedItem(pkt) =>
|
||||||
|
pkt match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, _, data) =>
|
||||||
|
oid mustEqual definition.ObjectId
|
||||||
|
guid mustEqual obj.GUID
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"EquipmentInHand" should {
|
||||||
|
"respond" in {
|
||||||
|
val obj = testSuppressor
|
||||||
|
val msg = AvatarAction.EquipmentInHand(PlanetSideGUID(100), 2, obj)
|
||||||
|
val definition = obj.Definition
|
||||||
|
val objectData = definition.Packet.ConstructorData(obj).get
|
||||||
|
msg.response() match {
|
||||||
|
case AvatarAction.EquipmentCreatedInHand(pkt) =>
|
||||||
|
pkt match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, pdata, data) =>
|
||||||
|
oid mustEqual definition.ObjectId
|
||||||
|
guid mustEqual obj.GUID
|
||||||
|
pdata.contains(ObjectCreateMessageParent(PlanetSideGUID(100), 2)) mustEqual true
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"LoadPlayer (1)" should {
|
||||||
|
"respond" in {
|
||||||
|
val obj = testPlayer
|
||||||
|
val definition = obj.Definition
|
||||||
|
val id = definition.ObjectId
|
||||||
|
val guid = obj.GUID
|
||||||
|
val objectData = definition.Packet.ConstructorData(obj).get
|
||||||
|
val msg = AvatarAction.LoadPlayer(id, guid, objectData, None)
|
||||||
|
msg.response() match {
|
||||||
|
case AvatarAction.LoadCreatedPlayer(pkt) =>
|
||||||
|
pkt match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, _, data) =>
|
||||||
|
oid mustEqual id
|
||||||
|
guid mustEqual guid
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"LoadPlayer (2)" should {
|
||||||
|
"respond" in {
|
||||||
|
val obj = testPlayer
|
||||||
|
val definition = obj.Definition
|
||||||
|
val id = definition.ObjectId
|
||||||
|
val guid = obj.GUID
|
||||||
|
val parentData = ObjectCreateMessageParent(PlanetSideGUID(100), 2)
|
||||||
|
val objectData = definition.Packet.ConstructorData(obj).get
|
||||||
|
val msg = AvatarAction.LoadPlayer(id, guid, objectData, Some(parentData))
|
||||||
|
msg.response() match {
|
||||||
|
case AvatarAction.LoadCreatedPlayer(pkt) =>
|
||||||
|
pkt match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, pdata, data) =>
|
||||||
|
oid mustEqual id
|
||||||
|
guid mustEqual guid
|
||||||
|
pdata.contains(parentData) mustEqual true
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"LoadProjectile" should {
|
||||||
|
assert(GlobalDefinitions.wasp_rocket_projectile != null, "missing definition - wasp_rocket_projectile does not exist")
|
||||||
|
assert(GlobalDefinitions.wasp_weapon_system != null, "missing definition - wasp_weapon_system does not exist")
|
||||||
|
|
||||||
|
"respond" in {
|
||||||
|
val obj = new Projectile(
|
||||||
|
GlobalDefinitions.wasp_rocket_projectile,
|
||||||
|
GlobalDefinitions.wasp_weapon_system,
|
||||||
|
GlobalDefinitions.wasp_weapon_system.FireModes.head,
|
||||||
|
Some((1, SourceEntry.None)),
|
||||||
|
SourceEntry.None,
|
||||||
|
GlobalDefinitions.wasp_weapon_system.ObjectId,
|
||||||
|
Vector3(1, 2, 3),
|
||||||
|
Vector3(4, 5, 6),
|
||||||
|
Some(Vector3(7, 8, 9))
|
||||||
|
)
|
||||||
|
obj.GUID = PlanetSideGUID(1)
|
||||||
|
val definition = obj.Definition
|
||||||
|
val id = definition.ObjectId
|
||||||
|
val guid = obj.GUID
|
||||||
|
val objectData = definition.Packet.ConstructorData(obj).get
|
||||||
|
val msg = AvatarAction.LoadProjectile(id, guid, objectData)
|
||||||
|
msg.response() match {
|
||||||
|
case AvatarAction.LoadCreatedProjectile(pkt) =>
|
||||||
|
pkt match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, _, data) =>
|
||||||
|
oid mustEqual id
|
||||||
|
guid mustEqual guid
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"PickupItem" should {
|
||||||
|
"respond" in {
|
||||||
|
val obj = testSuppressor
|
||||||
|
val msg = AvatarAction.PickupItem(obj, 2)
|
||||||
|
msg.response() match {
|
||||||
|
case ObjectDelete(guid, slot) =>
|
||||||
|
guid mustEqual obj.GUID
|
||||||
|
slot mustEqual 2
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Release" should {
|
||||||
|
val testZone: Zone = new Zone(id = "test", new ZoneMap( name = "test"), zoneNumber = 1)
|
||||||
|
|
||||||
|
"respond" in {
|
||||||
|
val obj = testPlayer
|
||||||
|
val msg = AvatarAction.Release(obj, testZone)
|
||||||
|
msg.response() match {
|
||||||
|
case AvatarAction.ReleasePlayer(player) =>
|
||||||
|
(player == obj) mustEqual true
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/test/scala/service/base/EnvelopeTest.scala
Normal file
89
src/test/scala/service/base/EnvelopeTest.scala
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.base
|
||||||
|
|
||||||
|
import net.psforever.services.base.EventSystemStamp
|
||||||
|
import net.psforever.services.base.envelope._
|
||||||
|
import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent}
|
||||||
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
object EnvelopeTest {
|
||||||
|
case object TestStamp extends EventSystemStamp
|
||||||
|
|
||||||
|
val TestFilter: PlanetSideGUID = PlanetSideGUID(1)
|
||||||
|
|
||||||
|
final def StringWithSlashes(str: String): String = s"/$str/"
|
||||||
|
|
||||||
|
final case class TestMessage(value: Int) extends SelfRespondingEvent
|
||||||
|
|
||||||
|
final case class TestOutputEvent(value: Int) extends EventResponse
|
||||||
|
|
||||||
|
final case class TestInputMessage(value: Int) extends EventMessage {
|
||||||
|
def response(): EventResponse = TestOutputEvent(value + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EnvelopeTest extends Specification {
|
||||||
|
import EnvelopeTest._
|
||||||
|
|
||||||
|
"MessageEnvelope" should {
|
||||||
|
"construct" in {
|
||||||
|
MessageEnvelope("test", TestFilter, TestMessage(5))
|
||||||
|
ok
|
||||||
|
}
|
||||||
|
|
||||||
|
"message match" in {
|
||||||
|
val input = MessageEnvelope("test", TestFilter, TestMessage(5))
|
||||||
|
input match {
|
||||||
|
case GenericMessageEnvelope("test", TestFilter, TestMessage(5)) =>
|
||||||
|
ok
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"response (no stamp)" in {
|
||||||
|
val input = MessageEnvelope("test", TestFilter, TestMessage(5))
|
||||||
|
input match {
|
||||||
|
case reply @ GenericResponseEnvelope("test", TestFilter, NoReply) =>
|
||||||
|
reply.stamp mustEqual Undelivered
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"response" in {
|
||||||
|
val input = MessageEnvelope("test", TestFilter, TestMessage(5))
|
||||||
|
val output = input.response(TestStamp, StringWithSlashes)
|
||||||
|
output match {
|
||||||
|
case reply @ GenericResponseEnvelope("/test/", TestFilter, TestMessage(5)) =>
|
||||||
|
reply.stamp mustEqual TestStamp
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"response (different from input)" in {
|
||||||
|
val input = MessageEnvelope("test", TestFilter, TestInputMessage(5))
|
||||||
|
val output = input.response(TestStamp, StringWithSlashes)
|
||||||
|
output match {
|
||||||
|
case reply @ GenericResponseEnvelope("/test/", TestFilter, TestOutputEvent(7)) =>
|
||||||
|
reply.stamp mustEqual TestStamp
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"GenericResponseEnvelope" should {
|
||||||
|
"construct (quick)" in {
|
||||||
|
val input = GenericResponseEnvelope(TestStamp, "test", TestFilter, TestMessage(5))
|
||||||
|
input match {
|
||||||
|
case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) =>
|
||||||
|
reply.stamp mustEqual TestStamp
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/test/scala/service/base/EventMessageTest.scala
Normal file
42
src/test/scala/service/base/EventMessageTest.scala
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.base
|
||||||
|
|
||||||
|
import net.psforever.services.base.message.{EventMessage, EventResponse, SelfRespondingEvent}
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
object EventMessageTest {
|
||||||
|
final case class TestOutputEvent(value: Int) extends EventResponse
|
||||||
|
|
||||||
|
final case class TestInputMessage(value: Int) extends EventMessage {
|
||||||
|
def response(): EventResponse = TestOutputEvent(value + 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class TestMessage(value: Int) extends SelfRespondingEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventMessageTest extends Specification {
|
||||||
|
import EventMessageTest._
|
||||||
|
|
||||||
|
"EventMessage" should {
|
||||||
|
"construct" in {
|
||||||
|
TestInputMessage(5)
|
||||||
|
ok
|
||||||
|
}
|
||||||
|
|
||||||
|
"response" in {
|
||||||
|
TestInputMessage(5).response() mustEqual TestOutputEvent(7)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"SelfResponseMessage" should {
|
||||||
|
"construct" in {
|
||||||
|
TestMessage(5)
|
||||||
|
ok
|
||||||
|
}
|
||||||
|
|
||||||
|
"response (is same as self)" in {
|
||||||
|
val msg = TestMessage(5)
|
||||||
|
msg.response() mustEqual msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
221
src/test/scala/service/base/EventServiceCacheSupportTest.scala
Normal file
221
src/test/scala/service/base/EventServiceCacheSupportTest.scala
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.base
|
||||||
|
|
||||||
|
import akka.actor.Props
|
||||||
|
import akka.testkit.TestProbe
|
||||||
|
import base.ActorTest
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.message.EventMessage
|
||||||
|
import net.psforever.services.base.{CachedGenericEventMessageEnvelope, EventServiceSupport, GenericEventServiceWithCacheAndSupport, GenericSupportEnvelope}
|
||||||
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
object EventServiceCacheSupportTest {
|
||||||
|
class TestCacheService(eventSupportServices: List[EventServiceSupport])
|
||||||
|
extends GenericEventServiceWithCacheAndSupport(EventServiceTestBase.TestStamp, eventSupportServices)
|
||||||
|
|
||||||
|
final case class CachedSupportTestEnvelope(
|
||||||
|
guid: PlanetSideGUID,
|
||||||
|
originalChannel: String,
|
||||||
|
override val msg: EventMessage,
|
||||||
|
supportMessage: Any
|
||||||
|
) extends CachedGenericEventMessageEnvelope with GenericSupportEnvelope {
|
||||||
|
assert(guid != Service.defaultPlayerGUID, "can not cache message under default GUID")
|
||||||
|
def filter: PlanetSideGUID = Service.defaultPlayerGUID
|
||||||
|
def supportLabel: String = "supportActor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestDefault extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"construct" in {
|
||||||
|
system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestSupportNormally extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"send a valid message to both subscribed channel and support class, like normal GenericEventServiceWithSupport" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val supportProbe = TestProbe("SupportProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestCacheService], List(TestSupportActorLoader)), name = "EventServiceCacheSupportTest.1")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val originalMessage = TestSupportEnvelope("test", SupportActorRepliesWith("hello world", supportProbe.ref))
|
||||||
|
events ! originalMessage
|
||||||
|
//main reply
|
||||||
|
val mainReply = mainProbe.receiveOne(250 milliseconds)
|
||||||
|
mainReply match {
|
||||||
|
case msg if msg == originalMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(1) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
//support reply
|
||||||
|
val supportReply = supportProbe.receiveOne(250 milliseconds)
|
||||||
|
supportReply match {
|
||||||
|
case msg: String if msg.equals("hello world") => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(2) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestCachedMessages extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"wait on sending designated cache-able messages after a few milliseconds" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.2")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1))
|
||||||
|
events ! firstMessage
|
||||||
|
mainProbe.expectNoMessage(50 milliseconds)
|
||||||
|
val reply = mainProbe.receiveOne(125 milliseconds)
|
||||||
|
reply match {
|
||||||
|
case msg if msg == firstMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(3) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestMultipleCachedMessagesAtOnce extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"send cache-able messages within a time span in bulk" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.3")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1))
|
||||||
|
val secondMessage = CachedEnvelope(PlanetSideGUID(2), "test", TestMessage(2))
|
||||||
|
val thirdMessage = CachedEnvelope(PlanetSideGUID(3), "test", TestMessage(3))
|
||||||
|
events ! firstMessage
|
||||||
|
events ! secondMessage
|
||||||
|
events ! thirdMessage
|
||||||
|
mainProbe.expectNoMessage(50 milliseconds)
|
||||||
|
val reply = mainProbe.receiveN(3, 125 milliseconds)
|
||||||
|
reply.head match {
|
||||||
|
case msg if msg == firstMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(4) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
reply(1) match {
|
||||||
|
case msg if msg == secondMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(5) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
reply(2) match {
|
||||||
|
case msg if msg == thirdMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(6) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
mainProbe.expectNoMessage(65 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestMultipleCachedSameMessages extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"only caches and dispatches the last message with a given filtering token" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.4")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1))
|
||||||
|
val secondMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(2))
|
||||||
|
val thirdMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(3)) //this one!
|
||||||
|
events ! firstMessage
|
||||||
|
events ! secondMessage
|
||||||
|
events ! thirdMessage
|
||||||
|
mainProbe.expectNoMessage(50 milliseconds)
|
||||||
|
val reply = mainProbe.receiveOne(125 milliseconds)
|
||||||
|
reply match {
|
||||||
|
case badmsg if badmsg == firstMessage =>
|
||||||
|
assert(false, s"(1) received wrong message - $badmsg")
|
||||||
|
case badmsg if badmsg == secondMessage =>
|
||||||
|
assert(false, s"(2) received wrong message - $badmsg")
|
||||||
|
case msg if msg == thirdMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(7) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestMultipleCachedMessages extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"send cache-able messages within a time span, separated if they are part of different caches" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestCacheService], List()), name = "EventServiceCacheSupportTest.5")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val firstMessage = CachedEnvelope(PlanetSideGUID(1), "test", TestMessage(1))
|
||||||
|
//first cache flush
|
||||||
|
events ! firstMessage
|
||||||
|
mainProbe.expectNoMessage(50 milliseconds)
|
||||||
|
val firstReply = mainProbe.receiveOne(125 milliseconds)
|
||||||
|
firstReply match {
|
||||||
|
case msg if msg == firstMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(8) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
mainProbe.expectNoMessage(100 milliseconds)
|
||||||
|
//second cache flush
|
||||||
|
val secondMessage = CachedEnvelope(PlanetSideGUID(2), "test", TestMessage(2))
|
||||||
|
events ! secondMessage
|
||||||
|
mainProbe.expectNoMessage(50 milliseconds)
|
||||||
|
val reply = mainProbe.receiveOne(125 milliseconds)
|
||||||
|
reply match {
|
||||||
|
case msg if msg == secondMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(9) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceCacheSupportTestSupportDelayed extends ActorTest {
|
||||||
|
import EventServiceCacheSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithCacheAndSupport" should {
|
||||||
|
"cache a message for a support actor, but only dispatch that message to the support actor when flushing the cache" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val supportProbe = TestProbe("SupportProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestCacheService], List(TestSupportActorLoader)), name = "EventServiceCacheSupportTest.6")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val originalMessage = CachedSupportTestEnvelope(
|
||||||
|
PlanetSideGUID(1),
|
||||||
|
"test",
|
||||||
|
TestMessage(1),
|
||||||
|
SupportActorRepliesWith("hello world", supportProbe.ref)
|
||||||
|
)
|
||||||
|
events ! originalMessage
|
||||||
|
//main reply
|
||||||
|
supportProbe.expectNoMessage(50 milliseconds)
|
||||||
|
mainProbe.expectNoMessage(10 milliseconds)
|
||||||
|
val mainReply = mainProbe.receiveOne(125 milliseconds)
|
||||||
|
mainReply match {
|
||||||
|
case msg if msg == originalMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(10) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
//support reply
|
||||||
|
val supportReply = supportProbe.receiveOne(10 milliseconds)
|
||||||
|
supportReply match {
|
||||||
|
case msg: String if msg.equals("hello world") => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(11) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
133
src/test/scala/service/base/EventServiceSupportTest.scala
Normal file
133
src/test/scala/service/base/EventServiceSupportTest.scala
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.base
|
||||||
|
|
||||||
|
import akka.actor.Props
|
||||||
|
import akka.testkit.TestProbe
|
||||||
|
import base.ActorTest
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.{EventServiceSupport, GenericEventServiceWithSupport, GenericSupportEnvelopeOnly}
|
||||||
|
|
||||||
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
object EventServiceSupportTest {
|
||||||
|
class TestSupportService(eventSupportServices: List[EventServiceSupport])
|
||||||
|
extends GenericEventServiceWithSupport(EventServiceTestBase.TestStamp, eventSupportServices)
|
||||||
|
|
||||||
|
final case class TestSupportOnlyEnvelope(supportLabel: String, supportMessage: EventServiceTestBase.SupportActorRepliesWith)
|
||||||
|
extends GenericSupportEnvelopeOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceSupportTestDefault extends ActorTest {
|
||||||
|
import EventServiceSupportTest._
|
||||||
|
"GenericEventServiceWithSupport" should {
|
||||||
|
"construct" in {
|
||||||
|
system.actorOf(Props(classOf[TestSupportService], List()), name = "EventServiceSupportTest.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceSupportTestLoadSupportClass extends ActorTest {
|
||||||
|
import EventServiceSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithSupport" should {
|
||||||
|
"construct with setting up a test support class" in {
|
||||||
|
system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceSupportTestSendToSupportClass extends ActorTest {
|
||||||
|
import EventServiceSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithSupport" should {
|
||||||
|
"send a valid message to both subscribed channel and support class" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val supportProbe = TestProbe("SupportProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.2")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val originalMessage = TestSupportEnvelope("test", SupportActorRepliesWith("hello world", supportProbe.ref))
|
||||||
|
events ! originalMessage
|
||||||
|
//main reply
|
||||||
|
val mainReply = mainProbe.receiveOne(250 milliseconds)
|
||||||
|
mainReply match {
|
||||||
|
case msg if msg == originalMessage => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(1) expected delivery of test envelope, but received $badmsg instead")
|
||||||
|
}
|
||||||
|
//support reply
|
||||||
|
val supportReply = supportProbe.receiveOne(250 milliseconds)
|
||||||
|
supportReply match {
|
||||||
|
case msg: String if msg.equals("hello world") => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(2) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceSupportTestSendToSupportClassOnly1 extends ActorTest {
|
||||||
|
import EventServiceSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithSupport" should {
|
||||||
|
"send a valid message to support class (but not to subscribed channel)" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val supportProbe = TestProbe("SupportProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.3")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val originalMessage = TestSupportEnvelope("notatest", SupportActorRepliesWith("hello world", supportProbe.ref))
|
||||||
|
events ! originalMessage
|
||||||
|
//main reply (no reply)
|
||||||
|
mainProbe.expectNoMessage(500 milliseconds)
|
||||||
|
//support reply
|
||||||
|
val supportReply = supportProbe.receiveOne(250 milliseconds)
|
||||||
|
supportReply match {
|
||||||
|
case msg: String if msg.equals("hello world") => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(3) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceSupportTestSendToSupportClassOnly2 extends ActorTest {
|
||||||
|
import EventServiceSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithSupport" should {
|
||||||
|
"send a valid message to support class (skip subscribed channel)" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val supportProbe = TestProbe("SupportProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.4")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val originalMessage = TestSupportOnlyEnvelope("supportActor", SupportActorRepliesWith("hello world", supportProbe.ref))
|
||||||
|
events ! originalMessage
|
||||||
|
//main reply (no reply)
|
||||||
|
mainProbe.expectNoMessage(500 milliseconds)
|
||||||
|
//support reply
|
||||||
|
val supportReply = supportProbe.receiveOne(250 milliseconds)
|
||||||
|
supportReply match {
|
||||||
|
case msg: String if msg.equals("hello world") => ()
|
||||||
|
case badmsg =>
|
||||||
|
assert(false, s"(4) expected delivery of test envelope payload 'hello world', but received '$badmsg' instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceSupportTestSendToNoOne extends ActorTest {
|
||||||
|
import EventServiceSupportTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventServiceWithSupport" should {
|
||||||
|
"send a valid message that neither support class nor subscribed channel handle" in {
|
||||||
|
val mainProbe = TestProbe("MainProbe")
|
||||||
|
val supportProbe = TestProbe("SupportProbe")
|
||||||
|
val events = system.actorOf(Props(classOf[TestSupportService], List(TestSupportActorLoader)), name = "EventServiceSupportTest.5")
|
||||||
|
events.tell(Service.Join("test"), mainProbe.ref)
|
||||||
|
val originalMessage = TestSupportOnlyEnvelope("notASupportActor", SupportActorRepliesWith("hello world", supportProbe.ref))
|
||||||
|
events ! originalMessage
|
||||||
|
//main reply (no reply)
|
||||||
|
mainProbe.expectNoMessage(500 milliseconds)
|
||||||
|
//support reply (no reply)
|
||||||
|
supportProbe.expectNoMessage(500 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
199
src/test/scala/service/base/EventServiceTest.scala
Normal file
199
src/test/scala/service/base/EventServiceTest.scala
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.base
|
||||||
|
|
||||||
|
import akka.actor.Props
|
||||||
|
import akka.testkit.TestProbe
|
||||||
|
import base.ActorTest
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.GenericEventService
|
||||||
|
import net.psforever.services.base.envelope.GenericResponseEnvelope
|
||||||
|
|
||||||
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
object EventServiceTest {
|
||||||
|
class TestService() extends GenericEventService(EventServiceTestBase.TestStamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTestDefault extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"construct" in {
|
||||||
|
system.actorOf(Props[TestService](), name = "EventServiceTest.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest1 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"be subscribed to by channel name" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.1")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
probe.expectNoMessage(100 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest2 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"receive messages from a subscribed channel" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.2")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
probe.receiveN(1, 100 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest3 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"receive messages that are responses to the original message from a subscribed channel" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.3")
|
||||||
|
val msg = MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
// s => "/$s" is the default channel manipulation of the event system
|
||||||
|
val formalReply = msg.response(EventServiceTestBase.TestStamp, s => "/$s")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
val reply = probe.receiveOne(100 milliseconds)
|
||||||
|
assert(reply == formalReply, "(1) message expected but not received format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest4 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"not receive messages from an unsubscribed channel" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val missedProbe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.4")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events.tell(Service.Join("notATest"), missedProbe.ref)
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
val reply = probe.receiveOne(100 milliseconds)
|
||||||
|
reply match {
|
||||||
|
case GenericResponseEnvelope("/test", _, TestMessage(5)) => ()
|
||||||
|
case _ => assert(false, "(2) message expected but not received")
|
||||||
|
}
|
||||||
|
missedProbe.expectNoMessage(100 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest5 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"ignore unexpected messages" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.5")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events ! TestMessage(5)
|
||||||
|
probe.expectNoMessage(250 milliseconds)
|
||||||
|
//the warn log should show something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest6 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"leave single channels" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.6")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events.tell(Service.Join("anotherTest"), probe.ref)
|
||||||
|
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
val reply1 = probe.receiveN(2, 100 milliseconds)
|
||||||
|
reply1.head match {
|
||||||
|
case GenericResponseEnvelope("/test", _, _) => ()
|
||||||
|
case _ => assert(false, "(3) message expected but not received")
|
||||||
|
}
|
||||||
|
reply1(1) match {
|
||||||
|
case GenericResponseEnvelope("/anotherTest", _, _) => ()
|
||||||
|
case _ => assert(false, "(4) message expected but not received")
|
||||||
|
}
|
||||||
|
|
||||||
|
events.tell(Service.Leave(Some("anotherTest")), probe.ref)
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6))
|
||||||
|
val reply2 = probe.receiveOne(100 milliseconds)
|
||||||
|
reply2 match {
|
||||||
|
case GenericResponseEnvelope("/test", _, TestMessage(5)) => ()
|
||||||
|
case _ => assert(false, "(5) message expected but not received")
|
||||||
|
}
|
||||||
|
probe.expectNoMessage(250 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest7 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"leave all channels (1)" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.7")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events.tell(Service.Join("anotherTest"), probe.ref)
|
||||||
|
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6))
|
||||||
|
val reply = probe.receiveN(2,100 milliseconds)
|
||||||
|
reply.head match {
|
||||||
|
case GenericResponseEnvelope("/test", _, TestMessage(5)) => ()
|
||||||
|
case _ => assert(false, "(6) message expected but not received")
|
||||||
|
}
|
||||||
|
reply(1) match {
|
||||||
|
case GenericResponseEnvelope("/anotherTest", _, TestMessage(6)) => ()
|
||||||
|
case _ => assert(false, "(7) message expected but not received")
|
||||||
|
}
|
||||||
|
|
||||||
|
events.tell(Service.Leave(), probe.ref)
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6))
|
||||||
|
probe.expectNoMessage(250 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventServiceTest8 extends ActorTest {
|
||||||
|
import EventServiceTest._
|
||||||
|
import EventServiceTestBase._
|
||||||
|
"GenericEventSystem" should {
|
||||||
|
"leave all channels" in {
|
||||||
|
val probe = TestProbe("testProbe")
|
||||||
|
val events = system.actorOf(Props[TestService](), name = "EventServiceTest.8")
|
||||||
|
events.tell(Service.Join("test"), probe.ref)
|
||||||
|
events.tell(Service.Join("anotherTest"), probe.ref)
|
||||||
|
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6))
|
||||||
|
val reply = probe.receiveN(2,100 milliseconds)
|
||||||
|
reply.head match {
|
||||||
|
case GenericResponseEnvelope("/test", _, TestMessage(5)) => ()
|
||||||
|
case _ => assert(false, "(6) message expected but not received")
|
||||||
|
}
|
||||||
|
reply(1) match {
|
||||||
|
case GenericResponseEnvelope("/anotherTest", _, TestMessage(6)) => ()
|
||||||
|
case _ => assert(false, "(7) message expected but not received")
|
||||||
|
}
|
||||||
|
|
||||||
|
events.tell(Service.LeaveAll(), probe.ref)
|
||||||
|
events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5))
|
||||||
|
events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6))
|
||||||
|
probe.expectNoMessage(250 milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/test/scala/service/base/EventServiceTestBase.scala
Normal file
39
src/test/scala/service/base/EventServiceTestBase.scala
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
package service.base
|
||||||
|
|
||||||
|
import akka.actor.{Actor, ActorContext, ActorRef, Props}
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.message.SelfRespondingEvent
|
||||||
|
import net.psforever.services.base.{EventServiceSupport, EventSystemStamp, GenericSupportEnvelope}
|
||||||
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
|
object EventServiceTestBase {
|
||||||
|
case object TestStamp extends EventSystemStamp
|
||||||
|
|
||||||
|
final case class TestMessage(value: Int) extends SelfRespondingEvent
|
||||||
|
|
||||||
|
final case class SupportActorRepliesWith(msg: String, sendTo: ActorRef) extends SelfRespondingEvent
|
||||||
|
|
||||||
|
class TestSupportActor extends Actor {
|
||||||
|
def receive: Receive = {
|
||||||
|
case SupportActorRepliesWith(msg, sendTo) =>
|
||||||
|
sendTo ! msg
|
||||||
|
case _ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case object TestSupportActorLoader extends EventServiceSupport {
|
||||||
|
def label: String = "supportActor"
|
||||||
|
def constructor(context: ActorContext): ActorRef = {
|
||||||
|
context.actorOf(Props[TestSupportActor](), name = "supportActor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final case class TestSupportEnvelope(
|
||||||
|
originalChannel: String,
|
||||||
|
msg: SupportActorRepliesWith
|
||||||
|
) extends GenericSupportEnvelope {
|
||||||
|
def filter: PlanetSideGUID = Service.defaultPlayerGUID
|
||||||
|
def supportLabel: String = "supportActor"
|
||||||
|
def supportMessage: Any = msg
|
||||||
|
}
|
||||||
|
}
|
||||||
73
src/test/scala/service/local/LocalActionTest.scala
Normal file
73
src/test/scala/service/local/LocalActionTest.scala
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.local
|
||||||
|
|
||||||
|
import net.psforever.objects.{ExplosiveDeployable, GlobalDefinitions}
|
||||||
|
import net.psforever.packet.game.{ObjectCreateMessage, TriggeredEffect, TriggeredEffectLocation}
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.message.SendResponse
|
||||||
|
import net.psforever.services.local.LocalAction
|
||||||
|
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
class LocalActionTest extends Specification {
|
||||||
|
"DeployItem" should {
|
||||||
|
assert(GlobalDefinitions.boomer != null, "missing definition - Boomer does not exist")
|
||||||
|
|
||||||
|
"respond" in {
|
||||||
|
val obj = new ExplosiveDeployable(GlobalDefinitions.boomer)
|
||||||
|
obj.GUID = PlanetSideGUID(1)
|
||||||
|
val msg = LocalAction.DeployItem(obj)
|
||||||
|
val definition = obj.Definition
|
||||||
|
val objectData = definition.Packet.ConstructorData(obj).get
|
||||||
|
msg.response() match {
|
||||||
|
case SendResponse(packets) =>
|
||||||
|
packets.head match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, _, data) =>
|
||||||
|
oid mustEqual definition.ObjectId
|
||||||
|
guid mustEqual obj.GUID
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"TriggerEffect" should {
|
||||||
|
"respond" in {
|
||||||
|
val msg = LocalAction.TriggerEffect("on", PlanetSideGUID(1))
|
||||||
|
msg.response() match {
|
||||||
|
case LocalAction.TriggerEffectAtLocation(PlanetSideGUID(1), "on", None, None) =>
|
||||||
|
ok
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"TriggerEffectInfo" should {
|
||||||
|
"respond" in {
|
||||||
|
val msg = LocalAction.TriggerEffectInfo(PlanetSideGUID(1), "on", unk1 = true, unk2 = 10L)
|
||||||
|
msg.response() match {
|
||||||
|
case LocalAction.TriggerEffectAtLocation(PlanetSideGUID(1), "on", Some(TriggeredEffect(true, 10L)), None) =>
|
||||||
|
ok
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"TriggerEffectLocation" should {
|
||||||
|
"respond" in {
|
||||||
|
val msg = LocalAction.TriggerEffectLocation("on", Vector3(1, 2, 3), Vector3(4, 5, 6))
|
||||||
|
msg.response() match {
|
||||||
|
case LocalAction.TriggerEffectAtLocation(Service.defaultPlayerGUID, "on", None, Some(TriggeredEffectLocation(Vector3(1, 2, 3), Vector3(4, 5, 6)))) =>
|
||||||
|
ok
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/test/scala/service/vehicle/VehicleActionTest.scala
Normal file
102
src/test/scala/service/vehicle/VehicleActionTest.scala
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package service.vehicle
|
||||||
|
|
||||||
|
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||||
|
import net.psforever.objects.{GlobalDefinitions, Tool, Vehicle}
|
||||||
|
import net.psforever.packet.game.ObjectCreateMessage
|
||||||
|
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||||
|
import net.psforever.services.vehicle.VehicleAction
|
||||||
|
import net.psforever.types.{DriveState, PlanetSideGUID}
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
object VehicleActionTest {
|
||||||
|
assert(GlobalDefinitions.quadstealth != null, "missing definition - quadstealth does not exist")
|
||||||
|
assert(GlobalDefinitions.ams_respawn_tube != null, "missing definition - ams_respawn_tube does not exist")
|
||||||
|
assert(GlobalDefinitions.ams != null, "missing definition - AMS does not exist")
|
||||||
|
|
||||||
|
final val testZone: Zone = {
|
||||||
|
var i = 1
|
||||||
|
val notAms = new Vehicle(GlobalDefinitions.quadstealth)
|
||||||
|
notAms.GUID = PlanetSideGUID(i)
|
||||||
|
notAms.Health = 1
|
||||||
|
i += 1
|
||||||
|
val ams = new Vehicle(GlobalDefinitions.ams)
|
||||||
|
ams.Health = 1
|
||||||
|
ams.GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
ams.Utilities.values.foreach { utility =>
|
||||||
|
utility.apply().GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
ams.DeploymentState = DriveState.Deployed
|
||||||
|
new Zone(id = "test", new ZoneMap( name = "test"), zoneNumber = 1) {
|
||||||
|
override def Vehicles: List[Vehicle] = List(notAms, ams)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VehicleActionTest extends Specification {
|
||||||
|
import VehicleActionTest._
|
||||||
|
|
||||||
|
"EquipmentInSlot" should {
|
||||||
|
assert(GlobalDefinitions.suppressor != null, "missing definition - Suppressor does not exist")
|
||||||
|
|
||||||
|
"respond" in {
|
||||||
|
var i = 1
|
||||||
|
val obj = new Tool(GlobalDefinitions.suppressor)
|
||||||
|
obj.GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
obj.AmmoSlots.map(_.Box).foreach { box =>
|
||||||
|
box.GUID = PlanetSideGUID(i)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
val msg = VehicleAction.EquipmentInSlot(PlanetSideGUID(1), 2, obj)
|
||||||
|
val definition = obj.Definition
|
||||||
|
val objectData = definition.Packet.ConstructorData(obj).get
|
||||||
|
msg.response() match {
|
||||||
|
case VehicleAction.EquipmentCreatedInSlot(packets) =>
|
||||||
|
packets match {
|
||||||
|
case ObjectCreateMessage(_, oid, guid, pdata, data) =>
|
||||||
|
oid mustEqual definition.ObjectId
|
||||||
|
guid mustEqual obj.GUID
|
||||||
|
pdata.contains(ObjectCreateMessageParent(PlanetSideGUID(1), 2)) mustEqual true
|
||||||
|
data mustEqual objectData
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"UpdateAmsSpawnPoint" should {
|
||||||
|
"respond" in {
|
||||||
|
testZone.Vehicles.size mustEqual 2
|
||||||
|
val msg = VehicleAction.UpdateAmsSpawnPoint(testZone)
|
||||||
|
msg.response() match {
|
||||||
|
case VehicleAction.UpdateAmsSpawnList(list) =>
|
||||||
|
list.size mustEqual 1
|
||||||
|
list.head.Definition mustEqual GlobalDefinitions.ams_respawn_tube
|
||||||
|
list.head.Owner.Definition mustEqual GlobalDefinitions.ams
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"AMSDeploymentChange" should {
|
||||||
|
"respond" in {
|
||||||
|
testZone.Vehicles.size mustEqual 2
|
||||||
|
val msg = VehicleAction.AMSDeploymentChange(testZone)
|
||||||
|
msg.response() match {
|
||||||
|
case VehicleAction.UpdateAmsSpawnList(list) =>
|
||||||
|
list.size mustEqual 1
|
||||||
|
list.head.Definition mustEqual GlobalDefinitions.ams_respawn_tube
|
||||||
|
list.head.Owner.Definition mustEqual GlobalDefinitions.ams
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue