diff --git a/common/src/main/scala/net/psforever/packet/ControlPacketOpcode.scala b/common/src/main/scala/net/psforever/packet/ControlPacketOpcode.scala index bf413ba1..9a4be3ed 100644 --- a/common/src/main/scala/net/psforever/packet/ControlPacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/ControlPacketOpcode.scala @@ -19,8 +19,8 @@ object ControlPacketOpcode extends Enumeration { Unknown4, Unknown5, Unknown6, - Unknown7, - Unknown8, + ControlSync, // sent to the server from the client + ControlSyncResp, // the response generated by the server SlottedMetaPacket0, // OPCODE 10 @@ -56,6 +56,8 @@ object ControlPacketOpcode extends Enumeration { case ServerStart => control.ServerStart.decode case ClientStart => control.ClientStart.decode case MultiPacket => control.MultiPacket.decode + case ControlSync => control.ControlSync.decode + case ControlSyncResp => control.ControlSyncResp.decode // IT'S GETTING "WET" IN HERE case SlottedMetaPacket0 => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket0) case SlottedMetaPacket1 => SlottedMetaPacket.decodeWithOpcode(SlottedMetaPacket1) diff --git a/common/src/main/scala/net/psforever/packet/control/ControlSync.scala b/common/src/main/scala/net/psforever/packet/control/ControlSync.scala new file mode 100644 index 00000000..ec3682de --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/control/ControlSync.scala @@ -0,0 +1,28 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.control + +import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket} +import scodec.Codec +import scodec.codecs._ + +final case class ControlSync(timeDiff : Int, unk : Long, + field1 : Long, field2 : Long, field3 : Long, field4 : Long, + field64A : Long, field64B : Long) + extends PlanetSideControlPacket { + type Packet = ControlSync + def opcode = ControlPacketOpcode.ControlSync + def encode = ControlSync.encode(this) +} + +object ControlSync extends Marshallable[ControlSync] { + implicit val codec : Codec[ControlSync] = ( + ("time_diff" | uint16) :: + ("unk" | uint32) :: + ("field1" | uint32) :: + ("field2" | uint32) :: + ("field3" | uint32) :: + ("field4" | uint32) :: + ("field64A" | int64) :: + ("field64B" | int64) + ).as[ControlSync] +} \ No newline at end of file diff --git a/common/src/main/scala/net/psforever/packet/control/ControlSyncResp.scala b/common/src/main/scala/net/psforever/packet/control/ControlSyncResp.scala new file mode 100644 index 00000000..7ade14ad --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/control/ControlSyncResp.scala @@ -0,0 +1,25 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.control + +import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket} +import scodec.Codec +import scodec.codecs._ + +final case class ControlSyncResp(timeDiff : Int, unk : Long, + field1 : Long, field2 : Long, field3 : Long, field4 : Long) + extends PlanetSideControlPacket { + type Packet = ControlSyncResp + def opcode = ControlPacketOpcode.ControlSyncResp + def encode = ControlSyncResp.encode(this) +} + +object ControlSyncResp extends Marshallable[ControlSyncResp] { + implicit val codec : Codec[ControlSyncResp] = ( + ("time_diff" | uint16) :: + ("unk" | uint32) :: + ("field1" | int64) :: + ("field2" | int64) :: + ("field3" | int64) :: + ("field4" | int64) + ).as[ControlSyncResp] +} \ No newline at end of file diff --git a/common/src/test/scala/ControlPacketTest.scala b/common/src/test/scala/ControlPacketTest.scala index 59a2442f..610ee22b 100644 --- a/common/src/test/scala/ControlPacketTest.scala +++ b/common/src/test/scala/ControlPacketTest.scala @@ -10,7 +10,58 @@ import scodec.codecs.uint16 class ControlPacketTest extends Specification { "PlanetSide control packet" in { - val cNonce = 656287232 + "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 => + true mustEqual false + } + } + + "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 => + true mustEqual false + } + } + + "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" ++