mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-02-19 22:53:37 +00:00
modified HandleGamePacket so that it should encode properly; modified CSA so that it attempt to detect packets that encode into ByteVectors that are 'too big' and will attempt to split them up separated the ControlPacket tests into invdividual files and wrote tests for RelatedA0, RelatedB0, and HandleGamePacket proof of concept MTU packet split in CSA; example in WSA @ character select modified session pipeline to accept n queued Actors rather than just two; special packet decoder in progress some effort separating useful sub-operations in encryption/decryption/encoding/decoding functions; introduced PacketCodingActor , devoted to encoding and decoding packets; simplified CSA so that it is devoted just to encrypting and decrypting
104 lines
2.7 KiB
Scala
104 lines
2.7 KiB
Scala
// Copyright (c) 2017 PSForever
|
|
|
|
import java.net.InetSocketAddress
|
|
|
|
import akka.actor._
|
|
import org.log4s.MDC
|
|
import scodec.bits._
|
|
|
|
import akka.actor.{ActorContext, ActorRef, PoisonPill}
|
|
import com.github.nscala_time.time.Imports._
|
|
import MDCContextAware.Implicits._
|
|
|
|
sealed trait SessionState
|
|
final case class New() extends SessionState
|
|
final case class Related() extends SessionState
|
|
final case class Handshaking() extends SessionState
|
|
final case class Established() extends SessionState
|
|
final case class Closing() extends SessionState
|
|
final case class Closed() extends SessionState
|
|
|
|
|
|
class Session(val sessionId : Long,
|
|
val socketAddress : InetSocketAddress,
|
|
returnActor : ActorRef,
|
|
sessionPipeline : List[SessionPipeline])
|
|
(implicit val context: ActorContext, implicit val self : ActorRef) {
|
|
|
|
var state : SessionState = New()
|
|
val sessionCreatedTime : DateTime = DateTime.now
|
|
var sessionEndedTime : DateTime = DateTime.now
|
|
|
|
val pipeline = sessionPipeline.map { actor =>
|
|
val a = context.actorOf(actor.props, actor.nameTemplate + sessionId.toString)
|
|
context.watch(a)
|
|
a
|
|
}
|
|
|
|
val pipelineIter = pipeline.iterator
|
|
if(pipelineIter.hasNext) {
|
|
pipelineIter.next ! HelloFriend(sessionId, pipelineIter)
|
|
}
|
|
|
|
// statistics
|
|
var bytesSent : Long = 0
|
|
var bytesReceived : Long = 0
|
|
var inboundPackets : Long = 0
|
|
var outboundPackets : Long = 0
|
|
|
|
var lastInboundEvent : Long = System.nanoTime()
|
|
var lastOutboundEvent : Long = System.nanoTime()
|
|
|
|
var inboundPacketRate : Double = 0.0
|
|
var outboundPacketRate : Double = 0.0
|
|
var inboundBytesPerSecond : Double = 0.0
|
|
var outboundBytesPerSecond : Double = 0.0
|
|
|
|
def receive(packet : RawPacket) : Unit = {
|
|
bytesReceived += packet.data.size
|
|
inboundPackets += 1
|
|
lastInboundEvent = System.nanoTime()
|
|
|
|
pipeline.head !> packet
|
|
}
|
|
|
|
def send(packet : ByteVector) : Unit = {
|
|
bytesSent += packet.size
|
|
outboundPackets += 1
|
|
lastOutboundEvent = System.nanoTime()
|
|
|
|
returnActor ! SendPacket(packet, socketAddress)
|
|
}
|
|
|
|
def dropSession(graceful : Boolean) = {
|
|
pipeline.foreach(context.unwatch)
|
|
pipeline.foreach(_ ! PoisonPill)
|
|
|
|
sessionEndedTime = DateTime.now
|
|
setState(Closed())
|
|
}
|
|
|
|
def getState = state
|
|
|
|
def setState(newState : SessionState) : Unit = {
|
|
state = newState
|
|
}
|
|
def getPipeline : List[ActorRef] = pipeline
|
|
|
|
def getTotalBytes = {
|
|
bytesSent + bytesReceived
|
|
}
|
|
|
|
def timeSinceLastInboundEvent = {
|
|
(System.nanoTime() - lastInboundEvent)/1000000
|
|
}
|
|
|
|
def timeSinceLastOutboundEvent = {
|
|
(System.nanoTime() - lastOutboundEvent)/1000000
|
|
}
|
|
|
|
|
|
override def toString : String = {
|
|
s"Session($sessionId, $getTotalBytes)"
|
|
}
|
|
}
|