def addAction(self, trigger, response, color=0, priority=5, onetime=0, tag=None): """ Compiles a trigger pattern and adds the entire action to the hash. @param trigger: the trigger pattern @type trigger: string @param response: what to do when the trigger pattern is found @type response: string @param color: whether (1) or not (0) we try matching the line with the ansi colors still in it. (i.e. if color==0, we filter the ansi colors out before matching) @type color: boolean @param priority: the priority to run this action at. actions are sorted by priority then by the trigger statement when we go to check for triggered actions. default is 5 @type priority: int @param onetime: if the trigger is found, should this action then get removed after the response is executed @type onetime: boolean @return: 1 @rtype: boolean """ expansion = exported.expand_ses_vars(trigger, self._ses) if not expansion: expansion = trigger compiled = utils.compile_regexp(expansion, 1) self._actions[trigger] = (trigger, compiled, response, color, priority, onetime, tag) self._actionlist = None # invalidating action list return 1
class ClerBot(bot.Bot): unmute_spell = u"освободить.разум" mass_heal_spell = u"массовое.исцеление" undrain_spell = u"слово.силы" unstone_spell = u"живое.прикосновение" group_headers = [ (utils.compile_regexp(u"r[^\s*?Имя\s+?Рядом$]"), "NEAR"), (utils.compile_regexp(u"r[^\s*?Имя\s+?H\s+?Позиция\s+?Рядом\s+?Укр$]"), "HEALTH"), (utils.compile_regexp(u"r[^\\s+?Имя\\s+?$]"), "INIT") ] def __init__(self, cmd_engine, event_classifier, myself): bot.Bot.__init__(self, cmd_engine, event_classifier, myself) cler_mod = ClerMod(cmd_engine, event_classifier, self._group_list) self.add_mod(cler_mod, "cler_mod") summon_mod = bot.AutoSummonMod(cmd_engine, event_classifier, self._group_list) self.add_mod(summon_mod, "summon_mod") self._handle_near = True def __del__(self): bot.Bot.__del__(self) gc.collect() refs = gc.get_referrers(self._mods["cler_mod"]) #for r in refs: # if type(r) == list: # exported.write_message("Globals Referer: {0} - {1}".format(r, namestr(r, globals()))) # exported.write_message("Locals Referer: {0} - {1}".format(r, namestr(r, locals()))) exported.write_message(str(gc.get_referrers(self._mods["cler_mod"]))) #exported.write_message("ClerBot: DEBUG: deleting ClerBot") #for r in refs: # if type(r) == list: # exported.write_message("ClerBot: DEBUG: list referrer") # exported.write_message(str(gc.get_referrers(r))) #exported.write_message("ClerBot: DEBUG: done listed referrers") def start(self): self._mods["cler_mod"].start() def stop(self): self._mods["cler_mod"].stop()
def addGag(self, item): """ Adds a gag to the dict. @param item: the item to gag @type item: string """ compiled = utils.compile_regexp(item, 1) self._gags[item] = compiled
def test_add_event(): ec = events.EventClassifier() #a = utils.compile_regexp(u"r[^(?P<who>.+) произнес магические слова .$]") ev = utils.compile_regexp(u"r[^Вам лучше встать на ноги!]") ec.add_event("better_stand_up", ev) ec.add_callback("better_stand_up", AssertListener("better_stand_up")) ec.mudfilter("Вам лучше встать на ноги!") assert ec.current() == "better_stand_up"
def __init__(self, event_classifier): # First few numbers, then not greedy for exits to not consume >, finally not # mapped to the group in the match result spaces if any self.non_battle_compiled = utils.compile_regexp(u"r[^(?P<hp>\d+)H (?P<mana>\d+)M (?P<moves>\d+)V (\d+)(X|MX) (\d+)C Вых:(?P<exits>.*?)>(?:\s*)$]", 1) self.battle_compiled = utils.compile_regexp(u"r[^(?P<hp>\d+)H (?P<mana>\d+)M (?P<moves>\d+)V (\d+)(X|MX) (\d+)C \[.+?\] \[.+?\] Вых:(?P<exits>.*?)>(?:\s*)$]", 1) self.assist_battle_compiled = utils.compile_regexp(u"r[^(?P<hp>\d+)H (?P<mana>\d+)M (?P<moves>\d+)V (\d+)(X|MX) (\d+)C \[.+?\]-\[.+?\] \[.+?\] Вых:(?P<exits>.*?)>(?:\s*)$]", 1) self._event_classifier = event_classifier self._exits = None self._hp = 0 self._mana = 0 self._moves = 0 self._last_received = None self._last_printed = None self._event_classifier.add_event("prompt", self.non_battle_compiled) self._event_classifier.add_event("prompt", self.battle_compiled) self._event_classifier.add_event("prompt", self.assist_battle_compiled) self._event_classifier.add_callback("prompt", self)
def addHighlight(self, style, text): """ Adds a highlight to the dict. @param style: the style to highlight the text with @type style: string @param text: the text to highlight @type text: string """ style = style.lower() markup, compiled = ansi.get_color(style), utils.compile_regexp(text, 0, 1) self._highlights[text] = (style, markup, compiled)
def _recompileRegexps(self): """ When a variable changes, we go through and recompile all the regular expressions for the actions in this session. """ for mem in self._actions.keys(): (trigger, compiled, response, color, priority, onetime, tag) = self._actions[mem] expansion = exported.expand_ses_vars(trigger, self._ses) if not expansion: expansion = trigger compiled = utils.compile_regexp(expansion, 1) self._actions[trigger] = (trigger, compiled, response, color, priority, onetime, tag)
def member(self): m = u"r[^\s*" m = m + "\s*".join( [ "(?P<{0}>{1})".format(c.name(), c.regexp()) for c in self._columns] ) m = m + "\s*$]" return utils.compile_regexp(m, 1)
def header(self): h = u"r[^\s*?" h = h + "\s+?".join( [c.header() for c in self._columns] ) h = h + "$]" return utils.compile_regexp(h)
class EventClassifier(object): followed = utils.compile_regexp(u"r[^Вы последовали за (?P<lead>.+)$]") successful_cast = utils.compile_regexp( u"r[^Вы произнесли магические слова '(?P<spell>.+)'\.\.\.$]") successful_cast_detect = utils.compile_regexp( u"r[^Вы произнесли магические слова '(?P<spell>.+)' \( сила .+ \)\.\.\.$]" ) successful_direct_cast = utils.compile_regexp( u"r[^Вы посмотрели на (?P<target>.+) и произнесли магические слова '(?P<spell>.+)'\.\.\.$]" ) successful_direct_cast_detect = utils.compile_regexp( u"r[^Вы посмотрели на (?P<target>.+) и произнесли магические слова '(?P<spell>.+)' \( сила .+ \)\.\.\.$]" ) room_cast = utils.compile_regexp( u"r[^(?P<caster>.+) произнес магические слова '(?P<spell>.+)'\.\.\.$]") room_cast_detect = utils.compile_regexp( u"r[^(?P<caster>.+) произнес магические слова '(?P<spell>.+)' \( сила .+ \)\.\.\.$]" ) stood_up = utils.compile_regexp(u"r[^Вы встали.$]") unmute = utils.compile_regexp( u"r[^Вы снова обрели способность разговаривать.$]") unhard_mute = utils.compile_regexp( u"r[^Черное безмолвие отступило от вас.$]") unhold = utils.compile_regexp(u"r[^Вы снова можете двигаться.$]") def __init__(self): # Dict of events: {"type": [regexp, ...]} self.__events = {} # Dict of callbacks: {"type": [listener, ...]} self.__callbacks = {} self._current = None self._raw = None self._gag = False self.add_event("you_followed", EventClassifier.followed) self.add_event("you_casted", EventClassifier.successful_cast) self.add_event("you_casted", EventClassifier.successful_cast_detect) self.add_event("you_casted", EventClassifier.successful_direct_cast) self.add_event("you_casted", EventClassifier.successful_direct_cast_detect) self.add_event("room_cast", EventClassifier.room_cast) self.add_event("room_cast", EventClassifier.room_cast_detect) self.add_event("you_stood_up", EventClassifier.stood_up) self.add_event("you_unhardmute", EventClassifier.unhard_mute) self.add_event("you_unmute", EventClassifier.unmute) self.add_event("you_unhold", EventClassifier.unhold) def add_event(self, ev_type, regexp): try: # Do not add the same regexp twice! if regexp not in self.__events[ev_type]: self.__events[ev_type].append(regexp) else: exported.write_message( "EvenetClassifier: WARN: trying to add the same regexp") except KeyError: self.__events[ev_type] = [regexp] if ev_type not in self.__callbacks: self.__callbacks[ev_type] = [] def remove_event(self, ev_type): try: self.__callbacks.pop(ev_type) self.__events.pop(ev_type) exported.write_message( "EventClassifier: DEBUG: successfully removed event {0}". format(ev_type)) except KeyError: exported.write_message( "EventClassifier: DEBUG: failed to remove event {0}, KeyError". format(ev_type)) return def add_callback(self, ev_type, listener): try: self.__callbacks[ev_type].append(listener) except KeyError: self.__callbacks[ev_type] = [listener] def remove_callback(self, ev_type, listener): try: self.__callbacks[ev_type].remove(listener) exported.write_message("EventClassifier: DEBUG: " + "successfully removed callback {0} {1}". format(ev_type, listener)) except KeyError: exported.write_message( "EventClassifier: DEBUG: " + "failed to remove callback {0} {1}, KeyError".format( ev_type, listener)) return except ValueError: exported.write_message( "EventClassifier: DEBUG: " + "failed to remove callback {0} {1}, ValueError".format( ev_type, listener)) pass def gag_current(self): self._gag = True def is_gagged(self): return self._gag def current(self): return self._current def get_raw(self): return self._raw def mudfilter(self, text): colorline = utils.filter_cm(text) nocolorline = ansi.filter_ansi(colorline) self._raw = colorline #exported.write_message("EventClassifier: DEBUG: " + # "callbacks {0}".format(self.__callbacks)) #exported.write_message("EventClassifier: DEBUG: " + # "events {0}".format(self.__events)) self._gag = False self._current = None #i = 0 #j = 0 #pattern = "" for t, list_r in self.__events.items(): for r in list_r: match = r.search(nocolorline) #pattern = pattern + "e{0} ".format(i) #i = i + 1 if match: self._current = t for c in self.__callbacks[t]: #exported.write_message(u"EventClassifier: DEBUG: callback for {0}".format(t)) #pattern = pattern + "c{0} ".format(j) #j = j + 1 c.on_event(t, match)
def addAntiGag(self, item): """ Adds an antigag.""" compiled = utils.compile_regexp(item, 1) self._antigags[item] = compiled
class AutoSummonMod(object): summon_spell = u"призыв" appear = utils.compile_regexp(u"r[^(?P<who>.+) неожиданно появился.$]") def __init__(self, cmd_engine, event_classifier, group_list, reverse=False): factory = group.GroupColumnFactory() nearView = group.GroupView() nearView.add_column(factory.get_num_column()) nearView.add_column(factory.get_name_column()) nearView.add_column(factory.get_near_column()) self._mode = False event_classifier.add_event("group_near_header", nearView.header()) event_classifier.add_event("group_near_member", nearView.member()) event_classifier.add_event("appear", AutoSummonMod.appear) event_classifier.add_callback("group_near_header", self) event_classifier.add_callback("group_near_member", self) event_classifier.add_callback("appear", self) event_classifier.add_callback("prompt", self) event_classifier.add_callback("you_casted", self) self._event_classifier = event_classifier self._group_list = group_list self._cmd_engine = cmd_engine self._reverse = reverse def unregister(self): self._event_classifier.remove_callback("group_near_header", self) self._event_classifier.remove_callback("group_near_member", self) self._event_classifier.remove_callback("appear", self) self._event_classifier.remove_callback("prompt", self) self._event_classifier.remove_callback("you_casted", self) def mode(self): if self._mode: return "NEAR" def on_event(self, ev_type, match): if ev_type == "group_near_header": self._event_classifier.gag_current() self._mode = True if (ev_type == "group_near_member") and self._mode: self._event_classifier.gag_current() self.group_member_near(match) if (ev_type == "prompt") and self._mode: self.do_auto_summon() self._mode = False if ev_type == "you_casted": if match.group('spell') == AutoSummonMod.summon_spell: self._mode = True if ev_type == "appear": self.on_appear(match.group("who")) def group_member_near(self, match): num = match.group("num") name = match.group("name") near = (match.group("near") == u'Д') try: self._group_list[name].set_near(near) except KeyError: exported.write_message( u"Bot: WARN: {0} is unknown group member".format(name)) def do_auto_summon(self): items = sorted(list(self._group_list.items())) if self._reverse: items = reversed(items) for name, char in items: if not char.is_near(): #print "Summoning " + name + " {0}".format(flag) cmd = cmds.CastCmd(AutoSummonMod.summon_spell, name) char.set_near(True) self._cmd_engine.put(cmd) return def on_appear(self, name): try: self._group_list[name].set_near(True) except KeyError: pass