From aece1e1aabc51942e3720770c115622dfbb98479 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 5 Mar 2017 16:27:37 -0500 Subject: [PATCH] Packet: GenericCollisionMsg (#105) * added new GenericCollisionMsg packet * added standard comments and a message display case * rebased GenericCollisionMsg * minor corrections * creating a Vector3 codec for leveraging float values --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../packet/game/GenericCollisionMsg.scala | 62 +++++++++++++++++++ .../scala/net/psforever/types/Vector3.scala | 6 ++ .../scala/game/GenericCollisionMsgTest.scala | 45 ++++++++++++++ .../src/main/scala/WorldSessionActor.scala | 4 +- 5 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/GenericCollisionMsg.scala create mode 100644 common/src/test/scala/game/GenericCollisionMsgTest.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 6a3b2b51c..6a4845579 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -389,7 +389,7 @@ object GamePacketOpcode extends Enumeration { case 0x39 => game.ChangeFireStateMessage_Start.decode case 0x3a => game.ChangeFireStateMessage_Stop.decode case 0x3b => noDecoder(UnknownMessage59) - case 0x3c => noDecoder(GenericCollisionMsg) + case 0x3c => game.GenericCollisionMsg.decode case 0x3d => game.QuantityUpdateMessage.decode case 0x3e => game.ArmorChangedMessage.decode case 0x3f => noDecoder(ProjectileStateMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/GenericCollisionMsg.scala b/common/src/main/scala/net/psforever/packet/game/GenericCollisionMsg.scala new file mode 100644 index 000000000..33d313023 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/GenericCollisionMsg.scala @@ -0,0 +1,62 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import net.psforever.types.Vector3 +import scodec.Codec +import scodec.codecs._ + +/** + * Dispatched by the client when the player has encountered a physical interaction that would cause damage.
+ *
+ * Collision information reports about two subjects who were involved in an altercation. + * The first is the `player`, that is, the client's avatar. + * The second is the `target` with respect to the `player` - whatever the avatar ran into, or whatever ran into the avatar. + * In the case of isolated forms of collision such as fall damage the `target` fields are blank or zero'd. + * @param unk1 na + * @param player the player or player-controlled vehicle + * @param target the other party in the collision + * @param player_health the player's health + * @param target_health the target's health + * @param player_velocity the player's velocity + * @param target_velocity the target's velocity + * @param player_pos the player's world coordinates + * @param target_pos the target's world coordinates + * @param unk2 na + * @param unk3 na + * @param unk4 na + */ +final case class GenericCollisionMsg(unk1 : Int, + player : PlanetSideGUID, + target : PlanetSideGUID, + player_health : Int, + target_health : Int, + player_velocity : Vector3, + target_velocity : Vector3, + player_pos : Vector3, + target_pos : Vector3, + unk2 : Long, + unk3 : Long, + unk4 : Long) + extends PlanetSideGamePacket { + type Packet = GenericCollisionMsg + def opcode = GamePacketOpcode.GenericCollisionMsg + def encode = GenericCollisionMsg.encode(this) +} + +object GenericCollisionMsg extends Marshallable[GenericCollisionMsg] { + implicit val codec : Codec[GenericCollisionMsg] = ( + ("unk1" | uint2) :: + ("p" | PlanetSideGUID.codec) :: + ("t" | PlanetSideGUID.codec) :: + ("p_health" | uint16L) :: + ("t_health" | uint16L) :: + ("p_vel" | Vector3.codec_float) :: + ("t_vel" | Vector3.codec_float) :: + ("p_pos" | Vector3.codec_pos) :: + ("t_pos" | Vector3.codec_pos) :: + ("unk2" | uint32L) :: + ("unk3" | uint32L) :: + ("unk4" | uint32L) + ).as[GenericCollisionMsg] +} diff --git a/common/src/main/scala/net/psforever/types/Vector3.scala b/common/src/main/scala/net/psforever/types/Vector3.scala index 3fdae394b..ecb00e8a3 100644 --- a/common/src/main/scala/net/psforever/types/Vector3.scala +++ b/common/src/main/scala/net/psforever/types/Vector3.scala @@ -21,4 +21,10 @@ object Vector3 { ("y" | newcodecs.q_float(-256.0, 256.0, 14)) :: ("z" | newcodecs.q_float(-256.0, 256.0, 14)) ).as[Vector3] + + implicit val codec_float : Codec[Vector3] = ( + ("x" | floatL) :: + ("y" | floatL) :: + ("z" | floatL) + ).as[Vector3] } diff --git a/common/src/test/scala/game/GenericCollisionMsgTest.scala b/common/src/test/scala/game/GenericCollisionMsgTest.scala new file mode 100644 index 000000000..970ce4f5b --- /dev/null +++ b/common/src/test/scala/game/GenericCollisionMsgTest.scala @@ -0,0 +1,45 @@ +// Copyright (c) 2016 PSForever.net to present +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import net.psforever.types.Vector3 +import scodec.bits._ + +class GenericCollisionMsgTest extends Specification { + //TODO find a better test later + val string = hex"3C 92C00000190000001B2A8010932CEF505C70946F00000000000000000000000017725EBC6D6A058000000000000000000000000000003F8FF45140" + "decode" in { + PacketCoding.DecodePacket(string).require match { + case GenericCollisionMsg(unk1, p, t, php, thp, pv, tv, ppos, tpos, unk2, unk3, unk4) => + unk1 mustEqual 2 + p mustEqual PlanetSideGUID(75) + t mustEqual PlanetSideGUID(0) + php mustEqual 100 + thp mustEqual 0 + pv.x mustEqual 32.166428f + pv.y mustEqual 23.712547f + pv.z mustEqual -0.012802706f + tv.x mustEqual 0.0f + tv.z mustEqual 0.0f + tv.x mustEqual 0.0f + ppos.x mustEqual 3986.7266f + ppos.y mustEqual 2615.3672f + ppos.z mustEqual 90.625f + tpos.x mustEqual 0.0f + tpos.y mustEqual 0.0f + tpos.z mustEqual 0.0f + unk2 mustEqual 0L + unk3 mustEqual 0L + unk4 mustEqual 1171341310L + case _ => + ko + } + } + "encode" in { + val msg = GenericCollisionMsg(2, PlanetSideGUID(75), PlanetSideGUID(0), 100, 0, Vector3(32.166428f, 23.712547f, -0.012802706f), Vector3(0.0f, 0.0f, 0.0f), Vector3(3986.7266f, 2615.3672f, 90.625f), Vector3(0.0f, 0.0f, 0.0f), 0L, 0L, 1171341310L) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + pkt mustEqual string + } +} diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 1af9aa6fe..f32a9fa9d 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -370,6 +370,9 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ SquadDefinitionActionMessage(a, b, c, d, e, f, g, h, i) => log.info("SquadDefinitionAction: " + msg) + case msg @ GenericCollisionMsg(u1, p, t, php, thp, pvx, pvy, pvz, tvx, tvy, tvz, ppos, tpos, u2, u3, u4) => + log.info("Ouch! " + msg) + case msg @ BugReportMessage(version_major,version_minor,version_date,bug_type,repeatable,location,zone,pos,summary,desc) => log.info("BugReportMessage: " + msg) @@ -377,7 +380,6 @@ class WorldSessionActor extends Actor with MDCContextAware { log.info("BindPlayerMessage: " + msg) case default => log.error(s"Unhandled GamePacket ${pkt}") - } def failWithError(error : String) = {