mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
OutfitMembershipRequest all packets known!
OutfitMembershipResponse decoded, needs rework OutfitMemberEvent decoded, needs rework Tests reworked
This commit is contained in:
parent
b070834a8a
commit
17682c08d6
|
|
@ -3,7 +3,6 @@ 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 net.psforever.types.PlanetSideGUID
|
|
||||||
import scodec.{Attempt, Codec, Err}
|
import scodec.{Attempt, Codec, Err}
|
||||||
import scodec.bits.BitVector
|
import scodec.bits.BitVector
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
|
|
|
||||||
|
|
@ -3,42 +3,52 @@ package net.psforever.packet.game
|
||||||
|
|
||||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
import scodec.Codec
|
import scodec.Codec
|
||||||
|
import scodec.bits.ByteVector
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
import shapeless.{::, HNil}
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
|
/*
|
||||||
|
action is unimplemented! if action == 0 only outfit_id and member_id are sent
|
||||||
|
action2 is unimplemented! if action2 == 0 unk2 will contain one additional uint32L
|
||||||
|
unk2 contains one byte of padding. may contain 4byte of unknown data depending on action2
|
||||||
|
*/
|
||||||
final case class OutfitMemberEvent(
|
final case class OutfitMemberEvent(
|
||||||
unk00: Int,
|
action: Int, // action is unimplemented
|
||||||
outfit_id: Long,
|
outfit_id: Long,
|
||||||
member_id: Long,
|
member_id: Long,
|
||||||
member_name: String,
|
member_name: String,
|
||||||
rank: Int, // 0-7
|
rank: Int, // 0-7
|
||||||
points: Long, // client divides this by 100
|
points: Long, // client divides this by 100
|
||||||
last_login: Long, // seconds ago from current time, 0 if online
|
last_login: Long, // seconds ago from current time, 0 if online
|
||||||
unk1: Int,
|
action2: Int, // this should always be 1, otherwise there will be actual data in unk2!
|
||||||
) extends PlanetSideGamePacket {
|
padding: ByteVector, // only contains information if unk1 is 0, 1 byte of padding otherwise
|
||||||
|
) extends PlanetSideGamePacket {
|
||||||
type Packet = OutfitMemberEvent
|
type Packet = OutfitMemberEvent
|
||||||
|
|
||||||
def opcode = GamePacketOpcode.OutfitMemberEvent
|
def opcode = GamePacketOpcode.OutfitMemberEvent
|
||||||
|
|
||||||
def encode = OutfitMemberEvent.encode(this)
|
def encode = OutfitMemberEvent.encode(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
object OutfitMemberEvent extends Marshallable[OutfitMemberEvent] {
|
object OutfitMemberEvent extends Marshallable[OutfitMemberEvent] {
|
||||||
implicit val codec: Codec[OutfitMemberEvent] = (
|
implicit val codec: Codec[OutfitMemberEvent] = (
|
||||||
("unk00" | uintL(2)) ::
|
("action" | uintL(2)) ::
|
||||||
("outfit_id" | uint32L) ::
|
("outfit_id" | uint32L) ::
|
||||||
("member_id" | uint32L) ::
|
("member_id" | uint32L) ::
|
||||||
("member_name" | PacketHelpers.encodedWideStringAligned(6)) ::
|
("member_name" | PacketHelpers.encodedWideStringAligned(6)) ::
|
||||||
("rank" | uint(3)) ::
|
("rank" | uint(3)) ::
|
||||||
("points" | uint32L) ::
|
("points" | uint32L) ::
|
||||||
("last_login" | uint32L) ::
|
("last_login" | uint32L) ::
|
||||||
("unk1" | uint(5))
|
("action2" | uintL(1)) ::
|
||||||
|
("padding" | bytes)
|
||||||
).xmap[OutfitMemberEvent](
|
).xmap[OutfitMemberEvent](
|
||||||
{
|
{
|
||||||
case unk00 :: outfit_id :: member_id :: member_name :: rank :: points :: last_login :: u1 :: HNil =>
|
case unk00 :: outfit_id :: member_id :: member_name :: rank :: points :: last_login :: u1 :: padding :: HNil =>
|
||||||
OutfitMemberEvent(unk00, outfit_id, member_id, member_name, rank, points, last_login, u1)
|
OutfitMemberEvent(unk00, outfit_id, member_id, member_name, rank, points, last_login, u1, padding)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case OutfitMemberEvent(unk00, outfit_id, member_id, member_name, rank, points, last_login, u1) =>
|
case OutfitMemberEvent(unk00, outfit_id, member_id, member_name, rank, points, last_login, action2, padding) =>
|
||||||
unk00 :: outfit_id :: member_id :: member_name :: rank :: points :: last_login :: u1 :: HNil
|
unk00 :: outfit_id :: member_id :: member_name :: rank :: points :: last_login :: action2 :: padding :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
package net.psforever.packet.game
|
package net.psforever.packet.game
|
||||||
|
|
||||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||||
import net.psforever.types.PlanetSideGUID
|
|
||||||
import scodec.Codec
|
import scodec.Codec
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
import shapeless.{::, HNil}
|
import shapeless.{::, HNil}
|
||||||
|
|
|
||||||
|
|
@ -22,41 +22,50 @@ final case class OutfitMembershipRequest(
|
||||||
|
|
||||||
abstract class OutfitMembershipRequestAction(val code: Int)
|
abstract class OutfitMembershipRequestAction(val code: Int)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Codecs 2,5,6,7 can either work off of the avatar_id (if GUI was used) or member_name (if chat command was used)
|
||||||
|
*/
|
||||||
object OutfitMembershipRequestAction {
|
object OutfitMembershipRequestAction {
|
||||||
|
|
||||||
final case class CreateOutfit(
|
final case class Create(
|
||||||
unk2: String,
|
unk1: String,
|
||||||
unk3: Int,
|
|
||||||
unk4: Boolean,
|
|
||||||
outfit_name: String
|
outfit_name: String
|
||||||
) extends OutfitMembershipRequestAction(code = 0)
|
) extends OutfitMembershipRequestAction(code = 0)
|
||||||
|
|
||||||
final case class FormOutfit(
|
final case class Form(
|
||||||
unk2: String,
|
unk1: String,
|
||||||
unk3: Int,
|
|
||||||
unk4: Boolean,
|
|
||||||
outfit_name: String
|
outfit_name: String
|
||||||
) extends OutfitMembershipRequestAction(code = 1)
|
) extends OutfitMembershipRequestAction(code = 1)
|
||||||
|
|
||||||
final case class Unk2(
|
final case class Invite(
|
||||||
unk2: Int,
|
avatar_id: Long,
|
||||||
unk3: Int,
|
|
||||||
member_name: String,
|
member_name: String,
|
||||||
) extends OutfitMembershipRequestAction(code = 2)
|
) extends OutfitMembershipRequestAction(code = 2)
|
||||||
final case class AcceptOutfitInvite(
|
|
||||||
unk2: String
|
final case class AcceptInvite(
|
||||||
|
member_name: String
|
||||||
) extends OutfitMembershipRequestAction(code = 3)
|
) extends OutfitMembershipRequestAction(code = 3)
|
||||||
|
|
||||||
final case class RejectOutfitInvite(
|
final case class RejectInvite(
|
||||||
unk2: String
|
member_name: String
|
||||||
) extends OutfitMembershipRequestAction(code = 4)
|
) extends OutfitMembershipRequestAction(code = 4)
|
||||||
|
|
||||||
final case class CancelOutfitInvite(
|
final case class CancelInvite(
|
||||||
unk5: Int,
|
avatar_id: Long,
|
||||||
unk6: Int,
|
member_name: String,
|
||||||
outfit_name: String
|
|
||||||
) extends OutfitMembershipRequestAction(code = 5)
|
) extends OutfitMembershipRequestAction(code = 5)
|
||||||
|
|
||||||
|
final case class Kick(
|
||||||
|
avatar_id: Long,
|
||||||
|
member_name: String,
|
||||||
|
) extends OutfitMembershipRequestAction(code = 6)
|
||||||
|
|
||||||
|
final case class SetRank(
|
||||||
|
avatar_id: Long, // 32
|
||||||
|
rank: Int, // 3
|
||||||
|
member_name: String,
|
||||||
|
) extends OutfitMembershipRequestAction(code = 7)
|
||||||
|
|
||||||
final case class Unknown(badCode: Int, data: BitVector) extends OutfitMembershipRequestAction(badCode)
|
final case class Unknown(badCode: Int, data: BitVector) extends OutfitMembershipRequestAction(badCode)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -66,96 +75,122 @@ object OutfitMembershipRequestAction {
|
||||||
object Codecs {
|
object Codecs {
|
||||||
private val everFailCondition = conditional(included = false, bool)
|
private val everFailCondition = conditional(included = false, bool)
|
||||||
|
|
||||||
val CreateOutfitCodec: Codec[CreateOutfit] =
|
val CreateCodec: Codec[Create] =
|
||||||
(
|
(
|
||||||
PacketHelpers.encodedWideString ::
|
PacketHelpers.encodedWideStringAligned(5) ::
|
||||||
uint4L ::
|
|
||||||
bool ::
|
|
||||||
PacketHelpers.encodedWideString
|
PacketHelpers.encodedWideString
|
||||||
).xmap[CreateOutfit](
|
).xmap[Create](
|
||||||
{
|
{
|
||||||
case unk2 :: unk3 :: unk4 :: outfit_name :: HNil =>
|
case u1 :: outfit_name :: HNil =>
|
||||||
CreateOutfit(unk2, unk3, unk4, outfit_name)
|
Create(u1, outfit_name)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case CreateOutfit(unk2, unk3, unk4, outfit_name) =>
|
case Create(u1, outfit_name) =>
|
||||||
unk2 :: unk3 :: unk4 :: outfit_name :: HNil
|
u1 :: outfit_name :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val FormOutfitCodec: Codec[FormOutfit] =
|
val FormCodec: Codec[Form] =
|
||||||
(
|
(
|
||||||
PacketHelpers.encodedWideString ::
|
PacketHelpers.encodedWideStringAligned(5) ::
|
||||||
uint4L ::
|
|
||||||
bool ::
|
|
||||||
PacketHelpers.encodedWideString
|
PacketHelpers.encodedWideString
|
||||||
).xmap[FormOutfit](
|
).xmap[Form](
|
||||||
{
|
{
|
||||||
case unk2 :: unk3 :: unk4 :: outfit_name :: HNil =>
|
case u1 :: outfit_name :: HNil =>
|
||||||
FormOutfit(unk2, unk3, unk4, outfit_name)
|
Form(u1, outfit_name)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case FormOutfit(unk2, unk3, unk4, outfit_name) =>
|
case Form(u1, outfit_name) =>
|
||||||
unk2 :: unk3 :: unk4 :: outfit_name :: HNil
|
u1 :: outfit_name :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val Unk2Codec: Codec[Unk2] =
|
val InviteCodec: Codec[Invite] =
|
||||||
(
|
(
|
||||||
uint16L ::
|
uint32L ::
|
||||||
uint16L ::
|
|
||||||
PacketHelpers.encodedWideStringAligned(5)
|
PacketHelpers.encodedWideStringAligned(5)
|
||||||
).xmap[Unk2](
|
).xmap[Invite](
|
||||||
{
|
{
|
||||||
case unk2 :: unk3 :: member_name :: HNil =>
|
case u1 :: member_name :: HNil =>
|
||||||
Unk2(unk2, unk3, member_name)
|
Invite(u1, member_name)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case Unk2(unk2, unk3, member_name) =>
|
case Invite(u1, member_name) =>
|
||||||
unk2 :: unk3 :: member_name :: HNil
|
u1 :: member_name :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val AcceptOutfitCodec: Codec[AcceptOutfitInvite] =
|
val AcceptInviteCodec: Codec[AcceptInvite] =
|
||||||
PacketHelpers.encodedWideString.xmap[AcceptOutfitInvite](
|
PacketHelpers.encodedWideString.xmap[AcceptInvite](
|
||||||
{
|
{
|
||||||
case unk2 =>
|
case u1 =>
|
||||||
AcceptOutfitInvite(unk2)
|
AcceptInvite(u1)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case AcceptOutfitInvite(unk2) =>
|
case AcceptInvite(u1) =>
|
||||||
unk2
|
u1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val RejectOutfitCodec: Codec[RejectOutfitInvite] =
|
val RejectInviteCodec: Codec[RejectInvite] =
|
||||||
PacketHelpers.encodedWideString.xmap[RejectOutfitInvite](
|
PacketHelpers.encodedWideString.xmap[RejectInvite](
|
||||||
{
|
{
|
||||||
case unk2 =>
|
case u1 =>
|
||||||
RejectOutfitInvite(unk2)
|
RejectInvite(u1)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case RejectOutfitInvite(unk2) =>
|
case RejectInvite(u1) =>
|
||||||
unk2
|
u1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val CancelOutfitCodec: Codec[CancelOutfitInvite] =
|
val CancelInviteCodec: Codec[CancelInvite] =
|
||||||
(
|
(
|
||||||
uint16L ::
|
uint32L ::
|
||||||
uint16L ::
|
|
||||||
PacketHelpers.encodedWideStringAligned(5)
|
PacketHelpers.encodedWideStringAligned(5)
|
||||||
).xmap[CancelOutfitInvite](
|
).xmap[CancelInvite](
|
||||||
{
|
{
|
||||||
case unk5 :: unk6 :: outfit_name :: HNil =>
|
case u1 :: outfit_name :: HNil =>
|
||||||
CancelOutfitInvite(unk5, unk6, outfit_name)
|
CancelInvite(u1, outfit_name)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case CancelOutfitInvite(unk5, unk6, outfit_name) =>
|
case CancelInvite(u1, outfit_name) =>
|
||||||
unk5 :: unk6 :: outfit_name :: HNil
|
u1 :: outfit_name :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val KickCodec: Codec[Kick] =
|
||||||
|
(
|
||||||
|
uint32L ::
|
||||||
|
PacketHelpers.encodedWideStringAligned(5)
|
||||||
|
).xmap[Kick](
|
||||||
|
{
|
||||||
|
case u1 :: member_name :: HNil =>
|
||||||
|
Kick(u1, member_name)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case Kick(u1, member_name) =>
|
||||||
|
u1 :: member_name :: HNil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val SetRankCodec: Codec[SetRank] =
|
||||||
|
(
|
||||||
|
uint32L ::
|
||||||
|
uintL(3) ::
|
||||||
|
PacketHelpers.encodedWideStringAligned(2)
|
||||||
|
).xmap[SetRank](
|
||||||
|
{
|
||||||
|
case u1 :: rank :: member_name :: HNil =>
|
||||||
|
SetRank(u1, rank, member_name)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case SetRank(u1, rank, member_name) =>
|
||||||
|
u1 :: rank :: member_name :: HNil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A common form for known action code indexes with an unknown purpose and transformation is an "Unknown" object.
|
* A common form for known action code indexes with an unknown purpose and transformation is an "Unknown" object.
|
||||||
*
|
*
|
||||||
|
|
@ -191,12 +226,12 @@ object OutfitMembershipRequest extends Marshallable[OutfitMembershipRequest] {
|
||||||
|
|
||||||
val Create: RequestType.Value = Value(0)
|
val Create: RequestType.Value = Value(0)
|
||||||
val Form: RequestType.Value = Value(1)
|
val Form: RequestType.Value = Value(1)
|
||||||
val Unk2: RequestType.Value = Value(2)
|
val Invite: RequestType.Value = Value(2)
|
||||||
val Accept: RequestType.Value = Value(3)
|
val Accept: RequestType.Value = Value(3)
|
||||||
val Reject: RequestType.Value = Value(4)
|
val Reject: RequestType.Value = Value(4)
|
||||||
val Cancel: RequestType.Value = Value(5)
|
val Cancel: RequestType.Value = Value(5)
|
||||||
val Unk6: RequestType.Value = Value(6) // 6 and 7 seen as failed decodes, validity unknown
|
val Kick: RequestType.Value = Value(6)
|
||||||
val Unk7: RequestType.Value = Value(7)
|
val SetRank: RequestType.Value = Value(7)
|
||||||
|
|
||||||
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
implicit val codec: Codec[Type] = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
||||||
}
|
}
|
||||||
|
|
@ -206,15 +241,15 @@ object OutfitMembershipRequest extends Marshallable[OutfitMembershipRequest] {
|
||||||
import scala.annotation.switch
|
import scala.annotation.switch
|
||||||
|
|
||||||
((code: @switch) match {
|
((code: @switch) match {
|
||||||
case 0 => CreateOutfitCodec
|
case 0 => CreateCodec
|
||||||
case 1 => FormOutfitCodec // so far same as Create
|
case 1 => FormCodec // so far same as Create
|
||||||
case 2 => Unk2Codec
|
case 2 => InviteCodec
|
||||||
case 3 => AcceptOutfitCodec
|
case 3 => AcceptInviteCodec
|
||||||
case 4 => RejectOutfitCodec // so far same as Accept
|
case 4 => RejectInviteCodec
|
||||||
case 5 => CancelOutfitCodec
|
case 5 => CancelInviteCodec
|
||||||
case 6 => unknownCodec(action = code)
|
case 6 => KickCodec
|
||||||
case 7 => unknownCodec(action = code)
|
case 7 => SetRankCodec
|
||||||
// 3 bit limit
|
|
||||||
case _ => failureCodec(code)
|
case _ => failureCodec(code)
|
||||||
}).asInstanceOf[Codec[OutfitMembershipRequestAction]]
|
}).asInstanceOf[Codec[OutfitMembershipRequestAction]]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ 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 net.psforever.types.PlanetSideGUID
|
|
||||||
import scodec.{Attempt, Codec, Err}
|
import scodec.{Attempt, Codec, Err}
|
||||||
import scodec.bits.BitVector
|
import scodec.bits.BitVector
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
|
|
@ -12,10 +11,9 @@ import shapeless.{::, HNil}
|
||||||
final case class OutfitMembershipResponse(
|
final case class OutfitMembershipResponse(
|
||||||
response_type: OutfitMembershipResponse.ResponseType.Type,
|
response_type: OutfitMembershipResponse.ResponseType.Type,
|
||||||
unk0: Int,
|
unk0: Int,
|
||||||
|
unk1: Int,
|
||||||
outfit_id: Long,
|
outfit_id: Long,
|
||||||
target_guid: PlanetSideGUID,
|
target_id: Long,
|
||||||
unk3: Int,
|
|
||||||
//unk4: Boolean,
|
|
||||||
action: OutfitMembershipResponseAction
|
action: OutfitMembershipResponseAction
|
||||||
) extends PlanetSideGamePacket {
|
) extends PlanetSideGamePacket {
|
||||||
type Packet = OutfitMembershipResponse
|
type Packet = OutfitMembershipResponse
|
||||||
|
|
@ -28,21 +26,39 @@ final case class OutfitMembershipResponse(
|
||||||
abstract class OutfitMembershipResponseAction(val code: Int)
|
abstract class OutfitMembershipResponseAction(val code: Int)
|
||||||
object OutfitMembershipResponseAction {
|
object OutfitMembershipResponseAction {
|
||||||
|
|
||||||
final case class CreateOutfitResponse(str1: String, str2: String, str3: String) extends OutfitMembershipResponseAction(code = 0)
|
final case class Universal(
|
||||||
|
str1: String,
|
||||||
|
str2: String,
|
||||||
|
flag: Boolean
|
||||||
|
) extends OutfitMembershipResponseAction(-1)
|
||||||
|
|
||||||
final case class Unk1OutfitResponse(player_name: String, outfit_name: String, unk7: Int) extends OutfitMembershipResponseAction(code = 1)
|
final case class CreateResponse(
|
||||||
|
str1: String,
|
||||||
|
str2: String,
|
||||||
|
str3: String
|
||||||
|
) extends OutfitMembershipResponseAction(code = 0)
|
||||||
|
|
||||||
final case class Unk2OutfitResponse(player_name: String, outfit_name: String, unk7: Int) extends OutfitMembershipResponseAction(code = 2) // unk7 = rank?
|
final case class Unk1OutfitResponse(
|
||||||
|
player_name: String,
|
||||||
|
outfit_name: String,
|
||||||
|
unk7: Int
|
||||||
|
) extends OutfitMembershipResponseAction(code = 1)
|
||||||
|
|
||||||
final case class Unk3OutfitResponse(unk2: String) extends OutfitMembershipResponseAction(code = 3)
|
final case class Unk2OutfitResponse(
|
||||||
|
player_name: String,
|
||||||
|
outfit_name: String,
|
||||||
|
unk7: Int
|
||||||
|
) extends OutfitMembershipResponseAction(code = 2) // unk7 = rank?
|
||||||
|
|
||||||
final case class Unk4OutfitResponse(unk5: Int, unk6: Int, outfit_name: String) extends OutfitMembershipResponseAction(code = 4)
|
final case class Unk3OutfitResponse(
|
||||||
|
unk2: String
|
||||||
|
) extends OutfitMembershipResponseAction(code = 3)
|
||||||
|
|
||||||
final case class Unk5OutfitResponse() extends OutfitMembershipResponseAction(code = 5)
|
final case class Unk4OutfitResponse(
|
||||||
|
unk5: Int,
|
||||||
final case class Unk6OutfitResponse() extends OutfitMembershipResponseAction(code = 6)
|
unk6: Int,
|
||||||
|
outfit_name: String
|
||||||
final case class Unk7OutfitResponse() extends OutfitMembershipResponseAction(code = 7)
|
) extends OutfitMembershipResponseAction(code = 4)
|
||||||
|
|
||||||
final case class Unknown(badCode: Int, data: BitVector) extends OutfitMembershipResponseAction(badCode)
|
final case class Unknown(badCode: Int, data: BitVector) extends OutfitMembershipResponseAction(badCode)
|
||||||
|
|
||||||
|
|
@ -53,17 +69,32 @@ object OutfitMembershipResponseAction {
|
||||||
object Codecs {
|
object Codecs {
|
||||||
private val everFailCondition = conditional(included = false, bool)
|
private val everFailCondition = conditional(included = false, bool)
|
||||||
|
|
||||||
val Unk0OutfitCodec: Codec[CreateOutfitResponse] = (
|
val UniversalResponseCodec: Codec[OutfitMembershipResponseAction] = (
|
||||||
|
PacketHelpers.encodedWideStringAligned(5) ::
|
||||||
|
PacketHelpers.encodedWideString ::
|
||||||
|
("flag" | bool)
|
||||||
|
).xmap[OutfitMembershipResponseAction](
|
||||||
|
{
|
||||||
|
case str1 :: str2 :: flag :: HNil =>
|
||||||
|
Universal(str1, str2, flag)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case Universal(str1, str2, flag) =>
|
||||||
|
str1 :: str2 :: flag :: HNil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val CreateOutfitCodec: Codec[CreateResponse] = (
|
||||||
PacketHelpers.encodedWideStringAligned(5) ::
|
PacketHelpers.encodedWideStringAligned(5) ::
|
||||||
PacketHelpers.encodedWideString ::
|
PacketHelpers.encodedWideString ::
|
||||||
PacketHelpers.encodedWideString
|
PacketHelpers.encodedWideString
|
||||||
).xmap[CreateOutfitResponse](
|
).xmap[CreateResponse](
|
||||||
{
|
{
|
||||||
case str1 :: str2 :: str3 :: HNil =>
|
case str1 :: str2 :: str3 :: HNil =>
|
||||||
CreateOutfitResponse(str1, str2, str3)
|
CreateResponse(str1, str2, str3)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case CreateOutfitResponse(str1, str2, str3) =>
|
case CreateResponse(str1, str2, str3) =>
|
||||||
str1 :: str2 :: str3 :: HNil
|
str1 :: str2 :: str3 :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -99,7 +130,7 @@ object OutfitMembershipResponseAction {
|
||||||
)
|
)
|
||||||
|
|
||||||
val Unk3OutfitCodec: Codec[Unk3OutfitResponse] =
|
val Unk3OutfitCodec: Codec[Unk3OutfitResponse] =
|
||||||
PacketHelpers.encodedWideString.xmap[Unk3OutfitResponse](
|
PacketHelpers.encodedWideStringAligned(5).xmap[Unk3OutfitResponse](
|
||||||
{
|
{
|
||||||
case unk2 =>
|
case unk2 =>
|
||||||
Unk3OutfitResponse(unk2)
|
Unk3OutfitResponse(unk2)
|
||||||
|
|
@ -110,8 +141,11 @@ object OutfitMembershipResponseAction {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val Unk4OutfitCodec: Codec[Unk4OutfitResponse] =
|
val Unk4OutfitCodec: Codec[Unk4OutfitResponse] = (
|
||||||
(uint16L :: uint16L :: PacketHelpers.encodedWideStringAligned(5)).xmap[Unk4OutfitResponse](
|
uint16L ::
|
||||||
|
uint16L ::
|
||||||
|
PacketHelpers.encodedWideStringAligned(5)
|
||||||
|
).xmap[Unk4OutfitResponse](
|
||||||
{
|
{
|
||||||
case unk5 :: unk6 :: outfit_name :: HNil =>
|
case unk5 :: unk6 :: outfit_name :: HNil =>
|
||||||
Unk4OutfitResponse(unk5, unk6, outfit_name)
|
Unk4OutfitResponse(unk5, unk6, outfit_name)
|
||||||
|
|
@ -122,42 +156,6 @@ object OutfitMembershipResponseAction {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// val Unk5OutfitCodec: Codec[Unk5OutfitResponse] =
|
|
||||||
// (uint16L :: uint16L :: PacketHelpers.encodedWideStringAligned(5)).xmap[Unk5OutfitResponse](
|
|
||||||
// {
|
|
||||||
// case unk5 :: unk6 :: outfit_name :: HNil =>
|
|
||||||
// Unk5OutfitResponse(unk5, unk6, outfit_name)
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// case Unk5OutfitResponse(unk5, unk6, outfit_name) =>
|
|
||||||
// unk5 :: unk6 :: outfit_name :: HNil
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val Unk6OutfitCodec: Codec[Unk6OutfitResponse] =
|
|
||||||
// (uint16L :: uint16L :: PacketHelpers.encodedWideStringAligned(5)).xmap[Unk6OutfitResponse](
|
|
||||||
// {
|
|
||||||
// case _ =>
|
|
||||||
// Unk6OutfitResponse()
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// case Unk6OutfitResponse() =>
|
|
||||||
// _
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val Unk7OutfitCodec: Codec[Unk7OutfitResponse] =
|
|
||||||
// (uint16L :: uint16L :: PacketHelpers.encodedWideStringAligned(5)).xmap[Unk7OutfitResponse](
|
|
||||||
// {
|
|
||||||
// case _ =>
|
|
||||||
// Unk7OutfitResponse()
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// case Unk7OutfitResponse() =>
|
|
||||||
// _
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A common form for known action code indexes with an unknown purpose and transformation is an "Unknown" object.
|
* A common form for known action code indexes with an unknown purpose and transformation is an "Unknown" object.
|
||||||
* @param action the action behavior code
|
* @param action the action behavior code
|
||||||
|
|
@ -206,14 +204,24 @@ object OutfitMembershipResponse extends Marshallable[OutfitMembershipResponse] {
|
||||||
import scala.annotation.switch
|
import scala.annotation.switch
|
||||||
|
|
||||||
((code: @switch) match {
|
((code: @switch) match {
|
||||||
case 0 => Unk0OutfitCodec // seem as OMReq Create response
|
case 0 => UniversalResponseCodec
|
||||||
case 1 => Unk1OutfitCodec
|
case 1 => UniversalResponseCodec
|
||||||
case 2 => Unk2OutfitCodec
|
case 2 => UniversalResponseCodec
|
||||||
case 3 => Unk3OutfitCodec
|
case 3 => UniversalResponseCodec
|
||||||
case 4 => Unk4OutfitCodec
|
case 4 => UniversalResponseCodec
|
||||||
case 5 => unknownCodec(action = code)
|
case 5 => UniversalResponseCodec
|
||||||
case 6 => unknownCodec(action = code)
|
case 6 => UniversalResponseCodec
|
||||||
case 7 => unknownCodec(action = code)
|
case 7 => UniversalResponseCodec
|
||||||
|
|
||||||
|
// case 0 => CreateOutfitCodec // seem as OMReq Create response
|
||||||
|
// case 1 => Unk1OutfitCodec
|
||||||
|
// case 2 => Unk2OutfitCodec
|
||||||
|
// case 3 => Unk3OutfitCodec
|
||||||
|
// case 4 => Unk4OutfitCodec
|
||||||
|
// case 5 => unknownCodec(action = code)
|
||||||
|
// case 6 => unknownCodec(action = code)
|
||||||
|
// case 7 => unknownCodec(action = code)
|
||||||
|
|
||||||
// 3 bit limit
|
// 3 bit limit
|
||||||
case _ => failureCodec(code)
|
case _ => failureCodec(code)
|
||||||
}).asInstanceOf[Codec[OutfitMembershipResponseAction]]
|
}).asInstanceOf[Codec[OutfitMembershipResponseAction]]
|
||||||
|
|
@ -221,21 +229,20 @@ object OutfitMembershipResponse extends Marshallable[OutfitMembershipResponse] {
|
||||||
|
|
||||||
implicit val codec: Codec[OutfitMembershipResponse] = (
|
implicit val codec: Codec[OutfitMembershipResponse] = (
|
||||||
("response_type" | ResponseType.codec) >>:~ { response_type =>
|
("response_type" | ResponseType.codec) >>:~ { response_type =>
|
||||||
("unk0" | uint8L) ::
|
("unk0" | uintL(5)) ::
|
||||||
|
("unk1" | uintL(3)) ::
|
||||||
("outfit_id" | uint32L) ::
|
("outfit_id" | uint32L) ::
|
||||||
("target_guid" | PlanetSideGUID.codec) ::
|
("target_id" | uint32L) ::
|
||||||
("unk3" | uint16L) ::
|
("action" | selectFromType(response_type.id))
|
||||||
//("unk4" | bool) ::
|
|
||||||
("action" | selectFromType(response_type.id))
|
|
||||||
}
|
}
|
||||||
).xmap[OutfitMembershipResponse](
|
).xmap[OutfitMembershipResponse](
|
||||||
{
|
{
|
||||||
case response_type :: u0 :: outfit_id :: target_guid :: u3 :: action :: HNil =>
|
case response_type :: u0 :: u1 :: outfit_id :: target_id :: action :: HNil =>
|
||||||
OutfitMembershipResponse(response_type, u0, outfit_id, target_guid, u3, action)
|
OutfitMembershipResponse(response_type, u0, u1, outfit_id, target_id, action)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case OutfitMembershipResponse(response_type, u0, outfit_id, u2, u3, action) =>
|
case OutfitMembershipResponse(response_type, u0, u1, outfit_id, target_id, action) =>
|
||||||
response_type :: u0 :: outfit_id :: u2 :: u3 :: action :: HNil
|
response_type :: u0 :: u1 :: outfit_id :: target_id :: action :: HNil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import net.psforever.packet._
|
||||||
import net.psforever.packet.game.OutfitEvent.RequestType
|
import net.psforever.packet.game.OutfitEvent.RequestType
|
||||||
import net.psforever.packet.game.OutfitEventAction._
|
import net.psforever.packet.game.OutfitEventAction._
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
import net.psforever.types.PlanetSideGUID
|
|
||||||
import org.specs2.mutable._
|
import org.specs2.mutable._
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
|
|
||||||
|
|
@ -64,7 +63,9 @@ class OutfitEventTest extends Specification {
|
||||||
unk9 = 0,
|
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.",
|
||||||
PlanetSideGUID(32783),
|
15,
|
||||||
|
128,
|
||||||
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
@ -93,7 +94,9 @@ class OutfitEventTest extends Specification {
|
||||||
unk9 = 0,
|
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.",
|
||||||
PlanetSideGUID(32783),
|
15,
|
||||||
|
128,
|
||||||
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
@ -151,8 +154,10 @@ class OutfitEventTest extends Specification {
|
||||||
unk9 = 0,
|
unk9 = 0,
|
||||||
OutfitRankNames("","","","","","","",""),
|
OutfitRankNames("","","","","","","",""),
|
||||||
"",
|
"",
|
||||||
PlanetSideGUID(28672),
|
0,
|
||||||
33353,
|
112,
|
||||||
|
73,
|
||||||
|
130,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
@ -179,15 +184,17 @@ class OutfitEventTest extends Specification {
|
||||||
unk9 = 0,
|
unk9 = 0,
|
||||||
OutfitRankNames("","","","","","","",""),
|
OutfitRankNames("","","","","","","",""),
|
||||||
"",
|
"",
|
||||||
PlanetSideGUID(28672),
|
0,
|
||||||
33353,
|
112,
|
||||||
0,
|
73,
|
||||||
|
130,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,18 @@ 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 5 e83a0000 000e1800 0800000 11404e0069006700680074004c006f00720064007300 854e005900430061007400")
|
val unk2_0_ABC: ByteVector = ByteVector.fromValidHex("98 5 e83a0000 000e1800 0800000 11404e0069006700680074004c006f00720064007300 854e005900430061007400")
|
||||||
val unk0_DEF: ByteVector = ByteVector.fromValidHex("98 4 ec281001 51a62800 3400000 11a0490052004f004e004600490053005400200043006c0061006e00 8654006f006c006a00")
|
val unk2_0_DEF: ByteVector = ByteVector.fromValidHex("98 4 ec281001 51a62800 3400000 11a0490052004f004e004600490053005400200043006c0061006e00 8654006f006c006a00")
|
||||||
val unk1_ABC: ByteVector = ByteVector.fromValidHex("98 4 723c0000 2aa81e00 2200000 11006900470061006d00650073002d004500 906900670061006d006500730043005400460057006800610063006b002d004500")
|
val unk2_1_ABC: ByteVector = ByteVector.fromValidHex("98 4 723c0000 2aa81e00 2200000 11006900470061006d00650073002d004500 906900670061006d006500730043005400460057006800610063006b002d004500")
|
||||||
val unk2_ABC: ByteVector = ByteVector.fromValidHex("98 4 9a3c0001 16da4e00 0400000 11a042006c006f006f00640020006f0066002000560061006e007500 864b00610072006e002d004500")
|
val unk2_2_ABC: ByteVector = ByteVector.fromValidHex("98 4 9a3c0001 16da4e00 0400000 11a042006c006f006f00640020006f0066002000560061006e007500 864b00610072006e002d004500")
|
||||||
val unk3_ABC: ByteVector = ByteVector.fromValidHex("98 4 9c3c0000 df587c00 1400000 11a054006800650020004e00650076006500720068006f006f006400 8e6f00460058006f00530074006f006e0065004d0061006e002d004700")
|
val unk2_3_ABC: ByteVector = ByteVector.fromValidHex("98 4 9c3c0000 df587c00 1400000 11a054006800650020004e00650076006500720068006f006f006400 8e6f00460058006f00530074006f006e0065004d0061006e002d004700")
|
||||||
val unk4_ABC: ByteVector = ByteVector.fromValidHex("98 4 c03c0000 24060400 0600000 1220540068006500200042006c00610063006b0020004b006e0069006700680074007300 874400720061007a00760065006e00")
|
val unk2_4_ABC: ByteVector = ByteVector.fromValidHex("98 4 c03c0000 24060400 0600000 1220540068006500200042006c00610063006b0020004b006e0069006700680074007300 874400720061007a00760065006e00")
|
||||||
val unk5_ABC: ByteVector = ByteVector.fromValidHex("98 5 383c0001 4b709a00 0c00000 10a03e005400760053003c00 89430061007000650062006f00610074007300")
|
val unk2_5_ABC: ByteVector = ByteVector.fromValidHex("98 5 383c0001 4b709a00 0c00000 10a03e005400760053003c00 89430061007000650062006f00610074007300")
|
||||||
val unk6_ABC: ByteVector = ByteVector.fromValidHex("98 5 b03c0000 35d67000 0400000 11404c006f0073007400200043006100750073006500 895a00650072006f004b00650077006c006c00")
|
val unk2_6_ABC: ByteVector = ByteVector.fromValidHex("98 5 b03c0000 35d67000 0400000 11404c006f0073007400200043006100750073006500 895a00650072006f004b00650077006c006c00")
|
||||||
val unk7_ABC: ByteVector = ByteVector.fromValidHex("98 4 043e0001 9fb82616 1400000 11e0540068006500200042006c00610063006b00200054006f00770065007200 874b00720075007000680065007800")
|
val unk2_7_ABC: ByteVector = ByteVector.fromValidHex("98 4 043e0001 9fb82616 1400000 11e0540068006500200042006c00610063006b00200054006f00770065007200 874b00720075007000680065007800")
|
||||||
|
|
||||||
"decode unk0_ABC" in {
|
"decode unk0_ABC" in {
|
||||||
PacketCoding.decodePacket(unk0_ABC).require match {
|
PacketCoding.decodePacket(unk2_0_ABC).require match {
|
||||||
case OutfitListEvent(code, ListElementOutfit(unk1, points, members, outfit_name, outfit_leader)) =>
|
case OutfitListEvent(code, ListElementOutfit(unk1, points, members, outfit_name, outfit_leader)) =>
|
||||||
code mustEqual OutfitListEvent.RequestType.ListElementOutfit
|
code mustEqual OutfitListEvent.RequestType.ListElementOutfit
|
||||||
unk1 mustEqual 7668
|
unk1 mustEqual 7668
|
||||||
|
|
@ -37,7 +37,7 @@ class OutfitListEventTest extends Specification {
|
||||||
val msg = OutfitListEvent(RequestType.ListElementOutfit, ListElementOutfit(7668, 788224, 4, "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 unk2_0_ABC
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,42 +10,29 @@ import scodec.bits._
|
||||||
class OutfitMemberEventTest extends Specification {
|
class OutfitMemberEventTest extends Specification {
|
||||||
|
|
||||||
//val unk0_ABC: ByteVector = hex"90 3518 4000 1a4e 4100 2 180 450078007000650072007400 8483 07e0 119d bfe0 70" // 0x90048640001030c28022404c0061007a00650072003100390038003200f43a45e00b4c604010
|
//val unk0_ABC: ByteVector = hex"90 3518 4000 1a4e 4100 2 180 450078007000650072007400 8483 07e0 119d bfe0 70" // 0x90048640001030c28022404c0061007a00650072003100390038003200f43a45e00b4c604010
|
||||||
val unk0_ABC_Lazer: ByteVector = hex"90 048640001030c28022404c0061007a00650072003100390038003200f43a45e00b4c604010"
|
val unk0_ABC_Lazer = hex"90 0 4864 0001 030c 2802 24 0 4c0061007a00650072003100390038003200 f43a 45e0 0b4c 6040 10"
|
||||||
|
|
||||||
val OpolE = hex"90 0 4864 0003 aad6 280a 14 0 4f0070006f006c004500 c9a1 80e0 0d03 2040 10"
|
val OpolE = hex"90 0 4864 0003 aad6 280a 14 0 4f0070006f006c004500 c9a1 80e0 0d03 2040 10"
|
||||||
val Billy = hex"90 0 4864 0003 a41a 280a 20 0 620069006c006c007900320035003600 935f 6000 186a b040 50"
|
val Billy = hex"90 0 4864 0003 a41a 280a 20 0 620069006c006c007900320035003600 935f 6000 186a b040 50"
|
||||||
val Lazer = hex"90 0 4864 0001 030c 2802 24 0 4c0061007a00650072003100390038003200 e6dc 25a0 153e 6040 10"
|
val Lazer = hex"90 0 4864 0001 030c 2802 24 0 4c0061007a00650072003100390038003200 e6dc 25a0 153e 6040 10"
|
||||||
val Virus = hex"90 0 4864 0002 1b64 4c02 28 0 5600690072007500730047006900760065007200 2f89 0080 0000 0000 10"
|
val Virus = hex"90 0 4864 0002 1b64 4c02 28 0 5600690072007500730047006900760065007200 2f89 0080 0000 0000 10"
|
||||||
val PvtPa = hex"90 0 4864 0000 1e69 e80a 2c 0 500076007400500061006e00630061006b0065007300 705e a080 0a85 e060 10"
|
val PvtPa = hex"90 0 4864 0000 1e69 e80a 2c 0 500076007400500061006e00630061006b0065007300 705e a080 0a85 e060 10"
|
||||||
val Night = hex"90 0 4864 0002 4cf0 3802 28 0 4e006900670068007400770069006e0067003100 b8fb 9a40 0da6 ec80 50"
|
val Night = hex"90 0 4864 0002 4cf0 3802 28 0 4e006900670068007400770069006e0067003100 b8fb 9a40 0da6 ec80 50"
|
||||||
|
|
||||||
/*
|
val Unk0 = hex"90 5 40542002 3f61e808 0"
|
||||||
OutfitMemberEvent(0, ValidPlanetSideGUID(6418), 0, 0, 64, 195, 10, 0, Lazer1982, 230, 220, 37, 160, 21, 62, 96, 64, 16, BitVector(empty))
|
|
||||||
OutfitMemberEvent(0, ValidPlanetSideGUID(6418), 0, 0, 7, 154, 122, 2, PvtPancakes, 112, 94, 160, 128, 10, 133, 224, 96, 16, BitVector(empty))
|
|
||||||
OutfitMemberEvent(0, ValidPlanetSideGUID(6418), 0, 0, 134, 217, 19, 0, VirusGiver, 47, 137, 0, 128, 0, 0, 0, 0, 16, BitVector(empty))
|
|
||||||
OutfitMemberEvent(0, ValidPlanetSideGUID(6418), 0, 0, 234, 181, 138, 2, OpolE, 201, 161, 128, 224, 13, 3, 32, 64, 16, BitVector(empty))
|
|
||||||
OutfitMemberEvent(0, ValidPlanetSideGUID(6418), 0, 0, 233, 6, 138, 2, billy256, 147, 95, 96, 0, 24, 106, 176, 64, 80, BitVector(empty))
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
"decode Unk0 ABC" in {
|
"decode Unk0 ABC" in {
|
||||||
PacketCoding.decodePacket(unk0_ABC_Lazer).require match {
|
PacketCoding.decodePacket(unk0_ABC_Lazer).require match {
|
||||||
case OutfitMemberEvent(unk00, outfit_guid, unk3, unk5, member_name, unk8, unk9, unk10, unk11, unk12, unk13,unk14,unk15,unk16) =>
|
case OutfitMemberEvent(action, outfit_id, member_id, member_name, rank, points, last_login, action2, padding) =>
|
||||||
unk00 mustEqual 0
|
action mustEqual 0
|
||||||
outfit_guid mustEqual 6418L
|
outfit_id mustEqual 6418L
|
||||||
unk3 mustEqual 49984
|
member_id mustEqual 705344
|
||||||
unk5 mustEqual 10
|
|
||||||
member_name mustEqual "Lazer1982"
|
member_name mustEqual "Lazer1982"
|
||||||
unk8 mustEqual 244
|
rank mustEqual 7
|
||||||
unk9 mustEqual 58
|
points mustEqual 3134113
|
||||||
unk10 mustEqual 69
|
last_login mustEqual 156506
|
||||||
unk11 mustEqual 224
|
action2 mustEqual 1
|
||||||
unk12 mustEqual 11
|
padding mustEqual ByteVector(0x0)
|
||||||
unk13 mustEqual 76
|
|
||||||
unk14 mustEqual 96
|
|
||||||
unk15 mustEqual 64
|
|
||||||
unk16 mustEqual 16
|
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
|
|
@ -53,20 +40,15 @@ val unk0_ABC_Lazer: ByteVector = hex"90 048640001030c28022404c0061007a00650
|
||||||
|
|
||||||
"encode Unk0 ABC" in {
|
"encode Unk0 ABC" in {
|
||||||
val msg = OutfitMemberEvent(
|
val msg = OutfitMemberEvent(
|
||||||
unk00 = 0,
|
action = 0,
|
||||||
outfit_id = 6418L,
|
outfit_id = 6418L,
|
||||||
unk3 = 49984,
|
member_id = 705344,
|
||||||
unk5 = 10,
|
|
||||||
member_name = "Lazer1982",
|
member_name = "Lazer1982",
|
||||||
unk8 = 244,
|
rank = 7,
|
||||||
unk9 = 58,
|
points = 3134113,
|
||||||
unk10 = 69,
|
last_login = 156506,
|
||||||
unk11 = 224,
|
action2 = 1,
|
||||||
unk12 = 11,
|
ByteVector.empty
|
||||||
unk13 = 76,
|
|
||||||
unk14 = 96,
|
|
||||||
unk15 = 64,
|
|
||||||
unk16 = 16,
|
|
||||||
)
|
)
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
val create_2222 = hex"8c 0 1000 000 1000 84 3200320032003200"
|
val create_2222 = hex"8c 0 1000 000 1000 84 3200320032003200"
|
||||||
val form_abc = hex"8c 2 0200 000 1000 83 610062006300"
|
val form_abc = hex"8c 2 0200 000 1000 83 610062006300"
|
||||||
val form_1 = hex"8c 2 1000 000 1000 81 3100"
|
val form_1 = hex"8c 2 1000 000 1000 81 3100"
|
||||||
val unk2 = hex"8c 5 bb399e0 2000 0000 1140 7600690072007500730067006900760065007200" // -- virusgiver
|
val invite_old = 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 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_1 = hex"8c 6 0200 000 1000"
|
||||||
val accept_2 = hex"8c 6 0400 000 1000"
|
val accept_2 = hex"8c 6 0400 000 1000"
|
||||||
|
|
@ -23,19 +23,24 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
val cancel_1_abc = hex"8c a 0200 000 0000 0000 1060 610062006300"
|
val cancel_1_abc = hex"8c a 0200 000 0000 0000 1060 610062006300"
|
||||||
val cancel_3_def = hex"8c a 0600 000 0000 0000 1060 640065006600" // /outfitcancel 123 def -- first parameter is skipped
|
val cancel_3_def = hex"8c a 0600 000 0000 0000 1060 640065006600" // /outfitcancel 123 def -- first parameter is skipped
|
||||||
|
|
||||||
|
// dumped from half implemented outfit
|
||||||
|
val invite = hex"8c4020000000000000116069006e00760069007400650054006500730074003100"
|
||||||
|
val kick = hex"8cc020000017ac8f405000"
|
||||||
|
val setrank = hex"8ce020000017ac8f404600" // setting rank from 0 to 1
|
||||||
|
|
||||||
"decode CreateOutfit ABC" in {
|
"decode CreateOutfit ABC" in {
|
||||||
PacketCoding.decodePacket(create_ABC).require match {
|
PacketCoding.decodePacket(create_ABC).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Create
|
request_type mustEqual RequestType.Create
|
||||||
avatar_id mustEqual 1
|
outfit_id mustEqual 1
|
||||||
action mustEqual CreateOutfit("", 0, unk4 = false, "ABC")
|
action mustEqual Create("", "ABC")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode CreateOutfit ABC" in {
|
"encode CreateOutfit ABC" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Create, 1, CreateOutfit("", 0, unk4 = false, "ABC"))
|
val msg = OutfitMembershipRequest(RequestType.Create, 1, Create("", "ABC"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual create_ABC
|
pkt mustEqual create_ABC
|
||||||
|
|
@ -43,17 +48,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode CreateOutfit 2222" in {
|
"decode CreateOutfit 2222" in {
|
||||||
PacketCoding.decodePacket(create_2222).require match {
|
PacketCoding.decodePacket(create_2222).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Create
|
request_type mustEqual RequestType.Create
|
||||||
avatar_id mustEqual 8
|
outfit_id mustEqual 8
|
||||||
action mustEqual CreateOutfit("", 0, unk4 = false, "2222")
|
action mustEqual Create("", "2222")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode CreateOutfit 2222" in {
|
"encode CreateOutfit 2222" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Create, 8, CreateOutfit("", 0, unk4 = false, "2222"))
|
val msg = OutfitMembershipRequest(RequestType.Create, 8, Create("", "2222"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual create_2222
|
pkt mustEqual create_2222
|
||||||
|
|
@ -61,17 +66,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode FormOutfit abc" in {
|
"decode FormOutfit abc" in {
|
||||||
PacketCoding.decodePacket(form_abc).require match {
|
PacketCoding.decodePacket(form_abc).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Form
|
request_type mustEqual RequestType.Form
|
||||||
avatar_id mustEqual 1
|
outfit_id mustEqual 1
|
||||||
action mustEqual FormOutfit("", 0, unk4 = false, "abc")
|
action mustEqual Form("", "abc")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode FormOutfit abc" in {
|
"encode FormOutfit abc" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Form, 1, FormOutfit("", 0, unk4 = false, "abc"))
|
val msg = OutfitMembershipRequest(RequestType.Form, 1, Form("", "abc"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual form_abc
|
pkt mustEqual form_abc
|
||||||
|
|
@ -79,53 +84,53 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode FormOutfit 1" in {
|
"decode FormOutfit 1" in {
|
||||||
PacketCoding.decodePacket(form_1).require match {
|
PacketCoding.decodePacket(form_1).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Form
|
request_type mustEqual RequestType.Form
|
||||||
avatar_id mustEqual 8
|
outfit_id mustEqual 8
|
||||||
action mustEqual FormOutfit("", 0, unk4 = false, "1")
|
action mustEqual Form("", "1")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode FormOutfit 1" in {
|
"encode FormOutfit 1" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Form, 8, FormOutfit("", 0, unk4 = false, "1"))
|
val msg = OutfitMembershipRequest(RequestType.Form, 8, Form("", "1"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual form_1
|
pkt mustEqual form_1
|
||||||
}
|
}
|
||||||
|
|
||||||
"decode Unk2" in {
|
"decode Invite" in {
|
||||||
PacketCoding.decodePacket(unk2).require match {
|
PacketCoding.decodePacket(invite_old).require match {
|
||||||
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Unk2
|
request_type mustEqual RequestType.Invite
|
||||||
outfit_id mustEqual 30383325L
|
outfit_id mustEqual 30383325L
|
||||||
action mustEqual Unk2(0, 0, "virusgiver")
|
action mustEqual Invite(0, "virusgiver")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode Unk2" in {
|
"encode Invite" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Unk2, 30383325L, Unk2(0, 0, "virusgiver"))
|
val msg = OutfitMembershipRequest(RequestType.Invite, 30383325L, Invite(0, "virusgiver"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual unk2
|
pkt mustEqual invite_old
|
||||||
}
|
}
|
||||||
|
|
||||||
"decode AcceptOutfitInvite 1" in {
|
"decode AcceptOutfitInvite 1" in {
|
||||||
PacketCoding.decodePacket(accept_1).require match {
|
PacketCoding.decodePacket(accept_1).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Accept
|
request_type mustEqual RequestType.Accept
|
||||||
avatar_id mustEqual 1
|
outfit_id mustEqual 1
|
||||||
action mustEqual AcceptOutfitInvite("")
|
action mustEqual AcceptInvite("")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode AcceptOutfitInvite 1" in {
|
"encode AcceptOutfitInvite 1" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Accept, 1, AcceptOutfitInvite(""))
|
val msg = OutfitMembershipRequest(RequestType.Accept, 1, AcceptInvite(""))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual accept_1
|
pkt mustEqual accept_1
|
||||||
|
|
@ -133,17 +138,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode AcceptOutfitInvite 2" in {
|
"decode AcceptOutfitInvite 2" in {
|
||||||
PacketCoding.decodePacket(accept_2).require match {
|
PacketCoding.decodePacket(accept_2).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Accept
|
request_type mustEqual RequestType.Accept
|
||||||
avatar_id mustEqual 2
|
outfit_id mustEqual 2
|
||||||
action mustEqual AcceptOutfitInvite("")
|
action mustEqual AcceptInvite("")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode AcceptOutfitInvite 2" in {
|
"encode AcceptOutfitInvite 2" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Accept, 2, AcceptOutfitInvite(""))
|
val msg = OutfitMembershipRequest(RequestType.Accept, 2, AcceptInvite(""))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual accept_2
|
pkt mustEqual accept_2
|
||||||
|
|
@ -151,17 +156,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode RejectOutfitInvite 1" in {
|
"decode RejectOutfitInvite 1" in {
|
||||||
PacketCoding.decodePacket(reject_1).require match {
|
PacketCoding.decodePacket(reject_1).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Reject
|
request_type mustEqual RequestType.Reject
|
||||||
avatar_id mustEqual 1
|
outfit_id mustEqual 1
|
||||||
action mustEqual RejectOutfitInvite("")
|
action mustEqual RejectInvite("")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode RejectOutfitInvite 1" in {
|
"encode RejectOutfitInvite 1" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Reject, 1, RejectOutfitInvite(""))
|
val msg = OutfitMembershipRequest(RequestType.Reject, 1, RejectInvite(""))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual reject_1
|
pkt mustEqual reject_1
|
||||||
|
|
@ -169,17 +174,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode RejectOutfitInvite 2" in {
|
"decode RejectOutfitInvite 2" in {
|
||||||
PacketCoding.decodePacket(reject_2).require match {
|
PacketCoding.decodePacket(reject_2).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Reject
|
request_type mustEqual RequestType.Reject
|
||||||
avatar_id mustEqual 2
|
outfit_id mustEqual 2
|
||||||
action mustEqual RejectOutfitInvite("")
|
action mustEqual RejectInvite("")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode RejectOutfitInvite 2" in {
|
"encode RejectOutfitInvite 2" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Reject, 2, RejectOutfitInvite(""))
|
val msg = OutfitMembershipRequest(RequestType.Reject, 2, RejectInvite(""))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual reject_2
|
pkt mustEqual reject_2
|
||||||
|
|
@ -187,17 +192,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode CancelOutfitInvite 3" in {
|
"decode CancelOutfitInvite 3" in {
|
||||||
PacketCoding.decodePacket(cancel_3).require match {
|
PacketCoding.decodePacket(cancel_3).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Cancel
|
request_type mustEqual RequestType.Cancel
|
||||||
avatar_id mustEqual 3
|
outfit_id mustEqual 3
|
||||||
action mustEqual CancelOutfitInvite(0, 0, "")
|
action mustEqual CancelInvite(0, "")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode CancelOutfitInvite 3" in {
|
"encode CancelOutfitInvite 3" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Cancel, 3, CancelOutfitInvite(0, 0, ""))
|
val msg = OutfitMembershipRequest(RequestType.Cancel, 3, CancelInvite(0, ""))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual cancel_3
|
pkt mustEqual cancel_3
|
||||||
|
|
@ -205,17 +210,17 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode CancelOutfitInvite 1 abc" in {
|
"decode CancelOutfitInvite 1 abc" in {
|
||||||
PacketCoding.decodePacket(cancel_1_abc).require match {
|
PacketCoding.decodePacket(cancel_1_abc).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Cancel
|
request_type mustEqual RequestType.Cancel
|
||||||
avatar_id mustEqual 1
|
outfit_id mustEqual 1
|
||||||
action mustEqual CancelOutfitInvite(0, 0, "abc")
|
action mustEqual CancelInvite(0, "abc")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode CancelOutfitInvite 1 abc" in {
|
"encode CancelOutfitInvite 1 abc" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Cancel, 1, CancelOutfitInvite(0, 0, "abc"))
|
val msg = OutfitMembershipRequest(RequestType.Cancel, 1, CancelInvite(0, "abc"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual cancel_1_abc
|
pkt mustEqual cancel_1_abc
|
||||||
|
|
@ -223,19 +228,81 @@ class OutfitMembershipRequestTest extends Specification {
|
||||||
|
|
||||||
"decode CancelOutfitInvite 3 def" in {
|
"decode CancelOutfitInvite 3 def" in {
|
||||||
PacketCoding.decodePacket(cancel_3_def).require match {
|
PacketCoding.decodePacket(cancel_3_def).require match {
|
||||||
case OutfitMembershipRequest(request_type, avatar_id, action) =>
|
case OutfitMembershipRequest(request_type, outfit_id, action) =>
|
||||||
request_type mustEqual RequestType.Cancel
|
request_type mustEqual RequestType.Cancel
|
||||||
avatar_id mustEqual 3
|
outfit_id mustEqual 3
|
||||||
action mustEqual CancelOutfitInvite(0, 0, "def")
|
action mustEqual CancelInvite(0, "def")
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode CancelOutfitInvite 3 def" in {
|
"encode CancelOutfitInvite 3 def" in {
|
||||||
val msg = OutfitMembershipRequest(RequestType.Cancel, 3, CancelOutfitInvite(0, 0, "def"))
|
val msg = OutfitMembershipRequest(RequestType.Cancel, 3, CancelInvite(0, "def"))
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual cancel_3_def
|
pkt mustEqual cancel_3_def
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
"decode invite" in {
|
||||||
|
PacketCoding.decodePacket(invite).require match {
|
||||||
|
case OutfitMembershipRequest(request_type, outfit_id, Invite(unk1, member_name)) =>
|
||||||
|
request_type mustEqual RequestType.Invite
|
||||||
|
outfit_id mustEqual 1
|
||||||
|
unk1 mustEqual 0
|
||||||
|
member_name mustEqual "inviteTest1"
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode invite" in {
|
||||||
|
val msg = OutfitMembershipRequest(RequestType.Invite, 1, Invite(0, "inviteTest1"))
|
||||||
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual invite
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"decode kick" in {
|
||||||
|
PacketCoding.decodePacket(kick).require match {
|
||||||
|
case OutfitMembershipRequest(request_type, outfit_id, Kick(avatar_id, member_name)) =>
|
||||||
|
request_type mustEqual RequestType.Kick
|
||||||
|
outfit_id mustEqual 1
|
||||||
|
avatar_id mustEqual 41575613
|
||||||
|
member_name mustEqual ""
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode kick" in {
|
||||||
|
val msg = OutfitMembershipRequest(RequestType.Kick, 1, Kick(41575613, ""))
|
||||||
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual kick
|
||||||
|
}
|
||||||
|
|
||||||
|
"decode setrank" in {
|
||||||
|
PacketCoding.decodePacket(setrank).require match {
|
||||||
|
case OutfitMembershipRequest(request_type, outfit_id, SetRank(avatar_id, rank, member_name)) =>
|
||||||
|
request_type mustEqual RequestType.SetRank
|
||||||
|
outfit_id mustEqual 1
|
||||||
|
avatar_id mustEqual 41575613
|
||||||
|
rank mustEqual 1
|
||||||
|
member_name mustEqual ""
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode setrank" in {
|
||||||
|
val msg = OutfitMembershipRequest(RequestType.SetRank, 1, SetRank(41575613, 1, ""))
|
||||||
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual setrank
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue