changing the conditions for the original first int value, and the conditions for the last int value; rewrote tests

This commit is contained in:
FateJH 2017-01-11 23:56:38 -05:00
parent 66a0ebe24b
commit 4143732977
2 changed files with 57 additions and 69 deletions

View file

@ -3,7 +3,7 @@ package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import net.psforever.types.Vector3 import net.psforever.types.Vector3
import scodec.Codec import scodec.{Attempt, Codec, Err}
import scodec.codecs._ import scodec.codecs._
import shapeless.{::, HNil} import shapeless.{::, HNil}
@ -25,13 +25,15 @@ import shapeless.{::, HNil}
* stopping in an invalid part of the range will cause the avatar to align to the __earliest__ still-valid 60-degree mark. * stopping in an invalid part of the range will cause the avatar to align to the __earliest__ still-valid 60-degree mark.
* For that reason, even if the avatar's final angle is closest to the "left mark," it may re-align to the "right mark." * For that reason, even if the avatar's final angle is closest to the "left mark," it may re-align to the "right mark."
* This also resets the avatar's angular displacement. * This also resets the avatar's angular displacement.
* @param unk na
* @param pos the position to move the character to in the world environment * @param pos the position to move the character to in the world environment
* @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect) * @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect)
* @param vel if defined, the velocity to apply to to the character at the given position * @param vel if defined, the velocity to apply to to the character at the given position
*/ */
final case class ShiftState(pos : Vector3, final case class ShiftState(unk : Int,
viewYawLim : Int, pos : Vector3,
vel : Option[Vector3]) viewYawLim : Int,
vel : Option[Vector3])
/** /**
* Push specific motion-based stimuli on a specific character.<br> * Push specific motion-based stimuli on a specific character.<br>
@ -41,18 +43,12 @@ final case class ShiftState(pos : Vector3,
* `PlayerStateShiftMessage` involves data transmitted from the server to a client about that client's avatar. * `PlayerStateShiftMessage` involves data transmitted from the server to a client about that client's avatar.
* It temporarily asserts itself before normal player movement and asserts specific placement and motion. * It temporarily asserts itself before normal player movement and asserts specific placement and motion.
* An application of this packet is being `/warp`ed within a zone via a non-triggering agent (like a teleporter). * An application of this packet is being `/warp`ed within a zone via a non-triggering agent (like a teleporter).
* Another, more common, application of this packet is being thrown about when the target of an attempted roadkill.<br> * Another, more common, application of this packet is being thrown about when the target of an attempted roadkill.
* <br>
* Exploration:<br>
* What do the leading and trailing values do?
* @param unk1 na;
* seems to have different purposes depending on whether `state` is defined
* @param state if defined, the behaviors to influence the character * @param state if defined, the behaviors to influence the character
* @param unk2 na * @param unk na
*/ */
final case class PlayerStateShiftMessage(unk1 : Int, final case class PlayerStateShiftMessage(state : Option[ShiftState],
state : Option[ShiftState], unk : Option[Int] = None)
unk2 : Boolean)
extends PlanetSideGamePacket { extends PlanetSideGamePacket {
type Packet = TimeOfDayMessage type Packet = TimeOfDayMessage
def opcode = GamePacketOpcode.PlayerStateShiftMessage def opcode = GamePacketOpcode.PlayerStateShiftMessage
@ -62,42 +58,38 @@ final case class PlayerStateShiftMessage(unk1 : Int,
object ShiftState extends Marshallable[ShiftState] { object ShiftState extends Marshallable[ShiftState] {
/** /**
* An abbreviated constructor for creating `ShiftState`, assuming velocity is not applied. * An abbreviated constructor for creating `ShiftState`, assuming velocity is not applied.
* @param unk na
* @param pos the position of the character in the world environment * @param pos the position of the character in the world environment
* @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect) * @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect)
* @param vel the velocity to apply to to the character at the given position * @param vel the velocity to apply to to the character at the given position
* @return a `ShiftState` object * @return a `ShiftState` object
*/ */
def apply(pos : Vector3, viewYawLim : Int, vel : Vector3) : ShiftState = def apply(unk : Int, pos : Vector3, viewYawLim : Int, vel : Vector3) : ShiftState =
ShiftState(pos, viewYawLim, Some(vel)) ShiftState(unk, pos, viewYawLim, Some(vel))
/** /**
* An abbreviated constructor for creating `ShiftState`, removing the optional condition of all parameters. * An abbreviated constructor for creating `ShiftState`, removing the optional condition of all parameters.
* @param unk na
* @param pos the position of the character in the world environment * @param pos the position of the character in the world environment
* @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect) * @param viewYawLim an angle with respect to the horizon towards which the avatar is looking (to some respect)
* @return a `ShiftState` object * @return a `ShiftState` object
*/ */
def apply(pos : Vector3, viewYawLim : Int) : ShiftState = def apply(unk : Int, pos : Vector3, viewYawLim : Int) : ShiftState =
ShiftState(pos, viewYawLim, None) ShiftState(unk, pos, viewYawLim, None)
implicit val codec : Codec[ShiftState] = ( implicit val codec : Codec[ShiftState] = (
("unk1" | uintL(3)) ::
("pos" | Vector3.codec_pos) :: ("pos" | Vector3.codec_pos) ::
("unk2" | uint8L) :: ("viewYawLim" | uint8L) ::
(bool >>:~ { test => optional(bool, "pos" | Vector3.codec_vel)
ignore(0) ::
conditional(test, "pos" | Vector3.codec_vel)
})
).xmap[ShiftState] ( ).xmap[ShiftState] (
{ {
case a :: b :: false :: _ :: None :: HNil => case a :: b :: c :: d :: HNil =>
ShiftState(a, b, None) ShiftState(a, b, c, d)
case a :: b :: true :: _ :: Some(vel) :: HNil =>
ShiftState(a, b, Some(vel))
}, },
{ {
case ShiftState(a, b, None) => case ShiftState(a, b, c, d) =>
a :: b :: false :: () :: None :: HNil a :: b :: c :: d :: HNil
case ShiftState(a, b, Some(vel)) =>
a :: b :: true :: () :: Some(vel) :: HNil
} }
).as[ShiftState] ).as[ShiftState]
} }
@ -105,40 +97,40 @@ object ShiftState extends Marshallable[ShiftState] {
object PlayerStateShiftMessage extends Marshallable[PlayerStateShiftMessage] { object PlayerStateShiftMessage extends Marshallable[PlayerStateShiftMessage] {
/** /**
* An abbreviated constructor for creating `PlayerStateShiftMessage`, removing the optional condition of `state`. * An abbreviated constructor for creating `PlayerStateShiftMessage`, removing the optional condition of `state`.
* @param unk1 na
* @param state the behaviors to influence the character * @param state the behaviors to influence the character
* @param unk2 na * @param unk na
* @return a `PlayerStateShiftMessage` packet * @return a `PlayerStateShiftMessage` packet
*/ */
def apply(unk1 : Int, state : ShiftState, unk2 : Boolean) : PlayerStateShiftMessage = def apply(state : ShiftState, unk : Int) : PlayerStateShiftMessage =
PlayerStateShiftMessage(unk1, Some(state), unk2) PlayerStateShiftMessage(Some(state), Some(unk))
/** /**
* An abbreviated constructor for creating `PlayerStateShiftMessage`, assuming the parameter `state` is not defined. * An abbreviated constructor for creating `PlayerStateShiftMessage`, removing the optional condition of `unk2`.
* @param unk1 na * @param state the behaviors to influence the character
* @param unk2 na
* @return a `PlayerStateShiftMessage` packet * @return a `PlayerStateShiftMessage` packet
*/ */
def apply(unk1 : Int, unk2 : Boolean) : PlayerStateShiftMessage = def apply(state : ShiftState) : PlayerStateShiftMessage =
PlayerStateShiftMessage(unk1, None, unk2) PlayerStateShiftMessage(Some(state), None)
/**
* An abbreviated constructor for creating `PlayerStateShiftMessage`, assuming the parameters `unk1` and `state` are not defined.
* @param unk na
* @return a `PlayerStateShiftMessage` packet
*/
def apply(unk : Int) : PlayerStateShiftMessage =
PlayerStateShiftMessage(None, Some(unk))
implicit val codec : Codec[PlayerStateShiftMessage] = ( implicit val codec : Codec[PlayerStateShiftMessage] = (
bool >>:~ { test => optional(bool, "state" | ShiftState.codec) ::
("unk1" | uintL(3)) :: optional(bool, "unk" | uintL(3))
conditional(test, "state" | ShiftState.codec) :: ).xmap[PlayerStateShiftMessage] (
("unk2" | bool)
}).xmap[PlayerStateShiftMessage] (
{ {
case false :: a :: None :: b :: HNil => case a :: b :: HNil =>
PlayerStateShiftMessage(a, None, b) PlayerStateShiftMessage(a, b)
case true :: a :: Some(pos) :: b :: HNil =>
PlayerStateShiftMessage(a, Some(pos), b)
}, },
{ {
case PlayerStateShiftMessage(a, None, b) => case PlayerStateShiftMessage(a, b) =>
false :: a :: None :: b :: HNil a :: b :: HNil
case PlayerStateShiftMessage(a, Some(pos), b) =>
true :: a :: Some(pos) :: b :: HNil
} }
).as[PlayerStateShiftMessage] ).as[PlayerStateShiftMessage]
} }

View file

@ -534,10 +534,10 @@ class GamePacketTest extends Specification {
"decode (short)" in { "decode (short)" in {
PacketCoding.DecodePacket(string_short).require match { PacketCoding.DecodePacket(string_short).require match {
case PlayerStateShiftMessage(unk1, state, unk2) => case PlayerStateShiftMessage(state, unk) =>
unk1 mustEqual 6
state.isDefined mustEqual false state.isDefined mustEqual false
unk2 mustEqual true unk.isDefined mustEqual true
unk.get mustEqual 5
case _ => case _ =>
ko ko
} }
@ -545,15 +545,15 @@ class GamePacketTest extends Specification {
"decode (pos)" in { "decode (pos)" in {
PacketCoding.DecodePacket(string_pos).require match { PacketCoding.DecodePacket(string_pos).require match {
case PlayerStateShiftMessage(unk1, state, unk2) => case PlayerStateShiftMessage(state, unk) =>
unk1 mustEqual 1
state.isDefined mustEqual true state.isDefined mustEqual true
state.get.unk mustEqual 1
state.get.pos.x mustEqual 4624.703f state.get.pos.x mustEqual 4624.703f
state.get.pos.y mustEqual 5922.1484f state.get.pos.y mustEqual 5922.1484f
state.get.pos.z mustEqual 46.171875f state.get.pos.z mustEqual 46.171875f
state.get.viewYawLim mustEqual 255 state.get.viewYawLim mustEqual 255
state.get.vel.isDefined mustEqual false state.get.vel.isDefined mustEqual false
unk2 mustEqual false unk.isDefined mustEqual false
case _ => case _ =>
ko ko
} }
@ -561,9 +561,9 @@ class GamePacketTest extends Specification {
"decode (pos and vel)" in { "decode (pos and vel)" in {
PacketCoding.DecodePacket(string_posAndVel).require match { PacketCoding.DecodePacket(string_posAndVel).require match {
case PlayerStateShiftMessage(unk1, state, unk2) => case PlayerStateShiftMessage(state, unk) =>
unk1 mustEqual 2
state.isDefined mustEqual true state.isDefined mustEqual true
state.get.unk mustEqual 2
state.get.pos.x mustEqual 4645.75f state.get.pos.x mustEqual 4645.75f
state.get.pos.y mustEqual 5811.6016f state.get.pos.y mustEqual 5811.6016f
state.get.pos.z mustEqual 50.3125f state.get.pos.z mustEqual 50.3125f
@ -572,32 +572,28 @@ class GamePacketTest extends Specification {
state.get.vel.get.x mustEqual 2.8125f state.get.vel.get.x mustEqual 2.8125f
state.get.vel.get.y mustEqual -8.0f state.get.vel.get.y mustEqual -8.0f
state.get.vel.get.z mustEqual 0.375f state.get.vel.get.z mustEqual 0.375f
unk2 mustEqual false unk.isDefined mustEqual false
case _ => case _ =>
ko ko
} }
} }
"encode (short)" in { "encode (short)" in {
val msg = PlayerStateShiftMessage(6, true) val msg = PlayerStateShiftMessage(5)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_short pkt mustEqual string_short
} }
"encode (pos)" in { "encode (pos)" in {
val msg = PlayerStateShiftMessage(1, val msg = PlayerStateShiftMessage(ShiftState(1, Vector3(4624.703f, 5922.1484f, 46.171875f), 255))
ShiftState(Vector3(4624.703f, 5922.1484f, 46.171875f), 255),
false)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_pos pkt mustEqual string_pos
} }
"encode (pos and vel)" in { "encode (pos and vel)" in {
val msg = PlayerStateShiftMessage(2, val msg = PlayerStateShiftMessage(ShiftState(2, Vector3(4645.75f, 5811.6016f, 50.3125f), 14, Vector3(2.8125f, -8.0f, 0.375f)))
ShiftState(Vector3(4645.75f, 5811.6016f, 50.3125f), 14, Vector3(2.8125f, -8.0f, 0.375f)),
false)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_posAndVel pkt mustEqual string_posAndVel