mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Implant Terminal Hack (#1221)
* preliminary functional implant hacking; am going to explore better hacking policies * HackMessage now uses custom fields and a float value rather than integers (2, 32, 32); separate hack state and hack clear states; everything changes
This commit is contained in:
parent
8afe7fa248
commit
02f95a293e
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 _ => ()
|
||||
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))
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ object GlobalDefinitionsMiscellaneous {
|
|||
cert_terminal.Geometry = GeometryForm.representByCylinder(radius = 0.66405f, height = 1.09374f)
|
||||
|
||||
implant_terminal_mech.Name = "implant_terminal_mech"
|
||||
implant_terminal_mech.MaxHealth = 1500 //TODO 1000; right now, 1000 (mech) + 500 (interface)
|
||||
implant_terminal_mech.MaxHealth = 1000
|
||||
implant_terminal_mech.Damageable = true
|
||||
implant_terminal_mech.Repairable = true
|
||||
implant_terminal_mech.autoRepair = AutoRepairStats(1.6f, 5000, 2400, 0.05f)
|
||||
|
|
@ -176,7 +176,7 @@ object GlobalDefinitionsMiscellaneous {
|
|||
implant_terminal_interface.Name = "implant_terminal_interface"
|
||||
implant_terminal_interface.Tab += 0 -> ImplantPage(ImplantTerminalDefinition.implants)
|
||||
implant_terminal_interface.MaxHealth = 500
|
||||
implant_terminal_interface.Damageable = false //TODO true
|
||||
implant_terminal_interface.Damageable = false //true
|
||||
implant_terminal_interface.Repairable = true
|
||||
implant_terminal_interface.autoRepair = AutoRepairStats(1, 5000, 200, 1)
|
||||
implant_terminal_interface.RepairIfDestroyed = true
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 _ => ;
|
||||
|
|
|
|||
|
|
@ -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 _ => ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 _ => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
package net.psforever.objects.serverobject.terminals.capture
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.annotation.unused
|
||||
|
||||
|
|
@ -24,28 +22,7 @@ trait CaptureTerminalAwareBehavior {
|
|||
|
||||
protected def captureTerminalIsResecured(@unused terminal: CaptureTerminal): Unit = { /* intentionally blank */ }
|
||||
|
||||
protected def captureTerminalIsHacked(@unused terminal: CaptureTerminal): Unit = {
|
||||
// Remove seated occupants for mountables
|
||||
CaptureTerminalAwareObject match {
|
||||
case mountable: Mountable =>
|
||||
val guid = mountable.GUID
|
||||
val zone = mountable.Zone
|
||||
val zoneId = zone.id
|
||||
val events = zone.VehicleEvents
|
||||
mountable.Seats.values.zipWithIndex.foreach {
|
||||
case (seat, seat_num) =>
|
||||
seat.occupant.collect {
|
||||
case player =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
if (player.HasGUID) {
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, seat_num, unk2=true, guid))
|
||||
}
|
||||
}
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
protected def captureTerminalIsHacked(@unused terminal: CaptureTerminal): Unit = { /* intentionally blank */ }
|
||||
}
|
||||
|
||||
object CaptureTerminalAwareBehavior {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,16 +20,16 @@ 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
|
||||
|
||||
log.info(s"${hackingPlayer.toString} hacked a ${target.Definition.Name}")
|
||||
// Wait for the target actor to set the HackedBy property
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
ask(target.Actor, CommonMessages.Hack(hackingPlayer, target))(timeout = 2 second)
|
||||
.mapTo[CommonMessages.EntityHackState]
|
||||
.onComplete {
|
||||
case Success(_) =>
|
||||
log.info(s"${hackingPlayer.toString} hacked a ${target.Definition.Name}")
|
||||
val zone = target.Zone
|
||||
val zoneid = zone.id
|
||||
val events = zone.LocalEvents
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.objects.serverobject.terminals.implant
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.hackable.{GenericHackables, Hackable}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.serverobject.terminals.{Terminal, TerminalControl}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
object ImplantInterfaceControl {
|
||||
private def FindPairedTerminalMech(
|
||||
zone: Zone,
|
||||
interfaceGuid: PlanetSideGUID
|
||||
): Option[Amenity with Hackable] = {
|
||||
zone
|
||||
.map
|
||||
.terminalToInterface
|
||||
.find { case (_, guid) => guid == interfaceGuid.guid }
|
||||
.flatMap { case (mechGuid, _) => zone.GUID(mechGuid) }
|
||||
.collect { case mech: ImplantTerminalMech if !mech.Destroyed && mech.HackedBy.isEmpty => mech }
|
||||
}
|
||||
}
|
||||
|
||||
class ImplantInterfaceControl(private val terminal: Terminal)
|
||||
extends TerminalControl(terminal) {
|
||||
|
||||
override def performHack(player: Player, data: Option[Any], replyTo: ActorRef): Unit = {
|
||||
HackableObject.HackedBy
|
||||
.orElse {
|
||||
super.performHack(player, data, replyTo)
|
||||
ImplantInterfaceControl
|
||||
.FindPairedTerminalMech(terminal.Zone, terminal.GUID)
|
||||
.foreach(GenericHackables.FinishHacking(_, player, hackValue = -1, hackClearValue = -1)())
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.objects.serverobject.terminals.implant
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.serverobject.terminals.{Terminal, TerminalDefinition}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
object ImplantTerminalInterface {
|
||||
/**
|
||||
* Instantiate and configure a `Terminal` object
|
||||
* @param pdef `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
* @param pos position
|
||||
* @param id the unique id that will be assigned to this entity
|
||||
* @param context a context to allow the object to properly set up `ActorSystem` functionality
|
||||
* @return the `Terminal` object
|
||||
*/
|
||||
def Constructor(pos: Vector3, pdef: TerminalDefinition)(id: Int, context: ActorContext): Terminal = {
|
||||
import akka.actor.Props
|
||||
|
||||
val obj = Terminal(pdef)
|
||||
obj.Position = pos
|
||||
obj.Actor = context.actorOf(Props(classOf[ImplantInterfaceControl], obj), s"${obj.Definition.Name}_$id")
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,47 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.terminals.implant
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior
|
||||
import net.psforever.objects.serverobject.damage.Damageable.Target
|
||||
import net.psforever.objects.serverobject.damage.{Damageable, DamageableEntity, DamageableMountable}
|
||||
import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBehavior}
|
||||
import net.psforever.objects.serverobject.hackable.{GenericHackables, Hackable, HackableBehavior}
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableAmenity, RepairableEntity}
|
||||
import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl}
|
||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalAwareBehavior
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, PoweredAmenityControl}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAwareBehavior}
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
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}
|
||||
|
||||
import scala.annotation.unused
|
||||
|
||||
object ImplantTerminalMechControl {
|
||||
private def FindPairedTerminalInterface(
|
||||
zone: Zone,
|
||||
mechGuid: PlanetSideGUID
|
||||
): Option[Amenity with Hackable] = {
|
||||
zone
|
||||
.map
|
||||
.terminalToInterface
|
||||
.find { case (guid, _) => guid == mechGuid.guid }
|
||||
.flatMap { case (_, interfaceGuid) => zone.GUID(interfaceGuid) }
|
||||
.collect { case terminal: Terminal if !terminal.Destroyed && terminal.HackedBy.isEmpty => terminal }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `ImplantTerminalMech`.
|
||||
* @param mech the "mech" object being governed
|
||||
*/
|
||||
* An `Actor` that handles messages being dispatched to a specific `ImplantTerminalMech`.
|
||||
* @param mech the "mech" object being governed
|
||||
*/
|
||||
class ImplantTerminalMechControl(mech: ImplantTerminalMech)
|
||||
extends PoweredAmenityControl
|
||||
extends PoweredAmenityControl
|
||||
with FactionAffinityBehavior.Check
|
||||
with MountableBehavior
|
||||
with HackableBehavior.GenericHackable
|
||||
|
|
@ -41,9 +63,11 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech)
|
|||
.orElse(takesDamage)
|
||||
.orElse(canBeRepairedByNanoDispenser)
|
||||
.orElse(autoRepairBehavior)
|
||||
.orElse(captureTerminalAwareBehaviour)
|
||||
|
||||
def poweredStateLogic : Receive =
|
||||
commonBehavior
|
||||
.orElse(hackableBehavior)
|
||||
.orElse(mountBehavior)
|
||||
.orElse {
|
||||
case CommonMessages.Use(player, Some(item: SimpleItem))
|
||||
|
|
@ -53,18 +77,19 @@ 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 _ => ;
|
||||
case _ => ()
|
||||
}
|
||||
case _ => ;
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
def unpoweredStateLogic: Receive =
|
||||
commonBehavior
|
||||
.orElse(hackableBehavior)
|
||||
.orElse {
|
||||
case _ => ;
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
override protected def mountTest(
|
||||
|
|
@ -120,14 +145,11 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech)
|
|||
val zoneId = zone.id
|
||||
val events = zone.VehicleEvents
|
||||
mech.Seats.values.foreach(seat =>
|
||||
seat.occupant match {
|
||||
case Some(player) =>
|
||||
seat.occupant.collect {
|
||||
case player =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
if (player.HasGUID) {
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, guid))
|
||||
}
|
||||
case None => ;
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2=false, guid))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -140,4 +162,123 @@ class ImplantTerminalMechControl(mech: ImplantTerminalMech)
|
|||
super.Restoration(obj)
|
||||
RepairableAmenity.RestorationOfHistory(obj)
|
||||
}
|
||||
|
||||
override def performHack(player: Player, data: Option[Any], replyTo: ActorRef): Unit = {
|
||||
//todo don't now how to properly hack this amenity
|
||||
super.performHack(player, data, replyTo)
|
||||
val zone = HackableObject.Zone
|
||||
val guid = HackableObject.GUID
|
||||
val localFaction = mech.Faction
|
||||
val events = zone.LocalEvents
|
||||
if (player.Faction == localFaction) {
|
||||
if (mech.Owner.asInstanceOf[Building].CaptureTerminalIsHacked) {
|
||||
//this is actually futile, as a hacked base does not grant access to the terminal
|
||||
events ! LocalServiceMessage(localFaction.toString, LocalAction.SetEmpire(guid, localFaction))
|
||||
}
|
||||
kickAllOccupantsNotOfFaction(zone, guid, mech, localFaction)
|
||||
} else {
|
||||
opposingFactionsMayAccess(zone, guid, localFaction)
|
||||
kickAllOccupantsOfFaction(zone, guid, mech, localFaction)
|
||||
}
|
||||
ImplantTerminalMechControl
|
||||
.FindPairedTerminalInterface(zone, guid)
|
||||
.foreach(GenericHackables.FinishHacking(_, player, hackValue = -1, hackClearValue = -1)())
|
||||
}
|
||||
|
||||
override def performClearHack(data: Option[Any], replyTo: ActorRef): Unit = {
|
||||
//todo don't now how to properly unhack this amenity
|
||||
HackableObject.HackedBy.collect { _ =>
|
||||
super.performClearHack(data, replyTo)
|
||||
val toFaction = HackableObject.Faction
|
||||
val zone = HackableObject.Zone
|
||||
val guid = HackableObject.GUID
|
||||
noAccessByOpposingFactions(zone, guid, toFaction)
|
||||
kickAllOccupantsNotOfFaction(zone, guid, mech, toFaction)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def captureTerminalIsHacked(@unused terminal: CaptureTerminal): Unit = {
|
||||
//todo don't now how to properly handle a hacked mech
|
||||
super.captureTerminalIsHacked(terminal)
|
||||
val zone = HackableObject.Zone
|
||||
val guid = HackableObject.GUID
|
||||
kickAllOccupantsNotOfFactionWithTest(zone, guid, mech, (_: PlanetSideEmpire.Value) => { true })
|
||||
}
|
||||
|
||||
override protected def captureTerminalIsResecured(terminal: CaptureTerminal): Unit = {
|
||||
//todo don't now how to properly handle a hacked mech
|
||||
super.captureTerminalIsResecured(terminal)
|
||||
//if hacked, correct
|
||||
val zone = HackableObject.Zone
|
||||
val guid = HackableObject.GUID
|
||||
val toFaction = HackableObject.Faction
|
||||
HackableObject.HackedBy.collect {
|
||||
case hackInfo if hackInfo.hackerFaction != toFaction =>
|
||||
opposingFactionsMayAccess(zone, guid, toFaction)
|
||||
}
|
||||
}
|
||||
|
||||
private def opposingFactionsMayAccess(
|
||||
zone: Zone,
|
||||
guid: PlanetSideGUID,
|
||||
setToFaction: PlanetSideEmpire.Value
|
||||
): Unit = {
|
||||
val events = zone.LocalEvents
|
||||
opposingFactionsAre(setToFaction).foreach { faction =>
|
||||
events ! LocalServiceMessage(faction.toString, LocalAction.SetEmpire(guid, faction))
|
||||
}
|
||||
}
|
||||
|
||||
private def noAccessByOpposingFactions(
|
||||
zone: Zone,
|
||||
guid: PlanetSideGUID,
|
||||
setToFaction: PlanetSideEmpire.Value
|
||||
): Unit = {
|
||||
val events = zone.LocalEvents
|
||||
opposingFactionsAre(setToFaction).foreach { faction =>
|
||||
events ! LocalServiceMessage(faction.toString, LocalAction.SetEmpire(guid, setToFaction))
|
||||
}
|
||||
}
|
||||
|
||||
private def opposingFactionsAre(faction: PlanetSideEmpire.Value): PlanetSideEmpire.ValueSet = {
|
||||
PlanetSideEmpire
|
||||
.values
|
||||
.filterNot { f => f == PlanetSideEmpire.NEUTRAL && f == faction }
|
||||
}
|
||||
|
||||
private def kickAllOccupantsOfFaction(
|
||||
zone: Zone,
|
||||
guid: PlanetSideGUID,
|
||||
obj: Mountable,
|
||||
isFaction: PlanetSideEmpire.Value
|
||||
): Unit = {
|
||||
kickAllOccupantsNotOfFactionWithTest(zone, guid, obj, (a: PlanetSideEmpire.Value) => { a == isFaction })
|
||||
}
|
||||
|
||||
private def kickAllOccupantsNotOfFaction(
|
||||
zone: Zone,
|
||||
guid: PlanetSideGUID,
|
||||
obj: Mountable,
|
||||
isFaction: PlanetSideEmpire.Value
|
||||
): Unit = {
|
||||
kickAllOccupantsNotOfFactionWithTest(zone, guid, obj, (a: PlanetSideEmpire.Value) => { a != isFaction })
|
||||
}
|
||||
|
||||
private def kickAllOccupantsNotOfFactionWithTest(
|
||||
zone: Zone,
|
||||
guid: PlanetSideGUID,
|
||||
obj: Mountable,
|
||||
test: PlanetSideEmpire.Value => Boolean
|
||||
): Unit = {
|
||||
val zoneId = zone.id
|
||||
val events = zone.LocalEvents
|
||||
obj.Seats.values.foreach(seat =>
|
||||
seat.occupant.collect {
|
||||
case player if test(player.Faction) =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, guid))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(_) =>
|
||||
|
|
@ -330,6 +330,21 @@ class FacilityTurretControl(turret: FacilityTurret)
|
|||
}
|
||||
|
||||
override protected def captureTerminalIsHacked(terminal: CaptureTerminal): Unit = {
|
||||
super.captureTerminalIsHacked(terminal)
|
||||
// Remove seated occupants
|
||||
val guid = turret.GUID
|
||||
val zone = turret.Zone
|
||||
val zoneId = zone.id
|
||||
val events = zone.VehicleEvents
|
||||
turret.Seats.values.zipWithIndex.foreach {
|
||||
case (seat, seat_num) =>
|
||||
seat.occupant.collect {
|
||||
case player =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, seat_num, unk2=true, guid))
|
||||
}
|
||||
}
|
||||
captureTerminalChanges(terminal, super.captureTerminalIsHacked, actionDelays = 3000L)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.<br>
|
||||
* `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
|
||||
|
||||
val Unknown0, Start, Cancelled, Ongoing, Finished, Unknown5, Hacked, HackCleared = Value
|
||||
object HackState extends IntEnum[HackState] {
|
||||
val values: IndexedSeq[HackState] = findValues
|
||||
|
||||
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L)
|
||||
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: 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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
|||
import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad
|
||||
import net.psforever.objects.serverobject.structures.{Building, BuildingDefinition, FoundationBuilder, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalDefinition}
|
||||
import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech
|
||||
import net.psforever.objects.serverobject.terminals.implant.{ImplantTerminalInterface, ImplantTerminalMech}
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.serverobject.turret.{FacilityTurret, FacilityTurretDefinition, VanuSentry}
|
||||
import net.psforever.objects.serverobject.zipline.ZipLinePath
|
||||
|
|
@ -637,7 +637,7 @@ object Zones {
|
|||
|
||||
zoneMap.addLocalObject(
|
||||
closestTerminal.guid,
|
||||
Terminal.Constructor(closestTerminal.position, GlobalDefinitions.implant_terminal_interface),
|
||||
ImplantTerminalInterface.Constructor(closestTerminal.position, GlobalDefinitions.implant_terminal_interface),
|
||||
owningBuildingGuid = ownerGuid
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue