mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 15:37:17 +02:00
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.
|
||||
_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
|
||||
_RE_REF_LANG = re.compile(r"\{+\##([0-9]+)\}+")
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
||||
"""
|
||||
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)
|
||||
else:
|
||||
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]
|
||||
errors.append(_EMOTE_MULTIMATCH_ERROR.format(
|
||||
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
|
||||
|
||||
|
||||
def receive_emote(sender, receiver, emote, sdesc_mapping, language_mapping):
|
||||
"""
|
||||
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):
|
||||
def send_emote(sender, receivers, emote, anonymous_add="first"):
|
||||
"""
|
||||
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
|
||||
'valid' to use in the emote.
|
||||
emote (str): The raw emote string as input by emoter.
|
||||
no_anonymous (bool, optional): Do not allow anonynous
|
||||
emotes, that is, emotes without sender self-referencing,
|
||||
but add an extra reference to the end of the emote
|
||||
if so.
|
||||
anonymous_add (str or None, optional): If `sender` is not
|
||||
self-referencing in the emote, this will auto-add
|
||||
`sender`'s data to the emote. Possible values are
|
||||
- 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:
|
||||
|
|
@ -468,15 +431,39 @@ def send_emote(sender, receivers, emote, no_anonymous=True):
|
|||
sender.msg(err.message)
|
||||
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
|
||||
key = "#%i" % sender.id
|
||||
emote = "%s [%s]" % (emote, "{%s}" % 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:
|
||||
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.
|
||||
emote = self.args
|
||||
targets = self.caller.location.contents
|
||||
if not emote.endswith("."):
|
||||
if not emote.endswith((".", "!")):
|
||||
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
|
||||
|
|
@ -549,7 +536,9 @@ class CmdSdesc(RPCommand): # set/look at own sdesc
|
|||
caller.msg("Usage: sdesc <sdesc-text>")
|
||||
return
|
||||
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)
|
||||
|
||||
|
||||
|
|
@ -562,6 +551,8 @@ class CmdPose(Command): # set current pose and default pose
|
|||
pose default <pose>
|
||||
pose reset
|
||||
pose obj = <pose>
|
||||
pose default obj = <pose>
|
||||
pose reset obj =
|
||||
|
||||
Examples:
|
||||
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))
|
||||
return
|
||||
else:
|
||||
caller.db.pose = pose
|
||||
target.db.pose = 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:
|
||||
caller.msg(_EMOTE_NOMATCH_ERROR.format(ref=sdesc))
|
||||
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)]
|
||||
caller.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=sdesc,reflist="\n ".join(reflist)))
|
||||
else:
|
||||
# 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)
|
||||
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
|
||||
|
|
@ -871,10 +866,11 @@ class RecogHandler(object):
|
|||
|
||||
# mapping #dbref:obj
|
||||
key = "#%i" % obj.id
|
||||
self.db._ref2recog[key] = recog
|
||||
self.db._obj2recog[obj] = recog
|
||||
print "self.obj:", self.obj, self.obj.db._ref2recog
|
||||
self.obj.db._recog_ref2recog[key] = recog
|
||||
self.obj.db._recog_obj2recog[obj] = recog
|
||||
regex = ordered_permutation_regex(cleaned_recog)
|
||||
self.db._obj2regex[obj] = regex
|
||||
self.obj.db._recog_obj2regex[obj] = regex
|
||||
# local caching
|
||||
self.ref2recog[key] = recog
|
||||
self.obj2recog[obj] = recog
|
||||
|
|
@ -883,14 +879,16 @@ class RecogHandler(object):
|
|||
|
||||
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:
|
||||
obj (Object): The object, whose sdesc to replace
|
||||
Returns:
|
||||
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):
|
||||
"""
|
||||
|
|
@ -900,9 +898,9 @@ class RecogHandler(object):
|
|||
obj (Object): The object for which to remove recog.
|
||||
"""
|
||||
if obj in self.db.obj2recog:
|
||||
del self.db.obj2recog[obj]
|
||||
del self.db.obj2regex[obj]
|
||||
del self.db.ref2regex["#%i" % obj.id]
|
||||
del self.db._recog_obj2recog[obj]
|
||||
del self.db._recog_obj2regex[obj]
|
||||
del self.db._recog_ref2regex["#%i" % obj.id]
|
||||
self._cache()
|
||||
|
||||
def get_regex_tuple(self, obj):
|
||||
|
|
@ -953,17 +951,36 @@ class RPObject(DefaultObject):
|
|||
if (isinstance(searchdata, basestring) and not
|
||||
(kwargs.get("global_search") or
|
||||
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)
|
||||
nmatches = len(matches)
|
||||
if nmatches == 1:
|
||||
return matches[0]
|
||||
elif nmatches > 1:
|
||||
# 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)]
|
||||
self.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=searchdata,reflist="\n ".join(reflist)))
|
||||
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
|
||||
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, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))):
|
||||
return True
|
||||
if not ":" in lockstring:
|
||||
lockstring = "%s:%s" % ("_dummy", lockstring)
|
||||
|
||||
locks = self._parse_lockstring(lockstring)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue