diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index e6af16977..58e1ee0e6 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -605,7 +605,7 @@ object GamePacketOpcode extends Enumeration { // OPCODES 0xf0-f3 case 0xf0 => noDecoder(QueueTimedHelpMessage) - case 0xf1 => noDecoder(MailMessage) + case 0xf1 => game.MailMessage.decode case 0xf2 => noDecoder(GameVarUpdate) case 0xf3 => noDecoder(ClientCheatedMessage) case default => noDecoder(opcode) diff --git a/common/src/main/scala/net/psforever/packet/game/MailMessage.scala b/common/src/main/scala/net/psforever/packet/game/MailMessage.scala new file mode 100644 index 000000000..79fd3491a --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/MailMessage.scala @@ -0,0 +1,35 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +/** + * Dispatched from the server, sending a "priority message" to the given client's avatar. + * The messaging inbox is generally accessible through the use of `alt`+`i`. + * It is also made accessible through use of an icon in the lower right corner when there is an outstanding message.
+ *
+ * Exploration:
+ * How does the PlanetSide Classic mail system work? + * At the moment, it only seems possible to receive and read mail from the server. + * @param sender the name of the player who sent the mail + * @param subject the subject + * @param message the message + */ +final case class MailMessage(sender : String, + subject : String, + message : String + ) extends PlanetSideGamePacket { + type Packet = MailMessage + def opcode = GamePacketOpcode.MailMessage + def encode = MailMessage.encode(this) +} + +object MailMessage extends Marshallable[MailMessage] { + implicit val codec : Codec[MailMessage] = ( + ("sender" | PacketHelpers.encodedString) :: + ("subject" | PacketHelpers.encodedString) :: + ("message" | PacketHelpers.encodedString) + ).as[MailMessage] +} \ No newline at end of file diff --git a/common/src/test/scala/game/MailMessageTest.scala b/common/src/test/scala/game/MailMessageTest.scala new file mode 100644 index 000000000..726060c7e --- /dev/null +++ b/common/src/test/scala/game/MailMessageTest.scala @@ -0,0 +1,30 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class MailMessageTest extends Specification { + //we've never received this packet before so this whole test is faked + val string = hex"F1 86466174654A489250726 96F72697479204D61696C2054657374 8E48656C6C6F204175726178697321" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case MailMessage(sender, subject, msg) => + sender mustEqual "FateJH" + subject mustEqual "Priority Mail Test" + msg mustEqual "Hello Auraxis!" + case _ => + ko + } + } + + "encode" in { + val msg = MailMessage("FateJH", "Priority Mail Test", "Hello Auraxis!") + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } +}