mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
* added extra checks to eliminate cosmetics from the packet transcoder where having them defined would be considered harmful to the data * new uniform options; moved cosmetics class file * assurance that the cosmetics settings are accurate during transitory points
601 lines
22 KiB
Scala
601 lines
22 KiB
Scala
// Copyright (c) 2017 PSForever
|
|
package game.objectcreate
|
|
|
|
import net.psforever.packet.PacketCoding
|
|
import net.psforever.packet.game.ObjectCreateMessage
|
|
import net.psforever.packet.game.objectcreate._
|
|
import net.psforever.types._
|
|
import org.specs2.mutable._
|
|
import scodec.bits._
|
|
|
|
class CharacterDataTest extends Specification {
|
|
val string =
|
|
hex"17 73070000 BC8 3E0F 6C2D7 65535 CA16 00 00 09 9741E4F804000000 234530063007200610077006E00790052006F006E006E0069006500 220B7 E67B540404001000000000022B50100 268042006C00610063006B002000420065007200650074002000410072006D006F007500720065006400200043006F00720070007300 1700E0030050040003BC00000234040001A004000 3FFF67A8F A0A5424E0E800000000080952A9C3A03000001081103E040000000A023782F1080C0000016244108200000000808382403A030000014284C3A0C0000000202512F00B80C00000578F80F840000000280838B3C320300000080"
|
|
//string seated was intentionally-produced test data
|
|
val string_seated =
|
|
hex"170307000069023c83e0f800000011a0530063007200610077006e00790052006f006e006e0069006500220b700000000000000000000000" ++
|
|
hex"06800000268042006c00610063006b002000420065007200650074002000410072006d006f007500720065006400200043006f0072007000" ++
|
|
hex"73001700e0030050040003bc00000234040001a00400020a8fa0a5424e0e800000000080952a9c3a03000001081103e040000000a023782f" ++
|
|
hex"1080c0000016244108200000000808382403a030000014284c3a0c0000000202512f00b80c00000578f80f840000000280838b3c320300000080"
|
|
val string_backpack =
|
|
hex"17 9C030000 BC8 340D F20A9 3956C AF0D 00 00 73 480000 87041006E00670065006C006C006F00 4A148 0000000000000000000000005C54200 24404F0072006900670069006E0061006C00200044006900730074007200690063007400 1740180181E8000000C202000042000000D202000000010A3C00"
|
|
|
|
"CharacterData" should {
|
|
"decode" in {
|
|
PacketCoding.decodePacket(string).require match {
|
|
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
|
len mustEqual 1907
|
|
cls mustEqual ObjectClass.avatar
|
|
guid mustEqual PlanetSideGUID(3902)
|
|
parent.isDefined mustEqual false
|
|
data match {
|
|
case PlayerData(Some(pos), basic, char, inv, hand) =>
|
|
pos.coord mustEqual Vector3(3674.8438f, 2726.789f, 91.15625f)
|
|
pos.orient mustEqual Vector3(0f, 0f, 64.6875f)
|
|
pos.vel.isDefined mustEqual true
|
|
pos.vel.get mustEqual Vector3(5.1749997f, -1.5749999f, 0.0f)
|
|
|
|
basic match {
|
|
case CharacterAppearanceData(a, b, ribbons) =>
|
|
a.app.name mustEqual "ScrawnyRonnie"
|
|
a.app.faction mustEqual PlanetSideEmpire.TR
|
|
a.app.sex mustEqual CharacterSex.Male
|
|
a.app.head mustEqual 5
|
|
a.app.voice mustEqual CharacterVoice.Voice5
|
|
a.data.bops mustEqual false
|
|
a.data.v1 mustEqual false
|
|
a.data.v2.isEmpty mustEqual true
|
|
a.data.jammered mustEqual false
|
|
a.data.v4.isEmpty mustEqual true
|
|
a.data.v5.isEmpty mustEqual true
|
|
a.exosuit mustEqual ExoSuitType.Reinforced
|
|
a.unk5 mustEqual 0
|
|
a.char_id mustEqual 30777081L
|
|
a.unk7 mustEqual 1
|
|
a.unk8 mustEqual 4
|
|
a.unk9 mustEqual 0
|
|
a.unkA mustEqual 0
|
|
|
|
b.outfit_id mustEqual 316554L
|
|
b.outfit_name mustEqual "Black Beret Armoured Corps"
|
|
b.outfit_logo mustEqual 23
|
|
b.backpack mustEqual false
|
|
b.facingPitch mustEqual -39.375f
|
|
b.facingYawUpper mustEqual 0
|
|
b.lfs mustEqual false
|
|
b.grenade_state mustEqual GrenadeState.None
|
|
b.is_cloaking mustEqual false
|
|
b.charging_pose mustEqual false
|
|
b.on_zipline.isEmpty mustEqual true
|
|
b.unk1 mustEqual false
|
|
b.unk2 mustEqual false
|
|
b.unk3 mustEqual false
|
|
b.unk4 mustEqual false
|
|
b.unk5 mustEqual false
|
|
b.unk6 mustEqual false
|
|
b.unk7 mustEqual false
|
|
|
|
ribbons.upper mustEqual MeritCommendation.MarkovVeteran
|
|
ribbons.middle mustEqual MeritCommendation.HeavyInfantry4
|
|
ribbons.lower mustEqual MeritCommendation.TankBuster7
|
|
ribbons.tos mustEqual MeritCommendation.SixYearTR
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
char.health mustEqual 255
|
|
char.armor mustEqual 253
|
|
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
|
char.command_rank mustEqual 5
|
|
char.implant_effects.length mustEqual 1
|
|
char.implant_effects.head mustEqual ImplantEffects.NoEffects
|
|
char.cosmetics must beSome(
|
|
beEqualTo(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
|
|
)
|
|
|
|
char.unk mustEqual 7
|
|
//short test of inventory items
|
|
inv.isDefined mustEqual true
|
|
val contents = inv.get.contents
|
|
contents.size mustEqual 5
|
|
//0
|
|
contents.head.objectClass mustEqual ObjectClass.plasma_grenade
|
|
contents.head.guid mustEqual PlanetSideGUID(3662)
|
|
contents.head.parentSlot mustEqual 0
|
|
contents.head.obj.asInstanceOf[WeaponData].fire_mode mustEqual 0
|
|
contents.head.obj.asInstanceOf[WeaponData].ammo.head.objectClass mustEqual ObjectClass.plasma_grenade_ammo
|
|
contents.head.obj.asInstanceOf[WeaponData].ammo.head.guid mustEqual PlanetSideGUID(3751)
|
|
//1
|
|
contents(1).objectClass mustEqual ObjectClass.bank
|
|
contents(1).guid mustEqual PlanetSideGUID(3908)
|
|
contents(1).parentSlot mustEqual 1
|
|
contents(1).obj.asInstanceOf[WeaponData].fire_mode mustEqual 1
|
|
contents(1).obj.asInstanceOf[WeaponData].ammo.head.objectClass mustEqual ObjectClass.armor_canister
|
|
contents(1).obj.asInstanceOf[WeaponData].ammo.head.guid mustEqual PlanetSideGUID(4143)
|
|
//2
|
|
contents(2).objectClass mustEqual ObjectClass.mini_chaingun
|
|
contents(2).guid mustEqual PlanetSideGUID(4164)
|
|
contents(2).parentSlot mustEqual 2
|
|
contents(2).obj.asInstanceOf[WeaponData].fire_mode mustEqual 0
|
|
contents(2).obj.asInstanceOf[WeaponData].ammo.head.objectClass mustEqual ObjectClass.bullet_9mm
|
|
contents(2).obj.asInstanceOf[WeaponData].ammo.head.guid mustEqual PlanetSideGUID(3728)
|
|
//3
|
|
contents(3).objectClass mustEqual ObjectClass.phoenix //actually, a decimator
|
|
contents(3).guid mustEqual PlanetSideGUID(3603)
|
|
contents(3).parentSlot mustEqual 3
|
|
contents(3).obj.asInstanceOf[WeaponData].fire_mode mustEqual 0
|
|
contents(3).obj.asInstanceOf[WeaponData].ammo.head.objectClass mustEqual ObjectClass.phoenix_missile
|
|
contents(3).obj.asInstanceOf[WeaponData].ammo.head.guid mustEqual PlanetSideGUID(3056)
|
|
//4
|
|
contents(4).objectClass mustEqual ObjectClass.chainblade
|
|
contents(4).guid mustEqual PlanetSideGUID(4088)
|
|
contents(4).parentSlot mustEqual 4
|
|
contents(4).obj.asInstanceOf[WeaponData].fire_mode mustEqual 1
|
|
contents(4).obj.asInstanceOf[WeaponData].ammo.head.objectClass mustEqual ObjectClass.melee_ammo
|
|
contents(4).obj.asInstanceOf[WeaponData].ammo.head.guid mustEqual PlanetSideGUID(3279)
|
|
|
|
hand mustEqual DrawnSlot.Rifle1
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
}
|
|
//
|
|
"decode (seated)" in {
|
|
PacketCoding.decodePacket(string_seated).require match {
|
|
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
|
len mustEqual 1795
|
|
cls mustEqual ObjectClass.avatar
|
|
guid mustEqual PlanetSideGUID(3902)
|
|
parent.contains(ObjectCreateMessageParent(PlanetSideGUID(1234), 0)) mustEqual true
|
|
data match {
|
|
case PlayerData(None, basic, _, _, _) =>
|
|
basic match {
|
|
case CharacterAppearanceData(a, b, ribbons) =>
|
|
a.app.name mustEqual "ScrawnyRonnie"
|
|
a.app.faction mustEqual PlanetSideEmpire.TR
|
|
a.app.sex mustEqual CharacterSex.Male
|
|
a.app.head mustEqual 5
|
|
a.app.voice mustEqual CharacterVoice.Voice5
|
|
a.data.bops mustEqual false
|
|
a.data.v1 mustEqual false
|
|
a.data.v2.isEmpty mustEqual true
|
|
a.data.jammered mustEqual false
|
|
a.data.v4.isEmpty mustEqual true
|
|
a.data.v5.isEmpty mustEqual true
|
|
a.exosuit mustEqual ExoSuitType.Reinforced
|
|
a.unk5 mustEqual 0
|
|
a.char_id mustEqual 192L
|
|
a.unk7 mustEqual 0
|
|
a.unk8 mustEqual 0
|
|
a.unk9 mustEqual 0
|
|
a.unkA mustEqual 0
|
|
|
|
b.outfit_id mustEqual 26L
|
|
b.outfit_name mustEqual "Black Beret Armoured Corps"
|
|
b.outfit_logo mustEqual 23
|
|
b.backpack mustEqual false
|
|
b.facingPitch mustEqual -39.375f
|
|
b.facingYawUpper mustEqual 0
|
|
b.lfs mustEqual false
|
|
b.grenade_state mustEqual GrenadeState.None
|
|
b.is_cloaking mustEqual false
|
|
b.charging_pose mustEqual false
|
|
b.on_zipline.isEmpty mustEqual true
|
|
b.unk1 mustEqual false
|
|
b.unk2 mustEqual false
|
|
b.unk3 mustEqual false
|
|
b.unk4 mustEqual false
|
|
b.unk5 mustEqual false
|
|
b.unk6 mustEqual false
|
|
b.unk7 mustEqual false
|
|
|
|
ribbons.upper mustEqual MeritCommendation.MarkovVeteran
|
|
ribbons.middle mustEqual MeritCommendation.HeavyInfantry4
|
|
ribbons.lower mustEqual MeritCommendation.TankBuster7
|
|
ribbons.tos mustEqual MeritCommendation.SixYearTR
|
|
//etc..
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
}
|
|
|
|
"decode (backpack)" in {
|
|
PacketCoding.decodePacket(string_backpack).require match {
|
|
case ObjectCreateMessage(len, cls, guid, parent, data) =>
|
|
len mustEqual 924L
|
|
cls mustEqual ObjectClass.avatar
|
|
guid mustEqual PlanetSideGUID(3380)
|
|
parent.isDefined mustEqual false
|
|
data match {
|
|
case PlayerData(Some(pos), basic, char, None, hand) =>
|
|
pos.coord mustEqual Vector3(4629.8906f, 6316.4453f, 54.734375f)
|
|
pos.orient mustEqual Vector3(0, 0, 126.5625f)
|
|
pos.vel.isDefined mustEqual false
|
|
|
|
basic match {
|
|
case CharacterAppearanceData(a, b, ribbons) =>
|
|
a.app.name mustEqual "Angello"
|
|
a.app.faction mustEqual PlanetSideEmpire.VS
|
|
a.app.sex mustEqual CharacterSex.Male
|
|
a.app.head mustEqual 10
|
|
a.app.voice mustEqual CharacterVoice.Voice2
|
|
a.data.bops mustEqual false
|
|
a.data.v1 mustEqual false
|
|
a.data.v2.isEmpty mustEqual true
|
|
a.data.jammered mustEqual false
|
|
a.data.v4.isEmpty mustEqual true
|
|
a.data.v5.isEmpty mustEqual true
|
|
a.exosuit mustEqual ExoSuitType.MAX
|
|
a.unk5 mustEqual 1
|
|
a.char_id mustEqual 0L
|
|
a.unk7 mustEqual 0
|
|
a.unk8 mustEqual 0
|
|
a.unk9 mustEqual 0
|
|
a.unkA mustEqual 0
|
|
|
|
b.outfit_id mustEqual 529687L
|
|
b.outfit_name mustEqual "Original District"
|
|
b.outfit_logo mustEqual 23
|
|
b.backpack mustEqual true
|
|
b.facingPitch mustEqual -8.4375f
|
|
b.facingYawUpper mustEqual 0
|
|
b.lfs mustEqual false
|
|
b.grenade_state mustEqual GrenadeState.None
|
|
b.is_cloaking mustEqual false
|
|
b.charging_pose mustEqual false
|
|
b.on_zipline.isEmpty mustEqual true
|
|
b.unk1 mustEqual false
|
|
b.unk2 mustEqual false
|
|
b.unk3 mustEqual false
|
|
b.unk4 mustEqual false
|
|
b.unk5 mustEqual false
|
|
b.unk6 mustEqual false
|
|
b.unk7 mustEqual false
|
|
|
|
ribbons.upper mustEqual MeritCommendation.Jacking2
|
|
ribbons.middle mustEqual MeritCommendation.ScavengerVS1
|
|
ribbons.lower mustEqual MeritCommendation.AMSSupport4
|
|
ribbons.tos mustEqual MeritCommendation.SixYearVS
|
|
//etc..
|
|
case _ =>
|
|
ko
|
|
}
|
|
|
|
char.health mustEqual 0
|
|
char.armor mustEqual 0
|
|
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
|
char.command_rank mustEqual 2
|
|
char.implant_effects.isEmpty mustEqual true
|
|
char.cosmetics must beSome(
|
|
beEqualTo(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
|
|
)
|
|
char.unk mustEqual 1
|
|
|
|
hand mustEqual DrawnSlot.Pistol1
|
|
case _ =>
|
|
ko
|
|
}
|
|
case _ =>
|
|
ko
|
|
}
|
|
}
|
|
|
|
"encode" in {
|
|
val pos: PlacementData = PlacementData(
|
|
Vector3(3674.8438f, 2726.789f, 91.15625f),
|
|
Vector3(0f, 0f, 64.6875f),
|
|
Some(Vector3(5.1749997f, -1.5749999f, 0.0f))
|
|
)
|
|
val a: Int => CharacterAppearanceA = CharacterAppearanceA(
|
|
BasicCharacterData(
|
|
"ScrawnyRonnie",
|
|
PlanetSideEmpire.TR,
|
|
CharacterSex.Male,
|
|
5,
|
|
CharacterVoice.Voice5
|
|
),
|
|
CommonFieldData(
|
|
PlanetSideEmpire.TR,
|
|
false,
|
|
false,
|
|
false,
|
|
None,
|
|
false,
|
|
None,
|
|
None,
|
|
PlanetSideGUID(0)
|
|
),
|
|
ExoSuitType.Reinforced,
|
|
0,
|
|
30777081L,
|
|
1,
|
|
4,
|
|
0,
|
|
0
|
|
)
|
|
val b: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
|
|
316554L,
|
|
"Black Beret Armoured Corps",
|
|
23,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
-39.375f,
|
|
0f,
|
|
false,
|
|
GrenadeState.None,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
None
|
|
)
|
|
|
|
val app: Int => CharacterAppearanceData = CharacterAppearanceData(
|
|
a,
|
|
b,
|
|
RibbonBars(
|
|
MeritCommendation.MarkovVeteran,
|
|
MeritCommendation.HeavyInfantry4,
|
|
MeritCommendation.TankBuster7,
|
|
MeritCommendation.SixYearTR
|
|
)
|
|
)
|
|
val char: (Boolean, Boolean) => CharacterData = CharacterData(
|
|
255,
|
|
253,
|
|
UniformStyle.ThirdUpgrade,
|
|
7,
|
|
5,
|
|
List(ImplantEffects.NoEffects),
|
|
Some(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
|
|
)
|
|
val inv = InventoryData(
|
|
InventoryItemData(
|
|
ObjectClass.plasma_grenade,
|
|
PlanetSideGUID(3662),
|
|
0,
|
|
WeaponData(0, 0, ObjectClass.plasma_grenade_ammo, PlanetSideGUID(3751), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.bank,
|
|
PlanetSideGUID(3908),
|
|
1,
|
|
WeaponData(0, 0, 1, ObjectClass.armor_canister, PlanetSideGUID(4143), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.mini_chaingun,
|
|
PlanetSideGUID(4164),
|
|
2,
|
|
WeaponData(0, 0, ObjectClass.bullet_9mm, PlanetSideGUID(3728), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.phoenix,
|
|
PlanetSideGUID(3603),
|
|
3,
|
|
WeaponData(0, 0, ObjectClass.phoenix_missile, PlanetSideGUID(3056), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.chainblade,
|
|
PlanetSideGUID(4088),
|
|
4,
|
|
WeaponData(0, 0, 1, ObjectClass.melee_ammo, PlanetSideGUID(3279), 0, CommonFieldData()(false))
|
|
) ::
|
|
Nil
|
|
)
|
|
val obj = PlayerData(pos, app, char, inv, DrawnSlot.Rifle1)
|
|
|
|
val msg = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(3902), obj)
|
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
|
pkt mustEqual string
|
|
}
|
|
|
|
"encode (seated)" in {
|
|
val a: Int => CharacterAppearanceA = CharacterAppearanceA(
|
|
BasicCharacterData(
|
|
"ScrawnyRonnie",
|
|
PlanetSideEmpire.TR,
|
|
CharacterSex.Male,
|
|
5,
|
|
CharacterVoice.Voice5
|
|
),
|
|
CommonFieldData(
|
|
PlanetSideEmpire.TR,
|
|
false,
|
|
false,
|
|
false,
|
|
None,
|
|
false,
|
|
None,
|
|
None,
|
|
PlanetSideGUID(0)
|
|
),
|
|
ExoSuitType.Reinforced,
|
|
0,
|
|
192L,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
)
|
|
val b: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
|
|
26L,
|
|
"Black Beret Armoured Corps",
|
|
23,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
-39.375f,
|
|
0f,
|
|
false,
|
|
GrenadeState.None,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
None
|
|
)
|
|
|
|
val app: Int => CharacterAppearanceData = CharacterAppearanceData(
|
|
a,
|
|
b,
|
|
RibbonBars(
|
|
MeritCommendation.MarkovVeteran,
|
|
MeritCommendation.HeavyInfantry4,
|
|
MeritCommendation.TankBuster7,
|
|
MeritCommendation.SixYearTR
|
|
)
|
|
)
|
|
val char: (Boolean, Boolean) => CharacterData = CharacterData(
|
|
255,
|
|
253,
|
|
UniformStyle.ThirdUpgrade,
|
|
5,
|
|
List(ImplantEffects.NoEffects),
|
|
Some(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
|
|
)
|
|
val inv = InventoryData(
|
|
InventoryItemData(
|
|
ObjectClass.plasma_grenade,
|
|
PlanetSideGUID(3662),
|
|
0,
|
|
WeaponData(0, 0, ObjectClass.plasma_grenade_ammo, PlanetSideGUID(3751), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.bank,
|
|
PlanetSideGUID(3908),
|
|
1,
|
|
WeaponData(0, 0, 1, ObjectClass.armor_canister, PlanetSideGUID(4143), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.mini_chaingun,
|
|
PlanetSideGUID(4164),
|
|
2,
|
|
WeaponData(0, 0, ObjectClass.bullet_9mm, PlanetSideGUID(3728), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.phoenix,
|
|
PlanetSideGUID(3603),
|
|
3,
|
|
WeaponData(0, 0, ObjectClass.phoenix_missile, PlanetSideGUID(3056), 0, CommonFieldData()(false))
|
|
) ::
|
|
InventoryItemData(
|
|
ObjectClass.chainblade,
|
|
PlanetSideGUID(4088),
|
|
4,
|
|
WeaponData(0, 0, 1, ObjectClass.melee_ammo, PlanetSideGUID(3279), 0, CommonFieldData()(false))
|
|
) ::
|
|
Nil
|
|
)
|
|
val obj = PlayerData(app, char, inv, DrawnSlot.Rifle1)
|
|
|
|
val msg = ObjectCreateMessage(
|
|
ObjectClass.avatar,
|
|
PlanetSideGUID(3902),
|
|
ObjectCreateMessageParent(PlanetSideGUID(1234), 0),
|
|
obj
|
|
)
|
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
|
pkt mustEqual string_seated
|
|
}
|
|
|
|
"encode (backpack)" in {
|
|
val pos = PlacementData(
|
|
Vector3(4629.8906f, 6316.4453f, 54.734375f),
|
|
Vector3(0, 0, 126.5625f)
|
|
)
|
|
val a: Int => CharacterAppearanceA = CharacterAppearanceA(
|
|
BasicCharacterData(
|
|
"Angello",
|
|
PlanetSideEmpire.VS,
|
|
CharacterSex.Male,
|
|
10,
|
|
CharacterVoice.Voice2
|
|
),
|
|
CommonFieldData(
|
|
PlanetSideEmpire.VS,
|
|
false,
|
|
true,
|
|
false,
|
|
None,
|
|
false,
|
|
None,
|
|
None,
|
|
PlanetSideGUID(0)
|
|
),
|
|
ExoSuitType.MAX,
|
|
1,
|
|
0L,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
)
|
|
val b: (Boolean, Int) => CharacterAppearanceB = CharacterAppearanceB(
|
|
529687L,
|
|
"Original District",
|
|
23,
|
|
false, //unk1
|
|
true, //backpack
|
|
false, //unk2
|
|
false, //unk3
|
|
false, //unk4
|
|
351.5625f,
|
|
0f, //also: -8.4375f, 0f
|
|
false, //lfs
|
|
GrenadeState.None,
|
|
false, //is_cloaking
|
|
false, //unk5
|
|
false, //unk6
|
|
false, //charging_pose
|
|
false, //unk7
|
|
None
|
|
)
|
|
|
|
val app: Int => CharacterAppearanceData = CharacterAppearanceData(
|
|
a,
|
|
b,
|
|
RibbonBars(
|
|
MeritCommendation.Jacking2,
|
|
MeritCommendation.ScavengerVS1,
|
|
MeritCommendation.AMSSupport4,
|
|
MeritCommendation.SixYearVS
|
|
)
|
|
)
|
|
val char: (Boolean, Boolean) => CharacterData = CharacterData(
|
|
0,
|
|
0,
|
|
UniformStyle.ThirdUpgrade,
|
|
1,
|
|
List(),
|
|
Some(Set(Cosmetic.NoHelmet, Cosmetic.Beret, Cosmetic.Sunglasses, Cosmetic.Earpiece))
|
|
)
|
|
val obj = PlayerData(pos, app, char, DrawnSlot.Pistol1)
|
|
|
|
val msg = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(3380), obj)
|
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
|
//granular test
|
|
val pkt_bitv = pkt.toBitVector
|
|
val ori_bitv = string_backpack.toBitVector
|
|
pkt_bitv.take(916) mustEqual pkt_bitv.take(916) //skip 4
|
|
pkt_bitv.drop(920) mustEqual pkt_bitv.drop(920)
|
|
//TODO work on CharacterData to make this pass as a single stream
|
|
}
|
|
}
|
|
}
|