From dfe449354a4813d49afd891a3ae5a06d5d943225 Mon Sep 17 00:00:00 2001 From: FateJH Date: Mon, 17 Oct 2016 20:58:33 -0400 Subject: [PATCH 1/2] identified a field for PlayerStateMessageUpstream; modified file and tests; comments --- .../game/PlayerStateMessageUpstream.scala | 36 +++++++++++++------ common/src/test/scala/GamePacketTest.scala | 8 ++--- 2 files changed, 30 insertions(+), 14 deletions(-) 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 e4a6cb52..471f3c62 100644 --- a/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala +++ b/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala @@ -6,10 +6,26 @@ 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. +/** + * Constantly sent from the client to the server to update player avatar properties.
+ *
+ * Exploration:
+ * `seq_time` appears to be used in other message definitions as well. + * It seems to represent a timestamp for ordering, e.g., player and weapon events. + * @param avatar_guid the player's GUID + * @param pos where the player is in the world + * @param vel how the player is moving + * @param unk1 na + * @param aim_pitch the vertical angle of viewing + * @param unk2 na + * @param seq_time na + * @param unk3 na + * @param is_crouching whether the player is crouched + * @param unk4 na + * @param unk5 na + * @param is_cloaking whether the player is cloaked (Infiltration Suit) + * @param unk6 na + * @param unk7 na */ final case class PlayerStateMessageUpstream(avatar_guid : PlanetSideGUID, pos : Vector3, @@ -22,9 +38,9 @@ final case class PlayerStateMessageUpstream(avatar_guid : PlanetSideGUID, is_crouching : Boolean, unk4 : Boolean, unk5 : Boolean, - unk6 : Boolean, - unk7 : Int, - unk8 : Int) + is_cloaking : Boolean, + unk6 : Int, + unk7 : Int) extends PlanetSideGamePacket { type Packet = PlayerStateMessageUpstream def opcode = GamePacketOpcode.PlayerStateMessageUpstream @@ -44,8 +60,8 @@ object PlayerStateMessageUpstream extends Marshallable[PlayerStateMessageUpstrea ("is_crouching" | bool) :: ("unk4" | bool) :: ("unk5" | bool) :: - ("unk6" | bool) :: - ("unk7" | uint8L) :: - ("unk8" | uint16L) + ("is_cloaking" | bool) :: + ("unk6" | uint8L) :: + ("unk7" | uint16L) ).as[PlayerStateMessageUpstream] } diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 2f7e8a11..19af621b 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -499,7 +499,7 @@ class GamePacketTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { - case PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, unk4, unk5, unk6, unk7, unk8) => + case PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, unk4, unk5, is_cloaking, unk6, unk7) => avatar_guid mustEqual PlanetSideGUID(75) pos mustEqual Vector3(3694.1094f, 2735.4531f, 90.84375f) vel mustEqual Some(Vector3(4.375f, 2.59375f, 0.0f)) @@ -511,9 +511,9 @@ class GamePacketTest extends Specification { is_crouching mustEqual false unk4 mustEqual false unk5 mustEqual false - unk6 mustEqual false - unk7 mustEqual 112 - unk8 mustEqual 0 + is_cloaking mustEqual false + unk6 mustEqual 112 + unk7 mustEqual 0 case default => ko } From 3a798264b2a2d8ae10298d68357683171c3ed43c Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 11 Jan 2017 11:03:15 -0500 Subject: [PATCH 2/2] changes to BuildingInfo, TimeOfDay, ZonePopulationUpdate, PlayerStateUpstream, and AvatarJump; TimeOfDay still makes no sense --- .../packet/game/AvatarJumpMessage.scala | 16 ++++++-- .../game/BuildingInfoUpdateMessage.scala | 2 - .../game/PlayerStateMessageUpstream.scala | 2 +- .../packet/game/TimeOfDayMessage.scala | 38 +++++++------------ .../game/ZonePopulationUpdateMessage.scala | 18 ++++----- common/src/test/scala/GamePacketTest.scala | 12 ++---- .../src/main/scala/WorldSessionActor.scala | 4 +- 7 files changed, 42 insertions(+), 50 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/AvatarJumpMessage.scala b/common/src/main/scala/net/psforever/packet/game/AvatarJumpMessage.scala index 1cc2d344..579919f2 100644 --- a/common/src/main/scala/net/psforever/packet/game/AvatarJumpMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/AvatarJumpMessage.scala @@ -6,6 +6,18 @@ import scodec.Codec import scodec.codecs._ import scodec.bits._ +/** + * Tell the server that the player is is jumping. + * This will allow it to coordinate animation with other clients.
+ *
+ * During the jump, the avatar's "height" coordinate does change, as reported in `PlayerStateMessageUpstream`. + * `PlayerStateMessage`, however, can depict another player with a proper jumping animation without the explicit coordinate change. + * The server must probably account for the distance to the ground when passing along data somehow.
+ *
+ * Exploration:
+ * Is `state` ever not `true`? + * @param state true + */ final case class AvatarJumpMessage(state : Boolean) extends PlanetSideGamePacket { type Packet = AvatarJumpMessage @@ -14,7 +26,5 @@ final case class AvatarJumpMessage(state : Boolean) } object AvatarJumpMessage extends Marshallable[AvatarJumpMessage] { - implicit val codec : Codec[AvatarJumpMessage] = ( - ("state" | bool) - ).as[AvatarJumpMessage] + implicit val codec : Codec[AvatarJumpMessage] = ("state" | bool).as[AvatarJumpMessage] } diff --git a/common/src/main/scala/net/psforever/packet/game/BuildingInfoUpdateMessage.scala b/common/src/main/scala/net/psforever/packet/game/BuildingInfoUpdateMessage.scala index 11510128..6e8b52ab 100644 --- a/common/src/main/scala/net/psforever/packet/game/BuildingInfoUpdateMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/BuildingInfoUpdateMessage.scala @@ -4,7 +4,6 @@ package net.psforever.packet.game import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} import scodec.Codec import scodec.codecs._ -import scodec.bits._ object PlanetSideGeneratorState extends Enumeration { type Type = Value @@ -66,7 +65,6 @@ object BuildingInfoUpdateMessage extends Marshallable[BuildingInfoUpdateMessage] ("unk5" | uint32L) :: ("unk6" | bool) :: ("unk7" | uint4L) :: //TODO: bool and uintL(2) follow if unk7 != 8 - ("boost_spawn_pain" | bool) :: ("boost_generator_pain" | bool) ).as[BuildingInfoUpdateMessage] 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 471f3c62..04a6fcf7 100644 --- a/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala +++ b/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala @@ -23,7 +23,7 @@ import scodec.codecs._ * @param is_crouching whether the player is crouched * @param unk4 na * @param unk5 na - * @param is_cloaking whether the player is cloaked (Infiltration Suit) + * @param is_cloaking whether the player is cloaked by virtue of an Infiltration Suit * @param unk6 na * @param unk7 na */ diff --git a/common/src/main/scala/net/psforever/packet/game/TimeOfDayMessage.scala b/common/src/main/scala/net/psforever/packet/game/TimeOfDayMessage.scala index 67d5d52a..a6ac86bc 100644 --- a/common/src/main/scala/net/psforever/packet/game/TimeOfDayMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/TimeOfDayMessage.scala @@ -6,8 +6,8 @@ import scodec.Codec import scodec.codecs._ /** - * Sets Auraxis time on the client. - * Use the slash-command /time to view the current time in the event window. + * Sets Auraxis time for a continent (zone) on the client. + * Use the slash-command `/time` to view the current time in the event window. * Auraxis time is represented as a standard military twenty-four hour clock, displayed in hours and minutes.
*
* Time is set per zone on map loading. @@ -21,26 +21,18 @@ import scodec.codecs._ * The current time is constrained to a looping twenty-four hour interval.
*
* If no time is set, the client starts counting from 10:00 at an initial rate of about one Auraxis minute every four or five real seconds. - * Setting the current time to 00 00 42 sets the current time to 00:00 with an indeterminate, but slow, rate. - * Time is normally initialized somewhere within an interval between 00 00 46 and FF FF 47. - * Setting the current time extremely high can cause psychedelic rendering as the current time overflows and the rate is too fast. - * (Setting the time to FF FF FF will reduce the rendering system to true gibberish.)
+ * Setting the current time to 1107296256 sets the current time to 00:00 with an indeterminate, but slow, rate. + * Time is normally initialized somewhere within an interval between 1174405120 and 1207959296. + * Setting the current time extremely high (near the numerical maximum) can cause psychedelic rendering. + * (Setting the time to 4294967040 exactly will reduce the rendering system to gibberish.)
*
- * The interval from 5E 39 46 (4602206, which is ~03:18) to 00 C0 47 (4702208, which is 03:18) is about a full twenty-four hours. - * Coincidentally, that is a count of 100002. - * @param unk1 consistently 00; does nothing? + * The interval from 1178164736 (~03:18) to 1203765248 (03:18) is about a full twenty-four hours. + * That is a count of 25600512. * @param time Auraxis time - * @param unk2 consistently 00; does nothing? - * @param unk3 consistently 00; does nothing? - * @param unk4 consistently 20; does nothing? - * @param unk5 consistently 41; does nothing? + * @param unk consistently 1092616192; does nothing? */ -final case class TimeOfDayMessage(unk1 : Int, - time : Int, - unk2 : Int, - unk3 : Int, - unk4 : Int, - unk5 : Int) +final case class TimeOfDayMessage(time : Long, + unk : Long = 1092616192L) extends PlanetSideGamePacket { type Packet = TimeOfDayMessage def opcode = GamePacketOpcode.TimeOfDayMessage @@ -49,12 +41,8 @@ final case class TimeOfDayMessage(unk1 : Int, object TimeOfDayMessage extends Marshallable[TimeOfDayMessage] { implicit val codec : Codec[TimeOfDayMessage] = ( - ("unk1" | uint8L) :: - ("time" | uintL(24)) :: - ("unk2" | uint8L) :: - ("unk3" | uint8L) :: - ("unk4" | uint8L) :: - ("unk5" | uint8L) + ("time" | uint32L) :: + ("unk" | uint32L) ).as[TimeOfDayMessage] } diff --git a/common/src/main/scala/net/psforever/packet/game/ZonePopulationUpdateMessage.scala b/common/src/main/scala/net/psforever/packet/game/ZonePopulationUpdateMessage.scala index 7be59000..4a1640d7 100644 --- a/common/src/main/scala/net/psforever/packet/game/ZonePopulationUpdateMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/ZonePopulationUpdateMessage.scala @@ -15,12 +15,12 @@ import scodec.codecs._ * This packet also shifts the flavor text for that zone.
*
* The size of zone's queue is the final upper population limit for that zone. - * Common values for the zone queue fields are 00 00 00 00 (locked) and 9E 01 00 00 (414 positions). + * Common values for the zone queue fields are 0 (locked) and 414 positions. * When a continent can not accept any players at all, a lock icon will appear over its view pane in the Interstellar View. * Setting the zone's queue to zero will also render this icon.
*
* The individual queue fields set the maximum empire occupancy for a zone that is represented in the zone Incentives text. - * Common values for the empire queue fields are 00 00 00 00 (locked population), 8A 00 00 00 (138 positions), and FA 01 00 00 (500 positions). + * Common values for the empire queue fields are 0 (locked population), 138 positions, and 500 positions. * Zone Incentives text, however, will never report more than a "100+" vacancy. * The actual limits are probably set based on server load. * The latter queue value is typical for VR area zones.
@@ -51,8 +51,8 @@ final case class ZonePopulationUpdateMessage(continent_guid : PlanetSideGUID, nc_pop : Long, vs_queue : Long, vs_pop : Long, - bo_queue : Long, - bo_pop : Long) + bo_queue : Long = 0L, + bo_pop : Long = 0L) extends PlanetSideGamePacket { type Packet = ZonePopulationUpdateMessage def opcode = GamePacketOpcode.ZonePopulationUpdateMessage @@ -62,10 +62,10 @@ final case class ZonePopulationUpdateMessage(continent_guid : PlanetSideGUID, object ZonePopulationUpdateMessage extends Marshallable[ZonePopulationUpdateMessage] { implicit val codec : Codec[ZonePopulationUpdateMessage] = ( ("continent_guid" | PlanetSideGUID.codec) :: - ("zone_queue" | ulongL(32)) :: - ("tr_queue" | ulongL(32)) :: ("tr_pop" | ulongL(32)) :: - ("nc_queue" | ulongL(32)) :: ("nc_pop" | ulongL(32)) :: - ("vs_queue" | ulongL(32)) :: ("vs_pop" | ulongL(32)) :: - ("bo_queue" | ulongL(32)) :: ("bo_pop" | ulongL(32)) + ("zone_queue" | uint32L) :: + ("tr_queue" | uint32L) :: ("tr_pop" | uint32L) :: + ("nc_queue" | uint32L) :: ("nc_pop" | uint32L) :: + ("vs_queue" | uint32L) :: ("vs_pop" | uint32L) :: + ("bo_queue" | uint32L) :: ("bo_pop" | uint32L) ).as[ZonePopulationUpdateMessage] } diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 19af621b..6ec97cc6 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -474,20 +474,16 @@ class GamePacketTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { - case TimeOfDayMessage(unk1, time, unk2, unk3, unk4, unk5) => - unk1 mustEqual 0 - time mustEqual 4653056 - unk2 mustEqual 0 - unk3 mustEqual 0 - unk4 mustEqual 32 - unk5 mustEqual 65 + case TimeOfDayMessage(time, unk) => + time mustEqual 1191182336 + unk mustEqual 1092616192 case default => ko } } "encode" in { - val msg = TimeOfDayMessage(0, 4653056, 0, 0, 32, 65) + val msg = TimeOfDayMessage(1191182336) 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 ea99a03c..f132c424 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 { sendResponse(PacketCoding.CreateGamePacket(0, SetEmpireMessage(PlanetSideGUID(2), PlanetSideEmpire.VS))) //HART building C sendResponse(PacketCoding.CreateGamePacket(0, SetEmpireMessage(PlanetSideGUID(29), PlanetSideEmpire.NC))) //South Villa Gun Tower - sendResponse(PacketCoding.CreateGamePacket(0, TimeOfDayMessage(0, 4653056, 0, 0, 32, 65))) + sendResponse(PacketCoding.CreateGamePacket(0, TimeOfDayMessage(1191182336))) sendResponse(PacketCoding.CreateGamePacket(0, ContinentalLockUpdateMessage(PlanetSideGUID(13), PlanetSideEmpire.VS))) // "The VS have captured the VS Sanctuary." sendResponse(PacketCoding.CreateGamePacket(0, BroadcastWarpgateUpdateMessage(PlanetSideGUID(13), PlanetSideGUID(1), 32))) // VS Sanctuary: Inactive Warpgate -> Broadcast Warpgate @@ -189,7 +189,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, seq_time, unk3, is_crouching, unk4, unk5, unk6, unk7, unk8) => + case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, unk4, unk5, is_cloaking, unk6, unk7) => //log.info("PlayerState: " + msg) case msg @ ChatMsg(messagetype, has_wide_contents, recipient, contents, note_contents) =>