mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-12 23:14:42 +00:00
Packet: MultiPacketEx, CharacterRequestMessage
Rename AggregatePacket -> MultiPacketEx as it makes more sense
This commit is contained in:
parent
9a0ef28723
commit
7b82491d0e
6 changed files with 143 additions and 4 deletions
|
|
@ -41,7 +41,7 @@ object ControlPacketOpcode extends Enumeration {
|
||||||
RelatedB1,
|
RelatedB1,
|
||||||
RelatedB2,
|
RelatedB2,
|
||||||
RelatedB3,
|
RelatedB3,
|
||||||
AggregatePacket, // same as MultiPacket, but with the ability to send extended length packets
|
MultiPacketEx, // same as MultiPacket, but with the ability to send extended length packets
|
||||||
Unknown26,
|
Unknown26,
|
||||||
Unknown27,
|
Unknown27,
|
||||||
Unknown28,
|
Unknown28,
|
||||||
|
|
@ -85,7 +85,7 @@ object ControlPacketOpcode extends Enumeration {
|
||||||
case RelatedB1 => noDecoder(opcode)
|
case RelatedB1 => noDecoder(opcode)
|
||||||
case RelatedB2 => noDecoder(opcode)
|
case RelatedB2 => noDecoder(opcode)
|
||||||
case RelatedB3 => noDecoder(opcode)
|
case RelatedB3 => noDecoder(opcode)
|
||||||
case AggregatePacket => noDecoder(opcode)
|
case MultiPacketEx => control.MultiPacketEx.decode
|
||||||
case Unknown26 => noDecoder(opcode)
|
case Unknown26 => noDecoder(opcode)
|
||||||
case Unknown27 => noDecoder(opcode)
|
case Unknown27 => noDecoder(opcode)
|
||||||
case Unknown28 => noDecoder(opcode)
|
case Unknown28 => noDecoder(opcode)
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ object GamePacketOpcode extends Enumeration {
|
||||||
UnknownMessage45,
|
UnknownMessage45,
|
||||||
UnknownMessage46,
|
UnknownMessage46,
|
||||||
UnknownMessage47,
|
UnknownMessage47,
|
||||||
UnknownMessage48,
|
CharacterRequestMessage,
|
||||||
LoadMapMessage,
|
LoadMapMessage,
|
||||||
|
|
||||||
// OPCODE 50
|
// OPCODE 50
|
||||||
|
|
@ -380,7 +380,7 @@ object GamePacketOpcode extends Enumeration {
|
||||||
case UnknownMessage45 => noDecoder(opcode)
|
case UnknownMessage45 => noDecoder(opcode)
|
||||||
case UnknownMessage46 => noDecoder(opcode)
|
case UnknownMessage46 => noDecoder(opcode)
|
||||||
case UnknownMessage47 => noDecoder(opcode)
|
case UnknownMessage47 => noDecoder(opcode)
|
||||||
case UnknownMessage48 => noDecoder(opcode)
|
case CharacterRequestMessage => game.CharacterRequestMessage.decode
|
||||||
case LoadMapMessage => noDecoder(opcode)
|
case LoadMapMessage => noDecoder(opcode)
|
||||||
|
|
||||||
// OPCODE 50
|
// OPCODE 50
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
|
package net.psforever.packet.control
|
||||||
|
|
||||||
|
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||||
|
import scodec.{Attempt, Codec, DecodeResult, SizeBound}
|
||||||
|
import scodec.bits._
|
||||||
|
import scodec.codecs._
|
||||||
|
|
||||||
|
final case class MultiPacketEx(packets : Vector[ByteVector])
|
||||||
|
extends PlanetSideControlPacket {
|
||||||
|
type Packet = MultiPacketEx
|
||||||
|
def opcode = ControlPacketOpcode.MultiPacketEx
|
||||||
|
def encode = MultiPacketEx.encode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
object MultiPacketEx extends Marshallable[MultiPacketEx] {
|
||||||
|
val ffFound: Codec[Boolean] = new Codec[Boolean] {
|
||||||
|
def sizeBound = SizeBound.exact(0)
|
||||||
|
def encode(b: Boolean) =
|
||||||
|
if(b)
|
||||||
|
Attempt.successful(hex"ff".bits)
|
||||||
|
else
|
||||||
|
Attempt.successful(bin"")
|
||||||
|
def decode(b: BitVector) = {
|
||||||
|
if (b.length >= 8 && b.take(8) == hex"ff".bits)
|
||||||
|
Attempt.successful(DecodeResult(true, b.drop(8)))
|
||||||
|
else
|
||||||
|
Attempt.successful(DecodeResult(false, b))
|
||||||
|
}
|
||||||
|
|
||||||
|
override def toString = "bitsRemaining"
|
||||||
|
}
|
||||||
|
|
||||||
|
val twoffFound: Codec[Boolean] = new Codec[Boolean] {
|
||||||
|
def sizeBound = SizeBound.exact(0)
|
||||||
|
def encode(b: Boolean) =
|
||||||
|
if(b)
|
||||||
|
Attempt.successful(hex"ffff".bits)
|
||||||
|
else
|
||||||
|
Attempt.successful(bin"")
|
||||||
|
def decode(b: BitVector) = {
|
||||||
|
if (b.length >= 16 && b.take(16) == hex"ffff".bits)
|
||||||
|
Attempt.successful(DecodeResult(true, b.drop(16)))
|
||||||
|
else
|
||||||
|
Attempt.successful(DecodeResult(false, b))
|
||||||
|
}
|
||||||
|
|
||||||
|
override def toString = "bitsRemaining"
|
||||||
|
}
|
||||||
|
|
||||||
|
val sizeCodec = either(ffFound, uint8L,
|
||||||
|
either(twoffFound, uint16L, uint32L).xmap[Long](
|
||||||
|
(a : Either[Int, Long]) => a.fold[Long](a => a, a => a),
|
||||||
|
(a : Long) =>
|
||||||
|
if(a < 0xffff) Left(a.toInt) else Right(a)
|
||||||
|
)
|
||||||
|
).xmap[Long](
|
||||||
|
(a : Either[Int, Long]) => a.fold[Long](a => a, a => a),
|
||||||
|
(a : Long) =>
|
||||||
|
if(a < 0xff) Left(a.toInt) else Right(a)
|
||||||
|
)
|
||||||
|
|
||||||
|
implicit val codec : Codec[MultiPacketEx] = (
|
||||||
|
("packets" | vector(variableSizeBytesLong(sizeCodec, bytes)))
|
||||||
|
).as[MultiPacketEx]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
|
package net.psforever.packet.game
|
||||||
|
|
||||||
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
|
import scodec.Codec
|
||||||
|
import scodec.codecs._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is sent by the PlanetSide client when selecting a character to play from the character selection
|
||||||
|
* menu.
|
||||||
|
*/
|
||||||
|
final case class CharacterRequestMessage(unk : Long, unk2 : Long)
|
||||||
|
extends PlanetSideGamePacket {
|
||||||
|
type Packet = CharacterRequestMessage
|
||||||
|
def opcode = GamePacketOpcode.CharacterRequestMessage
|
||||||
|
def encode = CharacterRequestMessage.encode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
object CharacterRequestMessage extends Marshallable[CharacterRequestMessage] {
|
||||||
|
implicit val codec : Codec[CharacterRequestMessage] = (
|
||||||
|
("unk1" | uint32L) ::
|
||||||
|
("unk2" | uint32L)
|
||||||
|
).as[CharacterRequestMessage]
|
||||||
|
}
|
||||||
|
|
@ -129,5 +129,45 @@ class ControlPacketTest extends Specification {
|
||||||
PacketCoding.EncodePacket(SlottedMetaPacket(0, 0x10000, hex"00")).require must throwA[IllegalArgumentException]
|
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 {
|
||||||
|
for(i <- strings.indices) {
|
||||||
|
MultiPacketEx.decode(strings{i}.bits).require.value mustEqual packets{i}
|
||||||
|
}
|
||||||
|
|
||||||
|
true mustEqual true
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode" in {
|
||||||
|
for(i <- packets.indices) {
|
||||||
|
MultiPacketEx.encode(packets{i}).require.toByteVector mustEqual strings{i}
|
||||||
|
}
|
||||||
|
|
||||||
|
true mustEqual true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +78,15 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
handlePkt(v)
|
handlePkt(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case MultiPacketEx(packets) =>
|
||||||
|
packets.foreach { pkt =>
|
||||||
|
PacketCoding.DecodePacket(pkt) match {
|
||||||
|
case Failure(e) =>
|
||||||
|
log.error(s"Failed to decode inner packet of MultiPacketEx: $e")
|
||||||
|
case Successful(v) =>
|
||||||
|
handlePkt(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
case default =>
|
case default =>
|
||||||
log.debug(s"Unhandled ControlPacket $default")
|
log.debug(s"Unhandled ControlPacket $default")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue