Improve ChatMsg and fix LoginRespMessage

This commit is contained in:
Chord 2016-08-06 11:23:28 -04:00
parent 38715c0d04
commit cb2507360e
4 changed files with 36 additions and 12 deletions

View file

@ -11,18 +11,28 @@ import scodec.codecs._
* Instructs client to display and/or process a chat message/command when sent server to client.
* Instructs server to route and/or process a chat message/command when sent client to server.
*
* @param messagetype the type of the chat message (CMT)
* @param has_wide_contents whether the contents contains wide characters or not
* @param messageType the type of the chat message (CMT)
* @param wideContents whether the contents contains wide characters or not. This is
* required because Java/Scala have one String type with a charset
* of UTF-16. Therefore, there is no way at runtime to determine the
* charset of String.
* @param recipient identifies the recipient of the message, such as in a tell (occasionally used as "sender" instead i.e. /note)
* @param contents the textual contents of the message
* @param note_contents only present when the message is of note type
* @param note only used when the message is of note type
*/
final case class ChatMsg(messagetype : ChatMessageType.Value,
has_wide_contents : Boolean,
final case class ChatMsg(messageType : ChatMessageType.Value,
wideContents : Boolean,
recipient : String,
contents : String,
note_contents : Option[String])
note : Option[String])
extends PlanetSideGamePacket {
// Prevent usage of the Note field unless the message is of type note
if(messageType == ChatMessageType.CMT_NOTE)
assert(note.isDefined, "Note contents required")
else
assert(note.isEmpty, "Note contents found, but message type isnt Note")
type Packet = ChatMsg
def opcode = GamePacketOpcode.ChatMsg
def encode = ChatMsg.encode(this)
@ -31,10 +41,13 @@ final case class ChatMsg(messagetype : ChatMessageType.Value,
object ChatMsg extends Marshallable[ChatMsg] {
implicit val codec : Codec[ChatMsg] = (
("messagetype" | ChatMessageType.codec) >>:~ { messagetype_value =>
(("has_wide_contents" | bool) >>:~ { has_wide_contents_value =>
(("has_wide_contents" | bool) >>:~ { isWide =>
("recipient" | PacketHelpers.encodedWideStringAligned(7)) ::
newcodecs.binary_choice(has_wide_contents_value, ("contents" | PacketHelpers.encodedWideString), ("contents" | PacketHelpers.encodedString))
newcodecs.binary_choice(isWide,
"contents" | PacketHelpers.encodedWideString,
"contents" | PacketHelpers.encodedString)
}) :+
conditional(messagetype_value == ChatMessageType.CMT_NOTE, ("note_contents" | PacketHelpers.encodedWideString))
conditional(messagetype_value == ChatMessageType.CMT_NOTE,
"note_contents" | PacketHelpers.encodedWideString)
}).as[ChatMsg]
}

View file

@ -26,7 +26,9 @@ object LoginRespMessage extends Marshallable[LoginRespMessage] {
("station_error" | uint32L) ::
("subscription_status" | uint32L) ::
("unknown" | uint32L) ::
("username" | PacketHelpers.encodedString) :: (
("privilege" | uint32L) flatZip { priv => bool } xmap[Long]({case (a, _) => a}, priv => (priv, (priv & 1) == 1)))
("username" | PacketHelpers.encodedString) ::
("privilege" | uint32L)
.flatZip(priv => bool)
.xmap[Long]({case (a, _) => a}, priv => (priv, (priv & 1) == 1))
).as[LoginRespMessage]
}

View file

@ -5,7 +5,7 @@ import net.psforever.crypto.CryptoInterface
import net.psforever.crypto.CryptoInterface.CryptoDHState
import scodec.bits._
class CryptoInterfaceTest extends Specification {
class CryptoInterfaceTest extends Specification { args(stopOnFail = true)
"Crypto interface" should {
"correctly initialize" in {
CryptoInterface.initialize()

View file

@ -206,6 +206,15 @@ class GamePacketTest extends Specification {
pkt_tell mustEqual string_tell
}
"allow and disallow note" in {
ChatMsg(ChatMessageType.CMT_ARMOR,
false,
"DontCare", "DontCare", Some("Should be here")) must throwA[AssertionError]
ChatMsg(ChatMessageType.CMT_NOTE,
false,
"DontCare", "DontCare", None) must throwA[AssertionError]
}
}
"ChangeFireModeMessage" should {