From 51b0b6905dce53bef6d4bc26dc4c3bea8bbb6377 Mon Sep 17 00:00:00 2001 From: FateJH Date: Fri, 30 Sep 2016 10:05:46 -0400 Subject: [PATCH 1/3] initial AvatarGrenadeStateMessage packet --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../game/AvatarGrenadeStateMessage.scala | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 6e9984e5..43a6d436 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -519,7 +519,7 @@ object GamePacketOpcode extends Enumeration { case 0xa7 => noDecoder(GenericActionMessage) // 0xa8 case 0xa8 => game.ContinentalLockUpdateMessage.decode - case 0xa9 => noDecoder(AvatarGrenadeStateMessage) + case 0xa9 => game.AvatarGrenadeStateMessage.decode case 0xaa => noDecoder(UnknownMessage170) case 0xab => noDecoder(UnknownMessage171) case 0xac => noDecoder(ReleaseAvatarRequestMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala b/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala new file mode 100644 index 00000000..652fca18 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala @@ -0,0 +1,40 @@ +// 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._ + +object GrenadeState extends Enumeration { + type Type = Value + val unk0, + PRIMED, + THROWN, + unk3 + = Value + + implicit val codec = PacketHelpers.createEnumerationCodec(this, uintL(1)) +} + +/** + * na + * @param player_guid the player + * @param count the state + */ +//case msg @ AvatarGrenadeStateMessage(player_guid, state) => +//log.info("AvatarGrenadeStateMessage: " + msg) +final case class AvatarGrenadeStateMessage(player_guid : PlanetSideGUID, + count : GrenadeState.Value) + extends PlanetSideGamePacket { + type Packet = AvatarGrenadeStateMessage + def opcode = GamePacketOpcode.AvatarGrenadeStateMessage + def encode = AvatarGrenadeStateMessage.encode(this) +} + +object AvatarGrenadeStateMessage extends Marshallable[AvatarGrenadeStateMessage] { + implicit val codec : Codec[AvatarGrenadeStateMessage] = ( + ("player_guid" | PlanetSideGUID.codec) :: + ("state" | GrenadeState.codec) + ).as[AvatarGrenadeStateMessage] +} + From e6c5f54647fd21ea19afaf7c257295e4fec03198 Mon Sep 17 00:00:00 2001 From: FateJH Date: Fri, 30 Sep 2016 13:52:44 -0400 Subject: [PATCH 2/3] slight file modifications; added tests --- .../game/AvatarGrenadeStateMessage.scala | 31 +++++++------------ common/src/test/scala/GamePacketTest.scala | 21 +++++++++++++ .../src/main/scala/WorldSessionActor.scala | 3 ++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala b/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala index 652fca18..77ad80d3 100644 --- a/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala @@ -1,30 +1,24 @@ // Copyright (c) 2016 PSForever.net to present 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._ -object GrenadeState extends Enumeration { - type Type = Value - val unk0, - PRIMED, - THROWN, - unk3 - = Value - - implicit val codec = PacketHelpers.createEnumerationCodec(this, uintL(1)) -} - /** - * na + * Report the state of the "grenade throw" animation for this player.
+ *
+ * States:
+ * 1 - prepare for throwing (grenade held back over shoulder)
+ * 2 - throwing (grenade released overhand)
+ *
+ * Exploration:
+ * How many grenade states are possible? * @param player_guid the player - * @param count the state + * @param state the animation state */ -//case msg @ AvatarGrenadeStateMessage(player_guid, state) => -//log.info("AvatarGrenadeStateMessage: " + msg) final case class AvatarGrenadeStateMessage(player_guid : PlanetSideGUID, - count : GrenadeState.Value) + state : Int) extends PlanetSideGamePacket { type Packet = AvatarGrenadeStateMessage def opcode = GamePacketOpcode.AvatarGrenadeStateMessage @@ -34,7 +28,6 @@ final case class AvatarGrenadeStateMessage(player_guid : PlanetSideGUID, object AvatarGrenadeStateMessage extends Marshallable[AvatarGrenadeStateMessage] { implicit val codec : Codec[AvatarGrenadeStateMessage] = ( ("player_guid" | PlanetSideGUID.codec) :: - ("state" | GrenadeState.codec) + ("state" | uint8L) ).as[AvatarGrenadeStateMessage] } - diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 2f7e8a11..31943426 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -681,6 +681,27 @@ class GamePacketTest extends Specification { } } + "AvatarGrenadeStateMessage" should { + val string = hex"A9 DA11 01" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case AvatarGrenadeStateMessage(player_guid, state) => + player_guid mustEqual PlanetSideGUID(4570) + state mustEqual 1 + case default => + ko + } + } + + "encode" in { + val msg = AvatarGrenadeStateMessage(PlanetSideGUID(4570), 1) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } + } + "BroadcastWarpgateUpdateMessage" should { val string = hex"D9 0D 00 01 00 20" diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index ea99a03c..aa725ffe 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -274,6 +274,9 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ AvatarFirstTimeEventMessage(avatar_guid, object_guid, unk1, event_name) => log.info("AvatarFirstTimeEvent: " + msg) + case msg @ AvatarGrenadeStateMessage(player_guid, state) => + log.info("AvatarGrenadeStateMessage: " + msg) + case default => log.debug(s"Unhandled GamePacket ${pkt}") } From 2ae217caf128e4a18525add0dd50a0bb90d2e960 Mon Sep 17 00:00:00 2001 From: FateJH Date: Fri, 27 Jan 2017 00:01:42 -0500 Subject: [PATCH 3/3] changes made to grenade states --- .../game/AvatarGrenadeStateMessage.scala | 42 +++++++++++++++---- common/src/test/scala/GamePacketTest.scala | 4 +- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala b/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala index 77ad80d3..08e9e27d 100644 --- a/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/AvatarGrenadeStateMessage.scala @@ -1,24 +1,48 @@ // Copyright (c) 2016 PSForever.net to present package net.psforever.packet.game -import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} import scodec.Codec import scodec.codecs._ /** - * Report the state of the "grenade throw" animation for this player.
+ * An `Enumeration` of the kinds of states applicable to the grenade animation. + */ +object GrenadeState extends Enumeration { + type Type = Value + val UNK0, + PRIMED, //avatars and other depicted player characters + THROWN //avatars only + = Value + + implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L) +} + +/** + * Report the state of the grenade throw animation for this player. + * The default state is "held at side," though the client's avatar never has to announce this.
+ *
+ * The throwing animation has a minor timing glitch. + * Causing another player to raise his arm will always result in that arm being lowered a few seconds later. + * This is as opposed to the client's avatar, who can seem to hold a grenade in the "prepare to throw" state indefinitely. + * If the avatar looks away from a player whose grenade arm is up ("prepare to throw"), however, when they look back at the player + * his grenade arm will occasionally have been lowered ("held at side") again before it would normally be lowered.
+ *
+ * A client will dispatch state '1' and state '2' for the avatar's actions. + * A client will only react temporarily for another character other than the avatar when the given a state '1'. + * If that internal state is not changed, however, that other character will not respond to any subsequent '1' state. + * (This may also be a glitch.)
*
* States:
- * 1 - prepare for throwing (grenade held back over shoulder)
- * 2 - throwing (grenade released overhand)
- *
- * Exploration:
- * How many grenade states are possible? + * ` + * 1 - prepare to throw (grenade held back over shoulder)
+ * 2 - throwing (grenade released overhand and then reset) (avatar only)
+ * ` * @param player_guid the player * @param state the animation state */ final case class AvatarGrenadeStateMessage(player_guid : PlanetSideGUID, - state : Int) + state : GrenadeState.Value) extends PlanetSideGamePacket { type Packet = AvatarGrenadeStateMessage def opcode = GamePacketOpcode.AvatarGrenadeStateMessage @@ -28,6 +52,6 @@ final case class AvatarGrenadeStateMessage(player_guid : PlanetSideGUID, object AvatarGrenadeStateMessage extends Marshallable[AvatarGrenadeStateMessage] { implicit val codec : Codec[AvatarGrenadeStateMessage] = ( ("player_guid" | PlanetSideGUID.codec) :: - ("state" | uint8L) + ("state" | GrenadeState.codec) ).as[AvatarGrenadeStateMessage] } diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 31943426..00810ce4 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -688,14 +688,14 @@ class GamePacketTest extends Specification { PacketCoding.DecodePacket(string).require match { case AvatarGrenadeStateMessage(player_guid, state) => player_guid mustEqual PlanetSideGUID(4570) - state mustEqual 1 + state mustEqual GrenadeState.PRIMED case default => ko } } "encode" in { - val msg = AvatarGrenadeStateMessage(PlanetSideGUID(4570), 1) + val msg = AvatarGrenadeStateMessage(PlanetSideGUID(4570), GrenadeState.PRIMED) val pkt = PacketCoding.EncodePacket(msg).require.toByteVector pkt mustEqual string