PSF-LoginServer/src/main/scala/net/psforever/packet/ControlPacketOpcode.scala
2021-04-17 10:08:16 +02:00

98 lines
3.8 KiB
Scala

// Copyright (c) 2017 PSForever
package net.psforever.packet
import net.psforever.packet.control.{RelatedA, RelatedB, SlottedMetaPacket}
import scodec.bits.BitVector
import scodec.{Attempt, Codec, DecodeResult, Err}
import scodec.codecs._
import scala.annotation.switch
object ControlPacketOpcode extends Enumeration {
type Type = Value
val
// OPCODES 0x00-0f
HandleGamePacket, // a whoopsi case: not actually a control packet, but a game packet
ClientStart, // first packet ever sent during client connection
ServerStart, // second packet sent in response to ClientStart
MultiPacket, // used to send multiple packets with one UDP message (subpackets limited to <= 255)
Unknown4, //
TeardownConnection, //
Unknown6, //
ControlSync, // sent to the server from the client
// 0x08
ControlSyncResp, // the response generated by the server
SlottedMetaPacket0, //
SlottedMetaPacket1, //
SlottedMetaPacket2, //
SlottedMetaPacket3, //
SlottedMetaPacket4, //
SlottedMetaPacket5, //
SlottedMetaPacket6, //
// OPCODES 0x10-1f
SlottedMetaPacket7, //
RelatedA0, //
RelatedA1, //
RelatedA2, //
RelatedA3, //
RelatedB0, //
RelatedB1, //
RelatedB2, //
// 0x18
RelatedB3, //
MultiPacketEx, // same as MultiPacket, but with the ability to send extended length packets
Unknown26, //
Unknown27, //
Unknown28, //
ConnectionClose, //
Unknown30 // Probably a more lightweight variant of ClientStart, containing only the client nonce
= Value
private def noDecoder(opcode: ControlPacketOpcode.Type) =
(bits: BitVector) => Attempt.failure(Err(s"Could not find a marshaller for control packet $opcode (${bits.toHex})"))
def getPacketDecoder(
opcode: ControlPacketOpcode.Type
): (BitVector) => Attempt[DecodeResult[PlanetSideControlPacket]] =
(opcode.id: @switch) match {
// OPCODES 0x00-0f
case 0x00 => control.HandleGamePacket.decode
case 0x01 => control.ClientStart.decode
case 0x02 => control.ServerStart.decode
case 0x03 => control.MultiPacket.decode
case 0x04 => noDecoder(Unknown4)
case 0x05 => control.TeardownConnection.decode
case 0x06 => noDecoder(Unknown6)
case 0x07 => control.ControlSync.decode
// 0x08
case 0x08 => control.ControlSyncResp.decode
case 0x09 => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket0)
case 0x0a => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket1)
case 0x0b => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket2)
case 0x0c => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket3)
case 0x0d => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket4)
case 0x0e => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket5)
case 0x0f => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket6)
// OPCODES 0x10-1e
case 0x10 => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket7)
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 => RelatedB.decodeWithOpcode(RelatedB3)
case 0x19 => control.MultiPacketEx.decode
case 0x1a => noDecoder(Unknown26)
case 0x1b => noDecoder(Unknown27)
case 0x1c => noDecoder(Unknown28)
case 0x1d => control.ConnectionClose.decode
case 0x1e => control.Unknown30.decode
case _ => noDecoder(opcode)
}
implicit val codec: Codec[this.Value] = PacketHelpers.createEnumerationCodec(this, uint8L)
}