diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala
index 7ea23d760..33e814221 100644
--- a/src/main/scala/net/psforever/actors/session/SessionActor.scala
+++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala
@@ -1,8 +1,29 @@
// Copyright (c) 2016, 2020, 2024 PSForever
package net.psforever.actors.session
-import akka.actor.{Actor, Cancellable, MDCContextAware, typed}
+import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware, typed}
import net.psforever.actors.session.normal.NormalMode
+import net.psforever.actors.session.support.ZoningOperations
+import net.psforever.objects.TurretDeployable
+import net.psforever.objects.serverobject.CommonMessages
+import net.psforever.objects.serverobject.containable.Containable
+import net.psforever.objects.serverobject.deploy.Deployment
+import net.psforever.objects.serverobject.mount.Mountable
+import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
+import net.psforever.objects.zones.Zone
+import net.psforever.packet.PlanetSideGamePacket
+import net.psforever.packet.game.{AIDamage, ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarGrenadeStateMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BeginZoningMessage, BindPlayerMessage, BugReportMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ChildObjectStateMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DeployRequestMessage, DismountVehicleCargoMsg, DismountVehicleMsg, DisplayedAwardMessage, DropItemMessage, DroppodLaunchRequestMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FavoritesRequest, FrameVehicleStateMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, HitMessage, InvalidTerrainMessage, ItemTransactionMessage, LashMessage, LongRangeProjectileInfoMessage, LootItemMessage, MountVehicleCargoMsg, MountVehicleMsg, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, ProjectileStateMessage, ProximityTerminalUseMessage, ReleaseAvatarRequestMessage, ReloadMessage, RequestDestroyMessage, SetChatFilterMessage, SpawnRequestMessage, SplashHitMessage, SquadDefinitionActionMessage, SquadMembershipRequest, SquadWaypointRequest, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UplinkRequest, UseItemMessage, VehicleStateMessage, VehicleSubStateMessage, VoiceHostInfo, VoiceHostRequest, WarpgateRequest, WeaponDelayFireMessage, WeaponDryFireMessage, WeaponFireMessage, WeaponLazeTargetPositionMessage, ZipLineMessage}
+import net.psforever.services.{InterstellarClusterService => ICS}
+import net.psforever.services.CavernRotationService
+import net.psforever.services.CavernRotationService.SendCavernRotationUpdates
+import net.psforever.services.ServiceManager.LookupResult
+import net.psforever.services.account.{PlayerToken, ReceiveAccountData}
+import net.psforever.services.avatar.AvatarServiceResponse
+import net.psforever.services.chat.ChatService
+import net.psforever.services.galaxy.GalaxyServiceResponse
+import net.psforever.services.local.LocalServiceResponse
+import net.psforever.services.teamwork.SquadServiceResponse
+import net.psforever.services.vehicle.VehicleServiceResponse
import org.joda.time.LocalDateTime
import org.log4s.MDC
@@ -105,8 +126,8 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
}
private def inTheGame: Receive = {
- /* used for the game's heartbeat */
case SessionActor.StartHeartbeat =>
+ //used for the game's heartbeat
startHeartbeat()
case SessionActor.PokeClient =>
@@ -115,13 +136,13 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case SessionActor.SetMode(newMode) =>
if (mode != newMode) {
logic.switchFrom(data.session)
+ mode = newMode
+ logic = mode.setup(data)
}
- mode = newMode
- logic = mode.setup(data)
logic.switchTo(data.session)
case packet =>
- logic.parse(sender())(packet)
+ parse(sender())(packet)
}
private def startHeartbeat(): Unit = {
@@ -135,4 +156,454 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
SessionActor.PokeClient
)
}
+
+ private def parse(sender: ActorRef): Receive = {
+ /* really common messages (very frequently, every life) */
+ case packet: PlanetSideGamePacket =>
+ handleGamePkt(packet)
+
+ case AvatarServiceResponse(toChannel, guid, reply) =>
+ logic.avatarResponse.handle(toChannel, guid, reply)
+
+ case GalaxyServiceResponse(_, reply) =>
+ logic.galaxy.handle(reply)
+
+ case LocalServiceResponse(toChannel, guid, reply) =>
+ logic.local.handle(toChannel, guid, reply)
+
+ case Mountable.MountMessages(tplayer, reply) =>
+ logic.mountResponse.handle(tplayer, reply)
+
+ case SquadServiceResponse(_, excluded, response) =>
+ logic.squad.handle(response, excluded)
+
+ case Terminal.TerminalMessage(tplayer, msg, order) =>
+ logic.terminals.handle(tplayer, msg, order)
+
+ case VehicleServiceResponse(toChannel, guid, reply) =>
+ logic.vehicleResponse.handle(toChannel, guid, reply)
+
+ case ChatService.MessageResponse(fromSession, message, _) =>
+ logic.chat.handleIncomingMessage(message, fromSession)
+
+ case SessionActor.SendResponse(packet) =>
+ data.sendResponse(packet)
+
+ case SessionActor.CharSaved =>
+ logic.general.handleRenewCharSavedTimer()
+
+ case SessionActor.CharSavedMsg =>
+ logic.general.handleRenewCharSavedTimerMsg()
+
+ /* common messages (maybe once every respawn) */
+ case ICS.SpawnPointResponse(response) =>
+ data.zoning.handleSpawnPointResponse(response)
+
+ case SessionActor.NewPlayerLoaded(tplayer) =>
+ data.zoning.spawn.handleNewPlayerLoaded(tplayer)
+
+ case SessionActor.PlayerLoaded(tplayer) =>
+ data.zoning.spawn.handlePlayerLoaded(tplayer)
+
+ case Zone.Population.PlayerHasLeft(zone, playerOpt) =>
+ data.zoning.spawn.handlePlayerHasLeft(zone, playerOpt)
+
+ case Zone.Population.PlayerCanNotSpawn(zone, tplayer) =>
+ data.zoning.spawn.handlePlayerCanNotSpawn(zone, tplayer)
+
+ case Zone.Population.PlayerAlreadySpawned(zone, tplayer) =>
+ data.zoning.spawn.handlePlayerAlreadySpawned(zone, tplayer)
+
+ case Zone.Vehicle.CanNotSpawn(zone, vehicle, reason) =>
+ data.zoning.spawn.handleCanNotSpawn(zone, vehicle, reason)
+
+ case Zone.Vehicle.CanNotDespawn(zone, vehicle, reason) =>
+ data.zoning.spawn.handleCanNotDespawn(zone, vehicle, reason)
+
+ case ICS.ZoneResponse(Some(zone)) =>
+ data.zoning.handleZoneResponse(zone)
+
+ /* uncommon messages (once a session) */
+ case ICS.ZonesResponse(zones) =>
+ data.zoning.handleZonesResponse(zones)
+
+ case SessionActor.SetAvatar(avatar) =>
+ logic.general.handleSetAvatar(avatar)
+
+ case PlayerToken.LoginInfo(name, Zone.Nowhere, _) =>
+ data.zoning.spawn.handleLoginInfoNowhere(name, sender)
+
+ case PlayerToken.LoginInfo(name, inZone, optionalSavedData) =>
+ data.zoning.spawn.handleLoginInfoSomewhere(name, inZone, optionalSavedData, sender)
+
+ case PlayerToken.RestoreInfo(playerName, inZone, pos) =>
+ data.zoning.spawn.handleLoginInfoRestore(playerName, inZone, pos, sender)
+
+ case PlayerToken.CanNotLogin(playerName, reason) =>
+ data.zoning.spawn.handleLoginCanNot(playerName, reason)
+
+ case ReceiveAccountData(account) =>
+ logic.general.handleReceiveAccountData(account)
+
+ case AvatarActor.AvatarResponse(avatar) =>
+ logic.general.handleAvatarResponse(avatar)
+
+ case AvatarActor.AvatarLoginResponse(avatar) =>
+ data.zoning.spawn.avatarLoginResponse(avatar)
+
+ case SessionActor.SetCurrentAvatar(tplayer, max_attempts, attempt) =>
+ data.zoning.spawn.ReadyToSetCurrentAvatar(tplayer, max_attempts, attempt)
+
+ case SessionActor.SetConnectionState(state) =>
+ data.connectionState = state
+
+ case SessionActor.AvatarLoadingSync(state) =>
+ data.zoning.spawn.handleAvatarLoadingSync(state)
+
+ /* uncommon messages (utility, or once in a while) */
+ case ZoningOperations.AvatarAwardMessageBundle(pkts, delay) =>
+ data.zoning.spawn.performAvatarAwardMessageDelivery(pkts, delay)
+
+ case CommonMessages.ProgressEvent(delta, finishedAction, stepAction, tick) =>
+ data.general.handleProgressChange(delta, finishedAction, stepAction, tick)
+
+ case CommonMessages.Progress(rate, finishedAction, stepAction) =>
+ data.general.setupProgressChange(rate, finishedAction, stepAction)
+
+ case CavernRotationService.CavernRotationServiceKey.Listing(listings) =>
+ listings.head ! SendCavernRotationUpdates(data.context.self)
+
+ case LookupResult("propertyOverrideManager", endpoint) =>
+ data.zoning.propertyOverrideManagerLoadOverrides(endpoint)
+
+ case SessionActor.UpdateIgnoredPlayers(msg) =>
+ logic.galaxy.handleUpdateIgnoredPlayers(msg)
+
+ case SessionActor.UseCooldownRenewed(definition, _) =>
+ logic.general.handleUseCooldownRenew(definition)
+
+ case Deployment.CanDeploy(obj, state) =>
+ logic.vehicles.handleCanDeploy(obj, state)
+
+ case Deployment.CanUndeploy(obj, state) =>
+ logic.vehicles.handleCanUndeploy(obj, state)
+
+ case Deployment.CanNotChangeDeployment(obj, state, reason) =>
+ logic.vehicles.handleCanNotChangeDeployment(obj, state, reason)
+
+ /* rare messages */
+ case ProximityUnit.StopAction(term, _) =>
+ logic.terminals.ops.LocalStopUsingProximityUnit(term)
+
+ case SessionActor.Suicide() =>
+ data.general.suicide(data.player)
+
+ case SessionActor.Recall() =>
+ data.zoning.handleRecall()
+
+ case SessionActor.InstantAction() =>
+ data.zoning.handleInstantAction()
+
+ case SessionActor.Quit() =>
+ data.zoning.handleQuit()
+
+ case ICS.DroppodLaunchDenial(errorCode, _) =>
+ data.zoning.handleDroppodLaunchDenial(errorCode)
+
+ case ICS.DroppodLaunchConfirmation(zone, position) =>
+ data.zoning.LoadZoneLaunchDroppod(zone, position)
+
+ case SessionActor.PlayerFailedToLoad(tplayer) =>
+ data.zoning.spawn.handlePlayerFailedToLoad(tplayer)
+
+ /* csr only */
+ case SessionActor.SetSpeed(speed) =>
+ logic.general.handleSetSpeed(speed)
+
+ case SessionActor.SetFlying(isFlying) =>
+ logic.general.handleSetFlying(isFlying)
+
+ case SessionActor.SetSpectator(isSpectator) =>
+ logic.general.handleSetSpectator(isSpectator)
+
+ case SessionActor.Kick(player, time) =>
+ logic.general.handleKick(player, time)
+
+ case SessionActor.SetZone(zoneId, position) =>
+ data.zoning.handleSetZone(zoneId, position)
+
+ case SessionActor.SetPosition(position) =>
+ data.zoning.spawn.handleSetPosition(position)
+
+ case SessionActor.SetSilenced(silenced) =>
+ logic.general.handleSilenced(silenced)
+
+ /* catch these messages */
+ case _: ProximityUnit.Action => ()
+
+ case _: Zone.Vehicle.HasSpawned => ()
+
+ case _: Zone.Vehicle.HasDespawned => ()
+
+ case Zone.Deployable.IsDismissed(obj: TurretDeployable) => //only if target deployable was never fully introduced
+ logic.local.handleTurretDeployableIsDismissed(obj)
+
+ case Zone.Deployable.IsDismissed(obj) => //only if target deployable was never fully introduced
+ logic.local.handleDeployableIsDismissed(obj)
+
+ case msg: Containable.ItemPutInSlot =>
+ logic.general.handleItemPutInSlot(msg)
+
+ case msg: Containable.CanNotPutItemInSlot =>
+ logic.general.handleCanNotPutItemInSlot(msg)
+
+ case default =>
+ logic.general.handleReceiveDefaultMessage(default, sender)
+ }
+
+ private def handleGamePkt: PlanetSideGamePacket => Unit = {
+ case packet: ConnectToWorldRequestMessage =>
+ logic.general.handleConnectToWorldRequest(packet)
+
+ case packet: MountVehicleCargoMsg =>
+ logic.mountResponse.handleMountVehicleCargo(packet)
+
+ case packet: DismountVehicleCargoMsg =>
+ logic.mountResponse.handleDismountVehicleCargo(packet)
+
+ case packet: CharacterCreateRequestMessage =>
+ logic.general.handleCharacterCreateRequest(packet)
+
+ case packet: CharacterRequestMessage =>
+ logic.general.handleCharacterRequest(packet)
+
+ case _: KeepAliveMessage =>
+ data.keepAliveFunc()
+
+ case packet: BeginZoningMessage =>
+ data.zoning.handleBeginZoning(packet)
+
+ case packet: PlayerStateMessageUpstream =>
+ logic.general.handlePlayerStateUpstream(packet)
+
+ case packet: ChildObjectStateMessage =>
+ logic.vehicles.handleChildObjectState(packet)
+
+ case packet: VehicleStateMessage =>
+ logic.vehicles.handleVehicleState(packet)
+
+ case packet: VehicleSubStateMessage =>
+ logic.vehicles.handleVehicleSubState(packet)
+
+ case packet: FrameVehicleStateMessage =>
+ logic.vehicles.handleFrameVehicleState(packet)
+
+ case packet: ProjectileStateMessage =>
+ logic.shooting.handleProjectileState(packet)
+
+ case packet: LongRangeProjectileInfoMessage =>
+ logic.shooting.handleLongRangeProjectileState(packet)
+
+ case packet: ReleaseAvatarRequestMessage =>
+ data.zoning.spawn.handleReleaseAvatarRequest(packet)
+
+ case packet: SpawnRequestMessage =>
+ data.zoning.spawn.handleSpawnRequest(packet)
+
+ case packet: ChatMsg =>
+ logic.chat.handleChatMsg(packet)
+
+ case packet: SetChatFilterMessage =>
+ logic.chat.handleChatFilter(packet)
+
+ case packet: VoiceHostRequest =>
+ logic.general.handleVoiceHostRequest(packet)
+
+ case packet: VoiceHostInfo =>
+ logic.general.handleVoiceHostInfo(packet)
+
+ case packet: ChangeAmmoMessage =>
+ logic.shooting.handleChangeAmmo(packet)
+
+ case packet: ChangeFireModeMessage =>
+ logic.shooting.handleChangeFireMode(packet)
+
+ case packet: ChangeFireStateMessage_Start =>
+ logic.shooting.handleChangeFireStateStart(packet)
+
+ case packet: ChangeFireStateMessage_Stop =>
+ logic.shooting.handleChangeFireStateStop(packet)
+
+ case packet: EmoteMsg =>
+ logic.general.handleEmote(packet)
+
+ case packet: DropItemMessage =>
+ logic.general.handleDropItem(packet)
+
+ case packet: PickupItemMessage =>
+ logic.general.handlePickupItem(packet)
+
+ case packet: ReloadMessage =>
+ logic.shooting.handleReload(packet)
+
+ case packet: ObjectHeldMessage =>
+ logic.general.handleObjectHeld(packet)
+
+ case packet: AvatarJumpMessage =>
+ logic.general.handleAvatarJump(packet)
+
+ case packet: ZipLineMessage =>
+ logic.general.handleZipLine(packet)
+
+ case packet: RequestDestroyMessage =>
+ logic.general.handleRequestDestroy(packet)
+
+ case packet: MoveItemMessage =>
+ logic.general.handleMoveItem(packet)
+
+ case packet: LootItemMessage =>
+ logic.general.handleLootItem(packet)
+
+ case packet: AvatarImplantMessage =>
+ logic.general.handleAvatarImplant(packet)
+
+ case packet: UseItemMessage =>
+ logic.general.handleUseItem(packet)
+
+ case packet: UnuseItemMessage =>
+ logic.general.handleUnuseItem(packet)
+
+ case packet: ProximityTerminalUseMessage =>
+ logic.terminals.handleProximityTerminalUse(packet)
+
+ case packet: DeployObjectMessage =>
+ logic.general.handleDeployObject(packet)
+
+ case packet: GenericObjectActionMessage =>
+ logic.general.handleGenericObjectAction(packet)
+
+ case packet: GenericObjectActionAtPositionMessage =>
+ logic.general.handleGenericObjectActionAtPosition(packet)
+
+ case packet: GenericObjectStateMsg =>
+ logic.general.handleGenericObjectState(packet)
+
+ case packet: GenericActionMessage =>
+ logic.general.handleGenericAction(packet)
+
+ case packet: ItemTransactionMessage =>
+ logic.terminals.handleItemTransaction(packet)
+
+ case packet: FavoritesRequest =>
+ logic.terminals.handleFavoritesRequest(packet)
+
+ case packet: WeaponDelayFireMessage =>
+ logic.shooting.handleWeaponDelayFire(packet)
+
+ case packet: WeaponDryFireMessage =>
+ logic.shooting.handleWeaponDryFire(packet)
+
+ case packet: WeaponFireMessage =>
+ logic.shooting.handleWeaponFire(packet)
+
+ case packet: WeaponLazeTargetPositionMessage =>
+ logic.shooting.handleWeaponLazeTargetPosition(packet)
+
+ case _: UplinkRequest => ()
+
+ case packet: HitMessage =>
+ logic.shooting.handleDirectHit(packet)
+
+ case packet: SplashHitMessage =>
+ logic.shooting.handleSplashHit(packet)
+
+ case packet: LashMessage =>
+ logic.shooting.handleLashHit(packet)
+
+ case packet: AIDamage =>
+ logic.shooting.handleAIDamage(packet)
+
+ case packet: AvatarFirstTimeEventMessage =>
+ logic.general.handleAvatarFirstTimeEvent(packet)
+
+ case packet: WarpgateRequest =>
+ data.zoning.handleWarpgateRequest(packet)
+
+ case packet: MountVehicleMsg =>
+ logic.mountResponse.handleMountVehicle(packet)
+
+ case packet: DismountVehicleMsg =>
+ logic.mountResponse.handleDismountVehicle(packet)
+
+ case packet: DeployRequestMessage =>
+ logic.vehicles.handleDeployRequest(packet)
+
+ case packet: AvatarGrenadeStateMessage =>
+ logic.shooting.handleAvatarGrenadeState(packet)
+
+ case packet: SquadDefinitionActionMessage =>
+ logic.squad.handleSquadDefinitionAction(packet)
+
+ case packet: SquadMembershipRequest =>
+ logic.squad.handleSquadMemberRequest(packet)
+
+ case packet: SquadWaypointRequest =>
+ logic.squad.handleSquadWaypointRequest(packet)
+
+ case packet: GenericCollisionMsg =>
+ logic.general.handleGenericCollision(packet)
+
+ case packet: BugReportMessage =>
+ logic.general.handleBugReport(packet)
+
+ case packet: BindPlayerMessage =>
+ logic.general.handleBindPlayer(packet)
+
+ case packet: PlanetsideAttributeMessage =>
+ logic.general.handlePlanetsideAttribute(packet)
+
+ case packet: FacilityBenefitShieldChargeRequestMessage =>
+ logic.general.handleFacilityBenefitShieldChargeRequest(packet)
+
+ case packet: BattleplanMessage =>
+ logic.general.handleBattleplan(packet)
+
+ case packet: CreateShortcutMessage =>
+ logic.general.handleCreateShortcut(packet)
+
+ case packet: ChangeShortcutBankMessage =>
+ logic.general.handleChangeShortcutBank(packet)
+
+ case packet: FriendsRequest =>
+ logic.general.handleFriendRequest(packet)
+
+ case packet: DroppodLaunchRequestMessage =>
+ data.zoning.handleDroppodLaunchRequest(packet)
+
+ case packet: InvalidTerrainMessage =>
+ logic.general.handleInvalidTerrain(packet)
+
+ case packet: ActionCancelMessage =>
+ logic.general.handleActionCancel(packet)
+
+ case packet: TradeMessage =>
+ logic.general.handleTrade(packet)
+
+ case packet: DisplayedAwardMessage =>
+ logic.general.handleDisplayedAward(packet)
+
+ case packet: ObjectDetectedMessage =>
+ logic.general.handleObjectDetected(packet)
+
+ case packet: TargetingImplantRequest =>
+ logic.general.handleTargetingImplantRequest(packet)
+
+ case packet: HitHint =>
+ logic.general.handleHitHint(packet)
+
+ case _: OutfitRequest => ()
+
+ case pkt =>
+ data.log.warn(s"Unhandled GamePacket $pkt")
+ }
}
diff --git a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala
index 0a84b1d3a..6c4460023 100644
--- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala
@@ -395,7 +395,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
avatarActor ! AvatarActor.AwardBep(bep, expType)
}
- case AvatarResponse.AwardCep(charId, cep) =>
+ case AvatarResponse.AwardCep(charId, cep) =>
//if the target player, always award (some) CEP
if (charId == player.CharId) {
avatarActor ! AvatarActor.AwardCep(cep)
@@ -469,7 +469,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
case AvatarResponse.Release(tplayer) if isNotSameTarget =>
sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer)
- case AvatarResponse.Revive(revivalTargetGuid) if resolvedPlayerGuid == revivalTargetGuid =>
+ case AvatarResponse.Revive(revivalTargetGuid)
+ if resolvedPlayerGuid == revivalTargetGuid =>
log.info(s"No time for rest, ${player.Name}. Back on your feet!")
sessionLogic.zoning.spawn.reviveTimer.cancel()
sessionLogic.zoning.spawn.deadState = DeadState.Alive
diff --git a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala
index f50d1e15b..f82492cf2 100644
--- a/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/GalaxyHandlerLogic.scala
@@ -65,12 +65,13 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
case GalaxyResponse.LockedZoneUpdate(zone, time) =>
sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time))
- case GalaxyResponse.UnlockedZoneUpdate(zone) => ;
+ case GalaxyResponse.UnlockedZoneUpdate(zone) =>
sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L))
val popBO = 0
- val popTR = zone.Players.count(_.faction == PlanetSideEmpire.TR)
- val popNC = zone.Players.count(_.faction == PlanetSideEmpire.NC)
- val popVS = zone.Players.count(_.faction == PlanetSideEmpire.VS)
+ val pop = zone.LivePlayers.distinctBy(_.CharId)
+ val popTR = pop.count(_.Faction == PlanetSideEmpire.TR)
+ val popNC = pop.count(_.Faction == PlanetSideEmpire.NC)
+ val popVS = pop.count(_.Faction == PlanetSideEmpire.VS)
sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
case GalaxyResponse.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) =>
diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala
index 812bf74af..e5a7f8417 100644
--- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala
@@ -2,7 +2,7 @@
package net.psforever.actors.session.normal
import akka.actor.typed.scaladsl.adapter._
-import akka.actor.{ActorContext, typed}
+import akka.actor.{ActorContext, ActorRef, typed}
import net.psforever.actors.session.{AvatarActor, SessionActor}
import net.psforever.actors.session.support.{GeneralFunctions, GeneralOperations, SessionData}
import net.psforever.login.WorldSession.{CallBackForTask, ContainableMoveItem, DropEquipmentFromInventory, PickUpEquipmentFromGround, RemoveOldEquipmentFromInventory}
@@ -17,6 +17,7 @@ import net.psforever.objects.guid.{GUIDTask, TaskBundle, TaskWorkflow}
import net.psforever.objects.inventory.Container
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject, ServerObject}
import net.psforever.objects.serverobject.affinity.FactionAffinity
+import net.psforever.objects.serverobject.containable.Containable
import net.psforever.objects.serverobject.doors.Door
import net.psforever.objects.serverobject.generator.Generator
import net.psforever.objects.serverobject.llu.CaptureFlag
@@ -39,7 +40,7 @@ import net.psforever.objects.vital.interaction.DamageInteraction
import net.psforever.objects.zones.{Zone, ZoneProjectile, Zoning}
import net.psforever.packet.PlanetSideGamePacket
import net.psforever.packet.game.objectcreate.ObjectClass
-import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BindStatus, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, ItemTransactionMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
+import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BindStatus, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, ItemTransactionMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
import net.psforever.services.RemoverActor
import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData}
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
@@ -190,19 +191,11 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
}
def handleVoiceHostRequest(pkt: VoiceHostRequest): Unit = {
- log.debug(s"$pkt")
- sendResponse(VoiceHostKill())
- sendResponse(
- ChatMsg(ChatMessageType.CMT_OPEN, wideContents=false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None)
- )
+ ops.noVoicedChat(pkt)
}
def handleVoiceHostInfo(pkt: VoiceHostInfo): Unit = {
- log.debug(s"$pkt")
- sendResponse(VoiceHostKill())
- sendResponse(
- ChatMsg(ChatMessageType.CMT_OPEN, wideContents=false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None)
- )
+ ops.noVoicedChat(pkt)
}
def handleEmote(pkt: EmoteMsg): Unit = {
@@ -269,7 +262,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
//travel along the zipline in the direction specified
sendResponse(ZipLineMessage(playerGuid, forwards, action, pathId, pos))
case 1 =>
- //disembark from zipline at destination!
+ //disembark from zipline at destination
sendResponse(ZipLineMessage(playerGuid, forwards, action, 0, pos))
case 2 =>
//get off by force
@@ -572,11 +565,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
//aphelion_laser discharge (no target)
sessionLogic.shooting.HandleWeaponFireAccountability(objectGuid, PlanetSideGUID(Projectile.baseUID))
} else {
- sessionLogic.validObject(player.VehicleSeated, decorator = "GenericObjectAction/Vehicle") match {
- case Some(vehicle: Vehicle)
+ sessionLogic.validObject(player.VehicleSeated, decorator = "GenericObjectAction/Vehicle") collect {
+ case vehicle: Vehicle
if vehicle.OwnerName.contains(player.Name) =>
vehicle.Actor ! ServerObject.GenericObjectAction(objectGuid, code, Some(tool))
- case _ =>
}
}
case _ =>
@@ -946,6 +938,20 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
/* messages */
+ def handleRenewCharSavedTimer(): Unit = {
+ ops.renewCharSavedTimer(
+ Config.app.game.savedMsg.interruptedByAction.fixed,
+ Config.app.game.savedMsg.interruptedByAction.variable
+ )
+ }
+
+ def handleRenewCharSavedTimerMsg(): Unit = {
+ ops.displayCharSavedMsgThenRenewTimer(
+ Config.app.game.savedMsg.interruptedByAction.fixed,
+ Config.app.game.savedMsg.interruptedByAction.variable
+ )
+ }
+
def handleSetAvatar(avatar: Avatar): Unit = {
session = session.copy(avatar = avatar)
if (session.player != null) {
@@ -991,6 +997,18 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
player.silenced = isSilenced
}
+ def handleItemPutInSlot(msg: Containable.ItemPutInSlot): Unit = {
+ log.debug(s"ItemPutInSlot: $msg")
+ }
+
+ def handleCanNotPutItemInSlot(msg: Containable.CanNotPutItemInSlot): Unit = {
+ log.debug(s"CanNotPutItemInSlot: $msg")
+ }
+
+ def handleReceiveDefaultMessage(default: Any, sender: ActorRef): Unit = {
+ log.warn(s"Invalid packet class received: $default from $sender")
+ }
+
/* supporting functions */
private def handleUseDoor(door: Door, equipment: Option[Equipment]): Unit = {
diff --git a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala
index b638b0d12..8ddb6896b 100644
--- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala
@@ -20,6 +20,16 @@ object LocalHandlerLogic {
class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: ActorContext) extends LocalHandlerFunctions {
def sessionLogic: SessionData = ops.sessionLogic
+ /* messages */
+
+ def handleTurretDeployableIsDismissed(obj: TurretDeployable): Unit = {
+ ops.handleTurretDeployableIsDismissed(obj)
+ }
+
+ def handleDeployableIsDismissed(obj: Deployable): Unit = {
+ ops.handleDeployableIsDismissed(obj)
+ }
+
/* response handlers */
/**
diff --git a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala
index b4325d743..92f4eebef 100644
--- a/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/MountHandlerLogic.scala
@@ -81,7 +81,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
v.SeatPermissionGroup(seat_num).contains(AccessPermissionGroup.Driver) &&
v.isFlying =>
v.Actor ! Vehicle.Deconstruct(None) //immediate deconstruction
- case _ => ;
+ case _ => ()
}
case None =>
diff --git a/src/main/scala/net/psforever/actors/session/normal/NormalMode.scala b/src/main/scala/net/psforever/actors/session/normal/NormalMode.scala
index d6fd141e3..1a88bf9f3 100644
--- a/src/main/scala/net/psforever/actors/session/normal/NormalMode.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/NormalMode.scala
@@ -1,36 +1,8 @@
// Copyright (c) 2024 PSForever
package net.psforever.actors.session.normal
-import akka.actor.Actor.Receive
-import akka.actor.ActorRef
import net.psforever.actors.session.support.{ChatFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
-import net.psforever.objects.Players
-import net.psforever.packet.game.UplinkRequest
-import net.psforever.services.chat.ChatService
-//
-import net.psforever.actors.session.{AvatarActor, SessionActor}
-import net.psforever.actors.session.support.{ModeLogic, PlayerMode, SessionData, ZoningOperations}
-import net.psforever.objects.TurretDeployable
-import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
-import net.psforever.objects.serverobject.CommonMessages
-import net.psforever.objects.serverobject.containable.Containable
-import net.psforever.objects.serverobject.deploy.Deployment
-import net.psforever.objects.serverobject.mount.Mountable
-import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.PlanetSideGamePacket
-import net.psforever.packet.game.{AIDamage, ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarGrenadeStateMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BeginZoningMessage, BindPlayerMessage, BugReportMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ChildObjectStateMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DeployRequestMessage, DismountVehicleCargoMsg, DismountVehicleMsg, DisplayedAwardMessage, DropItemMessage, DroppodLaunchRequestMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FavoritesRequest, FrameVehicleStateMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, HitMessage, InvalidTerrainMessage, ItemTransactionMessage, KeepAliveMessage, LashMessage, LongRangeProjectileInfoMessage, LootItemMessage, MountVehicleCargoMsg, MountVehicleMsg, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, ProjectileStateMessage, ProximityTerminalUseMessage, ReleaseAvatarRequestMessage, ReloadMessage, RequestDestroyMessage, SetChatFilterMessage, SpawnRequestMessage, SplashHitMessage, SquadDefinitionActionMessage, SquadMembershipRequest, SquadWaypointRequest, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VehicleStateMessage, VehicleSubStateMessage, VoiceHostInfo, VoiceHostRequest, WarpgateRequest, WeaponDelayFireMessage, WeaponDryFireMessage, WeaponFireMessage, WeaponLazeTargetPositionMessage, ZipLineMessage}
-import net.psforever.services.{InterstellarClusterService => ICS}
-import net.psforever.services.CavernRotationService
-import net.psforever.services.CavernRotationService.SendCavernRotationUpdates
-import net.psforever.services.ServiceManager.LookupResult
-import net.psforever.services.account.{PlayerToken, ReceiveAccountData}
-import net.psforever.services.avatar.AvatarServiceResponse
-import net.psforever.services.galaxy.GalaxyServiceResponse
-import net.psforever.services.local.LocalServiceResponse
-import net.psforever.services.teamwork.SquadServiceResponse
-import net.psforever.services.vehicle.VehicleServiceResponse
-import net.psforever.util.Config
+import net.psforever.actors.session.support.{ModeLogic, PlayerMode, SessionData}
class NormalModeLogic(data: SessionData) extends ModeLogic {
val avatarResponse: AvatarHandlerLogic = AvatarHandlerLogic(data.avatarResponse)
@@ -44,473 +16,6 @@ class NormalModeLogic(data: SessionData) extends ModeLogic {
val terminals: TerminalHandlerFunctions = TerminalHandlerLogic(data.terminals)
val vehicles: VehicleFunctions = VehicleLogic(data.vehicles)
val vehicleResponse: VehicleHandlerFunctions = VehicleHandlerLogic(data.vehicleResponseOperations)
-
- def parse(sender: ActorRef): Receive = {
- /* really common messages (very frequently, every life) */
- case packet: PlanetSideGamePacket =>
- handleGamePkt(packet)
-
- case AvatarServiceResponse(toChannel, guid, reply) =>
- avatarResponse.handle(toChannel, guid, reply)
-
- case GalaxyServiceResponse(_, reply) =>
- galaxy.handle(reply)
-
- case LocalServiceResponse(toChannel, guid, reply) =>
- local.handle(toChannel, guid, reply)
-
- case Mountable.MountMessages(tplayer, reply) =>
- mountResponse.handle(tplayer, reply)
-
- case SquadServiceResponse(_, excluded, response) =>
- squad.handle(response, excluded)
-
- case Terminal.TerminalMessage(tplayer, msg, order) =>
- terminals.handle(tplayer, msg, order)
-
- case VehicleServiceResponse(toChannel, guid, reply) =>
- vehicleResponse.handle(toChannel, guid, reply)
-
- case ChatService.MessageResponse(fromSession, message, _) =>
- chat.handleIncomingMessage(message, fromSession)
-
- case SessionActor.SendResponse(packet) =>
- data.sendResponse(packet)
-
- case SessionActor.CharSaved =>
- general.ops.renewCharSavedTimer(
- Config.app.game.savedMsg.interruptedByAction.fixed,
- Config.app.game.savedMsg.interruptedByAction.variable
- )
-
- case SessionActor.CharSavedMsg =>
- general.ops.displayCharSavedMsgThenRenewTimer(
- Config.app.game.savedMsg.renewal.fixed,
- Config.app.game.savedMsg.renewal.variable
- )
-
- /* common messages (maybe once every respawn) */
- case ICS.SpawnPointResponse(response) =>
- data.zoning.handleSpawnPointResponse(response)
-
- case SessionActor.NewPlayerLoaded(tplayer) =>
- data.zoning.spawn.handleNewPlayerLoaded(tplayer)
-
- case SessionActor.PlayerLoaded(tplayer) =>
- data.zoning.spawn.handlePlayerLoaded(tplayer)
-
- case Zone.Population.PlayerHasLeft(zone, None) =>
- data.log.debug(s"PlayerHasLeft: ${data.player.Name} does not have a body on ${zone.id}")
-
- case Zone.Population.PlayerHasLeft(zone, Some(tplayer)) =>
- if (tplayer.isAlive) {
- data.log.info(s"${tplayer.Name} has left zone ${zone.id}")
- }
-
- case Zone.Population.PlayerCanNotSpawn(zone, tplayer) =>
- data.log.warn(s"${tplayer.Name} can not spawn in zone ${zone.id}; why?")
-
- case Zone.Population.PlayerAlreadySpawned(zone, tplayer) =>
- data.log.warn(s"${tplayer.Name} is already spawned on zone ${zone.id}; is this a clerical error?")
-
- case Zone.Vehicle.CanNotSpawn(zone, vehicle, reason) =>
- data.log.warn(
- s"${data.player.Name}'s ${vehicle.Definition.Name} can not spawn in ${zone.id} because $reason"
- )
-
- case Zone.Vehicle.CanNotDespawn(zone, vehicle, reason) =>
- data.log.warn(
- s"${data.player.Name}'s ${vehicle.Definition.Name} can not deconstruct in ${zone.id} because $reason"
- )
-
- case ICS.ZoneResponse(Some(zone)) =>
- data.zoning.handleZoneResponse(zone)
-
- /* uncommon messages (once a session) */
- case ICS.ZonesResponse(zones) =>
- data.zoning.handleZonesResponse(zones)
-
- case SessionActor.SetAvatar(avatar) =>
- general.handleSetAvatar(avatar)
-
- case PlayerToken.LoginInfo(name, Zone.Nowhere, _) =>
- data.zoning.spawn.handleLoginInfoNowhere(name, sender)
-
- case PlayerToken.LoginInfo(name, inZone, optionalSavedData) =>
- data.zoning.spawn.handleLoginInfoSomewhere(name, inZone, optionalSavedData, sender)
-
- case PlayerToken.RestoreInfo(playerName, inZone, pos) =>
- data.zoning.spawn.handleLoginInfoRestore(playerName, inZone, pos, sender)
-
- case PlayerToken.CanNotLogin(playerName, reason) =>
- data.zoning.spawn.handleLoginCanNot(playerName, reason)
-
- case ReceiveAccountData(account) =>
- general.handleReceiveAccountData(account)
-
- case AvatarActor.AvatarResponse(avatar) =>
- general.handleAvatarResponse(avatar)
-
- case AvatarActor.AvatarLoginResponse(avatar) =>
- data.zoning.spawn.avatarLoginResponse(avatar)
-
- case SessionActor.SetCurrentAvatar(tplayer, max_attempts, attempt) =>
- data.zoning.spawn.ReadyToSetCurrentAvatar(tplayer, max_attempts, attempt)
-
- case SessionActor.SetConnectionState(state) =>
- data.connectionState = state
-
- case SessionActor.AvatarLoadingSync(state) =>
- data.zoning.spawn.handleAvatarLoadingSync(state)
-
- /* uncommon messages (utility, or once in a while) */
- case ZoningOperations.AvatarAwardMessageBundle(pkts, delay) =>
- data.zoning.spawn.performAvatarAwardMessageDelivery(pkts, delay)
-
- case CommonMessages.ProgressEvent(delta, finishedAction, stepAction, tick) =>
- general.ops.handleProgressChange(delta, finishedAction, stepAction, tick)
-
- case CommonMessages.Progress(rate, finishedAction, stepAction) =>
- general.ops.setupProgressChange(rate, finishedAction, stepAction)
-
- case CavernRotationService.CavernRotationServiceKey.Listing(listings) =>
- listings.head ! SendCavernRotationUpdates(data.context.self)
-
- case LookupResult("propertyOverrideManager", endpoint) =>
- data.zoning.propertyOverrideManagerLoadOverrides(endpoint)
-
- case SessionActor.UpdateIgnoredPlayers(msg) =>
- galaxy.handleUpdateIgnoredPlayers(msg)
-
- case SessionActor.UseCooldownRenewed(definition, _) =>
- general.handleUseCooldownRenew(definition)
-
- case Deployment.CanDeploy(obj, state) =>
- vehicles.handleCanDeploy(obj, state)
-
- case Deployment.CanUndeploy(obj, state) =>
- vehicles.handleCanUndeploy(obj, state)
-
- case Deployment.CanNotChangeDeployment(obj, state, reason) =>
- vehicles.handleCanNotChangeDeployment(obj, state, reason)
-
- /* rare messages */
- case ProximityUnit.StopAction(term, _) =>
- terminals.ops.LocalStopUsingProximityUnit(term)
-
- case SessionActor.Suicide() =>
- general.ops.suicide(data.player)
-
- case SessionActor.Recall() =>
- data.zoning.handleRecall()
-
- case SessionActor.InstantAction() =>
- data.zoning.handleInstantAction()
-
- case SessionActor.Quit() =>
- data.zoning.handleQuit()
-
- case ICS.DroppodLaunchDenial(errorCode, _) =>
- data.zoning.handleDroppodLaunchDenial(errorCode)
-
- case ICS.DroppodLaunchConfirmation(zone, position) =>
- data.zoning.LoadZoneLaunchDroppod(zone, position)
-
- case SessionActor.PlayerFailedToLoad(tplayer) =>
- data.failWithError(s"${tplayer.Name} failed to load anywhere")
-
- /* csr only */
- case SessionActor.SetSpeed(speed) =>
- general.handleSetSpeed(speed)
-
- case SessionActor.SetFlying(isFlying) =>
- general.handleSetFlying(isFlying)
-
- case SessionActor.SetSpectator(isSpectator) =>
- general.handleSetSpectator(isSpectator)
-
- case SessionActor.Kick(player, time) =>
- general.handleKick(player, time)
-
- case SessionActor.SetZone(zoneId, position) =>
- data.zoning.handleSetZone(zoneId, position)
-
- case SessionActor.SetPosition(position) =>
- data.zoning.spawn.handleSetPosition(position)
-
- case SessionActor.SetSilenced(silenced) =>
- general.handleSilenced(silenced)
-
- /* catch these messages */
- case _: ProximityUnit.Action => ;
-
- case _: Zone.Vehicle.HasSpawned => ;
-
- case _: Zone.Vehicle.HasDespawned => ;
-
- case Zone.Deployable.IsDismissed(obj: TurretDeployable) => //only if target deployable was never fully introduced
- Players.buildCooldownReset(data.continent, data.player.Name, obj)
- TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(data.continent.GUID, obj))
-
- case Zone.Deployable.IsDismissed(obj) => //only if target deployable was never fully introduced
- Players.buildCooldownReset(data.continent, data.player.Name, obj)
- TaskWorkflow.execute(GUIDTask.unregisterObject(data.continent.GUID, obj))
-
- case msg: Containable.ItemPutInSlot =>
- data.log.debug(s"ItemPutInSlot: $msg")
-
- case msg: Containable.CanNotPutItemInSlot =>
- data.log.debug(s"CanNotPutItemInSlot: $msg")
-
- case default =>
- data.log.warn(s"Invalid packet class received: $default from $sender")
- }
-
- private def handleGamePkt: PlanetSideGamePacket => Unit = {
- case packet: ConnectToWorldRequestMessage =>
- general.handleConnectToWorldRequest(packet)
-
- case packet: MountVehicleCargoMsg =>
- mountResponse.handleMountVehicleCargo(packet)
-
- case packet: DismountVehicleCargoMsg =>
- mountResponse.handleDismountVehicleCargo(packet)
-
- case packet: CharacterCreateRequestMessage =>
- general.handleCharacterCreateRequest(packet)
-
- case packet: CharacterRequestMessage =>
- general.handleCharacterRequest(packet)
-
- case _: KeepAliveMessage =>
- data.keepAliveFunc()
-
- case packet: BeginZoningMessage =>
- data.zoning.handleBeginZoning(packet)
-
- case packet: PlayerStateMessageUpstream =>
- general.handlePlayerStateUpstream(packet)
-
- case packet: ChildObjectStateMessage =>
- vehicles.handleChildObjectState(packet)
-
- case packet: VehicleStateMessage =>
- vehicles.handleVehicleState(packet)
-
- case packet: VehicleSubStateMessage =>
- vehicles.handleVehicleSubState(packet)
-
- case packet: FrameVehicleStateMessage =>
- vehicles.handleFrameVehicleState(packet)
-
- case packet: ProjectileStateMessage =>
- shooting.handleProjectileState(packet)
-
- case packet: LongRangeProjectileInfoMessage =>
- shooting.handleLongRangeProjectileState(packet)
-
- case packet: ReleaseAvatarRequestMessage =>
- data.zoning.spawn.handleReleaseAvatarRequest(packet)
-
- case packet: SpawnRequestMessage =>
- data.zoning.spawn.handleSpawnRequest(packet)
-
- case packet: ChatMsg =>
- chat.handleChatMsg(packet)
-
- case packet: SetChatFilterMessage =>
- chat.handleChatFilter(packet)
-
- case packet: VoiceHostRequest =>
- general.handleVoiceHostRequest(packet)
-
- case packet: VoiceHostInfo =>
- general.handleVoiceHostInfo(packet)
-
- case packet: ChangeAmmoMessage =>
- shooting.handleChangeAmmo(packet)
-
- case packet: ChangeFireModeMessage =>
- shooting.handleChangeFireMode(packet)
-
- case packet: ChangeFireStateMessage_Start =>
- shooting.handleChangeFireStateStart(packet)
-
- case packet: ChangeFireStateMessage_Stop =>
- shooting.handleChangeFireStateStop(packet)
-
- case packet: EmoteMsg =>
- general.handleEmote(packet)
-
- case packet: DropItemMessage =>
- general.handleDropItem(packet)
-
- case packet: PickupItemMessage =>
- general.handlePickupItem(packet)
-
- case packet: ReloadMessage =>
- shooting.handleReload(packet)
-
- case packet: ObjectHeldMessage =>
- general.handleObjectHeld(packet)
-
- case packet: AvatarJumpMessage =>
- general.handleAvatarJump(packet)
-
- case packet: ZipLineMessage =>
- general.handleZipLine(packet)
-
- case packet: RequestDestroyMessage =>
- general.handleRequestDestroy(packet)
-
- case packet: MoveItemMessage =>
- general.handleMoveItem(packet)
-
- case packet: LootItemMessage =>
- general.handleLootItem(packet)
-
- case packet: AvatarImplantMessage =>
- general.handleAvatarImplant(packet)
-
- case packet: UseItemMessage =>
- general.handleUseItem(packet)
-
- case packet: UnuseItemMessage =>
- general.handleUnuseItem(packet)
-
- case packet: ProximityTerminalUseMessage =>
- terminals.handleProximityTerminalUse(packet)
-
- case packet: DeployObjectMessage =>
- general.handleDeployObject(packet)
-
- case packet: GenericObjectActionMessage =>
- general.handleGenericObjectAction(packet)
-
- case packet: GenericObjectActionAtPositionMessage =>
- general.handleGenericObjectActionAtPosition(packet)
-
- case packet: GenericObjectStateMsg =>
- general.handleGenericObjectState(packet)
-
- case packet: GenericActionMessage =>
- general.handleGenericAction(packet)
-
- case packet: ItemTransactionMessage =>
- terminals.handleItemTransaction(packet)
-
- case packet: FavoritesRequest =>
- terminals.handleFavoritesRequest(packet)
-
- case packet: WeaponDelayFireMessage =>
- shooting.handleWeaponDelayFire(packet)
-
- case packet: WeaponDryFireMessage =>
- shooting.handleWeaponDryFire(packet)
-
- case packet: WeaponFireMessage =>
- shooting.handleWeaponFire(packet)
-
- case packet: WeaponLazeTargetPositionMessage =>
- shooting.handleWeaponLazeTargetPosition(packet)
-
- case _: UplinkRequest => ()
-
- case packet: HitMessage =>
- shooting.handleDirectHit(packet)
-
- case packet: SplashHitMessage =>
- shooting.handleSplashHit(packet)
-
- case packet: LashMessage =>
- shooting.handleLashHit(packet)
-
- case packet: AIDamage =>
- shooting.handleAIDamage(packet)
-
- case packet: AvatarFirstTimeEventMessage =>
- general.handleAvatarFirstTimeEvent(packet)
-
- case packet: WarpgateRequest =>
- data.zoning.handleWarpgateRequest(packet)
-
- case packet: MountVehicleMsg =>
- mountResponse.handleMountVehicle(packet)
-
- case packet: DismountVehicleMsg =>
- mountResponse.handleDismountVehicle(packet)
-
- case packet: DeployRequestMessage =>
- vehicles.handleDeployRequest(packet)
-
- case packet: AvatarGrenadeStateMessage =>
- shooting.handleAvatarGrenadeState(packet)
-
- case packet: SquadDefinitionActionMessage =>
- squad.handleSquadDefinitionAction(packet)
-
- case packet: SquadMembershipRequest =>
- squad.handleSquadMemberRequest(packet)
-
- case packet: SquadWaypointRequest =>
- squad.handleSquadWaypointRequest(packet)
-
- case packet: GenericCollisionMsg =>
- general.handleGenericCollision(packet)
-
- case packet: BugReportMessage =>
- general.handleBugReport(packet)
-
- case packet: BindPlayerMessage =>
- general.handleBindPlayer(packet)
-
- case packet: PlanetsideAttributeMessage =>
- general.handlePlanetsideAttribute(packet)
-
- case packet: FacilityBenefitShieldChargeRequestMessage =>
- general.handleFacilityBenefitShieldChargeRequest(packet)
-
- case packet: BattleplanMessage =>
- general.handleBattleplan(packet)
-
- case packet: CreateShortcutMessage =>
- general.handleCreateShortcut(packet)
-
- case packet: ChangeShortcutBankMessage =>
- general.handleChangeShortcutBank(packet)
-
- case packet: FriendsRequest =>
- general.handleFriendRequest(packet)
-
- case packet: DroppodLaunchRequestMessage =>
- data.zoning.handleDroppodLaunchRequest(packet)
-
- case packet: InvalidTerrainMessage =>
- general.handleInvalidTerrain(packet)
-
- case packet: ActionCancelMessage =>
- general.handleActionCancel(packet)
-
- case packet: TradeMessage =>
- general.handleTrade(packet)
-
- case packet: DisplayedAwardMessage =>
- general.handleDisplayedAward(packet)
-
- case packet: ObjectDetectedMessage =>
- general.handleObjectDetected(packet)
-
- case packet: TargetingImplantRequest =>
- general.handleTargetingImplantRequest(packet)
-
- case packet: HitHint =>
- general.handleHitHint(packet)
-
- case _: OutfitRequest => ()
-
- case pkt =>
- data.log.warn(s"Unhandled GamePacket $pkt")
- }
}
case object NormalMode extends PlayerMode {
diff --git a/src/main/scala/net/psforever/actors/session/normal/TerminalHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/TerminalHandlerLogic.scala
index 5b6618562..bf9eb1dc7 100644
--- a/src/main/scala/net/psforever/actors/session/normal/TerminalHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/TerminalHandlerLogic.scala
@@ -112,7 +112,7 @@ class TerminalHandlerLogic(val ops: SessionTerminalHandlers, implicit val contex
ops.lastTerminalOrderFulfillment = true
case Terminal.BuyVehicle(vehicle, _, _)
- if tplayer.avatar.purchaseCooldown(vehicle.Definition).nonEmpty || tplayer.spectator =>
+ if tplayer.avatar.purchaseCooldown(vehicle.Definition).nonEmpty =>
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, success = false))
ops.lastTerminalOrderFulfillment = true
diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala
index f6fe40c83..fdc8c1180 100644
--- a/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/VehicleLogic.scala
@@ -5,7 +5,7 @@ import akka.actor.{ActorContext, typed}
import net.psforever.actors.session.AvatarActor
import net.psforever.actors.session.support.{SessionData, VehicleFunctions, VehicleOperations}
import net.psforever.objects.serverobject.PlanetSideServerObject
-import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle, Vehicles}
+import net.psforever.objects.{Vehicle, Vehicles}
import net.psforever.objects.serverobject.deploy.Deployment
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.objects.vehicles.control.BfrFlight
@@ -41,7 +41,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
is_decelerating,
is_cloaked
) = pkt
- GetVehicleAndSeat() match {
+ ops.GetVehicleAndSeat() match {
case (Some(obj), Some(0)) =>
//we're driving the vehicle
sessionLogic.persist()
@@ -100,7 +100,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
log.error(
s"VehicleState: ${player.Name} should not be dispatching this kind of packet from vehicle ${vehicle_guid.guid} when not the driver (actually, seat $index)"
)
- case _ => ;
+ case _ => ()
}
if (player.death_by == -1) {
sessionLogic.kickedByAdministration()
@@ -124,7 +124,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
unk9,
unkA
) = pkt
- GetVehicleAndSeat() match {
+ ops.GetVehicleAndSeat() match {
case (Some(obj), Some(0)) =>
//we're driving the vehicle
sessionLogic.persist()
@@ -198,7 +198,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
log.error(
s"VehicleState: ${player.Name} should not be dispatching this kind of packet from vehicle ${vehicle_guid.guid} when not the driver (actually, seat $index)"
)
- case _ => ;
+ case _ => ()
}
if (player.death_by == -1) {
sessionLogic.kickedByAdministration()
@@ -213,7 +213,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
case Some(mount: Mountable) => (o, mount.PassengerInSeat(player))
case _ => (None, None)
}) match {
- case (None, None) | (_, None) | (Some(_: Vehicle), Some(0)) => ;
+ case (None, None) | (_, None) | (Some(_: Vehicle), Some(0)) => ()
case _ =>
sessionLogic.persist()
sessionLogic.turnCounterFunc(player.GUID)
@@ -241,33 +241,33 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
def handleVehicleSubState(pkt: VehicleSubStateMessage): Unit = {
val VehicleSubStateMessage(vehicle_guid, _, pos, ang, vel, unk1, _) = pkt
- sessionLogic.validObject(vehicle_guid, decorator = "VehicleSubState") match {
- case Some(obj: Vehicle) =>
- import net.psforever.login.WorldSession.boolToInt
- obj.Position = pos
- obj.Orientation = ang
- obj.Velocity = vel
- sessionLogic.updateBlockMap(obj, pos)
- obj.zoneInteractions()
- continent.VehicleEvents ! VehicleServiceMessage(
- continent.id,
- VehicleAction.VehicleState(
- player.GUID,
- vehicle_guid,
- unk1,
- pos,
- ang,
- obj.Velocity,
- obj.Flying,
- 0,
- 0,
- 15,
- unk5 = false,
- obj.Cloaked
+ sessionLogic.validObject(vehicle_guid, decorator = "VehicleSubState")
+ .collect {
+ case obj: Vehicle =>
+ import net.psforever.login.WorldSession.boolToInt
+ obj.Position = pos
+ obj.Orientation = ang
+ obj.Velocity = vel
+ sessionLogic.updateBlockMap(obj, pos)
+ obj.zoneInteractions()
+ continent.VehicleEvents ! VehicleServiceMessage(
+ continent.id,
+ VehicleAction.VehicleState(
+ player.GUID,
+ vehicle_guid,
+ unk1,
+ pos,
+ ang,
+ obj.Velocity,
+ obj.Flying,
+ 0,
+ 0,
+ 15,
+ unk5 = false,
+ obj.Cloaked
+ )
)
- )
- case _ => ()
- }
+ }
}
def handleDeployRequest(pkt: DeployRequestMessage): Unit = {
@@ -329,46 +329,6 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
/* support functions */
- /**
- * If the player is mounted in some entity, find that entity and get the mount index number at which the player is sat.
- * The priority of object confirmation is `direct` then `occupant.VehicleSeated`.
- * Once an object is found, the remainder are ignored.
- * @param direct a game object in which the player may be sat
- * @param occupant the player who is sat and may have specified the game object in which mounted
- * @return a tuple consisting of a vehicle reference and a mount index
- * if and only if the vehicle is known to this client and the `WorldSessioNActor`-global `player` occupies it;
- * `(None, None)`, otherwise (even if the vehicle can be determined)
- */
- private def GetMountableAndSeat(
- direct: Option[PlanetSideGameObject with Mountable],
- occupant: Player,
- zone: Zone
- ): (Option[PlanetSideGameObject with Mountable], Option[Int]) =
- direct.orElse(zone.GUID(occupant.VehicleSeated)) match {
- case Some(obj: PlanetSideGameObject with Mountable) =>
- obj.PassengerInSeat(occupant) match {
- case index @ Some(_) =>
- (Some(obj), index)
- case None =>
- (None, None)
- }
- case _ =>
- (None, None)
- }
-
- /**
- * If the player is seated in a vehicle, find that vehicle and get the mount index number at which the player is sat.
- * @see `GetMountableAndSeat`
- * @return a tuple consisting of a vehicle reference and a mount index
- * if and only if the vehicle is known to this client and the `WorldSessioNActor`-global `player` occupies it;
- * `(None, None)`, otherwise (even if the vehicle can be determined)
- */
- private def GetVehicleAndSeat(): (Option[Vehicle], Option[Int]) =
- GetMountableAndSeat(None, player, continent) match {
- case (Some(v: Vehicle), Some(seat)) => (Some(v), Some(seat))
- case _ => (None, None)
- }
-
/**
* Common reporting behavior when a `Deployment` object fails to properly transition between states.
* @param obj the game object that could not
diff --git a/src/main/scala/net/psforever/actors/session/normal/WeaponAndProjectileLogic.scala b/src/main/scala/net/psforever/actors/session/normal/WeaponAndProjectileLogic.scala
index 38f398828..05608922b 100644
--- a/src/main/scala/net/psforever/actors/session/normal/WeaponAndProjectileLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/normal/WeaponAndProjectileLogic.scala
@@ -88,6 +88,7 @@ object WeaponAndProjectileLogic {
Seq(start + endStart * (sqrt - b), start + endStart * (b + sqrt) * -1f)
}.filter(p => Vector3.DistanceSquared(start, p) <= a)
}
+
/**
* Preparation for explosion damage that utilizes the Scorpion's little buddy sub-projectiles.
* The main difference from "normal" server-side explosion
@@ -497,9 +498,7 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
}
if (profile.ExistsOnRemoteClients && projectile.HasGUID) {
//cleanup
- if (projectile.HasGUID) {
- continent.Projectile ! ZoneProjectile.Remove(projectile.GUID)
- }
+ continent.Projectile ! ZoneProjectile.Remove(projectile.GUID)
}
case None => ()
}
diff --git a/src/main/scala/net/psforever/actors/session/spectator/GalaxyHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GalaxyHandlerLogic.scala
index 7ecff65b9..d3b6abf63 100644
--- a/src/main/scala/net/psforever/actors/session/spectator/GalaxyHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/spectator/GalaxyHandlerLogic.scala
@@ -65,7 +65,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
case GalaxyResponse.LockedZoneUpdate(zone, time) =>
sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time))
- case GalaxyResponse.UnlockedZoneUpdate(zone) => ;
+ case GalaxyResponse.UnlockedZoneUpdate(zone) =>
sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L))
val popBO = 0
val popTR = zone.Players.count(_.faction == PlanetSideEmpire.TR)
diff --git a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala
index 2332b5115..806747a5a 100644
--- a/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/spectator/GeneralLogic.scala
@@ -1,7 +1,7 @@
// Copyright (c) 2024 PSForever
package net.psforever.actors.session.spectator
-import akka.actor.{ActorContext, typed}
+import akka.actor.{ActorContext, ActorRef, typed}
import net.psforever.actors.session.AvatarActor
import net.psforever.actors.session.support.{GeneralFunctions, GeneralOperations, SessionData}
import net.psforever.objects.{Account, GlobalDefinitions, LivePlayerList, PlanetSideGameObject, Player, TelepadDeployable, Tool, Vehicle}
@@ -11,15 +11,16 @@ import net.psforever.objects.ce.{Deployable, TelepadLike}
import net.psforever.objects.definition.{BasicDefinition, KitDefinition, SpecialExoSuitDefinition}
import net.psforever.objects.equipment.Equipment
import net.psforever.objects.serverobject.CommonMessages
+import net.psforever.objects.serverobject.containable.Containable
import net.psforever.objects.serverobject.doors.Door
import net.psforever.objects.vehicles.{Utility, UtilityType}
import net.psforever.objects.vehicles.Utility.InternalTelepad
import net.psforever.objects.zones.ZoneProjectile
import net.psforever.packet.PlanetSideGamePacket
-import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
+import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
import net.psforever.services.account.AccountPersistenceService
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
-import net.psforever.types.{ChatMessageType, DriveState, ExoSuitType, PlanetSideGUID, Vector3}
+import net.psforever.types.{DriveState, ExoSuitType, PlanetSideGUID, Vector3}
import net.psforever.util.Config
object GeneralLogic {
@@ -79,19 +80,11 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
}
def handleVoiceHostRequest(pkt: VoiceHostRequest): Unit = {
- log.debug(s"$pkt")
- sendResponse(VoiceHostKill())
- sendResponse(
- ChatMsg(ChatMessageType.CMT_OPEN, wideContents=false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None)
- )
+ ops.noVoicedChat(pkt)
}
def handleVoiceHostInfo(pkt: VoiceHostInfo): Unit = {
- log.debug(s"$pkt")
- sendResponse(VoiceHostKill())
- sendResponse(
- ChatMsg(ChatMessageType.CMT_OPEN, wideContents=false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None)
- )
+ ops.noVoicedChat(pkt)
}
def handleEmote(pkt: EmoteMsg): Unit = {
@@ -410,6 +403,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
/* messages */
+ def handleRenewCharSavedTimer(): Unit = { /* intentionally blank */ }
+
+ def handleRenewCharSavedTimerMsg(): Unit = { /* intentionally blank */ }
+
def handleSetAvatar(avatar: Avatar): Unit = {
session = session.copy(avatar = avatar)
if (session.player != null) {
@@ -455,6 +452,12 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
player.silenced = isSilenced
}
+ def handleItemPutInSlot(msg: Containable.ItemPutInSlot): Unit = { /* intentionally blank */ }
+
+ def handleCanNotPutItemInSlot(msg: Containable.CanNotPutItemInSlot): Unit = { /* intentionally blank */ }
+
+ def handleReceiveDefaultMessage(default: Any, sender: ActorRef): Unit = { /* intentionally blank */ }
+
/* supporting functions */
private def handleUseDoor(door: Door, equipment: Option[Equipment]): Unit = {
diff --git a/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala
index e0406f564..21d85d7a1 100644
--- a/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala
@@ -4,6 +4,7 @@ package net.psforever.actors.session.spectator
import akka.actor.ActorContext
import net.psforever.actors.session.support.{LocalHandlerFunctions, SessionData, SessionLocalHandlers}
import net.psforever.objects.ce.Deployable
+import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
import net.psforever.objects.vehicles.MountableWeapons
import net.psforever.objects.{BoomerDeployable, ExplosiveDeployable, TelepadDeployable, Tool, TurretDeployable}
import net.psforever.packet.game.{ChatMsg, DeployableObjectsInfoMessage, GenericActionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HackMessage, HackState, InventoryStateMessage, ObjectAttachMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, OrbitalShuttleTimeMsg, PadAndShuttlePair, PlanetsideAttributeMessage, ProximityTerminalUseMessage, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage}
@@ -20,6 +21,16 @@ object LocalHandlerLogic {
class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: ActorContext) extends LocalHandlerFunctions {
def sessionLogic: SessionData = ops.sessionLogic
+ /* messages */
+
+ def handleTurretDeployableIsDismissed(obj: TurretDeployable): Unit = {
+ TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(continent.GUID, obj))
+ }
+
+ def handleDeployableIsDismissed(obj: Deployable): Unit = {
+ TaskWorkflow.execute(GUIDTask.unregisterObject(continent.GUID, obj))
+ }
+
/* response handlers */
/**
diff --git a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala
index f5a6caea8..f6c3a4a43 100644
--- a/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/spectator/MountHandlerLogic.scala
@@ -66,7 +66,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
v.SeatPermissionGroup(seat_num).contains(AccessPermissionGroup.Driver) &&
v.isFlying =>
v.Actor ! Vehicle.Deconstruct(None) //immediate deconstruction
- case _ => ;
+ case _ => ()
}
case None =>
diff --git a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala
index 2f5647711..b950274db 100644
--- a/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala
+++ b/src/main/scala/net/psforever/actors/session/spectator/SpectatorMode.scala
@@ -1,8 +1,6 @@
// Copyright (c) 2024 PSForever
package net.psforever.actors.session.spectator
-import akka.actor.Actor.Receive
-import akka.actor.ActorRef
import net.psforever.actors.session.support.{AvatarHandlerFunctions, ChatFunctions, GalaxyHandlerFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
import net.psforever.actors.zone.ZoneActor
import net.psforever.objects.avatar.{BattleRank, CommandRank, DeployableToolbox, FirstTimeEvents, Implant, ProgressDecoration, Shortcut => AvatarShortcut}
@@ -14,32 +12,14 @@ import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage,
import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars}
import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
-import net.psforever.services.chat.{ChatService, SpectatorChannel}
+import net.psforever.services.chat.SpectatorChannel
import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage}
import net.psforever.types.{CapacitorStateType, ChatMessageType, ExoSuitType, MeritCommendation, SquadRequestType}
//
-import net.psforever.actors.session.{AvatarActor, SessionActor}
-import net.psforever.actors.session.support.{ModeLogic, PlayerMode, SessionData, ZoningOperations}
-import net.psforever.objects.TurretDeployable
-import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
-import net.psforever.objects.serverobject.CommonMessages
-import net.psforever.objects.serverobject.containable.Containable
-import net.psforever.objects.serverobject.deploy.Deployment
-import net.psforever.objects.serverobject.mount.Mountable
+import net.psforever.actors.session.AvatarActor
+import net.psforever.actors.session.support.{ModeLogic, PlayerMode, SessionData}
import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
-import net.psforever.objects.zones.Zone
-import net.psforever.packet.PlanetSideGamePacket
-import net.psforever.packet.game.{AIDamage, ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarGrenadeStateMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BeginZoningMessage, BindPlayerMessage, BugReportMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ChildObjectStateMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DeployRequestMessage, DismountVehicleCargoMsg, DismountVehicleMsg, DisplayedAwardMessage, DropItemMessage, DroppodLaunchRequestMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FavoritesRequest, FrameVehicleStateMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, HitMessage, InvalidTerrainMessage, ItemTransactionMessage, KeepAliveMessage, LashMessage, LongRangeProjectileInfoMessage, LootItemMessage, MountVehicleCargoMsg, MountVehicleMsg, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, ProjectileStateMessage, ProximityTerminalUseMessage, ReleaseAvatarRequestMessage, ReloadMessage, RequestDestroyMessage, SetChatFilterMessage, SpawnRequestMessage, SplashHitMessage, SquadDefinitionActionMessage, SquadMembershipRequest, SquadWaypointRequest, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UplinkRequest, UseItemMessage, VehicleStateMessage, VehicleSubStateMessage, VoiceHostInfo, VoiceHostRequest, WarpgateRequest, WeaponDelayFireMessage, WeaponDryFireMessage, WeaponFireMessage, WeaponLazeTargetPositionMessage, ZipLineMessage}
-import net.psforever.services.{InterstellarClusterService => ICS}
-import net.psforever.services.CavernRotationService
-import net.psforever.services.CavernRotationService.SendCavernRotationUpdates
-import net.psforever.services.ServiceManager.LookupResult
-import net.psforever.services.account.{PlayerToken, ReceiveAccountData}
-import net.psforever.services.avatar.AvatarServiceResponse
-import net.psforever.services.galaxy.GalaxyServiceResponse
-import net.psforever.services.local.LocalServiceResponse
-import net.psforever.services.teamwork.SquadServiceResponse
-import net.psforever.services.vehicle.VehicleServiceResponse
+import net.psforever.packet.game.{ChatMsg, CreateShortcutMessage, UnuseItemMessage}
class SpectatorModeLogic(data: SessionData) extends ModeLogic {
val avatarResponse: AvatarHandlerFunctions = AvatarHandlerLogic(data.avatarResponse)
@@ -186,463 +166,6 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
zoning.zoneReload = true
zoning.spawn.randomRespawn(0.seconds) //to sanctuary
}
-
- def parse(sender: ActorRef): Receive = {
- /* really common messages (very frequently, every life) */
- case packet: PlanetSideGamePacket =>
- handleGamePkt(packet)
-
- case AvatarServiceResponse(toChannel, guid, reply) =>
- avatarResponse.handle(toChannel, guid, reply)
-
- case GalaxyServiceResponse(_, reply) =>
- galaxy.handle(reply)
-
- case LocalServiceResponse(toChannel, guid, reply) =>
- local.handle(toChannel, guid, reply)
-
- case Mountable.MountMessages(tplayer, reply) =>
- mountResponse.handle(tplayer, reply)
-
- case SquadServiceResponse(_, excluded, response) =>
- squad.handle(response, excluded)
-
- case Terminal.TerminalMessage(tplayer, msg, order) =>
- terminals.handle(tplayer, msg, order)
-
- case VehicleServiceResponse(toChannel, guid, reply) =>
- vehicleResponse.handle(toChannel, guid, reply)
-
- case ChatService.MessageResponse(fromSession, message, _) =>
- chat.handleIncomingMessage(message, fromSession)
-
- case SessionActor.SendResponse(packet) =>
- data.sendResponse(packet)
-
- case SessionActor.CharSaved => ()
-
- case SessionActor.CharSavedMsg => ()
-
- /* common messages (maybe once every respawn) */
- case ICS.SpawnPointResponse(response) =>
- data.zoning.handleSpawnPointResponse(response)
-
- case SessionActor.NewPlayerLoaded(tplayer) =>
- data.zoning.spawn.handleNewPlayerLoaded(tplayer)
-
- case SessionActor.PlayerLoaded(tplayer) =>
- data.zoning.spawn.handlePlayerLoaded(tplayer)
-
- case Zone.Population.PlayerHasLeft(zone, None) =>
- data.log.debug(s"PlayerHasLeft: ${data.player.Name} does not have a body on ${zone.id}")
-
- case Zone.Population.PlayerHasLeft(zone, Some(tplayer)) =>
- if (tplayer.isAlive) {
- data.log.info(s"${tplayer.Name} has left zone ${zone.id}")
- }
-
- case Zone.Population.PlayerCanNotSpawn(zone, tplayer) =>
- data.log.warn(s"${tplayer.Name} can not spawn in zone ${zone.id}; why?")
-
- case Zone.Population.PlayerAlreadySpawned(zone, tplayer) =>
- data.log.warn(s"${tplayer.Name} is already spawned on zone ${zone.id}; is this a clerical error?")
-
- case Zone.Vehicle.CanNotSpawn(zone, vehicle, reason) =>
- data.log.warn(
- s"${data.player.Name}'s ${vehicle.Definition.Name} can not spawn in ${zone.id} because $reason"
- )
-
- case Zone.Vehicle.CanNotDespawn(zone, vehicle, reason) =>
- data.log.warn(
- s"${data.player.Name}'s ${vehicle.Definition.Name} can not deconstruct in ${zone.id} because $reason"
- )
-
- case ICS.ZoneResponse(Some(zone)) =>
- data.zoning.handleZoneResponse(zone)
-
- /* uncommon messages (once a session) */
- case ICS.ZonesResponse(zones) =>
- data.zoning.handleZonesResponse(zones)
-
- case SessionActor.SetAvatar(avatar) =>
- general.handleSetAvatar(avatar)
-
- case PlayerToken.LoginInfo(name, Zone.Nowhere, _) =>
- data.zoning.spawn.handleLoginInfoNowhere(name, sender)
-
- case PlayerToken.LoginInfo(name, inZone, optionalSavedData) =>
- data.zoning.spawn.handleLoginInfoSomewhere(name, inZone, optionalSavedData, sender)
-
- case PlayerToken.RestoreInfo(playerName, inZone, pos) =>
- data.zoning.spawn.handleLoginInfoRestore(playerName, inZone, pos, sender)
-
- case PlayerToken.CanNotLogin(playerName, reason) =>
- data.zoning.spawn.handleLoginCanNot(playerName, reason)
-
- case ReceiveAccountData(account) =>
- general.handleReceiveAccountData(account)
-
- case AvatarActor.AvatarResponse(avatar) =>
- general.handleAvatarResponse(avatar)
-
- case AvatarActor.AvatarLoginResponse(avatar) =>
- data.zoning.spawn.avatarLoginResponse(avatar)
-
- case SessionActor.SetCurrentAvatar(tplayer, max_attempts, attempt) =>
- data.zoning.spawn.ReadyToSetCurrentAvatar(tplayer, max_attempts, attempt)
-
- case SessionActor.SetConnectionState(state) =>
- data.connectionState = state
-
- case SessionActor.AvatarLoadingSync(state) =>
- data.zoning.spawn.handleAvatarLoadingSync(state)
-
- /* uncommon messages (utility, or once in a while) */
- case ZoningOperations.AvatarAwardMessageBundle(pkts, delay) =>
- data.zoning.spawn.performAvatarAwardMessageDelivery(pkts, delay)
-
- case CommonMessages.ProgressEvent(delta, finishedAction, stepAction, tick) =>
- general.ops.handleProgressChange(delta, finishedAction, stepAction, tick)
-
- case CommonMessages.Progress(rate, finishedAction, stepAction) =>
- general.ops.setupProgressChange(rate, finishedAction, stepAction)
-
- case CavernRotationService.CavernRotationServiceKey.Listing(listings) =>
- listings.head ! SendCavernRotationUpdates(data.context.self)
-
- case LookupResult("propertyOverrideManager", endpoint) =>
- data.zoning.propertyOverrideManagerLoadOverrides(endpoint)
-
- case SessionActor.UpdateIgnoredPlayers(msg) =>
- galaxy.handleUpdateIgnoredPlayers(msg)
-
- case SessionActor.UseCooldownRenewed(definition, _) =>
- general.handleUseCooldownRenew(definition)
-
- case Deployment.CanDeploy(obj, state) =>
- vehicles.handleCanDeploy(obj, state)
-
- case Deployment.CanUndeploy(obj, state) =>
- vehicles.handleCanUndeploy(obj, state)
-
- case Deployment.CanNotChangeDeployment(obj, state, reason) =>
- vehicles.handleCanNotChangeDeployment(obj, state, reason)
-
- /* rare messages */
- case ProximityUnit.StopAction(term, _) =>
- terminals.ops.LocalStopUsingProximityUnit(term)
-
- case SessionActor.Suicide() =>
- general.ops.suicide(data.player)
-
- case SessionActor.Recall() =>
- data.zoning.handleRecall()
-
- case SessionActor.InstantAction() =>
- data.zoning.handleInstantAction()
-
- case SessionActor.Quit() =>
- data.zoning.handleQuit()
-
- case ICS.DroppodLaunchDenial(errorCode, _) =>
- data.zoning.handleDroppodLaunchDenial(errorCode)
-
- case ICS.DroppodLaunchConfirmation(zone, position) =>
- data.zoning.LoadZoneLaunchDroppod(zone, position)
-
- case SessionActor.PlayerFailedToLoad(tplayer) =>
- data.failWithError(s"${tplayer.Name} failed to load anywhere")
-
- /* csr only */
- case SessionActor.SetSpeed(speed) =>
- general.handleSetSpeed(speed)
-
- case SessionActor.SetFlying(isFlying) =>
- general.handleSetFlying(isFlying)
-
- case SessionActor.SetSpectator(isSpectator) =>
- general.handleSetSpectator(isSpectator)
-
- case SessionActor.Kick(player, time) =>
- general.handleKick(player, time)
-
- case SessionActor.SetZone(zoneId, position) =>
- data.zoning.handleSetZone(zoneId, position)
-
- case SessionActor.SetPosition(position) =>
- data.zoning.spawn.handleSetPosition(position)
-
- case SessionActor.SetSilenced(silenced) =>
- general.handleSilenced(silenced)
-
- /* catch these messages */
- case _: ProximityUnit.Action => ;
-
- case _: Zone.Vehicle.HasSpawned => ;
-
- case _: Zone.Vehicle.HasDespawned => ;
-
- case Zone.Deployable.IsDismissed(obj: TurretDeployable) => //only if target deployable was never fully introduced
- TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(data.continent.GUID, obj))
-
- case Zone.Deployable.IsDismissed(obj) => //only if target deployable was never fully introduced
- TaskWorkflow.execute(GUIDTask.unregisterObject(data.continent.GUID, obj))
-
- case msg: Containable.ItemPutInSlot =>
- data.log.debug(s"ItemPutInSlot: $msg")
-
- case msg: Containable.CanNotPutItemInSlot =>
- data.log.debug(s"CanNotPutItemInSlot: $msg")
-
- case _ => ()
- }
-
- private def handleGamePkt: PlanetSideGamePacket => Unit = {
- case packet: ConnectToWorldRequestMessage =>
- general.handleConnectToWorldRequest(packet)
-
- case packet: MountVehicleCargoMsg =>
- mountResponse.handleMountVehicleCargo(packet)
-
- case packet: DismountVehicleCargoMsg =>
- mountResponse.handleDismountVehicleCargo(packet)
-
- case packet: CharacterCreateRequestMessage =>
- general.handleCharacterCreateRequest(packet)
-
- case packet: CharacterRequestMessage =>
- general.handleCharacterRequest(packet)
-
- case _: KeepAliveMessage =>
- data.keepAliveFunc()
-
- case packet: BeginZoningMessage =>
- data.zoning.handleBeginZoning(packet)
-
- case packet: PlayerStateMessageUpstream =>
- general.handlePlayerStateUpstream(packet)
-
- case packet: ChildObjectStateMessage =>
- vehicles.handleChildObjectState(packet)
-
- case packet: VehicleStateMessage =>
- vehicles.handleVehicleState(packet)
-
- case packet: VehicleSubStateMessage =>
- vehicles.handleVehicleSubState(packet)
-
- case packet: FrameVehicleStateMessage =>
- vehicles.handleFrameVehicleState(packet)
-
- case packet: ProjectileStateMessage =>
- shooting.handleProjectileState(packet)
-
- case packet: LongRangeProjectileInfoMessage =>
- shooting.handleLongRangeProjectileState(packet)
-
- case packet: ReleaseAvatarRequestMessage =>
- data.zoning.spawn.handleReleaseAvatarRequest(packet)
-
- case packet: SpawnRequestMessage =>
- data.zoning.spawn.handleSpawnRequest(packet)
-
- case packet: ChatMsg =>
- chat.handleChatMsg(packet)
-
- case packet: SetChatFilterMessage =>
- chat.handleChatFilter(packet)
-
- case packet: VoiceHostRequest =>
- general.handleVoiceHostRequest(packet)
-
- case packet: VoiceHostInfo =>
- general.handleVoiceHostInfo(packet)
-
- case packet: ChangeAmmoMessage =>
- shooting.handleChangeAmmo(packet)
-
- case packet: ChangeFireModeMessage =>
- shooting.handleChangeFireMode(packet)
-
- case packet: ChangeFireStateMessage_Start =>
- shooting.handleChangeFireStateStart(packet)
-
- case packet: ChangeFireStateMessage_Stop =>
- shooting.handleChangeFireStateStop(packet)
-
- case packet: EmoteMsg =>
- general.handleEmote(packet)
-
- case packet: DropItemMessage =>
- general.handleDropItem(packet)
-
- case packet: PickupItemMessage =>
- general.handlePickupItem(packet)
-
- case packet: ReloadMessage =>
- shooting.handleReload(packet)
-
- case packet: ObjectHeldMessage =>
- general.handleObjectHeld(packet)
-
- case packet: AvatarJumpMessage =>
- general.handleAvatarJump(packet)
-
- case packet: ZipLineMessage =>
- general.handleZipLine(packet)
-
- case packet: RequestDestroyMessage =>
- general.handleRequestDestroy(packet)
-
- case packet: MoveItemMessage =>
- general.handleMoveItem(packet)
-
- case packet: LootItemMessage =>
- general.handleLootItem(packet)
-
- case packet: AvatarImplantMessage =>
- general.handleAvatarImplant(packet)
-
- case packet: UseItemMessage =>
- general.handleUseItem(packet)
-
- case packet: UnuseItemMessage =>
- general.handleUnuseItem(packet)
-
- case packet: ProximityTerminalUseMessage =>
- terminals.handleProximityTerminalUse(packet)
-
- case packet: DeployObjectMessage =>
- general.handleDeployObject(packet)
-
- case packet: GenericObjectActionMessage =>
- general.handleGenericObjectAction(packet)
-
- case packet: GenericObjectActionAtPositionMessage =>
- general.handleGenericObjectActionAtPosition(packet)
-
- case packet: GenericObjectStateMsg =>
- general.handleGenericObjectState(packet)
-
- case packet: GenericActionMessage =>
- general.handleGenericAction(packet)
-
- case packet: ItemTransactionMessage =>
- terminals.handleItemTransaction(packet)
-
- case packet: FavoritesRequest =>
- terminals.handleFavoritesRequest(packet)
-
- case packet: WeaponDelayFireMessage =>
- shooting.handleWeaponDelayFire(packet)
-
- case packet: WeaponDryFireMessage =>
- shooting.handleWeaponDryFire(packet)
-
- case packet: WeaponFireMessage =>
- shooting.handleWeaponFire(packet)
-
- case packet: WeaponLazeTargetPositionMessage =>
- shooting.handleWeaponLazeTargetPosition(packet)
-
- case packet: UplinkRequest =>
- shooting.handleUplinkRequest(packet)
-
- case packet: HitMessage =>
- shooting.handleDirectHit(packet)
-
- case packet: SplashHitMessage =>
- shooting.handleSplashHit(packet)
-
- case packet: LashMessage =>
- shooting.handleLashHit(packet)
-
- case packet: AIDamage =>
- shooting.handleAIDamage(packet)
-
- case packet: AvatarFirstTimeEventMessage =>
- general.handleAvatarFirstTimeEvent(packet)
-
- case packet: WarpgateRequest =>
- data.zoning.handleWarpgateRequest(packet)
-
- case packet: MountVehicleMsg =>
- mountResponse.handleMountVehicle(packet)
-
- case packet: DismountVehicleMsg =>
- mountResponse.handleDismountVehicle(packet)
-
- case packet: DeployRequestMessage =>
- vehicles.handleDeployRequest(packet)
-
- case packet: AvatarGrenadeStateMessage =>
- shooting.handleAvatarGrenadeState(packet)
-
- case packet: SquadDefinitionActionMessage =>
- squad.handleSquadDefinitionAction(packet)
-
- case packet: SquadMembershipRequest =>
- squad.handleSquadMemberRequest(packet)
-
- case packet: SquadWaypointRequest =>
- squad.handleSquadWaypointRequest(packet)
-
- case packet: GenericCollisionMsg =>
- general.handleGenericCollision(packet)
-
- case packet: BugReportMessage =>
- general.handleBugReport(packet)
-
- case packet: BindPlayerMessage =>
- general.handleBindPlayer(packet)
-
- case packet: PlanetsideAttributeMessage =>
- general.handlePlanetsideAttribute(packet)
-
- case packet: FacilityBenefitShieldChargeRequestMessage =>
- general.handleFacilityBenefitShieldChargeRequest(packet)
-
- case packet: BattleplanMessage =>
- general.handleBattleplan(packet)
-
- case packet: CreateShortcutMessage =>
- general.handleCreateShortcut(packet)
-
- case packet: ChangeShortcutBankMessage =>
- general.handleChangeShortcutBank(packet)
-
- case packet: FriendsRequest =>
- general.handleFriendRequest(packet)
-
- case packet: DroppodLaunchRequestMessage =>
- data.zoning.handleDroppodLaunchRequest(packet)
-
- case packet: InvalidTerrainMessage =>
- general.handleInvalidTerrain(packet)
-
- case packet: ActionCancelMessage =>
- general.handleActionCancel(packet)
-
- case packet: TradeMessage =>
- general.handleTrade(packet)
-
- case packet: DisplayedAwardMessage =>
- general.handleDisplayedAward(packet)
-
- case packet: ObjectDetectedMessage =>
- general.handleObjectDetected(packet)
-
- case packet: TargetingImplantRequest =>
- general.handleTargetingImplantRequest(packet)
-
- case packet: HitHint =>
- general.handleHitHint(packet)
-
- case _: OutfitRequest => ()
-
- case pkt =>
- data.log.warn(s"Unhandled GamePacket $pkt")
- }
}
object SpectatorModeLogic {
diff --git a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala
index 355c1fdc5..10fdb8ed6 100644
--- a/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala
+++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleLogic.scala
@@ -5,11 +5,10 @@ import akka.actor.{ActorContext, typed}
import net.psforever.actors.session.AvatarActor
import net.psforever.actors.session.support.{SessionData, VehicleFunctions, VehicleOperations}
import net.psforever.objects.serverobject.PlanetSideServerObject
-import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle, Vehicles}
+import net.psforever.objects.{Vehicle, Vehicles}
import net.psforever.objects.serverobject.deploy.Deployment
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.objects.vehicles.control.BfrFlight
-import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import net.psforever.types.{DriveState, Vector3}
@@ -41,7 +40,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
is_decelerating,
is_cloaked
) = pkt
- GetVehicleAndSeat() match {
+ ops.GetVehicleAndSeat() match {
case (Some(obj), Some(0)) =>
//we're driving the vehicle
sessionLogic.persist()
@@ -100,7 +99,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
log.error(
s"VehicleState: ${player.Name} should not be dispatching this kind of packet from vehicle ${vehicle_guid.guid} when not the driver (actually, seat $index)"
)
- case _ => ;
+ case _ => ()
}
if (player.death_by == -1) {
sessionLogic.kickedByAdministration()
@@ -124,7 +123,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
unk9,
unkA
) = pkt
- GetVehicleAndSeat() match {
+ ops.GetVehicleAndSeat() match {
case (Some(obj), Some(0)) =>
//we're driving the vehicle
sessionLogic.persist()
@@ -296,46 +295,6 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
/* support functions */
- /**
- * If the player is mounted in some entity, find that entity and get the mount index number at which the player is sat.
- * The priority of object confirmation is `direct` then `occupant.VehicleSeated`.
- * Once an object is found, the remainder are ignored.
- * @param direct a game object in which the player may be sat
- * @param occupant the player who is sat and may have specified the game object in which mounted
- * @return a tuple consisting of a vehicle reference and a mount index
- * if and only if the vehicle is known to this client and the `WorldSessioNActor`-global `player` occupies it;
- * `(None, None)`, otherwise (even if the vehicle can be determined)
- */
- private def GetMountableAndSeat(
- direct: Option[PlanetSideGameObject with Mountable],
- occupant: Player,
- zone: Zone
- ): (Option[PlanetSideGameObject with Mountable], Option[Int]) =
- direct.orElse(zone.GUID(occupant.VehicleSeated)) match {
- case Some(obj: PlanetSideGameObject with Mountable) =>
- obj.PassengerInSeat(occupant) match {
- case index @ Some(_) =>
- (Some(obj), index)
- case None =>
- (None, None)
- }
- case _ =>
- (None, None)
- }
-
- /**
- * If the player is seated in a vehicle, find that vehicle and get the mount index number at which the player is sat.
- * @see `GetMountableAndSeat`
- * @return a tuple consisting of a vehicle reference and a mount index
- * if and only if the vehicle is known to this client and the `WorldSessioNActor`-global `player` occupies it;
- * `(None, None)`, otherwise (even if the vehicle can be determined)
- */
- private def GetVehicleAndSeat(): (Option[Vehicle], Option[Int]) =
- GetMountableAndSeat(None, player, continent) match {
- case (Some(v: Vehicle), Some(seat)) => (Some(v), Some(seat))
- case _ => (None, None)
- }
-
/**
* Common reporting behavior when a `Deployment` object fails to properly transition between states.
* @param obj the game object that could not
diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala
index 9ae7677a5..26d1db691 100644
--- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala
+++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala
@@ -2,6 +2,7 @@
package net.psforever.actors.session.support
import akka.actor.{ActorContext, ActorRef, Cancellable, typed}
+import net.psforever.objects.serverobject.containable.Containable
import net.psforever.objects.sourcing.PlayerSource
import scala.collection.mutable
@@ -122,6 +123,10 @@ trait GeneralFunctions extends CommonSessionInterfacingFunctionality {
/* messages */
+ def handleRenewCharSavedTimer(): Unit
+
+ def handleRenewCharSavedTimerMsg(): Unit
+
def handleSetAvatar(avatar: Avatar): Unit
def handleReceiveAccountData(account: Account): Unit
@@ -139,6 +144,12 @@ trait GeneralFunctions extends CommonSessionInterfacingFunctionality {
def handleKick(player: Player, time: Option[Long]): Unit
def handleSilenced(isSilenced: Boolean): Unit
+
+ def handleItemPutInSlot(msg: Containable.ItemPutInSlot): Unit
+
+ def handleCanNotPutItemInSlot(msg: Containable.CanNotPutItemInSlot): Unit
+
+ def handleReceiveDefaultMessage(default: Any, sender: ActorRef): Unit
}
class GeneralOperations(
@@ -741,6 +752,14 @@ class GeneralOperations(
sendResponse(ChatMsg(ChatMessageType.UNK_227, wideContents=false, "", "@charsaved", None))
}
+ def noVoicedChat(pkt: PlanetSideGamePacket): Unit = {
+ log.debug(s"$pkt")
+ sendResponse(VoiceHostKill())
+ sendResponse(
+ ChatMsg(ChatMessageType.CMT_OPEN, wideContents=false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None)
+ )
+ }
+
override protected[session] def actionsToCancel(): Unit = {
progressBarValue = None
kitToBeUsed = None
diff --git a/src/main/scala/net/psforever/actors/session/support/PlayerMode.scala b/src/main/scala/net/psforever/actors/session/support/PlayerMode.scala
index 6c5040057..46e7f52ed 100644
--- a/src/main/scala/net/psforever/actors/session/support/PlayerMode.scala
+++ b/src/main/scala/net/psforever/actors/session/support/PlayerMode.scala
@@ -1,8 +1,6 @@
// Copyright (c) 2024 PSForever
package net.psforever.actors.session.support
-import akka.actor.Actor.Receive
-import akka.actor.ActorRef
import net.psforever.objects.Session
trait ModeLogic {
@@ -21,8 +19,6 @@ trait ModeLogic {
def switchTo(session: Session): Unit = { /* to override */ }
def switchFrom(session: Session): Unit = { /* to override */ }
-
- def parse(sender: ActorRef): Receive
}
trait PlayerMode {
diff --git a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala
index df53c650e..456e3a237 100644
--- a/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala
+++ b/src/main/scala/net/psforever/actors/session/support/SessionLocalHandlers.scala
@@ -2,16 +2,35 @@
package net.psforever.actors.session.support
import akka.actor.ActorContext
+import net.psforever.objects.{Players, TurretDeployable}
+import net.psforever.objects.ce.Deployable
+import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
import net.psforever.services.local.LocalResponse
import net.psforever.types.PlanetSideGUID
trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality {
def ops: SessionLocalHandlers
+ def handleTurretDeployableIsDismissed(obj: TurretDeployable): Unit
+
+ def handleDeployableIsDismissed(obj: Deployable): Unit
+
def handle(toChannel: String, guid: PlanetSideGUID, reply: LocalResponse.Response): Unit
}
class SessionLocalHandlers(
val sessionLogic: SessionData,
implicit val context: ActorContext
- ) extends CommonSessionInterfacingFunctionality
+ ) extends CommonSessionInterfacingFunctionality {
+
+
+ def handleTurretDeployableIsDismissed(obj: TurretDeployable): Unit = {
+ Players.buildCooldownReset(continent, player.Name, obj)
+ TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(continent.GUID, obj))
+ }
+
+ def handleDeployableIsDismissed(obj: Deployable): Unit = {
+ Players.buildCooldownReset(continent, player.Name, obj)
+ TaskWorkflow.execute(GUIDTask.unregisterObject(continent.GUID, obj))
+ }
+}
diff --git a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala
index 470db3569..1ccb6bf3f 100644
--- a/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala
+++ b/src/main/scala/net/psforever/actors/session/support/SessionSquadHandlers.scala
@@ -74,7 +74,7 @@ class SessionSquadHandlers(
sendResponse(
SquadDefinitionActionMessage(PlanetSideGUID(0), index, SquadAction.ListSquadFavorite(loadout.task))
)
- case (None, _) => ;
+ case (None, _) => ()
}
//non-squad GUID-0 counts as the settings when not joined with a squad
sendResponse(SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SquadAction.IdentifyAsSquadLeader()))
diff --git a/src/main/scala/net/psforever/actors/session/support/SessionTerminalHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionTerminalHandlers.scala
index 21cc9f9d6..347139e6a 100644
--- a/src/main/scala/net/psforever/actors/session/support/SessionTerminalHandlers.scala
+++ b/src/main/scala/net/psforever/actors/session/support/SessionTerminalHandlers.scala
@@ -68,6 +68,26 @@ class SessionTerminalHandlers(
)
}
+ /**
+ * Construct tasking that adds a completed and registered vehicle into the scene.
+ * Use this function to renew the globally unique identifiers on a vehicle that has already been added to the scene once.
+ * @param vehicle the `Vehicle` object
+ * @see `RegisterVehicleFromSpawnPad`
+ * @return a `TaskBundle` message
+ */
+ def registerVehicle(vehicle: Vehicle): TaskBundle = {
+ TaskBundle(
+ new StraightforwardTask() {
+ private val localVehicle = vehicle
+
+ override def description(): String = s"register a ${localVehicle.Definition.Name}"
+
+ def action(): Future[Any] = Future(true)
+ },
+ List(GUIDTask.registerVehicle(continent.GUID, vehicle))
+ )
+ }
+
/**
* na
* @param terminal na
@@ -188,26 +208,6 @@ class SessionTerminalHandlers(
}
}
- /**
- * Construct tasking that adds a completed and registered vehicle into the scene.
- * Use this function to renew the globally unique identifiers on a vehicle that has already been added to the scene once.
- * @param vehicle the `Vehicle` object
- * @see `RegisterVehicleFromSpawnPad`
- * @return a `TaskBundle` message
- */
- def registerVehicle(vehicle: Vehicle): TaskBundle = {
- TaskBundle(
- new StraightforwardTask() {
- private val localVehicle = vehicle
-
- override def description(): String = s"register a ${localVehicle.Definition.Name}"
-
- def action(): Future[Any] = Future(true)
- },
- List(GUIDTask.registerVehicle(continent.GUID, vehicle))
- )
- }
-
override protected[session] def actionsToCancel(): Unit = {
lastTerminalOrderFulfillment = true
usingMedicalTerminal = None
diff --git a/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala b/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala
index d56107506..f23c61d38 100644
--- a/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala
+++ b/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala
@@ -66,6 +66,19 @@ class VehicleOperations(
(None, None)
}
+ /**
+ * If the player is seated in a vehicle, find that vehicle and get the mount index number at which the player is sat.
+ * @see `GetMountableAndSeat`
+ * @return a tuple consisting of a vehicle reference and a mount index
+ * if and only if the vehicle is known to this client and the `WorldSessioNActor`-global `player` occupies it;
+ * `(None, None)`, otherwise (even if the vehicle can be determined)
+ */
+ def GetVehicleAndSeat(): (Option[Vehicle], Option[Int]) =
+ GetMountableAndSeat(None, player, continent) match {
+ case (Some(v: Vehicle), Some(seat)) => (Some(v), Some(seat))
+ case _ => (None, None)
+ }
+
/**
* If the player is seated in a vehicle, find that vehicle and get the mount index number at which the player is sat.
*
@@ -86,19 +99,6 @@ class VehicleOperations(
case _ => (None, None)
}
- /**
- * If the player is seated in a vehicle, find that vehicle and get the mount index number at which the player is sat.
- * @see `GetMountableAndSeat`
- * @return a tuple consisting of a vehicle reference and a mount index
- * if and only if the vehicle is known to this client and the `WorldSessioNActor`-global `player` occupies it;
- * `(None, None)`, otherwise (even if the vehicle can be determined)
- */
- def GetVehicleAndSeat(): (Option[Vehicle], Option[Int]) =
- GetMountableAndSeat(None, player, continent) match {
- case (Some(v: Vehicle), Some(seat)) => (Some(v), Some(seat))
- case _ => (None, None)
- }
-
/**
* Place the current vehicle under the control of the driver's commands,
* but leave it in a cancellable auto-drive.
diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala
index ca3f4a125..47a87c748 100644
--- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala
+++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala
@@ -288,7 +288,7 @@ class ZoningOperations(
obj.Definition.DeployCategory == DeployableCategory.Sensors &&
!obj.Destroyed &&
(obj match {
- case jObj: JammableUnit => !jObj.Jammed;
+ case jObj: JammableUnit => !jObj.Jammed
case _ => true
})
)
@@ -449,7 +449,7 @@ class ZoningOperations(
if (vehicle.Shields > 0) {
sendResponse(PlanetsideAttributeMessage(vguid, vehicle.Definition.shieldUiAttribute, vehicle.Shields))
}
- case _ => ; //no vehicle
+ case _ => () //no vehicle
}
//vehicle wreckages
wreckages.foreach(vehicle => {
@@ -487,7 +487,7 @@ class ZoningOperations(
sendResponse(PlanetsideAttributeMessage(silo.GUID, 49, 1)) // silo orb particle effect
case Some(_: WarpGate) =>
sendResponse(PlanetsideAttributeMessage(obj.GUID, 49, 1)) // ant orb particle effect
- case _ => ;
+ case _ => ()
}
}
deployedVehicles.filter(_.Definition == GlobalDefinitions.router).foreach { obj =>
@@ -518,7 +518,7 @@ class ZoningOperations(
objDef.Packet.ConstructorData(obj).get
)
)
- case _ => ;
+ case _ => ()
}
//mount terminal occupants
continent.GUID(terminal_guid) match {
@@ -534,9 +534,9 @@ class ZoningOperations(
targetDefinition.Packet.ConstructorData(targetPlayer).get
)
)
- case _ => ;
+ case _ => ()
}
- case _ => ;
+ case _ => ()
}
})
//facility turrets
@@ -558,7 +558,7 @@ class ZoningOperations(
objDef.Packet.ConstructorData(obj).get
)
)
- case _ => ;
+ case _ => ()
}
}
//reserved ammunition?
@@ -575,7 +575,7 @@ class ZoningOperations(
targetDefinition.Packet.ConstructorData(targetPlayer).get
)
)
- case _ => ;
+ case _ => ()
}
turret.Target.collect {
target =>
@@ -1071,7 +1071,7 @@ class ZoningOperations(
)
)
}
- case _ => ;
+ case _ => ()
}
}
@@ -1092,7 +1092,7 @@ class ZoningOperations(
case Some(obj) if obj.Condition == PlanetSideGeneratorState.Destroyed || building.NtuLevel == 0 =>
sendResponse(PlanetsideAttributeMessage(guid, 48, 1)) //amenities disabled; red warning lights
sendResponse(PlanetsideAttributeMessage(guid, 38, 0)) //disable spawn target on deployment map
- case _ => ;
+ case _ => ()
}
// capitol force dome state
if (building.IsCapitol && building.ForceDomeActive) {
@@ -1177,7 +1177,7 @@ class ZoningOperations(
LocalAction.SendPacket(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252))
)
}
- case _ => ;
+ case _ => ()
}
}
@@ -1495,7 +1495,7 @@ class ZoningOperations(
// remove owner
vehicle.Actor ! Vehicle.Ownership(None)
- case _ => ;
+ case _ => ()
}
avatarActor ! AvatarActor.SetVehicle(None)
}
@@ -1736,7 +1736,7 @@ class ZoningOperations(
case Success(overrides: List[Any]) =>
//safe to cast like this
sendResponse(PropertyOverrideMessage(overrides.map { _.asInstanceOf[PropertyOverrideMessage.GamePropertyScope] }))
- case _ => ;
+ case _ => ()
}
}
@@ -2119,6 +2119,40 @@ class ZoningOperations(
}
}
+ def handlePlayerHasLeft(zone: Zone, playerOpt: Option[Player]): Unit = {
+ playerOpt match {
+ case None =>
+ log.debug(s"PlayerHasLeft: ${player.Name} does not have a body on ${zone.id}")
+ case Some(tplayer) if tplayer.isAlive =>
+ log.info(s"${tplayer.Name} has left zone ${zone.id}")
+ case _ => ()
+ }
+ }
+
+ def handlePlayerCanNotSpawn(zone: Zone, tplayer: Player): Unit = {
+ log.warn(s"${tplayer.Name} can not spawn in zone ${zone.id}; why?")
+ }
+
+ def handlePlayerAlreadySpawned(zone: Zone, tplayer: Player): Unit = {
+ log.warn(s"${tplayer.Name} is already spawned on zone ${zone.id}; is this a clerical error?")
+ }
+
+ def handleCanNotSpawn(zone: Zone, vehicle: Vehicle, reason: String): Unit = {
+ log.warn(
+ s"${player.Name}'s ${vehicle.Definition.Name} can not spawn in ${zone.id} because $reason"
+ )
+ }
+
+ def handleCanNotDespawn(zone: Zone, vehicle: Vehicle, reason: String): Unit = {
+ log.warn(
+ s"${player.Name}'s ${vehicle.Definition.Name} can not deconstruct in ${zone.id} because $reason"
+ )
+ }
+
+ def handlePlayerFailedToLoad(tplayer: Player): Unit = {
+ sessionLogic.failWithError(s"${tplayer.Name} failed to load anywhere")
+ }
+
/* support functions */
private def dropMedicalApplicators(p: Player): Unit = {
@@ -2289,7 +2323,7 @@ class ZoningOperations(
carrierInfo match {
case (Some(carrier), Some((index, _))) =>
CargoMountBehaviorForUs(carrier, vehicle, index)
- case _ => ;
+ case _ => ()
}
data
}
@@ -2476,7 +2510,7 @@ class ZoningOperations(
def FriskDeadBody(obj: Player): Unit = {
if (!obj.isAlive) {
obj.Slot(4).Equipment match {
- case None => ;
+ case None => ()
case Some(knife) =>
RemoveOldEquipmentFromInventory(obj)(knife)
}
@@ -2485,7 +2519,7 @@ class ZoningOperations(
if (GlobalDefinitions.isMaxArms(arms.Definition)) {
RemoveOldEquipmentFromInventory(obj)(arms)
}
- case _ => ;
+ case _ => ()
}
//disown boomers and drop triggers
val boomers = avatar.deployables.ClearDeployable(DeployedItem.boomer)
@@ -2493,7 +2527,7 @@ class ZoningOperations(
continent.GUID(boomer) match {
case Some(obj: BoomerDeployable) =>
obj.Actor ! Deployable.Ownership(None)
- case Some(_) | None => ;
+ case Some(_) | None => ()
}
})
removeBoomerTriggersFromInventory().foreach(trigger => { sessionLogic.general.normalItemDrop(obj, continent)(trigger) })
@@ -3035,7 +3069,7 @@ class ZoningOperations(
case (Some(vehicle), _) =>
//passenger
vehicle.Actor ! Vehicle.UpdateZoneInteractionProgressUI(tplayer)
- case _ => ;
+ case _ => ()
}
interstellarFerryTopLevelGUID = None
if (loadConfZone && sessionLogic.connectionState == 100) {
@@ -3329,7 +3363,7 @@ class ZoningOperations(
sendResponse(ObjectAttachMessage(vguid, pguid, seat))
sessionLogic.general.accessContainer(vehicle)
sessionLogic.keepAliveFunc = sessionLogic.keepAlivePersistence
- case _ => ;
+ case _ => ()
//we can't find a vehicle? and we're still here? that's bad
player.VehicleSeated = None
}
@@ -3517,7 +3551,7 @@ class ZoningOperations(
delay: Long
): Unit = {
messageBundles match {
- case Nil => ;
+ case Nil => ()
case x :: Nil =>
x.foreach {
sendResponse
@@ -3581,10 +3615,11 @@ class ZoningOperations(
}
def randomRespawn(time: FiniteDuration = 300.seconds): Unit = {
+ val faction = player.Faction
reviveTimer = context.system.scheduler.scheduleOnce(time) {
cluster ! ICS.GetRandomSpawnPoint(
- Zones.sanctuaryZoneNumber(player.Faction),
- player.Faction,
+ Zones.sanctuaryZoneNumber(faction),
+ faction,
Seq(SpawnGroup.Sanctuary),
context.self
)