mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
various fixes related to sentry alerts
This commit is contained in:
parent
0dcfb09e5d
commit
49d797e4ba
|
|
@ -23,6 +23,8 @@ import net.psforever.packet._
|
|||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.crypto.{ClientChallengeXchg, ClientFinished, ServerChallengeXchg, ServerFinished}
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.packet.crypto._
|
||||
import net.psforever.packet.game.{ChangeFireModeMessage, CharacterInfoMessage, KeepAliveMessage, PingMsg}
|
||||
import net.psforever.packet.PacketCoding.CryptoCoding
|
||||
import net.psforever.util.{Config, DiffieHellman, Md5Mac}
|
||||
|
||||
|
|
@ -382,7 +384,7 @@ class MiddlewareActor(
|
|||
PacketCoding.unmarshalPacket(msg, None, CryptoPacketOpcode.ClientFinished) match {
|
||||
case Successful(packet) =>
|
||||
packet match {
|
||||
case (ClientFinished(clientPubKey, _), Some(_)) =>
|
||||
case (ClientFinished(_, clientPubKey, _), Some(_)) =>
|
||||
serverMACBuffer ++= msg.drop(3)
|
||||
val agreedKey = dh.agree(clientPubKey.toArray)
|
||||
val agreedMessage = ByteVector("master secret".getBytes) ++ clientChallenge ++
|
||||
|
|
@ -439,6 +441,8 @@ class MiddlewareActor(
|
|||
.receiveMessage[Command] {
|
||||
case Receive(msg) =>
|
||||
PacketCoding.unmarshalPacket(msg, crypto) match {
|
||||
case Successful((Ignore(data), _)) =>
|
||||
log.info(s"caught CryptoPacket Ignore with hex - $data")
|
||||
case Successful((packet, Some(sequence))) =>
|
||||
activeSequenceFunc(packet, sequence)
|
||||
case Successful((packet, None)) =>
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
case out @ Some(obj) if obj.HasGUID =>
|
||||
out
|
||||
|
||||
case None if id.nonEmpty && id.get != PlanetSideGUID(0) =>
|
||||
case None if !id.contains(PlanetSideGUID(0)) =>
|
||||
//delete stale entity reference from client
|
||||
log.error(s"${player.Name} has an invalid reference to GUID ${id.get.guid} in zone ${continent.id}")
|
||||
sendResponse(ObjectDeleteMessage(id.get, 0))
|
||||
|
|
@ -4873,6 +4873,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
log.error(
|
||||
s"telepad@${object_guid.guid} is linked to wrong kind of object - ${o.Definition.Name}, ${obj.Router}"
|
||||
)
|
||||
obj.Actor ! Deployable.Deconstruct()
|
||||
case None => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -5427,6 +5428,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
dismountWarning(
|
||||
s"DismountVehicleMsg: player ${player.Name}_guid not considered seated in a mountable entity"
|
||||
)
|
||||
sendResponse(DismountVehicleMsg(player_guid, bailType, wasKickedByDriver))
|
||||
None
|
||||
}) match {
|
||||
case Some(_) if serverVehicleControlVelocity.nonEmpty =>
|
||||
|
|
@ -5710,6 +5712,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
progressBarUpdate.cancel()
|
||||
progressBarValue = None
|
||||
|
||||
case msg @ TradeMessage(_,_) =>
|
||||
log.info(s"${player.Name} wants to trade, for some reason - $msg")
|
||||
|
||||
case _ =>
|
||||
log.warn(s"Unhandled GamePacket $pkt")
|
||||
}
|
||||
|
|
@ -6362,39 +6367,42 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
FindEquipmentStock(obj, FindAmmoBoxThatUses(requestedAmmoType), fullMagazine, CountAmmunition).reverse match {
|
||||
case Nil => ;
|
||||
case x :: xs =>
|
||||
val (deleteFunc, modifyFunc): (Equipment => Future[Any], (AmmoBox, Int) => Unit) = obj match {
|
||||
case veh: Vehicle =>
|
||||
(RemoveOldEquipmentFromInventory(veh), ModifyAmmunitionInVehicle(veh))
|
||||
case _ =>
|
||||
(RemoveOldEquipmentFromInventory(obj), ModifyAmmunition(obj))
|
||||
val modifyFunc: (AmmoBox, Int) => Unit = obj match {
|
||||
case veh: Vehicle => ModifyAmmunitionInVehicle(veh)
|
||||
case _ => ModifyAmmunition(obj)
|
||||
}
|
||||
val (stowNewFunc, stowFunc): (Equipment => TaskResolver.GiveTask, Equipment => Future[Any]) =
|
||||
(PutNewEquipmentInInventoryOrDrop(obj), PutEquipmentInInventoryOrDrop(obj))
|
||||
val stowNewFunc: Equipment => TaskResolver.GiveTask = PutNewEquipmentInInventoryOrDrop(obj)
|
||||
val stowFunc: Equipment => Future[Any] = PutEquipmentInInventoryOrDrop(obj)
|
||||
|
||||
xs.foreach(item => {
|
||||
obj.Inventory -= x.start
|
||||
deleteFunc(item.obj)
|
||||
obj.Inventory -= item.start
|
||||
sendResponse(ObjectDeleteMessage(item.obj.GUID, 0))
|
||||
continent.tasks ! GUIDTask.UnregisterObjectTask(item.obj)(continent.GUID)
|
||||
})
|
||||
|
||||
//box will be the replacement ammo; give it the discovered magazine and load it into the weapon @ 0
|
||||
//box will be the replacement ammo; give it the discovered magazine and load it into the weapon
|
||||
val box = x.obj.asInstanceOf[AmmoBox]
|
||||
//previousBox is the current magazine in tool; it will be removed from the weapon
|
||||
val previousBox = tool.AmmoSlot.Box
|
||||
val originalBoxCapacity = box.Capacity
|
||||
val tailReloadValue: Int = if (xs.isEmpty) { 0 }
|
||||
else { xs.map(_.obj.asInstanceOf[AmmoBox].Capacity).sum }
|
||||
val tailReloadValue: Int = if (xs.isEmpty) {
|
||||
0
|
||||
} else {
|
||||
xs.map(_.obj.asInstanceOf[AmmoBox].Capacity).sum
|
||||
}
|
||||
val sumReloadValue: Int = originalBoxCapacity + tailReloadValue
|
||||
val previousBox = tool.AmmoSlot.Box //current magazine in tool
|
||||
sendResponse(ObjectDetachMessage(tool.GUID, previousBox.GUID, Vector3.Zero, 0f))
|
||||
sendResponse(ObjectDetachMessage(player.GUID, box.GUID, Vector3.Zero, 0f))
|
||||
val ammoSlotIndex = tool.FireMode.AmmoSlotIndex
|
||||
val box_guid = box.GUID
|
||||
val tool_guid = tool.GUID
|
||||
obj.Inventory -= x.start //remove replacement ammo from inventory
|
||||
val ammoSlotIndex = tool.FireMode.AmmoSlotIndex
|
||||
tool.AmmoSlots(ammoSlotIndex).Box = box //put replacement ammo in tool
|
||||
sendResponse(ObjectAttachMessage(tool.GUID, box.GUID, ammoSlotIndex))
|
||||
sendResponse(ObjectDetachMessage(tool_guid, previousBox.GUID, Vector3.Zero, 0f))
|
||||
sendResponse(ObjectDetachMessage(obj.GUID, box_guid, Vector3.Zero, 0f))
|
||||
sendResponse(ObjectAttachMessage(tool_guid, box_guid, ammoSlotIndex))
|
||||
|
||||
//announce swapped ammunition box in weapon
|
||||
val previous_box_guid = previousBox.GUID
|
||||
val boxDef = box.Definition
|
||||
val box_guid = box.GUID
|
||||
val tool_guid = tool.GUID
|
||||
sendResponse(ChangeAmmoMessage(tool_guid, box.Capacity))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.id,
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ class Player(var avatar: Avatar)
|
|||
None
|
||||
} else {
|
||||
val slot = iter.next()
|
||||
if (slot.Equipment.isDefined && slot.Equipment.get.GUID == guid) {
|
||||
if (slot.Equipment match { case Some(o) => o.GUID == guid; case _ => false }) {
|
||||
Some(index)
|
||||
} else {
|
||||
findInHolsters(iter, guid, index + 1)
|
||||
|
|
|
|||
|
|
@ -167,9 +167,10 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor {
|
|||
obj.Active = false
|
||||
val zone = obj.Zone
|
||||
zone.GUID(obj.Telepad) match {
|
||||
case Some(oldTpad: TelepadDeployable) if !obj.Active && !setup.isCancelled =>
|
||||
case Some(oldTpad: TelepadDeployable)
|
||||
if !obj.Active && !setup.isCancelled =>
|
||||
oldTpad.Actor ! TelepadLike.SeverLink(obj)
|
||||
case None => ;
|
||||
case _ => ;
|
||||
}
|
||||
obj.Telepad = None
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendResponse(ObjectDeleteMessage(obj.GUID, 0)))
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ object CryptoPacketOpcode extends Enumeration {
|
|||
type Type = Value
|
||||
val Ignore, ClientChallengeXchg, ServerChallengeXchg, ClientFinished, ServerFinished = Value
|
||||
|
||||
def getPacketDecoder(opcode: CryptoPacketOpcode.Type): (BitVector) => Attempt[DecodeResult[PlanetSideCryptoPacket]] =
|
||||
def getPacketDecoder(opcode: CryptoPacketOpcode.Type): BitVector => Attempt[DecodeResult[PlanetSideCryptoPacket]] =
|
||||
opcode match {
|
||||
case Ignore => crypto.Ignore.decode
|
||||
case ClientChallengeXchg => crypto.ClientChallengeXchg.decode
|
||||
case ServerChallengeXchg => crypto.ServerChallengeXchg.decode
|
||||
case ServerFinished => crypto.ServerFinished.decode
|
||||
|
|
@ -17,7 +18,7 @@ object CryptoPacketOpcode extends Enumeration {
|
|||
case default =>
|
||||
(a: BitVector) =>
|
||||
Attempt.failure(
|
||||
Err(s"Could not find a marshaller for crypto packet ${opcode}")
|
||||
Err(s"Could not find a marshaller for crypto packet $opcode")
|
||||
.pushContext("get_marshaller")
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ object GamePacketOpcode extends Enumeration {
|
|||
case 0x77 => game.SquadState.decode
|
||||
// 0x78
|
||||
case 0x78 => game.OxygenStateMessage.decode
|
||||
case 0x79 => noDecoder(TradeMessage)
|
||||
case 0x79 => game.TradeMessage.decode
|
||||
case 0x7a => noDecoder(UnknownMessage122)
|
||||
case 0x7b => game.DamageFeedbackMessage.decode
|
||||
case 0x7c => game.DismountBuildingMsg.decode
|
||||
|
|
|
|||
|
|
@ -2,22 +2,43 @@
|
|||
package net.psforever.packet.crypto
|
||||
|
||||
import net.psforever.packet.{CryptoPacketOpcode, Marshallable, PlanetSideCryptoPacket}
|
||||
import scodec.Attempt.Successful
|
||||
import scodec.Codec
|
||||
import scodec.bits.{ByteVector, _}
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
final case class ClientFinished(pubKey: ByteVector, challengeResult: ByteVector) extends PlanetSideCryptoPacket {
|
||||
final case class ClientFinished(
|
||||
obj_type: Int,
|
||||
pubKey: ByteVector,
|
||||
challengeResult: ByteVector
|
||||
) extends PlanetSideCryptoPacket {
|
||||
type Packet = ClientFinished
|
||||
def opcode = CryptoPacketOpcode.ClientFinished
|
||||
def encode = ClientFinished.encode(this)
|
||||
}
|
||||
|
||||
object ClientFinished extends Marshallable[ClientFinished] {
|
||||
def apply(pubKey: ByteVector, challengeResult: ByteVector): ClientFinished =
|
||||
ClientFinished(16, pubKey, challengeResult)
|
||||
|
||||
implicit val codec: Codec[ClientFinished] = (
|
||||
("obj_type?" | constant(hex"10".bits)) ::
|
||||
("obj_type?" | uint8) ::
|
||||
("pub_key_len" | constant(hex"1000")) ::
|
||||
("pub_key" | bytes(16)) ::
|
||||
("unknown" | constant(hex"0114".bits)) ::
|
||||
("challenge_result" | bytes(0xc))
|
||||
).as[ClientFinished]
|
||||
).exmap[ClientFinished](
|
||||
{
|
||||
case 16 :: () :: c :: () :: e :: HNil =>
|
||||
Successful(ClientFinished(16, c, e))
|
||||
case a :: () :: c :: () :: e :: HNil =>
|
||||
org.log4s.getLogger("ClientFinished").warn(s"obj_type?: expected 16 but got $a; attempting to bypass")
|
||||
Successful(ClientFinished(a, c, e))
|
||||
},
|
||||
{
|
||||
case ClientFinished(a, c, e) =>
|
||||
Successful(a :: () :: c :: () :: e :: HNil)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
18
src/main/scala/net/psforever/packet/crypto/Ignore.scala
Normal file
18
src/main/scala/net/psforever/packet/crypto/Ignore.scala
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package net.psforever.packet.crypto
|
||||
|
||||
import net.psforever.packet.{CryptoPacketOpcode, Marshallable, PlanetSideCryptoPacket}
|
||||
import scodec.Codec
|
||||
import scodec.bits.ByteVector
|
||||
import scodec.codecs._
|
||||
|
||||
final case class Ignore(data: ByteVector) extends PlanetSideCryptoPacket {
|
||||
type Packet = Ignore
|
||||
def opcode = CryptoPacketOpcode.Ignore
|
||||
def encode = Ignore.encode(this)
|
||||
}
|
||||
|
||||
object Ignore extends Marshallable[Ignore] {
|
||||
implicit val codec: Codec[Ignore] = ("data" | bytes).as[Ignore]
|
||||
}
|
||||
|
||||
111
src/main/scala/net/psforever/packet/game/TradeMessage.scala
Normal file
111
src/main/scala/net/psforever/packet/game/TradeMessage.scala
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import scodec.Codec
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
sealed trait Trade {
|
||||
def value: Int
|
||||
}
|
||||
|
||||
final case class NoTrade(value: Int) extends Trade {
|
||||
assert(value == 1 || value == 2 || value == 3, s"NoTrade has wrong code value - $value not in [a-f]")
|
||||
}
|
||||
|
||||
final case class TradeOne(value: Int, unk1: PlanetSideGUID, unk2: PlanetSideGUID, unk3: PlanetSideGUID) extends Trade {
|
||||
assert(value == 1 || value == 2 || value == 3, s"TradeOne has wrong code value - $value not in [1,2,3]")
|
||||
}
|
||||
|
||||
final case class TradeTwo(value: Int, unk1: PlanetSideGUID, unk2: PlanetSideGUID) extends Trade {
|
||||
assert(value == 4 || value == 5 || value == 7, s"TradeTwo has wrong code value - $value not in [4,5,7]")
|
||||
}
|
||||
|
||||
final case class TradeThree(value: Int, unk: PlanetSideGUID) extends Trade {
|
||||
assert(value == 6 || value == 8, s"TradeThree has wrong code value - $value not in [6,8]")
|
||||
}
|
||||
|
||||
final case class TradeFour(value: Int, unk: Int) extends Trade {
|
||||
assert(value == 9, s"TradeFour has wrong code value - $value not in [9]")
|
||||
}
|
||||
|
||||
final case class TradeMessage(unk: Int, trade: Trade)
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = TradeMessage
|
||||
def opcode = GamePacketOpcode.TradeMessage
|
||||
def encode = TradeMessage.encode(this)
|
||||
}
|
||||
|
||||
object TradeMessage extends Marshallable[TradeMessage] {
|
||||
private def tradeOneCodec(value: Int): Codec[TradeOne] = (
|
||||
("u1" | PlanetSideGUID.codec) ::
|
||||
("u2" | PlanetSideGUID.codec) ::
|
||||
("u3" | PlanetSideGUID.codec)
|
||||
).xmap[TradeOne](
|
||||
{
|
||||
case a :: b :: c :: HNil => TradeOne(value, a, b, c)
|
||||
},
|
||||
{
|
||||
case TradeOne(_, a, b, c) => a :: b :: c :: HNil
|
||||
}
|
||||
)
|
||||
|
||||
private def tradeTwoCodec(value: Int): Codec[TradeTwo] = (
|
||||
("u1" | PlanetSideGUID.codec) ::
|
||||
("u2" | PlanetSideGUID.codec)
|
||||
).xmap[TradeTwo](
|
||||
{
|
||||
case a :: b :: HNil => TradeTwo(value, a, b)
|
||||
},
|
||||
{
|
||||
case TradeTwo(_, a, b) => a :: b :: HNil
|
||||
}
|
||||
)
|
||||
|
||||
private def tradeThreeCodec(value: Int): Codec[TradeThree] = ("u1" | PlanetSideGUID.codec).xmap[TradeThree](
|
||||
a => TradeThree(value, a),
|
||||
{
|
||||
case TradeThree(_, a) => a
|
||||
}
|
||||
)
|
||||
|
||||
private def tradeFourCodec(value: Int): Codec[TradeFour] = ("u1" | uint4).xmap[TradeFour](
|
||||
a => TradeFour(value, a),
|
||||
{
|
||||
case TradeFour(_, a) => a
|
||||
}
|
||||
)
|
||||
|
||||
private def noTradeCodec(value: Int): Codec[NoTrade] = conditional(included = false, ignore(size = 1)).xmap[NoTrade](
|
||||
_ => NoTrade(value),
|
||||
{
|
||||
case NoTrade(_) => None
|
||||
}
|
||||
)
|
||||
|
||||
private def selectTradeCodec(code: Int): Codec[Trade] = {
|
||||
(code match {
|
||||
case 1 | 2 | 3 => tradeOneCodec(code)
|
||||
case 4 | 5 | 7 => tradeTwoCodec(code)
|
||||
case 6 | 8 => tradeThreeCodec(code)
|
||||
case 9 => tradeFourCodec(code)
|
||||
case _ => noTradeCodec(code)
|
||||
}).asInstanceOf[Codec[Trade]]
|
||||
}
|
||||
|
||||
implicit val codec: Codec[TradeMessage] = (
|
||||
("unk" | uint8) ::
|
||||
(uint4 >>:~ { code =>
|
||||
("trade" | selectTradeCodec(code)).hlist
|
||||
})
|
||||
).xmap[TradeMessage](
|
||||
{
|
||||
case unk :: _ :: trade :: HNil => TradeMessage(unk, trade)
|
||||
},
|
||||
{
|
||||
case TradeMessage(unk, trade) => unk :: trade.value :: trade :: HNil
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -2067,7 +2067,12 @@ class SquadService extends Actor {
|
|||
case (Some((fromMember, fromPosition)), (toMember, _)) if fromPosition != 0 =>
|
||||
val name = fromMember.Name
|
||||
SwapMemberPosition(toMember, fromMember)
|
||||
Publish(squadFeatures(guid).ToChannel, SquadResponse.AssignMember(squad, fromPosition, position))
|
||||
squadFeatures.get(guid) match {
|
||||
case Some(features) =>
|
||||
Publish(features.ToChannel, SquadResponse.AssignMember(squad, fromPosition, position))
|
||||
case None =>
|
||||
//we might be in trouble; we might not ...
|
||||
}
|
||||
UpdateSquadDetail(
|
||||
squad.GUID,
|
||||
SquadDetail().Members(
|
||||
|
|
|
|||
Loading…
Reference in a new issue