From 84a36dc9c810d3a2e9e1164ceb17e222db6961b9 Mon Sep 17 00:00:00 2001 From: Mazo Date: Tue, 26 Jan 2021 22:56:23 +0000 Subject: [PATCH] CaptureFlagUpdateMessage encoder/decoder + tests --- .../game/CaptureFlagUpdateMessage.scala | 57 +++++++++++++++++++ .../game/CaptureFlagUpdateMessageTest.scala | 48 ++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/main/scala/net/psforever/packet/game/CaptureFlagUpdateMessage.scala create mode 100644 src/test/scala/game/CaptureFlagUpdateMessageTest.scala diff --git a/src/main/scala/net/psforever/packet/game/CaptureFlagUpdateMessage.scala b/src/main/scala/net/psforever/packet/game/CaptureFlagUpdateMessage.scala new file mode 100644 index 00000000..becfbd67 --- /dev/null +++ b/src/main/scala/net/psforever/packet/game/CaptureFlagUpdateMessage.scala @@ -0,0 +1,57 @@ +package net.psforever.packet.game + +import net.psforever.newcodecs.newcodecs +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ +import shapeless.{::, HNil} + +/** + * + * @param zone_number The zone number this packet applies to + * @param flagInfoList The list of LLUs/Monolith units for this zone + */ +final case class CaptureFlagUpdateMessage(zone_number: Int, flagInfoList: List[FlagInfo]) extends PlanetSideGamePacket { + type Packet = CaptureFlagUpdateMessage + def opcode = GamePacketOpcode.CaptureFlagUpdateMessage + def encode = CaptureFlagUpdateMessage.encode(this) +} + +/** + * + * @param u1 No effect. Faction ID perhaps? + * @param owner_map_id The mapID of the base the LLU belongs to + * @param target_map_id The mapID of the base the LLU must be delivered to + * @param x X map position + * @param y Y map position + * @param u6 Time remaining for hack? No effect when modified + * @param isMonolithUnit Changes the icon on the map to the monolith unit icon + */ +final case class FlagInfo(u1: Int, owner_map_id: Int, target_map_id: Int, x: Float, y: Float, u6: Long, isMonolithUnit: Boolean) +object FlagInfo extends Marshallable[FlagInfo] { + implicit val codec: Codec[FlagInfo] = { + (("u1" | uint2L) + :: ("owner_map_id" | uint16L) + :: ("target_map_id" | uint16L) + :: ("u4" | newcodecs.q_float(0.0, 8192.0, 20)) + :: ("u5" | newcodecs.q_float(0.0, 8192.0, 20)) + :: ("u6" | uint32L) + :: ("isMonolithUnit" | bool)) + }.as[FlagInfo] +} + +object CaptureFlagUpdateMessage extends Marshallable[CaptureFlagUpdateMessage] { + implicit val codec: Codec[CaptureFlagUpdateMessage] = ( + ("zone_number" | uint16L) + :: ("flagInfoList" | PacketHelpers.listOfNAligned(longL(4), alignment = 0, FlagInfo.codec)) // Maximum of 7 on any map + ).xmap[CaptureFlagUpdateMessage] ( + { + case zone_number :: flagInfoList :: HNil => + CaptureFlagUpdateMessage(zone_number, flagInfoList) + }, + { + case CaptureFlagUpdateMessage(zone_number, flagInfoList) => + zone_number :: flagInfoList :: HNil + } + ) +} diff --git a/src/test/scala/game/CaptureFlagUpdateMessageTest.scala b/src/test/scala/game/CaptureFlagUpdateMessageTest.scala new file mode 100644 index 00000000..a4477a38 --- /dev/null +++ b/src/test/scala/game/CaptureFlagUpdateMessageTest.scala @@ -0,0 +1,48 @@ +package game + +import net.psforever.packet.PacketCoding +import net.psforever.packet.game.{CaptureFlagUpdateMessage, FlagInfo} +import org.specs2.control.Debug +import org.specs2.mutable.Specification +import scodec.bits._ + +class CaptureFlagUpdateMessageTest extends Specification with Debug { + val stringZero = hex"c0 0a0000" + val stringOne = hex"c0 0a0014300018025281dd852830803000" + + "decode (zero)" in { + PacketCoding.decodePacket(stringZero).require match { + case CaptureFlagUpdateMessage(zone_number, flagInfoList) => + zone_number mustEqual 10 + flagInfoList.length mustEqual 0 + case _ => + ko + } + } + + "decode (one)" in { + PacketCoding.decodePacket(stringOne).require match { + case CaptureFlagUpdateMessage(zone_number, flagInfoList) => + zone_number mustEqual 10 + flagInfoList.length mustEqual 1 + flagInfoList.head mustEqual FlagInfo(1, 12, 6, 3905.1562f, 5160.922f, 794636L, false) + case _ => + ko + } + } + + "encode (zero)" in { + val msg = CaptureFlagUpdateMessage(10, Nil) + val pkt = PacketCoding.encodePacket(msg).require.toByteVector + + pkt mustEqual stringZero + } + + "encode (one)" in { + val msg = CaptureFlagUpdateMessage(10, List(FlagInfo(1, 12, 6, 3905.1562f, 5160.922f, 794636L, false))) + val pkt = PacketCoding.encodePacket(msg).require.toByteVector + + pkt mustEqual stringOne + } +} +