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

View file

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