From 104fa16328620c2a851a4978f1e88cfe8dce0832 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 19 Mar 2017 18:40:40 -0400 Subject: [PATCH] Packet: ObjectDetectedMessage (#120) * importing ObjectDetectedMessage packet from aus repo and writing a test for it * comments --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../packet/game/ObjectDetectedMessage.scala | 49 +++++++++++++++++++ .../game/ObjectDetectedMessageTest.scala | 37 ++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/ObjectDetectedMessage.scala create mode 100644 common/src/test/scala/game/ObjectDetectedMessageTest.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 94e669a8..0ed57903 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -434,7 +434,7 @@ object GamePacketOpcode extends Enumeration { // OPCODES 0x60-6f case 0x60 => game.FavoritesMessage.decode - case 0x61 => noDecoder(ObjectDetectedMessage) + case 0x61 => game.ObjectDetectedMessage.decode case 0x62 => game.SplashHitMessage.decode case 0x63 => noDecoder(SetChatFilterMessage) case 0x64 => noDecoder(AvatarSearchCriteriaMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/ObjectDetectedMessage.scala b/common/src/main/scala/net/psforever/packet/game/ObjectDetectedMessage.scala new file mode 100644 index 00000000..e7f0600d --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/ObjectDetectedMessage.scala @@ -0,0 +1,49 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.codecs._ +import scodec.{Attempt, Codec, Err} +import shapeless.{::, HNil} + +/** + * na + * @param guid1 na + * @param guid2 na; + * often matches with `guid1` + * @param unk1 na + * @param unk2 na; + * normally contains at least one element + */ +final case class ObjectDetectedMessage(guid1 : PlanetSideGUID, + guid2 : PlanetSideGUID, + unk1 : Int, + unk2 : List[Int]) + extends PlanetSideGamePacket { + type Packet = ObjectDetectedMessage + def opcode = GamePacketOpcode.ObjectDetectedMessage + def encode = ObjectDetectedMessage.encode(this) +} + +object ObjectDetectedMessage extends Marshallable[ObjectDetectedMessage] { + implicit val codec : Codec[ObjectDetectedMessage] = ( + ("guid1" | PlanetSideGUID.codec) :: + ("guid2" | PlanetSideGUID.codec) :: + ("unk1" | uint8L) :: + ("unk2" | listOfN(uintL(6), uint16L)) //TODO are these uids? + ).exmap[ObjectDetectedMessage] ( + { + case g1 :: g2 :: u1 :: u2 :: HNil => + Attempt.successful(ObjectDetectedMessage(g1, g2, u1, u2)) + }, + { + case ObjectDetectedMessage(g1, g2, u1, u2) => + if(u2.size > 63) { + Attempt.failure(Err(s"too many list elements (max: 63, actual: ${u2.size})")) + } + else { + Attempt.successful(g1 :: g2 :: u1 :: u2 :: HNil) + } + } + ) +} diff --git a/common/src/test/scala/game/ObjectDetectedMessageTest.scala b/common/src/test/scala/game/ObjectDetectedMessageTest.scala new file mode 100644 index 00000000..674f1ba4 --- /dev/null +++ b/common/src/test/scala/game/ObjectDetectedMessageTest.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class ObjectDetectedMessageTest extends Specification { + val string = hex"61 E60F E60F 00 1C9C39F8304030AC18A8183436D42C" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case ObjectDetectedMessage(guid1, guid2, unk1, unk2) => + guid1 mustEqual PlanetSideGUID(4070) + guid2 mustEqual PlanetSideGUID(4070) + unk1 mustEqual 0 + unk2.size mustEqual 7 + unk2.head mustEqual 3623 + unk2(1) mustEqual 3198 + unk2(2) mustEqual 3088 + unk2(3) mustEqual 1579 + unk2(4) mustEqual 1578 + unk2(5) mustEqual 3341 + unk2(6) mustEqual 2997 + case _ => + ko + } + } + + "encode" in { + val msg = ObjectDetectedMessage(PlanetSideGUID(4070), PlanetSideGUID(4070), 0, 3623 :: 3198 :: 3088 :: 1579 :: 1578 :: 3341 :: 2997 :: Nil) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } +}