43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
import json
|
|
import struct
|
|
|
|
|
|
class Message:
|
|
"""
|
|
Data carrier for messages. Before a Message may be sent over the network, it must be encoded using the
|
|
`encode_message` function
|
|
"""
|
|
def __init__(self, buffer: bytes) -> None:
|
|
# The byte layout of the structure is a buffer of JSON data preceded by a 2-byte header that specifies how long
|
|
# it is.
|
|
message_length_size = 2
|
|
message_length = struct.unpack(">H", buffer[0:message_length_size])[0]
|
|
message = json.loads(buffer[message_length_size:(message_length_size + message_length)])
|
|
self.author = message["author"]
|
|
self.body = message["body"]
|
|
|
|
def as_command(self) -> str:
|
|
"""
|
|
Attempts to extract a command from the message.
|
|
|
|
:return: Contents of the command without the command character or an empty string if `self` is not a command.
|
|
"""
|
|
return (self.body[1:] if self.body.startswith("/") else "")
|
|
|
|
|
|
def encode_message(author: str, body: str) -> bytes:
|
|
"""
|
|
Encodes a message in the Chattle protocol format for transporting over a network connection.
|
|
|
|
:param author: Screen name of the user that the message originated from
|
|
:param body: Content of the message. Note that any trailing whitespace characters are stripped.
|
|
:return: An encoded byte buffer of the message that can be decoded by creating a `Message` instance from it.
|
|
"""
|
|
|
|
message = json.dumps({
|
|
"author": author,
|
|
"body": body.strip(),
|
|
}).encode("utf-8")
|
|
|
|
return (struct.pack(">H", len(message)) + message)
|