Emote system under testing, not working right just yet.

This commit is contained in:
Griatch 2015-09-07 23:16:04 +02:00
parent b1f5adb620
commit 16247e490e

View file

@ -77,6 +77,7 @@ _EMOTE_MULTIMATCH_ERROR = \
_LANGUAGE_NOMATCH_ERROR = \ _LANGUAGE_NOMATCH_ERROR = \
"""{{RNo language named {{r{langname}{{n""" """{{RNo language named {{r{langname}{{n"""
_RE_FLAGS = re.MULTILINE + re.IGNORECASE + re.UNICODE
# The prefix is the (single-character) symbol used to find the start # The prefix is the (single-character) symbol used to find the start
# of a object reference, such as /tall (note that # of a object reference, such as /tall (note that
@ -94,15 +95,15 @@ _NUM_SEP = "-"
# separate multimatches from one another and word is the first word in the # separate multimatches from one another and word is the first word in the
# marker. So entering "/tall man" will return groups ("", "tall") # marker. So entering "/tall man" will return groups ("", "tall")
# and "/2-tall man" will return groups ("2", "tall"). # and "/2-tall man" will return groups ("2", "tall").
_RE_OBJ_REF_START = re.compile(r"%s(?:([0-9]+)%s)*(\w+)" % (_PREFIX, _NUM_SEP), _RE_OBJ_REF_START = re.compile(r"%s(?:([0-9]+)%s)*(\w+)" %
re.MULTILINE + re.UNICODE + re.IGNORECASE) (_PREFIX, _NUM_SEP), _RE_FLAGS)
# Reference markers are used internally when distributing the emote to # Reference markers are used internally when distributing the emote to
# all that can see it. They are never seen by players and are on the form {#dbref}. # all that can see it. They are never seen by players and are on the form {#dbref}.
_RE_REF = re.compile(r"\{+\#([0-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.UNICODE + re.IGNORECASE) _RE_SELF_REF = re.compile(r"/me|@", _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]+)\}+")
@ -110,6 +111,7 @@ _RE_REF_LANG = re.compile(r"\{+\##([0-9]+)\}+")
# this regex returns in groups (langname, say), where langname can be empty. # this regex returns in groups (langname, say), where langname can be empty.
_RE_LANGUAGE = re.compile(r"(?:(\w+))*(\".+?\")") _RE_LANGUAGE = re.compile(r"(?:(\w+))*(\".+?\")")
#TODO #TODO
# make this into a pluggable language module for handling # make this into a pluggable language module for handling
# language errors and translations. # language errors and translations.
@ -296,7 +298,7 @@ def parse_sdescs_and_recogs(sender, candidates, emote):
if _RE_SELF_REF.search(emote): if _RE_SELF_REF.search(emote):
key = "#%i" % sender.id key = "#%i" % sender.id
emote = _RE_SELF_REF.sub("{%s}" % key, emote) emote = _RE_SELF_REF.sub("{%s}" % key, emote)
mapping[key] = sender mapping[key] = sender.db.sdesc or sender.key
# we now loop over all references and analyze them # we now loop over all references and analyze them
errors = [] errors = []
@ -312,11 +314,12 @@ def parse_sdescs_and_recogs(sender, candidates, emote):
istart = istart0 + 1 + (len(num_identifier) + 1 if num_identifier else 0) istart = istart0 + 1 + (len(num_identifier) + 1 if num_identifier else 0)
# loop over all candidate regexes and match against the string following the match # loop over all candidate regexes and match against the string following the match
matches = ((re_match(reg, emote[istart:], re.M + re.M + re.U), obj, text) for reg, obj, text in candidate_regexes) matches = ((re_match(reg, emote[istart:], _RE_FLAGS), obj, text)
for reg, obj, text in candidate_regexes)
# score matches by how long part of the string was matched # score matches by how long part of the string was matched
matches = [(match.endpos if match else -1, obj, text) for match, obj, text in matches] matches = [(match.endpos if match else -1, obj, text) for match, obj, text in matches]
maxscore = max(score for score, obj in matches) maxscore = max(score for score, obj, text in matches)
# analyze result # analyze result
if maxscore == -1: if maxscore == -1:
@ -325,35 +328,36 @@ def parse_sdescs_and_recogs(sender, candidates, emote):
continue continue
# we have a valid maxscore, extract all matches with this value # we have a valid maxscore, extract all matches with this value
bestmatches = [obj for score, obj in matches if maxscore == score] bestmatches = [(obj, text) for score, obj, text in matches if maxscore == score]
nmatches = len(bestmatches) nmatches = len(bestmatches)
print "nmatches:", nmatches, bestmatches
if nmatches == 1: if nmatches == 1:
# an exact match. # an exact match.
obj = bestmatches[0] obj = bestmatches[0][0]
if nmatches: if nmatches:
# several matches have the same score. # several matches have the same score.
inum = max(0, int(num_identifier) - 1) if num_identifier else None inum = max(0, int(num_identifier) - 1) if num_identifier else None
if all(bestmatches[0].id == obj.id for obj in bestmatches): if all(bestmatches[0][0].id == obj.id for obj, text in bestmatches):
# multi-matches all references the same obj (could happen with clashing recogs/sdescs) # multi-matches all references the same obj (could happen with clashing recogs/sdescs)
obj = bestmatches[0] obj = bestmatches[0][0]
else: else:
# was a numberical identifier given to help us separate the multi-match? # was a numberical identifier given to help us separate the multi-match?
if inum is None or inum > nmatches: if inum is None or inum > nmatches:
# no match or invalid match id given # no match or invalid match id given
refname = marker_match.group() refname = marker_match.group()
reflist = ["%s%s%s (%s)" % (inum, _NUM_SEP, refname, text) reflist = ["%s%s%s (%s)" % (inum, _NUM_SEP, refname, text)
for inum, (score, obj, text) in enumerate(bestmatches) if score == maxscore] for inum, (obj, text) in enumerate(bestmatches) if score == maxscore]
errors.append(_EMOTE_MULTIMATCH_ERROR.format(ref=marker_match.group(), reflist=reflist)) errors.append(_EMOTE_MULTIMATCH_ERROR.format(ref=marker_match.group(), reflist=reflist))
continue continue
else: else:
# A valid inum is given. Use this to separate data # A valid inum is given. Use this to separate data
obj = bestmatches[inum] obj = bestmatches[inum][0]
# if we get to this point we have identifed a local object tied to this sdesc or recog marker. # if we get to this point we have identifed a local object tied to this sdesc or recog marker.
# we replace it with the interal representation on the form {#dbref}. # we replace it with the interal representation on the form {#dbref}.
key = "#%i" % obj.id key = "#%i" % obj.id
emote = emote[:istart0] + "{%s}" % key + emote[score:] emote = emote[:istart0] + "{%s}" % key + emote[score:]
mapping[key] = obj mapping[key] = obj.db.sdesc or obj.key
if errors: if errors:
# make sure to not let errors through. # make sure to not let errors through.
@ -386,6 +390,7 @@ def receive_emote(sender, receiver, emote, sdesc_mapping, language_mapping):
This function will translage all text back based both on sdesc This function will translage all text back based both on sdesc
and recog mappings, but will give presedence to recog mappings. and recog mappings, but will give presedence to recog mappings.
""" """
print "receive_emote:", sender, receiver, emote, sdesc_mapping, language_mapping
# we make a local copy that we can modify # we make a local copy that we can modify
mapping = copy(sdesc_mapping) mapping = copy(sdesc_mapping)
# overload mapping with receiver's recogs (which is on the same form) # overload mapping with receiver's recogs (which is on the same form)
@ -394,7 +399,7 @@ def receive_emote(sender, receiver, emote, sdesc_mapping, language_mapping):
# handle the language mapping, which always produce different keys ##nn # handle the language mapping, which always produce different keys ##nn
for key, (langname, saytext) in language_mapping.iteritems(): for key, (langname, saytext) in language_mapping.iteritems():
mapping[key] = _LANGUAGE_TRANSLATE(sender, receiver, langname, saytext) mapping[key] = _LANGUAGE_TRANSLATE(sender, receiver, langname, saytext)
return emote.format(**mapping) receiver.msg(emote.format(**mapping))
def send_emote(sender, receivers, emote, no_anonymous=True): def send_emote(sender, receivers, emote, no_anonymous=True):
@ -422,11 +427,11 @@ def send_emote(sender, receivers, emote, no_anonymous=True):
sender.msg(err.message) sender.msg(err.message)
return return
if no_anonymous and not sender in sdesc_mapping.values(): if no_anonymous 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) emote = "%s [%s]" % (emote, "{%s}" % key)
sdesc_mapping[key] = sender sdesc_mapping[key] = sender.db.sdesc or sender.key
# broadcast emote # broadcast emote
for receiver in receivers: for receiver in receivers: