mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Handle meta packet and return ack. server scroller
The scroller isn't usable in production as the client will deselect the server listing each time the list is updated. This prevents you from selecting a server.
This commit is contained in:
parent
c7f70e3543
commit
cdf240cf66
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2016 PSForever.net to present
|
||||
package net.psforever.packet.control
|
||||
|
||||
import net.psforever.packet.{ControlPacketOpcode, Marshallable, PlanetSideControlPacket}
|
||||
import scodec.Codec
|
||||
import scodec.bits.{BitVector, ByteOrdering, ByteVector}
|
||||
import scodec.codecs._
|
||||
|
||||
final case class SlottedMetaAck(slot : Int, subslot : Int)
|
||||
extends PlanetSideControlPacket {
|
||||
type Packet = SlottedMetaAck
|
||||
|
||||
assert(slot >= 0 && slot <= 7, s"Slot number ($slot) is out of range")
|
||||
|
||||
def opcode = {
|
||||
val base = ControlPacketOpcode.RelatedB0.id
|
||||
ControlPacketOpcode(base + slot % 4)
|
||||
}
|
||||
|
||||
// XXX: a nasty hack to ignore the "slot" field
|
||||
// There is so much wrong with this it's not even funny. Why scodec, whyyyy...
|
||||
// I've never had a library make me feel so stupid and smart at the same time
|
||||
def encode = SlottedMetaAck.encode(this).map(vect => vect.drop(8))
|
||||
}
|
||||
|
||||
object SlottedMetaAck extends Marshallable[SlottedMetaAck] {
|
||||
implicit val codec : Codec[SlottedMetaAck] = (
|
||||
("slot" | uint8L.xmap[Int](a => a - ControlPacketOpcode.RelatedB0.id, a=>a) ) ::
|
||||
("subslot" | uint16)
|
||||
).as[SlottedMetaAck]
|
||||
|
||||
def decodeWithOpcode(slot : ControlPacketOpcode.Value)(bits : BitVector) = {
|
||||
decode(ControlPacketOpcode.codec.encode(slot).require ++ bits)
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +255,8 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
|||
def handleEstablishedPacket(from : ActorRef, cont : PlanetSidePacketContainer) = {
|
||||
// we are processing a packet we decrypted
|
||||
if(from == self) {
|
||||
rightRef ! cont
|
||||
import MDCContextAware.Implicits._
|
||||
rightRef !> cont
|
||||
} else if(from == rightRef) { // processing a completed packet from the right. encrypt
|
||||
val packet = PacketCoding.encryptPacket(cryptoState.get, cont).require
|
||||
sendResponse(packet)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@
|
|||
import java.net.{InetAddress, InetSocketAddress}
|
||||
|
||||
import akka.actor.{Actor, ActorRef, MDCContextAware}
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.{PlanetSideGamePacket, _}
|
||||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.game._
|
||||
import scodec.Attempt.{Failure, Successful}
|
||||
import scodec.bits._
|
||||
|
||||
import scala.util.Random
|
||||
|
||||
class LoginSessionActor extends Actor with MDCContextAware {
|
||||
private[this] val log = org.log4s.getLogger
|
||||
|
||||
private case class UpdateServerList()
|
||||
|
||||
var leftRef : ActorRef = ActorRef.noSender
|
||||
var rightRef : ActorRef = ActorRef.noSender
|
||||
|
||||
|
|
@ -28,27 +32,108 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
def Started : Receive = {
|
||||
case UpdateServerList() =>
|
||||
updateServerList
|
||||
case ctrl @ ControlPacket(_, _) =>
|
||||
handlePkt(ctrl)
|
||||
handlePktContainer(ctrl)
|
||||
case game @ GamePacket(_, _, _) =>
|
||||
handlePkt(game)
|
||||
handlePktContainer(game)
|
||||
case default => failWithError(s"Invalid packet class received: $default")
|
||||
}
|
||||
|
||||
def handlePkt(pkt : PlanetSidePacketContainer) : Unit = pkt match {
|
||||
def handlePkt(pkt : PlanetSidePacket) : Unit = pkt match {
|
||||
case ctrl : PlanetSideControlPacket =>
|
||||
handleControlPkt(ctrl)
|
||||
case game : PlanetSideGamePacket =>
|
||||
handleGamePkt(game)
|
||||
case default => failWithError(s"Invalid packet class received: $default")
|
||||
}
|
||||
|
||||
def handlePktContainer(pkt : PlanetSidePacketContainer) : Unit = pkt match {
|
||||
case ctrl @ ControlPacket(opcode, ctrlPkt) =>
|
||||
handleControlPkt(ctrlPkt)
|
||||
case game @ GamePacket(opcode, seq, gamePkt) =>
|
||||
handleGamePkt(gamePkt)
|
||||
case default => failWithError(s"Invalid packet class received: $default")
|
||||
case default => failWithError(s"Invalid packet container class received: $default")
|
||||
}
|
||||
|
||||
def handleControlPkt(pkt : PlanetSideControlPacket) = {
|
||||
pkt match {
|
||||
case meta @ SlottedMetaPacket(slot, subslot, innerPacket) =>
|
||||
case SlottedMetaPacket(slot, subslot, innerPacket) =>
|
||||
sendResponse(PacketCoding.CreateControlPacket(SlottedMetaAck(slot, subslot)))
|
||||
|
||||
PacketCoding.DecodePacket(innerPacket) match {
|
||||
case Successful(p) =>
|
||||
log.trace("RECV[INNER]: " + p)
|
||||
case Failure(e) =>
|
||||
log.error(s"Failed to decode inner packet of SlottedMetaPacket: $e")
|
||||
case Successful(v) =>
|
||||
handlePkt(v)
|
||||
}
|
||||
case MultiPacket(packets) =>
|
||||
packets.foreach { pkt =>
|
||||
PacketCoding.DecodePacket(pkt) match {
|
||||
case Failure(e) =>
|
||||
log.error(s"Failed to decode inner packet of MultiPacket: $e")
|
||||
case Successful(v) =>
|
||||
handlePkt(v)
|
||||
}
|
||||
}
|
||||
case default =>
|
||||
log.debug(s"Unhandled ControlPacket $default")
|
||||
}
|
||||
}
|
||||
|
||||
def handleGamePkt(pkt : PlanetSideGamePacket) = pkt match {
|
||||
case LoginMessage(majorVersion, minorVersion, buildDate, username,
|
||||
password, token, revision) =>
|
||||
|
||||
val clientVersion = s"Client Version: ${majorVersion}.${minorVersion}.${revision}, ${buildDate}"
|
||||
|
||||
if(token.isDefined)
|
||||
log.info(s"New login UN:$username Token:${token.get}. ${clientVersion}")
|
||||
else
|
||||
log.info(s"New login UN:$username PW:$password. ${clientVersion}")
|
||||
|
||||
val newToken = token.getOrElse("THISISMYTOKENYES")
|
||||
val response = LoginRespMessage(newToken, hex"00000000 18FABE0C 00000000 00000000",
|
||||
0, 1, 2, 685276011, username, 0, false)
|
||||
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, response))
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
context.system.scheduler.schedule(0 seconds, 250 milliseconds, self, UpdateServerList())
|
||||
|
||||
case default => log.debug(s"Unhandled GamePacket ${pkt}")
|
||||
}
|
||||
|
||||
val scrollerWindow = 20
|
||||
val scrollerText = "PSForever_The_next_generation_of_PlanetSide_Hey_what_a_neat_scroller!"
|
||||
var scrollerOffset = 0
|
||||
|
||||
def updateServerList = {
|
||||
val start = scrollerOffset % scrollerText.length
|
||||
var end = (scrollerOffset+scrollerWindow) % scrollerText.length
|
||||
|
||||
var finalName = ""
|
||||
if(end < start)
|
||||
finalName = scrollerText.substring(start, scrollerText.length) + ";" + scrollerText.substring(0, end)
|
||||
else
|
||||
finalName = scrollerText.substring(start, end)
|
||||
|
||||
scrollerOffset += 1
|
||||
|
||||
//println(finalName)
|
||||
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
||||
Vector(
|
||||
WorldInformation(finalName, WorldStatus.Up, ServerType.Development,
|
||||
Vector(WorldConnectionInfo(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 51000))), EmpireNeed.TR)
|
||||
))
|
||||
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, msg))
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
val packet = LoginRespMessage("AAAABBBBCCCCDDDD",
|
||||
hex"00000000 18FABE0C 00000000 00000000",
|
||||
|
|
@ -65,26 +150,7 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
|||
))
|
||||
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, msg))
|
||||
case Failure(e) => log.error("Failed to decode inner packet " + e)
|
||||
}
|
||||
case MultiPacket(packets) =>
|
||||
packets.foreach { pkt =>
|
||||
PacketCoding.UnmarshalPacket(pkt) match {
|
||||
case Failure(e) =>
|
||||
log.error(s"Failed to decode inner packet of MultiPacket: $e")
|
||||
case Successful(v) =>
|
||||
handlePkt(v) // dont send a message to ourselves as then packets will be processed in the wrong order
|
||||
}
|
||||
}
|
||||
case default =>
|
||||
log.debug(s"Unhandled ControlPacket $default")
|
||||
}
|
||||
}
|
||||
|
||||
def handleGamePkt(pkt : PlanetSideGamePacket) = {
|
||||
log.debug(s"Unhandled GamePacket ${pkt}")
|
||||
}
|
||||
|
||||
*/
|
||||
def failWithError(error : String) = {
|
||||
log.error(error)
|
||||
//sendResponse(PacketCoding.CreateControlPacket(ConnectionClose()))
|
||||
|
|
|
|||
Loading…
Reference in a new issue