initial work on OxygenStateMessage packet and tests

This commit is contained in:
FateJH 2017-05-07 23:27:02 -04:00
parent 461a4f9507
commit 729b36eba1
3 changed files with 143 additions and 1 deletions

View file

@ -461,7 +461,7 @@ object GamePacketOpcode extends Enumeration {
case 0x76 => game.DeployableObjectsInfoMessage.decode
case 0x77 => noDecoder(SquadState)
// 0x78
case 0x78 => noDecoder(OxygenStateMessage)
case 0x78 => game.OxygenStateMessage.decode
case 0x79 => noDecoder(TradeMessage)
case 0x7a => noDecoder(UnknownMessage122)
case 0x7b => noDecoder(DamageFeedbackMessage)

View file

@ -0,0 +1,89 @@
// Copyright (c) 2017 PSForever
package net.psforever.packet.game
import net.psforever.newcodecs.newcodecs
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import scodec.{Attempt, Codec}
import scodec.codecs._
import shapeless.{::, HNil}
/**
* na
* @param vehicle_guid the player's mounted vehicle
* @param time the countdown's time upon start
* @param active show a new countdown if `true` (resets any active countdown);
* clear any active countdowns if `false`
*/
final case class WaterloggedVehicleState(vehicle_guid : PlanetSideGUID,
time : Double,
active : Boolean)
/**
* na
* @param player_guid the player
* @param time the countdown's time upon start
* @param active show a new countdown if `true` (resets any active countdown);
* clear any active countdowns if `false`
* @param vehicle_state optional state of the vehicle the player is driving
*/
final case class OxygenStateMessage(player_guid : PlanetSideGUID,
time : Double,
active : Boolean,
vehicle_state : Option[WaterloggedVehicleState] = None)
extends PlanetSideGamePacket {
type Packet = OxygenStateMessage
def opcode = GamePacketOpcode.OxygenStateMessage
def encode = OxygenStateMessage.encode(this)
}
object OxygenStateMessage extends Marshallable[OxygenStateMessage] {
/**
* Overloaded constructor that removes the optional state of the `WaterloggedVehicleState` parameter.
* @param player_guid the player
* @param time the countdown's time upon start
* @param active show or clear the countdown
* @param vehicle_state state of the vehicle the player is driving
* @return
*/
def apply(player_guid : PlanetSideGUID, time : Double, active : Boolean, vehicle_state : WaterloggedVehicleState) : OxygenStateMessage =
OxygenStateMessage(player_guid, time, active, Some(vehicle_state))
/**
* A simple pattern that expands the datatypes of the packet's basic `Codec`.
*/
private type basePattern = PlanetSideGUID :: Double :: Boolean :: HNil
/**
* A `Codec` for the repeated processing of three values.
* This `Codec` is the basis for the packet's data.
*/
private val base_codec : Codec[basePattern] =
PlanetSideGUID.codec ::
newcodecs.q_double(0.0, 204.8, 11) :: //hackish: 2^11 == 2047, so it should be 204.7; but, 204.8 allows the decode == encode
bool
implicit val codec : Codec[OxygenStateMessage] = (
base_codec.exmap[basePattern] (
{
case guid :: time :: active :: HNil =>
Attempt.successful(guid :: time :: active :: HNil)
},
{
case guid :: time :: active :: HNil =>
Attempt.successful(guid :: time :: active :: HNil)
}
) :+
optional(bool,
"vehicle_state" | base_codec.exmap[WaterloggedVehicleState] (
{
case guid :: time :: active :: HNil =>
Attempt.successful(WaterloggedVehicleState(guid, time, active))
},
{
case WaterloggedVehicleState(guid, time, active) =>
Attempt.successful(guid :: time :: active :: HNil)
}
).as[WaterloggedVehicleState]
)
).as[OxygenStateMessage]
}

View file

@ -0,0 +1,53 @@
// Copyright (c) 2017 PSForever
package game
import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game._
import scodec.bits._
class OxygenStateMessageTest extends Specification {
val string_self = hex"78 4b00f430"
val string_vehicle = hex"78 4b00f4385037a180"
"decode (self)" in {
PacketCoding.DecodePacket(string_self).require match {
case OxygenStateMessage(guid, time, active, veh_state) =>
guid mustEqual PlanetSideGUID(75)
time mustEqual 50.0
active mustEqual true
veh_state.isDefined mustEqual false
case _ =>
ko
}
}
"decode (vehicle)" in {
PacketCoding.DecodePacket(string_vehicle).require match {
case OxygenStateMessage(guid, time, active, veh_state) =>
guid mustEqual PlanetSideGUID(75)
time mustEqual 50.0
active mustEqual true
veh_state.isDefined mustEqual true
veh_state.get.vehicle_guid mustEqual PlanetSideGUID(1546)
veh_state.get.time mustEqual 50.0
veh_state.get.active mustEqual true
case _ =>
ko
}
}
"encode (self)" in {
val msg = OxygenStateMessage(PlanetSideGUID(75), 50.0, true)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_self
}
"encode (vehicle)" in {
val msg = OxygenStateMessage(PlanetSideGUID(75), 50.0, true, WaterloggedVehicleState(PlanetSideGUID(1546), 50.0, true))
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_vehicle
}
}