Packet: GenericCollisionMsg (#105)

* added new GenericCollisionMsg packet

* added standard comments and a message display case

* rebased GenericCollisionMsg

* minor corrections

* creating a Vector3 codec for leveraging float values
This commit is contained in:
Fate-JH 2017-03-05 16:27:37 -05:00 committed by pschord
parent 6ada7c9a92
commit aece1e1aab
5 changed files with 117 additions and 2 deletions

View file

@ -389,7 +389,7 @@ object GamePacketOpcode extends Enumeration {
case 0x39 => game.ChangeFireStateMessage_Start.decode case 0x39 => game.ChangeFireStateMessage_Start.decode
case 0x3a => game.ChangeFireStateMessage_Stop.decode case 0x3a => game.ChangeFireStateMessage_Stop.decode
case 0x3b => noDecoder(UnknownMessage59) case 0x3b => noDecoder(UnknownMessage59)
case 0x3c => noDecoder(GenericCollisionMsg) case 0x3c => game.GenericCollisionMsg.decode
case 0x3d => game.QuantityUpdateMessage.decode case 0x3d => game.QuantityUpdateMessage.decode
case 0x3e => game.ArmorChangedMessage.decode case 0x3e => game.ArmorChangedMessage.decode
case 0x3f => noDecoder(ProjectileStateMessage) case 0x3f => noDecoder(ProjectileStateMessage)

View file

@ -0,0 +1,62 @@
// Copyright (c) 2016 PSForever.net to present
package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import net.psforever.types.Vector3
import scodec.Codec
import scodec.codecs._
/**
* Dispatched by the client when the player has encountered a physical interaction that would cause damage.<br>
* <br>
* Collision information reports about two subjects who were involved in an altercation.
* The first is the `player`, that is, the client's avatar.
* The second is the `target` with respect to the `player` - whatever the avatar ran into, or whatever ran into the avatar.
* In the case of isolated forms of collision such as fall damage the `target` fields are blank or zero'd.
* @param unk1 na
* @param player the player or player-controlled vehicle
* @param target the other party in the collision
* @param player_health the player's health
* @param target_health the target's health
* @param player_velocity the player's velocity
* @param target_velocity the target's velocity
* @param player_pos the player's world coordinates
* @param target_pos the target's world coordinates
* @param unk2 na
* @param unk3 na
* @param unk4 na
*/
final case class GenericCollisionMsg(unk1 : Int,
player : PlanetSideGUID,
target : PlanetSideGUID,
player_health : Int,
target_health : Int,
player_velocity : Vector3,
target_velocity : Vector3,
player_pos : Vector3,
target_pos : Vector3,
unk2 : Long,
unk3 : Long,
unk4 : Long)
extends PlanetSideGamePacket {
type Packet = GenericCollisionMsg
def opcode = GamePacketOpcode.GenericCollisionMsg
def encode = GenericCollisionMsg.encode(this)
}
object GenericCollisionMsg extends Marshallable[GenericCollisionMsg] {
implicit val codec : Codec[GenericCollisionMsg] = (
("unk1" | uint2) ::
("p" | PlanetSideGUID.codec) ::
("t" | PlanetSideGUID.codec) ::
("p_health" | uint16L) ::
("t_health" | uint16L) ::
("p_vel" | Vector3.codec_float) ::
("t_vel" | Vector3.codec_float) ::
("p_pos" | Vector3.codec_pos) ::
("t_pos" | Vector3.codec_pos) ::
("unk2" | uint32L) ::
("unk3" | uint32L) ::
("unk4" | uint32L)
).as[GenericCollisionMsg]
}

View file

@ -21,4 +21,10 @@ object Vector3 {
("y" | newcodecs.q_float(-256.0, 256.0, 14)) :: ("y" | newcodecs.q_float(-256.0, 256.0, 14)) ::
("z" | newcodecs.q_float(-256.0, 256.0, 14)) ("z" | newcodecs.q_float(-256.0, 256.0, 14))
).as[Vector3] ).as[Vector3]
implicit val codec_float : Codec[Vector3] = (
("x" | floatL) ::
("y" | floatL) ::
("z" | floatL)
).as[Vector3]
} }

View file

@ -0,0 +1,45 @@
// Copyright (c) 2016 PSForever.net to present
package game
import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game._
import net.psforever.types.Vector3
import scodec.bits._
class GenericCollisionMsgTest extends Specification {
//TODO find a better test later
val string = hex"3C 92C00000190000001B2A8010932CEF505C70946F00000000000000000000000017725EBC6D6A058000000000000000000000000000003F8FF45140"
"decode" in {
PacketCoding.DecodePacket(string).require match {
case GenericCollisionMsg(unk1, p, t, php, thp, pv, tv, ppos, tpos, unk2, unk3, unk4) =>
unk1 mustEqual 2
p mustEqual PlanetSideGUID(75)
t mustEqual PlanetSideGUID(0)
php mustEqual 100
thp mustEqual 0
pv.x mustEqual 32.166428f
pv.y mustEqual 23.712547f
pv.z mustEqual -0.012802706f
tv.x mustEqual 0.0f
tv.z mustEqual 0.0f
tv.x mustEqual 0.0f
ppos.x mustEqual 3986.7266f
ppos.y mustEqual 2615.3672f
ppos.z mustEqual 90.625f
tpos.x mustEqual 0.0f
tpos.y mustEqual 0.0f
tpos.z mustEqual 0.0f
unk2 mustEqual 0L
unk3 mustEqual 0L
unk4 mustEqual 1171341310L
case _ =>
ko
}
}
"encode" in {
val msg = GenericCollisionMsg(2, PlanetSideGUID(75), PlanetSideGUID(0), 100, 0, Vector3(32.166428f, 23.712547f, -0.012802706f), Vector3(0.0f, 0.0f, 0.0f), Vector3(3986.7266f, 2615.3672f, 90.625f), Vector3(0.0f, 0.0f, 0.0f), 0L, 0L, 1171341310L)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string
}
}

View file

@ -370,6 +370,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
case msg @ SquadDefinitionActionMessage(a, b, c, d, e, f, g, h, i) => case msg @ SquadDefinitionActionMessage(a, b, c, d, e, f, g, h, i) =>
log.info("SquadDefinitionAction: " + msg) log.info("SquadDefinitionAction: " + msg)
case msg @ GenericCollisionMsg(u1, p, t, php, thp, pvx, pvy, pvz, tvx, tvy, tvz, ppos, tpos, u2, u3, u4) =>
log.info("Ouch! " + msg)
case msg @ BugReportMessage(version_major,version_minor,version_date,bug_type,repeatable,location,zone,pos,summary,desc) => case msg @ BugReportMessage(version_major,version_minor,version_date,bug_type,repeatable,location,zone,pos,summary,desc) =>
log.info("BugReportMessage: " + msg) log.info("BugReportMessage: " + msg)
@ -377,7 +380,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.info("BindPlayerMessage: " + msg) log.info("BindPlayerMessage: " + msg)
case default => log.error(s"Unhandled GamePacket ${pkt}") case default => log.error(s"Unhandled GamePacket ${pkt}")
} }
def failWithError(error : String) = { def failWithError(error : String) = {