diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 4857fa52..ac612f1c 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -363,7 +363,7 @@ object GamePacketOpcode extends Enumeration { case 0x23 => noDecoder(ActionCancelAcknowledgeMessage) case 0x24 => game.SetEmpireMessage.decode case 0x25 => game.EmoteMsg.decode - case 0x26 => noDecoder(UnuseItemMessage) + case 0x26 => game.UnuseItemMessage.decode case 0x27 => game.ObjectDetachMessage.decode // 0x28 case 0x28 => game.CreateShortcutMessage.decode diff --git a/common/src/main/scala/net/psforever/packet/game/UnuseItemMessage.scala b/common/src/main/scala/net/psforever/packet/game/UnuseItemMessage.scala new file mode 100644 index 00000000..63433ded --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/UnuseItemMessage.scala @@ -0,0 +1,30 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +/** + * Dispatched by the client when its player is done using something.
+ *
+ * The common example is sifting through backpacks, an activity that only one player is allowed to do at a time. + * When a backpack is accessed by one player, other players are blocked. + * When the first player is done accessing the backpack, this packet informs the server so other players may be allowed access. + * @param player_guid the player + * @param item_guid the item + */ +final case class UnuseItemMessage(player_guid : PlanetSideGUID, + item_guid : PlanetSideGUID) + extends PlanetSideGamePacket { + type Packet = UnuseItemMessage + def opcode = GamePacketOpcode.UnuseItemMessage + def encode = UnuseItemMessage.encode(this) +} + +object UnuseItemMessage extends Marshallable[UnuseItemMessage] { + implicit val codec : Codec[UnuseItemMessage] = ( + ("player_guid" | PlanetSideGUID.codec) :: + ("item_guid" | PlanetSideGUID.codec) + ).as[UnuseItemMessage] +} diff --git a/common/src/test/scala/game/UnuseItemMessageTest.scala b/common/src/test/scala/game/UnuseItemMessageTest.scala new file mode 100644 index 00000000..c4b08213 --- /dev/null +++ b/common/src/test/scala/game/UnuseItemMessageTest.scala @@ -0,0 +1,28 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class UnuseItemMessageTest extends Specification { + val string = hex"26 4B00 340D" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case UnuseItemMessage(player, item) => + player mustEqual PlanetSideGUID(75) + item mustEqual PlanetSideGUID(3380) + case _ => + ko + } + } + + "encode" in { + val msg = UnuseItemMessage(PlanetSideGUID(75), PlanetSideGUID(3380)) + 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 3a7cd910..852833d5 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -190,7 +190,7 @@ class WorldSessionActor extends Actor with MDCContextAware { log.debug("Object: " + obj) // LoadMapMessage 13714 in mossy .gcap // XXX: hardcoded shit - sendResponse(PacketCoding.CreateGamePacket(0, LoadMapMessage("map10","z10",40100,25,true,3770441820L))) //VS Sanctuary + sendResponse(PacketCoding.CreateGamePacket(0, LoadMapMessage("map13","home3",40100,25,true,3770441820L))) //VS Sanctuary sendResponse(PacketCoding.CreateGamePacket(0, ZonePopulationUpdateMessage(PlanetSideGUID(13), 414, 138, 0, 138, 0, 138, 0, 138, 0))) sendResponse(PacketCoding.CreateGamePacket(0, objectHex)) @@ -364,6 +364,9 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, GenericObjectStateMsg(object_guid, 16))) } + case msg @ UnuseItemMessage(player, item) => + log.info("UnuseItem: " + msg) + case msg @ GenericObjectStateMsg(object_guid, unk1) => log.info("GenericObjectState: " + msg)