extend OMR with Unk2 codec

This commit is contained in:
Resaec 2025-08-17 19:51:20 +02:00
parent f2001dbc5f
commit d19cd744d5
3 changed files with 101 additions and 21 deletions

View file

@ -24,15 +24,38 @@ abstract class OutfitMembershipRequestAction(val code: Int)
object OutfitMembershipRequestAction {
final case class CreateOutfit(unk2: String, unk3: Int, unk4: Boolean, outfit_name: String) extends OutfitMembershipRequestAction(code = 0)
final case class CreateOutfit(
unk2: String,
unk3: Int,
unk4: Boolean,
outfit_name: String
) extends OutfitMembershipRequestAction(code = 0)
final case class FormOutfit(unk2: String, unk3: Int, unk4: Boolean, outfit_name: String) extends OutfitMembershipRequestAction(code = 1)
final case class FormOutfit(
unk2: String,
unk3: Int,
unk4: Boolean,
outfit_name: String
) extends OutfitMembershipRequestAction(code = 1)
final case class AcceptOutfitInvite(unk2: String) extends OutfitMembershipRequestAction(code = 3)
final case class Unk2(
unk2: Int,
unk3: Int,
member_name: String,
) extends OutfitMembershipRequestAction(code = 2)
final case class AcceptOutfitInvite(
unk2: String
) extends OutfitMembershipRequestAction(code = 3)
final case class RejectOutfitInvite(unk2: String) extends OutfitMembershipRequestAction(code = 4)
final case class RejectOutfitInvite(
unk2: String
) extends OutfitMembershipRequestAction(code = 4)
final case class CancelOutfitInvite(unk5: Int, unk6: Int, outfit_name: String) extends OutfitMembershipRequestAction(code = 5)
final case class CancelOutfitInvite(
unk5: Int,
unk6: Int,
outfit_name: String
) extends OutfitMembershipRequestAction(code = 5)
final case class Unknown(badCode: Int, data: BitVector) extends OutfitMembershipRequestAction(badCode)
@ -44,7 +67,12 @@ object OutfitMembershipRequestAction {
private val everFailCondition = conditional(included = false, bool)
val CreateOutfitCodec: Codec[CreateOutfit] =
(PacketHelpers.encodedWideString :: uint4L :: bool :: PacketHelpers.encodedWideString).xmap[CreateOutfit](
(
PacketHelpers.encodedWideString ::
uint4L ::
bool ::
PacketHelpers.encodedWideString
).xmap[CreateOutfit](
{
case unk2 :: unk3 :: unk4 :: outfit_name :: HNil =>
CreateOutfit(unk2, unk3, unk4, outfit_name)
@ -56,7 +84,12 @@ object OutfitMembershipRequestAction {
)
val FormOutfitCodec: Codec[FormOutfit] =
(PacketHelpers.encodedWideString :: uint4L :: bool :: PacketHelpers.encodedWideString).xmap[FormOutfit](
(
PacketHelpers.encodedWideString ::
uint4L ::
bool ::
PacketHelpers.encodedWideString
).xmap[FormOutfit](
{
case unk2 :: unk3 :: unk4 :: outfit_name :: HNil =>
FormOutfit(unk2, unk3, unk4, outfit_name)
@ -67,6 +100,22 @@ object OutfitMembershipRequestAction {
}
)
val Unk2Codec: Codec[Unk2] =
(
uint16L ::
uint16L ::
PacketHelpers.encodedWideStringAligned(5)
).xmap[Unk2](
{
case unk2 :: unk3 :: member_name :: HNil =>
Unk2(unk2, unk3, member_name)
},
{
case Unk2(unk2, unk3, member_name) =>
unk2 :: unk3 :: member_name :: HNil
}
)
val AcceptOutfitCodec: Codec[AcceptOutfitInvite] =
PacketHelpers.encodedWideString.xmap[AcceptOutfitInvite](
{
@ -92,7 +141,11 @@ object OutfitMembershipRequestAction {
)
val CancelOutfitCodec: Codec[CancelOutfitInvite] =
(uint16L :: uint16L :: PacketHelpers.encodedWideStringAligned(5)).xmap[CancelOutfitInvite](
(
uint16L ::
uint16L ::
PacketHelpers.encodedWideStringAligned(5)
).xmap[CancelOutfitInvite](
{
case unk5 :: unk6 :: outfit_name :: HNil =>
CancelOutfitInvite(unk5, unk6, outfit_name)
@ -155,7 +208,7 @@ object OutfitMembershipRequest extends Marshallable[OutfitMembershipRequest] {
((code: @switch) match {
case 0 => CreateOutfitCodec
case 1 => FormOutfitCodec // so far same as Create
case 2 => unknownCodec(action = code)
case 2 => Unk2Codec
case 3 => AcceptOutfitCodec
case 4 => RejectOutfitCodec // so far same as Accept
case 5 => CancelOutfitCodec

View file

@ -31,7 +31,7 @@ val unk0_ABC_Lazer: ByteVector = hex"90 048640001030c28022404c0061007a00650
"decode Unk0 ABC" in {
PacketCoding.decodePacket(unk0_ABC_Lazer).require match {
case OutfitMemberEvent(unk00, outfit_guid, unk3, unk4, unk5, unk6, member_name, unk7, unk8, unk9, unk10, unk11) =>
case OutfitMemberEvent(unk00, outfit_guid, unk3, unk4, unk5, unk6, member_name, unk8, unk9, unk10, unk11, unk12, unk13,unk14,unk15,unk16) =>
unk00 mustEqual 0
outfit_guid mustEqual 6418L
unk3 mustEqual 64
@ -39,11 +39,15 @@ val unk0_ABC_Lazer: ByteVector = hex"90 048640001030c28022404c0061007a00650
unk5 mustEqual 10
unk6 mustEqual 0
member_name mustEqual "Lazer1982"
unk7 mustEqual 15092
unk8 mustEqual 57413
unk9 mustEqual 19467
unk10 mustEqual 16480
unk11 mustEqual 16
unk8 mustEqual 244
unk9 mustEqual 58
unk10 mustEqual 69
unk11 mustEqual 224
unk12 mustEqual 11
unk13 mustEqual 76
unk14 mustEqual 96
unk15 mustEqual 64
unk16 mustEqual 16
case _ =>
ko
}
@ -58,11 +62,15 @@ val unk0_ABC_Lazer: ByteVector = hex"90 048640001030c28022404c0061007a00650
unk5 = 10,
unk6 = 0,
member_name = "Lazer1982",
unk7 = 15092,
unk8 = 57413,
unk9 = 19467,
unk10 = 16480,
unk11 = 16,
unk8 = 244,
unk9 = 58,
unk10 = 69,
unk11 = 224,
unk12 = 11,
unk13 = 76,
unk14 = 96,
unk15 = 64,
unk16 = 16,
)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector

View file

@ -13,7 +13,8 @@ class OutfitMembershipRequestTest extends Specification {
val create_2222 = hex"8c 0 1000 000 1000 84 3200320032003200"
val form_abc = hex"8c 2 0200 000 1000 83 610062006300"
val form_1 = hex"8c 2 1000 000 1000 81 3100"
val unk3 = hex"8c 5 bb39 9e0 2000 0000 1080 750072006f006200" // -- "urob" -- could be false positive -- seems to gets an OMSResp -> 0x8d271bb399e025af8f405080550072006f0062008080
val unk2 = hex"8c 5 bb399e0 2000 0000 1140 7600690072007500730067006900760065007200" // -- virusgiver
val unk3 = hex"8c 5 bb399e0 2000 0000 1080 750072006f006200" // -- "urob" -- could be false positive -- seems to gets an OMSResp -> 0x8d271bb399e025af8f405080550072006f0062008080
val accept_1 = hex"8c 6 0200 000 1000"
val accept_2 = hex"8c 6 0400 000 1000"
val reject_1 = hex"8c 8 0200 000 1000"
@ -94,6 +95,24 @@ class OutfitMembershipRequestTest extends Specification {
pkt mustEqual form_1
}
"decode Unk2" in {
PacketCoding.decodePacket(unk2).require match {
case OutfitMembershipRequest(request_type, outfit_id, action) =>
request_type mustEqual RequestType.Unk2
outfit_id mustEqual 30383325L
action mustEqual Unk2(0, 0, "virusgiver")
case _ =>
ko
}
}
"encode Unk2" in {
val msg = OutfitMembershipRequest(RequestType.Unk2, 30383325L, Unk2(0, 0, "virusgiver"))
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
pkt mustEqual unk2
}
"decode AcceptOutfitInvite 1" in {
PacketCoding.decodePacket(accept_1).require match {
case OutfitMembershipRequest(request_type, avatar_id, action) =>