mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-26 15:49:14 +00:00
reviewing logic and operations pairs to ensure that functionality should have been retained from parent structure; moving handling case from individual player modes to session actor, which makes it much closer to the pattern
This commit is contained in:
parent
450c35af72
commit
1847b4bedf
23 changed files with 732 additions and 1202 deletions
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)) =>
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.<br>
|
||||
* <br>
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue