From 6fa701d26334135965fc8a406a784659b3847300 Mon Sep 17 00:00:00 2001 From: FateJH Date: Fri, 21 Apr 2017 00:07:34 -0400 Subject: [PATCH] initial work on TargetingInfoMessage packet and working tests; want to try clarify unknown fields before finishing --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../packet/game/TargetingInfoMessage.scala | 53 ++++++++++++++++++ .../scala/game/TargetingInfoMessageTest.scala | 54 +++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/TargetingInfoMessage.scala create mode 100644 common/src/test/scala/game/TargetingInfoMessageTest.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 055c2235..8f369724 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -414,7 +414,7 @@ object GamePacketOpcode extends Enumeration { case 0x4f => game.LashMessage.decode // OPCODES 0x50-5f - case 0x50 => noDecoder(TargetingInfoMessage) + case 0x50 => game.TargetingInfoMessage.decode case 0x51 => noDecoder(TriggerEffectMessage) case 0x52 => game.WeaponDryFireMessage.decode case 0x53 => noDecoder(DroppodLaunchRequestMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/TargetingInfoMessage.scala b/common/src/main/scala/net/psforever/packet/game/TargetingInfoMessage.scala new file mode 100644 index 00000000..609271e2 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/TargetingInfoMessage.scala @@ -0,0 +1,53 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ +import shapeless.{::, HNil} + +/** + * na + * @param target_guid the target + * @param unk1 na + * @param unk2 na + */ +final case class TargetInfo(target_guid : PlanetSideGUID, + unk1 : Float, + unk2 : Float = 0f) + +/** + * na + * @param target_list a list of targets + */ +final case class TargetingInfoMessage(target_list : List[TargetInfo]) + extends PlanetSideGamePacket { + type Packet = TargetingInfoMessage + def opcode = GamePacketOpcode.TargetingInfoMessage + def encode = TargetingInfoMessage.encode(this) +} + +object TargetingInfoMessage extends Marshallable[TargetingInfoMessage] { + private final val unit : Double = 0.0039215689 //common constant for 1/255 + + private val info_codec : Codec[TargetInfo] = ( + ("target_guid" | PlanetSideGUID.codec) :: + ("unk1" | uint8L) :: + ("unk2" | uint8L) + ).xmap[TargetInfo] ( + { + case a :: b :: c :: HNil => + val bFloat : Float = (b.toDouble * unit).toFloat + val cFloat : Float = (c.toDouble * unit).toFloat + TargetInfo(a, bFloat, cFloat) + }, + { + case TargetInfo(a, bFloat, cFloat) => + val b : Int = (bFloat.toDouble * 255).toInt + val c : Int = (cFloat.toDouble * 255).toInt + a :: b :: c :: HNil + } + ) + + implicit val codec : Codec[TargetingInfoMessage] = ("target_list" | listOfN(uint8L, info_codec)).as[TargetingInfoMessage] +} diff --git a/common/src/test/scala/game/TargetingInfoMessageTest.scala b/common/src/test/scala/game/TargetingInfoMessageTest.scala new file mode 100644 index 00000000..b7f31c3e --- /dev/null +++ b/common/src/test/scala/game/TargetingInfoMessageTest.scala @@ -0,0 +1,54 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class TargetingInfoMessageTest extends Specification { + val string = hex"50 05 3D10C200 570EFF3C 2406EC00 2B068C00 2A069400" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case TargetingInfoMessage(target_list) => + target_list.size mustEqual 5 + //0 + target_list.head.target_guid mustEqual PlanetSideGUID(4157) + target_list.head.unk1 mustEqual 0.7607844f + target_list.head.unk2 mustEqual 0f + //1 + target_list(1).target_guid mustEqual PlanetSideGUID(3671) + target_list(1).unk1 mustEqual 1.0000001f + target_list(1).unk2 mustEqual 0.23529413f + //2 + target_list(2).target_guid mustEqual PlanetSideGUID(1572) + target_list(2).unk1 mustEqual 0.92549026f + target_list(2).unk2 mustEqual 0f + //3 + target_list(3).target_guid mustEqual PlanetSideGUID(1579) + target_list(3).unk1 mustEqual 0.54901963f + target_list(3).unk2 mustEqual 0f + //4 + target_list(4).target_guid mustEqual PlanetSideGUID(1578) + target_list(4).unk1 mustEqual 0.5803922f + target_list(4).unk2 mustEqual 0f + case _ => + ko + } + } + + "encode" in { + val msg = TargetingInfoMessage( + TargetInfo(PlanetSideGUID(4157), 0.7607844f) :: + TargetInfo(PlanetSideGUID(3671), 1.0000001f, 0.23529413f) :: + TargetInfo(PlanetSideGUID(1572), 0.92549026f) :: + TargetInfo(PlanetSideGUID(1579), 0.54901963f) :: + TargetInfo(PlanetSideGUID(1578), 0.5803922f) :: + Nil + ) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } +}