mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-24 12:34:44 +00:00
RelatedA0 and RelatedB0 have been superceded by RelatedA and RelatedB, respectively, with slots 0-3 for each; SlottedMetaAck has been removed and tests have been changed
This commit is contained in:
parent
adb7738268
commit
68e3377d2e
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet
|
||||
|
||||
import net.psforever.packet.control.SlottedMetaPacket
|
||||
import net.psforever.packet.control.{RelatedA, RelatedB, SlottedMetaPacket}
|
||||
import scodec.bits.BitVector
|
||||
import scodec.{Attempt, Codec, DecodeResult, Err}
|
||||
import scodec.codecs._
|
||||
|
|
@ -74,15 +74,15 @@ object ControlPacketOpcode extends Enumeration {
|
|||
|
||||
// OPCODES 0x10-1e
|
||||
case 0x10 => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket7)
|
||||
case 0x11 => control.RelatedA0.decode
|
||||
case 0x12 => noDecoder(RelatedA1)
|
||||
case 0x13 => noDecoder(RelatedA2)
|
||||
case 0x14 => noDecoder(RelatedA3)
|
||||
case 0x15 => control.RelatedB0.decode
|
||||
case 0x16 => noDecoder(RelatedB1)
|
||||
case 0x17 => noDecoder(RelatedB2)
|
||||
case 0x11 => RelatedA.decodeWithOpcode(RelatedA0)
|
||||
case 0x12 => RelatedA.decodeWithOpcode(RelatedA1)
|
||||
case 0x13 => RelatedA.decodeWithOpcode(RelatedA2)
|
||||
case 0x14 => RelatedA.decodeWithOpcode(RelatedA3)
|
||||
case 0x15 => RelatedB.decodeWithOpcode(RelatedB0)
|
||||
case 0x16 => RelatedB.decodeWithOpcode(RelatedB1)
|
||||
case 0x17 => RelatedB.decodeWithOpcode(RelatedB2)
|
||||
// 0x18
|
||||
case 0x18 => noDecoder(RelatedB3)
|
||||
case 0x18 => RelatedB.decodeWithOpcode(RelatedB3)
|
||||
case 0x19 => control.MultiPacketEx.decode
|
||||
case 0x1a => noDecoder(Unknown26)
|
||||
case 0x1b => noDecoder(Unknown27)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.control
|
||||
|
||||
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||
import scodec.Codec
|
||||
import scodec.bits.BitVector
|
||||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* Dispatched from the client in regards to errors trying to process prior `ControlPackets`.
|
||||
* Explains which packet was in error by sending back its `subslot` number.
|
||||
* @param slot the type of `ResultA` packet;
|
||||
* valid types are integers 0-3
|
||||
* @param subslot identification of a control packet
|
||||
*/
|
||||
final case class RelatedA(slot : Int, subslot : Int) extends PlanetSideControlPacket {
|
||||
type Packet = RelatedA
|
||||
if(slot < 0 || slot > 3) {
|
||||
throw new IllegalArgumentException(s"slot number is out of range - $slot")
|
||||
}
|
||||
|
||||
def opcode = {
|
||||
val base = ControlPacketOpcode.RelatedA0.id
|
||||
ControlPacketOpcode(base + slot)
|
||||
}
|
||||
def encode = RelatedA.encode(this).map(vect => vect.drop(8))
|
||||
}
|
||||
|
||||
object RelatedA extends Marshallable[RelatedA] {
|
||||
implicit val codec : Codec[RelatedA] = (
|
||||
("slot" | uint8L.xmap[Int](a => a - ControlPacketOpcode.RelatedA0.id, a=>a) ) ::
|
||||
("subslot" | uint16) // the slot is big endian. see 0x00A42F76
|
||||
).as[RelatedA]
|
||||
|
||||
def decodeWithOpcode(slot : ControlPacketOpcode.Value)(bits : BitVector) = {
|
||||
decode(ControlPacketOpcode.codec.encode(slot).require ++ bits)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.control
|
||||
|
||||
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* Dispatched from the client in regards to errors trying to process prior `ControlPackets`.
|
||||
* Explains which packet was in error by sending back its `subslot` number.
|
||||
* @param subslot identification of a control packet
|
||||
*/
|
||||
final case class RelatedA0(subslot : Int)
|
||||
extends PlanetSideControlPacket {
|
||||
type Packet = RelatedA0
|
||||
def opcode = ControlPacketOpcode.RelatedA0
|
||||
def encode = RelatedA0.encode(this)
|
||||
}
|
||||
|
||||
object RelatedA0 extends Marshallable[RelatedA0] {
|
||||
implicit val codec : Codec[RelatedA0] = ("subslot" | uint16).as[RelatedA0]
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.control
|
||||
|
||||
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||
import scodec.Codec
|
||||
import scodec.bits.BitVector
|
||||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* Dispatched to coordinate information regarding `ControlPacket` packets between the client and server.
|
||||
* When dispatched by the client, it relates the current (or last received) `SlottedMetaPacket` `subslot` number back to the server.
|
||||
* When dispatched by the server, it relates ???
|
||||
* @param slot the type of `ResultB` packet;
|
||||
* valid types are integers 0-3
|
||||
* @param subslot identification of a control packet
|
||||
*/
|
||||
final case class RelatedB(slot : Int, subslot : Int) extends PlanetSideControlPacket {
|
||||
type Packet = RelatedB
|
||||
if(slot < 0 || slot > 3) {
|
||||
throw new IllegalArgumentException(s"slot number is out of range - $slot")
|
||||
}
|
||||
|
||||
def opcode = {
|
||||
val base = ControlPacketOpcode.RelatedB0.id
|
||||
ControlPacketOpcode(base + slot)
|
||||
}
|
||||
def encode = RelatedB.encode(this).map(vect => vect.drop(8))
|
||||
}
|
||||
|
||||
object RelatedB extends Marshallable[RelatedB] {
|
||||
implicit val codec : Codec[RelatedB] = (
|
||||
("slot" | uint8L.xmap[Int](a => a - ControlPacketOpcode.RelatedB0.id, a=>a) ) ::
|
||||
("subslot" | uint16) // the slot is big endian. see 0x00A42F76
|
||||
).as[RelatedB]
|
||||
|
||||
def decodeWithOpcode(slot : ControlPacketOpcode.Value)(bits : BitVector) = {
|
||||
decode(ControlPacketOpcode.codec.encode(slot).require ++ bits)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.control
|
||||
|
||||
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* Dispatched to coordinate information regarding `ControlPacket` packets between the client and server.
|
||||
* When dispatched by the client, it relates the current (or last received) `SlottedMetaPacket` `subslot` number back to the server.
|
||||
* When dispatched by the server, it relates ???
|
||||
* @param subslot identification of a control packet
|
||||
*/
|
||||
final case class RelatedB0(subslot : Int)
|
||||
extends PlanetSideControlPacket {
|
||||
type Packet = RelatedB0
|
||||
def opcode = ControlPacketOpcode.RelatedB0
|
||||
def encode = RelatedB0.encode(this)
|
||||
}
|
||||
|
||||
object RelatedB0 extends Marshallable[RelatedB0] {
|
||||
implicit val codec : Codec[RelatedB0] = ("subslot" | uint16).as[RelatedB0]
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.packet.control
|
||||
|
||||
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||
import scodec.Codec
|
||||
import scodec.bits.BitVector
|
||||
import scodec.codecs._
|
||||
|
||||
final case class SlottedMetaAck(slot : Int, subslot : Int)
|
||||
extends PlanetSideControlPacket {
|
||||
type Packet = SlottedMetaAck
|
||||
|
||||
assert(slot >= 0 && slot <= 7, s"Slot number ($slot) is out of range") //TODO 7 types of SlottedMeta, 4 types of ResultB?
|
||||
|
||||
def opcode = {
|
||||
val base = ControlPacketOpcode.RelatedB0.id
|
||||
ControlPacketOpcode(base + slot % 4)
|
||||
}
|
||||
|
||||
// XXX: a nasty hack to ignore the "slot" field
|
||||
// There is so much wrong with this it's not even funny. Why scodec, whyyyy...
|
||||
// I've never had a library make me feel so stupid and smart at the same time
|
||||
def encode = SlottedMetaAck.encode(this).map(vect => vect.drop(8))
|
||||
}
|
||||
|
||||
object SlottedMetaAck extends Marshallable[SlottedMetaAck] {
|
||||
implicit val codec : Codec[SlottedMetaAck] = (
|
||||
("slot" | uint8L.xmap[Int](a => a - ControlPacketOpcode.RelatedB0.id, a=>a) ) ::
|
||||
("subslot" | uint16)
|
||||
).as[SlottedMetaAck]
|
||||
|
||||
def decodeWithOpcode(slot : ControlPacketOpcode.Value)(bits : BitVector) = {
|
||||
decode(ControlPacketOpcode.codec.encode(slot).require ++ bits)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,24 +3,80 @@ package control
|
|||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.control.RelatedA
|
||||
import scodec.bits._
|
||||
|
||||
class RelatedATest extends Specification {
|
||||
val string0 = hex"00 11 01 04"
|
||||
val string1 = hex"00 12 01 04"
|
||||
val string2 = hex"00 13 01 04"
|
||||
val string3 = hex"00 14 01 04"
|
||||
|
||||
"decode (0)" in {
|
||||
PacketCoding.DecodePacket(string0).require match {
|
||||
case RelatedA0(slot) =>
|
||||
slot mustEqual 260
|
||||
case RelatedA(slot, subslot) =>
|
||||
slot mustEqual 0
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (1)" in {
|
||||
PacketCoding.DecodePacket(string1).require match {
|
||||
case RelatedA(slot, subslot) =>
|
||||
slot mustEqual 1
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (2)" in {
|
||||
PacketCoding.DecodePacket(string2).require match {
|
||||
case RelatedA(slot, subslot) =>
|
||||
slot mustEqual 2
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (3)" in {
|
||||
PacketCoding.DecodePacket(string3).require match {
|
||||
case RelatedA(slot, subslot) =>
|
||||
slot mustEqual 3
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
val pkt = RelatedA0(260)
|
||||
val pkt = RelatedA(0, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string0
|
||||
}
|
||||
|
||||
"encode (1)" in {
|
||||
val pkt = RelatedA(1, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string1
|
||||
}
|
||||
|
||||
"encode (2)" in {
|
||||
val pkt = RelatedA(2, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string2
|
||||
}
|
||||
|
||||
"encode (3)" in {
|
||||
val pkt = RelatedA(3, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string3
|
||||
}
|
||||
|
||||
"encode (n)" in {
|
||||
RelatedA(4, 260) must throwA[IllegalArgumentException]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,80 @@ package control
|
|||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.control.RelatedB
|
||||
import scodec.bits._
|
||||
|
||||
class RelatedBTest extends Specification {
|
||||
val string0 = hex"00 15 01 04"
|
||||
val string1 = hex"00 16 01 04"
|
||||
val string2 = hex"00 17 01 04"
|
||||
val string3 = hex"00 18 01 04"
|
||||
|
||||
"decode (0)" in {
|
||||
PacketCoding.DecodePacket(string0).require match {
|
||||
case RelatedB0(slot) =>
|
||||
slot mustEqual 260
|
||||
case RelatedB(slot, subslot) =>
|
||||
slot mustEqual 0
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (1)" in {
|
||||
PacketCoding.DecodePacket(string1).require match {
|
||||
case RelatedB(slot, subslot) =>
|
||||
slot mustEqual 1
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (2)" in {
|
||||
PacketCoding.DecodePacket(string2).require match {
|
||||
case RelatedB(slot, subslot) =>
|
||||
slot mustEqual 2
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (3)" in {
|
||||
PacketCoding.DecodePacket(string3).require match {
|
||||
case RelatedB(slot, subslot) =>
|
||||
slot mustEqual 3
|
||||
subslot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
val pkt = RelatedB0(260)
|
||||
val pkt = RelatedB(0, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string0
|
||||
}
|
||||
|
||||
"encode (1)" in {
|
||||
val pkt = RelatedB(1, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string1
|
||||
}
|
||||
|
||||
"encode (2)" in {
|
||||
val pkt = RelatedB(2, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string2
|
||||
}
|
||||
|
||||
"encode (3)" in {
|
||||
val pkt = RelatedB(3, 260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string3
|
||||
}
|
||||
|
||||
"encode (n)" in {
|
||||
RelatedB(4, 260) must throwA[IllegalArgumentException]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class SlottedMetaAckTest extends Specification {
|
||||
val string = hex"00150da4"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case SlottedMetaAck(_, _) =>
|
||||
ko
|
||||
case RelatedB0(subslot) => //important!
|
||||
subslot mustEqual 3492
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val pkt = SlottedMetaAck(0, 3492)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
|
||||
msg mustEqual string
|
||||
}
|
||||
}
|
||||
|
|
@ -241,7 +241,7 @@ class PacketCodingActor extends Actor with MDCContextAware {
|
|||
packet match {
|
||||
case SlottedMetaPacket(slot, subslot, innerPacket) =>
|
||||
subslotInbound = subslot
|
||||
self.tell(PacketCoding.CreateControlPacket(SlottedMetaAck(slot, subslot)), rightRef) //will go towards network
|
||||
self.tell(PacketCoding.CreateControlPacket(RelatedB(slot, subslot)), rightRef) //will go to the network
|
||||
UnmarshalInnerPacket(innerPacket, "the inner packet of a SlottedMetaPacket")
|
||||
|
||||
case MultiPacket(packets) =>
|
||||
|
|
@ -250,11 +250,11 @@ class PacketCodingActor extends Actor with MDCContextAware {
|
|||
case MultiPacketEx(packets) =>
|
||||
packets.foreach { UnmarshalInnerPacket(_, "the inner packet of a MultiPacketEx") }
|
||||
|
||||
case RelatedA0(subslot) =>
|
||||
log.error(s"bad subslot data - $subslot; potential disarray")
|
||||
case RelatedA(slot, subslot) =>
|
||||
log.error(s"result $slot: subslot $subslot was in error")
|
||||
|
||||
case RelatedB0(subslot) =>
|
||||
log.trace(s"good control packet received - subslot data $subslot")
|
||||
case RelatedB(slot, subslot) =>
|
||||
log.trace(s"result $slot: subslot $subslot accepted")
|
||||
|
||||
case _ =>
|
||||
sendResponseRight(container)
|
||||
|
|
|
|||
Loading…
Reference in a new issue