diff --git a/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala b/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala index 61d7d552..c7ecaa1e 100644 --- a/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/ObjectCreateMessage.scala @@ -34,15 +34,18 @@ object AmmoBoxData extends Marshallable[AmmoBoxData] { case class WeaponData(ammo : InternalMold) extends ConstructorData object WeaponData extends Marshallable[WeaponData] { + type rawPattern = Int :: Unit :: Int :: Unit :: Int :: InternalMold :: HNil implicit val codec : Codec[WeaponData] = ( ("code" | uint16L) :: ignore(12) :: uint4L :: - ignore(4) :: - uintL(12) :: + ignore(16) :: + ("tail" | uintL(11)) :: ("data" | InternalMold.codec) ).exmap[WeaponData] ( { + case 0x48 :: _ :: 2 :: _ :: 0x2C0 :: ammo :: HNil => //TODO: this will work for decoding, but not for encoding + Attempt.successful(WeaponData(ammo)) case 0x88 :: _ :: 2 :: _ :: 0x2C0 :: ammo :: HNil => Attempt.successful(WeaponData(ammo)) case x :: _ :: y :: _ :: z :: _ :: HNil => @@ -50,7 +53,7 @@ object WeaponData extends Marshallable[WeaponData] { }, { case WeaponData(ammo) => - Attempt.successful(0x88 :: () :: 2 :: () :: 0x2C0 :: ammo :: HNil) + Attempt.successful(0x88 :: () :: 2 :: () :: 0x2C0 :: ammo :: HNil) //TODO: this will not work for encoding (see above) } ).as[WeaponData] } @@ -249,6 +252,10 @@ object Mold { val opt = WeaponData.codec.decode(data).toOption if(opt.isDefined) out = Some(opt.get.value) + case 0x159 => //gauss + val opt = WeaponData.codec.decode(data).toOption + if(opt.isDefined) + out = Some(opt.get.value) case _ => } } @@ -267,6 +274,10 @@ object Mold { val opt = WeaponData.codec.encode(obj.asInstanceOf[WeaponData]).toOption if(opt.isDefined) out = opt.get + case 0x159 => //gauss + val opt = WeaponData.codec.encode(obj.asInstanceOf[WeaponData]).toOption + if(opt.isDefined) + out = opt.get case _ => throw new ClassCastException("cannot find object code - "+objClass) } diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 54be73b6..292367c9 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -149,6 +149,7 @@ class GamePacketTest extends Specification { val packet2 = hex"18 F8 00 00 00 BC 8C 10 90 3B 45 C6 FA 94 00 9F F0 00 00 40 00 08 C0 44 00 69 00 66 00 66 00 45" //faked data? val packet2Rest = packet2.bits.drop(8 + 32 + 1 + 11 + 16) val string_9mm = hex"18 7C000000 2580 0E0 0005 A1 C8000064000" + val string_gauss = hex"18 DC000000 2580 2C9 B905 82 480000020000C04 1C00C0B0190000078000" "decode (2)" in { PacketCoding.DecodePacket(packet2).require match { @@ -174,7 +175,6 @@ class GamePacketTest extends Specification { parent.get.guid mustEqual PlanetSideGUID(75) parent.get.slot mustEqual 33 mold.isDefined mustEqual true - val obj = mold.get.asInstanceOf[AmmoBoxData] obj.magazine mustEqual 50 case default => @@ -182,6 +182,29 @@ class GamePacketTest extends Specification { } } + "decode (gauss)" in { + PacketCoding.DecodePacket(string_gauss).require match { + case obj @ ObjectCreateMessage(len, cls, guid, parent, mold) => + len mustEqual 220 + cls mustEqual 345 + guid mustEqual PlanetSideGUID(1465) + parent.isDefined mustEqual true + parent.get.guid mustEqual PlanetSideGUID(75) + parent.get.slot mustEqual 2 + mold.isDefined mustEqual true + val obj_wep = mold.get.asInstanceOf[WeaponData] + val obj_ammo = obj_wep.ammo//.asInstanceOf[InternalMold] + obj_ammo.objectClass mustEqual 28 + obj_ammo.guid mustEqual PlanetSideGUID(1286) + obj_ammo.parentSlot mustEqual 0 + obj_ammo.obj.isDefined mustEqual true + val ammo = obj_ammo.obj.get.asInstanceOf[AmmoBoxData] + ammo.magazine mustEqual 30 + case default => + ko + } + } + "encode (2)" in { val msg = ObjectCreateMessage(0, 121, PlanetSideGUID(2497), None, Mold(121, packet2Rest)) val pkt = PacketCoding.EncodePacket(msg).require.toByteVector