mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-04-29 15:55:23 +00:00
Fix implant terminal hacking (#246)
* Fix hacking implant terminals * Remove duplication and apply some DRY
This commit is contained in:
parent
cd5caf58a0
commit
8313ce6491
10 changed files with 99 additions and 50 deletions
|
|
@ -0,0 +1,27 @@
|
||||||
|
package net.psforever.objects.serverobject.hackable
|
||||||
|
|
||||||
|
import akka.actor.Actor
|
||||||
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
|
|
||||||
|
object HackableBehavior {
|
||||||
|
/**
|
||||||
|
* The logic governing generic `Hackable` objects that use the `Hack` and `ClearHack` message.
|
||||||
|
* This is a mix-in trait for combining with existing Receive` logic.
|
||||||
|
* @see `Hackable`
|
||||||
|
*/
|
||||||
|
trait GenericHackable {
|
||||||
|
this : Actor =>
|
||||||
|
|
||||||
|
def HackableObject : Hackable
|
||||||
|
|
||||||
|
val hackableBehavior : Receive = {
|
||||||
|
case CommonMessages.Hack(player) =>
|
||||||
|
val obj = HackableObject
|
||||||
|
obj.HackedBy = player
|
||||||
|
sender ! true
|
||||||
|
case CommonMessages.ClearHack() =>
|
||||||
|
val obj = HackableObject
|
||||||
|
obj.HackedBy = None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,18 +3,24 @@ package net.psforever.objects.serverobject.implantmech
|
||||||
|
|
||||||
import net.psforever.objects.Player
|
import net.psforever.objects.Player
|
||||||
import net.psforever.objects.definition.ObjectDefinition
|
import net.psforever.objects.definition.ObjectDefinition
|
||||||
|
import net.psforever.objects.serverobject.hackable.Hackable
|
||||||
import net.psforever.objects.serverobject.mount.Mountable
|
import net.psforever.objects.serverobject.mount.Mountable
|
||||||
import net.psforever.objects.serverobject.structures.Amenity
|
import net.psforever.objects.serverobject.structures.Amenity
|
||||||
import net.psforever.objects.vehicles.Seat
|
import net.psforever.objects.vehicles.Seat
|
||||||
|
import net.psforever.packet.game.TriggeredSound
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A structure-owned server object that is the visible and `Mountable` component of an implant terminal.
|
* A structure-owned server object that is the visible and `Mountable` component of an implant terminal.
|
||||||
* For the most part, it merely implements the support data structures indicated by `Mountable`.
|
* For the most part, it merely implements the support data structures indicated by `Mountable`.
|
||||||
* @param idef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
* @param idef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||||
*/
|
*/
|
||||||
class ImplantTerminalMech(private val idef : ImplantTerminalMechDefinition) extends Amenity with Mountable {
|
class ImplantTerminalMech(private val idef : ImplantTerminalMechDefinition) extends Amenity with Mountable with Hackable {
|
||||||
private val seats : Map[Int, Seat] = Map( 0 -> new Seat(idef.Seats(0)) )
|
private val seats : Map[Int, Seat] = Map( 0 -> new Seat(idef.Seats(0)) )
|
||||||
|
|
||||||
|
HackSound = TriggeredSound.HackTerminal
|
||||||
|
HackEffectDuration = Array(0, 30, 60, 90)
|
||||||
|
HackDuration = Array(0, 10, 5, 3)
|
||||||
|
|
||||||
def Seats : Map[Int, Seat] = seats
|
def Seats : Map[Int, Seat] = seats
|
||||||
|
|
||||||
def Seat(seatNum : Int) : Option[Seat] = seats.get(seatNum)
|
def Seat(seatNum : Int) : Option[Seat] = seats.get(seatNum)
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,23 @@ package net.psforever.objects.serverobject.implantmech
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.serverobject.mount.MountableBehavior
|
import net.psforever.objects.serverobject.mount.MountableBehavior
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `ImplantTerminalMech`.
|
* An `Actor` that handles messages being dispatched to a specific `ImplantTerminalMech`.
|
||||||
* @param mech the "mech" object being governed
|
* @param mech the "mech" object being governed
|
||||||
*/
|
*/
|
||||||
class ImplantTerminalMechControl(mech : ImplantTerminalMech) extends Actor with FactionAffinityBehavior.Check
|
class ImplantTerminalMechControl(mech : ImplantTerminalMech) extends Actor with FactionAffinityBehavior.Check
|
||||||
with MountableBehavior.Mount with MountableBehavior.Dismount {
|
with MountableBehavior.Mount with MountableBehavior.Dismount with HackableBehavior.GenericHackable {
|
||||||
def MountableObject = mech //do not add type!
|
def MountableObject = mech //do not add type!
|
||||||
|
def HackableObject = mech
|
||||||
|
|
||||||
def FactionObject : FactionAffinity = mech
|
def FactionObject : FactionAffinity = mech
|
||||||
|
|
||||||
def receive : Receive = checkBehavior
|
def receive : Receive = checkBehavior
|
||||||
.orElse(mountBehavior)
|
.orElse(mountBehavior)
|
||||||
.orElse(dismountBehavior)
|
.orElse(dismountBehavior)
|
||||||
|
.orElse(hackableBehavior)
|
||||||
.orElse {
|
.orElse {
|
||||||
case _ => ;
|
case _ => ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,20 @@ package net.psforever.objects.serverobject.locks
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `IFFLock`.
|
* An `Actor` that handles messages being dispatched to a specific `IFFLock`.
|
||||||
* @param lock the `IFFLock` object being governed
|
* @param lock the `IFFLock` object being governed
|
||||||
* @see `CommonMessages`
|
* @see `CommonMessages`
|
||||||
*/
|
*/
|
||||||
class IFFLockControl(lock : IFFLock) extends Actor with FactionAffinityBehavior.Check {
|
class IFFLockControl(lock : IFFLock) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable {
|
||||||
def FactionObject : FactionAffinity = lock
|
def FactionObject : FactionAffinity = lock
|
||||||
|
def HackableObject = lock
|
||||||
|
|
||||||
def receive : Receive = checkBehavior.orElse {
|
def receive : Receive = checkBehavior
|
||||||
case CommonMessages.Hack(player) =>
|
.orElse(hackableBehavior)
|
||||||
lock.HackedBy = player
|
.orElse {
|
||||||
sender ! true
|
case _ => ; //no default message
|
||||||
case CommonMessages.ClearHack() =>
|
|
||||||
lock.HackedBy = None
|
|
||||||
|
|
||||||
case _ => ; //no default message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,20 @@
|
||||||
package net.psforever.objects.serverobject.mblocker
|
package net.psforever.objects.serverobject.mblocker
|
||||||
|
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `Locker`.
|
* An `Actor` that handles messages being dispatched to a specific `Locker`.
|
||||||
* @param locker the `Locker` object being governed
|
* @param locker the `Locker` object being governed
|
||||||
*/
|
*/
|
||||||
class LockerControl(locker : Locker) extends Actor with FactionAffinityBehavior.Check {
|
class LockerControl(locker : Locker) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable {
|
||||||
def FactionObject : FactionAffinity = locker
|
def FactionObject : FactionAffinity = locker
|
||||||
|
def HackableObject = locker
|
||||||
|
|
||||||
def receive : Receive = checkBehavior.orElse {
|
def receive : Receive = checkBehavior
|
||||||
case CommonMessages.Hack(player) =>
|
.orElse(hackableBehavior)
|
||||||
locker.HackedBy = player
|
.orElse {
|
||||||
sender ! true
|
case _ => ;
|
||||||
case CommonMessages.ClearHack() =>
|
|
||||||
locker.HackedBy = None
|
|
||||||
case _ => ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import akka.actor.Actor
|
||||||
import net.psforever.objects.PlanetSideGameObject
|
import net.psforever.objects.PlanetSideGameObject
|
||||||
import net.psforever.objects.entity.{Identifiable, WorldEntity}
|
import net.psforever.objects.entity.{Identifiable, WorldEntity}
|
||||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||||
|
import net.psforever.objects.serverobject.hackable.Hackable
|
||||||
import net.psforever.objects.serverobject.turret.TurretDefinition
|
import net.psforever.objects.serverobject.turret.TurretDefinition
|
||||||
import net.psforever.types.Vector3
|
import net.psforever.types.Vector3
|
||||||
|
|
||||||
|
|
@ -25,7 +26,14 @@ object MountableBehavior {
|
||||||
val obj = MountableObject
|
val obj = MountableObject
|
||||||
obj.Seat(seat_num) match {
|
obj.Seat(seat_num) match {
|
||||||
case Some(seat) =>
|
case Some(seat) =>
|
||||||
if(user.Faction == obj.Faction && (seat.Occupant = user).contains(user)) {
|
|
||||||
|
var isHacked = false
|
||||||
|
if(MountableObject.isInstanceOf[Hackable]) {
|
||||||
|
// This is a special case for implant terminals, since they're both mountable and hackable, but not jackable.
|
||||||
|
isHacked = MountableObject.asInstanceOf[Hackable].HackedBy.isDefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if((user.Faction == obj.Faction || isHacked) && (seat.Occupant = user).contains(user)) {
|
||||||
user.VehicleSeated = obj.GUID
|
user.VehicleSeated = obj.GUID
|
||||||
sender ! Mountable.MountMessages(user, Mountable.CanMount(obj, seat_num))
|
sender ! Mountable.MountMessages(user, Mountable.CanMount(obj, seat_num))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,16 @@ package net.psforever.objects.serverobject.terminals
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||||
|
|
||||||
|
|
||||||
class CaptureTerminalControl(terminal : CaptureTerminal) extends Actor with FactionAffinityBehavior.Check {
|
class CaptureTerminalControl(terminal : CaptureTerminal) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable {
|
||||||
def FactionObject : FactionAffinity = terminal
|
def FactionObject : FactionAffinity = terminal
|
||||||
|
def HackableObject = terminal
|
||||||
|
|
||||||
def receive : Receive = checkBehavior.orElse {
|
def receive : Receive = checkBehavior
|
||||||
case CommonMessages.Hack(player) =>
|
.orElse(hackableBehavior)
|
||||||
terminal.HackedBy = player
|
.orElse {
|
||||||
sender ! true
|
|
||||||
case CommonMessages.ClearHack() =>
|
|
||||||
terminal.HackedBy = None
|
|
||||||
|
|
||||||
case _ => ; //no default message
|
case _ => ; //no default message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import akka.actor.{Actor, ActorRef, Cancellable}
|
||||||
import net.psforever.objects._
|
import net.psforever.objects._
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||||
import services.{Service, ServiceManager}
|
import services.{Service, ServiceManager}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
@ -16,13 +17,14 @@ import scala.concurrent.duration._
|
||||||
* it returns the same type of messages - wrapped in a `TerminalMessage` - to the `sender`.
|
* it returns the same type of messages - wrapped in a `TerminalMessage` - to the `sender`.
|
||||||
* @param term the proximity unit (terminal)
|
* @param term the proximity unit (terminal)
|
||||||
*/
|
*/
|
||||||
class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor with FactionAffinityBehavior.Check {
|
class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable {
|
||||||
var service : ActorRef = ActorRef.noSender
|
var service : ActorRef = ActorRef.noSender
|
||||||
var terminalAction : Cancellable = DefaultCancellable.obj
|
var terminalAction : Cancellable = DefaultCancellable.obj
|
||||||
val callbacks : mutable.ListBuffer[ActorRef] = new mutable.ListBuffer[ActorRef]()
|
val callbacks : mutable.ListBuffer[ActorRef] = new mutable.ListBuffer[ActorRef]()
|
||||||
val log = org.log4s.getLogger
|
val log = org.log4s.getLogger
|
||||||
|
|
||||||
def FactionObject : FactionAffinity = term
|
def FactionObject : FactionAffinity = term
|
||||||
|
def HackableObject = term
|
||||||
|
|
||||||
def TerminalObject : Terminal with ProximityUnit = term
|
def TerminalObject : Terminal with ProximityUnit = term
|
||||||
|
|
||||||
|
|
@ -41,7 +43,8 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
||||||
}
|
}
|
||||||
|
|
||||||
def Run : Receive = checkBehavior
|
def Run : Receive = checkBehavior
|
||||||
.orElse {
|
.orElse(hackableBehavior)
|
||||||
|
.orElse {
|
||||||
case CommonMessages.Use(_, Some(target : PlanetSideGameObject)) =>
|
case CommonMessages.Use(_, Some(target : PlanetSideGameObject)) =>
|
||||||
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
|
if(term.Definition.asInstanceOf[ProximityDefinition].Validations.exists(p => p(target))) {
|
||||||
Use(target, term.Continent, sender)
|
Use(target, term.Continent, sender)
|
||||||
|
|
@ -79,13 +82,6 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
case CommonMessages.Hack(player) =>
|
|
||||||
term.HackedBy = player
|
|
||||||
sender ! true
|
|
||||||
|
|
||||||
case CommonMessages.ClearHack() =>
|
|
||||||
term.HackedBy = None
|
|
||||||
|
|
||||||
case ProximityUnit.Action(_, _) =>
|
case ProximityUnit.Action(_, _) =>
|
||||||
//reserved
|
//reserved
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,26 +4,24 @@ package net.psforever.objects.serverobject.terminals
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `Terminal`.
|
* An `Actor` that handles messages being dispatched to a specific `Terminal`.
|
||||||
* @param term the `Terminal` object being governed
|
* @param term the `Terminal` object being governed
|
||||||
*/
|
*/
|
||||||
class TerminalControl(term : Terminal) extends Actor with FactionAffinityBehavior.Check {
|
class TerminalControl(term : Terminal) extends Actor with FactionAffinityBehavior.Check with HackableBehavior.GenericHackable {
|
||||||
def FactionObject : FactionAffinity = term
|
def FactionObject : FactionAffinity = term
|
||||||
|
def HackableObject = term
|
||||||
|
|
||||||
def receive : Receive = checkBehavior.orElse {
|
def receive : Receive = checkBehavior
|
||||||
case Terminal.Request(player, msg) =>
|
.orElse(hackableBehavior)
|
||||||
sender ! Terminal.TerminalMessage(player, msg, term.Request(player, msg))
|
.orElse {
|
||||||
|
case Terminal.Request(player, msg) =>
|
||||||
|
sender ! Terminal.TerminalMessage(player, msg, term.Request(player, msg))
|
||||||
|
|
||||||
case CommonMessages.Hack(player) =>
|
case _ => ;
|
||||||
term.HackedBy = player
|
}
|
||||||
sender ! true
|
|
||||||
case CommonMessages.ClearHack() =>
|
|
||||||
term.HackedBy = None
|
|
||||||
|
|
||||||
case _ => ;
|
|
||||||
}
|
|
||||||
|
|
||||||
override def toString : String = term.Definition.Name
|
override def toString : String = term.Definition.Name
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3673,6 +3673,23 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
log.info(s"UseItem: not $player's locker")
|
log.info(s"UseItem: not $player's locker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Some(implant_terminal : ImplantTerminalMech) =>
|
||||||
|
if(implant_terminal.Faction != player.Faction && implant_terminal.HackedBy.isEmpty) {
|
||||||
|
player.Slot(player.DrawnSlot).Equipment match {
|
||||||
|
case Some(tool: SimpleItem) =>
|
||||||
|
if (tool.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||||
|
val hackSpeed = GetPlayerHackSpeed(implant_terminal)
|
||||||
|
|
||||||
|
if(hackSpeed > 0) {
|
||||||
|
progressBarValue = Some(-hackSpeed)
|
||||||
|
self ! WorldSessionActor.HackingProgress(progressType = 1, player, implant_terminal, tool.GUID, hackSpeed, FinishHacking(implant_terminal, 3212836864L))
|
||||||
|
log.info("Hacking an implant terminal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case _ => ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case Some(captureTerminal : CaptureTerminal) =>
|
case Some(captureTerminal : CaptureTerminal) =>
|
||||||
val hackedByCurrentFaction = (captureTerminal.Faction != player.Faction && !captureTerminal.HackedBy.isEmpty && captureTerminal.HackedBy.head._1.Faction == player.Faction)
|
val hackedByCurrentFaction = (captureTerminal.Faction != player.Faction && !captureTerminal.HackedBy.isEmpty && captureTerminal.HackedBy.head._1.Faction == player.Faction)
|
||||||
val ownedByPlayerFactionAndHackedByEnemyFaction = (captureTerminal.Faction == player.Faction && !captureTerminal.HackedBy.isEmpty)
|
val ownedByPlayerFactionAndHackedByEnemyFaction = (captureTerminal.Faction == player.Faction && !captureTerminal.HackedBy.isEmpty)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue