mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-04-29 16:25:30 +00:00
OutfitListEvent ListElementOutfit decoded
This commit is contained in:
parent
308ea20dee
commit
d450a1b6e5
5 changed files with 174 additions and 72 deletions
|
|
@ -38,8 +38,8 @@ object OutfitEventAction {
|
||||||
|
|
||||||
final case class OutfitInfo(
|
final case class OutfitInfo(
|
||||||
outfit_name: String,
|
outfit_name: String,
|
||||||
unk6: Long,
|
outfit_points1: Long,
|
||||||
unk7: Long,
|
outfit_points2: Long, // same as outfit_points1
|
||||||
member_count: Int,
|
member_count: Int,
|
||||||
unk9: Int,
|
unk9: Int,
|
||||||
outfit_rank_names: OutfitRankNames,
|
outfit_rank_names: OutfitRankNames,
|
||||||
|
|
@ -276,31 +276,6 @@ object OutfitEvent extends Marshallable[OutfitEvent] {
|
||||||
val unk6: RequestType.Value = Value(6)
|
val unk6: RequestType.Value = Value(6)
|
||||||
val unk7: RequestType.Value = Value(7)
|
val unk7: RequestType.Value = Value(7)
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
OutfitEvent(Unk0, ValidPlanetSideGUID(18361), Unk0(OutfitInfo(0, 0, The Black Ravens, 338420223, 338420223, 433, 0, OutfitRankNames(Corporal (No Ventrilo), Sergeant - SGT, Advance Medical, , Master Sgt - MSG, Captain, Trusted Officer, OutFit Leader), TBR website..... http://trravens.darkbb.com ventrilo info: evolve.typefrag.com port: 45694 (vent pw dotaftw) Channel PW: zeroenigma : if you guys wants to contact me, my email is zero_overkill99@yahoo.com, ValidPlanetSideGUID(32787), 0, 0, 0, 1133571390, 0, 0, 0, 0)))
|
|
||||||
OutfitEvent(Unk2, ValidPlanetSideGUID(18361), Unk2(OutfitInfo(0, 0, The Black Ravens, 338420486, 338420486, 433, 0, OutfitRankNames(Corporal (No Ventrilo), Sergeant - SGT, Advance Medical, , Master Sgt - MSG, Captain, Trusted Officer, OutFit Leader), TBR website..... http://trravens.darkbb.com ventrilo info: evolve.typefrag.com port: 45694 (vent pw dotaftw) Channel PW: zeroenigma : if you guys wants to contact me, my email is zero_overkill99@yahoo.com, ValidPlanetSideGUID(32787), 0, 0, 0, 1133571390, 0, 0, 0, 0)))
|
|
||||||
|
|
||||||
|
|
||||||
unk3 -- #66162 PSCap-2016-02-28_02-58-10-PM.txt
|
|
||||||
|
|
||||||
MP(
|
|
||||||
SMP(
|
|
||||||
MPEx(
|
|
||||||
OutfitMembershipResponse,
|
|
||||||
OutfitEvent,
|
|
||||||
SquadMemberEvent
|
|
||||||
)
|
|
||||||
),
|
|
||||||
SMP(
|
|
||||||
MPEx(
|
|
||||||
PlanetsideAttributeMessage x 3 + PlanetsideStringAttributeMessage
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
|
|
||||||
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,14 @@ package net.psforever.packet.game
|
||||||
|
|
||||||
import net.psforever.packet.GamePacketOpcode.Type
|
import net.psforever.packet.GamePacketOpcode.Type
|
||||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
import scodec.bits.BitVector
|
import scodec.{Attempt, Codec, Err}
|
||||||
|
import scodec.bits.{BitVector, ByteVector}
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
import scodec.{Attempt, Codec}
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
// 98 5ec300000d01a020004000001 12056002e0053002e0053002e0055002e004400 845400680069006f009 85ee300001e2b 858000800000110041002e0027002e0041002e0027002e00 8448006900720075009 84003200005a540000060000011a0530065006300720065007400200043006800690065006600730085530069006c00610073009840a32000001953476fe0c00011c041007a0075007200650020005400770069006c006900670068007400874600720061006e0063006b006f009840c3200000d3a4c000c00000106030002e006f0085410074006c0061007300984183200011d9296000c0000011e0570061007200720069006f007200270073002000430072006500650064008653006500760061006b00690098442320001bf40e000080000013203100330033003700740068002000410072006d006f0072006500640020004400690076006900730069006f006e002d004b008548006f0073002d004b009844c320001b3d2c200060000012a03300330031007300740020004d0069006e006e00650073006f0074006100200054007200690062006500864d006100670069002d0045009846c3200009e206c00040000010c04100720065006100350031008942006c00610063
|
|
||||||
|
|
||||||
final case class OutfitListEvent(
|
final case class OutfitListEvent(
|
||||||
outfit_score: Long,
|
request_type: OutfitListEvent.RequestType.Type,
|
||||||
unk1: Long,
|
action: OutfitListEventAction
|
||||||
unk2: Long,
|
|
||||||
unk3: Int,
|
|
||||||
outfit_name: String,
|
|
||||||
outfit_leader: String,
|
|
||||||
) extends PlanetSideGamePacket {
|
) extends PlanetSideGamePacket {
|
||||||
type Packet = OutfitListEvent
|
type Packet = OutfitListEvent
|
||||||
|
|
||||||
|
|
@ -23,13 +18,144 @@ final case class OutfitListEvent(
|
||||||
|
|
||||||
def encode: Attempt[BitVector] = OutfitListEvent.encode(this)
|
def encode: Attempt[BitVector] = OutfitListEvent.encode(this)
|
||||||
}
|
}
|
||||||
object OutfitListEvent extends Marshallable[OutfitListEvent] {
|
|
||||||
implicit val codec: Codec[OutfitListEvent] = (
|
abstract class OutfitListEventAction(val code: Int)
|
||||||
("outfit_score" | uint32) ::
|
|
||||||
|
object OutfitListEventAction {
|
||||||
|
|
||||||
|
final case class ListElementOutfit(
|
||||||
|
outfit_id: Long,
|
||||||
|
points: Long,
|
||||||
|
members: Long,
|
||||||
|
outfit_name: String,
|
||||||
|
outfit_leader: String,
|
||||||
|
) extends OutfitListEventAction(code = 2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Check packet when bundle packet has been implemented (packet containing OutfitListEvent packets back to back)
|
||||||
|
For now it seems like there is no valid packet captured
|
||||||
|
*/
|
||||||
|
final case class Unk3(
|
||||||
|
unk1: Long,
|
||||||
|
data: ByteVector
|
||||||
|
) extends OutfitListEventAction(code = 3)
|
||||||
|
|
||||||
|
final case class Unknown(badCode: Int, data: BitVector) extends OutfitListEventAction(badCode)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `Codec`s used to transform the input stream into the context of a specific action
|
||||||
|
* and extract the field data from that stream.
|
||||||
|
*/
|
||||||
|
object Codecs {
|
||||||
|
private val everFailCondition = conditional(included = false, bool)
|
||||||
|
|
||||||
|
val ListElementOutfitCodec: Codec[ListElementOutfit] = (
|
||||||
("unk1" | uint32L) ::
|
("unk1" | uint32L) ::
|
||||||
("unk2" | uint32L) ::
|
("points" | uint32L) ::
|
||||||
("unk3" | uint(3)) ::
|
("members" | uint32L) ::
|
||||||
("outfit_name" | PacketHelpers.encodedWideStringAligned(5)) ::
|
("outfit_name" | PacketHelpers.encodedWideStringAligned(5)) ::
|
||||||
("outfit_leader" | PacketHelpers.encodedWideString)
|
("outfit_leader" | PacketHelpers.encodedWideString)
|
||||||
).as[OutfitListEvent]
|
).xmap[ListElementOutfit](
|
||||||
|
{
|
||||||
|
case u1 :: points :: members :: outfit_name :: outfit_leader :: HNil =>
|
||||||
|
ListElementOutfit(u1, points, members, outfit_name, outfit_leader)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case ListElementOutfit(u1, points, members, outfit_name, outfit_leader) =>
|
||||||
|
u1 :: points :: members :: outfit_name :: outfit_leader :: HNil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val Unk3Codec: Codec[Unk3] = (
|
||||||
|
("unk1" | uint32L) ::
|
||||||
|
("data" | bytes)
|
||||||
|
).xmap[Unk3](
|
||||||
|
{
|
||||||
|
case u1 :: data :: HNil =>
|
||||||
|
Unk3(u1, data)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case Unk3(u1, data) =>
|
||||||
|
u1 :: data :: HNil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common form for known action code indexes with an unknown purpose and transformation is an "Unknown" object.
|
||||||
|
*
|
||||||
|
* @param action the action behavior code
|
||||||
|
* @return a transformation between the action code and the unknown bit data
|
||||||
|
*/
|
||||||
|
def unknownCodec(action: Int): Codec[Unknown] =
|
||||||
|
bits.xmap[Unknown](
|
||||||
|
data => Unknown(action, data),
|
||||||
|
{
|
||||||
|
case Unknown(_, data) => data
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The action code was completely unanticipated!
|
||||||
|
*
|
||||||
|
* @param action the action behavior code
|
||||||
|
* @return nothing; always fail
|
||||||
|
*/
|
||||||
|
def failureCodec(action: Int): Codec[OutfitListEventAction] =
|
||||||
|
everFailCondition.exmap[OutfitListEventAction](
|
||||||
|
_ => Attempt.failure(Err(s"can not match a codec pattern for decoding $action")),
|
||||||
|
_ => Attempt.failure(Err(s"can not match a codec pattern for encoding $action"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object OutfitListEvent extends Marshallable[OutfitListEvent] {
|
||||||
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
|
object RequestType extends Enumeration {
|
||||||
|
type Type = Value
|
||||||
|
|
||||||
|
val Unk0: RequestType.Value = Value(0)
|
||||||
|
val Unk1: RequestType.Value = Value(1)
|
||||||
|
val ListElementOutfit: RequestType.Value = Value(2)
|
||||||
|
val Unk3: RequestType.Value = Value(3)
|
||||||
|
val Unk4: RequestType.Value = Value(4)
|
||||||
|
val Unk5: RequestType.Value = Value(5)
|
||||||
|
val unk6: RequestType.Value = Value(6)
|
||||||
|
val unk7: RequestType.Value = Value(7)
|
||||||
|
|
||||||
|
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
||||||
|
}
|
||||||
|
|
||||||
|
private def selectFromType(code: Int): Codec[OutfitListEventAction] = {
|
||||||
|
import OutfitListEventAction.Codecs._
|
||||||
|
import scala.annotation.switch
|
||||||
|
|
||||||
|
((code: @switch) match {
|
||||||
|
case 0 => unknownCodec(action = code)
|
||||||
|
case 1 => unknownCodec(action = code)
|
||||||
|
case 2 => ListElementOutfitCodec
|
||||||
|
case 3 => Unk3Codec // indicated in code
|
||||||
|
case 4 => unknownCodec(action = code)
|
||||||
|
case 5 => unknownCodec(action = code)
|
||||||
|
case 6 => unknownCodec(action = code)
|
||||||
|
case 7 => unknownCodec(action = code)
|
||||||
|
|
||||||
|
case _ => failureCodec(code)
|
||||||
|
}).asInstanceOf[Codec[OutfitListEventAction]]
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit val codec: Codec[OutfitListEvent] = (
|
||||||
|
("request_type" | RequestType.codec) >>:~ { request_type =>
|
||||||
|
("action" | selectFromType(request_type.id)).hlist
|
||||||
|
}
|
||||||
|
).xmap[OutfitListEvent](
|
||||||
|
{
|
||||||
|
case request_type :: action :: HNil =>
|
||||||
|
OutfitListEvent(request_type, action)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case OutfitListEvent(request_type, action) =>
|
||||||
|
request_type :: action :: HNil
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ object OutfitRequest extends Marshallable[OutfitRequest] {
|
||||||
val Rank: RequestType.Value = Value(1)
|
val Rank: RequestType.Value = Value(1)
|
||||||
val Unk2: RequestType.Value = Value(2)
|
val Unk2: RequestType.Value = Value(2)
|
||||||
val Detail: RequestType.Value = Value(3)
|
val Detail: RequestType.Value = Value(3)
|
||||||
val List: RequestType.Value = Value(4)
|
val List: RequestType.Value = Value(4) // sent by client if menu is either open (true) or closed (false)
|
||||||
|
|
||||||
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +175,7 @@ object OutfitRequest extends Marshallable[OutfitRequest] {
|
||||||
}
|
}
|
||||||
).xmap[OutfitRequest](
|
).xmap[OutfitRequest](
|
||||||
{
|
{
|
||||||
case _:: id:: action :: HNil =>
|
case _ :: id:: action :: HNil =>
|
||||||
OutfitRequest(id, action)
|
OutfitRequest(id, action)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ class OutfitEventTest extends Specification {
|
||||||
action mustEqual Unk0(
|
action mustEqual Unk0(
|
||||||
OutfitInfo(
|
OutfitInfo(
|
||||||
outfit_name = "Black Armored Reapers",
|
outfit_name = "Black Armored Reapers",
|
||||||
unk6 = 223190045,
|
outfit_points1 = 223190045,
|
||||||
unk7 = 223190045,
|
outfit_points2 = 223190045,
|
||||||
member_count = 171,
|
member_count = 171,
|
||||||
unk9 = 0,
|
unk9 = 0,
|
||||||
OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""),
|
OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""),
|
||||||
|
|
@ -87,8 +87,8 @@ class OutfitEventTest extends Specification {
|
||||||
Unk0(
|
Unk0(
|
||||||
OutfitInfo(
|
OutfitInfo(
|
||||||
outfit_name = "Black Armored Reapers",
|
outfit_name = "Black Armored Reapers",
|
||||||
unk6 = 223190045,
|
outfit_points1 = 223190045,
|
||||||
unk7 = 223190045,
|
outfit_points2 = 223190045,
|
||||||
member_count = 171,
|
member_count = 171,
|
||||||
unk9 = 0,
|
unk9 = 0,
|
||||||
OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""),
|
OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""),
|
||||||
|
|
@ -145,8 +145,8 @@ class OutfitEventTest extends Specification {
|
||||||
outfit_guid mustEqual 2147418113L
|
outfit_guid mustEqual 2147418113L
|
||||||
action mustEqual Unk2(OutfitInfo(
|
action mustEqual Unk2(OutfitInfo(
|
||||||
outfit_name = "PlanetSide_Forever_Vanu",
|
outfit_name = "PlanetSide_Forever_Vanu",
|
||||||
unk6 = 0,
|
outfit_points1 = 0,
|
||||||
unk7 = 0,
|
outfit_points2 = 0,
|
||||||
member_count = 1,
|
member_count = 1,
|
||||||
unk9 = 0,
|
unk9 = 0,
|
||||||
OutfitRankNames("","","","","","","",""),
|
OutfitRankNames("","","","","","","",""),
|
||||||
|
|
@ -173,8 +173,8 @@ class OutfitEventTest extends Specification {
|
||||||
Unk2(
|
Unk2(
|
||||||
OutfitInfo(
|
OutfitInfo(
|
||||||
outfit_name = "PlanetSide_Forever_Vanu",
|
outfit_name = "PlanetSide_Forever_Vanu",
|
||||||
unk6 = 0,
|
outfit_points1 = 0,
|
||||||
unk7 = 0,
|
outfit_points2 = 0,
|
||||||
member_count = 1,
|
member_count = 1,
|
||||||
unk9 = 0,
|
unk9 = 0,
|
||||||
OutfitRankNames("","","","","","","",""),
|
OutfitRankNames("","","","","","","",""),
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,30 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
import net.psforever.packet._
|
import net.psforever.packet._
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game.OutfitListEvent
|
||||||
|
import net.psforever.packet.game.OutfitListEvent.RequestType
|
||||||
|
import net.psforever.packet.game.OutfitListEventAction.ListElementOutfit
|
||||||
import org.specs2.mutable._
|
import org.specs2.mutable._
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
class OutfitListEventTest extends Specification {
|
class OutfitListEventTest extends Specification {
|
||||||
val unk0_ABC: ByteVector = ByteVector.fromValidHex("98 5e83a000 0000 e180 0080 0000 11404e0069006700680074004c006f00720064007300 854e005900430061007400")
|
val unk0_ABC: ByteVector = ByteVector.fromValidHex("98 5 e83a0000 000e1800 0800000 11404e0069006700680074004c006f00720064007300 854e005900430061007400")
|
||||||
val unk0_DEF: ByteVector = ByteVector.fromValidHex("98 4ec28100 151a 6280 0340 0000 11a0490052004f004e004600490053005400200043006c0061006e00 8654006f006c006a00")
|
val unk0_DEF: ByteVector = ByteVector.fromValidHex("98 4 ec281001 51a62800 3400000 11a0490052004f004e004600490053005400200043006c0061006e00 8654006f006c006a00")
|
||||||
val unk1_ABC: ByteVector = ByteVector.fromValidHex("98 4723c000 02aa 81e0 0220 0000 11006900470061006d00650073002d004500 906900670061006d006500730043005400460057006800610063006b002d004500")
|
val unk1_ABC: ByteVector = ByteVector.fromValidHex("98 4 723c0000 2aa81e00 2200000 11006900470061006d00650073002d004500 906900670061006d006500730043005400460057006800610063006b002d004500")
|
||||||
val unk2_ABC: ByteVector = ByteVector.fromValidHex("98 49a3c000 116d a4e0 0040 0000 11a042006c006f006f00640020006f0066002000560061006e007500 864b00610072006e002d004500")
|
val unk2_ABC: ByteVector = ByteVector.fromValidHex("98 4 9a3c0001 16da4e00 0400000 11a042006c006f006f00640020006f0066002000560061006e007500 864b00610072006e002d004500")
|
||||||
val unk3_ABC: ByteVector = ByteVector.fromValidHex("98 49c3c000 0df5 87c0 0140 0000 11a054006800650020004e00650076006500720068006f006f006400 8e6f00460058006f00530074006f006e0065004d0061006e002d004700")
|
val unk3_ABC: ByteVector = ByteVector.fromValidHex("98 4 9c3c0000 df587c00 1400000 11a054006800650020004e00650076006500720068006f006f006400 8e6f00460058006f00530074006f006e0065004d0061006e002d004700")
|
||||||
val unk4_ABC: ByteVector = ByteVector.fromValidHex("98 4c03c000 0240 6040 0060 0000 1220540068006500200042006c00610063006b0020004b006e0069006700680074007300 874400720061007a00760065006e00")
|
val unk4_ABC: ByteVector = ByteVector.fromValidHex("98 4 c03c0000 24060400 0600000 1220540068006500200042006c00610063006b0020004b006e0069006700680074007300 874400720061007a00760065006e00")
|
||||||
val unk5_ABC: ByteVector = ByteVector.fromValidHex("98 5383c000 14b7 09a0 00c0 0000 10a03e005400760053003c00 89430061007000650062006f00610074007300")
|
val unk5_ABC: ByteVector = ByteVector.fromValidHex("98 5 383c0001 4b709a00 0c00000 10a03e005400760053003c00 89430061007000650062006f00610074007300")
|
||||||
val unk6_ABC: ByteVector = ByteVector.fromValidHex("98 5b03c000 035d 6700 0040 0000 11404c006f0073007400200043006100750073006500 895a00650072006f004b00650077006c006c00")
|
val unk6_ABC: ByteVector = ByteVector.fromValidHex("98 5 b03c0000 35d67000 0400000 11404c006f0073007400200043006100750073006500 895a00650072006f004b00650077006c006c00")
|
||||||
val unk7_ABC: ByteVector = ByteVector.fromValidHex("98 4043e000 19fb 8261 6140 0000 11e0540068006500200042006c00610063006b00200054006f00770065007200 874b00720075007000680065007800")
|
val unk7_ABC: ByteVector = ByteVector.fromValidHex("98 4 043e0001 9fb82616 1400000 11e0540068006500200042006c00610063006b00200054006f00770065007200 874b00720075007000680065007800")
|
||||||
val unk8_ABC: ByteVector = ByteVector.fromValidHex("98 4a03e000 17e2") // broken, limit of SMP
|
|
||||||
|
|
||||||
"decode unk0_ABC" in {
|
"decode unk0_ABC" in {
|
||||||
PacketCoding.decodePacket(unk0_ABC).require match {
|
PacketCoding.decodePacket(unk0_ABC).require match {
|
||||||
case OutfitListEvent(outfit_score, unk1, unk2, unk3, outfit_name, outfit_leader) =>
|
case OutfitListEvent(code, ListElementOutfit(unk1, points, members, outfit_name, outfit_leader)) =>
|
||||||
outfit_score mustEqual 1585684480L
|
code mustEqual OutfitListEvent.RequestType.ListElementOutfit
|
||||||
unk1 mustEqual 2162229248L
|
unk1 mustEqual 7668
|
||||||
unk2 mustEqual 32768
|
points mustEqual 788224
|
||||||
unk3 mustEqual 0
|
members mustEqual 4
|
||||||
outfit_name mustEqual "NightLords"
|
outfit_name mustEqual "NightLords"
|
||||||
outfit_leader mustEqual "NYCat"
|
outfit_leader mustEqual "NYCat"
|
||||||
case _ =>
|
case _ =>
|
||||||
|
|
@ -33,7 +34,7 @@ class OutfitListEventTest extends Specification {
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode unk0_ABC" in {
|
"encode unk0_ABC" in {
|
||||||
val msg = OutfitListEvent(1585684480L, 2162229248L, 32768, 0, "NightLords", "NYCat")
|
val msg = OutfitListEvent(RequestType.ListElementOutfit, ListElementOutfit(7668, 788224, 4, "NightLords", "NYCat"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual unk0_ABC
|
pkt mustEqual unk0_ABC
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue