diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 7955e49e..1eb8898d 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -334,7 +334,7 @@ object GamePacketOpcode extends Enumeration { case 0x0b => noDecoder(DamageMessage) case 0x0c => noDecoder(DestroyMessage) case 0x0d => game.ReloadMessage.decode - case 0x0e => noDecoder(MountVehicleMsg) + case 0x0e => game.MountVehicleMsg.decode case 0x0f => noDecoder(DismountVehicleMsg) // OPCODES 0x10-1f diff --git a/common/src/main/scala/net/psforever/packet/game/MountVehicleMsg.scala b/common/src/main/scala/net/psforever/packet/game/MountVehicleMsg.scala new file mode 100644 index 00000000..5a398b41 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/MountVehicleMsg.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +/** + * Alert that the player wishes to board a vehicle at a specific entry point.
+ *
+ * The client will only dispatch this packet when it feels confident that the player can get into a vehicle. + * It makes its own check whether or not to display that "enter vehicle here" icon on the ground. + * This is called an "entry point." + * Entry points and seat numbers are not required as one-to-one; + * multiple entry points can lead to the same seat, such as the driver seat of an ANT.
+ *
+ * The player is not allowed to board anything until the server responds in affirmation. + * @param player_guid the player + * @param vehicle_guid the vehicle + * @param entry_point the entry index that maps to a seat index, specific to the selected vehicle + */ +final case class MountVehicleMsg(player_guid : PlanetSideGUID, + vehicle_guid : PlanetSideGUID, + entry_point : Int) + extends PlanetSideGamePacket { + type Packet = MountVehicleMsg + def opcode = GamePacketOpcode.MountVehicleMsg + def encode = MountVehicleMsg.encode(this) +} + +object MountVehicleMsg extends Marshallable[MountVehicleMsg] { + implicit val codec : Codec[MountVehicleMsg] = ( + ("player_guid" | PlanetSideGUID.codec) :: + ("vehicle_guid" | PlanetSideGUID.codec) :: + ("entry_point" | uint8L) + ).as[MountVehicleMsg] +} diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index f1dba3ab..769c9704 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -915,6 +915,28 @@ class GamePacketTest extends Specification { } } + "MountVehicleMsg" should { + val string = hex"0E E104 6704 06" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case MountVehicleMsg(player_guid, vehicle_guid, entry) => + player_guid mustEqual PlanetSideGUID(1249) + vehicle_guid mustEqual PlanetSideGUID(1127) + entry mustEqual 6 + case default => + ko + } + } + + "encode" in { + val msg = MountVehicleMsg(PlanetSideGUID(1249), PlanetSideGUID(1127), 6) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } + } + "ObjectHeldMessage" should { val string = hex"33 4B00 02 00" diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 8232882f..4a5fd72c 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -324,6 +324,9 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ AvatarFirstTimeEventMessage(avatar_guid, object_guid, unk1, event_name) => log.info("AvatarFirstTimeEvent: " + msg) + case msg @ MountVehicleMsg(player_guid, vehicle_guid, unk) => + log.info("MounVehicleMsg: "+msg) + case default => log.debug(s"Unhandled GamePacket ${pkt}") }