diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 38f4d140..1f0eb2a5 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -370,7 +370,7 @@ object GamePacketOpcode extends Enumeration { case 0x29 => game.ChangeShortcutBankMessage.decode case 0x2a => game.ObjectAttachMessage.decode case 0x2b => noDecoder(UnknownMessage43) - case 0x2c => noDecoder(PlanetsideAttributeMessage) + case 0x2c => game.PlanetsideAttributeMessage.decode case 0x2d => game.RequestDestroyMessage.decode case 0x2e => noDecoder(UnknownMessage46) case 0x2f => game.CharacterCreateRequestMessage.decode diff --git a/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala b/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala new file mode 100644 index 00000000..0818c906 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala @@ -0,0 +1,59 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +/** + * Attribute Type:
+ * Server to client :
+ * `0 - health`
+ * `1 - healthMax`
+ * `2 - stamina`
+ * `3 - staminaMax`
+ * `4 - armor`
+ * `5 - armorMax`
+ * `14 - Something with grief`
+ * `15 - Weapon Lock. Value exemple : 600 to have 1 min lock. Max possible is 30min lock`
+ * `17 - BEP. Value seems to be the same as BattleExperienceMessage`
+ * `18 - CEP.`
+ * `19 - Anchors. Value is 0 to disengage, 1 to engage.`
+ * `24 - Certifications`
+ * `29 - Visible ?! That's not the cloaked effect, Maybe for spectator mode ?. Value is 0 to visible, 1 to invisible.`
+ * `35 - BR. Value is the BR`
+ * `36 - CR. Value is the CR`
+ * `53 - LFS. Value is 1 to flag LFS`
+ * `54 - Player "Aura". Values are : 0 for nothing, 1 for plasma, 2 for ancient, 3 for plasma + ancient,
+ * 4 for LLU?, 5 for plasma + LLU?, 6 for ancient + LLU?, 7 for plasma + ancient + LLU?, 8 for fire,
+ * 9 for plasma + fire, 10 for ancient + fire, 11 for plasma + ancient + fire,
+ * 12 for LLU? + fire, 13 for plasma + LLU? + fire, 14 for ancient + LLU? + fire,
+ * 15 for plasma + ancient + LLU? + fire,`
+ * `55 - "Someone is attempting to Heal you". Value is 1`
+ * `56 - "Someone is attempting to Repair you". Value is 1`
+ * `73 - "You are locked into the Core Beam. Charging your Module now.". Value is 1 to active`
+ * `77 - Cavern Facility Captures. Value is the number of captures`
+ * `78 - Cavern Kills. Value is the number of kills`
+ * `106 - Custom Head` + * Client to Server :
+ * `106 - Custom Head` + * @param player_guid the player + * @param attribute_type na + * @param attribute_value na + */ +final case class PlanetsideAttributeMessage(player_guid : PlanetSideGUID, + attribute_type : Int, + attribute_value : Long) + extends PlanetSideGamePacket { + type Packet = PlanetsideAttributeMessage + def opcode = GamePacketOpcode.PlanetsideAttributeMessage + def encode = PlanetsideAttributeMessage.encode(this) +} + +object PlanetsideAttributeMessage extends Marshallable[PlanetsideAttributeMessage] { + implicit val codec : Codec[PlanetsideAttributeMessage] = ( + ("player_guid" | PlanetSideGUID.codec) :: + ("attribute_type" | uint8L) :: + ("attribute_value" | uint32L) + ).as[PlanetsideAttributeMessage] +} \ No newline at end of file diff --git a/common/src/test/scala/game/PlanetsideAttributeMessageTest.scala b/common/src/test/scala/game/PlanetsideAttributeMessageTest.scala new file mode 100644 index 00000000..0706bfa7 --- /dev/null +++ b/common/src/test/scala/game/PlanetsideAttributeMessageTest.scala @@ -0,0 +1,30 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable.Specification +import net.psforever.packet.PacketCoding +import net.psforever.packet.game._ +import scodec.bits._ + +class PlanetsideAttributeMessageTest extends Specification { + val string = hex"2c d9040458000000" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case PlanetsideAttributeMessage(player_guid, attribute_type, attribute_value) => + player_guid mustEqual PlanetSideGUID(1241) + attribute_type mustEqual 4 + attribute_value mustEqual 88 + case _ => + ko + } + } + + "encode" in { + val msg = PlanetsideAttributeMessage(PlanetSideGUID(1241), 4, 88) + 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 40da1943..7e87ab8b 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -392,6 +392,10 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ BindPlayerMessage(action, bindDesc, unk1, logging, unk2, unk3, unk4, pos) => log.info("BindPlayerMessage: " + msg) + case msg @ PlanetsideAttributeMessage(avatar_guid, attribute_type, attribute_value) => + log.info("PlanetsideAttributeMessage: "+msg) + sendResponse(PacketCoding.CreateGamePacket(0,PlanetsideAttributeMessage(avatar_guid, attribute_type, attribute_value))) + case default => log.error(s"Unhandled GamePacket ${pkt}") }