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], connections : Vector[WorldConnectionInfo],
empireNeed : PlanetSideEmpire.Value) 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 { extends PlanetSideGamePacket {
type Packet = VNLWorldStatusMessage type Packet = VNLWorldStatusMessage
def opcode = GamePacketOpcode.VNLWorldStatusMessage def opcode = GamePacketOpcode.VNLWorldStatusMessage
@ -99,17 +100,28 @@ object VNLWorldStatusMessage extends Marshallable[VNLWorldStatusMessage] {
(bytes(4) :: uint16L).xmap(decode, encode).as[WorldConnectionInfo] (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] = ( implicit val codec : Codec[VNLWorldStatusMessage] = (
("welcome_message" | PacketHelpers.encodedWideString) :: ("welcome_message" | PacketHelpers.encodedWideString) ::
("worlds" | vectorOfN(uint8L, ( (("num_worlds" | uint8L) flatPrepend { num_worlds =>
// XXX: this needs to be limited to 0x20 bytes ("primary_world" | world_codec) ::
// XXX: this needs to be byte aligned, but not sure how to do this ("extra_worlds" | vectorOfN(provide(num_worlds-1), world_codec_aligned)
("world_name" | PacketHelpers.encodedString) :: ( )})).as[VNLWorldStatusMessage]
("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]
} }

View file

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

View file

@ -164,10 +164,13 @@ class LoginSessionActor extends Actor with MDCContextAware {
} }
def updateServerList() = { 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( Vector(
WorldInformation( WorldInformation(
serverName, WorldStatus.Up, ServerType.Beta, Vector(WorldConnectionInfo(serverAddress)), PlanetSideEmpire.VS serverName + "A", WorldStatus.Up, ServerType.Beta, Vector(WorldConnectionInfo(serverAddress)), PlanetSideEmpire.TR
) )
) )
) )