OutfitEvent rework

renamed type Unk4 to UpdateOutfitId
This commit is contained in:
Resaec 2025-08-24 00:23:38 +02:00
parent e3fe9b69bf
commit 72a8a7cd89
2 changed files with 67 additions and 169 deletions

View file

@ -39,55 +39,38 @@ object OutfitEventAction {
outfit_name: String, outfit_name: String,
outfit_points1: Long, outfit_points1: Long,
outfit_points2: Long, // same as outfit_points1 outfit_points2: Long, // same as outfit_points1
member_count: Int, member_count: Long,
unk9: Int,
outfit_rank_names: OutfitRankNames, outfit_rank_names: OutfitRankNames,
motd: String, motd: String,
unk10: Int, unk10: Int,
unk11: Int, unk11: Boolean,
unk12: Int, unk12: Long, // only set if unk11 is false
unk13: Int,// ?
unk21: Int,
unk21_2: Int,
created_timestamp: Long, created_timestamp: Long,
unk23: Long, unk23: Long,
unk24: Long, unk24: Long,
unk25: Long, unk25: Long,
u123: Int,
) )
final case class Unk0( final case class Unk0(
outfitInfo: OutfitInfo outfit_info: OutfitInfo
) extends OutfitEventAction(code = 0) ) extends OutfitEventAction(code = 0)
final case class Unk1( final case class Unk1(
unk2: Int,
unk3: Boolean,
) extends OutfitEventAction(code = 1) ) extends OutfitEventAction(code = 1)
final case class Unk2( final case class Unk2(
outfitInfo: OutfitInfo, outfit_info: OutfitInfo,
) extends OutfitEventAction(code = 2) ) extends OutfitEventAction(code = 2)
final case class Unk3( final case class Unk3(
unk2: Int,
unk3: Boolean,
data: BitVector,
) extends OutfitEventAction(code = 3) ) extends OutfitEventAction(code = 3)
final case class Unk4( final case class UpdateOutfitId(
new_outfit_id: Long, new_outfit_id: Long,
unk3: Int,
unk4: Boolean,
data: BitVector,
) extends OutfitEventAction(code = 4) ) extends OutfitEventAction(code = 4)
final case class Unk5( final case class Unk5(
unk1: Int, unk1: Long,
unk2: Int,
unk3: Int,
unk4: Boolean,
data: BitVector,
) extends OutfitEventAction(code = 5) ) extends OutfitEventAction(code = 5)
final case class Unknown(badCode: Int, data: BitVector) extends OutfitEventAction(badCode) final case class Unknown(badCode: Int, data: BitVector) extends OutfitEventAction(badCode)
@ -120,38 +103,33 @@ object OutfitEventAction {
) )
private val InfoCodec: Codec[OutfitInfo] = ( private val InfoCodec: Codec[OutfitInfo] = (
PacketHelpers.encodedWideStringAligned(5) :: ("outfit_name" | PacketHelpers.encodedWideStringAligned(5)) ::
uint32L :: ("outfit_points1" | uint32L) ::
uint32L :: ("outfit_points2" | uint32L) ::
uint16L :: ("member_count" | uint32L) ::
uint16L :: ("outfit_rank_names" | OutfitRankNamesCodec) ::
OutfitRankNamesCodec :: ("motd" | PacketHelpers.encodedWideString) ::
PacketHelpers.encodedWideString :: ("" | uint8L) ::
uint8L :: ("" | bool) ::
uint8L :: ("" | uint32L) ::
uint8L ::
uint8L ::
uint8L :: // bool somewhere here
uintL(1) :: //
("created_timestamp" | uint32L) :: ("created_timestamp" | uint32L) ::
uint32L :: ("" | uint32L) ::
uint32L :: ("" | uint32L) ::
uint32L :: ("" | uint32L)
uintL(7)
).xmap[OutfitInfo]( ).xmap[OutfitInfo](
{ {
case outfit_name :: u6 :: u7 :: member_count :: u9 :: outfit_rank_names :: motd :: u10 :: u11 :: u12 :: u13 :: u21 :: u21_2 :: created_timestamp :: u23 :: u24 :: u25 :: u123 :: HNil => case outfit_name :: outfit_points1 :: outfit_points2 :: member_count :: outfit_rank_names :: motd :: u10 :: u11 :: u12 :: created_timestamp :: u23 :: u24 :: u25 :: HNil =>
OutfitInfo(outfit_name, u6, u7, member_count, u9, outfit_rank_names, motd, u10, u11, u12, u13, u21, u21_2, created_timestamp, u23, u24, u25, u123) OutfitInfo(outfit_name, outfit_points1, outfit_points2, member_count, outfit_rank_names, motd, u10, u11, u12, created_timestamp, u23, u24, u25)
}, },
{ {
case OutfitInfo(outfit_name, u6, u7, member_count, u9, outfit_rank_names, motd, u10, u11, u12, u13, u21, u21_2, created_timestamp, u23, u24, u25, u123) => case OutfitInfo(outfit_name, outfit_points1, outfit_points2, member_count, outfit_rank_names, motd, u10, u11, u12, created_timestamp, u23, u24, u25) =>
outfit_name :: u6 :: u7 :: member_count :: u9 :: outfit_rank_names :: motd :: u10 :: u11 :: u12 :: u13 :: u21 :: u21_2 :: created_timestamp :: u23 :: u24 :: u25 :: u123 :: HNil outfit_name :: outfit_points1 :: outfit_points2 :: member_count :: outfit_rank_names :: motd :: u10 :: u11 :: u12 :: created_timestamp :: u23 :: u24 :: u25 :: HNil
} }
) )
val Unk0Codec: Codec[Unk0] = ( val Unk0Codec: Codec[Unk0] = (
InfoCodec ("outfit_info" | InfoCodec)
).xmap[Unk0]( ).xmap[Unk0](
{ {
case info => case info =>
Unk0(info) Unk0(info)
@ -162,23 +140,11 @@ object OutfitEventAction {
} }
) )
val Unk1Codec: Codec[Unk1] = ( val Unk1Codec: Codec[Unk1] = PacketHelpers.emptyCodec(Unk1())
uint4L ::
bool
).xmap[Unk1](
{
case u2 :: u3 :: HNil =>
Unk1(u2, u3)
},
{
case Unk1(u2, u3) =>
u2 :: u3 :: HNil
}
)
val Unk2Codec: Codec[Unk2] = ( val Unk2Codec: Codec[Unk2] = (
InfoCodec ("outfit_info" | InfoCodec)
).xmap[Unk2]( ).xmap[Unk2](
{ {
case info => case info =>
Unk2(info) Unk2(info)
@ -189,51 +155,31 @@ object OutfitEventAction {
} }
) )
val Unk3Codec: Codec[Unk3] = ( val Unk3Codec: Codec[Unk3] = PacketHelpers.emptyCodec(Unk3())
uint4L ::
bool ::
bits
).xmap[Unk3](
{
case u2 :: u3 :: data :: HNil =>
Unk3(u2, u3, data)
},
{
case Unk3(u2, u3, data) =>
u2 :: u3 :: data :: HNil
}
)
val Unk4Codec: Codec[Unk4] = ( // update outfit_id? // 2016.03.18 #10640 // after this packet the referenced id changes to the new one, old is not used again val UpdateOutfitIdCodec: Codec[UpdateOutfitId] = ( // update outfit_id? // 2016.03.18 #10640 // after this packet the referenced id changes to the new one, old is not used again
uint32L :: // real / other outfit_id ("new_outfit_id" | uint32L)
uint4L :: ).xmap[UpdateOutfitId](
bool ::
bits
).xmap[Unk4](
{ {
case new_outfit_id :: u3 :: u4 :: data :: HNil => case new_outfit_id =>
Unk4(new_outfit_id, u3, u4, data) UpdateOutfitId(new_outfit_id)
}, },
{ {
case Unk4(new_outfit_id, u3, u4, data) => case UpdateOutfitId(new_outfit_id) =>
new_outfit_id ::u3 :: u4 :: data :: HNil new_outfit_id
} }
) )
val Unk5Codec: Codec[Unk5] = ( val Unk5Codec: Codec[Unk5] = (
uint16L :: ("" | uint32L)
uint16L :: ).xmap[Unk5](
uint4L ::
bool ::
bits
).xmap[Unk5](
{ {
case u1 :: u2 :: u3 :: u4 :: data :: HNil => case u1 =>
Unk5(u1, u2, u3, u4, data) Unk5(u1)
}, },
{ {
case Unk5(u1, u2, u3, u4, data) => case Unk5(u1) =>
u1 :: u2 :: u3 :: u4 :: data :: HNil u1
} }
) )
@ -274,10 +220,10 @@ object OutfitEvent extends Marshallable[OutfitEvent] {
val Unk1: RequestType.Value = Value(1) // end listing of members val Unk1: RequestType.Value = Value(1) // end listing of members
val Unk2: RequestType.Value = Value(2) // send after creating an outfit // normal info, same as Unk0 val Unk2: RequestType.Value = Value(2) // send after creating an outfit // normal info, same as Unk0
val Unk3: RequestType.Value = Value(3) // below val Unk3: RequestType.Value = Value(3) // below
val Unk4: RequestType.Value = Value(4) val UpdateOutfitId: RequestType.Value = Value(4)
val Unk5: RequestType.Value = Value(5) val Unk5: RequestType.Value = Value(5)
val unk6: RequestType.Value = Value(6) val Unk6: RequestType.Value = Value(6)
val unk7: RequestType.Value = Value(7) val Unk7: RequestType.Value = Value(7)
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3)) implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
} }
@ -291,7 +237,7 @@ object OutfitEvent extends Marshallable[OutfitEvent] {
case 1 => Unk1Codec case 1 => Unk1Codec
case 2 => Unk2Codec // sent after /outfitcreate and on login if in an outfit case 2 => Unk2Codec // sent after /outfitcreate and on login if in an outfit
case 3 => Unk3Codec case 3 => Unk3Codec
case 4 => Unk4Codec case 4 => UpdateOutfitIdCodec
case 5 => Unk5Codec case 5 => Unk5Codec
case 6 => unknownCodec(action = code) case 6 => unknownCodec(action = code)
case 7 => unknownCodec(action = code) case 7 => unknownCodec(action = code)

View file

@ -29,7 +29,7 @@ class OutfitEventTest extends Specification {
"0000 00737296 24000000 00000000 00000000 0000") "0000 00737296 24000000 00000000 00000000 0000")
val unk1_ABC: ByteVector = hex"8f 2 302a 10 00 0" val unk1_ABC: ByteVector = hex"8f 2 302a 10 00 0"
val unk2_ABC: ByteVector = ByteVector.fromValidHex( val unk2_ABC: ByteVector = ByteVector.fromValidHex(
"8f 4 0201 feff" + "8f 4 0201feff" +
"2e 0 50006c0061006e006500740053006900640065005f0046006f00720065007600650072005f00560061006e007500" + // PlanetSide_Forever_Vanu "2e 0 50006c0061006e006500740053006900640065005f0046006f00720065007600650072005f00560061006e007500" + // PlanetSide_Forever_Vanu
"00000000" + "00000000" +
"00000000" + "00000000" +
@ -60,17 +60,12 @@ class OutfitEventTest extends Specification {
outfit_points1 = 223190045, outfit_points1 = 223190045,
outfit_points2 = 223190045, outfit_points2 = 223190045,
member_count = 171, member_count = 171,
unk9 = 0,
OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""), OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""),
"\\#0000ffMumble \\#0033ffInfo \\#0066ffis \\#0099ffthemoose.typefrag.com \\#00ccffport \\#00ffff9350 \\#00ccffjoin \\#0099ffit \\#0066ffor \\#0033ffbe \\#0000ffkicked.", "\\#0000ffMumble \\#0033ffInfo \\#0066ffis \\#0099ffthemoose.typefrag.com \\#00ccffport \\#00ffff9350 \\#00ccffjoin \\#0099ffit \\#0066ffor \\#0033ffbe \\#0000ffkicked.",
15, 15,
128, unk11 = true,
0, unk12 = 0,
0, created_timestamp = 1210901990,
0,
0,
1210901990,
0,
0, 0,
0, 0,
0, 0,
@ -91,17 +86,12 @@ class OutfitEventTest extends Specification {
outfit_points1 = 223190045, outfit_points1 = 223190045,
outfit_points2 = 223190045, outfit_points2 = 223190045,
member_count = 171, member_count = 171,
unk9 = 0,
OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""), OutfitRankNames("Dog Meat","Russian","","","Squad Leaders","Acting Commanders","Reapers",""),
"\\#0000ffMumble \\#0033ffInfo \\#0066ffis \\#0099ffthemoose.typefrag.com \\#00ccffport \\#00ffff9350 \\#00ccffjoin \\#0099ffit \\#0066ffor \\#0033ffbe \\#0000ffkicked.", "\\#0000ffMumble \\#0033ffInfo \\#0066ffis \\#0099ffthemoose.typefrag.com \\#00ccffport \\#00ffff9350 \\#00ccffjoin \\#0099ffit \\#0066ffor \\#0033ffbe \\#0000ffkicked.",
15, 15,
128, unk11 = true,
0, unk12 = 0,
0, created_timestamp = 1210901990,
0,
0,
1210901990,
0,
0, 0,
0, 0,
0, 0,
@ -118,10 +108,7 @@ class OutfitEventTest extends Specification {
case OutfitEvent(request_type, outfit_guid, action) => case OutfitEvent(request_type, outfit_guid, action) =>
request_type mustEqual RequestType.Unk1 request_type mustEqual RequestType.Unk1
outfit_guid mustEqual 529688L outfit_guid mustEqual 529688L
action mustEqual Unk1( action mustEqual Unk1()
unk2 = 0,
unk3 = false
)
case _ => case _ =>
ko ko
} }
@ -131,10 +118,7 @@ class OutfitEventTest extends Specification {
val msg = OutfitEvent( val msg = OutfitEvent(
RequestType.Unk1, RequestType.Unk1,
529688L, 529688L,
Unk1( Unk1()
unk2 = 0,
unk3 = false,
)
) )
val pkt = PacketCoding.encodePacket(msg).require.toByteVector val pkt = PacketCoding.encodePacket(msg).require.toByteVector
@ -151,20 +135,15 @@ class OutfitEventTest extends Specification {
outfit_points1 = 0, outfit_points1 = 0,
outfit_points2 = 0, outfit_points2 = 0,
member_count = 1, member_count = 1,
unk9 = 0,
OutfitRankNames("","","","","","","",""), OutfitRankNames("","","","","","","",""),
"", "",
0, 0,
112, unk11 = false,
73, unk12 = 300000,
130, created_timestamp = 0,
0, 0,
0, 0,
0, 0,
0,
0,
0,
0
)) ))
case _ => case _ =>
ko ko
@ -181,20 +160,15 @@ class OutfitEventTest extends Specification {
outfit_points1 = 0, outfit_points1 = 0,
outfit_points2 = 0, outfit_points2 = 0,
member_count = 1, member_count = 1,
unk9 = 0,
OutfitRankNames("","","","","","","",""), OutfitRankNames("","","","","","","",""),
"", "",
0, 0,
112, unk11 = false,
73, unk12 = 300000,
130, created_timestamp = 0,
0, 0,
0, 0,
0, 0,
0,
0,
0,
0
) )
) )
) )
@ -208,11 +182,7 @@ class OutfitEventTest extends Specification {
case OutfitEvent(request_type, outfit_guid, action) => case OutfitEvent(request_type, outfit_guid, action) =>
request_type mustEqual RequestType.Unk3 request_type mustEqual RequestType.Unk3
outfit_guid mustEqual 2147418113L outfit_guid mustEqual 2147418113L
action mustEqual Unk3( action mustEqual Unk3()
unk2 = 0,
unk3 = false,
BitVector.fromValidHex("")
)
case _ => case _ =>
ko ko
} }
@ -222,11 +192,7 @@ class OutfitEventTest extends Specification {
val msg = OutfitEvent( val msg = OutfitEvent(
RequestType.Unk3, RequestType.Unk3,
2147418113L, 2147418113L,
Unk3( Unk3()
unk2 = 0,
unk3 = false,
BitVector.fromValidHex("")
)
) )
val pkt = PacketCoding.encodePacket(msg).require.toByteVector val pkt = PacketCoding.encodePacket(msg).require.toByteVector
@ -236,13 +202,10 @@ class OutfitEventTest extends Specification {
"decode Unk4 ABC" in { "decode Unk4 ABC" in {
PacketCoding.decodePacket(unk4_ABC).require match { PacketCoding.decodePacket(unk4_ABC).require match {
case OutfitEvent(request_type, outfit_guid, action) => case OutfitEvent(request_type, outfit_guid, action) =>
request_type mustEqual RequestType.Unk4 request_type mustEqual RequestType.UpdateOutfitId
outfit_guid mustEqual 2147418113L outfit_guid mustEqual 2147418113L
action mustEqual Unk4( action mustEqual UpdateOutfitId(
new_outfit_id = 529744L, new_outfit_id = 529744L,
0,
unk4 = false,
BitVector.fromValidHex("")
) )
case _ => case _ =>
ko ko
@ -251,13 +214,10 @@ class OutfitEventTest extends Specification {
"encode Unk4 ABC" in { "encode Unk4 ABC" in {
val msg = OutfitEvent( val msg = OutfitEvent(
RequestType.Unk4, RequestType.UpdateOutfitId,
2147418113L, 2147418113L,
Unk4( UpdateOutfitId(
new_outfit_id = 529744L, new_outfit_id = 529744L,
unk3 = 0,
unk4 = false,
BitVector.fromValidHex("")
) )
) )
val pkt = PacketCoding.encodePacket(msg).require.toByteVector val pkt = PacketCoding.encodePacket(msg).require.toByteVector
@ -272,10 +232,6 @@ class OutfitEventTest extends Specification {
outfit_guid mustEqual 2147418113L outfit_guid mustEqual 2147418113L
action mustEqual Unk5( action mustEqual Unk5(
unk1 = 2, unk1 = 2,
unk2 = 0,
unk3 = 0,
unk4 = false,
BitVector.fromValidHex("") // OR f88c2a0417c1a06101001f20f4b8c00000404090ac9c6745dea88cadf0f810e03e0200f92 with bool at the back
) )
case _ => case _ =>
ko ko
@ -288,10 +244,6 @@ class OutfitEventTest extends Specification {
2147418113L, 2147418113L,
Unk5( Unk5(
unk1 = 2, unk1 = 2,
unk2 = 0,
unk3 = 0,
unk4 = false,
BitVector.fromValidHex("")
) )
) )
val pkt = PacketCoding.encodePacket(msg).require.toByteVector val pkt = PacketCoding.encodePacket(msg).require.toByteVector