diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index af3b4a90f..236731264 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -428,7 +428,7 @@ object GamePacketOpcode extends Enumeration { case 0x5a => noDecoder(DelayedPathMountMsg) case 0x5b => noDecoder(OrbitalShuttleTimeMsg) case 0x5c => noDecoder(AIDamage) - case 0x5d => game.DeployObjectMessage.decode + case 0x5d => noDecoder(DeployObjectMessage) case 0x5e => noDecoder(FavoritesRequest) case 0x5f => noDecoder(FavoritesResponse) @@ -477,7 +477,7 @@ object GamePacketOpcode extends Enumeration { case 0x83 => noDecoder(SquadWaypointRequest) case 0x84 => noDecoder(SquadWaypointEvent) case 0x85 => noDecoder(OffshoreVehicleMessage) - case 0x86 => noDecoder(ObjectDeployedMessage) + case 0x86 => game.ObjectDeployedMessage.decode case 0x87 => noDecoder(ObjectDeployedCountMessage) // 0x88 case 0x88 => game.WeaponDelayFireMessage.decode diff --git a/common/src/main/scala/net/psforever/packet/game/DeployObjectMessage.scala b/common/src/main/scala/net/psforever/packet/game/DeployObjectMessage.scala deleted file mode 100644 index e18b24429..000000000 --- a/common/src/main/scala/net/psforever/packet/game/DeployObjectMessage.scala +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2017 PSForever -package net.psforever.packet.game - -import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} -import scodec.Codec -import scodec.codecs._ -import shapeless.{::, HNil} - -final case class DeployObjectMessage(guid : PlanetSideGUID, - str : String, - unk1 : Long, - unk2 : Long, - unk3 : Long) - extends PlanetSideGamePacket { - type Packet = DeployObjectMessage - def opcode = GamePacketOpcode.ObjectDeployedMessage - def encode = DeployObjectMessage.encode(this) -} - -object DeployObjectMessage extends Marshallable[DeployObjectMessage] { - implicit val codec : Codec[DeployObjectMessage] = ( - ("object_guid" | PlanetSideGUID.codec) :: - ("str" | PacketHelpers.encodedString) :: - ("unk1" | uint32L) :: - ("unk2" | uint32L) :: - ("unk3" | uint32L) - ).xmap[DeployObjectMessage] ( - { - case guid :: str :: u1 :: u2 :: u3 :: HNil => - DeployObjectMessage(guid, str, u1, u2, u3) - }, - { - case DeployObjectMessage(guid, str, u1, u2, u3) => - //truncate string length to 100 characters; raise no warnings - val limitedStr : String = if(str.length() > 100) { str.substring(0,100) } else { str } - guid :: limitedStr :: u1 :: u2 :: u3 :: HNil - } - ) -} diff --git a/common/src/main/scala/net/psforever/packet/game/ObjectDeployedMessage.scala b/common/src/main/scala/net/psforever/packet/game/ObjectDeployedMessage.scala new file mode 100644 index 000000000..007fb1ce1 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/ObjectDeployedMessage.scala @@ -0,0 +1,69 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ +import shapeless.{::, HNil} + +/** + * Dispatched by the server when placing deployables to generate a message in the events chat.
+ *
+ * This packet does not actually modify anything in regards to deployables. + * It merely generates the message:
+ * `"You have placed x of a possible y thing."`
+ * ... where `x` is the current count of objects of this type that have been deployed; + * `y` is the (reported) maximum amount of objects of this type that can be deployed; + * and, `thing` is the label for objects of this type. + * This text is not directly placed into the message's field but, rather, is a token for language-appropriate descriptive text.
+ * "boomer," for example, is replaced by "Heavy Explosive Mines" in the message for English language. + * @param guid na + * @param desc descriptive text of what kind of object is being deployed; + * matches the `String` description of the object class + * @param unk na + * @param count the current number of this type of object deployed + * @param max the maximum number of this type of object that can be deployed + * @see `ObjectClass` + */ +final case class ObjectDeployedMessage(guid : PlanetSideGUID, + desc : String, + unk : Long, + count : Long, + max : Long) + extends PlanetSideGamePacket { + type Packet = ObjectDeployedMessage + def opcode = GamePacketOpcode.ObjectDeployedMessage + def encode = ObjectDeployedMessage.encode(this) +} + +object ObjectDeployedMessage extends Marshallable[ObjectDeployedMessage] { + /** + * Overloaded constructor for when the guid is not required. + * @param desc descriptive text of what kind of object is being deployed + * @param unk na + * @param count the number of this type of object deployed + * @param max the maximum number of this type of object that can be deployed + * @return an `ObjectDeployedMessage` object + */ + def apply(desc : String, unk : Long, count : Long, max : Long) : ObjectDeployedMessage = + new ObjectDeployedMessage(PlanetSideGUID(0), desc, unk, count, max) + + implicit val codec : Codec[ObjectDeployedMessage] = ( + ("object_guid" | PlanetSideGUID.codec) :: + ("desc" | PacketHelpers.encodedString) :: + ("unk" | uint32L) :: + ("count" | uint32L) :: + ("max" | uint32L) + ).xmap[ObjectDeployedMessage] ( + { + case guid :: str :: unk :: cnt ::mx :: HNil => + ObjectDeployedMessage(guid, str, unk, cnt, mx) + }, + { + case ObjectDeployedMessage(guid, str, unk, cnt, mx) => + //truncate string length to 100 characters; raise no warnings + val limitedStr : String = if(str.length() > 100) { str.substring(0,100) } else { str } + guid :: limitedStr :: unk :: cnt :: mx :: HNil + } + ) +} diff --git a/common/src/test/scala/game/ObjectDeployedMessageTest.scala b/common/src/test/scala/game/ObjectDeployedMessageTest.scala new file mode 100644 index 000000000..1910ceea2 --- /dev/null +++ b/common/src/test/scala/game/ObjectDeployedMessageTest.scala @@ -0,0 +1,32 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import net.psforever.types.Vector3 +import scodec.bits._ + +class ObjectDeployedMessageTest extends Specification { + val string_boomer = hex"86 000086626F6F6D6572040000000100000019000000" + + "decode" in { + PacketCoding.DecodePacket(string_boomer).require match { + case ObjectDeployedMessage(guid : PlanetSideGUID, desc : String, unk : Long, count : Long, max : Long) => + guid mustEqual PlanetSideGUID(0) + desc mustEqual "boomer" + unk mustEqual 4 + count mustEqual 1 + max mustEqual 25 + case _ => + ko + } + } + + "encode" in { + val msg = ObjectDeployedMessage("boomer", 4, 1, 25) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string_boomer + } +}