From 2475b468b848d045c8865e80b0c743e1daa01666 Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 7 Mar 2018 22:58:42 -0500 Subject: [PATCH] added initial AvatarSearchCriteriaMessage packet and tests; worked ASCM into WSA login workflow --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../game/AvatarSearchCriteriaMessage.scala | 44 +++++++++++++++++ .../AvatarSearchCriteriaMessageTest.scala | 49 +++++++++++++++++++ .../game/DensityLevelUpdateMessageTest.scala | 8 +-- .../src/main/scala/WorldSessionActor.scala | 2 +- 5 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/AvatarSearchCriteriaMessage.scala create mode 100644 common/src/test/scala/game/AvatarSearchCriteriaMessageTest.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 931575c1..b6ab5d93 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -437,7 +437,7 @@ object GamePacketOpcode extends Enumeration { case 0x61 => game.ObjectDetectedMessage.decode case 0x62 => game.SplashHitMessage.decode case 0x63 => game.SetChatFilterMessage.decode - case 0x64 => noDecoder(AvatarSearchCriteriaMessage) + case 0x64 => game.AvatarSearchCriteriaMessage.decode case 0x65 => noDecoder(AvatarSearchResponse) case 0x66 => game.WeaponJammedMessage.decode case 0x67 => noDecoder(LinkDeadAwarenessMsg) diff --git a/common/src/main/scala/net/psforever/packet/game/AvatarSearchCriteriaMessage.scala b/common/src/main/scala/net/psforever/packet/game/AvatarSearchCriteriaMessage.scala new file mode 100644 index 00000000..b6ed5c52 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/AvatarSearchCriteriaMessage.scala @@ -0,0 +1,44 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.{Attempt, Codec, Err} +import scodec.codecs._ +import shapeless.{::, HNil} + +/** + * na + * @param unk1 na + * @param unk2 na + */ +final case class AvatarSearchCriteriaMessage(unk1 : PlanetSideGUID, + unk2 : List[Int]) + extends PlanetSideGamePacket { + type Packet = AvatarSearchCriteriaMessage + def opcode = GamePacketOpcode.AvatarSearchCriteriaMessage + def encode = AvatarSearchCriteriaMessage.encode(this) +} + +object AvatarSearchCriteriaMessage extends Marshallable[AvatarSearchCriteriaMessage] { + implicit val codec : Codec[AvatarSearchCriteriaMessage] = ( + ("unk1" | PlanetSideGUID.codec) :: + ("unk2" | PacketHelpers.listOfNSized(6, uint8L)) + ).exmap[AvatarSearchCriteriaMessage] ( + { + case a :: b :: HNil => + Attempt.Successful(AvatarSearchCriteriaMessage(a, b)) + }, + { + case AvatarSearchCriteriaMessage(a, b) => + if(b.length != 6) { + Attempt.Failure(Err("list must have 6 entries")) + } + else if(b.count(i => { i < 0 || i > 255 }) > 0) { + Attempt.Failure(Err("list entries must be 0-255 inclusive")) + } + else { + Attempt.Successful(a :: b :: HNil) + } + } + ) +} diff --git a/common/src/test/scala/game/AvatarSearchCriteriaMessageTest.scala b/common/src/test/scala/game/AvatarSearchCriteriaMessageTest.scala new file mode 100644 index 00000000..d0175d06 --- /dev/null +++ b/common/src/test/scala/game/AvatarSearchCriteriaMessageTest.scala @@ -0,0 +1,49 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class AvatarSearchCriteriaMessageTest extends Specification { + val string = hex"64 C604 00 00 00 00 00 00" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case AvatarSearchCriteriaMessage(unk1, unk2) => + unk1 mustEqual PlanetSideGUID(1222) + unk2.length mustEqual 6 + unk2.head mustEqual 0 + unk2(1) mustEqual 0 + unk2(2) mustEqual 0 + unk2(3) mustEqual 0 + unk2(4) mustEqual 0 + unk2(5) mustEqual 0 + case _ => + ko + } + } + + "encode" in { + val msg = AvatarSearchCriteriaMessage(PlanetSideGUID(1222), List(0, 0, 0, 0, 0, 0)) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } + + "encode (failure; wrong number of list entries)" in { + val msg = AvatarSearchCriteriaMessage(PlanetSideGUID(1222), List(0)) + PacketCoding.EncodePacket(msg).isSuccessful mustEqual false + } + + "encode (failure; list number too big)" in { + val msg = AvatarSearchCriteriaMessage(PlanetSideGUID(1222), List(0, 0, 0, 0, 0, 256)) + PacketCoding.EncodePacket(msg).isSuccessful mustEqual false + } + + "encode (failure; list number too small)" in { + val msg = AvatarSearchCriteriaMessage(PlanetSideGUID(1222), List(0, 0, 0, -1, 0, 0)) + PacketCoding.EncodePacket(msg).isSuccessful mustEqual false + } +} diff --git a/common/src/test/scala/game/DensityLevelUpdateMessageTest.scala b/common/src/test/scala/game/DensityLevelUpdateMessageTest.scala index fc0ea980..aa5e1f55 100644 --- a/common/src/test/scala/game/DensityLevelUpdateMessageTest.scala +++ b/common/src/test/scala/game/DensityLevelUpdateMessageTest.scala @@ -41,12 +41,12 @@ class DensityLevelUpdateMessageTest extends Specification { } "encode (failure; list number too big)" in { - val msg1 = DensityLevelUpdateMessage(1, 19999, List(0,0, 0,0, 0,0, 0,8)) - PacketCoding.EncodePacket(msg1).isSuccessful mustEqual false + val msg = DensityLevelUpdateMessage(1, 19999, List(0,0, 0,0, 0,0, 0,8)) + PacketCoding.EncodePacket(msg).isSuccessful mustEqual false } "encode (failure; list number too small)" in { - val msg1 = DensityLevelUpdateMessage(1, 19999, List(0,0, 0,0, 0,-1, 0,0)) - PacketCoding.EncodePacket(msg1).isSuccessful mustEqual false + val msg = DensityLevelUpdateMessage(1, 19999, List(0,0, 0,0, 0,-1, 0,0)) + PacketCoding.EncodePacket(msg).isSuccessful mustEqual false } } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 286cd32b..ac418032 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -1027,7 +1027,7 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(SetChatFilterMessage(ChatChannel.Local, false, ChatChannel.values.toList)) //TODO will not always be "on" sendResponse(AvatarDeadStateMessage(DeadState.Nothing, 0,0, tplayer.Position, 0, true)) sendResponse(PlanetsideAttributeMessage(guid, 53, 1)) - //AvatarSearchCriteriaMessage + sendResponse(AvatarSearchCriteriaMessage(guid, List(0,0,0,0,0,0))) (1 to 73).foreach( i => { sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(i), 67, 0)) })