Added comprehensive encoding handling to support both player-level encoding choices as well as global multiple encodings through the settings file.
This commit is contained in:
parent
7904916dba
commit
745df8356f
5 changed files with 69 additions and 34 deletions
|
|
@ -506,14 +506,8 @@ class ObjectDB(TypedObject):
|
||||||
# This is an important function that must always work.
|
# This is an important function that must always work.
|
||||||
# we use a different __getattribute__ to avoid recursive loops.
|
# we use a different __getattribute__ to avoid recursive loops.
|
||||||
|
|
||||||
if from_obj:
|
if object.__getattribute__(self, 'player'):
|
||||||
try:
|
object.__getattribute__(self, 'player').msg(message, markup)
|
||||||
from_obj.at_msg_send(message, self)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
if self.at_msg_receive(message, from_obj):
|
|
||||||
for session in object.__getattribute__(self, 'sessions'):
|
|
||||||
session.msg(message, markup)
|
|
||||||
|
|
||||||
def emit_to(self, message, from_obj=None):
|
def emit_to(self, message, from_obj=None):
|
||||||
"Deprecated. Alias for msg"
|
"Deprecated. Alias for msg"
|
||||||
|
|
|
||||||
|
|
@ -253,19 +253,15 @@ class PlayerDB(TypedObject):
|
||||||
|
|
||||||
def msg(self, message, from_obj=None, markup=True):
|
def msg(self, message, from_obj=None, markup=True):
|
||||||
"""
|
"""
|
||||||
This duplicates the same-named method on the Character.
|
This is the main route for sending data to the user.
|
||||||
It forwards messages to the character or uses
|
|
||||||
the session messaging directly.
|
|
||||||
"""
|
"""
|
||||||
|
if from_obj:
|
||||||
|
try:
|
||||||
|
from_obj.at_msg_send(message, self)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
if self.character:
|
if self.character:
|
||||||
self.character.msg(message, from_obj)
|
if self.character.at_msg_receive(message, from_obj):
|
||||||
else:
|
|
||||||
if from_obj:
|
|
||||||
try:
|
|
||||||
from_obj.at_msg_send(message, self)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
if self.at_msg_receive(message, from_obj):
|
|
||||||
for session in object.__getattribute__(self, 'sessions'):
|
for session in object.__getattribute__(self, 'sessions'):
|
||||||
session.msg(message, markup)
|
session.msg(message, markup)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ from src.utils import reloads
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
from src.utils import utils
|
from src.utils import utils
|
||||||
|
|
||||||
|
ENCODINGS = settings.ENCODINGS
|
||||||
|
|
||||||
class SessionProtocol(StatefulTelnetProtocol):
|
class SessionProtocol(StatefulTelnetProtocol):
|
||||||
"""
|
"""
|
||||||
This class represents a player's session. Each player
|
This class represents a player's session. Each player
|
||||||
|
|
@ -71,6 +73,7 @@ class SessionProtocol(StatefulTelnetProtocol):
|
||||||
self.name = None
|
self.name = None
|
||||||
self.uid = None
|
self.uid = None
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
|
self.encoding = "utf-8"
|
||||||
|
|
||||||
# The time the user last issued a command.
|
# The time the user last issued a command.
|
||||||
self.cmd_last = time.time()
|
self.cmd_last = time.time()
|
||||||
|
|
@ -103,12 +106,30 @@ class SessionProtocol(StatefulTelnetProtocol):
|
||||||
So we take the user input and pass it to the Player and their currently
|
So we take the user input and pass it to the Player and their currently
|
||||||
connected character.
|
connected character.
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
raw_string = utils.to_unicode(raw_string)
|
if self.encoding:
|
||||||
except Exception, e:
|
try:
|
||||||
self.sendLine(str(e))
|
raw_string = utils.to_unicode(raw_string, encoding=self.encoding)
|
||||||
return
|
self.execute_cmd(raw_string)
|
||||||
self.execute_cmd(raw_string)
|
return
|
||||||
|
except Exception, e:
|
||||||
|
err = str(e)
|
||||||
|
print err
|
||||||
|
pass
|
||||||
|
|
||||||
|
# malformed/wrong encoding defined on player-try some defaults
|
||||||
|
for encoding in ENCODINGS:
|
||||||
|
try:
|
||||||
|
raw_string = utils.to_unicode(raw_string, encoding=encoding)
|
||||||
|
err = None
|
||||||
|
break
|
||||||
|
except Exception, e:
|
||||||
|
err = str(e)
|
||||||
|
continue
|
||||||
|
if err:
|
||||||
|
self.sendLine(err)
|
||||||
|
else:
|
||||||
|
self.execute_cmd(raw_string)
|
||||||
|
|
||||||
def msg(self, message, markup=True):
|
def msg(self, message, markup=True):
|
||||||
"""
|
"""
|
||||||
|
|
@ -120,12 +141,27 @@ class SessionProtocol(StatefulTelnetProtocol):
|
||||||
colors, but could also be html tags for
|
colors, but could also be html tags for
|
||||||
web connections etc.
|
web connections etc.
|
||||||
"""
|
"""
|
||||||
try:
|
if self.encoding:
|
||||||
message = utils.to_str(message)
|
try:
|
||||||
except Exception, e:
|
message = utils.to_str(message, encoding=self.encoding)
|
||||||
self.sendLine(str(e))
|
self.sendLine(ansi.parse_ansi(message, strip_ansi=not markup))
|
||||||
return
|
return
|
||||||
self.sendLine(ansi.parse_ansi(message, strip_ansi=not markup))
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# malformed/wrong encoding defined on player - try some defaults
|
||||||
|
for encoding in ENCODINGS:
|
||||||
|
try:
|
||||||
|
message = utils.to_str(message, encoding=encoding)
|
||||||
|
err = None
|
||||||
|
break
|
||||||
|
except Exception, e:
|
||||||
|
err = str(e)
|
||||||
|
continue
|
||||||
|
if err:
|
||||||
|
self.sendLine(err)
|
||||||
|
else:
|
||||||
|
self.sendLine(ansi.parse_ansi(message, strip_ansi=not markup))
|
||||||
|
|
||||||
def get_character(self):
|
def get_character(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -228,6 +264,8 @@ class SessionProtocol(StatefulTelnetProtocol):
|
||||||
self.name = user.username
|
self.name = user.username
|
||||||
self.logged_in = True
|
self.logged_in = True
|
||||||
self.conn_time = time.time()
|
self.conn_time = time.time()
|
||||||
|
if player.db.encoding:
|
||||||
|
self.encoding = player.db.encoding
|
||||||
|
|
||||||
if not settings.ALLOW_MULTISESSION:
|
if not settings.ALLOW_MULTISESSION:
|
||||||
# disconnect previous sessions.
|
# disconnect previous sessions.
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,12 @@ IMPORT_MUX_HELP = False
|
||||||
# thrown off by sending the empty system command 'idle' to the server
|
# thrown off by sending the empty system command 'idle' to the server
|
||||||
# at regular intervals.
|
# at regular intervals.
|
||||||
IDLE_TIMEOUT = 3600
|
IDLE_TIMEOUT = 3600
|
||||||
|
# The set of encodings tried. A Player object may set an attribute "encoding" on
|
||||||
|
# itself to match the client used. If not set, or wrong encoding is
|
||||||
|
# given, this list is tried, in order, aborting on the first match.
|
||||||
|
# Add sets for languages/regions your players are likely to use.
|
||||||
|
# (see http://en.wikipedia.org/wiki/Character_encoding)
|
||||||
|
ENCODINGS = ["utf-8", "latin-1", "ISO-8859-1"]
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Evennia Database config
|
# Evennia Database config
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,7 @@ class Attribute(SharedMemoryModel):
|
||||||
such as dhango model instances, cannot be directly stored/pickled
|
such as dhango model instances, cannot be directly stored/pickled
|
||||||
in an attribute, so we have to be clever about it.
|
in an attribute, so we have to be clever about it.
|
||||||
Types of objects and how they are handled:
|
Types of objects and how they are handled:
|
||||||
* str - stored directly in field
|
* str - s5Atored directly in field
|
||||||
* django model object - store its dbref in field
|
* django model object - store its dbref in field
|
||||||
* any other python structure - pickle in field
|
* any other python structure - pickle in field
|
||||||
|
|
||||||
|
|
@ -813,7 +813,8 @@ class TypedObject(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
Returns all attributes defined on the object.
|
Returns all attributes defined on the object.
|
||||||
"""
|
"""
|
||||||
return [attr for attr in self.objattribute_set.all()]
|
attr_set_all = eval("self.%s_set.all()" % (self.attribute_model_name.lower()))
|
||||||
|
return [attr for attr in attr_set_all]
|
||||||
|
|
||||||
def attr(self, attribute_name=None, value=None, delete=False):
|
def attr(self, attribute_name=None, value=None, delete=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue