From e2dcf998e0a9f648c43de563a54583bbcba1653c Mon Sep 17 00:00:00 2001 From: FateJH Date: Fri, 18 May 2018 10:29:46 -0400 Subject: [PATCH] in an attempt to decipher the pickup sound, it seems every item pickup comes with a 'congratulations' packet --- .../packet/game/ActionResultMessage.scala | 13 ++++- .../scala/game/ActionResultMessageTest.scala | 57 ++++++++++++++----- .../src/main/scala/WorldSessionActor.scala | 1 + 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/ActionResultMessage.scala b/common/src/main/scala/net/psforever/packet/game/ActionResultMessage.scala index e90d5210..fe7f0b44 100644 --- a/common/src/main/scala/net/psforever/packet/game/ActionResultMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/ActionResultMessage.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017 PSForever package net.psforever.packet.game -import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} import scodec.Codec import scodec.codecs._ @@ -10,7 +10,8 @@ import scodec.codecs._ * Is sent by the server when the client has performed an action from a menu item * (i.e create character, delete character, etc...) */ -final case class ActionResultMessage(successfull : Boolean, errorCode : Option[Long]) +final case class ActionResultMessage(successful : Boolean, + errorCode : Option[Long]) extends PlanetSideGamePacket { type Packet = ActionResultMessage def opcode = GamePacketOpcode.ActionResultMessage @@ -18,6 +19,14 @@ final case class ActionResultMessage(successfull : Boolean, errorCode : Option[L } object ActionResultMessage extends Marshallable[ActionResultMessage] { + def apply() : ActionResultMessage = { + ActionResultMessage(true, None) + } + + def apply(error : Long) : ActionResultMessage = { + ActionResultMessage(false, Some(error)) + } + implicit val codec : Codec[ActionResultMessage] = ( ("successful" | bool) >>:~ { res => // if not successful, look for an error code diff --git a/common/src/test/scala/game/ActionResultMessageTest.scala b/common/src/test/scala/game/ActionResultMessageTest.scala index c8ee8eb2..a6bce43c 100644 --- a/common/src/test/scala/game/ActionResultMessageTest.scala +++ b/common/src/test/scala/game/ActionResultMessageTest.scala @@ -7,27 +7,54 @@ import net.psforever.packet.game._ import scodec.bits._ class ActionResultMessageTest extends Specification { - "decode" in { - PacketCoding.DecodePacket(hex"1f 80").require match { - case ActionResultMessage(okay, code) => - okay === true - code === None - case _ => - ko - } + val string_pass = hex"1f 80" + val string_fail = hex"1f 0080000000" - PacketCoding.DecodePacket((hex"1f".bits ++ bin"0" ++ hex"01000000".bits).toByteVector).require match { + "decode (pass)" in { + PacketCoding.DecodePacket(string_pass).require match { case ActionResultMessage(okay, code) => - okay === false - code === Some(1) + okay mustEqual true + code mustEqual None case _ => ko } } - "encode" in { - PacketCoding.EncodePacket(ActionResultMessage(true, None)).require.toByteVector === hex"1f 80" - PacketCoding.EncodePacket(ActionResultMessage(false, Some(1))).require.toByteVector === - (hex"1f".bits ++ bin"0" ++ hex"01000000".bits).toByteVector + "decode (fail)" in { + PacketCoding.DecodePacket(string_fail).require match { + case ActionResultMessage(okay, code) => + okay mustEqual false + code mustEqual Some(1) + case _ => + ko + } + } + + "encode (pass, full)" in { + val msg = ActionResultMessage(true, None) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string_pass + } + + "encode (pass, minimal)" in { + val msg = ActionResultMessage() + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string_pass + } + + "encode (fail, full)" in { + val msg = ActionResultMessage(false, Some(1)) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string_fail + } + + "encode (fail, minimal)" in { + val msg = ActionResultMessage(1) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string_fail } } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index b598e867..1a52cb10 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -1403,6 +1403,7 @@ class WorldSessionActor extends Actor with MDCContextAware { definition.Packet.DetailedConstructorData(item).get ) ) + sendResponse(ActionResultMessage()) if(tplayer.VisibleSlots.contains(slot)) { avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentInHand(player_guid, player_guid, slot, item)) }