Packet: Fix VNL packet to support multiple servers

This commit is contained in:
Chord 2019-12-15 21:45:14 -05:00 committed by pschord
parent 6d0649c25b
commit 37ad423820
3 changed files with 40 additions and 30 deletions

View file

@ -30,7 +30,8 @@ final case class WorldInformation(name : String, status : WorldStatus.Value,
connections : Vector[WorldConnectionInfo],
empireNeed : PlanetSideEmpire.Value)
final case class VNLWorldStatusMessage(welcomeMessage : String, worlds : Vector[WorldInformation])
final case class VNLWorldStatusMessage(welcomeMessage : String, world_count : Int, world : WorldInformation,
other_worlds : Vector[WorldInformation] = Vector())
extends PlanetSideGamePacket {
type Packet = VNLWorldStatusMessage
def opcode = GamePacketOpcode.VNLWorldStatusMessage
@ -99,17 +100,28 @@ object VNLWorldStatusMessage extends Marshallable[VNLWorldStatusMessage] {
(bytes(4) :: uint16L).xmap(decode, encode).as[WorldConnectionInfo]
}
implicit val world_codec : Codec[WorldInformation] = (
("world_name" | PacketHelpers.encodedString) :: (
("status_and_type" | statusCodec) :+
// TODO: limit the size of this vector to 11 as the client will fail on any more
("connections" | vectorOfN(uint8L, connectionCodec))
:+
("empire_need" | PlanetSideEmpire.codec)
)).as[WorldInformation]
implicit val world_codec_aligned : Codec[WorldInformation] = (
("world_name" | PacketHelpers.encodedStringAligned(6)) :: (
("status_and_type" | statusCodec) :+
// TODO: limit the size of this vector to 11 as the client will fail on any more
("connections" | vectorOfN(uint8L, connectionCodec))
:+
("empire_need" | PlanetSideEmpire.codec)
)).as[WorldInformation]
implicit val codec : Codec[VNLWorldStatusMessage] = (
("welcome_message" | PacketHelpers.encodedWideString) ::
("worlds" | vectorOfN(uint8L, (
// XXX: this needs to be limited to 0x20 bytes
// XXX: this needs to be byte aligned, but not sure how to do this
("world_name" | PacketHelpers.encodedString) :: (
("status_and_type" | statusCodec) :+
// TODO: limit the size of this vector to 11 as the client will fail on any more
("connections" | vectorOfN(uint8L, connectionCodec)) :+
("empire_need" | PlanetSideEmpire.codec)
)
).as[WorldInformation]
))).as[VNLWorldStatusMessage]
(("num_worlds" | uint8L) flatPrepend { num_worlds =>
("primary_world" | world_codec) ::
("extra_worlds" | vectorOfN(provide(num_worlds-1), world_codec_aligned)
)})).as[VNLWorldStatusMessage]
}

View file

@ -16,12 +16,9 @@ class VNLWorldStatusMessageTest extends Specification {
"decode" in {
PacketCoding.DecodePacket(string).require match {
case VNLWorldStatusMessage(message, worlds) =>
worlds.length mustEqual 1
case VNLWorldStatusMessage(message, _, world, extra_worlds) =>
extra_worlds.length mustEqual 0
message mustEqual "Welcome to PlanetSide! "
val world = worlds {
0
}
world.name mustEqual "gemini"
world.empireNeed mustEqual PlanetSideEmpire.NC
world.status mustEqual WorldStatus.Up
@ -39,13 +36,11 @@ class VNLWorldStatusMessageTest extends Specification {
}
"encode" in {
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
Vector(
WorldInformation("gemini", WorldStatus.Up, ServerType.Released,
Vector(
WorldConnectionInfo(new InetSocketAddress(InetAddress.getByName("64.37.158.69"), 30007))
), PlanetSideEmpire.NC
)
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ", 1,
WorldInformation("gemini", WorldStatus.Up, ServerType.Released,
Vector(
WorldConnectionInfo(new InetSocketAddress(InetAddress.getByName("64.37.158.69"), 30007))
), PlanetSideEmpire.NC
)
)
//0100 04 00 01459e2540377540
@ -56,15 +51,15 @@ class VNLWorldStatusMessageTest extends Specification {
}
"encode and decode multiple worlds" in {
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ", 2,
WorldInformation("ABCDABCD1", WorldStatus.Up, ServerType.Released, Vector(), PlanetSideEmpire.NC),
Vector(
WorldInformation("PSForever1", WorldStatus.Up, ServerType.Released, Vector(), PlanetSideEmpire.NC),
WorldInformation("PSForever2", WorldStatus.Down, ServerType.Beta, Vector(), PlanetSideEmpire.TR)
WorldInformation("ABCDABCD2", WorldStatus.Down, ServerType.Beta, Vector(), PlanetSideEmpire.TR)
))
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
//println(pkt)
println(pkt)
// TODO: actually test something
ok

View file

@ -164,10 +164,13 @@ class LoginSessionActor extends Actor with MDCContextAware {
}
def updateServerList() = {
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ", 2,
WorldInformation(
serverName, WorldStatus.Up, ServerType.Beta, Vector(WorldConnectionInfo(serverAddress)), PlanetSideEmpire.VS
),
Vector(
WorldInformation(
serverName, WorldStatus.Up, ServerType.Beta, Vector(WorldConnectionInfo(serverAddress)), PlanetSideEmpire.VS
serverName + "A", WorldStatus.Up, ServerType.Beta, Vector(WorldConnectionInfo(serverAddress)), PlanetSideEmpire.TR
)
)
)