Fix terminal hack clearing

Fixes #759
This commit is contained in:
Jakob Gillich 2021-04-18 01:33:06 +02:00
parent 765262f51a
commit ce32a1a1ff
2 changed files with 289 additions and 201 deletions

View file

@ -60,7 +60,12 @@ import net.psforever.services.local.support.{CaptureFlagManager, HackCaptureActo
import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse} import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse}
import net.psforever.services.properties.PropertyOverrideManager import net.psforever.services.properties.PropertyOverrideManager
import net.psforever.services.support.SupportActor import net.psforever.services.support.SupportActor
import net.psforever.services.teamwork.{SquadResponse, SquadServiceMessage, SquadServiceResponse, SquadAction => SquadServiceAction} import net.psforever.services.teamwork.{
SquadResponse,
SquadServiceMessage,
SquadServiceResponse,
SquadAction => SquadServiceAction
}
import net.psforever.services.hart.HartTimer import net.psforever.services.hart.HartTimer
import net.psforever.services.vehicle.{VehicleAction, VehicleResponse, VehicleServiceMessage, VehicleServiceResponse} import net.psforever.services.vehicle.{VehicleAction, VehicleResponse, VehicleServiceMessage, VehicleServiceResponse}
import net.psforever.services.{RemoverActor, Service, ServiceManager, InterstellarClusterService => ICS} import net.psforever.services.{RemoverActor, Service, ServiceManager, InterstellarClusterService => ICS}
@ -202,7 +207,8 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
var setupAvatarFunc: () => Unit = AvatarCreate var setupAvatarFunc: () => Unit = AvatarCreate
var setCurrentAvatarFunc: Player => Unit = SetCurrentAvatarNormally var setCurrentAvatarFunc: Player => Unit = SetCurrentAvatarNormally
var persist: () => Unit = NoPersistence var persist: () => Unit = NoPersistence
var specialItemSlotGuid : Option[PlanetSideGUID] = None // If a special item (e.g. LLU) has been attached to the player the GUID should be stored here, or cleared when dropped, since the drop hotkey doesn't send the GUID of the object to be dropped. var specialItemSlotGuid: Option[PlanetSideGUID] =
None // If a special item (e.g. LLU) has been attached to the player the GUID should be stored here, or cleared when dropped, since the drop hotkey doesn't send the GUID of the object to be dropped.
/** /**
* used during zone transfers to maintain reference to seated vehicle (which does not yet exist in the new zone) * used during zone transfers to maintain reference to seated vehicle (which does not yet exist in the new zone)
@ -349,14 +355,20 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
out out
case None => case None =>
//delete stale entity reference from client //delete stale entity reference from client
log.warn(s"ValidObject - ${player.Name} has an invalid GUID ${id.get.guid}, believing it in ${player.Sex.possessive} locker") log.warn(
s"ValidObject - ${player.Name} has an invalid GUID ${id.get.guid}, believing it in ${player.Sex.possessive} locker"
)
sendResponse(ObjectDeleteMessage(id.get, 0)) sendResponse(ObjectDeleteMessage(id.get, 0))
None None
} }
case Some(obj) if obj.HasGUID && obj.GUID != id.get => case Some(obj) if obj.HasGUID && obj.GUID != id.get =>
log.error(s"ValidObject: ${player.Name} found an object that isn't the one ${player.Sex.pronounSubject} thought it was in zone ${continent.id}") log.error(
log.debug(s"ValidObject: potentially fatal error in ${continent.id} - requested ${id.get}, got ${obj.Definition.Name} with ${obj.GUID}; GUID mismatch") s"ValidObject: ${player.Name} found an object that isn't the one ${player.Sex.pronounSubject} thought it was in zone ${continent.id}"
)
log.debug(
s"ValidObject: potentially fatal error in ${continent.id} - requested ${id.get}, got ${obj.Definition.Name} with ${obj.GUID}; GUID mismatch"
)
None None
case out @ Some(obj) if obj.HasGUID => case out @ Some(obj) if obj.HasGUID =>
@ -570,23 +582,26 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case Some(entry) if vehicle.Seats(entry.mount).occupant.contains(player) => case Some(entry) if vehicle.Seats(entry.mount).occupant.contains(player) =>
Some(vehicle) Some(vehicle)
case Some(entry) => case Some(entry) =>
log.warn(s"TransferPassenger: $playerName tried to mount seat ${entry.mount} during summoning, but it was already occupied, and ${player.Sex.pronounSubject} was rebuked") log.warn(
s"TransferPassenger: $playerName tried to mount seat ${entry.mount} during summoning, but it was already occupied, and ${player.Sex.pronounSubject} was rebuked"
)
None None
case None => case None =>
//log.warn(s"TransferPassenger: $playerName is missing from the manifest of a summoning ${vehicle.Definition.Name} from ${vehicle.Zone.id}") //log.warn(s"TransferPassenger: $playerName is missing from the manifest of a summoning ${vehicle.Definition.Name} from ${vehicle.Zone.id}")
None None
}).orElse { }).orElse {
manifest.cargo.find { _.name.equals(playerName) } match { manifest.cargo.find { _.name.equals(playerName) } match {
case Some(entry) => case Some(entry) =>
vehicle.CargoHolds(entry.mount).occupant match { vehicle.CargoHolds(entry.mount).occupant match {
case out @ Some(cargo) if cargo.Seats(0).occupants.exists(_.Name.equals(playerName)) => case out @ Some(cargo) if cargo.Seats(0).occupants.exists(_.Name.equals(playerName)) =>
out out
case _ => case _ =>
None None
} }
case None => case None =>
None None
}} match { }
} match {
case Some(v: Vehicle) => case Some(v: Vehicle) =>
galaxyService ! Service.Leave(Some(temp_channel)) //temporary vehicle-specific channel (see above) galaxyService ! Service.Leave(Some(temp_channel)) //temporary vehicle-specific channel (see above)
deadState = DeadState.Release deadState = DeadState.Release
@ -972,7 +987,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case ztype => case ztype =>
if (ztype != Zoning.Method.None) { if (ztype != Zoning.Method.None) {
log.warn(s"SpawnPointResponse: ${player.Name}'s zoning was not in order at the time a response was received; attempting to guess what ${player.Sex.pronounSubject} wants to do") log.warn(
s"SpawnPointResponse: ${player.Name}'s zoning was not in order at the time a response was received; attempting to guess what ${player.Sex.pronounSubject} wants to do"
)
} }
val previousZoningType = zoningType val previousZoningType = zoningType
CancelZoningProcess() CancelZoningProcess()
@ -994,7 +1011,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
else else
LoadZonePhysicalSpawnPoint(zone.id, pos, ori, CountSpawnDelay(zone.id, spawnPoint, continent.id)) LoadZonePhysicalSpawnPoint(zone.id, pos, ori, CountSpawnDelay(zone.id, spawnPoint, continent.id))
case None => case None =>
log.warn(s"SpawnPointResponse: ${player.Name} received no spawn point response when asking InterstellarClusterService; sending home") log.warn(
s"SpawnPointResponse: ${player.Name} received no spawn point response when asking InterstellarClusterService; sending home"
)
//Thread.sleep(1000) // throttle in case of infinite loop //Thread.sleep(1000) // throttle in case of infinite loop
RequestSanctuaryZoneSpawn(player, currentZone = 0) RequestSanctuaryZoneSpawn(player, currentZone = 0)
} }
@ -1137,7 +1156,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
log.warn( log.warn(
s"FinalizeDeployable: deployable ${definition.Item}@$guid not handled by specific case" s"FinalizeDeployable: deployable ${definition.Item}@$guid not handled by specific case"
) )
log.warn(s"FinalizeDeployable: deployable ${definition.Item}@$guid will be cleaned up, but may not get unregistered properly") log.warn(
s"FinalizeDeployable: deployable ${definition.Item}@$guid will be cleaned up, but may not get unregistered properly"
)
TryDropFDU(tool, index, obj.Position) TryDropFDU(tool, index, obj.Position)
obj.Position = Vector3.Zero obj.Position = Vector3.Zero
continent.Deployables ! Zone.Deployable.Dismiss(obj) continent.Deployables ! Zone.Deployable.Dismiss(obj)
@ -1382,8 +1403,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
} else { } else {
keepAliveFunc = GetMountableAndSeat(None, player, continent) match { keepAliveFunc = GetMountableAndSeat(None, player, continent) match {
case (Some(v: Vehicle), Some(seatNumber)) case (Some(v: Vehicle), Some(seatNumber))
if seatNumber > 0 && v.WeaponControlledFromSeat(seatNumber).isEmpty => KeepAlivePersistence if seatNumber > 0 && v.WeaponControlledFromSeat(seatNumber).isEmpty =>
case _ => NormalKeepAlive KeepAlivePersistence
case _ => NormalKeepAlive
} }
} }
//if not the condition above, player has started playing normally //if not the condition above, player has started playing normally
@ -1784,7 +1806,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case AvatarResponse.EnvironmentalDamage(target, source, amount) => case AvatarResponse.EnvironmentalDamage(target, source, amount) =>
CancelZoningProcessWithDescriptiveReason("cancel_dmg") CancelZoningProcessWithDescriptiveReason("cancel_dmg")
//TODO damage marker? //TODO damage marker?
case AvatarResponse.Destroy(victim, killer, weapon, pos) => case AvatarResponse.Destroy(victim, killer, weapon, pos) =>
// guid = victim // killer = killer ;) // guid = victim // killer = killer ;)
@ -1897,7 +1919,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
DrowningTarget(player.guid, player.progress, player.state), DrowningTarget(player.guid, player.progress, player.state),
vehicle match { vehicle match {
case Some(vinfo) => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) case Some(vinfo) => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state))
case None => None case None => None
} }
) )
) )
@ -2331,7 +2353,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
} }
case LocalResponse.SendHackMessageHackCleared(target_guid, unk1, unk2) => case LocalResponse.SendHackMessageHackCleared(target_guid, unk1, unk2) =>
//log.trace(s"Clearing hack for $target_guid") sendResponse(HackMessage(0, target_guid, guid, 0, unk1, HackState.HackCleared, unk2))
case LocalResponse.HackObject(target_guid, unk1, unk2) => case LocalResponse.HackObject(target_guid, unk1, unk2) =>
HackObject(target_guid, unk1, unk2) HackObject(target_guid, unk1, unk2)
@ -2353,11 +2375,13 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case LocalResponse.LluSpawned(llu) => case LocalResponse.LluSpawned(llu) =>
// Create LLU on client // Create LLU on client
sendResponse(ObjectCreateMessage( sendResponse(
llu.Definition.ObjectId, ObjectCreateMessage(
llu.GUID, llu.Definition.ObjectId,
llu.Definition.Packet.ConstructorData(llu).get llu.GUID,
)) llu.Definition.Packet.ConstructorData(llu).get
)
)
sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk = 20, 0.8000001f)) sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk = 20, 0.8000001f))
@ -2399,8 +2423,11 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case LocalResponse.ShuttleEvent(ev) => case LocalResponse.ShuttleEvent(ev) =>
val msg = OrbitalShuttleTimeMsg( val msg = OrbitalShuttleTimeMsg(
ev.u1, ev.u2, ev.u1,
ev.t1, ev.t2, ev.t3, ev.u2,
ev.t1,
ev.t2,
ev.t3,
ev.pairs.map { case ((a, b), c) => PadAndShuttlePair(a, b, c) } ev.pairs.map { case ((a, b), c) => PadAndShuttlePair(a, b, c) }
) )
sendResponse(msg) sendResponse(msg)
@ -2468,8 +2495,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
MountingAction(tplayer, obj, seat_number) MountingAction(tplayer, obj, seat_number)
keepAliveFunc = KeepAlivePersistence keepAliveFunc = KeepAlivePersistence
case Mountable.CanMount(obj: Vehicle, seat_number, _) case Mountable.CanMount(obj: Vehicle, seat_number, _) if obj.Definition == GlobalDefinitions.orbital_shuttle =>
if obj.Definition == GlobalDefinitions.orbital_shuttle =>
CancelZoningProcessWithDescriptiveReason("cancel_mount") CancelZoningProcessWithDescriptiveReason("cancel_mount")
log.info(s"${player.Name} mounts the orbital shuttle") log.info(s"${player.Name} mounts the orbital shuttle")
CancelAllProximityUnits() CancelAllProximityUnits()
@ -2478,13 +2504,11 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case Mountable.CanMount(obj: Vehicle, seat_number, _) => case Mountable.CanMount(obj: Vehicle, seat_number, _) =>
CancelZoningProcessWithDescriptiveReason("cancel_mount") CancelZoningProcessWithDescriptiveReason("cancel_mount")
log.info(s"${player.Name} mounts ${obj.Definition.Name} in ${ log.info(s"${player.Name} mounts ${obj.Definition.Name} in ${obj.SeatPermissionGroup(seat_number) match {
obj.SeatPermissionGroup(seat_number) match { case Some(AccessPermissionGroup.Driver) => "the driver seat"
case Some(AccessPermissionGroup.Driver) => "the driver seat" case Some(seatType) => s"a $seatType seat, #$seat_number"
case Some(seatType) => s"a $seatType seat, #$seat_number" case None => "a seat"
case None => "a seat" }}")
}
}")
val obj_guid: PlanetSideGUID = obj.GUID val obj_guid: PlanetSideGUID = obj.GUID
CancelAllProximityUnits() CancelAllProximityUnits()
sendResponse(PlanetsideAttributeMessage(obj_guid, 0, obj.Health)) sendResponse(PlanetsideAttributeMessage(obj_guid, 0, obj.Health))
@ -2541,12 +2565,12 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
DismountAction(tplayer, obj, seat_num) DismountAction(tplayer, obj, seat_num)
case Mountable.CanDismount(obj: Vehicle, seat_num, mount_point) case Mountable.CanDismount(obj: Vehicle, seat_num, mount_point)
if obj.Definition == GlobalDefinitions.orbital_shuttle => if obj.Definition == GlobalDefinitions.orbital_shuttle =>
val pguid = player.GUID val pguid = player.GUID
if (obj.MountedIn.nonEmpty) { if (obj.MountedIn.nonEmpty) {
//dismount to hart lobby //dismount to hart lobby
log.info(s"${tplayer.Name} dismounts the orbital shuttle into the lobby") log.info(s"${tplayer.Name} dismounts the orbital shuttle into the lobby")
val sguid = obj.GUID val sguid = obj.GUID
val (pos, zang) = Vehicles.dismountShuttle(obj, mount_point) val (pos, zang) = Vehicles.dismountShuttle(obj, mount_point)
tplayer.Position = pos tplayer.Position = pos
sendResponse(DelayedPathMountMsg(pguid, sguid, 60, true)) sendResponse(DelayedPathMountMsg(pguid, sguid, 60, true))
@ -2554,8 +2578,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
continent.id, continent.id,
LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, 0, 0, zang)) LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, 0, 0, zang))
) )
} } else {
else {
//get ready for orbital drop //get ready for orbital drop
DismountAction(tplayer, obj, seat_num) DismountAction(tplayer, obj, seat_num)
log.info(s"${player.Name} is prepped for dropping") log.info(s"${player.Name} is prepped for dropping")
@ -2582,8 +2605,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
} }
keepAliveFunc = NormalKeepAlive keepAliveFunc = NormalKeepAlive
case Mountable.CanDismount(obj: Vehicle, seat_num, _) case Mountable.CanDismount(obj: Vehicle, seat_num, _) if obj.Definition == GlobalDefinitions.droppod =>
if obj.Definition == GlobalDefinitions.droppod =>
log.info(s"${tplayer.Name} has landed on ${continent.id}") log.info(s"${tplayer.Name} has landed on ${continent.id}")
UnaccessContainer(obj) UnaccessContainer(obj)
DismountAction(tplayer, obj, seat_num) DismountAction(tplayer, obj, seat_num)
@ -2952,7 +2974,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
sendResponse(PlanetsideAttributeMessage(player.GUID, 21, vehicle_guid)) //ownership sendResponse(PlanetsideAttributeMessage(player.GUID, 21, vehicle_guid)) //ownership
vehicle.MountPoints.find { case (_, mp) => mp.seatIndex == 0 } match { vehicle.MountPoints.find { case (_, mp) => mp.seatIndex == 0 } match {
case Some((mountPoint, _)) => vehicle.Actor ! Mountable.TryMount(player, mountPoint) case Some((mountPoint, _)) => vehicle.Actor ! Mountable.TryMount(player, mountPoint)
case _ => ; case _ => ;
} }
case VehicleResponse.PlayerSeatedInVehicle(vehicle, pad) => case VehicleResponse.PlayerSeatedInVehicle(vehicle, pad) =>
@ -2998,7 +3020,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
vehicle.PassengerInSeat(player) match { vehicle.PassengerInSeat(player) match {
case Some(seatNum) => case Some(seatNum) =>
//participant: observe changes to equipment //participant: observe changes to equipment
(old_weapons ++ old_inventory).foreach { case (_, eguid) => sendResponse(ObjectDeleteMessage(eguid, 0)) } (old_weapons ++ old_inventory).foreach {
case (_, eguid) => sendResponse(ObjectDeleteMessage(eguid, 0))
}
UpdateWeaponAtSeatPosition(vehicle, seatNum) UpdateWeaponAtSeatPosition(vehicle, seatNum)
case None => case None =>
//observer: observe changes to external equipment //observer: observe changes to external equipment
@ -3370,7 +3394,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
def handleGamePkt(pkt: PlanetSideGamePacket) = def handleGamePkt(pkt: PlanetSideGamePacket) =
pkt match { pkt match {
case ConnectToWorldRequestMessage(server, token, majorVersion, minorVersion, revision, buildDate, unk) => case ConnectToWorldRequestMessage(server, token, majorVersion, minorVersion, revision, buildDate, unk) =>
log.trace(s"ConnectToWorldRequestMessage: client with versioning $majorVersion.$minorVersion.$revision, $buildDate has sent token $token to the server") log.trace(
s"ConnectToWorldRequestMessage: client with versioning $majorVersion.$minorVersion.$revision, $buildDate has sent token $token to the server"
)
sendResponse(ChatMsg(ChatMessageType.CMT_CULLWATERMARK, false, "", "", None)) sendResponse(ChatMsg(ChatMessageType.CMT_CULLWATERMARK, false, "", "", None))
import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.ExecutionContext.Implicits.global
clientKeepAlive.cancel() clientKeepAlive.cancel()
@ -3579,7 +3605,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
_.GUID != vehicle.GUID _.GUID != vehicle.GUID
} }
case Some(_) => case Some(_) =>
log.warn(s"BeginZoningMessage: ${player.Name} thought ${player.Sex.pronounSubject} was sitting in a vehicle, but it just evaporated around ${player.Sex.pronounObject}") log.warn(
s"BeginZoningMessage: ${player.Name} thought ${player.Sex.pronounSubject} was sitting in a vehicle, but it just evaporated around ${player.Sex.pronounObject}"
)
player.VehicleSeated = None player.VehicleSeated = None
(b, List.empty[Vehicle]) (b, List.empty[Vehicle])
case None => case None =>
@ -3696,7 +3724,8 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
ToggleTeleportSystem(obj, TelepadLike.AppraiseTeleportationSystem(obj, continent)) ToggleTeleportSystem(obj, TelepadLike.AppraiseTeleportationSystem(obj, continent))
} }
val name = avatar.name val name = avatar.name
serviceManager.ask(Lookup("hart"))(Timeout(2 seconds)) serviceManager
.ask(Lookup("hart"))(Timeout(2 seconds))
.onComplete { .onComplete {
case Success(LookupResult("hart", ref)) => case Success(LookupResult("hart", ref)) =>
ref ! HartTimer.Update(continentId, name) ref ! HartTimer.Update(continentId, name)
@ -3997,7 +4026,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
} }
case msg @ VehicleSubStateMessage(vehicle_guid, player_guid, vehicle_pos, vehicle_ang, vel, unk1, unk2) => case msg @ VehicleSubStateMessage(vehicle_guid, player_guid, vehicle_pos, vehicle_ang, vel, unk1, unk2) =>
log.debug(s"VehicleSubState: $vehicle_guid, ${player.Name}_guid, $vehicle_pos, $vehicle_ang, $vel, $unk1, $unk2") log.debug(
s"VehicleSubState: $vehicle_guid, ${player.Name}_guid, $vehicle_pos, $vehicle_ang, $vel, $unk1, $unk2"
)
case msg @ ProjectileStateMessage(projectile_guid, shot_pos, shot_vel, shot_orient, seq, end, target_guid) => case msg @ ProjectileStateMessage(projectile_guid, shot_pos, shot_vel, shot_orient, seq, end, target_guid) =>
val index = projectile_guid.guid - Projectile.baseUID val index = projectile_guid.guid - Projectile.baseUID
@ -4051,19 +4082,19 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
log.warn(s"SpawnRequestMessage: request consumed because ${player.Name} is already respawning ...") log.warn(s"SpawnRequestMessage: request consumed because ${player.Name} is already respawning ...")
} }
case _ : SetChatFilterMessage => //msg @ SetChatFilterMessage(send_channel, origin, whitelist) => ; case _: SetChatFilterMessage => //msg @ SetChatFilterMessage(send_channel, origin, whitelist) => ;
case msg : ChatMsg => case msg: ChatMsg =>
chatActor ! ChatActor.Message(msg) chatActor ! ChatActor.Message(msg)
case _ : VoiceHostRequest => case _: VoiceHostRequest =>
log.trace(s"VoiceHostRequest: ${player.Name} requested in-game voice chat.") log.trace(s"VoiceHostRequest: ${player.Name} requested in-game voice chat.")
sendResponse(VoiceHostKill()) sendResponse(VoiceHostKill())
sendResponse( sendResponse(
ChatMsg(ChatMessageType.CMT_OPEN, false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None) ChatMsg(ChatMessageType.CMT_OPEN, false, "", "Try our Discord at https://discord.gg/0nRe5TNbTYoUruA4", None)
) )
case _ : VoiceHostInfo => case _: VoiceHostInfo =>
sendResponse(VoiceHostKill()) sendResponse(VoiceHostKill())
case msg @ ChangeAmmoMessage(item_guid, unk1) => case msg @ ChangeAmmoMessage(item_guid, unk1) =>
@ -4189,7 +4220,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
) )
Some(tool) Some(tool)
case _ => case _ =>
log.warn(s"ChangeFireState_Stop: ${player.Name} never started firing item ${item_guid.guid} in the first place?") log.warn(
s"ChangeFireState_Stop: ${player.Name} never started firing item ${item_guid.guid} in the first place?"
)
None None
} }
} }
@ -4243,7 +4276,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
log.warn(s"DropItem: ${player.Name} wanted to drop a $obj, but that isn't possible") log.warn(s"DropItem: ${player.Name} wanted to drop a $obj, but that isn't possible")
case None => case None =>
sendResponse(ObjectDeleteMessage(item_guid, 0)) //this is fine; item doesn't exist to the server anyway sendResponse(ObjectDeleteMessage(item_guid, 0)) //this is fine; item doesn't exist to the server anyway
log.warn(s"DropItem: ${player.Name} wanted to drop an item ${item_guid.guid}, but it was nowhere to be found") log.warn(
s"DropItem: ${player.Name} wanted to drop an item ${item_guid.guid}, but it was nowhere to be found"
)
} }
case msg @ PickupItemMessage(item_guid, player_guid, unk1, unk2) => case msg @ PickupItemMessage(item_guid, player_guid, unk1, unk2) =>
@ -4294,7 +4329,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
reloadValue reloadValue
} }
val finalReloadValue = actualReloadValue + currentMagazine val finalReloadValue = actualReloadValue + currentMagazine
log.info(s"${player.Name} successfully reloaded $reloadValue ${tool.AmmoType} into ${tool.Definition.Name}") log.info(
s"${player.Name} successfully reloaded $reloadValue ${tool.AmmoType} into ${tool.Definition.Name}"
)
tool.Magazine = finalReloadValue tool.Magazine = finalReloadValue
sendResponse(ReloadMessage(item_guid, finalReloadValue, unk1)) sendResponse(ReloadMessage(item_guid, finalReloadValue, unk1))
continent.AvatarEvents ! AvatarServiceMessage( continent.AvatarEvents ! AvatarServiceMessage(
@ -4303,7 +4340,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
) )
} }
} else { } else {
log.warn(s"ReloadMessage: the ${tool.Definition.Name} under ${player.Name}'s control can not reload (full=$magazineSize, want=$reloadValue)") log.warn(
s"ReloadMessage: the ${tool.Definition.Name} under ${player.Name}'s control can not reload (full=$magazineSize, want=$reloadValue)"
)
} }
case (_, Some(_)) => case (_, Some(_)) =>
log.warn(s"ReloadMessage: the object that was found for $item_guid was not a Tool") log.warn(s"ReloadMessage: the object that was found for $item_guid was not a Tool")
@ -4401,8 +4440,8 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
(session.account.gm || (session.account.gm ||
(player.avatar.vehicle.contains(object_guid) && vehicle.Owner.contains(player.GUID)) || (player.avatar.vehicle.contains(object_guid) && vehicle.Owner.contains(player.GUID)) ||
(player.Faction == vehicle.Faction && (player.Faction == vehicle.Faction &&
(vehicle.Definition.CanBeOwned.nonEmpty && (vehicle.Definition.CanBeOwned.nonEmpty &&
(vehicle.Owner.isEmpty || continent.GUID(vehicle.Owner.get).isEmpty) || vehicle.Destroyed))) && (vehicle.Owner.isEmpty || continent.GUID(vehicle.Owner.get).isEmpty) || vehicle.Destroyed))) &&
(vehicle.MountedIn.isEmpty || !vehicle.Seats.values.exists(_.isOccupied)) (vehicle.MountedIn.isEmpty || !vehicle.Seats.values.exists(_.isOccupied))
) { ) {
vehicle.Actor ! Vehicle.Deconstruct() vehicle.Actor ! Vehicle.Deconstruct()
@ -4503,7 +4542,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
) => ) =>
ContainableMoveItem(player.Name, source, destination, item, dest) ContainableMoveItem(player.Name, source, destination, item, dest)
case (None, _, _) => case (None, _, _) =>
log.error(s"MoveItem: ${player.Name} wanted to move $item_guid from $source_guid, but could not find source object") log.error(
s"MoveItem: ${player.Name} wanted to move $item_guid from $source_guid, but could not find source object"
)
case (_, None, _) => case (_, None, _) =>
log.error( log.error(
s"MoveItem: ${player.Name} wanted to move $item_guid to $destination_guid, but could not find destination object" s"MoveItem: ${player.Name} wanted to move $item_guid to $destination_guid, but could not find destination object"
@ -4566,7 +4607,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
avatarActor ! AvatarActor.DeactivateImplant(implant.definition.implantType) avatarActor ! AvatarActor.DeactivateImplant(implant.definition.implantType)
} }
case Some(implant) if !implant.initialized => () case Some(implant) if !implant.initialized => ()
case _ => log.error(s"AvatarImplantMessage: ${player.Name} has an unknown implant in $slot") case _ => log.error(s"AvatarImplantMessage: ${player.Name} has an unknown implant in $slot")
} }
} }
@ -4820,7 +4861,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
if (llu.Target.GUID == captureTerminal.Owner.GUID) { if (llu.Target.GUID == captureTerminal.Owner.GUID) {
continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.LluCaptured(llu)) continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.LluCaptured(llu))
} else { } else {
log.info(s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}") log.info(
s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}"
)
} }
case _ => log.warn("Item in specialItemSlotGuid is not registered with continent or is not a LLU") case _ => log.warn("Item in specialItemSlotGuid is not registered with continent or is not a LLU")
} }
@ -4892,7 +4935,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
) { ) {
FindLocalVehicle match { FindLocalVehicle match {
case Some(vehicle) => case Some(vehicle) =>
log.info(s"${player.Name} is accessing a ${terminal.Definition.Name} for ${player.Sex.possessive} ${vehicle.Definition.Name}") log.info(
s"${player.Name} is accessing a ${terminal.Definition.Name} for ${player.Sex.possessive} ${vehicle.Definition.Name}"
)
sendResponse( sendResponse(
UseItemMessage( UseItemMessage(
avatar_guid, avatar_guid,
@ -5049,18 +5094,22 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case None => ; case None => ;
} }
case Some(obj: CaptureFlag) => case Some(obj: CaptureFlag) =>
// LLU can normally only be picked up the faction that owns it // LLU can normally only be picked up the faction that owns it
if (specialItemSlotGuid.isEmpty) { if (specialItemSlotGuid.isEmpty) {
if(obj.Faction == player.Faction) { if (obj.Faction == player.Faction) {
specialItemSlotGuid = Some(obj.GUID) specialItemSlotGuid = Some(obj.GUID)
continent.LocalEvents ! CaptureFlagManager.PickupFlag(obj, player) continent.LocalEvents ! CaptureFlagManager.PickupFlag(obj, player)
} else { } else {
log.warn(s"Player ${player.toString} tried to pick up LLU ${obj.GUID} - ${obj.Faction} that doesn't belong to their faction") log.warn(
s"Player ${player.toString} tried to pick up LLU ${obj.GUID} - ${obj.Faction} that doesn't belong to their faction"
)
}
} else if (specialItemSlotGuid.get != obj.GUID) { // Ignore duplicate pickup requests
log.warn(
s"Player ${player.toString} tried to pick up LLU ${obj.GUID} - ${obj.Faction} but their special slot already contains $specialItemSlotGuid"
)
} }
} else if(specialItemSlotGuid.get != obj.GUID) { // Ignore duplicate pickup requests
log.warn(s"Player ${player.toString} tried to pick up LLU ${obj.GUID} - ${obj.Faction} but their special slot already contains $specialItemSlotGuid")
}
case Some(obj) => case Some(obj) =>
CancelZoningProcessWithDescriptiveReason("cancel_use") CancelZoningProcessWithDescriptiveReason("cancel_use")
@ -5221,7 +5270,8 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
player.Faction match { player.Faction match {
case PlanetSideEmpire.NC => case PlanetSideEmpire.NC =>
ToggleMaxSpecialState(enable = false) ToggleMaxSpecialState(enable = false)
case _ => log.warn(s"GenericActionMessage: ${player.Name} tried to cancel an uncancellable MAX special ability") case _ =>
log.warn(s"GenericActionMessage: ${player.Name} tried to cancel an uncancellable MAX special ability")
} }
} else { } else {
log.warn(s"GenericActionMessage: ${player.Name} can't handle action code 21") log.warn(s"GenericActionMessage: ${player.Name} can't handle action code 21")
@ -5274,9 +5324,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
CancelZoningProcessWithDescriptiveReason("cancel_use") CancelZoningProcessWithDescriptiveReason("cancel_use")
log.info(s"${player.Name} wishes to load a saved favorite loadout") log.info(s"${player.Name} wishes to load a saved favorite loadout")
action match { action match {
case FavoritesAction.Save => avatarActor ! AvatarActor.SaveLoadout(player, loadoutType, label, line) case FavoritesAction.Save => avatarActor ! AvatarActor.SaveLoadout(player, loadoutType, label, line)
case FavoritesAction.Delete => avatarActor ! AvatarActor.DeleteLoadout(player, loadoutType, line) case FavoritesAction.Delete => avatarActor ! AvatarActor.DeleteLoadout(player, loadoutType, line)
case FavoritesAction.Unknown => log.warn(s"FavoritesRequest: ${player.Name} requested an unknown favorites action") case FavoritesAction.Unknown =>
log.warn(s"FavoritesRequest: ${player.Name} requested an unknown favorites action")
} }
case msg @ WeaponDelayFireMessage(seq_time, weapon_guid) => ; case msg @ WeaponDelayFireMessage(seq_time, weapon_guid) => ;
@ -5289,7 +5340,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
AvatarAction.WeaponDryFire(player.GUID, weapon_guid) AvatarAction.WeaponDryFire(player.GUID, weapon_guid)
) )
case _ => case _ =>
log.warn(s"WeaponDryFire: ${player.Name}'s weapon ${weapon_guid.guid} is either not a weapon or does not exist") log.warn(
s"WeaponDryFire: ${player.Name}'s weapon ${weapon_guid.guid} is either not a weapon or does not exist"
)
} }
case msg @ WeaponFireMessage( case msg @ WeaponFireMessage(
@ -5571,9 +5624,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//todo: kick cargo passengers out. To be added after PR #216 is merged //todo: kick cargo passengers out. To be added after PR #216 is merged
obj match { obj match {
case v: Vehicle case v: Vehicle
if bailType == BailType.Bailed && if bailType == BailType.Bailed &&
v.SeatPermissionGroup(seat_num).contains(AccessPermissionGroup.Driver) && v.SeatPermissionGroup(seat_num).contains(AccessPermissionGroup.Driver) &&
v.isFlying => v.isFlying =>
v.Actor ! Vehicle.Deconstruct(None) //immediate deconstruction v.Actor ! Vehicle.Deconstruct(None) //immediate deconstruction
case _ => ; case _ => ;
} }
@ -5674,7 +5727,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
log.debug(s"$msg") log.debug(s"$msg")
case msg @ BindPlayerMessage(action, bindDesc, unk1, logging, unk2, unk3, unk4, pos) => case msg @ BindPlayerMessage(action, bindDesc, unk1, logging, unk2, unk3, unk4, pos) =>
//log.info("BindPlayerMessage: " + msg) //log.info("BindPlayerMessage: " + msg)
case msg @ PlanetsideAttributeMessage(object_guid, attribute_type, attribute_value) => case msg @ PlanetsideAttributeMessage(object_guid, attribute_type, attribute_value) =>
ValidObject(object_guid) match { ValidObject(object_guid) match {
@ -5691,41 +5744,45 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
) )
//kick players who should not be seated in the vehicle due to permission changes //kick players who should not be seated in the vehicle due to permission changes
if (allow == VehicleLockState.Locked) { //TODO only important permission atm if (allow == VehicleLockState.Locked) { //TODO only important permission atm
vehicle.Seats.foreach { case (seatIndex, seat) => vehicle.Seats.foreach {
seat.occupant match { case (seatIndex, seat) =>
case Some(tplayer : Player) => seat.occupant match {
if ( case Some(tplayer: Player) =>
vehicle.SeatPermissionGroup(seatIndex).contains(group) && tplayer != player if (vehicle.SeatPermissionGroup(seatIndex).contains(group) && tplayer != player) { //can not kick self
) { //can not kick self seat.unmount(tplayer)
seat.unmount(tplayer) tplayer.VehicleSeated = None
tplayer.VehicleSeated = None continent.VehicleEvents ! VehicleServiceMessage(
continent.VehicleEvents ! VehicleServiceMessage( continent.id,
continent.id, VehicleAction.KickPassenger(tplayer.GUID, 4, false, object_guid)
VehicleAction.KickPassenger(tplayer.GUID, 4, false, object_guid) )
) }
} case _ => ; // No player seated
case _ => ; // No player seated }
}
} }
vehicle.CargoHolds.foreach { case (cargoIndex, hold) => vehicle.CargoHolds.foreach {
hold.occupant match { case (cargoIndex, hold) =>
case Some(cargo) => hold.occupant match {
if (vehicle.SeatPermissionGroup(cargoIndex).contains(group)) { case Some(cargo) =>
//todo: this probably doesn't work for passengers within the cargo vehicle if (vehicle.SeatPermissionGroup(cargoIndex).contains(group)) {
// Instruct client to start bail dismount procedure //todo: this probably doesn't work for passengers within the cargo vehicle
self ! DismountVehicleCargoMsg(player.GUID, cargo.GUID, true, false, false) // Instruct client to start bail dismount procedure
} self ! DismountVehicleCargoMsg(player.GUID, cargo.GUID, true, false, false)
case None => ; // No vehicle in cargo }
} case None => ; // No vehicle in cargo
}
} }
} }
case None => ; case None => ;
} }
} else { } else {
log.warn(s"PlanetsideAttribute: vehicle attributes - unsupported change on vehicle $object_guid - $attribute_type, ${player.Name}") log.warn(
s"PlanetsideAttribute: vehicle attributes - unsupported change on vehicle $object_guid - $attribute_type, ${player.Name}"
)
} }
} else { } else {
log.warn(s"PlanetsideAttribute: vehicle attributes - ${player.Name} does not own vehicle ${vehicle.GUID} and can not change it") log.warn(
s"PlanetsideAttribute: vehicle attributes - ${player.Name} does not own vehicle ${vehicle.GUID} and can not change it"
)
} }
// Cosmetics options // Cosmetics options
@ -5778,7 +5835,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
Some(TargetInfo(player.GUID, health, armor)) Some(TargetInfo(player.GUID, health, armor))
case _ => case _ =>
log.warn(s"TargetingImplantRequest: the info that ${player.Name} requested for target ${x.target_guid} is not for a player") log.warn(
s"TargetingImplantRequest: the info that ${player.Name} requested for target ${x.target_guid} is not for a player"
)
None None
} }
}) })
@ -6514,16 +6573,16 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//handle inventory contents //handle inventory contents
box.Capacity = if (sumReloadValue <= fullMagazine) { box.Capacity = if (sumReloadValue <= fullMagazine) {
sumReloadValue sumReloadValue
} else { } else {
val splitReloadAmmo: Int = sumReloadValue - fullMagazine val splitReloadAmmo: Int = sumReloadValue - fullMagazine
log.trace( log.trace(
s"PerformToolAmmoChange: ${player.Name} takes ${originalBoxCapacity - splitReloadAmmo} from a box of $originalBoxCapacity $requestedAmmoType ammo" s"PerformToolAmmoChange: ${player.Name} takes ${originalBoxCapacity - splitReloadAmmo} from a box of $originalBoxCapacity $requestedAmmoType ammo"
) )
val boxForInventory = AmmoBox(box.Definition, splitReloadAmmo) val boxForInventory = AmmoBox(box.Definition, splitReloadAmmo)
continent.tasks ! stowNewFunc(boxForInventory) continent.tasks ! stowNewFunc(boxForInventory)
fullMagazine fullMagazine
} }
sendResponse( sendResponse(
InventoryStateMessage(box.GUID, tool.GUID, box.Capacity) InventoryStateMessage(box.GUID, tool.GUID, box.Capacity)
) //should work for both players and vehicles ) //should work for both players and vehicles
@ -6637,12 +6696,12 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
else { xs.map(_.obj.asInstanceOf[Tool].Magazine).sum } else { xs.map(_.obj.asInstanceOf[Tool].Magazine).sum }
val sumReloadValue: Int = box.Magazine + tailReloadValue val sumReloadValue: Int = box.Magazine + tailReloadValue
val actualReloadValue = if (sumReloadValue <= 3) { val actualReloadValue = if (sumReloadValue <= 3) {
RemoveOldEquipmentFromInventory(player)(x.obj) RemoveOldEquipmentFromInventory(player)(x.obj)
sumReloadValue sumReloadValue
} else { } else {
ModifyAmmunition(player)(box.AmmoSlot.Box, 3 - tailReloadValue) ModifyAmmunition(player)(box.AmmoSlot.Box, 3 - tailReloadValue)
3 3
} }
log.info(s"${player.Name} found $actualReloadValue more $ammoType grenades to throw") log.info(s"${player.Name} found $actualReloadValue more $ammoType grenades to throw")
ModifyAmmunition(player)( ModifyAmmunition(player)(
tool.AmmoSlot.Box, tool.AmmoSlot.Box,
@ -6859,27 +6918,33 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case obj: Hackable if obj.HackedBy.nonEmpty => case obj: Hackable if obj.HackedBy.nonEmpty =>
//sync hack state //sync hack state
amenity.Definition match { amenity.Definition match {
case GlobalDefinitions.capture_terminal => case GlobalDefinitions.capture_terminal =>
SendPlanetsideAttributeMessage( SendPlanetsideAttributeMessage(
amenity.GUID, amenity.GUID,
PlanetsideAttributeEnum.ControlConsoleHackUpdate, PlanetsideAttributeEnum.ControlConsoleHackUpdate,
HackCaptureActor.GetHackUpdateAttributeValue(amenity.asInstanceOf[CaptureTerminal], isResecured = false)) HackCaptureActor.GetHackUpdateAttributeValue(amenity.asInstanceOf[CaptureTerminal], isResecured = false)
case _ => )
HackObject(amenity.GUID, 1114636288L, 8L) //generic hackable object case _ =>
} HackObject(amenity.GUID, 1114636288L, 8L) //generic hackable object
}
// sync capture flags // sync capture flags
case llu: CaptureFlag => case llu: CaptureFlag =>
// Create LLU // Create LLU
sendResponse(ObjectCreateMessage( sendResponse(
llu.Definition.ObjectId, ObjectCreateMessage(
llu.GUID, llu.Definition.ObjectId,
llu.Definition.Packet.ConstructorData(llu).get llu.GUID,
)) llu.Definition.Packet.ConstructorData(llu).get
)
)
// Attach it to a player if it has a carrier // Attach it to a player if it has a carrier
if (llu.Carrier.nonEmpty) { if (llu.Carrier.nonEmpty) {
continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.SendPacket(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252))) continent.LocalEvents ! LocalServiceMessage(
continent.id,
LocalAction.SendPacket(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252))
)
} }
case _ => ; case _ => ;
} }
@ -6926,7 +6991,11 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
* @param attribute_number The attribute number * @param attribute_number The attribute number
* @param attribute_value The attribute value * @param attribute_value The attribute value
*/ */
def SendPlanetsideAttributeMessage(target_guid: PlanetSideGUID, attribute_number: PlanetsideAttributeEnum, attribute_value: Long): Unit = { def SendPlanetsideAttributeMessage(
target_guid: PlanetSideGUID,
attribute_number: PlanetsideAttributeEnum,
attribute_value: Long
): Unit = {
sendResponse(PlanetsideAttributeMessage(target_guid, attribute_number, attribute_value)) sendResponse(PlanetsideAttributeMessage(target_guid, attribute_number, attribute_value))
} }
@ -7462,7 +7531,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
sendResponse(DisconnectMessage("RequestSanctuaryZoneSpawn: player is already in sanctuary.")) sendResponse(DisconnectMessage("RequestSanctuaryZoneSpawn: player is already in sanctuary."))
} else { } else {
continent.GUID(player.VehicleSeated) match { continent.GUID(player.VehicleSeated) match {
case Some(obj : Vehicle) if !obj.Destroyed => case Some(obj: Vehicle) if !obj.Destroyed =>
cluster ! ICS.GetRandomSpawnPoint( cluster ! ICS.GetRandomSpawnPoint(
Zones.sanctuaryZoneNumber(player.Faction), Zones.sanctuaryZoneNumber(player.Faction),
player.Faction, player.Faction,
@ -7528,7 +7597,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case _: Vehicle => case _: Vehicle =>
terminal.Actor ! CommonMessages.Use(player, Some((target, continent.VehicleEvents))) terminal.Actor ! CommonMessages.Use(player, Some((target, continent.VehicleEvents)))
case _ => case _ =>
log.error(s"StartUsingProximityUnit: ${player.Name}, this ${terminal.Definition.Name} can not deal with target $target") log.error(
s"StartUsingProximityUnit: ${player.Name}, this ${terminal.Definition.Name} can not deal with target $target"
)
} }
terminal.Definition match { terminal.Definition match {
case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal => case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal =>
@ -7561,7 +7632,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
*/ */
def StopUsingProximityUnit(terminal: Terminal with ProximityUnit): Unit = { def StopUsingProximityUnit(terminal: Terminal with ProximityUnit): Unit = {
val term_guid = terminal.GUID val term_guid = terminal.GUID
val targets = FindProximityUnitTargetsInScope(terminal) val targets = FindProximityUnitTargetsInScope(terminal)
if (targets.nonEmpty) { if (targets.nonEmpty) {
if (usingMedicalTerminal.contains(term_guid)) { if (usingMedicalTerminal.contains(term_guid)) {
usingMedicalTerminal = None usingMedicalTerminal = None
@ -7802,10 +7873,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
* @return the projectile * @return the projectile
*/ */
def ResolveProjectileInteraction( def ResolveProjectileInteraction(
projectile_guid: PlanetSideGUID, projectile_guid: PlanetSideGUID,
resolution: DamageResolution.Value, resolution: DamageResolution.Value,
target: PlanetSideGameObject with FactionAffinity with Vitality, target: PlanetSideGameObject with FactionAffinity with Vitality,
pos: Vector3 pos: Vector3
): Option[DamageInteraction] = { ): Option[DamageInteraction] = {
FindProjectileEntry(projectile_guid) match { FindProjectileEntry(projectile_guid) match {
case Some(projectile) => case Some(projectile) =>
@ -7824,11 +7895,11 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
* @return a copy of the projectile * @return a copy of the projectile
*/ */
def ResolveProjectileInteraction( def ResolveProjectileInteraction(
projectile: Projectile, projectile: Projectile,
index: Int, index: Int,
resolution: DamageResolution.Value, resolution: DamageResolution.Value,
target: PlanetSideGameObject with FactionAffinity with Vitality, target: PlanetSideGameObject with FactionAffinity with Vitality,
pos: Vector3 pos: Vector3
): Option[DamageInteraction] = { ): Option[DamageInteraction] = {
if (!projectiles(index).contains(projectile)) { if (!projectiles(index).contains(projectile)) {
log.error(s"expected projectile could not be found at $index; can not resolve") log.error(s"expected projectile could not be found at $index; can not resolve")
@ -7845,10 +7916,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
* @return a copy of the projectile * @return a copy of the projectile
*/ */
def ResolveProjectileInteraction( def ResolveProjectileInteraction(
projectile: Projectile, projectile: Projectile,
resolution: DamageResolution.Value, resolution: DamageResolution.Value,
target: PlanetSideGameObject with FactionAffinity with Vitality, target: PlanetSideGameObject with FactionAffinity with Vitality,
pos: Vector3 pos: Vector3
): Option[DamageInteraction] = { ): Option[DamageInteraction] = {
if (projectile.isMiss) { if (projectile.isMiss) {
log.warn("expected projectile was already counted as a missed shot; can not resolve any further") log.warn("expected projectile was already counted as a missed shot; can not resolve any further")
@ -8248,7 +8319,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
} else { } else {
player.Find(tool) match { player.Find(tool) match {
case Some(newIndex) => case Some(newIndex) =>
log.warn(s"$logDecorator: ${player.Name} was looking for an item in his hand $index, but item was found at $newIndex instead") log.warn(
s"$logDecorator: ${player.Name} was looking for an item in his hand $index, but item was found at $newIndex instead"
)
player.Slot(newIndex).Equipment = None player.Slot(newIndex).Equipment = None
true true
case None => case None =>
@ -8433,16 +8506,17 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
val events = continent.AvatarEvents val events = continent.AvatarEvents
val zoneId = continent.id val zoneId = continent.id
(player.Inventory.Items ++ player.HolsterItems()) (player.Inventory.Items ++ player.HolsterItems())
.collect { case InventoryItem(obj: BoomerTrigger, index) => .collect {
player.Slot(index).Equipment = None case InventoryItem(obj: BoomerTrigger, index) =>
sendResponse(ObjectDeleteMessage(obj.GUID, 0)) player.Slot(index).Equipment = None
if (player.HasGUID && player.VisibleSlots.contains(index)) { sendResponse(ObjectDeleteMessage(obj.GUID, 0))
events ! AvatarServiceMessage( if (player.HasGUID && player.VisibleSlots.contains(index)) {
zoneId, events ! AvatarServiceMessage(
AvatarAction.ObjectDelete(player.GUID, obj.GUID) zoneId,
) AvatarAction.ObjectDelete(player.GUID, obj.GUID)
} )
obj }
obj
} }
} }
@ -8626,7 +8700,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
val msg: String = s"${player.Name} is driving a ${vehicle.Definition.Name}" val msg: String = s"${player.Name} is driving a ${vehicle.Definition.Name}"
log.info(msg) log.info(msg)
log.debug(s"LoadZoneInVehicleAsDriver: $msg") log.debug(s"LoadZoneInVehicleAsDriver: $msg")
val manifest = vehicle.PrepareGatingManifest() val manifest = vehicle.PrepareGatingManifest()
val pguid = player.GUID val pguid = player.GUID
val toChannel = manifest.file val toChannel = manifest.file
val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID) val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID)
@ -8637,7 +8711,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
manifest.cargo.foreach { manifest.cargo.foreach {
case ManifestPassengerEntry("MISSING_DRIVER", index) => case ManifestPassengerEntry("MISSING_DRIVER", index) =>
val cargo = vehicle.CargoHolds(index).occupant.get val cargo = vehicle.CargoHolds(index).occupant.get
log.warn(s"LoadZoneInVehicleAsDriver: ${player.Name} must eject cargo in hold $index; vehicle is missing driver") log.warn(
s"LoadZoneInVehicleAsDriver: ${player.Name} must eject cargo in hold $index; vehicle is missing driver"
)
CargoBehavior.HandleVehicleCargoDismount(cargo.GUID, cargo, vehicle.GUID, vehicle, false, false, true) CargoBehavior.HandleVehicleCargoDismount(cargo.GUID, cargo, vehicle.GUID, vehicle, false, false, true)
case entry => case entry =>
val cargo = vehicle.CargoHolds(entry.mount).occupant.get val cargo = vehicle.CargoHolds(entry.mount).occupant.get
@ -8758,14 +8834,16 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case hold if hold.isOccupied => case hold if hold.isOccupied =>
val cargo = hold.occupant.get val cargo = hold.occupant.get
cargo.Continent = toZoneId cargo.Continent = toZoneId
//point to the cargo vehicle to instigate cargo vehicle driver transportation //point to the cargo vehicle to instigate cargo vehicle driver transportation
// galaxyService ! GalaxyServiceMessage( // galaxyService ! GalaxyServiceMessage(
// toChannel, // toChannel,
// GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest) // GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)
// ) // )
} }
case None => case None =>
log.error(s"LoadZoneTransferPassengerMessages: ${player.Name} expected a manifest for zone transfer; got nothing") log.error(
s"LoadZoneTransferPassengerMessages: ${player.Name} expected a manifest for zone transfer; got nothing"
)
} }
} }
@ -9522,18 +9600,18 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
s"WeaponFireMessage: ${player.Name}'s ${projectile_info.Name} is a remote projectile" s"WeaponFireMessage: ${player.Name}'s ${projectile_info.Name} is a remote projectile"
) )
continent.tasks ! (if (projectile.HasGUID) { continent.tasks ! (if (projectile.HasGUID) {
continent.AvatarEvents ! AvatarServiceMessage( continent.AvatarEvents ! AvatarServiceMessage(
continent.id, continent.id,
AvatarAction.ProjectileExplodes( AvatarAction.ProjectileExplodes(
player.GUID, player.GUID,
projectile.GUID, projectile.GUID,
projectile projectile
) )
) )
ReregisterProjectile(projectile) ReregisterProjectile(projectile)
} else { } else {
RegisterProjectile(projectile) RegisterProjectile(projectile)
}) })
} }
projectilesToCleanUp(projectileIndex) = false projectilesToCleanUp(projectileIndex) = false

View file

@ -18,11 +18,14 @@ import net.psforever.types.{PlanetSideGUID, Vector3}
import scala.concurrent.duration.{Duration, _} import scala.concurrent.duration.{Duration, _}
class LocalService(zone: Zone) extends Actor { class LocalService(zone: Zone) extends Actor {
private val doorCloser = context.actorOf(Props[DoorCloseActor](), s"${zone.id}-local-door-closer") private val doorCloser = context.actorOf(Props[DoorCloseActor](), s"${zone.id}-local-door-closer")
private val hackClearer = context.actorOf(Props[HackClearActor](), s"${zone.id}-local-hack-clearer") private val hackClearer = context.actorOf(Props[HackClearActor](), s"${zone.id}-local-hack-clearer")
private val hackCapturer = context.actorOf(Props(classOf[HackCaptureActor], zone.tasks), s"${zone.id}-local-hack-capturer") private val hackCapturer =
private val captureFlagManager = context.actorOf(Props(classOf[CaptureFlagManager], zone.tasks, zone), s"${zone.id}-local-capture-flag-manager") context.actorOf(Props(classOf[HackCaptureActor], zone.tasks), s"${zone.id}-local-hack-capturer")
private val engineer = context.actorOf(Props(classOf[DeployableRemover], zone.tasks), s"${zone.id}-deployable-remover-agent") private val captureFlagManager =
context.actorOf(Props(classOf[CaptureFlagManager], zone.tasks, zone), s"${zone.id}-local-capture-flag-manager")
private val engineer =
context.actorOf(Props(classOf[DeployableRemover], zone.tasks), s"${zone.id}-deployable-remover-agent")
private val teleportDeployment: ActorRef = private val teleportDeployment: ActorRef =
context.actorOf(Props[RouterTelepadActivation](), s"${zone.id}-telepad-activate-agent") context.actorOf(Props[RouterTelepadActivation](), s"${zone.id}-telepad-activate-agent")
private[this] val log = org.log4s.getLogger private[this] val log = org.log4s.getLogger
@ -83,7 +86,11 @@ class LocalService(zone: Zone) extends Actor {
) )
case LocalAction.HackClear(player_guid, target, unk1, unk2) => case LocalAction.HackClear(player_guid, target, unk1, unk2) =>
LocalEvents.publish( LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.SendHackMessageHackCleared(target.GUID, unk1, unk2)) LocalServiceResponse(
s"/$forChannel/Local",
player_guid,
LocalResponse.SendHackMessageHackCleared(target.GUID, unk1, unk2)
)
) )
case LocalAction.HackTemporarily(player_guid, _, target, unk1, duration, unk2) => case LocalAction.HackTemporarily(player_guid, _, target, unk1, duration, unk2) =>
hackClearer ! HackClearActor.ObjectIsHacked(target, zone, unk1, unk2, duration) hackClearer ! HackClearActor.ObjectIsHacked(target, zone, unk1, unk2, duration)
@ -281,6 +288,13 @@ class LocalService(zone: Zone) extends Actor {
//response from HackClearActor //response from HackClearActor
case HackClearActor.SendHackMessageHackCleared(target_guid, _, unk1, unk2) => case HackClearActor.SendHackMessageHackCleared(target_guid, _, unk1, unk2) =>
log.info(s"Clearing hack for $target_guid") log.info(s"Clearing hack for $target_guid")
LocalEvents.publish(
LocalServiceResponse(
s"/${zone.id}/Local",
Service.defaultPlayerGUID,
LocalResponse.SendHackMessageHackCleared(target_guid, unk1, unk2)
)
)
//message from ProximityTerminalControl //message from ProximityTerminalControl
case Terminal.StartProximityEffect(terminal) => case Terminal.StartProximityEffect(terminal) =>
@ -418,13 +432,9 @@ class LocalService(zone: Zone) extends Actor {
sender() ! Vitality.DamageResolution(target, cause) sender() ! Vitality.DamageResolution(target, cause)
// Forward all CaptureFlagManager messages // Forward all CaptureFlagManager messages
case msg @ case msg @ (CaptureFlagManager.SpawnCaptureFlag(_, _, _) | CaptureFlagManager.PickupFlag(_, _) |
(CaptureFlagManager.SpawnCaptureFlag(_, _, _) CaptureFlagManager.DropFlag(_) | CaptureFlagManager.Captured(_) | CaptureFlagManager.Lost(_, _) |
| CaptureFlagManager.PickupFlag(_, _) CaptureFlagManager) =>
| CaptureFlagManager.DropFlag(_)
| CaptureFlagManager.Captured(_)
| CaptureFlagManager.Lost(_, _)
| CaptureFlagManager) =>
captureFlagManager.forward(msg) captureFlagManager.forward(msg)
case msg => case msg =>