mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-11 14:34:40 +00:00
wrote tests for MultiPacketCollector, MultiPacketBundle, and the new functionality in PCA
This commit is contained in:
parent
87d314942a
commit
19224e471b
4 changed files with 665 additions and 41 deletions
|
|
@ -13,11 +13,18 @@ import net.psforever.packet.PlanetSidePacket
|
|||
* the only way to access these packets is through pattern matching
|
||||
*/
|
||||
final case class MultiPacketBundle(private var packets : List[PlanetSidePacket]) {
|
||||
packets match {
|
||||
MultiPacketBundle.collectValidPackets(packets) match {
|
||||
case Nil =>
|
||||
throw new IllegalArgumentException("can not create with zero packets")
|
||||
case list =>
|
||||
packets = list
|
||||
}
|
||||
|
||||
def +(t : MultiPacketBundle) : MultiPacketBundle = t match {
|
||||
case MultiPacketBundle(list) =>
|
||||
MultiPacketBundle(packets ++ list)
|
||||
case _ =>
|
||||
packets = MultiPacketBundle.collectValidPackets(packets)
|
||||
MultiPacketBundle(packets)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -39,19 +46,14 @@ object MultiPacketBundle {
|
|||
})
|
||||
if(bad.nonEmpty) {
|
||||
org.log4s.getLogger("MultiPacketBundle")
|
||||
.warn(s"attempted to include packet types that are on the whitelist; ${bad.size} items have been excluded")
|
||||
.warn(s"attempted to include packet types that are not in the whitelist; ${bad.size} items have been excluded")
|
||||
}
|
||||
good
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulator for packets that will eventually be bundled and submitted for composing a `MultiPacketEx` packet.<br>
|
||||
* <br>
|
||||
* The accumulator is intended to be a disposable convenience class to incrementally construct a `MultiPacketBundle`.
|
||||
* Packets can only be added on top of the existing internal collection and can not be removed.
|
||||
* (Overloaded methods for adding packets from various sources also exist.)
|
||||
* Additionally, retrieving a copy of the collection via a `MultiPacketBundle` does not empty the collection.
|
||||
* Accumulator for packets that will eventually be bundled and submitted for composing a `MultiPacketEx` packet.
|
||||
*/
|
||||
class MultiPacketCollector() {
|
||||
private var bundle : List[PlanetSidePacket] = List.empty
|
||||
|
|
@ -64,14 +66,27 @@ class MultiPacketCollector() {
|
|||
}
|
||||
|
||||
def Add(t : List[PlanetSidePacket]) : Unit = {
|
||||
bundle = bundle ++ t
|
||||
if(t.nonEmpty) {
|
||||
bundle = bundle ++ t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the internal collection of packets.
|
||||
* Reset the internal list of packets by clearing it.
|
||||
* @return a loaded `MultiPacketBundle` object
|
||||
*/
|
||||
def Bundle : MultiPacketBundle = MultiPacketBundle(bundle)
|
||||
def Bundle : MultiPacketBundle = {
|
||||
try {
|
||||
val out = MultiPacketBundle(bundle)
|
||||
bundle = List.empty
|
||||
out
|
||||
}
|
||||
catch {
|
||||
case _ : Exception => //catch and rethrow the exception
|
||||
throw new RuntimeException("no packets")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A safer `Bundle` that consumes any` Exceptions` that might be thrown in the process of producing output.
|
||||
|
|
@ -91,7 +106,18 @@ class MultiPacketCollector() {
|
|||
|
||||
object MultiPacketCollector {
|
||||
/**
|
||||
* Overload constructor that accepts a initial packets.
|
||||
* Overload constructor that accepts initial packets.
|
||||
* @param bundle previously bundled packets
|
||||
* @return a `MultiPacketCollector` object
|
||||
*/
|
||||
def apply(bundle : MultiPacketBundle) : MultiPacketCollector = {
|
||||
val obj = new MultiPacketCollector()
|
||||
obj.Add(bundle)
|
||||
obj
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload constructor that accepts initial packets.
|
||||
* @param packets a series of packets
|
||||
* @return a `MultiPacketCollector` object
|
||||
*/
|
||||
|
|
|
|||
183
common/src/test/scala/control/MultiPacketCollectorTest.scala
Normal file
183
common/src/test/scala/control/MultiPacketCollectorTest.scala
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package control
|
||||
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.packet.control.{ControlSync, MultiPacketBundle, MultiPacketCollector}
|
||||
import net.psforever.packet.crypto.{ClientFinished, ServerFinished}
|
||||
import net.psforever.packet.game.{ObjectDeleteMessage, PlanetSideGUID}
|
||||
|
||||
class MultiPacketCollectorTest extends Specification {
|
||||
val packet1 = ObjectDeleteMessage(PlanetSideGUID(1103), 2)
|
||||
|
||||
"MultiPacketBundle" should {
|
||||
import scodec.bits._
|
||||
val packet2 = ControlSync(21096, 0x4d, 0x52, 0x4d, 0x7c, 0x4d, 0x276, 0x275)
|
||||
|
||||
"construct" in {
|
||||
MultiPacketBundle(List(packet1))
|
||||
ok
|
||||
}
|
||||
|
||||
"fail to construct if not initialized with PlanetSidePackets" in {
|
||||
MultiPacketBundle(Nil) must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"concatenate bundles into a new bundle" in {
|
||||
val obj1 = MultiPacketBundle(List(packet1))
|
||||
val obj2 = MultiPacketBundle(List(packet2))
|
||||
val obj3 = obj1 + obj2
|
||||
obj3 match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 2
|
||||
list.head mustEqual packet1
|
||||
list(1) mustEqual packet2
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"accept PlanetSideGamePackets and PlanetSideControlPackets" in {
|
||||
MultiPacketBundle(List(packet2, packet1)) match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 2
|
||||
list.head mustEqual packet2
|
||||
list(1) mustEqual packet1
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"ignore other types of PlanetSideContainerPackets" in {
|
||||
val param = List(packet2, ClientFinished(hex"", hex""), packet1, ServerFinished(hex""))
|
||||
MultiPacketBundle(param) match { //warning message will display in log
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 2
|
||||
list.head mustEqual param.head
|
||||
list(1) mustEqual param(2)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"MultiPacketCollector" should {
|
||||
val packet2 = ObjectDeleteMessage(PlanetSideGUID(1105), 2)
|
||||
val packet3 = ObjectDeleteMessage(PlanetSideGUID(1107), 2)
|
||||
|
||||
"construct" in {
|
||||
new MultiPacketCollector()
|
||||
ok
|
||||
}
|
||||
|
||||
"construct with initial packets" in {
|
||||
MultiPacketCollector(List(packet1, packet2))
|
||||
ok
|
||||
}
|
||||
|
||||
"can retrieve a bundle packets" in {
|
||||
val obj = MultiPacketCollector(List(packet1, packet2))
|
||||
obj.Bundle match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 2
|
||||
list.head mustEqual packet1
|
||||
list(1) mustEqual packet2
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"can not retrieve a bundle of non-existent packets" in {
|
||||
val obj = new MultiPacketCollector()
|
||||
obj.Bundle must throwA[RuntimeException]
|
||||
}
|
||||
|
||||
"can safely retrieve a bundle of potential packets" in {
|
||||
val obj1 = new MultiPacketCollector()
|
||||
obj1.BundleOption match {
|
||||
case Some(_) =>
|
||||
ko
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
val obj2 = MultiPacketCollector(List(packet1, packet2))
|
||||
obj2.BundleOption match {
|
||||
case None =>
|
||||
ko
|
||||
case Some(MultiPacketBundle(list)) =>
|
||||
list.size mustEqual 2
|
||||
list.head mustEqual packet1
|
||||
list(1) mustEqual packet2
|
||||
}
|
||||
}
|
||||
|
||||
"clear packets after being asked to bundle" in {
|
||||
val list = List(packet1, packet2)
|
||||
val obj = MultiPacketCollector(list)
|
||||
obj.Bundle mustEqual MultiPacketBundle(list)
|
||||
obj.Bundle must throwA[RuntimeException]
|
||||
}
|
||||
|
||||
"add a packet" in {
|
||||
val obj = new MultiPacketCollector()
|
||||
obj.Add(packet1)
|
||||
obj.Bundle match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 1
|
||||
list.head mustEqual packet1
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"add packets" in {
|
||||
val obj = new MultiPacketCollector()
|
||||
obj.Add(List(packet1, packet2))
|
||||
obj.Bundle match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 2
|
||||
list.head mustEqual packet1
|
||||
list(1) mustEqual packet2
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"concatenate bundles (1)" in {
|
||||
|
||||
val obj1 = new MultiPacketCollector()
|
||||
obj1.Add(List(packet1, packet2))
|
||||
val bundle1 = obj1.Bundle
|
||||
|
||||
val obj2 = MultiPacketCollector(bundle1)
|
||||
obj2.Add(packet3)
|
||||
obj2.Bundle match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 3
|
||||
list.head mustEqual packet1
|
||||
list(1) mustEqual packet2
|
||||
list(2) mustEqual packet3
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"concatenate bundles (2)" in {
|
||||
val obj1 = new MultiPacketCollector()
|
||||
obj1.Add(List(packet1, packet2))
|
||||
val bundle1 = obj1.Bundle
|
||||
|
||||
val obj2 = new MultiPacketCollector()
|
||||
obj2.Add(packet3)
|
||||
obj2.Add(bundle1)
|
||||
obj2.Bundle match {
|
||||
case MultiPacketBundle(list) =>
|
||||
list.size mustEqual 3
|
||||
list.head mustEqual packet3
|
||||
list(1) mustEqual packet1
|
||||
list(2) mustEqual packet2
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue