From 5a5a08137eaa56e294acf93399181a9da7cae477 Mon Sep 17 00:00:00 2001 From: ScrawnyRonnie Date: Sun, 14 Dec 2025 18:20:18 -0500 Subject: [PATCH] some zoning protection, misc fixes --- src/main/resources/zonemaps/map05.json | 4 ++-- src/main/resources/zonemaps/ugd06.json | 4 ++-- .../session/support/ZoningOperations.scala | 21 +++++++++++++++++-- .../net/psforever/actors/zone/ZoneActor.scala | 8 ++++++- .../scala/net/psforever/objects/Player.scala | 1 + .../scala/net/psforever/objects/Vehicle.scala | 1 + .../objects/avatar/PlayerControl.scala | 2 +- .../damage/DamageableVehicle.scala | 2 +- .../local/support/HackCaptureActor.scala | 8 ++++++- 9 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/main/resources/zonemaps/map05.json b/src/main/resources/zonemaps/map05.json index a1e3816e4..1f72327d7 100644 --- a/src/main/resources/zonemaps/map05.json +++ b/src/main/resources/zonemaps/map05.json @@ -21625,7 +21625,7 @@ "Owner": 1303, "AbsX": 3577.178, "AbsY": 2712.24927, - "AbsZ": 32.8808441, + "AbsZ": 34.289, "Yaw": 318.0, "GUID": 1843, "MapID": null, @@ -21664,7 +21664,7 @@ "Owner": 1303, "AbsX": 3588.1582, "AbsY": 2700.0542, - "AbsZ": 32.8808441, + "AbsZ": 34.289, "Yaw": 318.0, "GUID": 1846, "MapID": null, diff --git a/src/main/resources/zonemaps/ugd06.json b/src/main/resources/zonemaps/ugd06.json index a87dd2108..33f2c5328 100644 --- a/src/main/resources/zonemaps/ugd06.json +++ b/src/main/resources/zonemaps/ugd06.json @@ -8289,7 +8289,7 @@ "AbsY": 1070.60535, "AbsZ": 173.239014, "Yaw": 338.0, - "GUID": 648, + "GUID": 649, "MapID": null, "IsChildObject": true }, @@ -8302,7 +8302,7 @@ "AbsY": 1132.36707, "AbsZ": 138.999, "Yaw": 124.0, - "GUID": 649, + "GUID": 648, "MapID": null, "IsChildObject": true }, diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index f0d373712..80376a530 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -634,8 +634,6 @@ class ZoningOperations( ) } } - player.Zone.ApplyHomeLockBenefitsOnLogin(player) - SessionOutfitHandlers.HandleLoginOutfitCheck(player, sessionLogic) } def handleZoneResponse(foundZone: Zone): Unit = { @@ -695,6 +693,7 @@ class ZoningOperations( 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" ) + player.protectedWhileZoning = true } val previousZoningType = ztype CancelZoningProcess() @@ -1111,6 +1110,12 @@ class ZoningOperations( PlanetsideAttributeEnum.ControlConsoleHackUpdate, HackCaptureActor.GetHackUpdateAttributeValue(amenity.asInstanceOf[CaptureTerminal], isResecured = false) ) + case GlobalDefinitions.vanu_control_console => + sessionLogic.general.sendPlanetsideAttributeMessage( + amenity.GUID, + PlanetsideAttributeEnum.ControlConsoleHackUpdate, + HackCaptureActor.GetHackUpdateAttributeValue(amenity.asInstanceOf[CaptureTerminal], isResecured = false) + ) case _ => sessionLogic.general.hackObject(amenity.GUID, unk1 = 1114636288L, HackState7.Unk8) //generic hackable object } @@ -1397,6 +1402,7 @@ class ZoningOperations( s"LoadZoneTransferPassengerMessages: ${player.Name} expected a manifest for zone transfer; got nothing" ) } + vehicle.protectedWhileZoning = false } /** Before changing zones, perform the following task (which can be a nesting of subtasks). */ @@ -1961,6 +1967,7 @@ class ZoningOperations( deadState = DeadState.RespawnTime val tplayer = new Player(avatar) session = session.copy(player = tplayer) + tplayer.protectedWhileZoning = true //actual zone is undefined; going to our sanctuary RandomSanctuarySpawnPosition(tplayer) DefinitionUtil.applyDefaultLoadout(tplayer) @@ -1973,6 +1980,7 @@ class ZoningOperations( deadState = DeadState.RespawnTime session = session.copy(player = new Player(avatar)) player.Zone = inZone + player.protectedWhileZoning = true optionalSavedData match { case Some(results) => val health = results.health @@ -2086,6 +2094,7 @@ class ZoningOperations( log.info(s"RestoreInfo: player $name is alive") deadState = DeadState.Alive session = session.copy(player = p, avatar = a) + p.protectedWhileZoning = true sessionLogic.persist() setupAvatarFunc = AvatarRejoin //dropMedicalApplicators(p) @@ -2635,6 +2644,7 @@ class ZoningOperations( def AvatarRejoin(): Unit = { sessionLogic.vehicles.GetKnownVehicleAndSeat() match { case (Some(vehicle: Vehicle), Some(seat: Int)) => + vehicle.protectedWhileZoning = true //vehicle and driver/passenger val vguid = vehicle.GUID sendResponse(OCM.apply(vehicle)) @@ -2678,6 +2688,8 @@ class ZoningOperations( StormInfo(Vector3(0.9f, 0.9f, 0.0f), 243, 215), StormInfo(Vector3(0.1f, 0.2f, 0.0f), 241, 215), StormInfo(Vector3(0.95f, 0.2f, 0.0f), 241, 215))))*/ + player.Zone.ApplyHomeLockBenefitsOnLogin(player) + SessionOutfitHandlers.HandleLoginOutfitCheck(player, sessionLogic) //begin looking for conditions to set the avatar context.system.scheduler.scheduleOnce(delay = 750 millisecond, context.self, SessionActor.SetCurrentAvatar(player, 200)) } @@ -3474,6 +3486,7 @@ class ZoningOperations( deadState = DeadState.Release //we may be alive or dead, may or may not be a corpse sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, player.Faction, unk5=true)) DrawCurrentAmsSpawnPoint() + player.protectedWhileZoning = true } /** @@ -3653,6 +3666,9 @@ class ZoningOperations( //originally the client sent a death statistic update in between each change of statistic categories, about 30 times sendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))) statisticsPacketFunc = respawnAvatarStatisticsFields + player.protectedWhileZoning = false + player.Zone.ApplyHomeLockBenefitsOnLogin(player) + SessionOutfitHandlers.HandleLoginOutfitCheck(player, sessionLogic) } /** @@ -3683,6 +3699,7 @@ class ZoningOperations( } //originally the client sent a death statistic update in between each change of statistic categories, about 30 times sendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))) + player.protectedWhileZoning = false } /** diff --git a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala index 381468766..d5461dc04 100644 --- a/src/main/scala/net/psforever/actors/zone/ZoneActor.scala +++ b/src/main/scala/net/psforever/actors/zone/ZoneActor.scala @@ -203,7 +203,13 @@ class ZoneActor( def AssignLockedBy(zone: Zone, notifyPlayers: Boolean): Unit = { val buildings = zone.Buildings.values - val facilities = buildings.filter(_.BuildingType == StructureType.Facility).toSeq + val facilities = if (zone.id.startsWith("c")) { + buildings.filter(b => + b.Name.startsWith("N") || b.Name.startsWith("S")).toSeq + } + else { + buildings.filter(_.BuildingType == StructureType.Facility).toSeq + } val factions = facilities.map(_.Faction).toSet zone.lockedBy = if (factions.size == 1) factions.head diff --git a/src/main/scala/net/psforever/objects/Player.scala b/src/main/scala/net/psforever/objects/Player.scala index e84a88baf..ef86bcbae 100644 --- a/src/main/scala/net/psforever/objects/Player.scala +++ b/src/main/scala/net/psforever/objects/Player.scala @@ -90,6 +90,7 @@ class Player(var avatar: Avatar) var outfit_window_open: Boolean = false var outfit_list_open: Boolean = false var maxAutoRunEnabled: Boolean = false + var protectedWhileZoning: Boolean = false /** From PlanetsideAttributeMessage */ var PlanetsideAttribute: Array[Long] = Array.ofDim(120) diff --git a/src/main/scala/net/psforever/objects/Vehicle.scala b/src/main/scala/net/psforever/objects/Vehicle.scala index 386aa98f4..f7435166f 100644 --- a/src/main/scala/net/psforever/objects/Vehicle.scala +++ b/src/main/scala/net/psforever/objects/Vehicle.scala @@ -114,6 +114,7 @@ class Vehicle(private val vehicleDef: VehicleDefinition) private var cloaked: Boolean = false private var flying: Option[Int] = None private var capacitor: Int = 0 + var protectedWhileZoning: Boolean = false /** * Permissions control who gets to access different parts of the vehicle; diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 03f74e764..aaff8903b 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -790,7 +790,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm target: Target, applyDamageTo: Output ): Unit = { - if (player.isAlive && !player.spectator) { + if (player.isAlive && !player.spectator && !player.protectedWhileZoning) { val originalHealth = player.Health val originalArmor = player.Armor val originalStamina = player.avatar.stamina diff --git a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala index 2519ddc4e..e49cd2d8b 100644 --- a/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala +++ b/src/main/scala/net/psforever/objects/serverobject/damage/DamageableVehicle.scala @@ -75,7 +75,7 @@ trait DamageableVehicle val shields = obj.Shields val damageToHealth = originalHealth - health val damageToShields = originalShields - shields - if (WillAffectTarget(target, damageToHealth + damageToShields, cause)) { + if (WillAffectTarget(target, damageToHealth + damageToShields, cause) && !obj.protectedWhileZoning) { target.LogActivity(cause) DamageLog( target, diff --git a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala index 00d556008..dc66a9281 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -277,7 +277,13 @@ class HackCaptureActor extends Actor { } val buildings = building.Zone.Buildings.values val hackedBaseId = building.GUID - val facilities = buildings.filter(_.BuildingType == StructureType.Facility).toSeq + val facilities = if (building.Zone.id.startsWith("c")) { + buildings.filter(b => + b.Name.startsWith("N") || b.Name.startsWith("S")).toSeq + } + else { + buildings.filter(_.BuildingType == StructureType.Facility).toSeq + } val ownedFacilities = facilities.filter(b => b.Faction == hackedByFaction && b.GUID != hackedBaseId )