mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-15 00:14:40 +00:00
initial work on SquadDefinitionActionMessage packet; prepared a debugging mode
This commit is contained in:
parent
bea1a0aad2
commit
8ee7f78db9
3 changed files with 296 additions and 1 deletions
|
|
@ -592,7 +592,7 @@ object GamePacketOpcode extends Enumeration {
|
||||||
case 0xe4 => noDecoder(MissionActionMessage)
|
case 0xe4 => noDecoder(MissionActionMessage)
|
||||||
case 0xe5 => noDecoder(MissionKillTriggerMessage)
|
case 0xe5 => noDecoder(MissionKillTriggerMessage)
|
||||||
case 0xe6 => noDecoder(ReplicationStreamMessage)
|
case 0xe6 => noDecoder(ReplicationStreamMessage)
|
||||||
case 0xe7 => noDecoder(SquadDefinitionActionMessage)
|
case 0xe7 => game.SquadDefinitionActionMessage.decode
|
||||||
// 0xe8
|
// 0xe8
|
||||||
case 0xe8 => noDecoder(SquadDetailDefinitionUpdateMessage)
|
case 0xe8 => noDecoder(SquadDetailDefinitionUpdateMessage)
|
||||||
case 0xe9 => noDecoder(TacticsMessage)
|
case 0xe9 => noDecoder(TacticsMessage)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,292 @@
|
||||||
|
// Copyright (c) 2016 PSForever.net to present
|
||||||
|
package net.psforever.packet.game
|
||||||
|
|
||||||
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
|
import scodec.{Attempt, Codec, Err}
|
||||||
|
import scodec.codecs._
|
||||||
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
|
final case class SquadDefinitionActionMessage(action : Int,
|
||||||
|
unk2 : Int,
|
||||||
|
unk3 : Int,
|
||||||
|
unk4 : Option[String],
|
||||||
|
unk5 : Option[Int],
|
||||||
|
unk6 : Option[Int],
|
||||||
|
unk7 : Option[Long],
|
||||||
|
unk8 : Option[Long],
|
||||||
|
unk9 : Option[Boolean])
|
||||||
|
extends PlanetSideGamePacket {
|
||||||
|
type Packet = SquadDefinitionActionMessage
|
||||||
|
def opcode = GamePacketOpcode.SquadDefinitionActionMessage
|
||||||
|
def encode = SquadDefinitionActionMessage.encode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
object SquadDefinitionActionMessage extends Marshallable[SquadDefinitionActionMessage] {
|
||||||
|
private type allPattern = Option[String] :: Option[Int] :: Option[Int] :: Option[Long] :: Option[Long] :: Option[Boolean] :: HNil
|
||||||
|
|
||||||
|
def boolCodec : Codec[allPattern] = bool.hlist.exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case n :: HNil =>
|
||||||
|
Attempt.successful(None :: None :: None :: None :: None :: Some(n) :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case _ :: _ :: _ :: _ :: _ :: None :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a boolean value but found nothing"))
|
||||||
|
case _ :: _ :: _ :: _ :: _ :: Some(n) :: HNil =>
|
||||||
|
Attempt.successful(n :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def intCodec(icodec : Codec[Int]) : Codec[allPattern] = icodec.hlist.exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case n :: HNil =>
|
||||||
|
Attempt.successful(None :: Some(n) :: None :: None :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case _ :: None :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected an integer value but found nothing"))
|
||||||
|
case _ :: Some(n) :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.successful(n :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def longCodec : Codec[allPattern] = uint32L.hlist.exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case n :: HNil =>
|
||||||
|
Attempt.successful(None :: None :: None :: Some(n) :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case _ :: _ :: _ :: None :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a long value but found nothing"))
|
||||||
|
case _ :: _ :: _ :: Some(n) :: _ :: _ :: HNil =>
|
||||||
|
Attempt.successful(n :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def stringCodec : Codec[allPattern] = PacketHelpers.encodedWideStringAligned(6).hlist.exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case a :: HNil =>
|
||||||
|
Attempt.successful(Some(a) :: None :: None :: None :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case None:: _ :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a string value but found nothing"))
|
||||||
|
case Some(a) :: _ :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.successful(a :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def intLongCodec(lcodec : Codec[Long]) : Codec[allPattern] = (
|
||||||
|
uint4L ::
|
||||||
|
lcodec
|
||||||
|
).exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case a :: b :: HNil =>
|
||||||
|
Attempt.successful(None :: Some(a) :: None :: Some(b) :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case _ :: None :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a integer value but found nothing"))
|
||||||
|
case _ :: _ :: _ :: None :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a long value but found nothing"))
|
||||||
|
case _ :: Some(a) :: _ :: Some(b) :: _ :: _ :: HNil =>
|
||||||
|
Attempt.successful(a :: b :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def intStringCodec : Codec[allPattern] = (
|
||||||
|
uint4L ::
|
||||||
|
PacketHelpers.encodedWideStringAligned(2)
|
||||||
|
).exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case a :: b :: HNil =>
|
||||||
|
Attempt.successful(Some(b) :: Some(a) :: None :: None :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case None:: _ :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a string value but found nothing"))
|
||||||
|
case _ :: None :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected an integer value but found nothing"))
|
||||||
|
case Some(b) :: Some(a) :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.successful(a :: b :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def longLongCodec : Codec[allPattern] = (
|
||||||
|
ulongL(46) ::
|
||||||
|
uint32L
|
||||||
|
).exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case a :: b :: HNil =>
|
||||||
|
Attempt.successful(None :: None :: None :: Some(a) :: Some(b) :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case (_ :: _ :: _ :: None :: _ :: _ :: HNil) | (_ :: _ :: _ :: _ :: None :: _ :: HNil) =>
|
||||||
|
Attempt.failure(Err("expected two long values but found one"))
|
||||||
|
case _ :: _ :: _ :: Some(a) :: Some(b) :: _ :: HNil =>
|
||||||
|
Attempt.successful(a :: b :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def complexCodec : Codec[allPattern] = (
|
||||||
|
PacketHelpers.encodedWideStringAligned(6) ::
|
||||||
|
ulongL(46) ::
|
||||||
|
uint16L ::
|
||||||
|
uintL(3)
|
||||||
|
).exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case a :: b :: c :: d :: HNil =>
|
||||||
|
Attempt.successful(Some(a) :: Some(c) :: Some(d) :: Some(b) :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case None:: _ :: _ :: _ :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a string value but found nothing"))
|
||||||
|
case _ :: _ :: _ :: None :: _ :: _ :: HNil =>
|
||||||
|
Attempt.failure(Err("expected a long value but found nothing"))
|
||||||
|
case (_ :: None :: _ :: _ :: _ :: _ :: HNil) | (_ :: _ :: None :: _ :: _ :: _ :: HNil) =>
|
||||||
|
Attempt.failure(Err("expected two integer values but found one"))
|
||||||
|
case Some(a) :: Some(c) :: Some(d) :: Some(b) :: _ :: _ :: HNil =>
|
||||||
|
Attempt.successful(a :: b :: c :: d :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
import scala.annotation.switch
|
||||||
|
def select_codec(action : Int) : Codec[allPattern] = (action : @switch) match {
|
||||||
|
case 28 | 29 | 30 | 31 =>
|
||||||
|
boolCodec
|
||||||
|
|
||||||
|
case 33 =>
|
||||||
|
intCodec(uintL(3))
|
||||||
|
case 10 | 11 | 21 | 22 | 40 =>
|
||||||
|
intCodec(uint4L)
|
||||||
|
case 20 =>
|
||||||
|
intCodec(uint16L)
|
||||||
|
|
||||||
|
case 13 | 14 | 15 | 37 =>
|
||||||
|
longCodec
|
||||||
|
|
||||||
|
case 7 | 19 =>
|
||||||
|
stringCodec
|
||||||
|
|
||||||
|
case 12 | 38 =>
|
||||||
|
intLongCodec(uint32L)
|
||||||
|
case 25 =>
|
||||||
|
intLongCodec(ulongL(46))
|
||||||
|
|
||||||
|
case 23 | 24 =>
|
||||||
|
intStringCodec
|
||||||
|
|
||||||
|
case 36 =>
|
||||||
|
longLongCodec
|
||||||
|
|
||||||
|
case 34 =>
|
||||||
|
complexCodec
|
||||||
|
|
||||||
|
case _ =>
|
||||||
|
//TODO for debugging purposes only
|
||||||
|
bits.hlist.exmap[allPattern] (
|
||||||
|
{
|
||||||
|
case x :: HNil =>
|
||||||
|
org.log4s.getLogger.warn(s"can not match a codec pattern for decoding $action")
|
||||||
|
Attempt.successful(Some(x.toString) :: None :: None :: None :: None :: None :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case Some(x) :: None :: None :: None :: None :: None :: HNil =>
|
||||||
|
org.log4s.getLogger.warn(s"can not match a codec pattern for encoding $action")
|
||||||
|
Attempt.successful(scodec.bits.BitVector.fromValidBin(x) :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// ignore(0).exmap[allPattern] (
|
||||||
|
// {
|
||||||
|
// case () =>
|
||||||
|
// Attempt.failure(Err(s"can not match a codec pattern for decoding $test"))
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// case _ =>
|
||||||
|
// Attempt.failure(Err(s"can not match a codec pattern for encoding $test"))
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit val codec : Codec[SquadDefinitionActionMessage] = (
|
||||||
|
("action" | uintL(6)) >>:~ { action =>
|
||||||
|
("unk2" | uint16L) ::
|
||||||
|
("unk3" | uint4L) ::
|
||||||
|
select_codec(action)
|
||||||
|
// conditional(unk1 == 7, "unk4" | PacketHelpers.encodedWideStringAligned(6)) ::
|
||||||
|
// conditional((unk1 > 9 && unk1 < 13) || (unk1 > 20 && unk1 < 26) || unk1 == 38 || unk1 == 40, "unk5" | uint4L) ::
|
||||||
|
// conditional(unk1 == 23 || unk1 == 34, "unk6" | PacketHelpers.encodedWideStringAligned(4)) ::
|
||||||
|
// conditional(unk1 == 25 || unk1 == 34 || unk1 == 36, "unk7" | ulongL(46)) ::
|
||||||
|
// conditional(unk1 == 19, "unk8" | PacketHelpers.encodedWideStringAligned(2)) :: //goto LABEL_49
|
||||||
|
// conditional(unk1 == 20 || unk1 == 34, "unk9" | uint16L) :: //goto LABEL_48
|
||||||
|
// conditional(unk1 == 24, "unkA" | PacketHelpers.encodedWideString) :: //goto LABEL_49
|
||||||
|
// conditional((unk1 > 11 && unk1 < 16) || (unk1 > 35 && unk1 < 39), "unkB" | uint32L) :: //goto LABEL_49
|
||||||
|
// //LABEL_48
|
||||||
|
// conditional(unk1 > 27 && unk1 < 32, "unkC" | bool) :: //goto LABEL_49
|
||||||
|
// conditional(unk1 == 33, "unkD" | uintL(3)) ::
|
||||||
|
// //LABEL_49
|
||||||
|
// conditional(unk1 == 34, "unkE" | uintL(3))
|
||||||
|
}
|
||||||
|
).as[SquadDefinitionActionMessage]
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
("change" specifically indicates the perspective is from the SL; "update for squad member" actions may be different)
|
||||||
|
("[#]" indicates the mode is detected but not properly parsed; the length of the combined fields may follow
|
||||||
|
|
||||||
|
[0] - clicking on a squad listed in the "Find Squad" tab / cancel squad search
|
||||||
|
[3] - save sqad favorite (6 bits)
|
||||||
|
[4] - load a squad definition favorite (6 bits)
|
||||||
|
7 -
|
||||||
|
[8] - list squad (6 bits)
|
||||||
|
10 - select this role for yourself
|
||||||
|
11 -
|
||||||
|
12 -
|
||||||
|
13 -
|
||||||
|
14 -
|
||||||
|
15 -
|
||||||
|
19 - change purpose
|
||||||
|
20 - change zone
|
||||||
|
21 - change/close squad member position
|
||||||
|
22 - change/add squad member position
|
||||||
|
23 - change squad member req role
|
||||||
|
24 - change squad member req detailed orders
|
||||||
|
25 - change squad member req weapons
|
||||||
|
[26] - reset all (6 bits)
|
||||||
|
28 - auto-approve requests for invitation
|
||||||
|
29 -
|
||||||
|
30 -
|
||||||
|
31 - location follows squad lead
|
||||||
|
33 -
|
||||||
|
34 - search for squads with a particular role
|
||||||
|
36 -
|
||||||
|
37 -
|
||||||
|
38 -
|
||||||
|
40 - find LFS soldiers that meet the requirements for this role
|
||||||
|
[41] - cancel search for LFS soldiers (6 bits)
|
||||||
|
|
||||||
|
28 - 1u (Boolean)
|
||||||
|
29 - iu (Boolean)
|
||||||
|
30 - 1u (Boolean)
|
||||||
|
31 - 1u (Boolean)
|
||||||
|
33 - 3u (Int)
|
||||||
|
10 - 4u (Int)
|
||||||
|
11 - 4u (Int)
|
||||||
|
21 - 4u (Int)
|
||||||
|
22 - 4u (Int)
|
||||||
|
40 - 4u (Int)
|
||||||
|
20 - 16u (Int)
|
||||||
|
13 - 32u (Long)
|
||||||
|
14 - 32u (Long)
|
||||||
|
15 - 32u (Long)
|
||||||
|
37 - 32u (Long)
|
||||||
|
7 - String(6) (String)
|
||||||
|
19 - String(6) (String)
|
||||||
|
12 - 4u + 32u (Int :: Long)
|
||||||
|
38 - 4u + 32u (Int :: Long)
|
||||||
|
25 - 4u + 46u (Int :: Long)
|
||||||
|
23 - 4u + String(2) (Int :: String)
|
||||||
|
24 - 4u + String(2) (Int :: String)
|
||||||
|
36 - 46u + 32u (Long :: Long)
|
||||||
|
34 - String(6) + 46u + 16u + 3u (String :: Long :: Int :: Int)
|
||||||
|
*/
|
||||||
|
|
@ -332,6 +332,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
case msg @ AvatarGrenadeStateMessage(player_guid, state) =>
|
case msg @ AvatarGrenadeStateMessage(player_guid, state) =>
|
||||||
log.info("AvatarGrenadeStateMessage: " + msg)
|
log.info("AvatarGrenadeStateMessage: " + msg)
|
||||||
|
|
||||||
|
case msg @ SquadDefinitionActionMessage(a, b, c, d, e, f, g, h, i) =>
|
||||||
|
log.info("SquadDefinitionAction: " + msg)
|
||||||
|
|
||||||
case default => log.debug(s"Unhandled GamePacket ${pkt}")
|
case default => log.debug(s"Unhandled GamePacket ${pkt}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue