diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 75d7a45b..369a9299 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -481,7 +481,7 @@ object GamePacketOpcode extends Enumeration { case OffshoreVehicleMessage => noDecoder(opcode) case ObjectDeployedMessage => noDecoder(opcode) case ObjectDeployedCountMessage => noDecoder(opcode) - case WeaponDelayFireMessage => noDecoder(opcode) + case WeaponDelayFireMessage => game.WeaponDelayFireMessage.decode case BugReportMessage => noDecoder(opcode) case PlayerStasisMessage => noDecoder(opcode) case UnknownMessage139 => noDecoder(opcode) diff --git a/common/src/main/scala/net/psforever/packet/game/WeaponDelayFireMessage.scala b/common/src/main/scala/net/psforever/packet/game/WeaponDelayFireMessage.scala new file mode 100644 index 00000000..81fc5d53 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/WeaponDelayFireMessage.scala @@ -0,0 +1,25 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +/** WeaponDelayFireMessage seems to be sent when a weapon has a delayed projectile after firing, such as the knife. + * + * See [[PlayerStateMessageUpstream]] for explanation of seq_time. + */ +final case class WeaponDelayFireMessage(seq_time : Int, + weapon_guid : PlanetSideGUID) + extends PlanetSideGamePacket { + type Packet = WeaponDelayFireMessage + def opcode = GamePacketOpcode.WeaponDelayFireMessage + def encode = WeaponDelayFireMessage.encode(this) +} + +object WeaponDelayFireMessage extends Marshallable[WeaponDelayFireMessage] { + implicit val codec : Codec[WeaponDelayFireMessage] = ( + ("seq_time" | uintL(10)) :: + ("weapon_guid" | PlanetSideGUID.codec) + ).as[WeaponDelayFireMessage] +} diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 2701ef80..e10ef562 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -580,5 +580,26 @@ class GamePacketTest extends Specification { pkt_forget mustEqual string_forget } } + + "WeaponDelayFireMessage" should { + val string = hex"88 A3140000" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case WeaponDelayFireMessage(seq_time, weapon_guid) => + seq_time mustEqual 163 + weapon_guid mustEqual PlanetSideGUID(80) + case default => + ko + } + } + + "encode" in { + val msg = WeaponDelayFireMessage(163, PlanetSideGUID(80)) + 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 dee12365..ff4d6ca8 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -206,6 +206,9 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ ItemTransactionMessage(terminal_guid, transaction_type, item_page, item_name, unk1, item_guid) => log.info("ItemTransaction: " + msg) + case msg @ WeaponDelayFireMessage(seq_time, weapon_guid) => + log.info("WeaponDelayFire: " + msg) + case default => log.debug(s"Unhandled GamePacket ${pkt}") }