mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-03 12:10:22 +00:00
initial RelatedA0 and RelatedB0 packets
modified HandleGamePacket so that it should encode properly; modified CSA so that it attempt to detect packets that encode into ByteVectors that are 'too big' and will attempt to split them up separated the ControlPacket tests into invdividual files and wrote tests for RelatedA0, RelatedB0, and HandleGamePacket proof of concept MTU packet split in CSA; example in WSA @ character select modified session pipeline to accept n queued Actors rather than just two; special packet decoder in progress some effort separating useful sub-operations in encryption/decryption/encoding/decoding functions; introduced PacketCodingActor , devoted to encoding and decoding packets; simplified CSA so that it is devoted just to encrypting and decrypting
This commit is contained in:
parent
3e5e8a2573
commit
294d5335c9
23 changed files with 833 additions and 370 deletions
|
|
@ -1,190 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
|
||||
import org.specs2.mutable._
|
||||
import org.specs2.specification
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import org.specs2.specification.core.Fragment
|
||||
import scodec.Attempt.Successful
|
||||
import scodec.bits._
|
||||
import scodec.codecs.uint16
|
||||
|
||||
class ControlPacketTest extends Specification {
|
||||
|
||||
"PlanetSide control packet" in {
|
||||
"ControlSync" should {
|
||||
val string = hex"0007 5268 0000004D 00000052 0000004D 0000007C 0000004D 0000000000000276 0000000000000275"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case ControlSync(a, b, c, d, e, f, g, h) =>
|
||||
a mustEqual 21096
|
||||
|
||||
b mustEqual 0x4d
|
||||
c mustEqual 0x52
|
||||
d mustEqual 0x4d
|
||||
e mustEqual 0x7c
|
||||
f mustEqual 0x4d
|
||||
|
||||
g mustEqual 0x276
|
||||
h mustEqual 0x275
|
||||
case default =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(ControlSync(21096, 0x4d, 0x52, 0x4d, 0x7c, 0x4d, 0x276, 0x275)).require
|
||||
|
||||
encoded.toByteVector mustEqual string
|
||||
}
|
||||
}
|
||||
|
||||
"ControlSyncResp" should {
|
||||
val string = hex"0008 5268 21392D92 0000000000000276 0000000000000275 0000000000000275 0000000000000276"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case ControlSyncResp(a, b, c, d, e, f) =>
|
||||
a mustEqual 21096
|
||||
|
||||
b mustEqual 0x21392D92
|
||||
c mustEqual 0x276
|
||||
d mustEqual 0x275
|
||||
e mustEqual 0x275
|
||||
f mustEqual 0x276
|
||||
case default =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(ControlSyncResp(21096, 0x21392D92, 0x276, 0x275, 0x275, 0x276)).require
|
||||
|
||||
encoded.toByteVector mustEqual string
|
||||
}
|
||||
}
|
||||
|
||||
"SlottedMetaPacket" should {
|
||||
val string = hex"00 09 00 00 00194302484C36563130433F" ++
|
||||
hex"4C6835316369774A0000000018FABE0C" ++
|
||||
hex"00000000000000000000000001000000" ++
|
||||
hex"020000006B7BD8288C6469666671756F" ++
|
||||
hex"7469656E740000000000440597570065" ++
|
||||
hex"006C0063006F006D006500200074006F" ++
|
||||
hex"00200050006C0061006E006500740053" ++
|
||||
hex"0069006400650021002000018667656D" ++
|
||||
hex"696E690100040001459E2540377540"
|
||||
|
||||
def createMetaPacket(slot : Int, subslot : Int, rest : ByteVector) = hex"00" ++
|
||||
ControlPacketOpcode.codec.encode(
|
||||
ControlPacketOpcode(ControlPacketOpcode.SlottedMetaPacket0.id + slot)
|
||||
).require.toByteVector ++ uint16.encode(subslot).require.toByteVector ++ rest
|
||||
|
||||
"decode as the base slot and subslot" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case SlottedMetaPacket(slot, subslot, rest) =>
|
||||
slot mustEqual 0
|
||||
subslot mustEqual 0
|
||||
rest mustEqual string.drop(4)
|
||||
case default =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode as an arbitrary slot and subslot" in {
|
||||
val maxSlots = ControlPacketOpcode.SlottedMetaPacket7.id - ControlPacketOpcode.SlottedMetaPacket0.id
|
||||
|
||||
// create all possible SlottedMetaPackets
|
||||
Fragment.foreach(0 to maxSlots) { i =>
|
||||
"slot " + i ! {
|
||||
val subslot = 12323
|
||||
val pkt = createMetaPacket(i, subslot, ByteVector.empty)
|
||||
|
||||
PacketCoding.DecodePacket(pkt).require match {
|
||||
case SlottedMetaPacket(slot, subslotDecoded, rest) =>
|
||||
|
||||
// XXX: there isn't a simple solution to Slot0 and Slot4 be aliases of each other structurally
|
||||
// This is probably best left to higher layers
|
||||
//slot mustEqual i % 4 // this is seen at 0x00A3FBFA
|
||||
slot mustEqual i
|
||||
subslotDecoded mustEqual subslot
|
||||
rest mustEqual ByteVector.empty // empty in this case
|
||||
case default =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(SlottedMetaPacket(0, 0x1000, ByteVector.empty)).require
|
||||
val encoded2 = PacketCoding.EncodePacket(SlottedMetaPacket(3, 0xffff, hex"414243")).require
|
||||
val encoded3 = PacketCoding.EncodePacket(SlottedMetaPacket(7, 0, hex"00")).require
|
||||
|
||||
encoded.toByteVector mustEqual createMetaPacket(0, 0x1000, ByteVector.empty)
|
||||
encoded2.toByteVector mustEqual createMetaPacket(3, 0xffff, hex"414243")
|
||||
encoded3.toByteVector mustEqual createMetaPacket(7, 0, hex"00")
|
||||
|
||||
PacketCoding.EncodePacket(SlottedMetaPacket(8, 0, hex"00")).require must throwA[AssertionError]
|
||||
PacketCoding.EncodePacket(SlottedMetaPacket(-1, 0, hex"00")).require must throwA[AssertionError]
|
||||
PacketCoding.EncodePacket(SlottedMetaPacket(0, 0x10000, hex"00")).require must throwA[IllegalArgumentException]
|
||||
}
|
||||
}
|
||||
|
||||
"MultiPacketEx" should {
|
||||
val strings = Vector(
|
||||
hex"00",
|
||||
hex"01 41",
|
||||
hex"01 41" ++ hex"02 4142",
|
||||
hex"fe" ++ ByteVector.fill(0xfe)(0x41),
|
||||
hex"ffff00" ++ ByteVector.fill(0xff)(0x41),
|
||||
hex"ff0001" ++ ByteVector.fill(0x100)(0x41),
|
||||
hex"ff ffff ffff 0000" ++ ByteVector.fill(0x0000ffff)(0x41),
|
||||
hex"ff ffff 0000 0100" ++ ByteVector.fill(0x00010000)(0x41)
|
||||
)
|
||||
|
||||
val packets = Vector(
|
||||
MultiPacketEx(Vector(ByteVector.empty)),
|
||||
MultiPacketEx(Vector(hex"41")),
|
||||
MultiPacketEx(Vector(hex"41", hex"4142")),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0xfe)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0xff)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0x100)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0x0000ffff)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0x00010000)(0x41)))
|
||||
)
|
||||
|
||||
"decode" in {
|
||||
Fragment.foreach(strings.indices) { i =>
|
||||
"test "+i ! { MultiPacketEx.decode(strings{i}.bits).require.value mustEqual packets{i} }
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
Fragment.foreach(packets.indices) { i =>
|
||||
"test "+i ! { MultiPacketEx.encode(packets{i}).require.toByteVector mustEqual strings{i} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"TeardownConnection" should {
|
||||
val string = hex"00 05 02 4F 57 17 00 06"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case TeardownConnection(nonce) =>
|
||||
nonce mustEqual 391597826
|
||||
case default =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(TeardownConnection(391597826)).require
|
||||
|
||||
encoded.toByteVector mustEqual string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
common/src/test/scala/control/ControlSyncRespTest.scala
Normal file
32
common/src/test/scala/control/ControlSyncRespTest.scala
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class ControlSyncRespTest extends Specification {
|
||||
val string = hex"0008 5268 21392D92 0000000000000276 0000000000000275 0000000000000275 0000000000000276"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case ControlSyncResp(a, b, c, d, e, f) =>
|
||||
a mustEqual 21096
|
||||
|
||||
b mustEqual 0x21392D92
|
||||
c mustEqual 0x276
|
||||
d mustEqual 0x275
|
||||
e mustEqual 0x275
|
||||
f mustEqual 0x276
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(ControlSyncResp(21096, 0x21392D92, 0x276, 0x275, 0x275, 0x276)).require
|
||||
|
||||
encoded.toByteVector mustEqual string
|
||||
}
|
||||
}
|
||||
32
common/src/test/scala/control/ControlSyncTest.scala
Normal file
32
common/src/test/scala/control/ControlSyncTest.scala
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class ControlSyncTest extends Specification {
|
||||
val string = hex"0007 5268 0000004D 00000052 0000004D 0000007C 0000004D 0000000000000276 0000000000000275"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case ControlSync(a, b, c, d, e, f, g, h) =>
|
||||
a mustEqual 21096
|
||||
b mustEqual 0x4d
|
||||
c mustEqual 0x52
|
||||
d mustEqual 0x4d
|
||||
e mustEqual 0x7c
|
||||
f mustEqual 0x4d
|
||||
g mustEqual 0x276
|
||||
h mustEqual 0x275
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(ControlSync(21096, 0x4d, 0x52, 0x4d, 0x7c, 0x4d, 0x276, 0x275)).require
|
||||
encoded.toByteVector mustEqual string
|
||||
}
|
||||
}
|
||||
30
common/src/test/scala/control/HandleGamePacketTest.scala
Normal file
30
common/src/test/scala/control/HandleGamePacketTest.scala
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class HandleGamePacketTest extends Specification {
|
||||
//this is the first from a series of SlottedMetaPacket4s; the length field was modified from 12 DC to pass the test
|
||||
val base = hex"18 D5 96 00 00 BC 8E 00 03 A2 16 5D A4 5F B0 80 00 04 30 40 00 08 30 46 00 4A 00 48 00 02 02 F0 62 1E 80 80 00 00 00 00 00 3F FF CC 0D 40 00 20 00 03 00 27 C3 01 C8 00 00 03 08 00 00 03 FF FF FF FC A4 04 00 00 62 00 18 02 00 50 00 00 00 00 00 00 00 00 00 00 00 00 00 01 90 01 90 00 C8 00 00 01 00 7E C8 00 C8 00 00 00 5D B0 81 40 00 00 00 00 00 00 00 00 00 00 00 00 02 C0 00 40 83 85 46 86 C7 07 8A 4A 80 70 0C 00 01 98 00 00 01 24 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 31 30 90 78 70 65 5F 6A 6F 69 6E 5F 70 6C 61 74 6F 6F 6E 92 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 31 34 8F 78 70 65 5F 6A 6F 69 6E 5F 6F 75 74 66 69 74 92 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 31 31 91 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 39 91 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 38 92 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 31 33 93 78 70 65 5F 77 61 72 70 5F 67 61 74 65 5F 75 73 61 67 65 91 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 32 92 78 70 65 5F 69 6E 73 74 61 6E 74 5F 61 63 74 69 6F 6E 8E 78 70 65 5F 66 6F 72 6D 5F 73 71 75 61 64 91 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 36 91 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 37 8E 78 70 65 5F 6A 6F 69 6E 5F 73 71 75 61 64 8C 78 70 65 5F 62 69 6E 64 5F 61 6D 73 91 78 70 65 5F 62 61 74 74 6C 65 5F 72 61 6E 6B 5F 35 91 78 70 65 5F 62 69 6E 64 5F 66 61 63 69 6C 69 74"
|
||||
val string = hex"00 00 01 CB" ++ base
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case HandleGamePacket(len, data, extra) =>
|
||||
len mustEqual 459
|
||||
data mustEqual base
|
||||
extra mustEqual BitVector.empty
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val pkt = HandleGamePacket(base)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string
|
||||
}
|
||||
}
|
||||
43
common/src/test/scala/control/MultiPacketExTest.scala
Normal file
43
common/src/test/scala/control/MultiPacketExTest.scala
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet.control._
|
||||
import org.specs2.specification.core.Fragment
|
||||
import scodec.bits._
|
||||
|
||||
class MultiPacketExTest extends Specification {
|
||||
val strings = Vector(
|
||||
hex"00",
|
||||
hex"01 41",
|
||||
hex"01 41" ++ hex"02 4142",
|
||||
hex"fe" ++ ByteVector.fill(0xfe)(0x41),
|
||||
hex"ffff00" ++ ByteVector.fill(0xff)(0x41),
|
||||
hex"ff0001" ++ ByteVector.fill(0x100)(0x41),
|
||||
hex"ff ffff ffff 0000" ++ ByteVector.fill(0x0000ffff)(0x41),
|
||||
hex"ff ffff 0000 0100" ++ ByteVector.fill(0x00010000)(0x41)
|
||||
)
|
||||
|
||||
val packets = Vector(
|
||||
MultiPacketEx(Vector(ByteVector.empty)),
|
||||
MultiPacketEx(Vector(hex"41")),
|
||||
MultiPacketEx(Vector(hex"41", hex"4142")),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0xfe)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0xff)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0x100)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0x0000ffff)(0x41))),
|
||||
MultiPacketEx(Vector(ByteVector.fill(0x00010000)(0x41)))
|
||||
)
|
||||
|
||||
"decode" in {
|
||||
Fragment.foreach(strings.indices) { i =>
|
||||
"test "+i ! { MultiPacketEx.decode(strings{i}.bits).require.value mustEqual packets{i} }
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
Fragment.foreach(packets.indices) { i =>
|
||||
"test "+i ! { MultiPacketEx.encode(packets{i}).require.toByteVector mustEqual strings{i} }
|
||||
}
|
||||
}
|
||||
}
|
||||
26
common/src/test/scala/control/RelatedATest.scala
Normal file
26
common/src/test/scala/control/RelatedATest.scala
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class RelatedATest extends Specification {
|
||||
val string0 = hex"00 11 01 04"
|
||||
|
||||
"decode (0)" in {
|
||||
PacketCoding.DecodePacket(string0).require match {
|
||||
case RelatedA0(slot) =>
|
||||
slot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
val pkt = RelatedA0(260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string0
|
||||
}
|
||||
}
|
||||
26
common/src/test/scala/control/RelatedBTest.scala
Normal file
26
common/src/test/scala/control/RelatedBTest.scala
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class RelatedBTest extends Specification {
|
||||
val string0 = hex"00 15 01 04"
|
||||
|
||||
"decode (0)" in {
|
||||
PacketCoding.DecodePacket(string0).require match {
|
||||
case RelatedB0(slot) =>
|
||||
slot mustEqual 260
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode (0)" in {
|
||||
val pkt = RelatedB0(260)
|
||||
val msg = PacketCoding.EncodePacket(pkt).require.toByteVector
|
||||
msg mustEqual string0
|
||||
}
|
||||
}
|
||||
76
common/src/test/scala/control/SlottedMetaPacketTest.scala
Normal file
76
common/src/test/scala/control/SlottedMetaPacketTest.scala
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import org.specs2.specification.core.Fragment
|
||||
import scodec.bits._
|
||||
import scodec.codecs.uint16
|
||||
|
||||
class SlottedMetaPacketTest extends Specification {
|
||||
val string = hex"00 09 00 00 00194302484C36563130433F" ++
|
||||
hex"4C6835316369774A0000000018FABE0C" ++
|
||||
hex"00000000000000000000000001000000" ++
|
||||
hex"020000006B7BD8288C6469666671756F" ++
|
||||
hex"7469656E740000000000440597570065" ++
|
||||
hex"006C0063006F006D006500200074006F" ++
|
||||
hex"00200050006C0061006E006500740053" ++
|
||||
hex"0069006400650021002000018667656D" ++
|
||||
hex"696E690100040001459E2540377540"
|
||||
|
||||
def createMetaPacket(slot : Int, subslot : Int, rest : ByteVector) = hex"00" ++
|
||||
ControlPacketOpcode.codec.encode(
|
||||
ControlPacketOpcode(ControlPacketOpcode.SlottedMetaPacket0.id + slot)
|
||||
).require.toByteVector ++ uint16.encode(subslot).require.toByteVector ++ rest
|
||||
|
||||
"decode as the base slot and subslot" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case SlottedMetaPacket(slot, subslot, rest) =>
|
||||
slot mustEqual 0
|
||||
subslot mustEqual 0
|
||||
rest mustEqual string.drop(4)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode as an arbitrary slot and subslot" in {
|
||||
val maxSlots = ControlPacketOpcode.SlottedMetaPacket7.id - ControlPacketOpcode.SlottedMetaPacket0.id
|
||||
|
||||
// create all possible SlottedMetaPackets
|
||||
Fragment.foreach(0 to maxSlots) { i =>
|
||||
"slot " + i ! {
|
||||
val subslot = 12323
|
||||
val pkt = createMetaPacket(i, subslot, ByteVector.empty)
|
||||
|
||||
PacketCoding.DecodePacket(pkt).require match {
|
||||
case SlottedMetaPacket(slot, subslotDecoded, rest) =>
|
||||
|
||||
// XXX: there isn't a simple solution to Slot0 and Slot4 be aliases of each other structurally
|
||||
// This is probably best left to higher layers
|
||||
//slot mustEqual i % 4 // this is seen at 0x00A3FBFA
|
||||
slot mustEqual i
|
||||
subslotDecoded mustEqual subslot
|
||||
rest mustEqual ByteVector.empty // empty in this case
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(SlottedMetaPacket(0, 0x1000, ByteVector.empty)).require
|
||||
val encoded2 = PacketCoding.EncodePacket(SlottedMetaPacket(3, 0xffff, hex"414243")).require
|
||||
val encoded3 = PacketCoding.EncodePacket(SlottedMetaPacket(7, 0, hex"00")).require
|
||||
|
||||
encoded.toByteVector mustEqual createMetaPacket(0, 0x1000, ByteVector.empty)
|
||||
encoded2.toByteVector mustEqual createMetaPacket(3, 0xffff, hex"414243")
|
||||
encoded3.toByteVector mustEqual createMetaPacket(7, 0, hex"00")
|
||||
|
||||
PacketCoding.EncodePacket(SlottedMetaPacket(8, 0, hex"00")).require must throwA[AssertionError]
|
||||
PacketCoding.EncodePacket(SlottedMetaPacket(-1, 0, hex"00")).require must throwA[AssertionError]
|
||||
PacketCoding.EncodePacket(SlottedMetaPacket(0, 0x10000, hex"00")).require must throwA[IllegalArgumentException]
|
||||
}
|
||||
}
|
||||
26
common/src/test/scala/control/TeardownConnectionTest.scala
Normal file
26
common/src/test/scala/control/TeardownConnectionTest.scala
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import scodec.bits._
|
||||
|
||||
class TeardownConnectionTest extends Specification {
|
||||
val string = hex"00 05 02 4F 57 17 00 06"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case TeardownConnection(nonce) =>
|
||||
nonce mustEqual 391597826
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
val encoded = PacketCoding.EncodePacket(TeardownConnection(391597826)).require
|
||||
|
||||
encoded.toByteVector mustEqual string
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue