mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-13 15:34:45 +00:00
reset sequence at 0x8000, but only when retrieving a new sequence number; caching common flag values when marshalling packets
This commit is contained in:
parent
aac0ecfd3e
commit
5ce499672d
2 changed files with 28 additions and 21 deletions
|
|
@ -222,7 +222,8 @@ class MiddlewareActor(
|
||||||
* @return next sequence number
|
* @return next sequence number
|
||||||
*/
|
*/
|
||||||
private def nextSequence: Int = {
|
private def nextSequence: Int = {
|
||||||
if (outSequence >= 0xffff) {
|
if (outSequence >= 0x8000) {
|
||||||
|
send(ResetSequence(), Some(outSequence), crypto)
|
||||||
performResetSequenceReset()
|
performResetSequenceReset()
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -258,7 +259,6 @@ class MiddlewareActor(
|
||||||
* and gaslight the client to send packets using refreshed (delivered) id's.
|
* and gaslight the client to send packets using refreshed (delivered) id's.
|
||||||
*/
|
*/
|
||||||
private def performResetSequenceReset(): Unit = {
|
private def performResetSequenceReset(): Unit = {
|
||||||
send(ResetSequence(), None, crypto)
|
|
||||||
outSequence = 0
|
outSequence = 0
|
||||||
inSequence = 0
|
inSequence = 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,12 @@ object PacketCoding {
|
||||||
): Attempt[BitVector] = {
|
): Attempt[BitVector] = {
|
||||||
packet match {
|
packet match {
|
||||||
case _: PlanetSideControlPacket if crypto.isEmpty =>
|
case _: PlanetSideControlPacket if crypto.isEmpty =>
|
||||||
marshalPacketWithSequence(packet, BitVector.empty, crypto)
|
marshalPacket(packet, BitVector.empty, crypto)
|
||||||
case _: PlanetSideResetSequencePacket =>
|
|
||||||
marshalPacketWithSequence(packet, BitVector.empty, crypto)
|
|
||||||
case _ =>
|
case _ =>
|
||||||
sequenceOpt match {
|
sequenceOpt match {
|
||||||
case Some(sequence) =>
|
case Some(sequence) =>
|
||||||
uint16L.encode(sequence) match {
|
uint16L.encode(sequence) match {
|
||||||
case Successful(encodedSequence) => marshalPacketWithSequence(packet, encodedSequence, crypto)
|
case Successful(encodedSequence) => marshalPacket(packet, encodedSequence, crypto)
|
||||||
case f: Failure => f
|
case f: Failure => f
|
||||||
}
|
}
|
||||||
case None =>
|
case None =>
|
||||||
|
|
@ -55,6 +53,19 @@ object PacketCoding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Common flags for normal encrypted packets. */
|
||||||
|
private val normalSecuredFlags: BitVector = PlanetSidePacketFlags.codec
|
||||||
|
.encode(PlanetSidePacketFlags(PacketType.Normal, secured = true))
|
||||||
|
.require
|
||||||
|
/** Common flags for normal unencrypted packets. */
|
||||||
|
private val normalNotSecuredFlags: BitVector = PlanetSidePacketFlags.codec
|
||||||
|
.encode(PlanetSidePacketFlags(PacketType.Normal, secured = false))
|
||||||
|
.require
|
||||||
|
/** Common flags for crypto unencrypted packets (that's not illogical). */
|
||||||
|
private val cryptoNotSecuredFlags: BitVector = PlanetSidePacketFlags.codec
|
||||||
|
.encode(PlanetSidePacketFlags(PacketType.Crypto, secured = false))
|
||||||
|
.require
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform a kind of packet into the sequence of data that represents it.
|
* Transform a kind of packet into the sequence of data that represents it.
|
||||||
* @param packet the packet to encode
|
* @param packet the packet to encode
|
||||||
|
|
@ -62,27 +73,25 @@ object PacketCoding {
|
||||||
* @param crypto if set, encrypt final payload
|
* @param crypto if set, encrypt final payload
|
||||||
* @return a `BitVector` translated from the packet's data
|
* @return a `BitVector` translated from the packet's data
|
||||||
*/
|
*/
|
||||||
private def marshalPacketWithSequence(
|
private def marshalPacket(
|
||||||
packet: PlanetSidePacket,
|
packet: PlanetSidePacket,
|
||||||
sequence: BitVector,
|
sequence: BitVector,
|
||||||
crypto: Option[CryptoCoding] = None
|
crypto: Option[CryptoCoding]
|
||||||
): Attempt[BitVector] = {
|
): Attempt[BitVector] = {
|
||||||
packet match {
|
packet match {
|
||||||
case _: PlanetSideGamePacket | _: PlanetSideControlPacket if crypto.isDefined =>
|
case _: PlanetSideGamePacket | _: PlanetSideControlPacket if crypto.isDefined =>
|
||||||
encodePacket(packet)
|
encodePacket(packet)
|
||||||
.flatMap { _payload => crypto.get.encrypt(_payload.bytes) }
|
.flatMap { _payload => crypto.get.encrypt(_payload.bytes) }
|
||||||
.flatMap { encryptedPayload =>
|
.flatMap { encryptedPayload =>
|
||||||
// encrypted packets need to be aligned to 4 bytes before encryption/decryption
|
// these encrypted packets need to be aligned to 4 bytes before encryption/decryption
|
||||||
// first byte are flags, second is the sequence, and third is the pad
|
// first byte are flags, second is the sequence, and third is the pad
|
||||||
val flags = PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.Normal, secured = true)).require
|
|
||||||
val payload = hex"00".bits ++ encryptedPayload.bits
|
val payload = hex"00".bits ++ encryptedPayload.bits
|
||||||
Successful(flags ++ sequence ++ payload)
|
Successful(normalSecuredFlags ++ sequence ++ payload)
|
||||||
}
|
}
|
||||||
case packet: PlanetSideGamePacket =>
|
case packet: PlanetSideGamePacket =>
|
||||||
encodePacket(packet)
|
encodePacket(packet)
|
||||||
.flatMap { _payload =>
|
.flatMap { _payload =>
|
||||||
val flags = PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.Normal, secured = false)).require
|
Successful(normalNotSecuredFlags ++ sequence ++ _payload)
|
||||||
Successful(flags ++ sequence ++ _payload)
|
|
||||||
}
|
}
|
||||||
case packet: PlanetSideControlPacket =>
|
case packet: PlanetSideControlPacket =>
|
||||||
encodePacket(packet)
|
encodePacket(packet)
|
||||||
|
|
@ -92,20 +101,18 @@ object PacketCoding {
|
||||||
case packet: PlanetSideCryptoPacket =>
|
case packet: PlanetSideCryptoPacket =>
|
||||||
encodePacket(packet)
|
encodePacket(packet)
|
||||||
.flatMap { _payload =>
|
.flatMap { _payload =>
|
||||||
val flags = PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.Crypto, secured = false)).require
|
Successful(cryptoNotSecuredFlags ++ sequence ++ _payload)
|
||||||
Successful(flags ++ sequence ++ _payload)
|
|
||||||
}
|
}
|
||||||
case packet: PlanetSideResetSequencePacket if crypto.isDefined =>
|
case packet: PlanetSideResetSequencePacket if crypto.isDefined =>
|
||||||
encodePacket(packet)
|
encodePacket(packet)
|
||||||
.flatMap { _payload => crypto.get.encrypt(_payload.bytes) }
|
.flatMap { _payload => crypto.get.encrypt(_payload.bytes) }
|
||||||
.flatMap { encryptedPayload =>
|
.flatMap { encryptedPayload =>
|
||||||
|
//uncommon, so it's fine to not cache these flags (above)
|
||||||
val flags = PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.ResetSequence, secured = true)).require
|
val flags = PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.ResetSequence, secured = true)).require
|
||||||
Successful(flags ++ sequence ++ encryptedPayload.bits)
|
Successful(flags ++ sequence ++ encryptedPayload.bits)
|
||||||
}
|
}
|
||||||
case _: PlanetSideResetSequencePacket =>
|
|
||||||
Failure(Err(s"can not marshal a ResetSequence packet when crypto state is unavailable"))
|
|
||||||
case _ =>
|
case _ =>
|
||||||
Failure(Err(s"can not marshal $packet"))
|
Failure(Err(s"can not marshal $packet, sequence? $sequence, crypto state? ${crypto.isDefined}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue