Various fixes to ChatMsg (#43)

* Add BinaryChoiceCodec

* Proper ChatMsg structuring
This commit is contained in:
tfarley 2016-07-28 19:23:38 -07:00 committed by pschord
parent 4fb13fdc57
commit fc2ef50be6
5 changed files with 61 additions and 22 deletions

View file

@ -0,0 +1,31 @@
// Copyright (c) 2016 PSForever.net to present
package net.psforever.newcodecs
import scodec.{ Codec, SizeBound }
import scodec.bits.BitVector
private[newcodecs] final class BinaryChoiceCodec[A](choice: Boolean, codec_true: => Codec[A], codec_false: => Codec[A]) extends Codec[A] {
private lazy val evaluatedCodec_true = codec_true
private lazy val evaluatedCodec_false = codec_false
override def sizeBound = if (choice) evaluatedCodec_true.sizeBound else evaluatedCodec_false.sizeBound
override def encode(a: A) = {
if (choice)
evaluatedCodec_true.encode(a)
else
evaluatedCodec_false.encode(a)
}
override def decode(buffer: BitVector) = {
if (choice)
evaluatedCodec_true.decode(buffer)
else
evaluatedCodec_false.decode(buffer)
}
override def toString = if(choice) s"binarychoice(true, $evaluatedCodec_true, ?)" else "binarychoice(false, ?, $evaluatedCodec_false)"
}

View file

@ -11,4 +11,6 @@ package object newcodecs {
def q_float(min : Double, max : Double, bits : Int): Codec[Float] = q_double(min, max, bits).narrow(v => Attempt.successful(v.toFloat), _.toDouble)
def binary_choice[A](choice: Boolean, codec_true: => Codec[A], codec_false: => Codec[A]): Codec[A] = new BinaryChoiceCodec(choice, codec_true, codec_false)
}

View file

@ -1,15 +1,17 @@
// Copyright (c) 2016 PSForever.net to present
package net.psforever.packet.game
import net.psforever.newcodecs._
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
import net.psforever.types.ChatMessageType
import scodec.Codec
import scodec.codecs._
final case class ChatMsg(channel : ChatMessageType.Value,
unk1 : Boolean,
final case class ChatMsg(messagetype : ChatMessageType.Value,
has_wide_contents : Boolean,
recipient : String,
contents : String)
contents : String,
note_contents : Option[String])
extends PlanetSideGamePacket {
type Packet = ChatMsg
def opcode = GamePacketOpcode.ChatMsg
@ -18,9 +20,11 @@ final case class ChatMsg(channel : ChatMessageType.Value,
object ChatMsg extends Marshallable[ChatMsg] {
implicit val codec : Codec[ChatMsg] = (
("messagetype" | ChatMessageType.codec) ::
("unk1" | bool) ::
("recipient" | PacketHelpers.encodedWideStringAligned(7)) ::
("contents" | PacketHelpers.encodedWideString)
).as[ChatMsg]
("messagetype" | ChatMessageType.codec) >>:~ { messagetype_value =>
(("has_wide_contents" | bool) >>:~ { has_wide_contents_value =>
("recipient" | PacketHelpers.encodedWideStringAligned(7)) ::
newcodecs.binary_choice(has_wide_contents_value, ("contents" | PacketHelpers.encodedWideString), ("contents" | PacketHelpers.encodedString))
}) :+
conditional(messagetype_value == ChatMessageType.Note, ("note_contents" | PacketHelpers.encodedWideString))
}).as[ChatMsg]
}