From 902ed94ac9fb1b54d13ef881a7a54dbcb628c7da Mon Sep 17 00:00:00 2001 From: FateJH Date: Tue, 8 Aug 2017 23:36:11 -0400 Subject: [PATCH 1/4] initial work on PropertyOverrideMessage packet and tests --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../packet/game/PropertyOverrideMessage.scala | 115 ++++++++++++++++++ .../game/PropertyOverrideMessageTest.scala | 28 +++++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala create mode 100644 common/src/test/scala/game/PropertyOverrideMessageTest.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index a502732a..757772ee 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -571,7 +571,7 @@ object GamePacketOpcode extends Enumeration { case 0xd2 => noDecoder(RespawnAMSInfoMessage) case 0xd3 => noDecoder(ComponentDamageMessage) case 0xd4 => noDecoder(GenericObjectActionAtPositionMessage) - case 0xd5 => noDecoder(PropertyOverrideMessage) + case 0xd5 => game.PropertyOverrideMessage.decode case 0xd6 => noDecoder(WarpgateLinkOverrideMessage) case 0xd7 => noDecoder(EmpireBenefitsMessage) // 0xd8 diff --git a/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala b/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala new file mode 100644 index 00000000..1aab5e3c --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala @@ -0,0 +1,115 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ +import shapeless.{::, HNil} + +final case class PropertyOverrideMessage(list : List[PropertyOverrideMessage.GameProperty]) + extends PlanetSideGamePacket { + type Packet = PropertyOverrideMessage + def opcode = GamePacketOpcode.PropertyOverrideMessage + def encode = PropertyOverrideMessage.encode(this) +} + +object GamePropertyValues { + def apply(field1 : String) : PropertyOverrideMessage.GamePropertyValues = { + PropertyOverrideMessage.GamePropertyValues(field1, "") + } + + def apply(field1 : String, field2 : String) : PropertyOverrideMessage.GamePropertyValues = { + PropertyOverrideMessage.GamePropertyValues(field1, field2) + } +} + +object GamePropertyField { + def apply(unk : Int) : PropertyOverrideMessage.GamePropertyField = { + PropertyOverrideMessage.GamePropertyField(unk, Nil) + } + + def apply(unk : Int, list : List[PropertyOverrideMessage.GamePropertyValues]) : PropertyOverrideMessage.GamePropertyField = { + PropertyOverrideMessage.GamePropertyField(unk, list) + } +} + +object GameProperty { + def apply(unk : Int) : PropertyOverrideMessage.GameProperty = { + PropertyOverrideMessage.GameProperty(unk, Nil) + } + + def apply(unk : Int, list : List[PropertyOverrideMessage.GamePropertyField]) : PropertyOverrideMessage.GameProperty = { + PropertyOverrideMessage.GameProperty(unk, list) + } +} + +object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { + final case class GamePropertyValues(field1 : String, field2 : String) + + final case class GamePropertyField(unk : Int, list : List[GamePropertyValues]) + + final case class GameProperty(unk : Int, list : List[GamePropertyField]) + + private def value_pair_aligned_codec(n : Int) : Codec[GamePropertyValues] = ( + ("field1" | PacketHelpers.encodedStringAligned(n)) :: + ("field2" | PacketHelpers.encodedString) + ).as[GamePropertyValues] + + private val value_pair_codec : Codec[GamePropertyValues] = ( + ("field1" | PacketHelpers.encodedString) :: + ("field2" | PacketHelpers.encodedString) + ).as[GamePropertyValues] + + private def game_subproperty_codec(n : Int) : Codec[GamePropertyField] = ( + ("unk" | uintL(11)) :: + (("len" | uint16L) >>:~ { len => + conditional(len > 0, value_pair_aligned_codec(n)) :: + conditional(len > 1, PacketHelpers.listOfNSized((len - 1).toLong, value_pair_codec)) + }) + ).xmap[GamePropertyField] ( + { + case unk :: _ :: Some(first) :: None :: HNil => + GamePropertyField(unk, first :: Nil) + + case unk :: _ :: Some(first) :: Some(other) :: HNil => + GamePropertyField(unk, first +: other) + }, + { + case GamePropertyField(unk, list) => + val (first, other) = list match { + case ((f : GamePropertyValues) +: (rest : List[GamePropertyValues])) => (Some(f), Some(rest)) + case (f : GamePropertyValues) +: Nil => (Some(f), None) + case Nil => (None, None) + } + unk :: list.length :: first :: other :: HNil + } + ) + + private val game_property_codec : Codec[GameProperty] = ( + ("unk" | uint16L) :: + (("len" | uintL(11)) >>:~ { len => + conditional(len > 0, game_subproperty_codec(2)) :: + conditional(len > 1, PacketHelpers.listOfNSized((len - 1).toLong, game_subproperty_codec(5))) + }) + ).xmap[GameProperty] ( + { + case unk :: _ :: Some(first) :: None :: HNil => + GameProperty(unk, first :: Nil) + + case unk :: _ :: Some(first) :: Some(other) :: HNil => + GameProperty(unk, first +: other) + }, + { + case GameProperty(unk, list) => + val (first, other) = list match { + case ((f : GamePropertyField) +: (rest : List[GamePropertyField])) => (Some(f), Some(rest)) + case (f : GamePropertyField) +: Nil => (Some(f), None) + case Nil => (None, None) + } + unk :: list.length :: first :: other :: HNil + } + ) + + implicit val codec : Codec[PropertyOverrideMessage] = + listOfN(uint16L, game_property_codec).as[PropertyOverrideMessage] +} diff --git a/common/src/test/scala/game/PropertyOverrideMessageTest.scala b/common/src/test/scala/game/PropertyOverrideMessageTest.scala new file mode 100644 index 00000000..09c40d80 --- /dev/null +++ b/common/src/test/scala/game/PropertyOverrideMessageTest.scala @@ -0,0 +1,28 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class PropertyOverrideMessageTest extends Specification { + val string = hex"D5 0B 00 00 00 01 0A E4 0C 02 48 70 75 72 63 68 61 73 65 5F 65 78 65 6D 70 74 5F 76 73 80 92 70 75 72 63 68 61 73 65 5F 65 78 65 6D 70 74 5F 74 72 80 92 70 75 72 63 68 61 73 65 5F 65 78 65 6D 70 74 5F 6E 63 80 11 00 01 14 A4 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 12 00 01 14 A4 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 13 00 01 14 A4 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 14 00 01 14 A4 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 15 00 01 14 A4 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 16 00 01 14 A4 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 1D 00 15 0A 60 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 54 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 76 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 87 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C7 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C8 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 26 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 52 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 AD 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B0 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CE 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 D6 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 2C 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 82 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 83 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CA 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 61 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 9B 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 DA 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 1E 00 15 0A 60 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 54 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 76 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 87 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C7 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C8 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 26 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 52 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 AD 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B0 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CE 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 D6 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 2C 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 82 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 83 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CA 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 61 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 9B 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 DA 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 1F 00 15 0A 60 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 54 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 76 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 87 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C7 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C8 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 26 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 52 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 AD 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B0 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CE 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 D6 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 2C 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 82 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 83 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CA 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 61 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 9B 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 DA 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 20 00 15 0A 60 04 02 1C 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 54 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 76 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 87 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C7 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 C8 00 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 26 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 52 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 AD 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B0 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CE 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 D6 20 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 2C 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 82 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 83 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 B9 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 CA 40 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 61 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 9B 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65 DA 60 20 10 E0 61 6C 6C 6F 77 65 64 85 66 61 6C 73 65" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case PropertyOverrideMessage(list) => + //List(GameProperty(0,List(GamePropertyField(343,List(GamePropertyValues(purchase_exempt_vs,), GamePropertyValues(purchase_exempt_tr,), GamePropertyValues(purchase_exempt_nc,))))), GameProperty(17,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(18,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(19,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(20,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(21,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(22,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(29,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false))))), GameProperty(30,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false))))), GameProperty(31,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false))))), GameProperty(32,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false)))))) + ok + case _ => + ko + } + } + + "encode" in { + ok +// val msg = ProximityTerminalUseMessage(PlanetSideGUID(75), PlanetSideGUID(167), true) +// val pkt = PacketCoding.EncodePacket(msg).require.toByteVector +// pkt mustEqual string + } +} From 25952d12dc04f5b85ac876340dbe56739a42e6f4 Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 9 Aug 2017 00:58:12 -0400 Subject: [PATCH 2/4] what a painful test --- .../game/PropertyOverrideMessageTest.scala | 533 +++++++++++++++++- 1 file changed, 526 insertions(+), 7 deletions(-) diff --git a/common/src/test/scala/game/PropertyOverrideMessageTest.scala b/common/src/test/scala/game/PropertyOverrideMessageTest.scala index 09c40d80..3145f3b4 100644 --- a/common/src/test/scala/game/PropertyOverrideMessageTest.scala +++ b/common/src/test/scala/game/PropertyOverrideMessageTest.scala @@ -3,7 +3,7 @@ package game import org.specs2.mutable._ import net.psforever.packet._ -import net.psforever.packet.game._ +import net.psforever.packet.game.{GamePropertyField, _} import scodec.bits._ class PropertyOverrideMessageTest extends Specification { @@ -12,17 +12,536 @@ class PropertyOverrideMessageTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { case PropertyOverrideMessage(list) => - //List(GameProperty(0,List(GamePropertyField(343,List(GamePropertyValues(purchase_exempt_vs,), GamePropertyValues(purchase_exempt_tr,), GamePropertyValues(purchase_exempt_nc,))))), GameProperty(17,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(18,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(19,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(20,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(21,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(22,List(GamePropertyField(421,List(GamePropertyValues(allowed,false))))), GameProperty(29,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false))))), GameProperty(30,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false))))), GameProperty(31,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false))))), GameProperty(32,List(GamePropertyField(83,List(GamePropertyValues(allowed,false))), GamePropertyField(84,List(GamePropertyValues(allowed,false))), GamePropertyField(118,List(GamePropertyValues(allowed,false))), GamePropertyField(135,List(GamePropertyValues(allowed,false))), GamePropertyField(199,List(GamePropertyValues(allowed,false))), GamePropertyField(200,List(GamePropertyValues(allowed,false))), GamePropertyField(294,List(GamePropertyValues(allowed,false))), GamePropertyField(338,List(GamePropertyValues(allowed,false))), GamePropertyField(429,List(GamePropertyValues(allowed,false))), GamePropertyField(432,List(GamePropertyValues(allowed,false))), GamePropertyField(441,List(GamePropertyValues(allowed,false))), GamePropertyField(462,List(GamePropertyValues(allowed,false))), GamePropertyField(470,List(GamePropertyValues(allowed,false))), GamePropertyField(556,List(GamePropertyValues(allowed,false))), GamePropertyField(642,List(GamePropertyValues(allowed,false))), GamePropertyField(643,List(GamePropertyValues(allowed,false))), GamePropertyField(697,List(GamePropertyValues(allowed,false))), GamePropertyField(714,List(GamePropertyValues(allowed,false))), GamePropertyField(865,List(GamePropertyValues(allowed,false))), GamePropertyField(923,List(GamePropertyValues(allowed,false))), GamePropertyField(986,List(GamePropertyValues(allowed,false)))))) - ok + list.length mustEqual 11 + // + list.head.unk mustEqual 0 + list.head.list.length mustEqual 1 + list.head.list.head.unk mustEqual 343 + list.head.list.head.list.length mustEqual 3 + list.head.list.head.list.head.field1 mustEqual "purchase_exempt_vs" + list.head.list.head.list.head.field2 mustEqual "" + list.head.list.head.list(1).field1 mustEqual "purchase_exempt_tr" + list.head.list.head.list(1).field2 mustEqual "" + list.head.list.head.list(2).field1 mustEqual "purchase_exempt_nc" + list.head.list.head.list(2).field2 mustEqual "" + // + list(1).unk mustEqual 17 + list(1).list.length mustEqual 1 + list(1).list.head.unk mustEqual 421 + list(1).list.head.list.length mustEqual 1 + list(1).list.head.list.head.field1 mustEqual "allowed" + list(1).list.head.list.head.field2 mustEqual "false" + // + list(2).unk mustEqual 18 + list(2).list.length mustEqual 1 + list(2).list.head.unk mustEqual 421 + list(2).list.head.list.length mustEqual 1 + list(2).list.head.list.head.field1 mustEqual "allowed" + list(2).list.head.list.head.field2 mustEqual "false" + // + list(3).unk mustEqual 19 + list(3).list.length mustEqual 1 + list(3).list.head.unk mustEqual 421 + list(3).list.head.list.length mustEqual 1 + list(3).list.head.list.head.field1 mustEqual "allowed" + list(3).list.head.list.head.field2 mustEqual "false" + // + list(4).unk mustEqual 20 + list(4).list.length mustEqual 1 + list(4).list.head.unk mustEqual 421 + list(4).list.head.list.length mustEqual 1 + list(4).list.head.list.head.field1 mustEqual "allowed" + list(4).list.head.list.head.field2 mustEqual "false" + // + list(5).unk mustEqual 21 + list(5).list.length mustEqual 1 + list(5).list.head.unk mustEqual 421 + list(5).list.head.list.length mustEqual 1 + list(5).list.head.list.head.field1 mustEqual "allowed" + list(5).list.head.list.head.field2 mustEqual "false" + // + list(6).unk mustEqual 22 + list(6).list.length mustEqual 1 + list(6).list.head.unk mustEqual 421 + list(6).list.head.list.length mustEqual 1 + list(6).list.head.list.head.field1 mustEqual "allowed" + list(6).list.head.list.head.field2 mustEqual "false" + // + list(7).unk mustEqual 29 + list(7).list.length mustEqual 21 + list(7).list.head.unk mustEqual 83 + list(7).list.head.list.length mustEqual 1 + list(7).list.head.list.head.field1 mustEqual "allowed" + list(7).list.head.list.head.field2 mustEqual "false" + list(7).list(1).unk mustEqual 84 + list(7).list(1).list.length mustEqual 1 + list(7).list(1).list.head.field1 mustEqual "allowed" + list(7).list(1).list.head.field2 mustEqual "false" + list(7).list(2).unk mustEqual 118 + list(7).list(2).list.length mustEqual 1 + list(7).list(2).list.head.field1 mustEqual "allowed" + list(7).list(2).list.head.field2 mustEqual "false" + list(7).list(3).unk mustEqual 135 + list(7).list(3).list.length mustEqual 1 + list(7).list(3).list.head.field1 mustEqual "allowed" + list(7).list(3).list.head.field2 mustEqual "false" + list(7).list(4).unk mustEqual 199 + list(7).list(4).list.length mustEqual 1 + list(7).list(4).list.head.field1 mustEqual "allowed" + list(7).list(4).list.head.field2 mustEqual "false" + list(7).list(5).unk mustEqual 200 + list(7).list(5).list.length mustEqual 1 + list(7).list(5).list.head.field1 mustEqual "allowed" + list(7).list(5).list.head.field2 mustEqual "false" + list(7).list(6).unk mustEqual 294 + list(7).list(6).list.length mustEqual 1 + list(7).list(6).list.head.field1 mustEqual "allowed" + list(7).list(6).list.head.field2 mustEqual "false" + list(7).list(7).unk mustEqual 338 + list(7).list(7).list.length mustEqual 1 + list(7).list(7).list.head.field1 mustEqual "allowed" + list(7).list(7).list.head.field2 mustEqual "false" + list(7).list(8).unk mustEqual 429 + list(7).list(8).list.length mustEqual 1 + list(7).list(8).list.head.field1 mustEqual "allowed" + list(7).list(8).list.head.field2 mustEqual "false" + list(7).list(9).unk mustEqual 432 + list(7).list(9).list.length mustEqual 1 + list(7).list(9).list.head.field1 mustEqual "allowed" + list(7).list(9).list.head.field2 mustEqual "false" + list(7).list(10).unk mustEqual 441 + list(7).list(10).list.length mustEqual 1 + list(7).list(10).list.head.field1 mustEqual "allowed" + list(7).list(10).list.head.field2 mustEqual "false" + list(7).list(11).unk mustEqual 462 + list(7).list(11).list.length mustEqual 1 + list(7).list(11).list.head.field1 mustEqual "allowed" + list(7).list(11).list.head.field2 mustEqual "false" + list(7).list(12).unk mustEqual 470 + list(7).list(12).list.length mustEqual 1 + list(7).list(12).list.head.field1 mustEqual "allowed" + list(7).list(12).list.head.field2 mustEqual "false" + list(7).list(13).unk mustEqual 556 + list(7).list(13).list.length mustEqual 1 + list(7).list(13).list.head.field1 mustEqual "allowed" + list(7).list(13).list.head.field2 mustEqual "false" + list(7).list(14).unk mustEqual 642 + list(7).list(14).list.length mustEqual 1 + list(7).list(14).list.head.field1 mustEqual "allowed" + list(7).list(14).list.head.field2 mustEqual "false" + list(7).list(15).unk mustEqual 643 + list(7).list(15).list.length mustEqual 1 + list(7).list(15).list.head.field1 mustEqual "allowed" + list(7).list(15).list.head.field2 mustEqual "false" + list(7).list(16).unk mustEqual 697 + list(7).list(16).list.length mustEqual 1 + list(7).list(16).list.head.field1 mustEqual "allowed" + list(7).list(16).list.head.field2 mustEqual "false" + list(7).list(17).unk mustEqual 714 + list(7).list(17).list.length mustEqual 1 + list(7).list(17).list.head.field1 mustEqual "allowed" + list(7).list(17).list.head.field2 mustEqual "false" + list(7).list(18).unk mustEqual 865 + list(7).list(18).list.length mustEqual 1 + list(7).list(18).list.head.field1 mustEqual "allowed" + list(7).list(18).list.head.field2 mustEqual "false" + list(7).list(19).unk mustEqual 923 + list(7).list(19).list.length mustEqual 1 + list(7).list(19).list.head.field1 mustEqual "allowed" + list(7).list(19).list.head.field2 mustEqual "false" + list(7).list(20).unk mustEqual 986 + list(7).list(20).list.length mustEqual 1 + list(7).list(20).list.head.field1 mustEqual "allowed" + list(7).list(20).list.head.field2 mustEqual "false" + // + list(8).unk mustEqual 30 + list(8).list.length mustEqual 21 + list(7).list.head.unk mustEqual 83 + list(8).list.head.list.length mustEqual 1 + list(8).list.head.list.head.field1 mustEqual "allowed" + list(8).list.head.list.head.field2 mustEqual "false" + list(8).list(1).unk mustEqual 84 + list(8).list(1).list.length mustEqual 1 + list(8).list(1).list.head.field1 mustEqual "allowed" + list(8).list(1).list.head.field2 mustEqual "false" + list(8).list(2).unk mustEqual 118 + list(8).list(2).list.length mustEqual 1 + list(8).list(2).list.head.field1 mustEqual "allowed" + list(8).list(2).list.head.field2 mustEqual "false" + list(8).list(3).unk mustEqual 135 + list(8).list(3).list.length mustEqual 1 + list(8).list(3).list.head.field1 mustEqual "allowed" + list(8).list(3).list.head.field2 mustEqual "false" + list(8).list(4).unk mustEqual 199 + list(8).list(4).list.length mustEqual 1 + list(8).list(4).list.head.field1 mustEqual "allowed" + list(8).list(4).list.head.field2 mustEqual "false" + list(8).list(5).unk mustEqual 200 + list(8).list(5).list.length mustEqual 1 + list(8).list(5).list.head.field1 mustEqual "allowed" + list(8).list(5).list.head.field2 mustEqual "false" + list(8).list(6).unk mustEqual 294 + list(8).list(6).list.length mustEqual 1 + list(8).list(6).list.head.field1 mustEqual "allowed" + list(8).list(6).list.head.field2 mustEqual "false" + list(8).list(7).unk mustEqual 338 + list(8).list(7).list.length mustEqual 1 + list(8).list(7).list.head.field1 mustEqual "allowed" + list(8).list(7).list.head.field2 mustEqual "false" + list(8).list(8).unk mustEqual 429 + list(8).list(8).list.length mustEqual 1 + list(8).list(8).list.head.field1 mustEqual "allowed" + list(8).list(8).list.head.field2 mustEqual "false" + list(8).list(9).unk mustEqual 432 + list(8).list(9).list.length mustEqual 1 + list(8).list(9).list.head.field1 mustEqual "allowed" + list(8).list(9).list.head.field2 mustEqual "false" + list(8).list(10).unk mustEqual 441 + list(8).list(10).list.length mustEqual 1 + list(8).list(10).list.head.field1 mustEqual "allowed" + list(8).list(10).list.head.field2 mustEqual "false" + list(8).list(11).unk mustEqual 462 + list(8).list(11).list.length mustEqual 1 + list(8).list(11).list.head.field1 mustEqual "allowed" + list(8).list(11).list.head.field2 mustEqual "false" + list(8).list(12).unk mustEqual 470 + list(8).list(12).list.length mustEqual 1 + list(8).list(12).list.head.field1 mustEqual "allowed" + list(8).list(12).list.head.field2 mustEqual "false" + list(8).list(13).unk mustEqual 556 + list(8).list(13).list.length mustEqual 1 + list(8).list(13).list.head.field1 mustEqual "allowed" + list(8).list(13).list.head.field2 mustEqual "false" + list(8).list(14).unk mustEqual 642 + list(8).list(14).list.length mustEqual 1 + list(8).list(14).list.head.field1 mustEqual "allowed" + list(8).list(14).list.head.field2 mustEqual "false" + list(8).list(15).unk mustEqual 643 + list(8).list(15).list.length mustEqual 1 + list(8).list(15).list.head.field1 mustEqual "allowed" + list(8).list(15).list.head.field2 mustEqual "false" + list(8).list(16).unk mustEqual 697 + list(8).list(16).list.length mustEqual 1 + list(8).list(16).list.head.field1 mustEqual "allowed" + list(8).list(16).list.head.field2 mustEqual "false" + list(8).list(17).unk mustEqual 714 + list(8).list(17).list.length mustEqual 1 + list(8).list(17).list.head.field1 mustEqual "allowed" + list(8).list(17).list.head.field2 mustEqual "false" + list(8).list(18).unk mustEqual 865 + list(8).list(18).list.length mustEqual 1 + list(8).list(18).list.head.field1 mustEqual "allowed" + list(8).list(18).list.head.field2 mustEqual "false" + list(8).list(19).unk mustEqual 923 + list(8).list(19).list.length mustEqual 1 + list(8).list(19).list.head.field1 mustEqual "allowed" + list(8).list(19).list.head.field2 mustEqual "false" + list(8).list(20).unk mustEqual 986 + list(8).list(20).list.length mustEqual 1 + list(8).list(20).list.head.field1 mustEqual "allowed" + list(8).list(20).list.head.field2 mustEqual "false" + // + list(9).unk mustEqual 31 + list(9).list.length mustEqual 21 + list(9).list.head.unk mustEqual 83 + list(9).list.head.list.length mustEqual 1 + list(9).list.head.list.head.field1 mustEqual "allowed" + list(9).list.head.list.head.field2 mustEqual "false" + list(9).list(1).unk mustEqual 84 + list(9).list(1).list.length mustEqual 1 + list(9).list(1).list.head.field1 mustEqual "allowed" + list(9).list(1).list.head.field2 mustEqual "false" + list(9).list(2).unk mustEqual 118 + list(9).list(2).list.length mustEqual 1 + list(9).list(2).list.head.field1 mustEqual "allowed" + list(9).list(2).list.head.field2 mustEqual "false" + list(9).list(3).unk mustEqual 135 + list(9).list(3).list.length mustEqual 1 + list(9).list(3).list.head.field1 mustEqual "allowed" + list(9).list(3).list.head.field2 mustEqual "false" + list(9).list(4).unk mustEqual 199 + list(9).list(4).list.length mustEqual 1 + list(9).list(4).list.head.field1 mustEqual "allowed" + list(9).list(4).list.head.field2 mustEqual "false" + list(9).list(5).unk mustEqual 200 + list(9).list(5).list.length mustEqual 1 + list(9).list(5).list.head.field1 mustEqual "allowed" + list(9).list(5).list.head.field2 mustEqual "false" + list(9).list(6).unk mustEqual 294 + list(9).list(6).list.length mustEqual 1 + list(9).list(6).list.head.field1 mustEqual "allowed" + list(9).list(6).list.head.field2 mustEqual "false" + list(9).list(7).unk mustEqual 338 + list(9).list(7).list.length mustEqual 1 + list(9).list(7).list.head.field1 mustEqual "allowed" + list(9).list(7).list.head.field2 mustEqual "false" + list(9).list(8).unk mustEqual 429 + list(9).list(8).list.length mustEqual 1 + list(9).list(8).list.head.field1 mustEqual "allowed" + list(9).list(8).list.head.field2 mustEqual "false" + list(9).list(9).unk mustEqual 432 + list(9).list(9).list.length mustEqual 1 + list(9).list(9).list.head.field1 mustEqual "allowed" + list(9).list(9).list.head.field2 mustEqual "false" + list(9).list(10).unk mustEqual 441 + list(9).list(10).list.length mustEqual 1 + list(9).list(10).list.head.field1 mustEqual "allowed" + list(9).list(10).list.head.field2 mustEqual "false" + list(9).list(11).unk mustEqual 462 + list(9).list(11).list.length mustEqual 1 + list(9).list(11).list.head.field1 mustEqual "allowed" + list(9).list(11).list.head.field2 mustEqual "false" + list(9).list(12).unk mustEqual 470 + list(9).list(12).list.length mustEqual 1 + list(9).list(12).list.head.field1 mustEqual "allowed" + list(9).list(12).list.head.field2 mustEqual "false" + list(9).list(13).unk mustEqual 556 + list(9).list(13).list.length mustEqual 1 + list(9).list(13).list.head.field1 mustEqual "allowed" + list(9).list(13).list.head.field2 mustEqual "false" + list(9).list(14).unk mustEqual 642 + list(9).list(14).list.length mustEqual 1 + list(9).list(14).list.head.field1 mustEqual "allowed" + list(9).list(14).list.head.field2 mustEqual "false" + list(9).list(15).unk mustEqual 643 + list(9).list(15).list.length mustEqual 1 + list(9).list(15).list.head.field1 mustEqual "allowed" + list(9).list(15).list.head.field2 mustEqual "false" + list(9).list(16).unk mustEqual 697 + list(9).list(16).list.length mustEqual 1 + list(9).list(16).list.head.field1 mustEqual "allowed" + list(9).list(16).list.head.field2 mustEqual "false" + list(9).list(17).unk mustEqual 714 + list(9).list(17).list.length mustEqual 1 + list(9).list(17).list.head.field1 mustEqual "allowed" + list(9).list(17).list.head.field2 mustEqual "false" + list(9).list(18).unk mustEqual 865 + list(9).list(18).list.length mustEqual 1 + list(9).list(18).list.head.field1 mustEqual "allowed" + list(9).list(18).list.head.field2 mustEqual "false" + list(9).list(19).unk mustEqual 923 + list(9).list(19).list.length mustEqual 1 + list(9).list(19).list.head.field1 mustEqual "allowed" + list(9).list(19).list.head.field2 mustEqual "false" + list(9).list(20).unk mustEqual 986 + list(9).list(20).list.length mustEqual 1 + list(9).list(20).list.head.field1 mustEqual "allowed" + list(9).list(20).list.head.field2 mustEqual "false" + // + list(10).unk mustEqual 32 + list(10).list.length mustEqual 21 + list(10).list.head.unk mustEqual 83 + list(10).list.head.list.length mustEqual 1 + list(10).list.head.list.head.field1 mustEqual "allowed" + list(10).list.head.list.head.field2 mustEqual "false" + list(10).list(1).unk mustEqual 84 + list(10).list(1).list.length mustEqual 1 + list(10).list(1).list.head.field1 mustEqual "allowed" + list(10).list(1).list.head.field2 mustEqual "false" + list(10).list(2).unk mustEqual 118 + list(10).list(2).list.length mustEqual 1 + list(10).list(2).list.head.field1 mustEqual "allowed" + list(10).list(2).list.head.field2 mustEqual "false" + list(10).list(3).unk mustEqual 135 + list(10).list(3).list.length mustEqual 1 + list(10).list(3).list.head.field1 mustEqual "allowed" + list(10).list(3).list.head.field2 mustEqual "false" + list(10).list(4).unk mustEqual 199 + list(10).list(4).list.length mustEqual 1 + list(10).list(4).list.head.field1 mustEqual "allowed" + list(10).list(4).list.head.field2 mustEqual "false" + list(10).list(5).unk mustEqual 200 + list(10).list(5).list.length mustEqual 1 + list(10).list(5).list.head.field1 mustEqual "allowed" + list(10).list(5).list.head.field2 mustEqual "false" + list(10).list(6).unk mustEqual 294 + list(10).list(6).list.length mustEqual 1 + list(10).list(6).list.head.field1 mustEqual "allowed" + list(10).list(6).list.head.field2 mustEqual "false" + list(10).list(7).unk mustEqual 338 + list(10).list(7).list.length mustEqual 1 + list(10).list(7).list.head.field1 mustEqual "allowed" + list(10).list(7).list.head.field2 mustEqual "false" + list(10).list(8).unk mustEqual 429 + list(10).list(8).list.length mustEqual 1 + list(10).list(8).list.head.field1 mustEqual "allowed" + list(10).list(8).list.head.field2 mustEqual "false" + list(10).list(9).unk mustEqual 432 + list(10).list(9).list.length mustEqual 1 + list(10).list(9).list.head.field1 mustEqual "allowed" + list(10).list(9).list.head.field2 mustEqual "false" + list(10).list(10).unk mustEqual 441 + list(10).list(10).list.length mustEqual 1 + list(10).list(10).list.head.field1 mustEqual "allowed" + list(10).list(10).list.head.field2 mustEqual "false" + list(10).list(11).unk mustEqual 462 + list(10).list(11).list.length mustEqual 1 + list(10).list(11).list.head.field1 mustEqual "allowed" + list(10).list(11).list.head.field2 mustEqual "false" + list(10).list(12).unk mustEqual 470 + list(10).list(12).list.length mustEqual 1 + list(10).list(12).list.head.field1 mustEqual "allowed" + list(10).list(12).list.head.field2 mustEqual "false" + list(10).list(13).unk mustEqual 556 + list(10).list(13).list.length mustEqual 1 + list(10).list(13).list.head.field1 mustEqual "allowed" + list(10).list(13).list.head.field2 mustEqual "false" + list(10).list(14).unk mustEqual 642 + list(10).list(14).list.length mustEqual 1 + list(10).list(14).list.head.field1 mustEqual "allowed" + list(10).list(14).list.head.field2 mustEqual "false" + list(10).list(15).unk mustEqual 643 + list(10).list(15).list.length mustEqual 1 + list(10).list(15).list.head.field1 mustEqual "allowed" + list(10).list(15).list.head.field2 mustEqual "false" + list(10).list(16).unk mustEqual 697 + list(10).list(16).list.length mustEqual 1 + list(10).list(16).list.head.field1 mustEqual "allowed" + list(10).list(16).list.head.field2 mustEqual "false" + list(10).list(17).unk mustEqual 714 + list(10).list(17).list.length mustEqual 1 + list(10).list(17).list.head.field1 mustEqual "allowed" + list(10).list(17).list.head.field2 mustEqual "false" + list(10).list(18).unk mustEqual 865 + list(10).list(18).list.length mustEqual 1 + list(10).list(18).list.head.field1 mustEqual "allowed" + list(10).list(18).list.head.field2 mustEqual "false" + list(10).list(19).unk mustEqual 923 + list(10).list(19).list.length mustEqual 1 + list(10).list(19).list.head.field1 mustEqual "allowed" + list(10).list(19).list.head.field2 mustEqual "false" + list(10).list(20).unk mustEqual 986 + list(10).list(20).list.length mustEqual 1 + list(10).list(20).list.head.field1 mustEqual "allowed" + list(10).list(20).list.head.field2 mustEqual "false" case _ => ko } } "encode" in { - ok -// val msg = ProximityTerminalUseMessage(PlanetSideGUID(75), PlanetSideGUID(167), true) -// val pkt = PacketCoding.EncodePacket(msg).require.toByteVector -// pkt mustEqual string + val msg = PropertyOverrideMessage( + List( + GameProperty(0, List( + GamePropertyField(343, List( + GamePropertyValues("purchase_exempt_vs", ""), + GamePropertyValues("purchase_exempt_tr", ""), + GamePropertyValues("purchase_exempt_nc", "") + )) + )), + GameProperty(17, List( + GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(18, List( + GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(19, List( + GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(20, List( + GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(21, List( + GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(22, List( + GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(29, List( + GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(30, List( + GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(31, List( + GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) + )), + GameProperty(32, List( + GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), + GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) + )) + ) + ) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + pkt mustEqual string } } From 86b08390b0bc57f4ffc2fb49c3c1e852291e2f86 Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 9 Aug 2017 09:23:16 -0400 Subject: [PATCH 3/4] changed fields and case class names to reflect purpose; added entries to ObjectClass as needed; made PropertyOverrideMessage encoding much less verbose --- .../packet/game/PropertyOverrideMessage.scala | 99 ++-- .../game/objectcreate/ObjectClass.scala | 14 + .../game/PropertyOverrideMessageTest.scala | 431 +++++++++--------- 3 files changed, 281 insertions(+), 263 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala b/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala index 1aab5e3c..b7419ce9 100644 --- a/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala @@ -6,49 +6,52 @@ import scodec.Codec import scodec.codecs._ import shapeless.{::, HNil} -final case class PropertyOverrideMessage(list : List[PropertyOverrideMessage.GameProperty]) +final case class PropertyOverrideMessage(list : List[PropertyOverrideMessage.GamePropertyScope]) extends PlanetSideGamePacket { type Packet = PropertyOverrideMessage def opcode = GamePacketOpcode.PropertyOverrideMessage def encode = PropertyOverrideMessage.encode(this) } -object GamePropertyValues { - def apply(field1 : String) : PropertyOverrideMessage.GamePropertyValues = { - PropertyOverrideMessage.GamePropertyValues(field1, "") +object GamePropertyTarget { + final val game_properties : Int = 343 + + def apply(target : Int) : PropertyOverrideMessage.GamePropertyTarget = { + PropertyOverrideMessage.GamePropertyTarget(target, Nil) } - def apply(field1 : String, field2 : String) : PropertyOverrideMessage.GamePropertyValues = { - PropertyOverrideMessage.GamePropertyValues(field1, field2) + def apply(target : Int, kv : (String, String)) : PropertyOverrideMessage.GamePropertyTarget = { + PropertyOverrideMessage.GamePropertyTarget(target, PropertyOverrideMessage.GamePropertyValues(kv._1, kv._2) :: Nil) + } + + def apply(target : Int, list : List[(String, String)]) : PropertyOverrideMessage.GamePropertyTarget = { + PropertyOverrideMessage.GamePropertyTarget(target, list.map({ + case(key, value) => + PropertyOverrideMessage.GamePropertyValues(key, value) + })) } } -object GamePropertyField { - def apply(unk : Int) : PropertyOverrideMessage.GamePropertyField = { - PropertyOverrideMessage.GamePropertyField(unk, Nil) +object GamePropertyScope { + def apply(zone : Int, list : PropertyOverrideMessage.GamePropertyTarget) : PropertyOverrideMessage.GamePropertyScope = { + PropertyOverrideMessage.GamePropertyScope(zone, list :: Nil) } - def apply(unk : Int, list : List[PropertyOverrideMessage.GamePropertyValues]) : PropertyOverrideMessage.GamePropertyField = { - PropertyOverrideMessage.GamePropertyField(unk, list) - } -} - -object GameProperty { - def apply(unk : Int) : PropertyOverrideMessage.GameProperty = { - PropertyOverrideMessage.GameProperty(unk, Nil) - } - - def apply(unk : Int, list : List[PropertyOverrideMessage.GamePropertyField]) : PropertyOverrideMessage.GameProperty = { - PropertyOverrideMessage.GameProperty(unk, list) + def apply(zone : Int, list : List[PropertyOverrideMessage.GamePropertyTarget]) : PropertyOverrideMessage.GamePropertyScope = { + PropertyOverrideMessage.GamePropertyScope(zone, list) } } object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { final case class GamePropertyValues(field1 : String, field2 : String) - final case class GamePropertyField(unk : Int, list : List[GamePropertyValues]) + final case class GamePropertyTarget(target : Int, list : List[GamePropertyValues]) - final case class GameProperty(unk : Int, list : List[GamePropertyField]) + final case class GamePropertyScope(zone : Int, list : List[GamePropertyTarget]) + + def apply(list : PropertyOverrideMessage.GamePropertyScope) : PropertyOverrideMessage = { + PropertyOverrideMessage(list :: Nil) + } private def value_pair_aligned_codec(n : Int) : Codec[GamePropertyValues] = ( ("field1" | PacketHelpers.encodedStringAligned(n)) :: @@ -60,56 +63,56 @@ object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { ("field2" | PacketHelpers.encodedString) ).as[GamePropertyValues] - private def game_subproperty_codec(n : Int) : Codec[GamePropertyField] = ( - ("unk" | uintL(11)) :: - (("len" | uint16L) >>:~ { len => + private def game_property_target_codec(n : Int) : Codec[GamePropertyTarget] = ( + ("target" | uintL(11)) :: + (uint16L >>:~ { len => conditional(len > 0, value_pair_aligned_codec(n)) :: conditional(len > 1, PacketHelpers.listOfNSized((len - 1).toLong, value_pair_codec)) }) - ).xmap[GamePropertyField] ( + ).xmap[GamePropertyTarget] ( { - case unk :: _ :: Some(first) :: None :: HNil => - GamePropertyField(unk, first :: Nil) + case target :: _ :: Some(first) :: None :: HNil => + GamePropertyTarget(target, first :: Nil) - case unk :: _ :: Some(first) :: Some(other) :: HNil => - GamePropertyField(unk, first +: other) + case target :: _ :: Some(first) :: Some(other) :: HNil => + GamePropertyTarget(target, first +: other) }, { - case GamePropertyField(unk, list) => + case GamePropertyTarget(target, list) => val (first, other) = list match { case ((f : GamePropertyValues) +: (rest : List[GamePropertyValues])) => (Some(f), Some(rest)) case (f : GamePropertyValues) +: Nil => (Some(f), None) case Nil => (None, None) } - unk :: list.length :: first :: other :: HNil + target :: list.length :: first :: other :: HNil } ) - private val game_property_codec : Codec[GameProperty] = ( - ("unk" | uint16L) :: - (("len" | uintL(11)) >>:~ { len => - conditional(len > 0, game_subproperty_codec(2)) :: - conditional(len > 1, PacketHelpers.listOfNSized((len - 1).toLong, game_subproperty_codec(5))) + private val game_property_scope_codec : Codec[GamePropertyScope] = ( + ("zone" | uint16L) :: + (uintL(11) >>:~ { len => + conditional(len > 0, game_property_target_codec(2)) :: + conditional(len > 1, PacketHelpers.listOfNSized((len - 1).toLong, game_property_target_codec(5))) }) - ).xmap[GameProperty] ( + ).xmap[GamePropertyScope] ( { - case unk :: _ :: Some(first) :: None :: HNil => - GameProperty(unk, first :: Nil) + case zone :: _ :: Some(first) :: None :: HNil => + GamePropertyScope(zone, first :: Nil) - case unk :: _ :: Some(first) :: Some(other) :: HNil => - GameProperty(unk, first +: other) + case zone :: _ :: Some(first) :: Some(other) :: HNil => + GamePropertyScope(zone, first +: other) }, { - case GameProperty(unk, list) => + case GamePropertyScope(zone, list) => val (first, other) = list match { - case ((f : GamePropertyField) +: (rest : List[GamePropertyField])) => (Some(f), Some(rest)) - case (f : GamePropertyField) +: Nil => (Some(f), None) + case ((f : GamePropertyTarget) +: (rest : List[GamePropertyTarget])) => (Some(f), Some(rest)) + case (f : GamePropertyTarget) +: Nil => (Some(f), None) case Nil => (None, None) } - unk :: list.length :: first :: other :: HNil + zone :: list.length :: first :: other :: HNil } ) implicit val codec : Codec[PropertyOverrideMessage] = - listOfN(uint16L, game_property_codec).as[PropertyOverrideMessage] + listOfN(uint16L, game_property_scope_codec).as[PropertyOverrideMessage] } diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala index 030def3d..53de8257 100644 --- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala +++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala @@ -304,15 +304,27 @@ object ObjectClass { final val ams_destroyed = 47 final val ant = 60 final val ant_destroyed = 61 + final val aphelion_flight = 83 + final val aphelion_gunner = 84 final val aurora = 118 final val battlewagon = 135 //raider + final val colossus_flight = 199 + final val colossus_gunner = 200 final val droppod = 258 + final val flail = 294 final val fury = 335 + final val galaxy_gunship = 338 + final val liberator = 432 + final val lightgunship = 441 final val lightning = 446 final val lightning_destroyed = 447 + final val magrider = 470 final val mediumtransport = 532 final val mediumtransport_destroyed = 533 final val orbital_shuttle = 608 + final val peregrine_flight = 642 + final val peregrine_gunner = 643 + final val prowler = 697 final val quadassault = 707 final val quadassault_destroyed = 708 final val quadstealth = 710 @@ -328,6 +340,8 @@ object ObjectClass { final val twomanheavybuggy_destroyed = 899 final val twomanhoverbuggy = 900 //thresher final val twomanhoverbuggy_destroyed = 901 + final val vanguard = 923 + final val vulture = 986 //other final val ams_respawn_tube = 49 final val avatar = 121 diff --git a/common/src/test/scala/game/PropertyOverrideMessageTest.scala b/common/src/test/scala/game/PropertyOverrideMessageTest.scala index 3145f3b4..bf4c22dd 100644 --- a/common/src/test/scala/game/PropertyOverrideMessageTest.scala +++ b/common/src/test/scala/game/PropertyOverrideMessageTest.scala @@ -3,7 +3,8 @@ package game import org.specs2.mutable._ import net.psforever.packet._ -import net.psforever.packet.game.{GamePropertyField, _} +import net.psforever.packet.game._ +import net.psforever.packet.game.objectcreate.ObjectClass import scodec.bits._ class PropertyOverrideMessageTest extends Specification { @@ -14,9 +15,9 @@ class PropertyOverrideMessageTest extends Specification { case PropertyOverrideMessage(list) => list.length mustEqual 11 // - list.head.unk mustEqual 0 + list.head.zone mustEqual 0 list.head.list.length mustEqual 1 - list.head.list.head.unk mustEqual 343 + list.head.list.head.target mustEqual 343 list.head.list.head.list.length mustEqual 3 list.head.list.head.list.head.field1 mustEqual "purchase_exempt_vs" list.head.list.head.list.head.field2 mustEqual "" @@ -25,392 +26,392 @@ class PropertyOverrideMessageTest extends Specification { list.head.list.head.list(2).field1 mustEqual "purchase_exempt_nc" list.head.list.head.list(2).field2 mustEqual "" // - list(1).unk mustEqual 17 + list(1).zone mustEqual 17 list(1).list.length mustEqual 1 - list(1).list.head.unk mustEqual 421 + list(1).list.head.target mustEqual 421 list(1).list.head.list.length mustEqual 1 list(1).list.head.list.head.field1 mustEqual "allowed" list(1).list.head.list.head.field2 mustEqual "false" // - list(2).unk mustEqual 18 + list(2).zone mustEqual 18 list(2).list.length mustEqual 1 - list(2).list.head.unk mustEqual 421 + list(2).list.head.target mustEqual 421 list(2).list.head.list.length mustEqual 1 list(2).list.head.list.head.field1 mustEqual "allowed" list(2).list.head.list.head.field2 mustEqual "false" // - list(3).unk mustEqual 19 + list(3).zone mustEqual 19 list(3).list.length mustEqual 1 - list(3).list.head.unk mustEqual 421 + list(3).list.head.target mustEqual 421 list(3).list.head.list.length mustEqual 1 list(3).list.head.list.head.field1 mustEqual "allowed" list(3).list.head.list.head.field2 mustEqual "false" // - list(4).unk mustEqual 20 + list(4).zone mustEqual 20 list(4).list.length mustEqual 1 - list(4).list.head.unk mustEqual 421 + list(4).list.head.target mustEqual 421 list(4).list.head.list.length mustEqual 1 list(4).list.head.list.head.field1 mustEqual "allowed" list(4).list.head.list.head.field2 mustEqual "false" // - list(5).unk mustEqual 21 + list(5).zone mustEqual 21 list(5).list.length mustEqual 1 - list(5).list.head.unk mustEqual 421 + list(5).list.head.target mustEqual 421 list(5).list.head.list.length mustEqual 1 list(5).list.head.list.head.field1 mustEqual "allowed" list(5).list.head.list.head.field2 mustEqual "false" // - list(6).unk mustEqual 22 + list(6).zone mustEqual 22 list(6).list.length mustEqual 1 - list(6).list.head.unk mustEqual 421 + list(6).list.head.target mustEqual 421 list(6).list.head.list.length mustEqual 1 list(6).list.head.list.head.field1 mustEqual "allowed" list(6).list.head.list.head.field2 mustEqual "false" // - list(7).unk mustEqual 29 + list(7).zone mustEqual 29 list(7).list.length mustEqual 21 - list(7).list.head.unk mustEqual 83 + list(7).list.head.target mustEqual 83 list(7).list.head.list.length mustEqual 1 list(7).list.head.list.head.field1 mustEqual "allowed" list(7).list.head.list.head.field2 mustEqual "false" - list(7).list(1).unk mustEqual 84 + list(7).list(1).target mustEqual 84 list(7).list(1).list.length mustEqual 1 list(7).list(1).list.head.field1 mustEqual "allowed" list(7).list(1).list.head.field2 mustEqual "false" - list(7).list(2).unk mustEqual 118 + list(7).list(2).target mustEqual 118 list(7).list(2).list.length mustEqual 1 list(7).list(2).list.head.field1 mustEqual "allowed" list(7).list(2).list.head.field2 mustEqual "false" - list(7).list(3).unk mustEqual 135 + list(7).list(3).target mustEqual 135 list(7).list(3).list.length mustEqual 1 list(7).list(3).list.head.field1 mustEqual "allowed" list(7).list(3).list.head.field2 mustEqual "false" - list(7).list(4).unk mustEqual 199 + list(7).list(4).target mustEqual 199 list(7).list(4).list.length mustEqual 1 list(7).list(4).list.head.field1 mustEqual "allowed" list(7).list(4).list.head.field2 mustEqual "false" - list(7).list(5).unk mustEqual 200 + list(7).list(5).target mustEqual 200 list(7).list(5).list.length mustEqual 1 list(7).list(5).list.head.field1 mustEqual "allowed" list(7).list(5).list.head.field2 mustEqual "false" - list(7).list(6).unk mustEqual 294 + list(7).list(6).target mustEqual 294 list(7).list(6).list.length mustEqual 1 list(7).list(6).list.head.field1 mustEqual "allowed" list(7).list(6).list.head.field2 mustEqual "false" - list(7).list(7).unk mustEqual 338 + list(7).list(7).target mustEqual 338 list(7).list(7).list.length mustEqual 1 list(7).list(7).list.head.field1 mustEqual "allowed" list(7).list(7).list.head.field2 mustEqual "false" - list(7).list(8).unk mustEqual 429 + list(7).list(8).target mustEqual 429 list(7).list(8).list.length mustEqual 1 list(7).list(8).list.head.field1 mustEqual "allowed" list(7).list(8).list.head.field2 mustEqual "false" - list(7).list(9).unk mustEqual 432 + list(7).list(9).target mustEqual 432 list(7).list(9).list.length mustEqual 1 list(7).list(9).list.head.field1 mustEqual "allowed" list(7).list(9).list.head.field2 mustEqual "false" - list(7).list(10).unk mustEqual 441 + list(7).list(10).target mustEqual 441 list(7).list(10).list.length mustEqual 1 list(7).list(10).list.head.field1 mustEqual "allowed" list(7).list(10).list.head.field2 mustEqual "false" - list(7).list(11).unk mustEqual 462 + list(7).list(11).target mustEqual 462 list(7).list(11).list.length mustEqual 1 list(7).list(11).list.head.field1 mustEqual "allowed" list(7).list(11).list.head.field2 mustEqual "false" - list(7).list(12).unk mustEqual 470 + list(7).list(12).target mustEqual 470 list(7).list(12).list.length mustEqual 1 list(7).list(12).list.head.field1 mustEqual "allowed" list(7).list(12).list.head.field2 mustEqual "false" - list(7).list(13).unk mustEqual 556 + list(7).list(13).target mustEqual 556 list(7).list(13).list.length mustEqual 1 list(7).list(13).list.head.field1 mustEqual "allowed" list(7).list(13).list.head.field2 mustEqual "false" - list(7).list(14).unk mustEqual 642 + list(7).list(14).target mustEqual 642 list(7).list(14).list.length mustEqual 1 list(7).list(14).list.head.field1 mustEqual "allowed" list(7).list(14).list.head.field2 mustEqual "false" - list(7).list(15).unk mustEqual 643 + list(7).list(15).target mustEqual 643 list(7).list(15).list.length mustEqual 1 list(7).list(15).list.head.field1 mustEqual "allowed" list(7).list(15).list.head.field2 mustEqual "false" - list(7).list(16).unk mustEqual 697 + list(7).list(16).target mustEqual 697 list(7).list(16).list.length mustEqual 1 list(7).list(16).list.head.field1 mustEqual "allowed" list(7).list(16).list.head.field2 mustEqual "false" - list(7).list(17).unk mustEqual 714 + list(7).list(17).target mustEqual 714 list(7).list(17).list.length mustEqual 1 list(7).list(17).list.head.field1 mustEqual "allowed" list(7).list(17).list.head.field2 mustEqual "false" - list(7).list(18).unk mustEqual 865 + list(7).list(18).target mustEqual 865 list(7).list(18).list.length mustEqual 1 list(7).list(18).list.head.field1 mustEqual "allowed" list(7).list(18).list.head.field2 mustEqual "false" - list(7).list(19).unk mustEqual 923 + list(7).list(19).target mustEqual 923 list(7).list(19).list.length mustEqual 1 list(7).list(19).list.head.field1 mustEqual "allowed" list(7).list(19).list.head.field2 mustEqual "false" - list(7).list(20).unk mustEqual 986 + list(7).list(20).target mustEqual 986 list(7).list(20).list.length mustEqual 1 list(7).list(20).list.head.field1 mustEqual "allowed" list(7).list(20).list.head.field2 mustEqual "false" // - list(8).unk mustEqual 30 + list(8).zone mustEqual 30 list(8).list.length mustEqual 21 - list(7).list.head.unk mustEqual 83 + list(7).list.head.target mustEqual 83 list(8).list.head.list.length mustEqual 1 list(8).list.head.list.head.field1 mustEqual "allowed" list(8).list.head.list.head.field2 mustEqual "false" - list(8).list(1).unk mustEqual 84 + list(8).list(1).target mustEqual 84 list(8).list(1).list.length mustEqual 1 list(8).list(1).list.head.field1 mustEqual "allowed" list(8).list(1).list.head.field2 mustEqual "false" - list(8).list(2).unk mustEqual 118 + list(8).list(2).target mustEqual 118 list(8).list(2).list.length mustEqual 1 list(8).list(2).list.head.field1 mustEqual "allowed" list(8).list(2).list.head.field2 mustEqual "false" - list(8).list(3).unk mustEqual 135 + list(8).list(3).target mustEqual 135 list(8).list(3).list.length mustEqual 1 list(8).list(3).list.head.field1 mustEqual "allowed" list(8).list(3).list.head.field2 mustEqual "false" - list(8).list(4).unk mustEqual 199 + list(8).list(4).target mustEqual 199 list(8).list(4).list.length mustEqual 1 list(8).list(4).list.head.field1 mustEqual "allowed" list(8).list(4).list.head.field2 mustEqual "false" - list(8).list(5).unk mustEqual 200 + list(8).list(5).target mustEqual 200 list(8).list(5).list.length mustEqual 1 list(8).list(5).list.head.field1 mustEqual "allowed" list(8).list(5).list.head.field2 mustEqual "false" - list(8).list(6).unk mustEqual 294 + list(8).list(6).target mustEqual 294 list(8).list(6).list.length mustEqual 1 list(8).list(6).list.head.field1 mustEqual "allowed" list(8).list(6).list.head.field2 mustEqual "false" - list(8).list(7).unk mustEqual 338 + list(8).list(7).target mustEqual 338 list(8).list(7).list.length mustEqual 1 list(8).list(7).list.head.field1 mustEqual "allowed" list(8).list(7).list.head.field2 mustEqual "false" - list(8).list(8).unk mustEqual 429 + list(8).list(8).target mustEqual 429 list(8).list(8).list.length mustEqual 1 list(8).list(8).list.head.field1 mustEqual "allowed" list(8).list(8).list.head.field2 mustEqual "false" - list(8).list(9).unk mustEqual 432 + list(8).list(9).target mustEqual 432 list(8).list(9).list.length mustEqual 1 list(8).list(9).list.head.field1 mustEqual "allowed" list(8).list(9).list.head.field2 mustEqual "false" - list(8).list(10).unk mustEqual 441 + list(8).list(10).target mustEqual 441 list(8).list(10).list.length mustEqual 1 list(8).list(10).list.head.field1 mustEqual "allowed" list(8).list(10).list.head.field2 mustEqual "false" - list(8).list(11).unk mustEqual 462 + list(8).list(11).target mustEqual 462 list(8).list(11).list.length mustEqual 1 list(8).list(11).list.head.field1 mustEqual "allowed" list(8).list(11).list.head.field2 mustEqual "false" - list(8).list(12).unk mustEqual 470 + list(8).list(12).target mustEqual 470 list(8).list(12).list.length mustEqual 1 list(8).list(12).list.head.field1 mustEqual "allowed" list(8).list(12).list.head.field2 mustEqual "false" - list(8).list(13).unk mustEqual 556 + list(8).list(13).target mustEqual 556 list(8).list(13).list.length mustEqual 1 list(8).list(13).list.head.field1 mustEqual "allowed" list(8).list(13).list.head.field2 mustEqual "false" - list(8).list(14).unk mustEqual 642 + list(8).list(14).target mustEqual 642 list(8).list(14).list.length mustEqual 1 list(8).list(14).list.head.field1 mustEqual "allowed" list(8).list(14).list.head.field2 mustEqual "false" - list(8).list(15).unk mustEqual 643 + list(8).list(15).target mustEqual 643 list(8).list(15).list.length mustEqual 1 list(8).list(15).list.head.field1 mustEqual "allowed" list(8).list(15).list.head.field2 mustEqual "false" - list(8).list(16).unk mustEqual 697 + list(8).list(16).target mustEqual 697 list(8).list(16).list.length mustEqual 1 list(8).list(16).list.head.field1 mustEqual "allowed" list(8).list(16).list.head.field2 mustEqual "false" - list(8).list(17).unk mustEqual 714 + list(8).list(17).target mustEqual 714 list(8).list(17).list.length mustEqual 1 list(8).list(17).list.head.field1 mustEqual "allowed" list(8).list(17).list.head.field2 mustEqual "false" - list(8).list(18).unk mustEqual 865 + list(8).list(18).target mustEqual 865 list(8).list(18).list.length mustEqual 1 list(8).list(18).list.head.field1 mustEqual "allowed" list(8).list(18).list.head.field2 mustEqual "false" - list(8).list(19).unk mustEqual 923 + list(8).list(19).target mustEqual 923 list(8).list(19).list.length mustEqual 1 list(8).list(19).list.head.field1 mustEqual "allowed" list(8).list(19).list.head.field2 mustEqual "false" - list(8).list(20).unk mustEqual 986 + list(8).list(20).target mustEqual 986 list(8).list(20).list.length mustEqual 1 list(8).list(20).list.head.field1 mustEqual "allowed" list(8).list(20).list.head.field2 mustEqual "false" // - list(9).unk mustEqual 31 + list(9).zone mustEqual 31 list(9).list.length mustEqual 21 - list(9).list.head.unk mustEqual 83 + list(9).list.head.target mustEqual 83 list(9).list.head.list.length mustEqual 1 list(9).list.head.list.head.field1 mustEqual "allowed" list(9).list.head.list.head.field2 mustEqual "false" - list(9).list(1).unk mustEqual 84 + list(9).list(1).target mustEqual 84 list(9).list(1).list.length mustEqual 1 list(9).list(1).list.head.field1 mustEqual "allowed" list(9).list(1).list.head.field2 mustEqual "false" - list(9).list(2).unk mustEqual 118 + list(9).list(2).target mustEqual 118 list(9).list(2).list.length mustEqual 1 list(9).list(2).list.head.field1 mustEqual "allowed" list(9).list(2).list.head.field2 mustEqual "false" - list(9).list(3).unk mustEqual 135 + list(9).list(3).target mustEqual 135 list(9).list(3).list.length mustEqual 1 list(9).list(3).list.head.field1 mustEqual "allowed" list(9).list(3).list.head.field2 mustEqual "false" - list(9).list(4).unk mustEqual 199 + list(9).list(4).target mustEqual 199 list(9).list(4).list.length mustEqual 1 list(9).list(4).list.head.field1 mustEqual "allowed" list(9).list(4).list.head.field2 mustEqual "false" - list(9).list(5).unk mustEqual 200 + list(9).list(5).target mustEqual 200 list(9).list(5).list.length mustEqual 1 list(9).list(5).list.head.field1 mustEqual "allowed" list(9).list(5).list.head.field2 mustEqual "false" - list(9).list(6).unk mustEqual 294 + list(9).list(6).target mustEqual 294 list(9).list(6).list.length mustEqual 1 list(9).list(6).list.head.field1 mustEqual "allowed" list(9).list(6).list.head.field2 mustEqual "false" - list(9).list(7).unk mustEqual 338 + list(9).list(7).target mustEqual 338 list(9).list(7).list.length mustEqual 1 list(9).list(7).list.head.field1 mustEqual "allowed" list(9).list(7).list.head.field2 mustEqual "false" - list(9).list(8).unk mustEqual 429 + list(9).list(8).target mustEqual 429 list(9).list(8).list.length mustEqual 1 list(9).list(8).list.head.field1 mustEqual "allowed" list(9).list(8).list.head.field2 mustEqual "false" - list(9).list(9).unk mustEqual 432 + list(9).list(9).target mustEqual 432 list(9).list(9).list.length mustEqual 1 list(9).list(9).list.head.field1 mustEqual "allowed" list(9).list(9).list.head.field2 mustEqual "false" - list(9).list(10).unk mustEqual 441 + list(9).list(10).target mustEqual 441 list(9).list(10).list.length mustEqual 1 list(9).list(10).list.head.field1 mustEqual "allowed" list(9).list(10).list.head.field2 mustEqual "false" - list(9).list(11).unk mustEqual 462 + list(9).list(11).target mustEqual 462 list(9).list(11).list.length mustEqual 1 list(9).list(11).list.head.field1 mustEqual "allowed" list(9).list(11).list.head.field2 mustEqual "false" - list(9).list(12).unk mustEqual 470 + list(9).list(12).target mustEqual 470 list(9).list(12).list.length mustEqual 1 list(9).list(12).list.head.field1 mustEqual "allowed" list(9).list(12).list.head.field2 mustEqual "false" - list(9).list(13).unk mustEqual 556 + list(9).list(13).target mustEqual 556 list(9).list(13).list.length mustEqual 1 list(9).list(13).list.head.field1 mustEqual "allowed" list(9).list(13).list.head.field2 mustEqual "false" - list(9).list(14).unk mustEqual 642 + list(9).list(14).target mustEqual 642 list(9).list(14).list.length mustEqual 1 list(9).list(14).list.head.field1 mustEqual "allowed" list(9).list(14).list.head.field2 mustEqual "false" - list(9).list(15).unk mustEqual 643 + list(9).list(15).target mustEqual 643 list(9).list(15).list.length mustEqual 1 list(9).list(15).list.head.field1 mustEqual "allowed" list(9).list(15).list.head.field2 mustEqual "false" - list(9).list(16).unk mustEqual 697 + list(9).list(16).target mustEqual 697 list(9).list(16).list.length mustEqual 1 list(9).list(16).list.head.field1 mustEqual "allowed" list(9).list(16).list.head.field2 mustEqual "false" - list(9).list(17).unk mustEqual 714 + list(9).list(17).target mustEqual 714 list(9).list(17).list.length mustEqual 1 list(9).list(17).list.head.field1 mustEqual "allowed" list(9).list(17).list.head.field2 mustEqual "false" - list(9).list(18).unk mustEqual 865 + list(9).list(18).target mustEqual 865 list(9).list(18).list.length mustEqual 1 list(9).list(18).list.head.field1 mustEqual "allowed" list(9).list(18).list.head.field2 mustEqual "false" - list(9).list(19).unk mustEqual 923 + list(9).list(19).target mustEqual 923 list(9).list(19).list.length mustEqual 1 list(9).list(19).list.head.field1 mustEqual "allowed" list(9).list(19).list.head.field2 mustEqual "false" - list(9).list(20).unk mustEqual 986 + list(9).list(20).target mustEqual 986 list(9).list(20).list.length mustEqual 1 list(9).list(20).list.head.field1 mustEqual "allowed" list(9).list(20).list.head.field2 mustEqual "false" // - list(10).unk mustEqual 32 + list(10).zone mustEqual 32 list(10).list.length mustEqual 21 - list(10).list.head.unk mustEqual 83 + list(10).list.head.target mustEqual 83 list(10).list.head.list.length mustEqual 1 list(10).list.head.list.head.field1 mustEqual "allowed" list(10).list.head.list.head.field2 mustEqual "false" - list(10).list(1).unk mustEqual 84 + list(10).list(1).target mustEqual 84 list(10).list(1).list.length mustEqual 1 list(10).list(1).list.head.field1 mustEqual "allowed" list(10).list(1).list.head.field2 mustEqual "false" - list(10).list(2).unk mustEqual 118 + list(10).list(2).target mustEqual 118 list(10).list(2).list.length mustEqual 1 list(10).list(2).list.head.field1 mustEqual "allowed" list(10).list(2).list.head.field2 mustEqual "false" - list(10).list(3).unk mustEqual 135 + list(10).list(3).target mustEqual 135 list(10).list(3).list.length mustEqual 1 list(10).list(3).list.head.field1 mustEqual "allowed" list(10).list(3).list.head.field2 mustEqual "false" - list(10).list(4).unk mustEqual 199 + list(10).list(4).target mustEqual 199 list(10).list(4).list.length mustEqual 1 list(10).list(4).list.head.field1 mustEqual "allowed" list(10).list(4).list.head.field2 mustEqual "false" - list(10).list(5).unk mustEqual 200 + list(10).list(5).target mustEqual 200 list(10).list(5).list.length mustEqual 1 list(10).list(5).list.head.field1 mustEqual "allowed" list(10).list(5).list.head.field2 mustEqual "false" - list(10).list(6).unk mustEqual 294 + list(10).list(6).target mustEqual 294 list(10).list(6).list.length mustEqual 1 list(10).list(6).list.head.field1 mustEqual "allowed" list(10).list(6).list.head.field2 mustEqual "false" - list(10).list(7).unk mustEqual 338 + list(10).list(7).target mustEqual 338 list(10).list(7).list.length mustEqual 1 list(10).list(7).list.head.field1 mustEqual "allowed" list(10).list(7).list.head.field2 mustEqual "false" - list(10).list(8).unk mustEqual 429 + list(10).list(8).target mustEqual 429 list(10).list(8).list.length mustEqual 1 list(10).list(8).list.head.field1 mustEqual "allowed" list(10).list(8).list.head.field2 mustEqual "false" - list(10).list(9).unk mustEqual 432 + list(10).list(9).target mustEqual 432 list(10).list(9).list.length mustEqual 1 list(10).list(9).list.head.field1 mustEqual "allowed" list(10).list(9).list.head.field2 mustEqual "false" - list(10).list(10).unk mustEqual 441 + list(10).list(10).target mustEqual 441 list(10).list(10).list.length mustEqual 1 list(10).list(10).list.head.field1 mustEqual "allowed" list(10).list(10).list.head.field2 mustEqual "false" - list(10).list(11).unk mustEqual 462 + list(10).list(11).target mustEqual 462 list(10).list(11).list.length mustEqual 1 list(10).list(11).list.head.field1 mustEqual "allowed" list(10).list(11).list.head.field2 mustEqual "false" - list(10).list(12).unk mustEqual 470 + list(10).list(12).target mustEqual 470 list(10).list(12).list.length mustEqual 1 list(10).list(12).list.head.field1 mustEqual "allowed" list(10).list(12).list.head.field2 mustEqual "false" - list(10).list(13).unk mustEqual 556 + list(10).list(13).target mustEqual 556 list(10).list(13).list.length mustEqual 1 list(10).list(13).list.head.field1 mustEqual "allowed" list(10).list(13).list.head.field2 mustEqual "false" - list(10).list(14).unk mustEqual 642 + list(10).list(14).target mustEqual 642 list(10).list(14).list.length mustEqual 1 list(10).list(14).list.head.field1 mustEqual "allowed" list(10).list(14).list.head.field2 mustEqual "false" - list(10).list(15).unk mustEqual 643 + list(10).list(15).target mustEqual 643 list(10).list(15).list.length mustEqual 1 list(10).list(15).list.head.field1 mustEqual "allowed" list(10).list(15).list.head.field2 mustEqual "false" - list(10).list(16).unk mustEqual 697 + list(10).list(16).target mustEqual 697 list(10).list(16).list.length mustEqual 1 list(10).list(16).list.head.field1 mustEqual "allowed" list(10).list(16).list.head.field2 mustEqual "false" - list(10).list(17).unk mustEqual 714 + list(10).list(17).target mustEqual 714 list(10).list(17).list.length mustEqual 1 list(10).list(17).list.head.field1 mustEqual "allowed" list(10).list(17).list.head.field2 mustEqual "false" - list(10).list(18).unk mustEqual 865 + list(10).list(18).target mustEqual 865 list(10).list(18).list.length mustEqual 1 list(10).list(18).list.head.field1 mustEqual "allowed" list(10).list(18).list.head.field2 mustEqual "false" - list(10).list(19).unk mustEqual 923 + list(10).list(19).target mustEqual 923 list(10).list(19).list.length mustEqual 1 list(10).list(19).list.head.field1 mustEqual "allowed" list(10).list(19).list.head.field2 mustEqual "false" - list(10).list(20).unk mustEqual 986 + list(10).list(20).target mustEqual 986 list(10).list(20).list.length mustEqual 1 list(10).list(20).list.head.field1 mustEqual "allowed" list(10).list(20).list.head.field2 mustEqual "false" @@ -422,122 +423,122 @@ class PropertyOverrideMessageTest extends Specification { "encode" in { val msg = PropertyOverrideMessage( List( - GameProperty(0, List( - GamePropertyField(343, List( - GamePropertyValues("purchase_exempt_vs", ""), - GamePropertyValues("purchase_exempt_tr", ""), - GamePropertyValues("purchase_exempt_nc", "") - )) + GamePropertyScope(0, + GamePropertyTarget(GamePropertyTarget.game_properties, List( + "purchase_exempt_vs" -> "", + "purchase_exempt_tr" -> "", + "purchase_exempt_nc" -> "" + ) )), - GameProperty(17, List( - GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + GamePropertyScope(17, + GamePropertyTarget(ObjectClass.katana, "allowed" -> "false") + ), + GamePropertyScope(18, + GamePropertyTarget(ObjectClass.katana, "allowed" -> "false") + ), + GamePropertyScope(19, + GamePropertyTarget(ObjectClass.katana, "allowed" -> "false") + ), + GamePropertyScope(20, + GamePropertyTarget(ObjectClass.katana, "allowed" -> "false") + ), + GamePropertyScope(21, + GamePropertyTarget(ObjectClass.katana, "allowed" -> "false") + ), + GamePropertyScope(22, + GamePropertyTarget(ObjectClass.katana, "allowed" -> "false") + ), + GamePropertyScope(29, List( + GamePropertyTarget(ObjectClass.aphelion_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aphelion_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aurora, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.battlewagon, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.flail, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.galaxy_gunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lasher, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.liberator, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lightgunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.maelstrom, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.magrider, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.mini_chaingun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.prowler, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.r_shotgun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.thunderer, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vanguard, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vulture, "allowed" -> "false") )), - GameProperty(18, List( - GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + GamePropertyScope(30, List( + GamePropertyTarget(ObjectClass.aphelion_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aphelion_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aurora, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.battlewagon, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.flail, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.galaxy_gunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lasher, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.liberator, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lightgunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.maelstrom, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.magrider, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.mini_chaingun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.prowler, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.r_shotgun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.thunderer, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vanguard, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vulture, "allowed" -> "false") )), - GameProperty(19, List( - GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) + GamePropertyScope(31, List( + GamePropertyTarget(ObjectClass.aphelion_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aphelion_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aurora, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.battlewagon, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.flail, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.galaxy_gunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lasher, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.liberator, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lightgunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.maelstrom, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.magrider, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.mini_chaingun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.prowler, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.r_shotgun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.thunderer, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vanguard, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vulture, "allowed" -> "false") )), - GameProperty(20, List( - GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) - )), - GameProperty(21, List( - GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) - )), - GameProperty(22, List( - GamePropertyField(421, List(GamePropertyValues("allowed", "false"))) - )), - GameProperty(29, List( - GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) - )), - GameProperty(30, List( - GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) - )), - GameProperty(31, List( - GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) - )), - GameProperty(32, List( - GamePropertyField(83, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(84, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(118, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(135, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(199, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(200, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(294, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(338, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(429, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(432, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(441, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(462, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(470, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(556, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(642, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(643, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(697, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(714, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(865, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(923, List(GamePropertyValues("allowed", "false"))), - GamePropertyField(986, List(GamePropertyValues("allowed", "false"))) + GamePropertyScope(32, List( + GamePropertyTarget(ObjectClass.aphelion_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aphelion_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.aurora, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.battlewagon, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.colossus_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.flail, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.galaxy_gunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lasher, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.liberator, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.lightgunship, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.maelstrom, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.magrider, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.mini_chaingun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_flight, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.peregrine_gunner, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.prowler, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.r_shotgun, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.thunderer, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vanguard, "allowed" -> "false"), + GamePropertyTarget(ObjectClass.vulture, "allowed" -> "false") )) ) ) From edc0f57d39f0e24a79634a30db95828a044eb8dc Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 9 Aug 2017 12:51:03 -0400 Subject: [PATCH 4/4] added comments, mainly --- .../packet/game/PropertyOverrideMessage.scala | 124 +++++++++++++++--- .../game/PropertyOverrideMessageTest.scala | 2 +- 2 files changed, 105 insertions(+), 21 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala b/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala index b7419ce9..39a5a7ae 100644 --- a/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/PropertyOverrideMessage.scala @@ -6,6 +6,16 @@ import scodec.Codec import scodec.codecs._ import shapeless.{::, HNil} +/** + * Dispatched by the server to alert the client about custom permissions in different zones.
+ *
+ * The primarily way this packet was used on Gemini Live was to restrict weapons per zone. + * The Battle Island restrictions, for example, were enforced by these properties.
+ *
+ * Exploration:
+ * What else can you do with this packet? + * @param list a `List` defining scopes for the targets of internal property changes + */ final case class PropertyOverrideMessage(list : List[PropertyOverrideMessage.GamePropertyScope]) extends PlanetSideGamePacket { type Packet = PropertyOverrideMessage @@ -14,55 +24,116 @@ final case class PropertyOverrideMessage(list : List[PropertyOverrideMessage.Gam } object GamePropertyTarget { + /** + * A target value referring to general game properties. + * In the context of this `GamePacket`, usually scoped to a "global" zone. + */ final val game_properties : Int = 343 - def apply(target : Int) : PropertyOverrideMessage.GamePropertyTarget = { - PropertyOverrideMessage.GamePropertyTarget(target, Nil) - } - + /** + * Overloaded constructor for defining a target for a single paired key and value (String -> String). + * @param target the target + * @param kv the key-value pair + * @return a `PropertyOverrideMessage.GamePropertyTarget` association object + */ def apply(target : Int, kv : (String, String)) : PropertyOverrideMessage.GamePropertyTarget = { - PropertyOverrideMessage.GamePropertyTarget(target, PropertyOverrideMessage.GamePropertyValues(kv._1, kv._2) :: Nil) + PropertyOverrideMessage.GamePropertyTarget(target, PropertyOverrideMessage.GameProperty(kv._1, kv._2) :: Nil) } + /** + * Overloaded constructor for defining a target for a list of paired key and value. + * @param target the target + * @param list a `List` of key-value pairs + * @return a `PropertyOverrideMessage.GamePropertyTarget` association object + */ def apply(target : Int, list : List[(String, String)]) : PropertyOverrideMessage.GamePropertyTarget = { PropertyOverrideMessage.GamePropertyTarget(target, list.map({ case(key, value) => - PropertyOverrideMessage.GamePropertyValues(key, value) + PropertyOverrideMessage.GameProperty(key, value) })) } } object GamePropertyScope { - def apply(zone : Int, list : PropertyOverrideMessage.GamePropertyTarget) : PropertyOverrideMessage.GamePropertyScope = { - PropertyOverrideMessage.GamePropertyScope(zone, list :: Nil) + /** + * Overloaded constructor for defining a scope for the contained property. + * @param zone a game zone where this property is valid + * @param property a targeted key-value pair + * @return a `PropertyOverrideMessage.GamePropertyScope` association object + */ + def apply(zone : Int, property : PropertyOverrideMessage.GamePropertyTarget) : PropertyOverrideMessage.GamePropertyScope = { + PropertyOverrideMessage.GamePropertyScope(zone, property :: Nil) } + /** + * Overloaded constructor for defining a scope for the contained properties. + * @param zone a game zone where this property is valid + * @param list a `List` of targeted key-value pairs + * @return a `PropertyOverrideMessage.GamePropertyScope` association object + */ def apply(zone : Int, list : List[PropertyOverrideMessage.GamePropertyTarget]) : PropertyOverrideMessage.GamePropertyScope = { PropertyOverrideMessage.GamePropertyScope(zone, list) } } object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { - final case class GamePropertyValues(field1 : String, field2 : String) + /** + * A wrapper class for the key-value pair. + * Another class's overloading allows this to be parsed in a format `field1 -> field2` slightly more idiomatic to pairs. + * @param field1 usually the "key;" + * occasionally, the only param + * @param field2 the "value" + */ + final case class GameProperty(field1 : String, field2 : String) - final case class GamePropertyTarget(target : Int, list : List[GamePropertyValues]) + /** + * The association between a target and the properties that affect it. + * @param target what game object is affected by these properties + * @param list the properties + * @see `ObjectClass` + */ + final case class GamePropertyTarget(target : Int, list : List[GameProperty]) + /** + * The association between a continent/zone and how game objects are affected differently in that region. + * @param zone the continent/zone number; + * 0 refers to server-wide properties + * @param list the target and its property changes + */ final case class GamePropertyScope(zone : Int, list : List[GamePropertyTarget]) + /** + * Overloaded constructor for defining a single region where object properties are to be changed. + * @param list a list of regions, objects, and changed properties + * @return a `PropertyOverrideMessage` object + */ def apply(list : PropertyOverrideMessage.GamePropertyScope) : PropertyOverrideMessage = { PropertyOverrideMessage(list :: Nil) } - private def value_pair_aligned_codec(n : Int) : Codec[GamePropertyValues] = ( + /** + * `Codec` for two strings containing a key-value pair, with the key being padded. + * @param n the padding of the first `String` + * @return a `GameProperty` object + */ + private def value_pair_aligned_codec(n : Int) : Codec[GameProperty] = ( ("field1" | PacketHelpers.encodedStringAligned(n)) :: ("field2" | PacketHelpers.encodedString) - ).as[GamePropertyValues] + ).as[GameProperty] - private val value_pair_codec : Codec[GamePropertyValues] = ( + /** + * `Codec` for two strings containing a key-value pair. + */ + private val value_pair_codec : Codec[GameProperty] = ( ("field1" | PacketHelpers.encodedString) :: ("field2" | PacketHelpers.encodedString) - ).as[GamePropertyValues] + ).as[GameProperty] + /** + * `Codec` for defining the target and switching between and concatenating different key-value pair `Codec`s. + * @param n the padding of the first key in the first entry of the contents + * @return a `GamePropertyTarget` object + */ private def game_property_target_codec(n : Int) : Codec[GamePropertyTarget] = ( ("target" | uintL(11)) :: (uint16L >>:~ { len => @@ -71,6 +142,9 @@ object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { }) ).xmap[GamePropertyTarget] ( { + case target :: _ :: None :: None :: HNil => //unlikely + GamePropertyTarget(target, Nil) + case target :: _ :: Some(first) :: None :: HNil => GamePropertyTarget(target, first :: Nil) @@ -80,14 +154,22 @@ object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { { case GamePropertyTarget(target, list) => val (first, other) = list match { - case ((f : GamePropertyValues) +: (rest : List[GamePropertyValues])) => (Some(f), Some(rest)) - case (f : GamePropertyValues) +: Nil => (Some(f), None) - case Nil => (None, None) + case ((f : GameProperty) +: (rest : List[GameProperty])) => (Some(f), Some(rest)) + case (f : GameProperty) +: Nil => (Some(f), None) + case Nil => (None, None) //unlikely } target :: list.length :: first :: other :: HNil } ) + /** + * `Codec` for defining the scope and switching between and concatenating different alignments for the target `Codec`.
+ *
+ * For every first target entry of a scope, the leading property string will incur the displacement of two 11-bit fields. + * That property will be byte-aligned by two bits. + * For every subsequent scope, the leading property will only incur the displacement of a single 11-bit field. + * These properties will be byte-aligned by five bits. + */ private val game_property_scope_codec : Codec[GamePropertyScope] = ( ("zone" | uint16L) :: (uintL(11) >>:~ { len => @@ -96,6 +178,9 @@ object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { }) ).xmap[GamePropertyScope] ( { + case zone :: _ :: None :: None :: HNil => //unlikely + GamePropertyScope(zone, Nil) + case zone :: _ :: Some(first) :: None :: HNil => GamePropertyScope(zone, first :: Nil) @@ -107,12 +192,11 @@ object PropertyOverrideMessage extends Marshallable[PropertyOverrideMessage] { val (first, other) = list match { case ((f : GamePropertyTarget) +: (rest : List[GamePropertyTarget])) => (Some(f), Some(rest)) case (f : GamePropertyTarget) +: Nil => (Some(f), None) - case Nil => (None, None) + case Nil => (None, None) //unlikely } zone :: list.length :: first :: other :: HNil } ) - implicit val codec : Codec[PropertyOverrideMessage] = - listOfN(uint16L, game_property_scope_codec).as[PropertyOverrideMessage] + implicit val codec : Codec[PropertyOverrideMessage] = listOfN(uint16L, game_property_scope_codec).as[PropertyOverrideMessage] } diff --git a/common/src/test/scala/game/PropertyOverrideMessageTest.scala b/common/src/test/scala/game/PropertyOverrideMessageTest.scala index bf4c22dd..4eb301cd 100644 --- a/common/src/test/scala/game/PropertyOverrideMessageTest.scala +++ b/common/src/test/scala/game/PropertyOverrideMessageTest.scala @@ -157,7 +157,7 @@ class PropertyOverrideMessageTest extends Specification { // list(8).zone mustEqual 30 list(8).list.length mustEqual 21 - list(7).list.head.target mustEqual 83 + list(8).list.head.target mustEqual 83 list(8).list.head.list.length mustEqual 1 list(8).list.head.list.head.field1 mustEqual "allowed" list(8).list.head.list.head.field2 mustEqual "false"