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) =>