mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Fix MDC sessionId passing, annotate ping message
This commit is contained in:
parent
f97dda9704
commit
c1257cb1ec
|
|
@ -7,10 +7,10 @@ import scodec.codecs._
|
||||||
|
|
||||||
/** Sent periodically by the PlanetSide client when connected to the Login server. Not encrypted
|
/** Sent periodically by the PlanetSide client when connected to the Login server. Not encrypted
|
||||||
*
|
*
|
||||||
* @param unk1
|
* @param serverSlot Which server on the server display is the ping referring to
|
||||||
* @param unk2
|
* @param ticks The number of ticks. Usually just reflected back to the client
|
||||||
*/
|
*/
|
||||||
final case class PingMsg(unk1 : Long, unk2 : Long) extends PlanetSideGamePacket {
|
final case class PingMsg(serverSlot : Long, ticks : Long) extends PlanetSideGamePacket {
|
||||||
type Packet = PingMsg
|
type Packet = PingMsg
|
||||||
def opcode = GamePacketOpcode.PingMsg
|
def opcode = GamePacketOpcode.PingMsg
|
||||||
def encode = PingMsg.encode(this)
|
def encode = PingMsg.encode(this)
|
||||||
|
|
@ -18,7 +18,7 @@ final case class PingMsg(unk1 : Long, unk2 : Long) extends PlanetSideGamePacket
|
||||||
|
|
||||||
object PingMsg extends Marshallable[PingMsg] {
|
object PingMsg extends Marshallable[PingMsg] {
|
||||||
implicit val codec : Codec[PingMsg] = (
|
implicit val codec : Codec[PingMsg] = (
|
||||||
("unk1" | uint32L) ::
|
("server_slot" | uint32L) ::
|
||||||
("unk2" | uint32L)
|
("ticks" | uint32L)
|
||||||
).as[PingMsg]
|
).as[PingMsg]
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
<configuration>
|
<configuration scan="true" scanPeriod="10 seconds">
|
||||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<!-- encoders are assigned the type
|
|
||||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default
|
|
||||||
http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout
|
|
||||||
-->
|
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>[%highlight(%5level)] %logger{35} - %msg%n</pattern>
|
<pattern>[%highlight(%5level)] %logger{35} - %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
|
|
@ -12,27 +8,28 @@
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="FILE-TRACE" class="ch.qos.logback.core.FileAppender">
|
|
||||||
<file>pslogin-trace.log</file>
|
|
||||||
<encoder>
|
|
||||||
<pattern>%date{ISO8601} [%thread] %-5level %X %logger{35} - %msg%n</pattern>
|
|
||||||
</encoder>
|
|
||||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
|
||||||
<level>TRACE</level>
|
|
||||||
</filter>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<appender name="FILE-DEBUG" class="ch.qos.logback.core.FileAppender">
|
<appender name="FILE-DEBUG" class="ch.qos.logback.core.FileAppender">
|
||||||
<file>pslogin-debug.log</file>
|
<file>pslogin-debug.log</file>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%date{ISO8601} %-5level %X %logger{35} - %msg%n</pattern>
|
<pattern>%date{ISO8601} %5level "%X" %logger{35} - %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
<level>DEBUG</level>
|
<level>DEBUG</level>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<root level="INFO">
|
<appender name="FILE-TRACE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>pslogin-trace.log</file>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%date{ISO8601} [%thread] %5level "%X" %logger{35} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>OFF</level>
|
||||||
|
<!--<level>TRACE</level>-->
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="TRACE">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
<appender-ref ref="FILE-TRACE" />
|
<appender-ref ref="FILE-TRACE" />
|
||||||
<appender-ref ref="FILE-DEBUG" />
|
<appender-ref ref="FILE-DEBUG" />
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import java.security.SecureRandom
|
||||||
import net.psforever.packet.control.{ClientStart, ServerStart}
|
import net.psforever.packet.control.{ClientStart, ServerStart}
|
||||||
import net.psforever.packet.crypto._
|
import net.psforever.packet.crypto._
|
||||||
import net.psforever.packet.game.PingMsg
|
import net.psforever.packet.game.PingMsg
|
||||||
|
import org.log4s.MDC
|
||||||
|
import MDCContextAware.Implicits._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actor that stores crypto state for a connection, appropriately encrypts and decrypts packets,
|
* Actor that stores crypto state for a connection, appropriately encrypts and decrypts packets,
|
||||||
|
|
@ -22,6 +24,7 @@ import net.psforever.packet.game.PingMsg
|
||||||
class CryptoSessionActor extends Actor with MDCContextAware {
|
class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
private[this] val log = org.log4s.getLogger
|
private[this] val log = org.log4s.getLogger
|
||||||
|
|
||||||
|
var sessionId : Long = 0
|
||||||
var leftRef : ActorRef = ActorRef.noSender
|
var leftRef : ActorRef = ActorRef.noSender
|
||||||
var rightRef : ActorRef = ActorRef.noSender
|
var rightRef : ActorRef = ActorRef.noSender
|
||||||
|
|
||||||
|
|
@ -46,13 +49,14 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
def receive = Initializing
|
def receive = Initializing
|
||||||
|
|
||||||
def Initializing : Receive = {
|
def Initializing : Receive = {
|
||||||
case HelloFriend(right) =>
|
case HelloFriend(sessionId, right) =>
|
||||||
import MDCContextAware.Implicits._
|
import MDCContextAware.Implicits._
|
||||||
|
this.sessionId = sessionId
|
||||||
leftRef = sender()
|
leftRef = sender()
|
||||||
rightRef = right.asInstanceOf[ActorRef]
|
rightRef = right.asInstanceOf[ActorRef]
|
||||||
|
|
||||||
// who ever we send to has to send something back to us
|
// who ever we send to has to send something back to us
|
||||||
rightRef !> HelloFriend(self)
|
rightRef !> HelloFriend(sessionId, self)
|
||||||
|
|
||||||
log.trace(s"Left sender ${leftRef.path.name}")
|
log.trace(s"Left sender ${leftRef.path.name}")
|
||||||
|
|
||||||
|
|
@ -78,14 +82,14 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
}
|
}
|
||||||
case Failure(e) =>
|
case Failure(e) =>
|
||||||
// There is a special case where no crypto is being used.
|
// There is a special case where no crypto is being used.
|
||||||
// The only packet coming through looks like PingMsg
|
// The only packet coming through looks like PingMsg. This is a hardcoded
|
||||||
|
// feature of the client @ 0x005FD618
|
||||||
PacketCoding.DecodePacket(msg) match {
|
PacketCoding.DecodePacket(msg) match {
|
||||||
case Successful(packet) =>
|
case Successful(packet) =>
|
||||||
packet match {
|
packet match {
|
||||||
case ping @ PingMsg(unk1, unk2) =>
|
case ping @ PingMsg(_, _) =>
|
||||||
// TODO: figure out how to get ping to show up on the planetside client
|
// reflect the packet back to the sender
|
||||||
//sendResponse(PingMsg(unk2, unk1))
|
sendResponse(ping)
|
||||||
case default => log.error(s"Unexpected non-crypto packet type ${packet} in state NewClient")
|
case default => log.error(s"Unexpected non-crypto packet type ${packet} in state NewClient")
|
||||||
}
|
}
|
||||||
case Failure(e) =>
|
case Failure(e) =>
|
||||||
|
|
@ -238,7 +242,7 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
case encPacket @ EncryptedPacket(seq, _) =>
|
case encPacket @ EncryptedPacket(seq, _) =>
|
||||||
PacketCoding.decryptPacket(cryptoState.get, encPacket) match {
|
PacketCoding.decryptPacket(cryptoState.get, encPacket) match {
|
||||||
case Successful(packet) =>
|
case Successful(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)
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +296,6 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
def handleEstablishedPacket(from : ActorRef, cont : PlanetSidePacketContainer) = {
|
def handleEstablishedPacket(from : ActorRef, cont : PlanetSidePacketContainer) = {
|
||||||
// we are processing a packet we decrypted
|
// we are processing a packet we decrypted
|
||||||
if(from == self) {
|
if(from == self) {
|
||||||
import MDCContextAware.Implicits._
|
|
||||||
rightRef !> cont
|
rightRef !> cont
|
||||||
} else if(from == rightRef) { // processing a completed packet from the right. encrypt
|
} else if(from == rightRef) { // processing a completed packet from the right. encrypt
|
||||||
val packet = PacketCoding.encryptPacket(cryptoState.get, cont).require
|
val packet = PacketCoding.encryptPacket(cryptoState.get, cont).require
|
||||||
|
|
@ -312,7 +315,10 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
ByteVector.empty
|
ByteVector.empty
|
||||||
case Successful(v) =>
|
case Successful(v) =>
|
||||||
val bytes = v.toByteVector
|
val bytes = v.toByteVector
|
||||||
leftRef ! ResponsePacket(bytes)
|
|
||||||
|
MDC("sessionId") = sessionId.toString
|
||||||
|
leftRef !> ResponsePacket(bytes)
|
||||||
|
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -327,7 +333,10 @@ class CryptoSessionActor extends Actor with MDCContextAware {
|
||||||
ByteVector.empty
|
ByteVector.empty
|
||||||
case Successful(v) =>
|
case Successful(v) =>
|
||||||
val bytes = v.toByteVector
|
val bytes = v.toByteVector
|
||||||
leftRef ! ResponsePacket(bytes)
|
|
||||||
|
MDC("sessionId") = sessionId.toString
|
||||||
|
leftRef !> ResponsePacket(bytes)
|
||||||
|
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import akka.actor.{Actor, ActorRef, MDCContextAware}
|
||||||
import net.psforever.packet.{PlanetSideGamePacket, _}
|
import net.psforever.packet.{PlanetSideGamePacket, _}
|
||||||
import net.psforever.packet.control._
|
import net.psforever.packet.control._
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
|
import org.log4s.MDC
|
||||||
import scodec.Attempt.{Failure, Successful}
|
import scodec.Attempt.{Failure, Successful}
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
|
import MDCContextAware.Implicits._
|
||||||
|
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
|
||||||
|
|
@ -15,13 +17,15 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
private case class UpdateServerList()
|
private case class UpdateServerList()
|
||||||
|
|
||||||
|
var sessionId : Long = 0
|
||||||
var leftRef : ActorRef = ActorRef.noSender
|
var leftRef : ActorRef = ActorRef.noSender
|
||||||
var rightRef : ActorRef = ActorRef.noSender
|
var rightRef : ActorRef = ActorRef.noSender
|
||||||
|
|
||||||
def receive = Initializing
|
def receive = Initializing
|
||||||
|
|
||||||
def Initializing : Receive = {
|
def Initializing : Receive = {
|
||||||
case HelloFriend(right) =>
|
case HelloFriend(sessionId, right) =>
|
||||||
|
this.sessionId = sessionId
|
||||||
leftRef = sender()
|
leftRef = sender()
|
||||||
rightRef = right.asInstanceOf[ActorRef]
|
rightRef = right.asInstanceOf[ActorRef]
|
||||||
|
|
||||||
|
|
@ -33,7 +37,7 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
def Started : Receive = {
|
def Started : Receive = {
|
||||||
case UpdateServerList() =>
|
case UpdateServerList() =>
|
||||||
updateServerList
|
updateServerList()
|
||||||
case ctrl @ ControlPacket(_, _) =>
|
case ctrl @ ControlPacket(_, _) =>
|
||||||
handlePktContainer(ctrl)
|
handlePktContainer(ctrl)
|
||||||
case game @ GamePacket(_, _, _) =>
|
case game @ GamePacket(_, _, _) =>
|
||||||
|
|
@ -74,7 +78,6 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
val serverTick = Math.abs(System.nanoTime().toInt) // limit the size to prevent encoding error
|
val serverTick = Math.abs(System.nanoTime().toInt) // limit the size to prevent encoding error
|
||||||
sendResponse(PacketCoding.CreateControlPacket(ControlSyncResp(diff, serverTick,
|
sendResponse(PacketCoding.CreateControlPacket(ControlSyncResp(diff, serverTick,
|
||||||
fa, fb, fb, fa)))
|
fa, fb, fb, fa)))
|
||||||
|
|
||||||
case MultiPacket(packets) =>
|
case MultiPacket(packets) =>
|
||||||
packets.foreach { pkt =>
|
packets.foreach { pkt =>
|
||||||
PacketCoding.DecodePacket(pkt) match {
|
PacketCoding.DecodePacket(pkt) match {
|
||||||
|
|
@ -109,7 +112,7 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
0, 1, 2, 685276011, username, 0, false)
|
0, 1, 2, 685276011, username, 0, false)
|
||||||
|
|
||||||
sendResponse(PacketCoding.CreateGamePacket(0, response))
|
sendResponse(PacketCoding.CreateGamePacket(0, response))
|
||||||
updateServerList
|
updateServerList()
|
||||||
case ConnectToWorldRequestMessage(name, _, _, _, _, _, _) =>
|
case ConnectToWorldRequestMessage(name, _, _, _, _, _, _) =>
|
||||||
log.info(s"Connect to world request for '${name}'")
|
log.info(s"Connect to world request for '${name}'")
|
||||||
|
|
||||||
|
|
@ -118,7 +121,7 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
case default => log.debug(s"Unhandled GamePacket ${pkt}")
|
case default => log.debug(s"Unhandled GamePacket ${pkt}")
|
||||||
}
|
}
|
||||||
|
|
||||||
def updateServerList = {
|
def updateServerList() = {
|
||||||
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
val msg = VNLWorldStatusMessage("Welcome to PlanetSide! ",
|
||||||
Vector(
|
Vector(
|
||||||
WorldInformation(serverName, WorldStatus.Up, ServerType.Released,
|
WorldInformation(serverName, WorldStatus.Up, ServerType.Released,
|
||||||
|
|
@ -135,11 +138,15 @@ class LoginSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
def sendResponse(cont : PlanetSidePacketContainer) = {
|
def sendResponse(cont : PlanetSidePacketContainer) = {
|
||||||
log.trace("LOGIN SEND: " + cont)
|
log.trace("LOGIN SEND: " + cont)
|
||||||
rightRef ! cont
|
|
||||||
|
MDC("sessionId") = sessionId.toString
|
||||||
|
rightRef !> cont
|
||||||
}
|
}
|
||||||
|
|
||||||
def sendRawResponse(pkt : ByteVector) = {
|
def sendRawResponse(pkt : ByteVector) = {
|
||||||
log.trace("LOGIN SEND RAW: " + pkt)
|
log.trace("LOGIN SEND RAW: " + pkt)
|
||||||
rightRef ! RawPacket(pkt)
|
|
||||||
|
MDC("sessionId") = sessionId.toString
|
||||||
|
rightRef !> RawPacket(pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ trait MDCContextAware extends Actor with ActorLogging {
|
||||||
val orig = MDC.getCopyOfContextMap
|
val orig = MDC.getCopyOfContextMap
|
||||||
try {
|
try {
|
||||||
msg match {
|
msg match {
|
||||||
case MdcMsg(mdc, origMsg) =>
|
case mdcObj @ MdcMsg(mdc, origMsg) =>
|
||||||
if (mdc != null)
|
if (mdc != null)
|
||||||
MDC.setContextMap(mdc)
|
MDC.setContextMap(mdc)
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class SessionRouter(pipeline : List[SessionPipeline]) extends Actor with MDCCont
|
||||||
* ^ | ^ | ^ |
|
* ^ | ^ | ^ |
|
||||||
* | write() | | encrypt | | response |
|
* | write() | | encrypt | | response |
|
||||||
* +--------------+ +-----------+ +-----------------+
|
* +--------------+ +-----------+ +-----------------+
|
||||||
*/
|
**/
|
||||||
|
|
||||||
def receive = initializing
|
def receive = initializing
|
||||||
|
|
||||||
|
|
@ -84,35 +84,35 @@ class SessionRouter(pipeline : List[SessionPipeline]) extends Actor with MDCCont
|
||||||
log.info("New session from " + from.toString)
|
log.info("New session from " + from.toString)
|
||||||
|
|
||||||
// send the initial message with MDC context (give the session ID to the lower layers)
|
// send the initial message with MDC context (give the session ID to the lower layers)
|
||||||
sessionById{session.id}.startOfPipe !> HelloFriend(sessionById{session.id}.nextOfStart)
|
sessionById{session.id}.startOfPipe !> HelloFriend(session.id, sessionById{session.id}.nextOfStart)
|
||||||
sessionById{session.id}.startOfPipe !> RawPacket(msg)
|
sessionById{session.id}.startOfPipe !> RawPacket(msg)
|
||||||
|
|
||||||
MDC.clear()
|
MDC.clear()
|
||||||
}
|
}
|
||||||
case ResponsePacket(msg) =>
|
case ResponsePacket(msg) =>
|
||||||
val session = sessionByActor.get(sender())
|
val session = sessionByActor.get(sender())
|
||||||
|
if(session.isDefined) {
|
||||||
// drop any old queued messages from old actors
|
|
||||||
//if(session.isDefined) {
|
|
||||||
log.trace(s"Sending response ${msg}")
|
log.trace(s"Sending response ${msg}")
|
||||||
|
|
||||||
inputRef ! SendPacket(msg, session.get.address)
|
inputRef ! SendPacket(msg, session.get.address)
|
||||||
//}
|
} else {
|
||||||
|
log.error("Dropped old response packet from session actor " + sender().path.name)
|
||||||
|
}
|
||||||
case Terminated(actor) =>
|
case Terminated(actor) =>
|
||||||
val terminatedSession = sessionByActor.get(actor)
|
val terminatedSession = sessionByActor.get(actor)
|
||||||
|
|
||||||
if(terminatedSession.isDefined) {
|
if(terminatedSession.isDefined) {
|
||||||
removeSessionById(terminatedSession.get.id, s"${actor.path.name} died")
|
removeSessionById(terminatedSession.get.id, s"${actor.path.name} died")
|
||||||
|
} else {
|
||||||
|
log.error("Received an invalid actor Termination from " + actor.path.name)
|
||||||
}
|
}
|
||||||
case default =>
|
case default =>
|
||||||
log.error(s"Unknown message $default")
|
log.error(s"Unknown message $default from " + sender().path)
|
||||||
}
|
}
|
||||||
|
|
||||||
def createNewSession(address : InetSocketAddress) = {
|
def createNewSession(address : InetSocketAddress) = {
|
||||||
val id = newSessionId
|
val id = newSessionId
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// inflate the pipeline
|
// inflate the pipeline
|
||||||
val actors = pipeline.map { actor =>
|
val actors = pipeline.map { actor =>
|
||||||
val a = context.actorOf(actor.props, actor.nameTemplate + id.toString)
|
val a = context.actorOf(actor.props, actor.nameTemplate + id.toString)
|
||||||
|
|
@ -120,21 +120,13 @@ class SessionRouter(pipeline : List[SessionPipeline]) extends Actor with MDCCont
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
/*val cryptoSession = context.actorOf(Props[CryptoSessionActor],
|
|
||||||
"crypto-session-" + id.toString)
|
|
||||||
val loginSession = context.actorOf(Props[LoginSessionActor],
|
|
||||||
"login-session-" + id.toString)*/
|
|
||||||
|
|
||||||
//context.watch(cryptoSession)
|
|
||||||
//context.watch(loginSession)
|
|
||||||
|
|
||||||
SessionState(id, address, actors)
|
SessionState(id, address, actors)
|
||||||
}
|
}
|
||||||
|
|
||||||
def removeSessionById(id : Long, reason : String) : Unit = {
|
def removeSessionById(id : Long, reason : String) : Unit = {
|
||||||
val sessionOption = sessionById.get(id)
|
val sessionOption = sessionById.get(id)
|
||||||
|
|
||||||
if(!sessionOption.isDefined)
|
if(sessionOption.isEmpty)
|
||||||
return
|
return
|
||||||
|
|
||||||
val session = sessionOption.get
|
val session = sessionOption.get
|
||||||
|
|
@ -142,7 +134,7 @@ class SessionRouter(pipeline : List[SessionPipeline]) extends Actor with MDCCont
|
||||||
// TODO: add some sort of delay to prevent old session packets from coming through
|
// TODO: add some sort of delay to prevent old session packets from coming through
|
||||||
// kill all session specific actors
|
// kill all session specific actors
|
||||||
session.pipeline.foreach(_ ! PoisonPill)
|
session.pipeline.foreach(_ ! PoisonPill)
|
||||||
session.pipeline.foreach(sessionByActor remove _)
|
session.pipeline.foreach(sessionByActor remove)
|
||||||
sessionById.remove(id)
|
sessionById.remove(id)
|
||||||
idBySocket.remove(session.address)
|
idBySocket.remove(session.address)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import akka.util.ByteString
|
||||||
final case class ReceivedPacket(msg : ByteVector, from : InetSocketAddress)
|
final case class ReceivedPacket(msg : ByteVector, from : InetSocketAddress)
|
||||||
final case class SendPacket(msg : ByteVector, to : InetSocketAddress)
|
final case class SendPacket(msg : ByteVector, to : InetSocketAddress)
|
||||||
final case class Hello()
|
final case class Hello()
|
||||||
final case class HelloFriend(next: ActorRef)
|
final case class HelloFriend(sessionId : Long, next: ActorRef)
|
||||||
|
|
||||||
class UdpListener(nextActorProps : Props, nextActorName : String, address : InetAddress, port : Int) extends Actor {
|
class UdpListener(nextActorProps : Props, nextActorName : String, address : InetAddress, port : Int) extends Actor {
|
||||||
private val log = org.log4s.getLogger(self.path.name)
|
private val log = org.log4s.getLogger(self.path.name)
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,23 @@ import net.psforever.packet.control._
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
import scodec.Attempt.{Failure, Successful}
|
import scodec.Attempt.{Failure, Successful}
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
|
import org.log4s.MDC
|
||||||
|
import MDCContextAware.Implicits._
|
||||||
|
|
||||||
class WorldSessionActor extends Actor with MDCContextAware {
|
class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
private[this] val log = org.log4s.getLogger
|
private[this] val log = org.log4s.getLogger
|
||||||
|
|
||||||
private case class PokeClient()
|
private case class PokeClient()
|
||||||
|
|
||||||
|
var sessionId : Long = 0
|
||||||
var leftRef : ActorRef = ActorRef.noSender
|
var leftRef : ActorRef = ActorRef.noSender
|
||||||
var rightRef : ActorRef = ActorRef.noSender
|
var rightRef : ActorRef = ActorRef.noSender
|
||||||
|
|
||||||
def receive = Initializing
|
def receive = Initializing
|
||||||
|
|
||||||
def Initializing : Receive = {
|
def Initializing : Receive = {
|
||||||
case HelloFriend(right) =>
|
case HelloFriend(sessionId, right) =>
|
||||||
|
this.sessionId = sessionId
|
||||||
leftRef = sender()
|
leftRef = sender()
|
||||||
rightRef = right.asInstanceOf[ActorRef]
|
rightRef = right.asInstanceOf[ActorRef]
|
||||||
|
|
||||||
|
|
@ -121,7 +125,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
sendResponse(PacketCoding.CreateGamePacket(0, ActionResultMessage(false, Some(1))))
|
sendResponse(PacketCoding.CreateGamePacket(0, ActionResultMessage(false, Some(1))))
|
||||||
case CharacterRequestAction.Select =>
|
case CharacterRequestAction.Select =>
|
||||||
PacketCoding.DecodeGamePacket(objectHex).require match {
|
PacketCoding.DecodeGamePacket(objectHex).require match {
|
||||||
case ObjectCreateMessage(len, cls, guid, _) =>
|
case obj @ ObjectCreateMessage(len, cls, guid, _, _) =>
|
||||||
|
log.debug("Object: " + obj)
|
||||||
// LoadMapMessage 13714 in mossy .gcap
|
// LoadMapMessage 13714 in mossy .gcap
|
||||||
// XXX: hardcoded shit
|
// XXX: hardcoded shit
|
||||||
sendRawResponse(hex"31 85 6D 61 70 31 33 85 68 6F 6D 65 33 A4 9C 19 00 00 00 AE 30 5E 70 00 ")
|
sendRawResponse(hex"31 85 6D 61 70 31 33 85 68 6F 6D 65 33 A4 9C 19 00 00 00 AE 30 5E 70 00 ")
|
||||||
|
|
@ -232,11 +237,15 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
def sendResponse(cont : PlanetSidePacketContainer) = {
|
def sendResponse(cont : PlanetSidePacketContainer) = {
|
||||||
log.trace("WORLD SEND: " + cont)
|
log.trace("WORLD SEND: " + cont)
|
||||||
rightRef ! cont
|
|
||||||
|
MDC("sessionId") = sessionId.toString
|
||||||
|
rightRef !> cont
|
||||||
}
|
}
|
||||||
|
|
||||||
def sendRawResponse(pkt : ByteVector) = {
|
def sendRawResponse(pkt : ByteVector) = {
|
||||||
log.trace("WORLD SEND RAW: " + pkt)
|
log.trace("WORLD SEND RAW: " + pkt)
|
||||||
rightRef ! RawPacket(pkt)
|
|
||||||
|
MDC("sessionId") = sessionId.toString
|
||||||
|
rightRef !> RawPacket(pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue