Further work on stabilizing output across different situations.
This commit is contained in:
parent
bac8f51401
commit
23e63111cc
2 changed files with 89 additions and 70 deletions
|
|
@ -108,6 +108,9 @@ _RE_REF = re.compile(r"\{+\#([0-9]+)\}+")
|
||||||
# This regex is used to quickly reference one self in an emote.
|
# This regex is used to quickly reference one self in an emote.
|
||||||
_RE_SELF_REF = re.compile(r"/me|@", _RE_FLAGS)
|
_RE_SELF_REF = re.compile(r"/me|@", _RE_FLAGS)
|
||||||
|
|
||||||
|
# regex for non-alphanumberic end of a string
|
||||||
|
_RE_CHAREND = re.compile(r"\W+$", _RE_FLAGS)
|
||||||
|
|
||||||
# reference markers for language
|
# reference markers for language
|
||||||
_RE_REF_LANG = re.compile(r"\{+\##([0-9]+)\}+")
|
_RE_REF_LANG = re.compile(r"\{+\##([0-9]+)\}+")
|
||||||
# language says in the emote are on the form "..." or langname"..." (no spaces).
|
# language says in the emote are on the form "..." or langname"..." (no spaces).
|
||||||
|
|
@ -262,7 +265,6 @@ def parse_language(speaker, emote):
|
||||||
return emote, mapping
|
return emote, mapping
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||||
"""
|
"""
|
||||||
Read a textraw emote and parse it into an intermediary
|
Read a textraw emote and parse it into an intermediary
|
||||||
|
|
@ -379,7 +381,9 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||||
mapping[key] = obj if search_mode else (obj.db.sdesc or obj.key)
|
mapping[key] = obj if search_mode else (obj.db.sdesc or obj.key)
|
||||||
else:
|
else:
|
||||||
refname = marker_match.group()
|
refname = marker_match.group()
|
||||||
reflist = ["%s%s%s (%s)" % (inum+1, _NUM_SEP, _RE_PREFIX.sub("", refname), text)
|
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP,
|
||||||
|
_RE_PREFIX.sub("", refname), text,
|
||||||
|
" (%s)" % sender.key if sender == obj else "")
|
||||||
for inum, (obj, text) in enumerate(bestmatches) if score == maxscore]
|
for inum, (obj, text) in enumerate(bestmatches) if score == maxscore]
|
||||||
errors.append(_EMOTE_MULTIMATCH_ERROR.format(
|
errors.append(_EMOTE_MULTIMATCH_ERROR.format(
|
||||||
ref=marker_match.group(), reflist="\n ".join(reflist)))
|
ref=marker_match.group(), reflist="\n ".join(reflist)))
|
||||||
|
|
@ -401,50 +405,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||||
return string, mapping
|
return string, mapping
|
||||||
|
|
||||||
|
|
||||||
def receive_emote(sender, receiver, emote, sdesc_mapping, language_mapping):
|
def send_emote(sender, receivers, emote, anonymous_add="first"):
|
||||||
"""
|
|
||||||
Receive a pre-parsed emote.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
sender (Object): The object sending the emote.
|
|
||||||
receiver (Object): The object receiving (seeing) the emote.
|
|
||||||
emote (str): A pre-parsed emote string created with
|
|
||||||
`parse_emote`, with {#dbref} and {##nn} references for
|
|
||||||
objects and languages respectively.
|
|
||||||
sdesc_mapping (dict): A mapping between "#dbref" keys and
|
|
||||||
objects.
|
|
||||||
language_mapping (dict): A mapping "##dbref" and (langname, saytext).
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
finished_emote (str): The finished and ready-to-send emote
|
|
||||||
string, customized for receiver.
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
This function will translage all text back based both on sdesc
|
|
||||||
and recog mappings, but will give presedence to recog mappings.
|
|
||||||
"""
|
|
||||||
# we make a local copy that we can modify
|
|
||||||
mapping = copy(sdesc_mapping)
|
|
||||||
# overload mapping with receiver's recogs (which is on the same form)
|
|
||||||
try:
|
|
||||||
mapping.update(receiver.recog.ref2recog)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
# handle the language mapping, which always produce different keys ##nn
|
|
||||||
for key, (langname, saytext) in language_mapping.iteritems():
|
|
||||||
# color say's white
|
|
||||||
mapping[key] = "{w%s{n" % _LANGUAGE_TRANSLATE(sender, receiver, langname, saytext)
|
|
||||||
# make sure receiver always sees their real name
|
|
||||||
rkey = "#%i" % receiver.id
|
|
||||||
if rkey in mapping:
|
|
||||||
mapping[rkey] = receiver.key
|
|
||||||
|
|
||||||
#TODO - color handling
|
|
||||||
mapping = dict((key, "{b%s{n" % val) for key, val in mapping.iteritems())
|
|
||||||
receiver.msg(emote.format(**mapping))
|
|
||||||
|
|
||||||
|
|
||||||
def send_emote(sender, receivers, emote, no_anonymous=True):
|
|
||||||
"""
|
"""
|
||||||
Main access function for distribute an emote.
|
Main access function for distribute an emote.
|
||||||
|
|
||||||
|
|
@ -454,10 +415,12 @@ def send_emote(sender, receivers, emote, no_anonymous=True):
|
||||||
will also form the basis for which sdescs are
|
will also form the basis for which sdescs are
|
||||||
'valid' to use in the emote.
|
'valid' to use in the emote.
|
||||||
emote (str): The raw emote string as input by emoter.
|
emote (str): The raw emote string as input by emoter.
|
||||||
no_anonymous (bool, optional): Do not allow anonynous
|
anonymous_add (str or None, optional): If `sender` is not
|
||||||
emotes, that is, emotes without sender self-referencing,
|
self-referencing in the emote, this will auto-add
|
||||||
but add an extra reference to the end of the emote
|
`sender`'s data to the emote. Possible values are
|
||||||
if so.
|
- None: No auto-add at anonymous emote
|
||||||
|
- 'last': Add sender to the end of emote as [sender]
|
||||||
|
- 'first': Prepend sender to start of emote.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -468,15 +431,39 @@ def send_emote(sender, receivers, emote, no_anonymous=True):
|
||||||
sender.msg(err.message)
|
sender.msg(err.message)
|
||||||
return
|
return
|
||||||
|
|
||||||
if no_anonymous and not "#%i" % sender.id in sdesc_mapping:
|
if anonymous_add and not "#%i" % sender.id in sdesc_mapping:
|
||||||
# no self-reference in the emote - add to the end
|
# no self-reference in the emote - add to the end
|
||||||
key = "#%i" % sender.id
|
key = "#%i" % sender.id
|
||||||
emote = "%s [%s]" % (emote, "{%s}" % key)
|
|
||||||
sdesc_mapping[key] = sender.sdesc.get() or sender.key
|
sdesc_mapping[key] = sender.sdesc.get() or sender.key
|
||||||
|
if anonymous_add == 'first':
|
||||||
|
possessive = "" if emote.startswith('\'') else " "
|
||||||
|
emote = "%s%s%s" % ("{%s}" % key, possessive, emote)
|
||||||
|
else:
|
||||||
|
emote = "%s [%s]" % (emote, "{%s}" % key)
|
||||||
|
|
||||||
# broadcast emote
|
# broadcast emote to everyone
|
||||||
for receiver in receivers:
|
for receiver in receivers:
|
||||||
receive_emote(sender, receiver, emote, sdesc_mapping, language_mapping)
|
# we make a temporary copy that we can modify
|
||||||
|
mapping = copy(sdesc_mapping)
|
||||||
|
# overload mapping with receiver's recogs (which is on the same form)
|
||||||
|
try:
|
||||||
|
mapping.update(receiver.recog.ref2recog)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
# handle the language mapping, which always produce different keys ##nn
|
||||||
|
for key, (langname, saytext) in language_mapping.iteritems():
|
||||||
|
# color say's white
|
||||||
|
mapping[key] = "{w%s{n" % _LANGUAGE_TRANSLATE(sender, receiver, langname, saytext)
|
||||||
|
# make sure receiver always sees their real name
|
||||||
|
rkey = "#%i" % receiver.id
|
||||||
|
if rkey in mapping:
|
||||||
|
mapping[rkey] = receiver.key
|
||||||
|
|
||||||
|
#TODO - color handling
|
||||||
|
mapping = dict((key, "%s" % val) for key, val in mapping.iteritems())
|
||||||
|
|
||||||
|
# do the template replacement
|
||||||
|
receiver.msg(emote.format(**mapping))
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
@ -524,9 +511,9 @@ class CmdEmote(RPCommand): # replaces the main emote
|
||||||
# we also include ourselves here.
|
# we also include ourselves here.
|
||||||
emote = self.args
|
emote = self.args
|
||||||
targets = self.caller.location.contents
|
targets = self.caller.location.contents
|
||||||
if not emote.endswith("."):
|
if not emote.endswith((".", "!")):
|
||||||
emote = "%s." % emote
|
emote = "%s." % emote
|
||||||
send_emote(self.caller, targets, emote, no_anonymous=True)
|
send_emote(self.caller, targets, emote, anonymous_add='first')
|
||||||
|
|
||||||
|
|
||||||
class CmdSdesc(RPCommand): # set/look at own sdesc
|
class CmdSdesc(RPCommand): # set/look at own sdesc
|
||||||
|
|
@ -549,7 +536,9 @@ class CmdSdesc(RPCommand): # set/look at own sdesc
|
||||||
caller.msg("Usage: sdesc <sdesc-text>")
|
caller.msg("Usage: sdesc <sdesc-text>")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
sdesc = caller.sdesc.add(self.args)
|
# strip non-alfanum chars from end of sdesc
|
||||||
|
sdesc = _RE_CHAREND.sub("", self.args)
|
||||||
|
sdesc = caller.sdesc.add(sdesc)
|
||||||
caller.msg("Your sdesc was set to '%s'." % sdesc)
|
caller.msg("Your sdesc was set to '%s'." % sdesc)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -562,6 +551,8 @@ class CmdPose(Command): # set current pose and default pose
|
||||||
pose default <pose>
|
pose default <pose>
|
||||||
pose reset
|
pose reset
|
||||||
pose obj = <pose>
|
pose obj = <pose>
|
||||||
|
pose default obj = <pose>
|
||||||
|
pose reset obj =
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
pose leans against the tree
|
pose leans against the tree
|
||||||
|
|
@ -632,7 +623,7 @@ class CmdPose(Command): # set current pose and default pose
|
||||||
caller.msg("Default pose is now '%s %s'." % (target_name, pose))
|
caller.msg("Default pose is now '%s %s'." % (target_name, pose))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
caller.db.pose = pose
|
target.db.pose = pose
|
||||||
caller.msg("Pose will read '%s %s'." % (target_name, pose))
|
caller.msg("Pose will read '%s %s'." % (target_name, pose))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -675,13 +666,17 @@ class CmdRecog(Command): # assign personal alias to object in room
|
||||||
if nmatches == 0:
|
if nmatches == 0:
|
||||||
caller.msg(_EMOTE_NOMATCH_ERROR.format(ref=sdesc))
|
caller.msg(_EMOTE_NOMATCH_ERROR.format(ref=sdesc))
|
||||||
elif nmatches > 1:
|
elif nmatches > 1:
|
||||||
reflist = ["%s%s%s (%s)" % (inum+1, _NUM_SEP, _RE_PREFIX.sub("", sdesc), obj.sdesc.get())
|
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP,
|
||||||
|
_RE_PREFIX.sub("", sdesc), caller.recog.get(obj),
|
||||||
|
" (%s)" % caller.key if caller == obj else "")
|
||||||
for inum, obj in enumerate(matches)]
|
for inum, obj in enumerate(matches)]
|
||||||
caller.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=sdesc,reflist="\n ".join(reflist)))
|
caller.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=sdesc,reflist="\n ".join(reflist)))
|
||||||
else:
|
else:
|
||||||
# we have all we need, add the recog alias
|
# we have all we need, add the recog alias
|
||||||
|
obj = matches[0]
|
||||||
|
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||||
alias = caller.recog.add(obj, alias)
|
alias = caller.recog.add(obj, alias)
|
||||||
caller.msg("You will now remember {w%s{n as {w%s{n." % (obj.db.sdesc, alias))
|
caller.msg("You will now remember {w%s{n as {w%s{n." % (sdesc, alias))
|
||||||
|
|
||||||
|
|
||||||
class CmdLanguage(Command): # list available languages
|
class CmdLanguage(Command): # list available languages
|
||||||
|
|
@ -871,10 +866,11 @@ class RecogHandler(object):
|
||||||
|
|
||||||
# mapping #dbref:obj
|
# mapping #dbref:obj
|
||||||
key = "#%i" % obj.id
|
key = "#%i" % obj.id
|
||||||
self.db._ref2recog[key] = recog
|
print "self.obj:", self.obj, self.obj.db._ref2recog
|
||||||
self.db._obj2recog[obj] = recog
|
self.obj.db._recog_ref2recog[key] = recog
|
||||||
|
self.obj.db._recog_obj2recog[obj] = recog
|
||||||
regex = ordered_permutation_regex(cleaned_recog)
|
regex = ordered_permutation_regex(cleaned_recog)
|
||||||
self.db._obj2regex[obj] = regex
|
self.obj.db._recog_obj2regex[obj] = regex
|
||||||
# local caching
|
# local caching
|
||||||
self.ref2recog[key] = recog
|
self.ref2recog[key] = recog
|
||||||
self.obj2recog[obj] = recog
|
self.obj2recog[obj] = recog
|
||||||
|
|
@ -883,14 +879,16 @@ class RecogHandler(object):
|
||||||
|
|
||||||
def get(self, obj):
|
def get(self, obj):
|
||||||
"""
|
"""
|
||||||
Get recog replacement string, if one exists.
|
Get recog replacement string, if one exists, otherwise
|
||||||
|
get sdesc and as a last resort, the object's key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
obj (Object): The object, whose sdesc to replace
|
obj (Object): The object, whose sdesc to replace
|
||||||
Returns:
|
Returns:
|
||||||
recog (str): The replacement string to use.
|
recog (str): The replacement string to use.
|
||||||
"""
|
"""
|
||||||
return self.obj2recog.get(obj)
|
return self.obj2recog.get(obj, obj.sdesc.get()
|
||||||
|
if hasattr(obj, "sdesc") else obj.key)
|
||||||
|
|
||||||
def remove(self, obj):
|
def remove(self, obj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -900,9 +898,9 @@ class RecogHandler(object):
|
||||||
obj (Object): The object for which to remove recog.
|
obj (Object): The object for which to remove recog.
|
||||||
"""
|
"""
|
||||||
if obj in self.db.obj2recog:
|
if obj in self.db.obj2recog:
|
||||||
del self.db.obj2recog[obj]
|
del self.db._recog_obj2recog[obj]
|
||||||
del self.db.obj2regex[obj]
|
del self.db._recog_obj2regex[obj]
|
||||||
del self.db.ref2regex["#%i" % obj.id]
|
del self.db._recog_ref2regex["#%i" % obj.id]
|
||||||
self._cache()
|
self._cache()
|
||||||
|
|
||||||
def get_regex_tuple(self, obj):
|
def get_regex_tuple(self, obj):
|
||||||
|
|
@ -953,17 +951,36 @@ class RPObject(DefaultObject):
|
||||||
if (isinstance(searchdata, basestring) and not
|
if (isinstance(searchdata, basestring) and not
|
||||||
(kwargs.get("global_search") or
|
(kwargs.get("global_search") or
|
||||||
kwargs.get("candidates"))):
|
kwargs.get("candidates"))):
|
||||||
matches = parse_sdescs_and_recogs(self, self.location.contents,
|
# searchdata is a string; common self-references
|
||||||
|
if searchdata.lower() in ("here", ):
|
||||||
|
return [self.location] if "quiet" in kwargs else self.location
|
||||||
|
if searchdata.lower() in ("me", "self",):
|
||||||
|
return [self] if "quiet" in kwargs else self
|
||||||
|
if searchdata.lower() == self.key.lower():
|
||||||
|
return [self] if "quiet" in kwargs else self
|
||||||
|
|
||||||
|
# sdesc/recog matching
|
||||||
|
candidates = self.location.contents
|
||||||
|
matches = parse_sdescs_and_recogs(self, candidates,
|
||||||
_PREFIX + searchdata, search_mode=True)
|
_PREFIX + searchdata, search_mode=True)
|
||||||
nmatches = len(matches)
|
nmatches = len(matches)
|
||||||
if nmatches == 1:
|
if nmatches == 1:
|
||||||
return matches[0]
|
return matches[0]
|
||||||
elif nmatches > 1:
|
elif nmatches > 1:
|
||||||
# multimatch
|
# multimatch
|
||||||
reflist = ["%s%s%s (%s)" % (inum+1, _NUM_SEP, searchdata, obj.sdesc.get())
|
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP, searchdata, self.recog.get(obj),
|
||||||
|
" (%s)" % self.key if self == obj else "")
|
||||||
for inum, obj in enumerate(matches)]
|
for inum, obj in enumerate(matches)]
|
||||||
self.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=searchdata,reflist="\n ".join(reflist)))
|
self.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=searchdata,reflist="\n ".join(reflist)))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not self.locks.check_lockstring(self, "perm(Builders)"):
|
||||||
|
# we block lookup unless we have access to continue
|
||||||
|
if "nofound_string" in kwargs:
|
||||||
|
self.msg(kwargs["nofound_string"])
|
||||||
|
else:
|
||||||
|
self.msg("There is nothing here called '%s'." % searchdata)
|
||||||
|
return
|
||||||
# fall back to normal search
|
# fall back to normal search
|
||||||
return super(RPObject, self).search(searchdata, **kwargs)
|
return super(RPObject, self).search(searchdata, **kwargs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -503,6 +503,8 @@ class LockHandler(object):
|
||||||
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
|
||||||
or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))):
|
or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))):
|
||||||
return True
|
return True
|
||||||
|
if not ":" in lockstring:
|
||||||
|
lockstring = "%s:%s" % ("_dummy", lockstring)
|
||||||
|
|
||||||
locks = self._parse_lockstring(lockstring)
|
locks = self._parse_lockstring(lockstring)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue