diff --git a/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala b/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala index 30092e62..e4a6cb52 100644 --- a/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala +++ b/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala @@ -6,20 +6,25 @@ import net.psforever.types.Vector3 import scodec.Codec import scodec.codecs._ +/** PlayerStateMessageUpstream is constantly sent from the client to the server to update avatar properties. + * + * Note: seq_time appears to be used in other message definitions as well. It + * seems to represent a timestamp for ordering of e.g. player and weapon events. + */ final case class PlayerStateMessageUpstream(avatar_guid : PlanetSideGUID, pos : Vector3, vel : Option[Vector3], unk1 : Int, aim_pitch : Int, unk2 : Int, + seq_time : Int, unk3 : Int, - unk4 : Int, is_crouching : Boolean, + unk4 : Boolean, unk5 : Boolean, unk6 : Boolean, - unk7 : Boolean, - unk8 : Int, - unk9 : Int) + unk7 : Int, + unk8 : Int) extends PlanetSideGamePacket { type Packet = PlayerStateMessageUpstream def opcode = GamePacketOpcode.PlayerStateMessageUpstream @@ -34,13 +39,13 @@ object PlayerStateMessageUpstream extends Marshallable[PlayerStateMessageUpstrea ("unk1" | uint8L) :: ("aim_pitch" | uint8L) :: ("unk2" | uint8L) :: - ("unk3" | uintL(10)) :: - ("unk4" | uintL(3)) :: + ("seq_time" | uintL(10)) :: + ("unk3" | uintL(3)) :: ("is_crouching" | bool) :: + ("unk4" | bool) :: ("unk5" | bool) :: ("unk6" | bool) :: - ("unk7" | bool) :: - ("unk8" | uint8L) :: - ("unk9" | uint16L) + ("unk7" | uint8L) :: + ("unk8" | uint16L) ).as[PlayerStateMessageUpstream] } diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index da9aa495..2701ef80 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -441,21 +441,21 @@ class GamePacketTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { - case PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, unk3, unk4, is_crouching, unk5, unk6, unk7, unk8, unk9) => + case PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, unk4, unk5, unk6, unk7, unk8) => avatar_guid mustEqual PlanetSideGUID(75) pos mustEqual Vector3(3694.1094f, 2735.4531f, 90.84375f) vel mustEqual Some(Vector3(4.375f, 2.59375f, 0.0f)) unk1 mustEqual 10 aim_pitch mustEqual 3 unk2 mustEqual 0 - unk3 mustEqual 136 - unk4 mustEqual 0 + seq_time mustEqual 136 + unk3 mustEqual 0 is_crouching mustEqual false + unk4 mustEqual false unk5 mustEqual false unk6 mustEqual false - unk7 mustEqual false - unk8 mustEqual 112 - unk9 mustEqual 0 + unk7 mustEqual 112 + unk8 mustEqual 0 case default => ko } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 6fe09271..dee12365 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -145,7 +145,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case KeepAliveMessage(code) => sendResponse(PacketCoding.CreateGamePacket(0, KeepAliveMessage(0))) - case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, unk3, unk4, is_crouching, unk5, unk6, unk7, unk8, unk9) => + case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, unk4, unk5, unk6, unk7, unk8) => //log.info("PlayerState: " + msg) case msg @ ChatMsg(messagetype, unk1, recipient, contents) =>