summaryrefslogtreecommitdiff
path: root/asciifarmclient/common/messages.py
diff options
context:
space:
mode:
Diffstat (limited to 'asciifarmclient/common/messages.py')
-rw-r--r--asciifarmclient/common/messages.py157
1 files changed, 157 insertions, 0 deletions
diff --git a/asciifarmclient/common/messages.py b/asciifarmclient/common/messages.py
new file mode 100644
index 0000000..d3aed9a
--- /dev/null
+++ b/asciifarmclient/common/messages.py
@@ -0,0 +1,157 @@
+
+import re
+import unicodedata
+import json
+
+class InvalidMessageError(Exception):
+ errType = "invalidmessage"
+ description = ""
+
+ def __init__(self, description="", errType=None):
+ self.description = description
+ if errType is not None:
+ self.errType = errType
+
+ def toMessage(self):
+ return ErrorMessage(self.errType, self.description)
+
+class InvalidNameError(InvalidMessageError):
+ errType = "invalidname"
+
+class Message:
+
+ @classmethod
+ def msgType(cls):
+ return cls.typename
+
+ def to_json(self):
+ raise NotImplementedError
+
+ def to_json_bytes(self):
+ return bytes(json.dumps(self.to_json()), "utf-8")
+
+ @classmethod
+ def from_json(cls, jsonobj):
+ raise NotImplementedError
+
+class ClientToServerMessage(Message):
+
+ def body(self):
+ raise NotImplementedError
+
+ def to_json(self):
+ return [self.typename, self.body()]
+
+ @classmethod
+ def from_json(cls, jsonlist):
+ assert len(jsonlist) == 2, InvalidMessageError
+ typename, body = jsonlist
+ assert typename == cls.msgType(), InvalidMessageError
+ return cls(body)
+
+
+class NameMessage(ClientToServerMessage):
+
+ typename = "name"
+ categories = {"Lu", "Ll", "Lt", "Lm", "Lo", "Nd", "Nl", "No", "Pc"}
+
+
+ def __init__(self, name):
+ assert isinstance(name, str), InvalidNameError("name must be a string")
+ assert (len(name) > 0), InvalidNameError("name needs at least one character")
+ assert (len(bytes(name, "utf-8")) <= 256), InvalidNameError("name may not be longer than 256 utf8 bytes")
+ if name[0] != "~":
+ for char in name:
+ category = unicodedata.category(char)
+ assert category in self.categories, InvalidNameError("all name caracters must be in these unicode categories: " + "|".join(self.categories) + " (except for tildenames)")
+ self.name = name
+
+ def body(self):
+ return self.name
+
+
+class InputMessage(ClientToServerMessage):
+
+ typename = "input"
+
+ def __init__(self, inp):
+ self.inp = inp
+
+ def body(self):
+ return self.inp
+
+class ChatMessage(ClientToServerMessage):
+
+ typename = "chat"
+
+ def __init__(self, text):
+ assert isinstance(text, str), InvalidMessageError("chat message must be a string")
+ assert text.isprintable(), InvalidMessageError("chat messages may only contain printable unicode characters")
+ self.text = text
+
+ def body(self):
+ return self.text
+
+
+
+class ServerToClientMessage(Message):
+ msglen = 0
+
+
+ @classmethod
+ def from_json(cls, jsonlist):
+ assert len(jsonlist) == cls.msglen, InvalidMessageError
+ assert jsonlist[0] == cls.msgType(), InvalidMessageError
+ return cls(*jsonlist[1:])
+
+
+class MessageMessage(ServerToClientMessage): # this name feels stupid
+ """ A message to inform the client. This is meant to be read by the user"""
+
+ typename = "message"
+ msglen = 3
+
+ def __init__(self, text, type=""):
+ self.text = text
+ self.type = type
+
+ def to_json(self):
+ return [self.typename, self.text, self.type]
+
+
+class WorldMessage(ServerToClientMessage):
+ """ A message about the world state """
+
+ typename = "world"
+ msglen = 2
+
+ def __init__(self, updates):
+ assert isinstance(updates, list), InvalidMessageError
+ self.updates = updates
+
+ def to_json(self):
+ return [self.typename, self.updates]
+
+class ErrorMessage(ServerToClientMessage):
+
+ typename = "error"
+ msglen = 3
+
+ def __init__(self, errType, description=""):
+ self.errType = errType
+ self.description = description
+
+ def to_json(self):
+ return [self.typename, self.errType, self.description]
+
+
+
+messages = {message.msgType(): message for message in [
+ NameMessage,
+ InputMessage,
+ ChatMessage,
+ WorldMessage,
+ ErrorMessage,
+ MessageMessage
+]}
+