mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
[Packet] VNLWorldStatus message - added IP port
Found out that the hidden fields were an array of IP and ports
This commit is contained in:
parent
cc87c15b21
commit
f762aa8e1f
|
|
@ -1,5 +1,8 @@
|
||||||
// Copyright (c) 2016 PSForever.net to present
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
package psforever.net
|
package psforever.net
|
||||||
|
|
||||||
|
import java.net.{InetAddress, InetSocketAddress}
|
||||||
|
|
||||||
import scodec._
|
import scodec._
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
|
|
@ -24,8 +27,12 @@ object EmpireNeed extends Enumeration {
|
||||||
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint2L)
|
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint2L)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final case class WorldConnectionInfo(address : InetSocketAddress)
|
||||||
|
|
||||||
final case class WorldInformation(name : String, status : WorldStatus.Value,
|
final case class WorldInformation(name : String, status : WorldStatus.Value,
|
||||||
serverType : ServerType.Value, empireNeed : EmpireNeed.Value)
|
serverType : ServerType.Value,
|
||||||
|
connections : Vector[WorldConnectionInfo],
|
||||||
|
empireNeed : EmpireNeed.Value)
|
||||||
|
|
||||||
final case class VNLWorldStatusMessage(welcomeMessage : String, worlds : Vector[WorldInformation])
|
final case class VNLWorldStatusMessage(welcomeMessage : String, worlds : Vector[WorldInformation])
|
||||||
extends PlanetSideGamePacket {
|
extends PlanetSideGamePacket {
|
||||||
|
|
@ -74,6 +81,28 @@ object VNLWorldStatusMessage extends Marshallable[VNLWorldStatusMessage] {
|
||||||
("status1" | uint8L)).xmap(to, from)
|
("status1" | uint8L)).xmap(to, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implicit val connectionCodec : Codec[WorldConnectionInfo] = {
|
||||||
|
|
||||||
|
type DecodeStruct = ByteVector :: Int :: HNil
|
||||||
|
type EncodeStruct = InetSocketAddress :: HNil
|
||||||
|
|
||||||
|
def decode(a : DecodeStruct) : EncodeStruct = a match {
|
||||||
|
case ipBytes :: port :: HNil =>
|
||||||
|
val addr = new InetSocketAddress(InetAddress.getByAddress(ipBytes.reverse.toArray), port)
|
||||||
|
addr :: HNil
|
||||||
|
}
|
||||||
|
|
||||||
|
def encode(a : EncodeStruct) : DecodeStruct = a match {
|
||||||
|
case addr :: HNil =>
|
||||||
|
val ip = addr.getAddress.getAddress
|
||||||
|
val port = addr.getPort
|
||||||
|
|
||||||
|
ByteVector(ip).reverse :: port :: HNil
|
||||||
|
}
|
||||||
|
|
||||||
|
(bytes(4) :: uint16L).xmap(decode, encode).as[WorldConnectionInfo]
|
||||||
|
}
|
||||||
|
|
||||||
implicit val codec : Codec[VNLWorldStatusMessage] = (
|
implicit val codec : Codec[VNLWorldStatusMessage] = (
|
||||||
("welcome_message" | PacketHelpers.encodedWideString) ::
|
("welcome_message" | PacketHelpers.encodedWideString) ::
|
||||||
("worlds" | vectorOfN(uint8L, (
|
("worlds" | vectorOfN(uint8L, (
|
||||||
|
|
@ -81,7 +110,8 @@ object VNLWorldStatusMessage extends Marshallable[VNLWorldStatusMessage] {
|
||||||
// XXX: this needs to be byte aligned, but not sure how to do this
|
// XXX: this needs to be byte aligned, but not sure how to do this
|
||||||
("world_name" | PacketHelpers.encodedString) :: (
|
("world_name" | PacketHelpers.encodedString) :: (
|
||||||
("status_and_type" | statusCodec) :+
|
("status_and_type" | statusCodec) :+
|
||||||
("unknown" | constant(hex"01459e25403775")) :+
|
// TODO: limit the size of this vector to 11 as the client will fail on any more
|
||||||
|
("connections" | vectorOfN(uint8L, connectionCodec)) :+
|
||||||
("empire_need" | EmpireNeed.codec)
|
("empire_need" | EmpireNeed.codec)
|
||||||
)
|
)
|
||||||
).as[WorldInformation]
|
).as[WorldInformation]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
// Copyright (c) 2016 PSForever.net to present
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
|
import java.net.{InetAddress, InetSocketAddress}
|
||||||
|
|
||||||
import org.specs2.mutable._
|
import org.specs2.mutable._
|
||||||
import psforever.net._
|
import psforever.net._
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
|
|
@ -17,9 +19,15 @@ class GamePacketTest extends Specification {
|
||||||
case VNLWorldStatusMessage(message, worlds) =>
|
case VNLWorldStatusMessage(message, worlds) =>
|
||||||
worlds.length mustEqual 1
|
worlds.length mustEqual 1
|
||||||
message mustEqual "Welcome to PlanetSide! "
|
message mustEqual "Welcome to PlanetSide! "
|
||||||
worlds{0}.name mustEqual "gemini"
|
val world = worlds{0}
|
||||||
worlds{0}.empireNeed mustEqual EmpireNeed.NC
|
|
||||||
worlds{0}.status mustEqual WorldStatus.Up
|
world.name mustEqual "gemini"
|
||||||
|
world.empireNeed mustEqual EmpireNeed.NC
|
||||||
|
world.status mustEqual WorldStatus.Up
|
||||||
|
|
||||||
|
world.connections.length mustEqual 1
|
||||||
|
world.connections{0}.address.getPort mustEqual 30007
|
||||||
|
world.connections{0}.address.getAddress.toString mustEqual "/64.37.158.69"
|
||||||
case default =>
|
case default =>
|
||||||
true mustEqual false
|
true mustEqual false
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +35,14 @@ class GamePacketTest extends Specification {
|
||||||
|
|
||||||
"encode" in {
|
"encode" in {
|
||||||
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
||||||
Vector(WorldInformation("gemini", WorldStatus.Up, ServerType.Beta, EmpireNeed.NC)))
|
Vector(
|
||||||
|
WorldInformation("gemini", WorldStatus.Up, ServerType.Beta,
|
||||||
|
Vector(
|
||||||
|
WorldConnectionInfo(new InetSocketAddress(InetAddress.getByName("64.37.158.69"), 30007))
|
||||||
|
), EmpireNeed.NC
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
//0100 04 00 01459e2540377540
|
//0100 04 00 01459e2540377540
|
||||||
|
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
@ -38,8 +53,8 @@ class GamePacketTest 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! ",
|
||||||
Vector(
|
Vector(
|
||||||
WorldInformation("PSForever1", WorldStatus.Up, ServerType.Released, EmpireNeed.NC),
|
WorldInformation("PSForever1", WorldStatus.Up, ServerType.Released, Vector(), EmpireNeed.NC),
|
||||||
WorldInformation("PSForever2", WorldStatus.Down, ServerType.Beta, EmpireNeed.TR)
|
WorldInformation("PSForever2", WorldStatus.Down, ServerType.Beta, Vector(), EmpireNeed.TR)
|
||||||
))
|
))
|
||||||
|
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ class LoginSessionActor(session : LoginSession) extends Actor with ActorLogging
|
||||||
|
|
||||||
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
||||||
Vector(
|
Vector(
|
||||||
WorldInformation("gemini", WorldStatus.Up, ServerType.Released, EmpireNeed.NC)
|
WorldInformation("gemini", WorldStatus.Up, ServerType.Released, Vector(), EmpireNeed.NC)
|
||||||
))
|
))
|
||||||
|
|
||||||
sendResponse(PacketCoding.encryptPacket(cryptoState.get, PacketCoding.CreateGamePacket(4,
|
sendResponse(PacketCoding.encryptPacket(cryptoState.get, PacketCoding.CreateGamePacket(4,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue