From b328d072695710d215a95b418a643194238689d4 Mon Sep 17 00:00:00 2001 From: Kayomn Date: Fri, 1 Oct 2021 00:17:20 +0100 Subject: [PATCH] Add Chattle protocol --- chattle.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 chattle.py diff --git a/chattle.py b/chattle.py new file mode 100644 index 0000000..01ae756 --- /dev/null +++ b/chattle.py @@ -0,0 +1,42 @@ +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)