mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
stop reporting the origin of a projectile as a valid hit position; creating pipelines for either damage proxy management and no damage proxy management
This commit is contained in:
parent
b02de0f80a
commit
01c014a59c
|
|
@ -127,14 +127,14 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
val list = ops.composeDirectDamageInformation(pkt)
|
||||
if (!player.spectator) {
|
||||
list.foreach {
|
||||
case (target, projectile, _, _) =>
|
||||
ops.resolveProjectileInteraction(target, projectile, DamageResolution.Hit, target.Position)
|
||||
case (target, projectile, _, targetPos) =>
|
||||
ops.resolveProjectileInteractionAndProxy(target, projectile, DamageResolution.Hit, targetPos)
|
||||
}
|
||||
//...
|
||||
if (list.isEmpty) {
|
||||
ops.handleProxyDamage(pkt.projectile_guid, pkt.hit_info.map(_.hit_pos).getOrElse(Vector3.Zero)).foreach {
|
||||
case (target, proxy, hitPos, _) =>
|
||||
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Hit, hitPos)
|
||||
case (target, proxy, _, targetPos) =>
|
||||
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Hit, targetPos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,12 +157,12 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
//...
|
||||
val (direct, others) = list.partition { case (_, _, hitPos, targetPos) => hitPos == targetPos }
|
||||
direct.foreach {
|
||||
case (target, _, _, _) =>
|
||||
ops.resolveProjectileInteraction(target, projectile, resolution1, target.Position)
|
||||
case (target, _, _, targetPos) =>
|
||||
ops.resolveProjectileInteractionAndProxy(target, projectile, resolution1, targetPos)
|
||||
}
|
||||
others.foreach {
|
||||
case (target, _, _, _) =>
|
||||
ops.resolveProjectileInteraction(target, projectile, resolution2, target.Position)
|
||||
case (target, _, _, targetPos) =>
|
||||
ops.resolveProjectileInteraction(target, projectile, resolution2, targetPos)
|
||||
}
|
||||
//...
|
||||
if (
|
||||
|
|
@ -183,11 +183,11 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
if (profile.ExistsOnRemoteClients && projectile.HasGUID) {
|
||||
continent.Projectile ! ZoneProjectile.Remove(projectileGuid)
|
||||
}
|
||||
}
|
||||
//...
|
||||
ops.handleProxyDamage(pkt.projectile_uid, pkt.projectile_pos).foreach {
|
||||
case (target, proxy, hitPos, _) =>
|
||||
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Splash, hitPos)
|
||||
} else {
|
||||
ops.handleProxyDamage(pkt.projectile_uid, pkt.projectile_pos).foreach {
|
||||
case (target, proxy, _, targetPos) =>
|
||||
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Splash, targetPos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,9 +144,9 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
val projectileGuid = pkt.projectile_guid
|
||||
val list = ops.composeDirectDamageInformation(pkt)
|
||||
.collect {
|
||||
case (target, projectile, hitPos, _) =>
|
||||
ops.checkForHitPositionDiscrepancy(projectileGuid, hitPos, target)
|
||||
ops.resolveProjectileInteraction(target, projectile, DamageResolution.Hit, hitPos)
|
||||
case (target, projectile, hitPos, targetPos) =>
|
||||
ops.checkForHitPositionDiscrepancy(projectileGuid, hitPos, targetPos)
|
||||
ops.resolveProjectileInteractionAndProxy(target, projectile, DamageResolution.Hit, hitPos)
|
||||
projectile
|
||||
}
|
||||
//...
|
||||
|
|
@ -174,9 +174,9 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
//...
|
||||
val (direct, others) = list.partition { case (_, _, hitPos, targetPos) => hitPos == targetPos }
|
||||
direct.foreach {
|
||||
case (target, _, hitPos, _) =>
|
||||
ops.checkForHitPositionDiscrepancy(projectileGuid, hitPos, target)
|
||||
ops.resolveProjectileInteraction(target, projectile, resolution1, hitPos)
|
||||
case (target, _, hitPos, targetPos) =>
|
||||
ops.checkForHitPositionDiscrepancy(projectileGuid, hitPos, targetPos)
|
||||
ops.resolveProjectileInteractionAndProxy(target, projectile, resolution1, hitPos)
|
||||
}
|
||||
others.foreach {
|
||||
case (target, _, hitPos, _) =>
|
||||
|
|
@ -202,19 +202,19 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
//cleanup
|
||||
continent.Projectile ! ZoneProjectile.Remove(projectile.GUID)
|
||||
}
|
||||
}
|
||||
//...
|
||||
ops.handleProxyDamage(pkt.projectile_uid, pkt.projectile_pos).foreach {
|
||||
case (target, proxy, hitPos, _) =>
|
||||
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Splash, hitPos)
|
||||
} else {
|
||||
ops.handleProxyDamage(pkt.projectile_uid, pkt.projectile_pos).foreach {
|
||||
case (target, proxy, hitPos, _) =>
|
||||
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Splash, hitPos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def handleLashHit(pkt: LashMessage): Unit = {
|
||||
val list = ops.composeLashDamageInformation(pkt)
|
||||
list.foreach {
|
||||
case (target, projectile, hitPos, _) =>
|
||||
ops.checkForHitPositionDiscrepancy(projectile.GUID, hitPos, target)
|
||||
case (target, projectile, hitPos, targetPos) =>
|
||||
ops.checkForHitPositionDiscrepancy(projectile.GUID, hitPos, targetPos)
|
||||
ops.resolveProjectileInteraction(target, projectile, DamageResolution.Lash, hitPos)
|
||||
}
|
||||
}
|
||||
|
|
@ -223,8 +223,8 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
|
|||
val list = ops.composeAIDamageInformation(pkt)
|
||||
if (ops.confirmAIDamageTarget(pkt, list.map(_._1))) {
|
||||
list.foreach {
|
||||
case (target, projectile, hitPos, _) =>
|
||||
ops.checkForHitPositionDiscrepancy(pkt.attacker_guid, hitPos, target)
|
||||
case (target, projectile, hitPos, targetPos) =>
|
||||
ops.checkForHitPositionDiscrepancy(pkt.attacker_guid, hitPos, targetPos)
|
||||
ops.resolveProjectileInteraction(target, projectile, DamageResolution.Hit, hitPos)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -513,6 +513,7 @@ class WeaponAndProjectileOperations(
|
|||
hit_info match {
|
||||
case Some(hitInfo) =>
|
||||
val hitPos = hitInfo.hit_pos
|
||||
projectile.Position = hitPos
|
||||
sessionLogic.validObject(hitInfo.hitobject_guid, decorator = "Hit/hitInfo") match {
|
||||
case _ if projectile.profile == GlobalDefinitions.flail_projectile =>
|
||||
val radius = projectile.profile.DamageRadius * projectile.profile.DamageRadius
|
||||
|
|
@ -522,7 +523,7 @@ class WeaponAndProjectileOperations(
|
|||
.map(target => (target, projectile, hitPos, target.Position))
|
||||
|
||||
case Some(target: PlanetSideGameObject with FactionAffinity with Vitality) =>
|
||||
List((target, projectile, hitInfo.shot_origin, hitPos))
|
||||
List((target, projectile, hitPos, target.Position))
|
||||
|
||||
case None =>
|
||||
Nil
|
||||
|
|
@ -585,7 +586,9 @@ class WeaponAndProjectileOperations(
|
|||
FindProjectileEntry(projectile_guid)
|
||||
.flatMap {
|
||||
projectile =>
|
||||
sessionLogic
|
||||
//projectile may still be moving, and may lash other targets in the future when in a different position
|
||||
projectile.Position = hit_pos
|
||||
sessionLogic
|
||||
.validObject(victim_guid, decorator = "LashHit/victim_guid")
|
||||
.collect {
|
||||
case target: PlanetSideGameObject with FactionAffinity with Vitality =>
|
||||
|
|
@ -826,6 +829,26 @@ class WeaponAndProjectileOperations(
|
|||
context.system.scheduler.scheduleOnce(500.milliseconds) { explosionFunc() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a projectile with the given globally unique identifier and mark it as a resolved shot.
|
||||
* A `Resolved` shot has either encountered an obstacle or is being cleaned up for not finding an obstacle.
|
||||
* Check if we are required to deal with damage proxy management as well.
|
||||
* @param projectile projectile
|
||||
* @param resolution resolution status to promote the projectile
|
||||
* @return package that contains information about the damage
|
||||
*/
|
||||
def resolveProjectileInteractionAndProxy(
|
||||
target: PlanetSideGameObject with FactionAffinity with Vitality,
|
||||
projectile: Projectile,
|
||||
resolution: DamageResolution.Value,
|
||||
hitPosition: Vector3
|
||||
): Option[DamageInteraction] = {
|
||||
if (projectile.profile.DamageProxyOnDirectHit.exists(_.test(target))) {
|
||||
handleProxyDamage(projectile, hitPosition)
|
||||
}
|
||||
resolveProjectileInteraction(target, projectile, resolution, hitPosition)
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a projectile with the given globally unique identifier and mark it as a resolved shot.
|
||||
* A `Resolved` shot has either encountered an obstacle or is being cleaned up for not finding an obstacle.
|
||||
|
|
@ -842,9 +865,6 @@ class WeaponAndProjectileOperations(
|
|||
if (projectile.isMiss) {
|
||||
None
|
||||
} else {
|
||||
if (projectile.profile.DamageProxyOnDirectHit.exists(_.test(target))) {
|
||||
handleProxyDamage(projectile, hitPosition)
|
||||
}
|
||||
val outProjectile = ProjectileQuality.modifiers(projectile, resolution, target, hitPosition, Some(player))
|
||||
if (projectile.tool_def.Size == EquipmentSize.Melee && outProjectile.quality == ProjectileQuality.Modified(25)) {
|
||||
avatarActor ! AvatarActor.ConsumeStamina(10)
|
||||
|
|
@ -1462,15 +1482,23 @@ class WeaponAndProjectileOperations(
|
|||
}
|
||||
|
||||
def checkForHitPositionDiscrepancy(
|
||||
projectile_guid: PlanetSideGUID,
|
||||
hitPos: Vector3,
|
||||
projectileGuid: PlanetSideGUID,
|
||||
hitPosition: Vector3,
|
||||
target: PlanetSideGameObject with Vitality
|
||||
): Unit = {
|
||||
val hitPositionDiscrepancy = Vector3.DistanceSquared(hitPos, target.Position)
|
||||
checkForHitPositionDiscrepancy(projectileGuid, hitPosition, target.Position)
|
||||
}
|
||||
|
||||
def checkForHitPositionDiscrepancy(
|
||||
projectileGuid: PlanetSideGUID,
|
||||
hitPosition: Vector3,
|
||||
targetPosition: Vector3
|
||||
): Unit = {
|
||||
val hitPositionDiscrepancy = Vector3.DistanceSquared(hitPosition, targetPosition)
|
||||
if (hitPositionDiscrepancy > Config.app.antiCheat.hitPositionDiscrepancyThreshold) {
|
||||
// If the target position on the server does not match the position where the projectile landed within reason there may be foul play
|
||||
log.warn(
|
||||
s"${player.Name}'s shot #${projectile_guid.guid} has hit discrepancy with target. Target: ${target.Position}, Reported: $hitPos, Distance: $hitPositionDiscrepancy / ${math.sqrt(hitPositionDiscrepancy).toFloat}; suspect"
|
||||
s"${player.Name}'s shot #${projectileGuid.guid} has hit discrepancy with target. Target: $targetPosition, Reported: $hitPosition, Distance: $hitPositionDiscrepancy / ${math.sqrt(hitPositionDiscrepancy).toFloat}; suspect"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue