diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index df4c74044..3936fa7ea 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -13,7 +13,7 @@ import net.psforever.objects.avatar.scoring.{Assist, Death, EquipmentStat, KDASt import net.psforever.objects.sourcing.{TurretSource, VehicleSource} import net.psforever.packet.game.ImplantAction import net.psforever.services.avatar.AvatarServiceResponse -import net.psforever.types.{ChatMessageType, StatisticalCategory, StatisticalElement, Vector3} +import net.psforever.types.{ChatMessageType, StatisticalCategory, StatisticalElement} import net.psforever.zones.Zones import org.joda.time.{LocalDateTime, Seconds} diff --git a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala index 009d0bbd7..09bd78579 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -7,7 +7,7 @@ import net.psforever.objects.ce.Deployable import net.psforever.objects.serverobject.doors.Door 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} +import net.psforever.packet.game.{ChatMsg, DeployableObjectsInfoMessage, GenericActionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HackMessage, HackState, HackState1, InventoryStateMessage, ObjectAttachMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, OrbitalShuttleTimeMsg, PadAndShuttlePair, PlanetsideAttributeMessage, ProximityTerminalUseMessage, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} import net.psforever.services.Service import net.psforever.services.local.LocalResponse import net.psforever.types.{ChatMessageType, PlanetSideGUID, Vector3} @@ -136,7 +136,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) case LocalResponse.SendHackMessageHackCleared(targetGuid, unk1, unk2) => - sendResponse(HackMessage(unk1=0, targetGuid, guid, progress=0, unk1, HackState.HackCleared, unk2)) + sendResponse(HackMessage(HackState1.Unk0, targetGuid, guid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) case LocalResponse.HackObject(targetGuid, unk1, unk2) => sessionLogic.general.hackObject(targetGuid, unk1, unk2) diff --git a/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala index c0810ab64..f28ab0f38 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/LocalHandlerLogic.scala @@ -7,7 +7,7 @@ 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} +import net.psforever.packet.game.{ChatMsg, DeployableObjectsInfoMessage, GenericActionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HackMessage, HackState, HackState1, InventoryStateMessage, ObjectAttachMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, OrbitalShuttleTimeMsg, PadAndShuttlePair, PlanetsideAttributeMessage, ProximityTerminalUseMessage, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} import net.psforever.services.Service import net.psforever.services.local.LocalResponse import net.psforever.types.{ChatMessageType, PlanetSideGUID, Vector3} @@ -125,7 +125,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) case LocalResponse.SendHackMessageHackCleared(targetGuid, unk1, unk2) => - sendResponse(HackMessage(unk1=0, targetGuid, guid, progress=0, unk1, HackState.HackCleared, unk2)) + sendResponse(HackMessage(HackState1.Unk0, targetGuid, guid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) case LocalResponse.HackObject(targetGuid, unk1, unk2) => sessionLogic.general.hackObject(targetGuid, unk1, unk2) diff --git a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala index 26d1db691..9f3961911 100644 --- a/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/GeneralOperations.scala @@ -562,8 +562,8 @@ class GeneralOperations( * @param unk1 na * @param unk2 na */ - def hackObject(targetGuid: PlanetSideGUID, unk1: Long, unk2: Long): Unit = { - sendResponse(HackMessage(unk1=0, targetGuid, player_guid=Service.defaultPlayerGUID, progress=100, unk1, HackState.Hacked, unk2)) + def hackObject(targetGuid: PlanetSideGUID, unk1: Long, unk2: HackState7): Unit = { + sendResponse(HackMessage(HackState1.Unk0, targetGuid, player_guid=Service.defaultPlayerGUID, progress=100, unk1, HackState.Hacked, unk2)) } /** 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 6648cf3ba..93ffd42f4 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -17,7 +17,7 @@ import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.serverobject.turret.auto.AutomatedTurret import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource} import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, ReconstructionActivity, SpawningActivity} -import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, MailMessage, ObjectDetectedMessage, SessionStatistic} +import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic} import net.psforever.services.chat.DefaultChannel import scala.collection.mutable @@ -1084,26 +1084,30 @@ class ZoningOperations( * @param zone the zone being loaded */ def configZone(zone: Zone): Unit = { - zone.Buildings.values.foreach(building => { - val guid = building.GUID - sendResponse(SetEmpireMessage(guid, building.Faction)) - // power - building.Generator match { - 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 _ => () - } - // capitol force dome state - if (building.IsCapitol && building.ForceDomeActive) { - sendResponse(GenericObjectActionMessage(guid, 13)) - } - // amenities - building.Amenities.collect { - case obj if obj.Destroyed => configAmenityAsDestroyed(obj) - case obj => configAmenityAsWorking(obj) + zone + .Buildings + .values + .foreach { building => + val guid = building.GUID + sendResponse(SetEmpireMessage(guid, building.Faction)) + // power + building.Generator match { + 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 _ => () + } + // capitol force dome state + if (building.IsCapitol && building.ForceDomeActive) { + sendResponse(GenericObjectActionMessage(guid, 13)) + } + // amenities + building.Amenities.collect { + case obj if obj.Destroyed => configAmenityAsDestroyed(obj) + case obj => configAmenityAsWorking(obj) + } + //sendResponse(HackMessage(HackState1.Unk3, guid, Service.defaultPlayerGUID, progress=0, -1f, HackState.HackCleared, HackState7.Unk8)) } - }) } /** @@ -1156,7 +1160,7 @@ class ZoningOperations( HackCaptureActor.GetHackUpdateAttributeValue(amenity.asInstanceOf[CaptureTerminal], isResecured = false) ) case _ => - sessionLogic.general.hackObject(amenity.GUID, 1114636288L, 8L) //generic hackable object + sessionLogic.general.hackObject(amenity.GUID, unk1 = 1114636288L, HackState7.Unk8) //generic hackable object } // sync capture flags diff --git a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala index 4d894c2a2..1745f6476 100644 --- a/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/FieldTurretDeployable.scala @@ -11,6 +11,7 @@ import net.psforever.objects.serverobject.turret.{MountableTurret, WeaponTurrets import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.sourcing.SourceEntry import net.psforever.objects.vital.{InGameActivity, ShieldCharge} +import net.psforever.packet.game.HackState1 import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.PlanetSideGUID @@ -54,7 +55,7 @@ class FieldTurretControl(turret: TurretDeployable) sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, turret), WeaponTurrets.FinishHackingTurretDeployable(turret, player), - GenericHackables.HackingTickAction(progressType = 1, player, turret, item.GUID) + GenericHackables.HackingTickAction(HackState1.Unk1, player, turret, item.GUID) ) case CommonMessages.ChargeShields(amount, motivator) => diff --git a/src/main/scala/net/psforever/objects/Vehicles.scala b/src/main/scala/net/psforever/objects/Vehicles.scala index c25073e06..086d7d04d 100644 --- a/src/main/scala/net/psforever/objects/Vehicles.scala +++ b/src/main/scala/net/psforever/objects/Vehicles.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.transfer.TransferContainer import net.psforever.objects.serverobject.structures.WarpGate import net.psforever.objects.vehicles._ import net.psforever.objects.zones.Zone -import net.psforever.packet.game.TriggeredSound +import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, TriggeredSound} import net.psforever.types.{DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} @@ -73,7 +73,7 @@ object Vehicles { } vehicle.AssignOwnership(None) val empire = VehicleLockState.Empire.id - val factionChannel = s"${vehicle.Faction}" + //val factionChannel = s"${vehicle.Faction}" (0 to 2).foreach(group => { vehicle.PermissionGroup(group, empire) /*vehicle.Zone.VehicleEvents ! VehicleServiceMessage( @@ -131,7 +131,7 @@ object Vehicles { if (vehicle.OwnerGuid.contains(pguid)) { vehicle.AssignOwnership(None) //vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, VehicleAction.Ownership(pguid, PlanetSideGUID(0))) - val vguid = vehicle.GUID + //val vguid = vehicle.GUID val empire = VehicleLockState.Empire.id (0 to 2).foreach(group => { vehicle.PermissionGroup(group, empire) @@ -230,11 +230,23 @@ object Vehicles { * Change the faction of the vehicle to the hacker's faction and remove all occupants. * @param target The `Vehicle` object that has been hacked/jacked * @param hacker the one whoi performed the hack and will inherit ownership of the target vehicle - * @param unk na; used by `HackMessage` as `unk5` */ - def FinishHackingVehicle(target: Vehicle, hacker: Player, unk: Long)(): Unit = { + def FinishHackingVehicle(target: Vehicle, hacker: Player)(): Unit = { log.info(s"${hacker.Name} has jacked a ${target.Definition.Name}") + val tGuid = target.GUID + val hGuid = hacker.GUID + val hFaction = hacker.Faction val zone = target.Zone + val zoneid = zone.id + val vehicleEvents = zone.VehicleEvents + vehicleEvents ! VehicleServiceMessage( + zoneid, + VehicleAction.SendResponse( + Service.defaultPlayerGUID, + HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8) + ) + ) + target.Actor ! CommonMessages.Hack(hacker, target) // Forcefully dismount any cargo target.CargoHolds.foreach { case (_, cargoHold) => cargoHold.occupant.collect { @@ -244,18 +256,16 @@ object Vehicles { // Forcefully dismount all seated occupants from the vehicle target.Seats.values.foreach(seat => { seat.occupant.collect { - tplayer: Player => - seat.unmount(tplayer) - tplayer.VehicleSeated = None - if (tplayer.HasGUID) { - zone.VehicleEvents ! VehicleServiceMessage( - zone.id, - VehicleAction.KickPassenger(tplayer.GUID, 4, unk2 = false, target.GUID) - ) - } + player: Player => + seat.unmount(player) + player.VehicleSeated = None + vehicleEvents ! VehicleServiceMessage( + zoneid, + VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, tGuid) + ) } }) - // If the vehicle can fly and is flying deconstruct it, and well played to whomever managed to hack a plane in mid air. I'm impressed. + // If the vehicle can fly and is flying: deconstruct it; and well played to whomever managed to hack a plane in mid air if (target.Definition.CanFly && target.isFlying) { // todo: Should this force the vehicle to land in the same way as when a pilot bails with passengers on board? target.Actor ! Vehicle.Deconstruct() @@ -273,19 +283,18 @@ object Vehicles { Vehicles.Disown(tplayer, target) } // Now take ownership of the jacked vehicle - target.Actor ! CommonMessages.Hack(hacker, target) - target.Faction = hacker.Faction + target.Faction = hFaction Vehicles.Own(target, hacker) //todo: Send HackMessage -> HackCleared to vehicle? can be found in packet captures. Not sure if necessary. // And broadcast the faction change to other clients zone.AvatarEvents ! AvatarServiceMessage( - zone.id, - AvatarAction.SetEmpire(Service.defaultPlayerGUID, target.GUID, hacker.Faction) + zoneid, + AvatarAction.SetEmpire(Service.defaultPlayerGUID, tGuid, hFaction) ) } zone.LocalEvents ! LocalServiceMessage( - zone.id, - LocalAction.TriggerSound(hacker.GUID, TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f) + zoneid, + LocalAction.TriggerSound(hGuid, TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f) ) // Clean up after specific vehicles, e.g. remove router telepads // If AMS is deployed, swap it to the new faction @@ -298,9 +307,17 @@ object Vehicles { util.Actor ! TelepadLike.Activate(util) } case GlobalDefinitions.ams if target.DeploymentState == DriveState.Deployed => - zone.VehicleEvents ! VehicleServiceMessage.AMSDeploymentChange(zone) + vehicleEvents ! VehicleServiceMessage.AMSDeploymentChange(zone) case _ => () } + vehicleEvents ! VehicleServiceMessage( + zoneid, + VehicleAction.SendResponse( + Service.defaultPlayerGUID, + HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8) + ) + ) + target.Actor ! CommonMessages.ClearHack() } def FindANTChargingSource( diff --git a/src/main/scala/net/psforever/objects/serverobject/environment/interaction/common/WithDeath.scala b/src/main/scala/net/psforever/objects/serverobject/environment/interaction/common/WithDeath.scala index 4e3898847..4e63d45ba 100644 --- a/src/main/scala/net/psforever/objects/serverobject/environment/interaction/common/WithDeath.scala +++ b/src/main/scala/net/psforever/objects/serverobject/environment/interaction/common/WithDeath.scala @@ -6,7 +6,7 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env import net.psforever.objects.sourcing.SourceEntry import net.psforever.objects.vital.etc.SuicideReason import net.psforever.objects.vital.interaction.DamageInteraction -import net.psforever.objects.vital.{IncarnationActivity, ReconstructionActivity, Vitality} +import net.psforever.objects.vital.{IncarnationActivity, Vitality} import net.psforever.objects.zones.InteractsWithZone import scala.annotation.unused diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index a88b1907e..3511b4dc5 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.hackable import net.psforever.objects.{Player, Vehicle} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} -import net.psforever.packet.game.{HackMessage, HackState} +import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7} import net.psforever.types.PlanetSideGUID import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} @@ -68,43 +68,34 @@ object GenericHackables { * @see `HackState` * @param progressType 1 - remote electronics kit hack (various ...); * 2 - nano dispenser (upgrade canister) turret upgrade - * @param tplayer the player performing the action + * @param hacker the player performing the action * @param target the object being affected * @param tool_guid the tool being used to affest the object * @param progress the current progress value * @return `true`, if the next cycle of progress should occur; * `false`, otherwise */ - def HackingTickAction(progressType: Int, tplayer: Player, target: PlanetSideServerObject, tool_guid: PlanetSideGUID)( + def HackingTickAction(progressType: HackState1, hacker: Player, target: PlanetSideServerObject, tool_guid: PlanetSideGUID)( progress: Float ): Boolean = { //hack state for progress bar visibility - val vis = if (progress <= 0L) { - HackState.Start + val (progressState, progressGrade) = if (progress <= 0L) { + (HackState.Start, 0) } else if (progress >= 100L) { - HackState.Finished - } else if (target.isMoving(test = 1f)) { - // If the object is moving (more than slightly to account for things like magriders rotating, or the last velocity reported being the magrider dipping down on dismount) then cancel the hack - HackState.Cancelled + (HackState.Finished, 100) + } else if (target.isMoving(test = 1f) || target.Destroyed || !target.HasGUID) { + (HackState.Cancelled, 0) } else { - HackState.Ongoing + (HackState.Ongoing, progress.toInt) } target.Zone.AvatarEvents ! AvatarServiceMessage( - tplayer.Name, + hacker.Name, AvatarAction.SendResponse( Service.defaultPlayerGUID, - if (!target.HasGUID) { - //cancel the hack (target is gone) - HackMessage(progressType, target.GUID, tplayer.GUID, 0, 0L, HackState.Cancelled, 8L) - } else if (vis == HackState.Cancelled) { - //cancel the hack (e.g. vehicle drove away) - HackMessage(progressType, target.GUID, tplayer.GUID, 0, 0L, vis, 8L) - } else { - HackMessage(progressType, target.GUID, tplayer.GUID, progress.toInt, 0L, vis, 8L) - } + HackMessage(progressType, target.GUID, hacker.GUID, progressGrade, 0L, progressState, HackState7.Unk8) ) ) - vis != HackState.Cancelled + progressState != HackState.Cancelled } /** @@ -112,12 +103,12 @@ object GenericHackables { * Pass the message onto the hackable object and onto the local events system. * @param target the `Hackable` object that has been hacked * @param user the player that is performing this hacking task - * @param unk na; - * used by `HackMessage` as `unk5` + * @param hackValue na; + * @param hackClearValue na * @see `HackMessage` */ //TODO add params here depending on which params in HackMessage are important - def FinishHacking(target: PlanetSideServerObject with Hackable, user: Player, unk: Long)(): Unit = { + def FinishHacking(target: PlanetSideServerObject with Hackable, user: Player, hackValue: Int, hackClearValue: Int)(): Unit = { import akka.pattern.ask import scala.concurrent.duration._ // Wait for the target actor to set the HackedBy property, otherwise LocalAction.HackTemporarily will not complete properly @@ -138,7 +129,7 @@ object GenericHackables { zone.LocalEvents ! LocalServiceMessage( zoneId, LocalAction - .HackTemporarily(pguid, zone, target, unk, target.HackEffectDuration(user.avatar.hackingSkillLevel())) + .HackTemporarily(pguid, zone, target, hackValue, hackClearValue, target.HackEffectDuration(user.avatar.hackingSkillLevel())) ) case Failure(_) => log.warn(s"Hack message failed on target: ${target.Definition.Name}@${target.GUID.guid}") diff --git a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLockControl.scala b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLockControl.scala index 026f3f1f1..e9249e104 100644 --- a/src/main/scala/net/psforever/objects/serverobject/locks/IFFLockControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/locks/IFFLockControl.scala @@ -4,9 +4,10 @@ package net.psforever.objects.serverobject.locks import akka.actor.Actor import net.psforever.objects.{GlobalDefinitions, SimpleItem} import net.psforever.objects.serverobject.CommonMessages -import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} +import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBehavior} import net.psforever.objects.serverobject.structures.Building +import net.psforever.packet.game.HackState1 import net.psforever.types.{PlanetSideEmpire, Vector3} /** @@ -18,8 +19,8 @@ class IFFLockControl(lock: IFFLock) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable { - def FactionObject: FactionAffinity = lock - def HackableObject = lock + def FactionObject: IFFLock = lock + def HackableObject: IFFLock = lock def receive: Receive = checkBehavior @@ -28,16 +29,17 @@ class IFFLockControl(lock: IFFLock) case CommonMessages.Use(player, Some(item: SimpleItem)) if item.Definition == GlobalDefinitions.remote_electronics_kit => if (lock.Faction != player.Faction) { + // 300 / 1 sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, lock), - GenericHackables.FinishHacking(lock, player, 1114636288L), - GenericHackables.HackingTickAction(progressType = 1, player, lock, item.GUID) + GenericHackables.FinishHacking(lock, player, hackValue = 60, hackClearValue = 60), + GenericHackables.HackingTickAction(HackState1.Unk1, player, lock, item.GUID) ) } else if (lock.Faction == player.Faction && lock.HackedBy.nonEmpty) { sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, lock), IFFLocks.FinishResecuringIFFLock(lock), - GenericHackables.HackingTickAction(progressType = 1, player, lock, item.GUID) + GenericHackables.HackingTickAction(HackState1.Unk1, player, lock, item.GUID) ) } else { val log = org.log4s.getLogger diff --git a/src/main/scala/net/psforever/objects/serverobject/mblocker/LockerControl.scala b/src/main/scala/net/psforever/objects/serverobject/mblocker/LockerControl.scala index 1ba6ffd20..6d1305d43 100644 --- a/src/main/scala/net/psforever/objects/serverobject/mblocker/LockerControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/mblocker/LockerControl.scala @@ -4,8 +4,9 @@ package net.psforever.objects.serverobject.mblocker import akka.actor.Actor import net.psforever.objects.{GlobalDefinitions, SimpleItem} import net.psforever.objects.serverobject.CommonMessages -import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} +import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBehavior} +import net.psforever.packet.game.HackState1 /** * An `Actor` that handles messages being dispatched to a specific `Locker`. @@ -15,8 +16,8 @@ class LockerControl(locker: Locker) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable { - def FactionObject: FactionAffinity = locker - def HackableObject = locker + def FactionObject: Locker = locker + def HackableObject: Locker = locker def receive: Receive = checkBehavior @@ -28,8 +29,8 @@ class LockerControl(locker: Locker) if (locker.Faction != player.Faction && locker.HackedBy.isEmpty) { sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, locker), - GenericHackables.FinishHacking(locker, player, 3212836864L), - GenericHackables.HackingTickAction(progressType = 1, player, locker, item.GUID) + GenericHackables.FinishHacking(locker, player, hackValue = -1, hackClearValue = -1), + GenericHackables.HackingTickAction(HackState1.Unk1, player, locker, item.GUID) ) } case _ => ; diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala index adea8ef27..9e5e1b34a 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/ProximityTerminalControl.scala @@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.terminals import akka.actor.{ActorRef, Cancellable} import net.psforever.objects.sourcing.AmenitySource +import net.psforever.packet.game.HackState1 import org.log4s.Logger import scala.annotation.unused @@ -73,8 +74,8 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit) case b: Building if (b.Faction != player.Faction || b.CaptureTerminalIsHacked) && term.HackedBy.isEmpty => sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, term), - GenericHackables.FinishHacking(term, player, 3212836864L), - GenericHackables.HackingTickAction(progressType = 1, player, term, item.GUID) + GenericHackables.FinishHacking(term, player, hackValue = -1, hackClearValue = -1), + GenericHackables.HackingTickAction(HackState1.Unk1, player, term, item.GUID) ) case _ => ; } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala index 46f596aa8..94c340fde 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalControl.scala @@ -11,6 +11,7 @@ import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBe import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableAmenity} import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl} import net.psforever.objects.vital.interaction.DamageResult +import net.psforever.packet.game.HackState1 import net.psforever.services.Service import net.psforever.services.local.{LocalAction, LocalServiceMessage} @@ -48,10 +49,11 @@ class TerminalControl(term: Terminal) //TODO setup certifications check term.Owner match { case b: Building if (b.Faction != player.Faction || b.CaptureTerminalIsHacked) && term.HackedBy.isEmpty => + //order terminals are 90 / 1, or 60 / ? sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, term), - GenericHackables.FinishHacking(term, player, 3212836864L), - GenericHackables.HackingTickAction(progressType = 1, player, term, item.GUID) + GenericHackables.FinishHacking(term, player, hackValue = -1, hackClearValue = -1), + GenericHackables.HackingTickAction(HackState1.Unk1, player, term, item.GUID) ) case _ => () } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminalControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminalControl.scala index 973f2d748..f5dc91a72 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminalControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminalControl.scala @@ -3,16 +3,17 @@ package net.psforever.objects.serverobject.terminals.capture import akka.actor.Actor import net.psforever.objects.serverobject.CommonMessages -import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} +import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBehavior} import net.psforever.objects.{GlobalDefinitions, SimpleItem} +import net.psforever.packet.game.HackState1 class CaptureTerminalControl(terminal: CaptureTerminal) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable { - def FactionObject: FactionAffinity = terminal - def HackableObject = terminal + def FactionObject: CaptureTerminal = terminal + def HackableObject: CaptureTerminal = terminal def receive: Receive = checkBehavior @@ -27,11 +28,11 @@ class CaptureTerminalControl(terminal: CaptureTerminal) if (canHack) { sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, terminal), - CaptureTerminals.FinishHackingCaptureConsole(terminal, player, 3212836864L), - GenericHackables.HackingTickAction(progressType = 1, player, terminal, item.GUID) + CaptureTerminals.FinishHackingCaptureConsole(terminal, player, unk = -1), + GenericHackables.HackingTickAction(HackState1.Unk1, player, terminal, item.GUID) ) } - case _ => ; //no default message + case _ => () //no default message } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala index ab06e4981..399d45d84 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/capture/CaptureTerminals.scala @@ -20,7 +20,7 @@ object CaptureTerminals {import scala.concurrent.duration._ * @see `HackMessage` */ //TODO add params here depending on which params in HackMessage are important - def FinishHackingCaptureConsole(target: CaptureTerminal, hackingPlayer: Player, unk: Long)(): Unit = { + def FinishHackingCaptureConsole(target: CaptureTerminal, hackingPlayer: Player, unk: Int)(): Unit = { import akka.pattern.ask // Wait for the target actor to set the HackedBy property diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantInterfaceControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantInterfaceControl.scala index 576b50a03..e6dea2add 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantInterfaceControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantInterfaceControl.scala @@ -32,7 +32,7 @@ class ImplantInterfaceControl(private val terminal: Terminal) super.performHack(player, data, replyTo) ImplantInterfaceControl .FindPairedTerminalMech(terminal.Zone, terminal.GUID) - .foreach(GenericHackables.FinishHacking(_, player, unk = 3212836864L)()) + .foreach(GenericHackables.FinishHacking(_, player, hackValue = -1, hackClearValue = -1)()) None } } diff --git a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala index f2762ef6c..c03709e69 100644 --- a/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/terminals/implant/ImplantTerminalMechControl.scala @@ -15,6 +15,7 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.zones.Zone import net.psforever.objects.{GlobalDefinitions, Player, SimpleItem} +import net.psforever.packet.game.HackState1 import net.psforever.services.local.{LocalAction, LocalServiceMessage} import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} @@ -76,8 +77,8 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) case b: Building if (b.Faction != player.Faction || b.CaptureTerminalIsHacked) && mech.HackedBy.isEmpty => sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, mech), - GenericHackables.FinishHacking(mech, player, 3212836864L), - GenericHackables.HackingTickAction(progressType = 1, player, mech, item.GUID) + GenericHackables.FinishHacking(mech, player, hackValue = -1, hackClearValue = -1), + GenericHackables.HackingTickAction(HackState1.Unk1, player, mech, item.GUID) ) case _ => () } @@ -181,7 +182,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) } ImplantTerminalMechControl .FindPairedTerminalInterface(zone, guid) - .foreach(GenericHackables.FinishHacking(_, player, unk = 3212836864L)()) + .foreach(GenericHackables.FinishHacking(_, player, hackValue = -1, hackClearValue = -1)()) } override def performClearHack(data: Option[Any], replyTo: ActorRef): Unit = { @@ -201,7 +202,7 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech) super.captureTerminalIsHacked(terminal) val zone = HackableObject.Zone val guid = HackableObject.GUID - kickAllOccupantsNotOfFactionWithTest(zone, guid, mech, (a: PlanetSideEmpire.Value) => { true }) + kickAllOccupantsNotOfFactionWithTest(zone, guid, mech, (_: PlanetSideEmpire.Value) => { true }) } override protected def captureTerminalIsResecured(terminal: CaptureTerminal): Unit = { diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index 6ecddd0e8..12be65269 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -13,7 +13,7 @@ import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, Ca import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.packet.game.ChangeFireModeMessage +import net.psforever.packet.game.{ChangeFireModeMessage, HackState1} import net.psforever.services.Service import net.psforever.services.vehicle.support.TurretUpgrader import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} @@ -67,7 +67,7 @@ class FacilityTurretControl(turret: FacilityTurret) sender() ! CommonMessages.Progress( 1.25f, WeaponTurrets.FinishUpgradingMannedTurret(TurretObject, player, item, upgrade), - WeaponTurrets.TurretUpgradingTickAction(progressType = 2, player, TurretObject, item.GUID) + WeaponTurrets.TurretUpgradingTickAction(HackState1.Unk2, player, TurretObject, item.GUID) ) } case TurretUpgrader.UpgradeCompleted(_) => diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index ae839f0e3..9dd64c311 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -5,7 +5,7 @@ import net.psforever.objects.avatar.Certification import net.psforever.objects.ce.Deployable import net.psforever.objects.serverobject.hackable.GenericHackables.updateTurretUpgradeTime import net.psforever.objects.{Player, Tool, TurretDeployable} -import net.psforever.packet.game.{HackMessage, HackState, InventoryStateMessage} +import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.local.{LocalAction, LocalServiceMessage} @@ -73,26 +73,27 @@ object WeaponTurrets { * @return `true`, if the next cycle of progress should occur; * `false`, otherwise */ - def TurretUpgradingTickAction(progressType: Int, tplayer: Player, turret: FacilityTurret, tool_guid: PlanetSideGUID)( + def TurretUpgradingTickAction(progressType: HackState1, tplayer: Player, turret: FacilityTurret, tool_guid: PlanetSideGUID)( progress: Float ): Boolean = { - //hack state for progress bar visibility - val vis = if (progress <= 0L) { - HackState.Start + val (progressState, progressGrade) = if (progress <= 0L) { + (HackState.Start, 0) } else if (progress >= 100L) { - HackState.Finished + (HackState.Finished, 100) + } else if (turret.Destroyed) { + (HackState.Cancelled, 0) } else { updateTurretUpgradeTime() - HackState.Ongoing + (HackState.Ongoing, progress.toInt) } turret.Zone.AvatarEvents ! AvatarServiceMessage( tplayer.Name, AvatarAction.SendResponse( Service.defaultPlayerGUID, - HackMessage(progressType, turret.GUID, tplayer.GUID, progress.toInt, 0L, vis, 8L) + HackMessage(progressType, turret.GUID, tplayer.GUID, progressGrade, -1f, progressState, HackState7.Unk8) ) ) - vis != HackState.Cancelled + progressState != HackState.Cancelled } def FinishHackingTurretDeployable(target: TurretDeployable, hacker: Player)(): Unit = { diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index 0f9687bc6..8a5d48a2e 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -179,8 +179,8 @@ class VehicleControl(vehicle: Vehicle) if (vehicle.Faction != player.Faction) { sender() ! CommonMessages.Progress( GenericHackables.GetHackSpeed(player, vehicle), - Vehicles.FinishHackingVehicle(vehicle, player, 3212836864L), - GenericHackables.HackingTickAction(progressType = 1, player, vehicle, item.GUID) + Vehicles.FinishHackingVehicle(vehicle, player), + GenericHackables.HackingTickAction(HackState1.Unk1, player, vehicle, item.GUID) ) } diff --git a/src/main/scala/net/psforever/packet/game/HackMessage.scala b/src/main/scala/net/psforever/packet/game/HackMessage.scala index 77df26d8b..1df1afb5d 100644 --- a/src/main/scala/net/psforever/packet/game/HackMessage.scala +++ b/src/main/scala/net/psforever/packet/game/HackMessage.scala @@ -1,10 +1,52 @@ // Copyright (c) 2017 PSForever package net.psforever.packet.game +import enumeratum.values.{IntEnum, IntEnumEntry} +import net.psforever.packet.GamePacketOpcode.Type import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} import net.psforever.types.PlanetSideGUID -import scodec.Codec +import scodec.bits.BitVector +import scodec.{Attempt, Codec} import scodec.codecs._ +import shapeless.{::, HNil} + +sealed abstract class HackState1(val value: Int) extends IntEnumEntry + +object HackState1 extends IntEnum[HackState1] { + val values: IndexedSeq[HackState1] = findValues + + case object Unk0 extends HackState1(value = 0) + case object Unk1 extends HackState1(value = 1) + case object Unk2 extends HackState1(value = 2) + case object Unk3 extends HackState1(value = 3) + + implicit val codec: Codec[HackState1] = PacketHelpers.createIntEnumCodec(this, uint2) +} + +sealed abstract class HackState7(val value: Int) extends IntEnumEntry + +object HackState7 extends IntEnum[HackState7] { + val values: IndexedSeq[HackState7] = findValues + + case object Unk0 extends HackState7(value = 0) + case object Unk1 extends HackState7(value = 1) + case object Unk2 extends HackState7(value = 2) + case object Unk3 extends HackState7(value = 3) + case object Unk4 extends HackState7(value = 4) + case object Unk5 extends HackState7(value = 5) + case object Unk6 extends HackState7(value = 6) + case object Unk7 extends HackState7(value = 7) + case object Unk8 extends HackState7(value = 8) + + implicit val codec: Codec[HackState7] = (PacketHelpers.createIntEnumCodec(this, uint8) :: ignore(size = 24)).xmap[HackState7]( + { + case a :: _ :: HNil => a + }, + { + a => a :: () :: HNil + } + ) +} /** * An `Enumeration` of the various states and activities of the hacking process. @@ -16,12 +58,21 @@ import scodec.codecs._ * `Hacked` modifies the target of the hack.
* `HackCleared` modifies the target of the hack, opposite of `Hacked`. */ -object HackState extends Enumeration { - type Type = Value +sealed abstract class HackState(val value: Int) extends IntEnumEntry + +object HackState extends IntEnum[HackState] { + val values: IndexedSeq[HackState] = findValues - val Unknown0, Start, Cancelled, Ongoing, Finished, Unknown5, Hacked, HackCleared = Value + case object Unknown0 extends HackState(value = 0) + case object Start extends HackState(value = 1) + case object Cancelled extends HackState(value = 2) + case object Ongoing extends HackState(value = 3) + case object Finished extends HackState(value = 4) + case object Unknown5 extends HackState(value = 5) + case object Hacked extends HackState(value = 6) + case object HackCleared extends HackState(value = 7) - implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L) + implicit val codec: Codec[HackState] = PacketHelpers.createIntEnumCodec(this, uint8L) } /** @@ -44,11 +95,12 @@ object HackState extends Enumeration { * As mentioned, one of the unexpected uses of this message * will assist the conversion of allied facility turreted weapons to their upgraded armaments. * @param unk1 na; - * 0 commonly; - * 2 when performing (phalanx) upgrades; - * 3 for building objects during login phase; - * hack type? - * possibly player hacking level 0-3? + * 0 commonly; + * 1 unknown; + * 2 when performing (phalanx) upgrades; + * 3 for building objects during login phase; + * hack type? + * possibly player hacking level 0-3? * @param target_guid the target of the hack * @param player_guid the player * @param progress the amount of progress visible; @@ -58,31 +110,44 @@ object HackState extends Enumeration { * doesn't seem to be `char_id`? * @param hack_state hack state * @param unk7 na; + * usually 8; + * values 3-7 noted for the Hacked state; * 5 - boost pain field at matrixing terminal? - * usually, 8? */ final case class HackMessage( - unk1: Int, - target_guid: PlanetSideGUID, - player_guid: PlanetSideGUID, - progress: Int, - unk5: Long, - hack_state: HackState.Value, - unk7: Long -) extends PlanetSideGamePacket { + unk1: HackState1, + target_guid: PlanetSideGUID, + player_guid: PlanetSideGUID, + progress: Int, + unk5: Float, + hack_state: HackState, + unk7: HackState7 + ) extends PlanetSideGamePacket { type Packet = HackMessage - def opcode = GamePacketOpcode.HackMessage - def encode = HackMessage.encode(this) + def opcode: Type = GamePacketOpcode.HackMessage + def encode: Attempt[BitVector] = HackMessage.encode(this) } object HackMessage extends Marshallable[HackMessage] { + def apply( + unk1: HackState1, + target_guid: PlanetSideGUID, + player_guid: PlanetSideGUID, + progress: Int, + unk5: Int, + hack_state: HackState, + unk7: HackState7 + ): HackMessage = { + new HackMessage(unk1, target_guid, player_guid, progress, unk5.toFloat, hack_state, unk7) + } + implicit val codec: Codec[HackMessage] = ( - ("unk1" | uint2L) :: + ("unk1" | HackState1.codec) :: ("object_guid" | PlanetSideGUID.codec) :: ("player_guid" | PlanetSideGUID.codec) :: ("progress" | uint8L) :: - ("unk5" | uint32L) :: + ("unk5" | floatL) :: ("hack_state" | HackState.codec) :: - ("unk7" | uint32L) + ("unk7" | HackState7.codec) ).as[HackMessage] } diff --git a/src/main/scala/net/psforever/services/local/LocalService.scala b/src/main/scala/net/psforever/services/local/LocalService.scala index e1e18d511..c8cbea046 100644 --- a/src/main/scala/net/psforever/services/local/LocalService.scala +++ b/src/main/scala/net/psforever/services/local/LocalService.scala @@ -96,10 +96,10 @@ class LocalService(zone: Zone) extends Actor { LocalResponse.SendHackMessageHackCleared(target.GUID, unk1, unk2) ) ) - case LocalAction.HackTemporarily(player_guid, _, target, unk1, duration, unk2) => - hackClearer ! HackClearActor.ObjectIsHacked(target, zone, unk1, unk2, duration) + case LocalAction.HackTemporarily(player_guid, _, target, hackValue, hackClear, duration, unk2) => + hackClearer ! HackClearActor.ObjectIsHacked(target, zone, hackClear, unk2, duration) LocalEvents.publish( - LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackObject(target.GUID, unk1, unk2)) + LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackObject(target.GUID, hackValue, unk2)) ) case LocalAction.ClearTemporaryHack(_, target) => hackClearer ! HackClearActor.ObjectIsResecured(target) diff --git a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala index 6a162058d..df0fdb5af 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceMessage.scala @@ -14,7 +14,7 @@ import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle} import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum -import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, TriggeredSound} +import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, TriggeredSound} import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -43,15 +43,16 @@ object LocalAction { pos: Vector3, deletionEffect: Int ) extends Action - final case class HackClear(player_guid: PlanetSideGUID, target: PlanetSideServerObject, unk1: Long, unk2: Long = 8L) + final case class HackClear(player_guid: PlanetSideGUID, target: PlanetSideServerObject, unk1: Long, unk2: HackState7 = HackState7.Unk8) extends Action final case class HackTemporarily( player_guid: PlanetSideGUID, continent: Zone, target: PlanetSideServerObject, - unk1: Long, + hackValue: Long, + hackClearValue: Long, duration: Int, - unk2: Long = 8L + unk2: HackState7 = HackState7.Unk8 ) extends Action final case class ClearTemporaryHack(player_guid: PlanetSideGUID, target: PlanetSideServerObject with Hackable) extends Action diff --git a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala index 277dddccd..ffb1bb3ff 100644 --- a/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala +++ b/src/main/scala/net/psforever/services/local/LocalServiceResponse.scala @@ -34,8 +34,8 @@ object LocalResponse { pos: Vector3, deletionEffect: Int ) extends Response - final case class SendHackMessageHackCleared(target_guid: PlanetSideGUID, unk1: Long, unk2: Long) extends Response - final case class HackObject(target_guid: PlanetSideGUID, unk1: Long, unk2: Long) extends Response + final case class SendHackMessageHackCleared(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends Response + final case class HackObject(target_guid: PlanetSideGUID, unk1: Long, unk2: HackState7) extends Response final case class SendPacket(packet: PlanetSideGamePacket) extends Response final case class PlanetsideAttribute(target_guid: PlanetSideGUID, attribute_number: PlanetsideAttributeEnum, attribute_value: Long) 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 689d5e231..b9a4f4700 100644 --- a/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackCaptureActor.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal import net.psforever.objects.zones.Zone import net.psforever.objects.Default -import net.psforever.packet.game.{GenericAction, PlanetsideAttributeEnum} +import net.psforever.packet.game.{GenericAction, HackState7, PlanetsideAttributeEnum} import net.psforever.objects.sourcing.PlayerSource import net.psforever.services.Service import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction @@ -231,7 +231,7 @@ class HackCaptureActor extends Actor { } NotifyHackStateChange(terminal, isResecured = true) // todo: this appears to be the way to reset the base warning lights after the hack finishes but it doesn't seem to work. - context.parent ! HackClearActor.SendHackMessageHackCleared(building.GUID, terminal.Zone.id, 3212836864L, 8L) //call up + context.parent ! HackClearActor.SendHackMessageHackCleared(building.GUID, terminal.Zone.id, 3212836864L, HackState7.Unk8) //call up } private def RestartTimer(): Unit = { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index c6f8e8bb4..6cb3e5bc6 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -2,12 +2,12 @@ package net.psforever.services.local.support import java.util.concurrent.TimeUnit - import akka.actor.{Actor, Cancellable} import net.psforever.objects.Default import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone +import net.psforever.packet.game.HackState7 import net.psforever.types.PlanetSideGUID import scala.annotation.tailrec @@ -156,7 +156,7 @@ object HackClearActor { target: PlanetSideServerObject, zone: Zone, unk1: Long, - unk2: Long, + unk2: HackState7, duration: Int, time: Long = System.currentTimeMillis() ) @@ -172,7 +172,7 @@ object HackClearActor { * @param obj the server object * @param zone_id the zone in which the object resides */ - final case class SendHackMessageHackCleared(obj: PlanetSideGUID, zone_id: String, unk1: Long, unk2: Long) + final case class SendHackMessageHackCleared(obj: PlanetSideGUID, zone_id: String, unk1: Long, unk2: HackState7) /** * Internal message used to signal a test of the queued door information. @@ -192,7 +192,7 @@ object HackClearActor { target: PlanetSideServerObject, zone: Zone, unk1: Long, - unk2: Long, + unk2: HackState7, time: Long, duration: Long ) diff --git a/src/test/scala/game/HackMessageTest.scala b/src/test/scala/game/HackMessageTest.scala index bd6bc9433..dd6c77a9d 100644 --- a/src/test/scala/game/HackMessageTest.scala +++ b/src/test/scala/game/HackMessageTest.scala @@ -14,20 +14,20 @@ class HackMessageTest extends Specification { "decode" in { PacketCoding.decodePacket(string).require match { case HackMessage(unk1, target_guid, player_guid, progress, unk5, hack_state, unk7) => - unk1 mustEqual 0 + unk1 mustEqual HackState1.Unk0 target_guid mustEqual PlanetSideGUID(1024) player_guid mustEqual PlanetSideGUID(3607) progress mustEqual 0 - unk5 mustEqual 3212836864L + unk5 mustEqual -1.0f hack_state mustEqual HackState.Start - unk7 mustEqual 8L + unk7 mustEqual HackState7.Unk8 case _ => ko } } "encode" in { - val msg = HackMessage(0, PlanetSideGUID(1024), PlanetSideGUID(3607), 0, 3212836864L, HackState.Start, 8L) + val msg = HackMessage(HackState1.Unk0, PlanetSideGUID(1024), PlanetSideGUID(3607), 0, -1.0f, HackState.Start, HackState7.Unk8) val pkt = PacketCoding.encodePacket(msg).require.toByteVector pkt mustEqual string } diff --git a/src/test/scala/service/LocalServiceTest.scala b/src/test/scala/service/LocalServiceTest.scala index 7c96d6ed1..05b8fe7b0 100644 --- a/src/test/scala/service/LocalServiceTest.scala +++ b/src/test/scala/service/LocalServiceTest.scala @@ -136,9 +136,9 @@ class HackClearTest extends ActorTest { "pass HackClear" in { val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") service ! Service.Join("test") - service ! LocalServiceMessage("test", LocalAction.HackClear(PlanetSideGUID(10), obj, 0L, 1000L)) + service ! LocalServiceMessage("test", LocalAction.HackClear(PlanetSideGUID(10), obj, 0L, HackState7.Unk8)) expectMsg( - LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.SendHackMessageHackCleared(PlanetSideGUID(40), 0L, 1000L)) + LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.SendHackMessageHackCleared(PlanetSideGUID(40), 0L, HackState7.Unk8)) ) } }