From 49eb2b2873f24647a5a9bf571b184d83d775d5ed Mon Sep 17 00:00:00 2001 From: Vincent Le Goff Date: Sat, 12 Jan 2019 15:27:36 +0100 Subject: [PATCH] Solve the accentuation problem in Evennia (Python 3) --- evennia/server/evennia_launcher.py | 2 +- evennia/server/portal/amp.py | 4 ++-- evennia/server/portal/telnet.py | 4 ++-- evennia/server/session.py | 35 ++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 62779f184e..7eefb9804d 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -638,7 +638,7 @@ class AMPLauncherProtocol(amp.AMP): else: status = pickle.loads(status) callback(status) - return {b"status": b""} + return {"status": pickle.dumps(b"")} def send_instruction(operation, arguments, callback=None, errback=None): diff --git a/evennia/server/portal/amp.py b/evennia/server/portal/amp.py index c70528ac70..618cc97cec 100644 --- a/evennia/server/portal/amp.py +++ b/evennia/server/portal/amp.py @@ -73,11 +73,11 @@ Content-Type: text/html # Helper functions for pickling. def dumps(data): - return to_str(pickle.dumps(to_str(data), pickle.HIGHEST_PROTOCOL)) + return pickle.dumps(data, pickle.HIGHEST_PROTOCOL) def loads(data): - return pickle.loads(to_str(data)) + return pickle.loads(data) @wraps diff --git a/evennia/server/portal/telnet.py b/evennia/server/portal/telnet.py index 41fbf33750..74aa9721cf 100644 --- a/evennia/server/portal/telnet.py +++ b/evennia/server/portal/telnet.py @@ -243,7 +243,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): line (str): Line to send. """ - line = bytes(line, 'utf-8') + line = self.try_encode(line) # escape IAC in line mode, and correctly add \r\n (the TELNET end-of-line) line = line.replace(IAC, IAC + IAC) line = line.replace(b'\n', b'\r\n') @@ -343,7 +343,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): strip_ansi=nocolor, xterm256=xterm256) if mxp: prompt = mxp_parse(prompt) - prompt = prompt.encode() + prompt = self.try_encode(prompt) prompt = prompt.replace(IAC, IAC + IAC).replace(b'\n', b'\r\n') prompt += IAC + GA self.transport.write(mccp_compress(self, prompt)) diff --git a/evennia/server/session.py b/evennia/server/session.py index eb77321a24..5481860163 100644 --- a/evennia/server/session.py +++ b/evennia/server/session.py @@ -135,6 +135,41 @@ class Session(object): if self.account: self.protocol_flags.update(self.account.attributes.get("_saved_protocol_flags", {})) + # helpers + + def try_encode(self, text): + """ + Try to encode the given text, following the session's protocol flag. + + Args: + text (str or bytes): the text to encode to bytes. + + Returns: + encoded_text (bytes): the encoded text following the session's + protocol flag. If the converting fails, log the error + and send the text with "?" in place of problematic + characters. If the specified encoding cannot be found, + the protocol flag is reset to utf-8. + In any case, returns bytes. + + Note: + If the argument is bytes, return it as is. + + """ + if isinstance(text, bytes): + return text + + try: + encoded = text.encode(self.protocol_flags["ENCODING"]) + except LookupError: + self.protocol_flags["ENCODING"] = 'utf-8' + encoded = text.encode('utf-8') + except UnicodeEncodeError: + print("An error occurred during string encoding to {encoding}. Will remove errors and try again.".format(encoding=self.protocol_flags["ENCODING"])) + encoded = text.encode(self.protocol_flags["ENCODING"], errors="replace") + + return encoded + # access hooks def disconnect(self, reason=None):