mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Made some hacks to get to 100% on the World login
Literally sending raw bytes instead of actual packets. No fks given
This commit is contained in:
parent
3c07cc4cf0
commit
d27bd7988c
|
|
@ -214,23 +214,28 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
def Established : Receive = {
|
def Established : Receive = {
|
||||||
case RawPacket(msg) =>
|
case RawPacket(msg) =>
|
||||||
PacketCoding.UnmarshalPacket(msg) match {
|
if(sender() == rightRef) {
|
||||||
case Successful(p) =>
|
val packet = PacketCoding.encryptPacket(cryptoState.get, 0, msg).require
|
||||||
p match {
|
sendResponse(packet)
|
||||||
case encPacket @ EncryptedPacket(seq, _) =>
|
} else {
|
||||||
//println("Decrypting packet..." + encPacket)
|
PacketCoding.UnmarshalPacket(msg) match {
|
||||||
PacketCoding.decryptPacket(cryptoState.get, encPacket) match {
|
case Successful(p) =>
|
||||||
case Successful(packet) =>
|
p match {
|
||||||
//println("RECV[E]: " + packet)
|
case encPacket @ EncryptedPacket(seq, _) =>
|
||||||
|
//println("Decrypting packet..." + encPacket)
|
||||||
|
PacketCoding.decryptPacket(cryptoState.get, encPacket) match {
|
||||||
|
case Successful(packet) =>
|
||||||
|
//println("RECV[E]: " + packet)
|
||||||
|
|
||||||
self ! packet
|
self ! packet
|
||||||
case Failure(e) =>
|
case Failure(e) =>
|
||||||
log.error("Failed to decode encrypted packet: " + e)
|
log.error("Failed to decode encrypted packet: " + e)
|
||||||
}
|
}
|
||||||
case default => failWithError(s"Unexpected packet type $default in state Established")
|
case default => failWithError(s"Unexpected packet type $default in state Established")
|
||||||
|
|
||||||
}
|
}
|
||||||
case Failure(e) => log.error("Could not decode raw packet: " + e)
|
case Failure(e) => log.error("Could not decode raw packet: " + e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case ctrl @ ControlPacket(_, _) =>
|
case ctrl @ ControlPacket(_, _) =>
|
||||||
val from = sender()
|
val from = sender()
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
val serverName = "PSForever"
|
val serverName = "PSForever"
|
||||||
val serverAddress = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 51000)
|
val serverAddress = new InetSocketAddress(InetAddress.getLocalHost, 51001)
|
||||||
|
|
||||||
def handleGamePkt(pkt : PlanetSideGamePacket) = pkt match {
|
def handleGamePkt(pkt : PlanetSideGamePacket) = pkt match {
|
||||||
case LoginMessage(majorVersion, minorVersion, buildDate, username,
|
case LoginMessage(majorVersion, minorVersion, buildDate, username,
|
||||||
|
|
@ -134,4 +134,9 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
log.trace("LOGIN SEND: " + cont)
|
log.trace("LOGIN SEND: " + cont)
|
||||||
rightRef ! cont
|
rightRef ! cont
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def sendRawResponse(pkt : ByteVector) = {
|
||||||
|
log.trace("LOGIN SEND RAW: " + pkt)
|
||||||
|
rightRef ! RawPacket(pkt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,15 @@ object PsLogin {
|
||||||
|
|
||||||
//val system = ActorSystem("PsLogin", Some(ConfigFactory.parseMap(config)), None, Some(MDCPropagatingExecutionContextWrapper(ExecutionContext.Implicits.global)))
|
//val system = ActorSystem("PsLogin", Some(ConfigFactory.parseMap(config)), None, Some(MDCPropagatingExecutionContextWrapper(ExecutionContext.Implicits.global)))
|
||||||
val system = ActorSystem("PsLogin", ConfigFactory.parseMap(config))
|
val system = ActorSystem("PsLogin", ConfigFactory.parseMap(config))
|
||||||
val listener = system.actorOf(Props(new UdpListener(Props[SessionRouter], "session-router",
|
|
||||||
|
val loginTemplate = List(SessionPipeline("crypto-session-", Props[CryptoSessionActor]),
|
||||||
|
SessionPipeline("login-session-", Props[LoginSessionActor]))
|
||||||
|
val worldTemplate = List(SessionPipeline("crypto-session-", Props[CryptoSessionActor]),
|
||||||
|
SessionPipeline("world-session-", Props[WorldSessionActor]))
|
||||||
|
|
||||||
|
val listener = system.actorOf(Props(new UdpListener(Props(new SessionRouter(loginTemplate)), "login-session-router",
|
||||||
InetAddress.getLocalHost, 51000)), "login-udp-endpoint")
|
InetAddress.getLocalHost, 51000)), "login-udp-endpoint")
|
||||||
|
val worldListener = system.actorOf(Props(new UdpListener(Props(new SessionRouter(worldTemplate)), "world-session-router",
|
||||||
|
InetAddress.getLocalHost, 51001)), "world-udp-endpoint")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ case class SessionState(id : Long, address : InetSocketAddress, pipeline : List[
|
||||||
def nextOfStart = pipeline.tail.head
|
def nextOfStart = pipeline.tail.head
|
||||||
}
|
}
|
||||||
|
|
||||||
class SessionRouter extends Actor with MDCContextAware {
|
case class SessionPipeline(nameTemplate : String, props : Props)
|
||||||
|
|
||||||
|
class SessionRouter(pipeline : List[SessionPipeline]) extends Actor with MDCContextAware {
|
||||||
private[this] val log = org.log4s.getLogger
|
private[this] val log = org.log4s.getLogger
|
||||||
|
|
||||||
val idBySocket = mutable.Map[InetSocketAddress, Long]()
|
val idBySocket = mutable.Map[InetSocketAddress, Long]()
|
||||||
|
|
@ -112,15 +114,24 @@ class SessionRouter extends Actor with MDCContextAware {
|
||||||
def createNewSession(address : InetSocketAddress) = {
|
def createNewSession(address : InetSocketAddress) = {
|
||||||
val id = newSessionId
|
val id = newSessionId
|
||||||
|
|
||||||
val cryptoSession = context.actorOf(Props[CryptoSessionActor],
|
|
||||||
|
|
||||||
|
// inflate the pipeline
|
||||||
|
val actors = pipeline.map { actor =>
|
||||||
|
val a = context.actorOf(actor.props, actor.nameTemplate + id.toString)
|
||||||
|
context.watch(a)
|
||||||
|
a
|
||||||
|
}
|
||||||
|
|
||||||
|
/*val cryptoSession = context.actorOf(Props[CryptoSessionActor],
|
||||||
"crypto-session-" + id.toString)
|
"crypto-session-" + id.toString)
|
||||||
val loginSession = context.actorOf(Props[LoginSessionActor],
|
val loginSession = context.actorOf(Props[LoginSessionActor],
|
||||||
"login-session-" + id.toString)
|
"login-session-" + id.toString)*/
|
||||||
|
|
||||||
context.watch(cryptoSession)
|
//context.watch(cryptoSession)
|
||||||
context.watch(loginSession)
|
//context.watch(loginSession)
|
||||||
|
|
||||||
SessionState(id, address, List(cryptoSession, loginSession))
|
SessionState(id, address, actors)
|
||||||
}
|
}
|
||||||
|
|
||||||
def removeSessionById(id : Long, reason : String) : Unit = {
|
def removeSessionById(id : Long, reason : String) : Unit = {
|
||||||
|
|
|
||||||
117
pslogin/src/main/scala/WorldSessionActor.scala
Normal file
117
pslogin/src/main/scala/WorldSessionActor.scala
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
|
import java.net.{InetAddress, InetSocketAddress}
|
||||||
|
|
||||||
|
import akka.actor.{Actor, ActorRef, MDCContextAware}
|
||||||
|
import net.psforever.packet.{PlanetSideGamePacket, _}
|
||||||
|
import net.psforever.packet.control._
|
||||||
|
import net.psforever.packet.game._
|
||||||
|
import scodec.Attempt.{Failure, Successful}
|
||||||
|
import scodec.bits._
|
||||||
|
|
||||||
|
class WorldSessionActor 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
|
||||||
|
|
||||||
|
def receive = Initializing
|
||||||
|
|
||||||
|
def Initializing : Receive = {
|
||||||
|
case HelloFriend(right) =>
|
||||||
|
leftRef = sender()
|
||||||
|
rightRef = right.asInstanceOf[ActorRef]
|
||||||
|
|
||||||
|
context.become(Started)
|
||||||
|
case _ =>
|
||||||
|
log.error("Unknown message")
|
||||||
|
context.stop(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
def Started : Receive = {
|
||||||
|
case ctrl @ ControlPacket(_, _) =>
|
||||||
|
handlePktContainer(ctrl)
|
||||||
|
case game @ GamePacket(_, _, _) =>
|
||||||
|
handlePktContainer(game)
|
||||||
|
case default => failWithError(s"Invalid packet class received: $default")
|
||||||
|
}
|
||||||
|
|
||||||
|
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 container class received: $default")
|
||||||
|
}
|
||||||
|
|
||||||
|
def handleControlPkt(pkt : PlanetSideControlPacket) = {
|
||||||
|
pkt match {
|
||||||
|
case SlottedMetaPacket(slot, subslot, innerPacket) =>
|
||||||
|
sendResponse(PacketCoding.CreateControlPacket(SlottedMetaAck(slot, subslot)))
|
||||||
|
|
||||||
|
PacketCoding.DecodePacket(innerPacket) match {
|
||||||
|
case Failure(e) =>
|
||||||
|
log.error(s"Failed to decode inner packet of SlottedMetaPacket: $e")
|
||||||
|
case Successful(v) =>
|
||||||
|
handlePkt(v)
|
||||||
|
}
|
||||||
|
case sync @ ControlSync(diff, unk, f1, f2, f3, f4, fa, fb) =>
|
||||||
|
log.debug(s"SYNC: ${sync}")
|
||||||
|
val serverTick = Math.abs(System.nanoTime().toInt) // limit the size to prevent encoding error
|
||||||
|
sendResponse(PacketCoding.CreateControlPacket(ControlSyncResp(diff, serverTick,
|
||||||
|
fa, fb, fb, fa)))
|
||||||
|
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}")
|
||||||
|
|
||||||
|
// testing
|
||||||
|
//sendRawResponse(hex"00 09 00 00 00 19 08 2C 00 00 4B 00 00 00 00 02 1F 80 09 9B 05 00 00 00 0D 77 BC F1 05 12 2E 40 00 80 3F D7 04 00 00 00 61 C0 6C 6F 63 6B 2D 7A 33 61 C0 6C 6F 63 6B 2D 7A 34 61 C0 6C 6F 63 6B 2D 7A 39 64 00 6C 6F 63 6B 2D 69 31 2D 69 32 2D 69 33 2D 69 34 04 00 00 00 40 40 10 30 04 10 01 06 00 ")
|
||||||
|
//sendRawResponse(hex"00 09 00 01 00 19 08 2C 00 00 70 01 00 00 00 6A 95 01 00 00 00 00 79 94 FD BF 00 A1 AF BF F3 A5 D0 3E 26 39 76 3B 08 00 00 00 36 AE 11 3F 70 5D 9B 3E 2E 15 9A 9B 3A 3F CC 90 DB 3E 45 1C EC 0F 14 3D AF CF 36 3F 06 32 BA AF 13 3F 18 4C 12 3F 26 2F D2 2D 71 3F 94 AA FB 3E 4D 16 5D 1B 1A 3F 0C 25 D5 3C 55 6B 38 89 63 3F 5D F5 25 3F 3C AC 8E 5E E6 3E 79 25 62 3F 10 32 1F 12 E3 40 00 9A 40 43 4D 54 5F 43 55 4C 4C 57 41 54 45 52 4D 41 52 4B 5F 73 75 63 63 65 73 73 ")
|
||||||
|
case default => log.debug(s"Unhandled GamePacket ${pkt}")
|
||||||
|
}
|
||||||
|
|
||||||
|
def failWithError(error : String) = {
|
||||||
|
log.error(error)
|
||||||
|
//sendResponse(PacketCoding.CreateControlPacket(ConnectionClose()))
|
||||||
|
}
|
||||||
|
|
||||||
|
def sendResponse(cont : PlanetSidePacketContainer) = {
|
||||||
|
log.trace("WORLD SEND: " + cont)
|
||||||
|
rightRef ! cont
|
||||||
|
}
|
||||||
|
|
||||||
|
def sendRawResponse(pkt : ByteVector) = {
|
||||||
|
log.trace("WORLD SEND RAW: " + pkt)
|
||||||
|
rightRef ! RawPacket(pkt)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue