added more comments, cleaned up a couple lines
This commit is contained in:
parent
0769ffbef1
commit
e86b81917b
1 changed files with 71 additions and 33 deletions
|
|
@ -149,7 +149,6 @@ Extra Installation Instructions:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from re import escape as re_escape
|
|
||||||
from string import punctuation
|
from string import punctuation
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from evennia.objects.objects import DefaultObject, DefaultCharacter
|
from evennia.objects.objects import DefaultObject, DefaultCharacter
|
||||||
|
|
@ -338,13 +337,18 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
||||||
- says, "..." are
|
- says, "..." are
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
# build a list of candidates with all possible referrable names
|
||||||
|
# include 'me' keyword for self-ref
|
||||||
candidate_map = [(sender, 'me')]
|
candidate_map = [(sender, 'me')]
|
||||||
for obj in candidates:
|
for obj in candidates:
|
||||||
|
# check if sender has any recogs for obj and add
|
||||||
if hasattr(sender, "recog"):
|
if hasattr(sender, "recog"):
|
||||||
if recog := sender.recog.get(obj):
|
if recog := sender.recog.get(obj):
|
||||||
candidate_map.append((obj, recog))
|
candidate_map.append((obj, recog))
|
||||||
|
# check if obj has an sdesc and add
|
||||||
if hasattr(obj, "sdesc"):
|
if hasattr(obj, "sdesc"):
|
||||||
candidate_map.append((obj, obj.sdesc.get()))
|
candidate_map.append((obj, obj.sdesc.get()))
|
||||||
|
# if no sdesc, include key plus aliases instead
|
||||||
else:
|
else:
|
||||||
candidate_map += [(obj, obj.key)] + [(obj, alias) for alias in obj.aliases.all()]
|
candidate_map += [(obj, obj.key)] + [(obj, alias) for alias in obj.aliases.all()]
|
||||||
|
|
||||||
|
|
@ -372,32 +376,39 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
||||||
tail = string[match_index+1:]
|
tail = string[match_index+1:]
|
||||||
|
|
||||||
if search_mode:
|
if search_mode:
|
||||||
|
# match the candidates against the whole search string
|
||||||
rquery = "".join([r"\b(" + re.escape(word.strip(punctuation)) + r").*" for word in iter(tail.split())])
|
rquery = "".join([r"\b(" + re.escape(word.strip(punctuation)) + r").*" for word in iter(tail.split())])
|
||||||
rquery = re.compile(rquery, _RE_FLAGS)
|
matches = ((re.search(rquery, text, _RE_FLAGS), obj, text) for obj, text in candidate_map)
|
||||||
matches = ((rquery.search(text), obj, text) for obj, text in candidate_map)
|
# filter out any non-matching candidates
|
||||||
bestmatches = [(obj, match.group()) for match, obj, text in matches if match]
|
bestmatches = [(obj, match.group()) for match, obj, text in matches if match]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# to find the longest match, we start from the marker and lengthen the
|
||||||
|
# match query one word at a time.
|
||||||
word_list = []
|
word_list = []
|
||||||
bestmatches = []
|
bestmatches = []
|
||||||
|
# preserve punctuation when splitting
|
||||||
tail = re.split('(\W)', tail)
|
tail = re.split('(\W)', tail)
|
||||||
istart = 0
|
iend = 0
|
||||||
for i, item in enumerate(tail):
|
for i, item in enumerate(tail):
|
||||||
|
# don't add non-word characters to the search query
|
||||||
if not item.isalpha():
|
if not item.isalpha():
|
||||||
continue
|
continue
|
||||||
word_list.append(item)
|
word_list.append(item)
|
||||||
rquery = "".join([r"\b(" + re.escape(word) + r").*" for word in word_list])
|
rquery = "".join([r"\b(" + re.escape(word) + r").*" for word in word_list])
|
||||||
rquery = re.compile(rquery, _RE_FLAGS)
|
# match candidates against the current set of words
|
||||||
matches = ((rquery.search(text), obj, text) for obj, text in candidate_map)
|
matches = ((re.search(re.search(rquery, text, _RE_FLAGS), obj, text) for obj, text in candidate_map)
|
||||||
matches = [(obj, match.group()) for match, obj, text in matches if match]
|
matches = [(obj, match.group()) for match, obj, text in matches if match]
|
||||||
if len(matches) == 0:
|
if len(matches) == 0:
|
||||||
# no matches at this length, keep previous iteration
|
# no matches at this length, keep previous iteration as best
|
||||||
break
|
break
|
||||||
# set latest match set as best matches
|
# since this is the longest match so far, set latest match set as best matches
|
||||||
bestmatches = matches
|
bestmatches = matches
|
||||||
istart = i
|
# save current index as end point of matched text
|
||||||
|
iend = i
|
||||||
|
|
||||||
tail = "".join(tail[istart+1:])
|
# recombine remainder of emote back into a string
|
||||||
|
tail = "".join(tail[iend+1:])
|
||||||
|
|
||||||
nmatches = len(bestmatches)
|
nmatches = len(bestmatches)
|
||||||
|
|
||||||
|
|
@ -448,7 +459,8 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
||||||
elif matchtext.islower():
|
elif matchtext.islower():
|
||||||
case = "v"
|
case = "v"
|
||||||
|
|
||||||
key = "#%i%s" % (obj.id, case)
|
key = f"#{obj.id}{case}"
|
||||||
|
# recombine emote with matched text replaced by ref
|
||||||
string = f"{head}{{{key}}}{tail}"
|
string = f"{head}{{{key}}}{tail}"
|
||||||
mapping[key] = obj
|
mapping[key] = obj
|
||||||
|
|
||||||
|
|
@ -534,14 +546,17 @@ def send_emote(sender, receivers, emote, anonymous_add="first", **kwargs):
|
||||||
# if anonymous_add is passed as a kwarg, collect and remove it from kwargs
|
# if anonymous_add is passed as a kwarg, collect and remove it from kwargs
|
||||||
if "anonymous_add" in kwargs:
|
if "anonymous_add" in kwargs:
|
||||||
anonymous_add = kwargs.pop("anonymous_add")
|
anonymous_add = kwargs.pop("anonymous_add")
|
||||||
|
# make sure to catch all possible self-refs
|
||||||
self_refs = [f"{skey}{ref}" for ref in ('t','^','v','~','')]
|
self_refs = [f"{skey}{ref}" for ref in ('t','^','v','~','')]
|
||||||
if anonymous_add and not any(1 for tag in obj_mapping if tag in self_refs):
|
if anonymous_add and not any(1 for tag in obj_mapping if tag in self_refs):
|
||||||
# no self-reference in the emote - add to the end
|
# no self-reference in the emote - add it
|
||||||
if anonymous_add == "first":
|
if anonymous_add == "first":
|
||||||
skey = skey + 't'
|
# add case flag for initial caps
|
||||||
|
skey += 't'
|
||||||
possessive = "" if emote.startswith("'") else " "
|
possessive = "" if emote.startswith("'") else " "
|
||||||
emote = "%s%s%s" % ("{{%s}}" % skey, possessive, emote)
|
emote = "%s%s%s" % ("{{%s}}" % skey, possessive, emote)
|
||||||
else:
|
else:
|
||||||
|
# add it to the end
|
||||||
emote = "%s [%s]" % (emote, "{{%s}}" % skey)
|
emote = "%s [%s]" % (emote, "{{%s}}" % skey)
|
||||||
obj_mapping[skey] = sender
|
obj_mapping[skey] = sender
|
||||||
|
|
||||||
|
|
@ -562,10 +577,11 @@ def send_emote(sender, receivers, emote, anonymous_add="first", **kwargs):
|
||||||
# the form {{#num}} to {#num} markers ready to sdesc-map in the next step.
|
# the form {{#num}} to {#num} markers ready to sdesc-map in the next step.
|
||||||
sendemote = emote.format(**receiver_lang_mapping)
|
sendemote = emote.format(**receiver_lang_mapping)
|
||||||
|
|
||||||
|
# map the ref keys to sdescs
|
||||||
receiver_sdesc_mapping = dict(
|
receiver_sdesc_mapping = dict(
|
||||||
(
|
(
|
||||||
ref,
|
ref,
|
||||||
obj.get_display_name(receiver, ref=ref, no_id=True),
|
obj.get_display_name(receiver, noid=True),
|
||||||
)
|
)
|
||||||
for ref, obj in obj_mapping.items()
|
for ref, obj in obj_mapping.items()
|
||||||
)
|
)
|
||||||
|
|
@ -1117,7 +1133,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||||
if forget_mode:
|
if forget_mode:
|
||||||
# remove existing recog
|
# remove existing recog
|
||||||
caller.recog.remove(obj)
|
caller.recog.remove(obj)
|
||||||
caller.msg("%s will now know them only as '%s'." % (caller.key, obj.get_display_name(caller, no_id=True)))
|
caller.msg("%s will now know them only as '%s'." % (caller.key, obj.get_display_name(caller, noid=True)))
|
||||||
else:
|
else:
|
||||||
# set recog
|
# set recog
|
||||||
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||||
|
|
@ -1397,24 +1413,34 @@ class ContribRPObject(DefaultObject):
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
pose (bool): Include the pose (if available) in the return.
|
pose (bool): Include the pose (if available) in the return.
|
||||||
ref (str): Specifies the capitalization for the displayed name.
|
ref (str): The reference marker found in string to replace.
|
||||||
|
This is on the form #{num}{case}, like '#12^', where
|
||||||
|
the number is a processing location in the string and the
|
||||||
|
case symbol indicates the case of the original tag input
|
||||||
|
- `t` - input was Titled, like /Tall
|
||||||
|
- `^` - input was all uppercase, like /TALL
|
||||||
|
- `v` - input was all lowercase, like /tall
|
||||||
|
- `~` - input case should be kept, or was mixed-case
|
||||||
|
noid (bool): Don't show DBREF even if viewer has control access.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
name (str): A string of the sdesc containing the name of the object,
|
name (str): A string of the sdesc containing the name of the object,
|
||||||
if this is defined.
|
if this is defined. By default, included the DBREF if this user
|
||||||
including the DBREF if this user is privileged to control
|
is privileged to control said object.
|
||||||
said object.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
idstr = "(#%s)" % self.id if self.access(looker, access_type="control") and not kwargs.get("no_id", False) else ""
|
idstr = "(#%s)" % self.id if self.access(looker, access_type="control") and not kwargs.get("noid",False) else ""
|
||||||
ref = kwargs.get("ref","~")
|
ref = kwargs.get("ref","~")
|
||||||
|
|
||||||
if looker == self:
|
if looker == self:
|
||||||
|
# always show your own key
|
||||||
sdesc = self.key
|
sdesc = self.key
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
# get the sdesc looker should see
|
||||||
sdesc = looker.get_sdesc(self, ref=ref)
|
sdesc = looker.get_sdesc(self, ref=ref)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
# use own sdesc as a fallback
|
||||||
sdesc = self.sdesc.get()
|
sdesc = self.sdesc.get()
|
||||||
pose = " %s" % (self.db.pose or "is here.") if kwargs.get("pose", False) else ""
|
pose = " %s" % (self.db.pose or "is here.") if kwargs.get("pose", False) else ""
|
||||||
return "%s%s%s" % (sdesc, idstr, pose)
|
return "%s%s%s" % (sdesc, idstr, pose)
|
||||||
|
|
@ -1426,6 +1452,10 @@ class ContribRPObject(DefaultObject):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
looker (Object): Object doing the looking.
|
looker (Object): Object doing the looking.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string (str): A string containing the name, appearance and contents
|
||||||
|
of the object.
|
||||||
"""
|
"""
|
||||||
if not looker:
|
if not looker:
|
||||||
return ""
|
return ""
|
||||||
|
|
@ -1449,6 +1479,7 @@ class ContribRPObject(DefaultObject):
|
||||||
string += "\n|wExits:|n " + ", ".join(exits)
|
string += "\n|wExits:|n " + ", ".join(exits)
|
||||||
if users or things:
|
if users or things:
|
||||||
string += "\n " + "\n ".join(users + things)
|
string += "\n " + "\n ".join(users + things)
|
||||||
|
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1479,19 +1510,27 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
pose (bool): Include the pose (if available) in the return.
|
pose (bool): Include the pose (if available) in the return.
|
||||||
|
ref (str): The reference marker found in string to replace.
|
||||||
|
This is on the form #{num}{case}, like '#12^', where
|
||||||
|
the number is a processing location in the string and the
|
||||||
|
case symbol indicates the case of the original tag input
|
||||||
|
- `t` - input was Titled, like /Tall
|
||||||
|
- `^` - input was all uppercase, like /TALL
|
||||||
|
- `v` - input was all lowercase, like /tall
|
||||||
|
- `~` - input case should be kept, or was mixed-case
|
||||||
|
noid (bool): Don't show DBREF even if viewer has control access.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
name (str): A string of the sdesc containing the name of the object,
|
name (str): A string of the sdesc containing the name of the object,
|
||||||
if this is defined.
|
if this is defined. By default, included the DBREF if this user
|
||||||
including the DBREF if this user is privileged to control
|
is privileged to control said object.
|
||||||
said object.
|
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
The RPCharacter version adds additional processing to sdescs to make
|
The RPCharacter version adds additional processing to sdescs to make
|
||||||
characters stand out from other objects.
|
characters stand out from other objects.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
idstr = "(#%s)" % self.id if self.access(looker, access_type="control") and not kwargs.get("no_id",False) else ""
|
idstr = "(#%s)" % self.id if self.access(looker, access_type="control") and not kwargs.get("noid",False) else ""
|
||||||
ref = kwargs.get("ref","~")
|
ref = kwargs.get("ref","~")
|
||||||
|
|
||||||
if looker == self:
|
if looker == self:
|
||||||
|
|
@ -1512,10 +1551,8 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
|
||||||
super().at_object_creation()
|
super().at_object_creation()
|
||||||
|
|
||||||
self.db._sdesc = ""
|
self.db._sdesc = ""
|
||||||
self.db._sdesc_regex = ""
|
|
||||||
|
|
||||||
self.db._recog_ref2recog = {}
|
self.db._recog_ref2recog = {}
|
||||||
self.db._recog_obj2regex = {}
|
|
||||||
self.db._recog_obj2recog = {}
|
self.db._recog_obj2recog = {}
|
||||||
|
|
||||||
self.cmdset.add(RPSystemCmdSet, persistent=True)
|
self.cmdset.add(RPSystemCmdSet, persistent=True)
|
||||||
|
|
@ -1538,7 +1575,7 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
|
||||||
|
|
||||||
def get_sdesc(self, obj, process=False, **kwargs):
|
def get_sdesc(self, obj, process=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
Single hook method to handle getting recogs with sdesc fallback in an
|
Single method to handle getting recogs with sdesc fallback in an
|
||||||
aware manner, to allow separate processing of recogs from sdescs.
|
aware manner, to allow separate processing of recogs from sdescs.
|
||||||
Gets the sdesc or recog for obj from the view of self.
|
Gets the sdesc or recog for obj from the view of self.
|
||||||
|
|
||||||
|
|
@ -1546,19 +1583,20 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
|
||||||
obj (Object): the object whose sdesc or recog is being gotten
|
obj (Object): the object whose sdesc or recog is being gotten
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
process (bool): If True, the sdesc/recog is run through the
|
process (bool): If True, the sdesc/recog is run through the
|
||||||
appropriate process_X method.
|
appropriate process method (process_sdesc or process_recog)
|
||||||
"""
|
"""
|
||||||
|
# always see own key
|
||||||
if obj == self:
|
if obj == self:
|
||||||
recog = self.key
|
recog = self.key
|
||||||
sdesc = self.key
|
sdesc = self.key
|
||||||
else:
|
else:
|
||||||
try:
|
# first check if we have a recog for this object
|
||||||
recog = self.recog.get(obj)
|
recog = self.recog.get(obj)
|
||||||
except AttributeError:
|
# set sdesc to recog, using sdesc as a fallback, or the object's key if no sdesc
|
||||||
recog = None
|
|
||||||
sdesc = recog or (hasattr(obj, "sdesc") and obj.sdesc.get()) or obj.key
|
sdesc = recog or (hasattr(obj, "sdesc") and obj.sdesc.get()) or obj.key
|
||||||
|
|
||||||
if process:
|
if process:
|
||||||
|
# process the sdesc as a recog if a recog was found, else as an sdesc
|
||||||
sdesc = (self.process_recog if recog else self.process_sdesc)(sdesc, obj, **kwargs)
|
sdesc = (self.process_recog if recog else self.process_sdesc)(sdesc, obj, **kwargs)
|
||||||
|
|
||||||
return sdesc
|
return sdesc
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue