Skip to content

Commit

Permalink
HackMessage now uses custom fields and a float value rather than inte…
Browse files Browse the repository at this point in the history
…gers (2, 32, 32); separate hack state and hack clear states; everything changes
  • Loading branch information
Fate-JH committed Aug 2, 2024
1 parent e0439a7 commit 27567a9
Show file tree
Hide file tree
Showing 28 changed files with 250 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
}
})
}

/**
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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) =>
Expand Down
61 changes: 39 additions & 22 deletions src/main/scala/net/psforever/objects/Vehicles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -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()
Expand All @@ -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
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -68,56 +68,47 @@ 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
}

/**
* The process of hacking an object is completed.
* 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
Expand All @@ -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}")
Expand Down
Loading

0 comments on commit 27567a9

Please sign in to comment.