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
|
|
@ -505,15 +505,9 @@ class ObjectDB(TypedObject):
|
|||
"""
|
||||
# This is an important function that must always work.
|
||||
# we use a different __getattribute__ to avoid recursive loops.
|
||||
|
||||
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'):
|
||||
session.msg(message, markup)
|
||||
|
||||
if object.__getattribute__(self, 'player'):
|
||||
object.__getattribute__(self, 'player').msg(message, markup)
|
||||
|
||||
def emit_to(self, message, from_obj=None):
|
||||
"Deprecated. Alias for msg"
|
||||
|
|
|
|||
|
|
@ -253,19 +253,15 @@ class PlayerDB(TypedObject):
|
|||
|
||||
def msg(self, message, from_obj=None, markup=True):
|
||||
"""
|
||||
This duplicates the same-named method on the Character.
|
||||
It forwards messages to the character or uses
|
||||
the session messaging directly.
|
||||
This is the main route for sending data to the user.
|
||||
"""
|
||||
if from_obj:
|
||||
try:
|
||||
from_obj.at_msg_send(message, self)
|
||||
except Exception:
|
||||
pass
|
||||
if self.character:
|
||||
self.character.msg(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):
|
||||
if self.character.at_msg_receive(message, from_obj):
|
||||
for session in object.__getattribute__(self, 'sessions'):
|
||||
session.msg(message, markup)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ from src.utils import reloads
|
|||
from src.utils import logger
|
||||
from src.utils import utils
|
||||
|
||||
ENCODINGS = settings.ENCODINGS
|
||||
|
||||
class SessionProtocol(StatefulTelnetProtocol):
|
||||
"""
|
||||
This class represents a player's session. Each player
|
||||
|
|
@ -71,6 +73,7 @@ class SessionProtocol(StatefulTelnetProtocol):
|
|||
self.name = None
|
||||
self.uid = None
|
||||
self.logged_in = False
|
||||
self.encoding = "utf-8"
|
||||
|
||||
# The time the user last issued a command.
|
||||
self.cmd_last = time.time()
|
||||
|
|
@ -103,13 +106,31 @@ class SessionProtocol(StatefulTelnetProtocol):
|
|||
So we take the user input and pass it to the Player and their currently
|
||||
connected character.
|
||||
"""
|
||||
try:
|
||||
raw_string = utils.to_unicode(raw_string)
|
||||
except Exception, e:
|
||||
self.sendLine(str(e))
|
||||
return
|
||||
self.execute_cmd(raw_string)
|
||||
|
||||
if self.encoding:
|
||||
try:
|
||||
raw_string = utils.to_unicode(raw_string, encoding=self.encoding)
|
||||
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):
|
||||
"""
|
||||
Communication Evennia -> Player
|
||||
|
|
@ -120,12 +141,27 @@ class SessionProtocol(StatefulTelnetProtocol):
|
|||
colors, but could also be html tags for
|
||||
web connections etc.
|
||||
"""
|
||||
try:
|
||||
message = utils.to_str(message)
|
||||
except Exception, e:
|
||||
self.sendLine(str(e))
|
||||
return
|
||||
self.sendLine(ansi.parse_ansi(message, strip_ansi=not markup))
|
||||
if self.encoding:
|
||||
try:
|
||||
message = utils.to_str(message, encoding=self.encoding)
|
||||
self.sendLine(ansi.parse_ansi(message, strip_ansi=not markup))
|
||||
return
|
||||
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):
|
||||
"""
|
||||
|
|
@ -228,6 +264,8 @@ class SessionProtocol(StatefulTelnetProtocol):
|
|||
self.name = user.username
|
||||
self.logged_in = True
|
||||
self.conn_time = time.time()
|
||||
if player.db.encoding:
|
||||
self.encoding = player.db.encoding
|
||||
|
||||
if not settings.ALLOW_MULTISESSION:
|
||||
# disconnect previous sessions.
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@ IMPORT_MUX_HELP = False
|
|||
# thrown off by sending the empty system command 'idle' to the server
|
||||
# at regular intervals.
|
||||
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
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ class Attribute(SharedMemoryModel):
|
|||
such as dhango model instances, cannot be directly stored/pickled
|
||||
in an attribute, so we have to be clever about it.
|
||||
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
|
||||
* any other python structure - pickle in field
|
||||
|
||||
|
|
@ -813,7 +813,8 @@ class TypedObject(SharedMemoryModel):
|
|||
"""
|
||||
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):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue