Example #1
0
class Plugin(BasePlugin):
  """
  a plugin for user actions
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    BasePlugin.__init__(self, *args, **kwargs)

    self.canreload = True

    self.regexlookup = {}
    self.actiongroups = {}
    self.compiledregex = {}
    self.sessionhits = {}

    self.saveactionsfile = os.path.join(self.savedir, 'actions.txt')
    self.actions = PersistentDict(self.saveactionsfile, 'c')

  def load(self):
    """
    load the plugin
    """
    BasePlugin.load(self)

    self.api('setting.add')('nextnum', 0, int,
                            'the number of the next action added',
                            readonly=True)

    parser = argp.ArgumentParser(add_help=False,
                                 description='add a action')
    parser.add_argument('regex',
                        help='the regex to match',
                        default='',
                        nargs='?')
    parser.add_argument('action',
                        help='the action to take',
                        default='',
                        nargs='?')
    parser.add_argument('send',
                        help='where to send the action',
                        default='execute',
                        nargs='?',
                        choices=self.api('api.getchildren')('send'))
    parser.add_argument('-c',
                        "--color",
                        help="match colors (@@colors)",
                        action="store_true")
    parser.add_argument('-d',
                        "--disable",
                        help="disable the action",
                        action="store_true")
    parser.add_argument('-g',
                        "--group",
                        help="the action group",
                        default="")
    parser.add_argument('-o',
                        "--overwrite",
                        help="overwrite an action if it already exists",
                        action="store_true")
    self.api('commands.add')('add',
                             self.cmd_add,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='list actions')
    parser.add_argument('match',
                        help='list only actions that have this argument in them',
                        default='',
                        nargs='?')
    self.api('commands.add')('list',
                             self.cmd_list,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='remove an action')
    parser.add_argument('action',
                        help='the action to remove',
                        default='',
                        nargs='?')
    self.api('commands.add')('remove',
                             self.cmd_remove,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='toggle enabled flag')
    parser.add_argument('action',
                        help='the action to toggle',
                        default='',
                        nargs='?')
    action = parser.add_mutually_exclusive_group()
    action.add_argument('-t', '--toggle', action='store_const',
                        dest='togact', const='toggle',
                        default='toggle', help='toggle the action')
    action.add_argument('-d', '--disable', action='store_const',
                        dest='togact', const='disable',
                        help='disable the action')
    action.add_argument('-e', '--enable', action='store_const',
                        dest='togact', const='enable',
                        help='enable the action')
    self.api('commands.add')('toggle',
                             self.cmd_toggle,
                             parser=parser)


    parser = argp.ArgumentParser(add_help=False,
                                 description='get detail for an action')
    parser.add_argument('action',
                        help='the action to get details for',
                        default='',
                        nargs='?')
    self.api('commands.add')('detail',
                             self.cmd_detail,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='toggle all actions in a group')
    parser.add_argument('group',
                        help='the group to toggle',
                        default='',
                        nargs='?')
    action = parser.add_mutually_exclusive_group()
    action.add_argument('-t', '--toggle', action='store_const',
                        dest='togact', const='toggle',
                        default='toggle', help='toggle the action')
    action.add_argument('-d', '--disable', action='store_const',
                        dest='togact', const='disable',
                        help='disable the action')
    action.add_argument('-e', '--enable', action='store_const',
                        dest='togact', const='enable',
                        help='enable the action')
    self.api('commands.add')('groupt',
                             self.cmd_grouptoggle,
                             parser=parser)

    for action in self.actions.values():
      self.register_action(action)

    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)

  def register_action(self, action):
    """
    register an action as a trigger
    """
    if 'triggername' not in action:
      action['triggername'] = "action_%s" % action['num']
    self.api('triggers.add')(action['triggername'],
                             action['regex'])
    self.api('events.register')('trigger_%s' % action['triggername'],
                                self.action_matched)

  def unregister_action(self, action):
    """
    unregister an action
    """
    self.api('events.unregister')('trigger_%s' % action['triggername'],
                                  self.action_matched)
    self.api('triggers.remove')(action['triggername'])

  def action_matched(self, args):
    """
    do something when an action is matched
    """
    actionnum = int(args['triggername'].split('_')[-1])
    action = self.lookup_action(actionnum)
    if action:
      akey = action['regex']
      if akey not in self.sessionhits:
        self.sessionhits[akey] = 0
      self.sessionhits[akey] = self.sessionhits[akey] + 1
      action['hits'] = action['hits'] + 1
      self.api('send.msg')('matched line: %s to action %s' % (args['line'],
                                                              akey))
      templ = Template(action['action'])
      newaction = templ.safe_substitute(args)
      sendtype = 'send.' + action['send']
      self.api('send.msg')('sent %s to %s' % (newaction, sendtype))
      self.api(sendtype)(newaction)
    else:
      self.api('send.error')("Bug: could not find action for trigger %s" % \
                              args['triggername'])

  def lookup_action(self, action):
    """
    lookup an action by number or name
    """
    nitem = None
    try:
      num = int(action)
      nitem = None
      for titem in self.actions.keys():
        if num == self.actions[titem]['num']:
          nitem = self.actions[titem]
          break

    except ValueError:
      if action in self.actions:
        nitem = action

    return nitem

  def cmd_add(self, args):
    """
    add user defined actions
    """
    if not args['regex']:
      return False, ['Please include a regex']
    if not args['action']:
      return False, ['Please include an action']

    if not args['overwrite'] and args['regex'] in self.actions:
      return True, ['Action: %s already exists.' % args['regex']]
    else:
      num = 0

      if args['regex'] in self.actions:
        num = self.actions[args['regex']]['num']
      else:
        num = self.api('setting.gets')('nextnum')
        self.api('setting.change')('nextnum', num + 1)

      self.actions[args['regex']] = {
          'num':num,
          'hits':0,
          'regex': args['regex'],
          'action':args['action'],
          'send':args['send'],
          'matchcolor':args['color'],
          'enabled':not args['disable'],
          'group':args['group'],
          'triggername':"action_%s" % num
      }
      self.actions.sync()

      self.register_action(self.actions[args['regex']])

      return True, ['added action %s - regex: %s' % (num, args['regex'])]

    return False, ['You should never see this']

  def cmd_remove(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      Remove an action
      @CUsage@w: rem @Y<originalstring>@w
        @Yoriginalstring@w    = The original string
    """
    tmsg = []
    if args['action']:
      retval = self.removeaction(args['action'])
      if retval:
        tmsg.append("@GRemoving action@w : '%s'" % (retval))
      else:
        tmsg.append("@GCould not remove action@w : '%s'" % (args['action']))

      return True, tmsg
    else:
      return False, ['@RPlease include an action to remove@w']

  def cmd_list(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      List actiones
      @CUsage@w: list
    """
    tmsg = self.listactions(args['match'])
    return True, tmsg

  def cmd_toggle(self, args):
    """
    toggle the enabled flag
    """
    tmsg = []

    if args['togact'] == 'disable':
      state = False
    elif args['togact'] == 'enable':
      state = True
    else:
      state = "toggle"
    if args['action']:
      action = self.toggleaction(args['action'], flag=state)
      if action:
        if action['enabled']:
          tmsg.append("@GEnabled action@w : '%s'" % (action['num']))
        else:
          tmsg.append("@GDisabled action@w : '%s'" % (action['num']))
      else:
        tmsg.append("@GDoes not exist@w : '%s'" % (args['action']))
      return True, tmsg

    else:
      return False, ['@RPlease include an action to toggle@w']

  def cmd_grouptoggle(self, args):
    """
    toggle all actions in a group
    """
    tmsg = []
    togglea = []
    if args['togact'] == 'disable':
      state = False
    elif args['togact'] == 'enable':
      state = True
    else:
      state = "toggle"
    if args['group']:
      for i in self.actions:
        if self.actions[i]['group'] == args['group']:
          self.toggleaction(self.actions[i]['num'], flag=state)
          togglea.append('%s' % self.actions[i]['num'])

      if togglea:
        tmsg.append('The following actions were %s: %s' % \
              ('enabled' if state else 'disabled',
               ','.join(togglea)))
      else:
        tmsg.append('No actions were modified')

      return True, tmsg
    else:
      return False, ['@RPlease include a group to toggle@w']

  def cmd_detail(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      get details of an action
      @CUsage@w: detail 1
        @Yaction@w    = the action to get details, either the number or regex
    """
    tmsg = []
    if args['action']:
      action = self.lookup_action(args['action'])
      if action:
        if 'hits' not in action:
          action['hits'] = 0
        if action['regex'] not in self.sessionhits:
          self.sessionhits[action['regex']] = 0
        tmsg.append('%-12s : %d' % ('Num', action['num']))
        tmsg.append('%-12s : %s' % \
            ('Enabled', 'Y' if action['enabled'] else 'N'))
        tmsg.append('%-12s : %d' % ('Total Hits',
                                    action['hits']))
        tmsg.append('%-12s : %d' % ('Session Hits',
                                    self.sessionhits[action['regex']]))
        tmsg.append('%-12s : %s' % ('Regex', action['regex']))
        tmsg.append('%-12s : %s' % ('Action', action['action']))
        tmsg.append('%-12s : %s' % ('Group', action['group']))
        tmsg.append('%-12s : %s' % ('Match Color',
                                    action['matchcolor']))
        tmsg.append('%-12s : %s' % ('Trigger Name',
                                    action['triggername']))
      else:
        return True, ['@RAction does not exist@w : \'%s\'' % (args['action'])]

      return True, tmsg
    else:
      return False, ['@RPlease include all arguments@w']

  def listactions(self, match):
    """
    return a table of strings that list actions
    """
    tmsg = []
    for action in sorted(self.actions.keys()):
      item = self.actions[action]
      if not match or match in item:
        regex = self.api('colors.stripansi')(item['regex'])
        if len(regex) > 30:
          regex = regex[:27] + '...'
        action = self.api('colors.stripansi')(item['action'])
        if len(action) > 30:
          action = action[:27] + '...'
        tmsg.append("%4s %2s  %-10s %-32s : %s@w" % \
                     (item['num'],
                      'Y' if item['enabled'] else 'N',
                      item['group'],
                      regex,
                      action))
    if not tmsg:
      tmsg = ['None']
    else:
      tmsg.insert(0, "%4s %2s  %-10s %-32s : %s@w" % ('#', 'E', 'Group',
                                                      'Regex', 'Action'))
      tmsg.insert(1, '@B' + '-' * 60 + '@w')

    return tmsg

  def removeaction(self, item):
    """
    internally remove a action
    """
    action = self.lookup_action(item)

    if action and action['regex'] in self.actions:
      self.unregister_action(action)
      del self.actions[action['regex']]
      self.actions.sync()

    return action

  def toggleaction(self, item, flag="toggle"):
    """
    toggle an action
    """
    action = self.lookup_action(item)
    if action:
      if flag == "toggle":
        action['enabled'] = not action['enabled']
      else:
        action['enabled'] = bool(flag)
      if action['enabled']:
        self.register_action(action)
      else:
        self.unregister_action(action)

    return action

  def clearactions(self):
    """
    clear all actiones
    """
    for action in self.actions.values():
      self.unregister_action(action)

    self.actions.clear()
    self.actions.sync()

  def reset(self):
    """
    reset the plugin
    """
    BasePlugin.reset(self)
    self.clearactions()

  def _savestate(self, _=None):
    """
    save states
    """
    self.actions.sync()
Example #2
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin to handle aardwolf quest events
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.savegqfile = os.path.join(self.savedir, 'gq.txt')
        self.gqinfo = PersistentDict(self.savegqfile, 'c')
        self._gqsdeclared = {}
        self._gqsstarted = {}
        self.api.get('setting.add')('joined', -1, int, 'the gq number joined')
        self.api.get('setting.add')('maxkills', False, bool,
                                    'no qp because of maxkills')
        self.mobsleft = []
        self.linecount = 0

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)
        self.api.get('watch.add')(
            'gq_check', '^(gq|gqu|gque|gques|gquest) (c|ch|che|chec|check)$')

        self.api.get('triggers.add')('gqdeclared',
                      "^Global Quest: Global quest \# *(?P<gqnum>\d*) has been " \
                        "declared for levels (?P<lowlev>\d*) to (?P<highlev>\d*)( - .*)*\.$",
                      argtypes={'gqnum':int})
        self.api.get('triggers.add')(
            'gqjoined',
            "^You have now joined Global Quest \# *(?P<gqnum>\d*)\. .*$",
            argtypes={
                'gqnum': int
            })
        self.api.get('triggers.add')('gqstarted',
                      "^Global Quest: Global quest \# *(?P<gqnum>\d*) for levels .* "\
                        "to .* has now started\.$",
                      argtypes={'gqnum':int})
        self.api.get('triggers.add')('gqcancelled',
                      "^Global Quest: Global quest \# *(?P<gqnum>\d*) has been " \
                        "cancelled due to lack of (activity|participants)\.$",
                      argtypes={'gqnum':int})
        self.api.get('triggers.add')('gqquit',
                      "^You are no longer part of Global Quest \# *(?P<gqnum>\d*) " \
                        "and will be unable to rejoin.$",
                      argtypes={'gqnum':int})

        # GQ Check triggers
        self.api.get('triggers.add')('gqnone',
                                     "^You are not in a global quest\.$",
                                     enabled=False,
                                     group='gqcheck')
        self.api.get('triggers.add')('gqitem',
                      "^You still have to kill (?P<num>[\d]*) \* " \
                        "(?P<mob>.*?) \((?P<location>.*?)\)(|\.)$",
                      enabled=False, group='gqcheck',
                      argtypes={'num':int})
        self.api.get('triggers.add')(
            'gqnotstarted',
            "^Global Quest \# *(?P<gqnum>\d*) has not yet started.",
            enabled=False,
            group='gqcheck',
            argtypes={
                'gqnum': int
            })
        self.api.get('triggers.add')(
            'gqwins',
            "^You may win .* more gquests* at this level\.$",
            enabled=False,
            group='gqcheck')

        self.api.get('triggers.add')(
            'gqreward',
            "^\s*Reward of (?P<amount>\d+) (?P<type>.+) .+ added\.$",
            enabled=False,
            group='gqrew',
            argtypes={
                'amount': int
            })

        self.api.get('triggers.add')(
            'gqmobdead',
            "^Congratulations, that was one of the GLOBAL QUEST mobs!$",
            enabled=False,
            group='gqin')

        self.api.get('triggers.add')('gqextended',
                      "^Global Quest: Global Quest \# *(?P<gqnum>\d*) will go " \
                        "into extended time for 3 more minutes.$",
                      enabled=False, group='gqin',
                      argtypes={'gqnum':int})

        self.api.get('triggers.add')(
            'gqwon',
            "^You were the first to complete this quest!$",
            enabled=False,
            group='gqin')
        self.api.get('triggers.add')('gqextfin',
                                     "^You have finished this global quest.$",
                                     enabled=False,
                                     group='gqin')
        self.api.get('triggers.add')('gqwonannounce',
                      "Global Quest: Global Quest \#(?P<gqnum>.*) has been won " \
                        "by (?P<winner>.*) - (.*) win.$",
                      enabled=False, group='gqin',
                      argtypes={'gqnum':int})

        self.api.get('triggers.add')('gqnote',
                      "^INFO: New post \#(?P<bdnum>.*) in forum Gquest from " \
                        "Aardwolf Subj: Lvl (?P<low>.*) to (?P<high>.*) - " \
                        "Global quest \# *(?P<gqnum>\d*)$",
                        argtypes={'gqnum':int})

        self.api.get('triggers.add')('gqmaxkills', "^You have reached the " \
            "maximum (.*) kills for which you can earn quest points this level\.$")

        self.api.get('events.register')('trigger_gqdeclared', self._gqdeclared)
        self.api.get('events.register')('trigger_gqjoined', self._gqjoined)
        self.api.get('events.register')('trigger_gqstarted', self._gqstarted)
        self.api.get('events.register')('trigger_gqcancelled',
                                        self._gqcancelled)
        self.api.get('events.register')('trigger_gqquit', self._gqquit)

        self.api.get('events.register')('trigger_gqnone', self._notstarted)
        self.api.get('events.register')('trigger_gqitem', self._gqitem)
        self.api.get('events.register')('trigger_gqnotstarted',
                                        self._notstarted)
        self.api.get('events.register')('trigger_gqwins', self._gqwins)

        self.api.get('events.register')('trigger_gqreward', self._gqreward)

        self.api.get('events.register')('trigger_gqmobdead', self._gqmobdead)

        self.api.get('events.register')('trigger_gqextended', self._gqextended)

        self.api.get('events.register')('trigger_gqwon', self._gqwon)
        self.api.get('events.register')('trigger_gqextfin', self._gqextfin)
        self.api.get('events.register')('trigger_gqwonannounce',
                                        self._gqwonannounce)

        self.api.get('events.register')('trigger_gqnote', self._gqnote)
        self.api.get('events.register')('trigger_gqmaxkills', self._gqmaxkills)

        self.api.get('events.register')('watch_gq_check', self._gqcheckcmd)

    def _gqnew(self):
        """
    reset the gq info
    """
        self.mobsleft = {}
        self.gqinfo.clear()
        self.gqinfo['mobs'] = {}
        self.gqinfo['trains'] = 0
        self.gqinfo['pracs'] = 0
        self.gqinfo['gold'] = 0
        self.gqinfo['tp'] = 0
        self.gqinfo['qp'] = 0
        self.gqinfo['qpmobs'] = 0
        self.gqinfo['level'] = self.api.get('aardu.getactuallevel')(
            self.api.get('GMCP.getv')('char.status.level'))
        self.gqinfo['starttime'] = 0
        self.gqinfo['finishtime'] = 0
        self.gqinfo['length'] = 0
        self.gqinfo['won'] = 0
        self.gqinfo['completed'] = 0
        self.gqinfo['extended'] = 0
        self.api.get('setting.change')('maxkills', False)
        self.savestate()

    def _gqdeclared(self, args):
        """
    do something when a gq is declared
    """
        self._gqsdeclared[args['gqnum']] = True
        self._checkgqavailable()
        self._raisegq('aard_gq_declared', args)

    def _gqjoined(self, args):
        """
    do something when a gq is joined
    """
        self._gqnew()
        self.api.get('setting.change')('joined', args['gqnum'])

        self.mobsleft = []

        if args['gqnum'] in self._gqsstarted:
            self._gqstarted(args)
        elif not (args['gqnum'] in self._gqsdeclared):
            self._gqsdeclared[args['gqnum']] = True
            self._gqstarted(args)
        self._raisegq('aard_gq_joined', args)

    def _gqstarted(self, args):
        """
    do something when a gq starts
    """
        if not (args['gqnum'] in self._gqsstarted):
            self._gqsstarted[args['gqnum']] = True
            self._raisegq('aard_gq_started', args)
            self._checkgqavailable()
        if self.api.get('setting.gets')('joined') == args['gqnum']:
            self.gqinfo['starttime'] = time.time()
            self.api.get('triggers.togglegroup')("gqin", True)
            self.api.get('send.execute')("gq check")

    def _gqcancelled(self, args):
        """
    the gq has been cancelled
    """
        self._raisegq('aard_gq_cancelled', {'gqnum': args['gqnum']})
        if args['gqnum'] == self.api('setting.gets')('joined'):
            if self.gqinfo['qpmobs'] > 0:
                self.gqinfo['finishtime'] = time.time()
                self._raisegq('aard_gq_done', self.gqinfo)
            self._gqreset({'gqnum': args['gqnum']})

        else:
            if args['gqnum'] in self._gqsdeclared:
                del (self._gqsdeclared[args['gqnum']])
            if args['gqnum'] in self._gqsstarted:
                del (self._gqsstarted[args['gqnum']])
            self._checkgqavailable()

    def _gqitem(self, args):
        """
    do something with a gq item
    """
        name = args['mob']
        num = args['num']
        location = args['location']
        if not name or not location or not num:
            self.api.get('send.client')("error parsing line: %s" %
                                        args['line'])
        else:
            self.mobsleft.append({
                'name':
                name,
                'nocolorname':
                self.api.get('colors.stripansi')(name),
                'location':
                location,
                'num':
                num
            })

    def _notstarted(self, _=None):
        """
    this will be called when a gq check returns the not started message
    """
        self.api.get('triggers.togglegroup')('gqcheck', False)
        self.api.get('triggers.togglegroup')('gqin', False)

    def _gqwins(self, _=None):
        """
    this will be enabled when gq check is enabled
    """
        if not self.gqinfo['mobs']:
            self.gqinfo['mobs'] = self.mobsleft[:]
            self.savestate()

        self.api.get('triggers.togglegroup')('gqcheck', False)
        self._raisegq('aard_gq_mobsleft',
                      {'mobsleft': copy.deepcopy(self.mobsleft)})

    def _gqmobdead(self, _=None):
        """
    called when a gq mob is killed
    """
        if not self.api.get('setting.gets')('maxkills'):
            self.gqinfo['qpmobs'] = self.gqinfo['qpmobs'] + 3
        self.api.get('events.register')('aard_mobkill', self._mobkillevent)

    def _gqextended(self, args):
        """
    gquest went into extended time
    """
        if args['gqnum'] == self.api('setting.gets')('joined'):
            self.gqinfo['extended'] = 1

    def _gqmaxkills(self, args):
        """
    didn't get xp for that last kill
    """
        self.api.get('setting.change')('maxkills', True)

    def _mobkillevent(self, args):
        """
    this will be registered to the mobkill hook
    """
        self.api.get('send.msg')('checking kill %s' % args['name'])
        self.api.get('events.register')('aard_mobkill', self._mobkillevent)

        found = False
        removeitem = None
        for i in range(len(self.mobsleft)):
            tmob = self.mobsleft[i]
            if tmob['name'] == args['name']:
                self.api.get('send.msg')('found %s' % tmob['name'])
                found = True
                if tmob['num'] == 1:
                    removeitem = i
                else:
                    tmob['num'] = tmob['num'] - 1

        if removeitem:
            del (self.mobsleft[removeitem])

        if found:
            self._raisegq('aard_gq_mobsleft', {'mobsleft': self.mobsleft})
        else:
            self.api.get('send.msg')("BP GQ: could not find mob: %s" %
                                     args['name'])
            self.api.get('send.execute')("gq check")

    def _gqwon(self, _=None):
        """
    the gquest was won
    """
        self.gqinfo['won'] = 1
        self.gqinfo['finishtime'] = time.time()
        self.api.get('triggers.togglegroup')("gqrew", True)

    def _gqwonannounce(self, args):
        """
    the mud announced that someone won the gquest
    """
        if self.api('GMCP.getv')('char.base.name') == args['winner']:
            # we won
            self._raisegq('aard_gq_won', self.gqinfo)
            self._gqreset(args)

    def _gqreward(self, args=None):
        """
    handle cpreward
    """
        rtype = args['type']
        ramount = args['amount']
        rewardt = self.api.get('aardu.rewardtable')()
        self.gqinfo[rewardt[rtype]] = ramount
        self.savestate()

    def _gqcheckcmd(self, args=None):
        """
    do something after we see a gq check
    """
        self.mobsleft = []
        self.api.get('triggers.togglegroup')('gqcheck', True)
        return args

    def _gqquit(self, args):
        """
    quit the gq
    """
        if self.gqinfo['qpmobs'] > 0:
            self.gqinfo['finishtime'] = time.time()
            self._raisegq('aard_gq_done', self.gqinfo)
        self._gqreset(args)

    def _gqextfin(self, _=None):
        """
    the character finished the extended gq
    """
        if self.gqinfo['qpmobs'] > 0:
            self.gqinfo['completed'] = 1
            self.gqinfo['finishtime'] = time.time()
            self._raisegq('aard_gq_completed', self.gqinfo)
            self._gqreset({'gqnum': self.api('setting.gets')('joined')})

    def _raisegq(self, event, data=None):
        """
    raise a gq event
    """
        self.api('send.msg')('raising %s with %s' % (event, data))
        self.savestate()
        if data:
            self.api.get('events.eraise')(event, copy.deepcopy(data))
        else:
            self.api.get('events.eraise')(event)

    def _gqnote(self, args):
        """
    do something on the gquest note
    """
        if args['gqnum'] == self.api('setting.gets')('joined'):
            if self.gqinfo['qpmobs'] > 0:
                self.gqinfo['finishtime'] = time.time()
                self._raisegq('aard_gq_done', self.gqinfo)
            self._gqreset(args)
        if args['gqnum'] in self._gqsdeclared:
            del (self._gqsdeclared[args['gqnum']])
        if args['gqnum'] in self._gqsstarted:
            del (self._gqsstarted[args['gqnum']])
        self._checkgqavailable()

    def _gqreset(self, args={}):
        """
    reset gq settings
    """
        self._gqnew()
        if args:
            if args['gqnum'] in self._gqsdeclared:
                del (self._gqsdeclared[args['gqnum']])
            if args['gqnum'] in self._gqsstarted:
                del (self._gqsstarted[args['gqnum']])
            self._checkgqavailable()
        self.api.get('triggers.togglegroup')("gqcheck", False)
        self.api.get('triggers.togglegroup')("gqin", False)
        self.api.get('triggers.togglegroup')("gqrew", False)
        self.api.get('events.unregister')('aard_mobkill', self._mobkillevent)
        self.api.get('setting.change')('joined', 'default')
        self.api.get('setting.change')('maxkills', False)
        self.savestate()

    def _checkgqavailable(self):
        if len(self._gqsdeclared) > 0:
            self._raisegq('aard_gq_available')
        else:
            self._raisegq('aard_gq_notavailable')

    def savestate(self):
        """
    save states
    """
        AardwolfBasePlugin.savestate(self)
        self.gqinfo.sync()
Example #3
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin to handle aardwolf quest events
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.savequestfile = os.path.join(self.savedir, 'quest.txt')
    self.queststuff = PersistentDict(self.savequestfile, 'c')

  def load(self):
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)

    self.api('events.register')('GMCP:comm.quest', self.quest)

    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)


  def resetquest(self):
    """
    reset the quest info
    """
    self.queststuff.clear()
    self.queststuff['finishtime'] = -1
    self.queststuff['starttime'] = time.time()
    self.queststuff['killedtime'] = -1
    self.queststuff['mobname'] = ''
    self.queststuff['mobarea'] = ''
    self.queststuff['mobroom'] = ''
    self.queststuff['level'] = self.api('aardu.getactuallevel')(
        self.api('GMCP.getv')('char.status.level'))
    self.queststuff['failed'] = 0

  def quest(self, args):
    """
    process the quest event
    """
    questi = args['data']
    self.api('send.msg')('quest: %s' % questi)
    if questi['action'] == 'ready':
      self.api('events.eraise')('aard_quest_ready', {})
    elif questi['action'] == 'start':
      self.resetquest()
      self.queststuff['mobname'] = questi['targ']
      self.queststuff['mobarea'] = questi['area']
      self.queststuff['mobroom'] = questi['room']
      self.queststuff['stimer'] = questi['timer']
      self.api('events.eraise')('aard_quest_start', self.queststuff)
    elif questi['action'] == 'killed':
      self.queststuff['killedtime'] = time.time()
      self.api('events.eraise')('aard_quest_killed', self.queststuff)
    elif questi['action'] == 'comp':
      self.queststuff['finishtime'] = time.time()
      self.queststuff.update(questi)
      self.api('events.eraise')('aard_quest_comp',
                                copy.deepcopy(self.queststuff))
    elif questi['action'] == 'fail' or questi['action'] == 'timeout':
      self.queststuff['finishtime'] = time.time()
      self.queststuff['failed'] = 1
      self.api('events.eraise')('aard_quest_failed',
                                copy.deepcopy(self.queststuff))
    elif questi['action'] == 'status':
      self.api('events.eraise')('aard_quest_status', questi)
    elif questi['action'] == 'reset':
      #reset the timer to 60 seconds
      #when_required = os.time() + (stuff.timer * 60)
      #update_timer()
      self.api('events.eraise')('aard_quest_reset', {})
    self.queststuff.sync()

  def _savestate(self, _=None):
    """
    save states
    """
    self.queststuff.sync()
Example #4
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin manage info about spells and skills
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.saveskillfile = os.path.join(self.savedir, 'skills.txt')
        self.skills = PersistentDict(self.saveskillfile, 'c')
        self.skillsnamelookup = {}
        for i in self.skills:
            self.skillsnamelookup[self.skills[i]['name']] = i

        self.saverecovfile = os.path.join(self.savedir, 'recoveries.txt')
        self.recoveries = PersistentDict(self.saverecovfile, 'c')
        self.recoveriesnamelookup = {}
        for i in self.recoveries:
            self.recoveriesnamelookup[self.recoveries[i]['name']] = i

        self.current = ''
        self.isuptodatef = False

        self.cmdqueue = None

        self.api.get('dependency.add')('cmdq')

        self.api.get('api.add')('gets', self.api_getskill)
        self.api.get('api.add')('isspellup', self.api_isspellup)
        self.api.get('api.add')('getspellups', self.api_getspellups)
        self.api.get('api.add')('sendcmd', self.api_sendcmd)
        self.api.get('api.add')('isaffected', self.api_isaffected)
        self.api.get('api.add')('isblockedbyrecovery',
                                self.api_isblockedbyrecovery)
        self.api.get('api.add')('ispracticed', self.api_ispracticed)
        self.api.get('api.add')('canuse', self.api_canuse)
        self.api.get('api.add')('isuptodate', self.api_isuptodate)
        self.api.get('api.add')('isbad', self.api_isbad)

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)

        self.api.get('send.msg')('running load function of skills')

        parser = argparse.ArgumentParser(
            add_help=False, description='refresh skills and spells')
        self.api.get('commands.add')('refresh',
                                     self.cmd_refresh,
                                     parser=parser)

        parser = argparse.ArgumentParser(
            add_help=False, description='lookup skill or spell by name or sn')
        parser.add_argument('skill',
                            help='the skill to lookup',
                            default='',
                            nargs='?')
        self.api.get('commands.add')('lu', self.cmd_lu, parser=parser)

        self.api.get('triggers.add')('spellh_noprompt',
                                     "^\{spellheaders noprompt\}$",
                                     group='slist',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')('spellh_spellup_noprompt',
                                     "^\{spellheaders spellup noprompt\}$",
                                     group='slist',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')('spellh_affected_noprompt',
                                     "^\{spellheaders affected noprompt\}$",
                                     group='slist',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')('spellh_spellline',
                "^(?P<sn>\d+),(?P<name>.+),(?P<target>\d+)," \
                  "(?P<duration>\d+),(?P<pct>\d+),(?P<rcvy>-?\d+),(?P<type>\d+)$",
                group='spellhead', enabled=False, omit=True)
        self.api.get('triggers.add')('spellh_end_noprompt',
                                     "^\{/spellheaders\}$",
                                     group='spellhead',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')('affoff', "^\{affoff\}(?P<sn>\d+)$")
        self.api.get('triggers.add')(
            'affon', "^\{affon\}(?P<sn>\d+),(?P<duration>\d+)$")
        self.api.get('triggers.add')('recov_noprompt',
                                     "^\{recoveries noprompt\}$",
                                     group='slist',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')('recov_affected_noprompt',
                                     "^\{recoveries affected noprompt\}$",
                                     group='slist',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')(
            'spellh_recovline',
            "^(?P<sn>\d+),(?P<name>.+),(?P<duration>\d+)$",
            group='recoveries',
            enabled=False,
            omit=True)
        self.api.get('triggers.add')('recov_end_noprompt',
                                     "^\{/recoveries\}$",
                                     group='recoveries',
                                     enabled=False,
                                     omit=True)
        self.api.get('triggers.add')('recoff', "^\{recoff\}(?P<sn>\d+)$")
        self.api.get('triggers.add')(
            'recon', "^\{recon\}(?P<sn>\d+),(?P<duration>\d+)$")
        self.api.get('triggers.add')(
            'skillgain', "^\{skillgain\}(?P<sn>\d+),(?P<percent>\d+)$")
        self.api.get('triggers.add')('skillfail',
                "^\{sfail\}(?P<sn>\d+),(?P<target>\d+)," \
                  "(?P<reason>\d+),(?P<recovery>-?\d+)$")

        self.api.get('events.register')('trigger_spellh_noprompt',
                                        self.skillstart)
        self.api.get('events.register')('trigger_spellh_spellup_noprompt',
                                        self.skillstart)
        self.api.get('events.register')('trigger_spellh_affected_noprompt',
                                        self.skillstart)
        self.api.get('events.register')('trigger_spellh_spellline',
                                        self.skillline)
        self.api.get('events.register')('trigger_spellh_end_noprompt',
                                        self.skillend)
        self.api.get('events.register')('trigger_affoff', self.affoff)
        self.api.get('events.register')('trigger_affon', self.affon)
        self.api.get('events.register')('trigger_recov_noprompt',
                                        self.recovstart)
        self.api.get('events.register')('trigger_recov_affected_noprompt',
                                        self.recovstart)
        self.api.get('events.register')('trigger_spellh_recovline',
                                        self.recovline)
        self.api.get('events.register')('trigger_recov_end_noprompt',
                                        self.recovend)
        self.api.get('events.register')('trigger_recoff', self.recoff)
        self.api.get('events.register')('trigger_recon', self.recon)

        self.api.get('events.register')('trigger_skillgain', self.skillgain)
        self.api.get('events.register')('trigger_skillfail', self.skillfail)

        self.api.get('events.register')('GMCP:char.status', self.checkskills)

        self.api.get('events.register')('aard_level_tier', self.cmd_refresh)
        self.api.get('events.register')('aard_level_remort', self.cmd_refresh)

        self.cmdqueue = self.api.get('cmdq.baseclass')()(self)
        self.cmdqueue.addcmdtype('slist',
                                 'slist',
                                 "^slist\s*(.*)$",
                                 beforef=self.slistbefore,
                                 afterf=self.slistafter)

        self.checkskills()

    def slistbefore(self):
        """
    stuff to do before doing slist command
    """
        self.api.get('triggers.togglegroup')('slist', True)

    def slistafter(self):
        """
    stuff to do after doing slist command
    """
        self.savestate()
        self.api.get('triggers.togglegroup')('slist', False)

    def afterfirstactive(self, _=None):
        """
    do something on connect
    """
        AardwolfBasePlugin.afterfirstactive(self)
        self.checkskills()

    # check if the spells/skills list is up to date
    def api_isuptodate(self):
        """
    return True if we have seen affected or all spells refresh
    """
        return self.isuptodatef

    def cmd_lu(self, args):
        """
    cmd to lookup a spell
    """
        msg = []
        skill = self.api.get('skills.gets')(args['skill'])
        if skill:
            msg.append('%-8s : %s' % ('SN', skill['sn']))
            msg.append('%-8s : %s' % ('Name', skill['name']))
            msg.append('%-8s : %s' % ('Percent', skill['percent']))
            if skill['duration'] > 0:
                msg.append(
                    '%-8s : %s' %
                    ('Duration', self.api.get('utils.timedeltatostring')(
                        time.time(), skill['duration'])))
            msg.append('%-8s : %s' % ('Target', skill['target']))
            msg.append('%-8s : %s' % ('Spellup', skill['spellup']))
            msg.append('%-8s : %s' % ('Type', skill['type']))
            if skill['recovery']:
                recov = skill['recovery']
                if recov['duration'] > 0:
                    duration = self.api.get('utils.timedeltatostring')(
                        time.time(), recov['duration'])
                    msg.append('%-8s : %s (%s)' %
                               ('Recovery', recov['name'], duration))
                else:
                    msg.append('%-8s : %s' % ('Recovery', recov['name']))
        else:
            msg.append('Could not find: %s' % args['skill'])

        return True, msg

    def cmd_refresh(self, args):
        """
    refresh spells and skills
    """
        self.skills.clear()
        self.recoveries.clear()
        self.cmdqueue.addtoqueue('slist', 'noprompt')
        self.cmdqueue.addtoqueue('slist', 'spellup noprompt')
        msg = ['Refreshing spells and skills']
        return True, msg

    def checkskills(self, _=None):
        """
    check to see if we have spells
    """
        state = self.api.get('GMCP.getv')('char.status.state')
        if state == 3:
            self.api.get('send.msg')('refreshing skills')
            self.api.get('events.unregister')('GMCP:char.status',
                                              self.checkskills)
            self.api.get('A102.toggle')('SPELLUPTAGS', True)
            self.api.get('A102.toggle')('SKILLGAINTAGS', True)
            self.api.get('A102.toggle')('QUIETTAGS', False)
            if len(self.skills) == 0:
                self.cmd_refresh({})
            else:
                self.resetskills()
                self.cmdqueue.addtoqueue('slist', 'affected noprompt')

    def resetskills(self):
        """
    reset the skills
    """
        for i in self.skills:
            self.skills[i]['duration'] = 0
        for i in self.recoveries:
            self.recoveries[i]['duration'] = 0

    def skillgain(self, args):
        """
    handle a skillgain tag
    """
        spellnum = int(args['sn'])
        pct = int(args['percent'])
        if spellnum in self.skills:
            self.skills[spellnum]['percent'] = pct
            self.api.get('events.eraise')('aard_skill_gain', {
                'sn': spellnum,
                'percent': pct
            })

    def skillfail(self, args):
        """
    raise an event when we fail a skill/spell
    """
        spellnum = int(args['sn'])
        reason = FAILREASON[int(args['reason'])]
        ndict = {
            'sn': spellnum,
            'reason': reason,
            'target': FAILTARG[int(args['target'])],
            'recovery': int(args['recovery'])
        }
        if reason == 'dontknow' and self.skills[spellnum]['percent'] > 0:
            self.api.get('send.msg')(
                'refreshing spells because of an unlearned spell')
            self.cmd_refresh({})
        self.api.get('send.msg')('raising skillfail: %s' % ndict)
        self.api.get('events.eraise')('skill_fail_%s' % args['sn'], ndict)
        self.api.get('events.eraise')('skill_fail', ndict)

    def affoff(self, args):
        """
    set the affect to off for spell that wears off
    """
        spellnum = int(args['sn'])
        if spellnum in self.skills:
            self.skills[spellnum]['duration'] = 0
            self.savestate()
            self.api.get('events.eraise')('aard_skill_affoff_%s' % spellnum, {
                'sn': spellnum
            })
            self.api.get('events.eraise')('aard_skill_affoff', {
                'sn': spellnum
            })

    def affon(self, args):
        """
    set the spell's duration when we see an affon
    """
        spellnum = int(args['sn'])
        duration = int(args['duration'])
        if spellnum in self.skills:
            self.skills[spellnum]['duration'] = time.mktime(time.localtime()) + \
                                                              duration
            self.savestate()
            self.api.get('events.eraise')(
                'aard_skill_affon_%s' % spellnum, {
                    'sn': spellnum,
                    'duration': self.skills[spellnum]['duration']
                })
            self.api.get('events.eraise')(
                'aard_skill_affon', {
                    'sn': spellnum,
                    'duration': self.skills[spellnum]['duration']
                })

    def recovstart(self, args):
        """
    show that the trigger fired
    """
        if 'triggername' in args \
            and args['triggername'] == 'trigger_recov_affected_noprompt':
            self.current = 'affected'
        else:
            self.current = ''
        self.api.get('triggers.togglegroup')('recoveries', True)

    def recovline(self, args):
        """
    parse a recovery line
    """
        spellnum = int(args['sn'])
        name = args['name']
        if int(args['duration']) != 0:
            duration = time.mktime(time.localtime()) + int(args['duration'])
        else:
            duration = 0

        if not (spellnum in self.recoveries):
            self.recoveries[spellnum] = {}

        self.recoveries[spellnum]['name'] = name
        self.recoveries[spellnum]['duration'] = duration
        self.recoveries[spellnum]['sn'] = spellnum

        self.recoveriesnamelookup[name] = spellnum

    def recovend(self, args):
        """
    reset current when seeing a spellheaders ending
    """
        self.api.get('triggers.togglegroup')('recoveries', False)
        if self.current == '' or self.current == 'affected':
            self.isuptodatef = True
            self.api.get('send.msg')('sending skills_affected_update')
            self.api.get('events.eraise')('skills_affected_update', {})
        self.cmdqueue.cmddone('slist')

    def recoff(self, args):
        """
    set the affect to off for spell that wears off
    """
        spellnum = int(args['sn'])
        if spellnum in self.recoveries:
            self.recoveries[spellnum]['duration'] = 0
            self.savestate()
            self.api.get('events.eraise')('aard_skill_recoff', {
                'sn': spellnum
            })

    def recon(self, args):
        """
    set the spell's duration when we see an affon
    """
        spellnum = int(args['sn'])
        duration = int(args['duration'])
        if spellnum in self.recoveries:
            self.recoveries[spellnum]['duration'] = \
                              time.mktime(time.localtime()) + duration
            self.savestate()
            self.api.get('events.eraise')(
                'aard_skill_recon', {
                    'sn': spellnum,
                    'duration': self.recoveries[spellnum]['duration']
                })

    def skillstart(self, args):
        """
    show that the trigger fired
    """
        if 'triggername' in args \
            and args['triggername'] == 'spellh_spellup_noprompt':
            self.current = 'spellup'
        elif 'triggername' in args \
            and args['triggername'] == 'spellh_affected_noprompt':
            self.current = 'affected'
        else:
            self.current = ''
        self.api.get('triggers.togglegroup')('spellhead', True)

    def skillline(self, args):
        """
    parse spell lines
    """
        spellnum = int(args['sn'])
        name = args['name']
        target = int(args['target'])
        if int(args['duration']) != 0:
            duration = time.mktime(time.localtime()) + int(args['duration'])
        else:
            duration = 0
        percent = int(args['pct'])
        recovery = int(args['rcvy'])
        stype = int(args['type'])

        if not (spellnum in self.skills):
            self.skills[spellnum] = {}

        self.skills[spellnum]['name'] = name
        self.skills[spellnum]['target'] = TARGET[target]
        self.skills[spellnum]['duration'] = duration
        self.skills[spellnum]['percent'] = percent
        self.skills[spellnum]['recovery'] = recovery
        self.skills[spellnum]['type'] = STYPE[stype]
        self.skills[spellnum]['sn'] = spellnum
        if not ('spellup' in self.skills[spellnum]):
            self.skills[spellnum]['spellup'] = False
        if self.current == 'spellup':
            self.skills[spellnum]['spellup'] = True

        self.skillsnamelookup[name] = spellnum

    def skillend(self, args):
        """
    reset current when seeing a spellheaders ending
    """
        self.api.get('triggers.togglegroup')('spellhead', False)
        self.savestate()
        if self.current:
            evname = 'aard_skill_ref_%s' % self.current
        else:
            evname = 'aard_skill_ref'
        self.api.get('events.eraise')(evname, {})
        self.current = ''

    # get a spell/skill by number
    def api_getskill(self, tsn):
        """
    get a skill
    """
        #self.api.get('send.msg')('looking for %s' % tsn)
        spellnum = -1
        name = tsn
        try:
            spellnum = int(tsn)
        except ValueError:
            pass

        tskill = None
        if spellnum >= 1:
            #self.api.get('send.msg')('%s >= 0' % spellnum)
            if spellnum in self.skills:
                #self.api.get('send.msg')('found spellnum')
                tskill = copy.deepcopy(self.skills[spellnum])
                #tskill = self.skills[spellnum]
            else:
                self.api.get('send.msg')('did not find skill for %s' %
                                         spellnum)

        if not tskill and name:
            #self.api.get('send.msg')('trying name')
            tlist = self.api.get('utils.checklistformatch')(
                name, self.skillsnamelookup.keys())
            if len(tlist) == 1:
                tskill = copy.deepcopy(
                    self.skills[self.skillsnamelookup[tlist[0]]])

        if tskill:
            if tskill['recovery'] and tskill['recovery'] != -1:
                tskill['recovery'] = copy.deepcopy(
                    self.recoveries[tskill['recovery']])
            else:
                tskill['recovery'] = None

        return tskill

    # send the command to active a skill/spell
    def api_sendcmd(self, spellnum):
        """
    send the command to activate a skill/spell
    """
        skill = self.api.get('skills.gets')(spellnum)
        if skill:
            if skill['type'] == 'spell':
                self.api.get('send.msg')('casting %s' % skill['name'])
                self.api.get('send.execute')('cast %s' % skill['sn'])
            else:
                name = skill['name'].split()[0]
                self.api.get('send.msg')('sending skill %s' % skill['name'])
                self.api.get('send.execute')(name)

    # check if a skill/spell can be used
    def api_canuse(self, spellnum):
        """
    return True if the spell can be used
    """
        if self.api.get('skills.isaffected')(spellnum) \
            or self.api.get('skills.isblockedbyrecovery')(spellnum) \
            or not self.api.get('skills.ispracticed')(spellnum):
            return False

        return True

    # check if a skill/spell is a spellup
    def api_isspellup(self, spellnum):
        """
    return True for a spellup, else return False
    """
        spellnum = int(spellnum)
        if spellnum in self.skills:
            return self.skills[spellnum]['spellup']

        return False

    # check if a skill/spell is bad
    def api_isbad(self, spellnum):
        """
    return True for a bad spell, False for a good spell
    """
        skill = self.api.get('skill.gets')(spellnum)
        if (skill['target'] == 'attack' or skill['target'] == 'special') and \
              not skill['spellup']:
            return True

        return False

    # check if a skill/spell is active
    def api_isaffected(self, spellnum):
        """
    return True for a spellup, else return False
    """
        skill = self.api.get('skills.gets')(spellnum)
        if skill:
            return skill['duration'] > 0

        return False

    # check if a skill/spell is blocked by a recovery
    def api_isblockedbyrecovery(self, spellnum):
        """
    check to see if a spell/skill is blocked by a recovery
    """
        skill = self.api.get('skills.gets')(spellnum)
        if skill:
            if 'recovery' in skill and skill['recovery'] and \
                skill['recovery']['duration'] > 0:
                return True

        return False

    # check if a skill/spell is practiced
    def api_ispracticed(self, spellnum):
        """
    is the spell learned
    """
        skill = self.api.get('skills.gets')(spellnum)
        if skill:
            if skill['percent'] > 10:
                return True

        return False

    # get the list of spellup spells/skills
    def api_getspellups(self):
        """
    return a list of spellup spells
    """
        sus = [x for x in self.skills.values() if x['spellup']]
        return sus

    def savestate(self):
        """
    save states
    """
        AardwolfBasePlugin.savestate(self)
        self.skills.sync()
        self.recoveries.sync()
Example #5
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin to handle aardwolf cp events
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.savelevelfile = os.path.join(self.savedir, 'level.txt')
    self.levelinfo = PersistentDict(self.savelevelfile, 'c')

  def load(self): # pylint: disable=too-many-statements
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)

    self.api('setting.add')('preremort', False, bool,
                            'flag for pre remort')
    self.api('setting.add')('remortcomp', False, bool,
                            'flag for remort completion')
    self.api('setting.add')('tiering', False, bool, 'flag for tiering')
    self.api('setting.add')('seen2', False, bool,
                            'we saw a state 2 after tiering')

    self.api('watch.add')('shloud', '^superhero loud$')
    self.api('watch.add')('shsilent', '^superhero silent$')
    self.api('watch.add')('shconfirm', '^superhero confirm$')
    self.api('watch.add')('shloudconfirm', '^superhero loud confirm$')

    self.api('triggers.add')('lvlpup',
                             r"^Congratulations, hero. You have increased your powers!$")
    self.api('triggers.add')('lvlpupbless',
                             r"^You gain a powerup\.$")
    self.api('triggers.add')('lvllevel',
                             r"^You raise a level! You are now level (?P<level>\d*).$",
                             argtypes={'level':int})
    self.api('triggers.add')('lvlshloud',
                             r"^Congratulations! You are now a superhero!" \
                             r" You receive (?P<trains>) trains for superhero loud.$",
                             argtypes={'trains':int})
    self.api('triggers.add')('lvlsh',
                             r"^Congratulations! You are now a superhero!")
    self.api('triggers.add')('lvlbless',
                             r"^You gain a level - you are now level (?P<level>\d*).$",
                             argtypes={'level':int})
    self.api('triggers.add')('lvlgains',
                             r"^You gain (?P<hp>\d*) hit points, (?P<mp>\d*) mana, "\
                               r"(?P<mv>\d*) moves, (?P<pr>\d*) practices and " \
                               r"(?P<tr>\d*) trains.$",
                             enabled=False, group='linfo',
                             argtypes={'hp':int, 'mn':int, 'mv':int, 'pr':int, 'tr':int})
    self.api('triggers.add')('lvlblesstrain',
                             r"^You gain (?P<tr>\d*) extra trains? " \
                               r"daily blessing bonus.$",
                             enabled=False, group='linfo',
                             argtypes={'tr':int})
    self.api('triggers.add')('lvlpupgains',
                             r"^You gain (?P<tr>\d*) trains.$",
                             enabled=False, group='linfo',
                             argtypes={'tr':int})
    self.api('triggers.add')('lvlbattlelearntrains',
                             r"^You gain (?P<tr>\d*) additional training sessions? " \
                               r"from your enhanced battle learning.$",
                             enabled=False, group='linfo',
                             argtypes={'tr':int})
    self.api('triggers.add')('lvlbonustrains',
                             r"^Lucky! You gain an extra (?P<tr>\d*) " \
                               r"training sessions?!$",
                             enabled=False, group='linfo',
                             argtypes={'tr':int})
    self.api('triggers.add')('lvlbonusstat',
                             r"^You gain a bonus (?P<stat>.*) point!$",
                             enabled=False, group='linfo')

    self.api('triggers.add')('lvlshbadstar',
                             r"^%s$" % re.escape("*******************************" \
                                "****************************************"),
                             enabled=False, group='superhero')
    self.api('triggers.add')('lvlshbad',
                             r"^Use either: 'superhero loud'   - (?P<mins>.*) mins of " \
                               r"double xp, (?P<qp>.*)qp and (?P<gold>.*) gold$",
                             enabled=False, group='superhero')
    self.api('triggers.add')('lvlshnogold',
                             r"^You must be carrying at least 500,000 gold coins.$",
                             enabled=False, group='superhero')
    self.api('triggers.add')('lvlshnoqp',
                             r"^You must have at least 1000 quest points.$",
                             enabled=False, group='superhero')
    self.api('triggers.add')('lvlshnodbl',
                             r"^You cannot superhero loud until double exp is over.$",
                             enabled=False, group='superhero')
    self.api('triggers.add')('lvlshnot200',
                             r"^You have to be level 200 to superhero.$",
                             enabled=False, group='superhero')

    self.api('triggers.add')('lvlpreremort',
                             r"^You are now flagged as remorting.$",
                             enabled=True, group='remort')
    self.api('triggers.add')('lvlremortcomp',
                             r"^\* Remort transformation complete!$",
                             enabled=True, group='remort')
    self.api('triggers.add')('lvltier',
                             r"^## You have already remorted the max number of times.$",
                             enabled=True, group='remort')


    self.api('events.register')('trigger_lvlpup', self._lvl)
    self.api('events.register')('trigger_lvlpupbless', self._lvl)
    self.api('events.register')('trigger_lvllevel', self._lvl)
    self.api('events.register')('trigger_lvlbless', self._lvl)
    #self.api('events.register')('trigger_lvlsh', self._lvl)
    self.api('events.register')('trigger_lvlgains', self._lvlgains)
    self.api('events.register')('trigger_lvlpupgains', self._lvlgains)
    self.api('events.register')('trigger_lvlblesstrain',
                                self._lvlblesstrains)
    self.api('events.register')('trigger_lvlbonustrains',
                                self._lvlbonustrains)
    self.api('events.register')('trigger_lvlbonusstat',
                                self._lvlbonusstat)
    self.api('events.register')('trigger_lvlbattlelearntrains',
                                self._lvlbattlelearntrains)

    self.api('events.register')('trigger_lvlshbadstar',
                                self._superherobad)
    self.api('events.register')('trigger_lvlshbad', self._superherobad)
    self.api('events.register')('trigger_lvlshnogold',
                                self._superherobad)
    self.api('events.register')('trigger_lvlshnoqp', self._superherobad)
    self.api('events.register')('trigger_lvlshnodbl', self._superherobad)
    self.api('events.register')('trigger_lvlshnot200', self._superherobad)

    self.api('events.register')('watch_shloud', self.cmd_superhero)
    self.api('events.register')('watch_shsilent', self.cmd_superhero)
    self.api('events.register')('watch_shconfirm', self.cmd_superhero)
    self.api('events.register')('watch_shloudconfirm', self.cmd_superhero)

    self.api('events.register')('trigger_lvlpreremort', self._preremort)
    self.api('events.register')('trigger_lvlremortcomp', self._remortcomp)
    self.api('events.register')('trigger_lvltier', self._tier)

    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)

  def _gmcpstatus(self, _=None):
    """
    check gmcp status when tiering
    """
    state = self.api('GMCP.getv')('char.status.state')
    if state == 2:
      self.api('ouput.client')('seen2')
      self.api('setting.change')('seen2', True)
      self.api('events.unregister')('GMCP:char.status', self._gmcpstatus)
      self.api('events.register')('GMCP:char.base', self._gmcpbase)

  def _gmcpbase(self, _=None):
    """
    look for a new base when we remort
    """
    self.api('send.client')('called char.base')
    state = self.api('GMCP.getv')('char.status.state')
    tiering = self.api('setting.gets')('tiering')
    seen2 = self.api('setting.gets')('seen2')
    if tiering and seen2 and state == 3:
      self.api('send.client')('in char.base')
      self.api('events.unregister')('GMCP:char.base', self._gmcpstatus)
      self._lvl({'level':1})

  def _tier(self, _=None):
    """
    about to tier
    """
    self.api('setting.change')('tiering', True)
    self.api('send.client')('tiering')
    self.api('events.register')('GMCP:char.status', self._gmcpstatus)

  def _remortcomp(self, _=None):
    """
    do stuff when a remort is complete
    """
    self.api('setting.change')('preremort', False)
    self.api('setting.change')('remortcomp', True)
    self._lvl({'level':1})

  def _preremort(self, _=None):
    """
    set the preremort flag
    """
    self.api('setting.change')('preremort', True)
    self.api('events.eraise')('aard_level_preremort', {})

  def cmd_superhero(self, _=None):
    """
    figure out what is done when superhero is typed
    """
    self.api('send.client')('superhero was typed')
    self.api('triggers.togglegroup')('superhero', True)
    self._lvl({'level':201})

  def _superherobad(self, _=None):
    """
    undo things that we typed if we didn't really superhero
    """
    self.api('send.client')('didn\'t sh though')
    self.api('triggers.togglegroup')('superhero', False)
    self.api('triggers.togglegroup')('linfo', False)
    self.api('events.unregister')('trigger_emptyline', self._finish)

  def resetlevel(self):
    """
    reset the level info, use the finishtime of the last level as
    the starttime of the next level
    """
    if 'finishtime' in self.levelinfo and self.levelinfo['finishtime'] > 0:
      starttime = self.levelinfo['finishtime']
    else:
      starttime = time.time()
    self.levelinfo.clear()
    self.levelinfo['type'] = ""
    self.levelinfo['level'] = -1
    self.levelinfo['str'] = 0
    self.levelinfo['int'] = 0
    self.levelinfo['wis'] = 0
    self.levelinfo['dex'] = 0
    self.levelinfo['con'] = 0
    self.levelinfo['luc'] = 0
    self.levelinfo['starttime'] = starttime
    self.levelinfo['hp'] = 0
    self.levelinfo['mp'] = 0
    self.levelinfo['mv'] = 0
    self.levelinfo['pracs'] = 0
    self.levelinfo['trains'] = 0
    self.levelinfo['bonustrains'] = 0
    self.levelinfo['blessingtrains'] = 0
    self.levelinfo['battlelearntrains'] = 0
    self.levelinfo['totallevels'] = 0

  def _lvl(self, args=None):
    """
    trigger for leveling
    """
    if not args:
      return

    self.resetlevel()
    if 'triggername' in args and (args['triggername'] == 'lvlpup' \
        or args['triggername'] == 'lvlpupbless'):
      self.levelinfo['level'] = self.api('GMCP.getv')('char.status.level')
      self.levelinfo['totallevels'] = self.api('aardu.getactuallevel')()
      self.levelinfo['type'] = 'pup'
    else:
      self.levelinfo['level'] = args['level']
      self.levelinfo['totallevels'] = self.api('aardu.getactuallevel')(
          args['level'])
      self.levelinfo['type'] = 'level'

    self.api('triggers.togglegroup')('linfo', True)
    self.api('events.register')('trigger_emptyline', self._finish)


  def _lvlblesstrains(self, args):
    """
    trigger for blessing trains
    """
    self.levelinfo['blessingtrains'] = args['tr']

  def _lvlbonustrains(self, args):
    """
    trigger for bonus trains
    """
    self.levelinfo['bonustrains'] = args['tr']

  def _lvlbattlelearntrains(self, args):
    """
    trigger for bonus trains
    """
    self.levelinfo['battlelearntrains'] = args['tr']

  def _lvlbonusstat(self, args):
    """
    trigger for bonus stats
    """
    self.levelinfo[args['stat'][:3].lower()] = 1

  def _lvlgains(self, args):
    """
    trigger for level gains
    """
    self.levelinfo['trains'] = args['tr']

    if args['triggername'] == "lvlgains":
      self.levelinfo['hp'] = args['hp']
      self.levelinfo['mp'] = args['mp']
      self.levelinfo['mv'] = args['mv']
      self.levelinfo['pracs'] = args['pr']

  def _finish(self, _):
    """
    finish up and raise the level event
    """
    remortcomp = self.api('setting.gets')('remortcomp')
    tiering = self.api('setting.gets')('tiering')
    if self.levelinfo['trains'] == 0 and not remortcomp or tiering:
      return
    self.levelinfo['finishtime'] = time.time()
    self.levelinfo.sync()
    self.api('triggers.togglegroup')('linfo', False)
    self.api('events.unregister')('trigger_emptyline', self._finish)
    self.api('events.eraise')('aard_level_gain',
                              copy.deepcopy(self.levelinfo))
    if self.levelinfo['level'] == 200 and self.levelinfo['type'] == 'level':
      self.api('send.msg')('raising hero event', 'level')
      self.api('events.eraise')('aard_level_hero', {})
    elif self.levelinfo['level'] == 201 and self.levelinfo['type'] == 'level':
      self.api('send.msg')('raising superhero event', 'level')
      self.api('events.eraise')('aard_level_superhero', {})
    elif self.levelinfo['level'] == 1:
      if self.api('setting.gets')('tiering'):
        self.api('send.msg')('raising tier event', 'level')
        self.api('setting.change')('tiering', False)
        self.api('setting.change')('seen2', False)
        self.api('events.eraise')('aard_level_tier', {})
      else:
        self.api('send.msg')('raising remort event', 'level')
        self.api('setting.change')('remortcomp', False)
        self.api('events.eraise')('aard_level_remort', {})

  def _savestate(self, _=None):
    """
    save states
    """
    self.levelinfo.sync()
Example #6
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin to handle aardwolf cp events
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.savelevelfile = os.path.join(self.savedir, 'level.txt')
        self.levelinfo = PersistentDict(self.savelevelfile, 'c')

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)

        self.api.get('setting.add')('preremort', False, bool,
                                    'flag for pre remort')
        self.api.get('setting.add')('remortcomp', False, bool,
                                    'flag for remort completion')
        self.api.get('setting.add')('tiering', False, bool, 'flag for tiering')
        self.api.get('setting.add')('seen2', False, bool,
                                    'we saw a state 2 after tiering')

        self.api.get('watch.add')('shloud', '^superhero loud$')
        self.api.get('watch.add')('shsilent', '^superhero silent$')
        self.api.get('watch.add')('shconfirm', '^superhero confirm$')
        self.api.get('watch.add')('shloudconfirm', '^superhero loud confirm$')

        self.api.get('triggers.add')(
            'lvlpup',
            "^Congratulations, hero. You have increased your powers!$")
        self.api.get('triggers.add')('lvlpupbless', "^You gain a powerup\.$")
        self.api.get('triggers.add')(
            'lvllevel',
            "^You raise a level! You are now level (?P<level>\d*).$",
            argtypes={
                'level': int
            })
        self.api.get('triggers.add')(
            'lvlsh',
            "^Congratulations! You are now a superhero!$",
            argtypes={
                'level': int
            })
        self.api.get('triggers.add')(
            'lvlbless',
            "^You gain a level - you are now level (?P<level>\d*).$",
            argtypes={
                'level': int
            })
        self.api.get('triggers.add')('lvlgains',
            "^You gain (?P<hp>\d*) hit points, (?P<mp>\d*) mana, "\
              "(?P<mv>\d*) moves, (?P<pr>\d*) practices and (?P<tr>\d*) trains.$",
            enabled=False, group='linfo',
            argtypes={'hp':int, 'mn':int, 'mv':int, 'pr':int, 'tr':int})
        self.api.get('triggers.add')(
            'lvlblesstrain',
            "^You gain (?P<tr>\d*) extra trains? daily blessing bonus.$",
            enabled=False,
            group='linfo',
            argtypes={
                'tr': int
            })
        self.api.get('triggers.add')('lvlpupgains',
                                     "^You gain (?P<tr>\d*) trains.$",
                                     enabled=False,
                                     group='linfo',
                                     argtypes={
                                         'tr': int
                                     })
        self.api.get('triggers.add')(
            'lvlbonustrains',
            "^Lucky! You gain an extra (?P<tr>\d*) training sessions?!$",
            enabled=False,
            group='linfo',
            argtypes={
                'tr': int
            })
        self.api.get('triggers.add')('lvlbonusstat',
                                     "^You gain a bonus (?P<stat>.*) point!$",
                                     enabled=False,
                                     group='linfo')

        self.api.get('triggers.add')('lvlshbadstar',
            "^%s$" % re.escape("*******************************" \
                  "****************************************"),
            enabled=False, group='superhero')
        self.api.get('triggers.add')('lvlshbad',
            "^Use either: 'superhero loud'   - (?P<mins>.*) mins of " \
              "double xp, (?P<qp>.*)qp and (?P<gold>.*) gold$",
            enabled=False, group='superhero')
        self.api.get('triggers.add')(
            'lvlshnogold',
            "^You must be carrying at least 500,000 gold coins.$",
            enabled=False,
            group='superhero')
        self.api.get('triggers.add')(
            'lvlshnoqp',
            "^You must have at least 1000 quest points.$",
            enabled=False,
            group='superhero')

        self.api.get('triggers.add')('lvlpreremort',
                                     "^You are now flagged as remorting.$",
                                     enabled=True,
                                     group='remort')
        self.api.get('triggers.add')('lvlremortcomp',
                                     "^\* Remort transformation complete!$",
                                     enabled=True,
                                     group='remort')
        self.api.get('triggers.add')(
            'lvltier',
            "^## You have already remorted the max number of times.$",
            enabled=True,
            group='remort')

        self.api.get('events.register')('trigger_lvlpup', self._lvl)
        self.api.get('events.register')('trigger_lvlpupbless', self._lvl)
        self.api.get('events.register')('trigger_lvllevel', self._lvl)
        self.api.get('events.register')('trigger_lvlbless', self._lvl)
        self.api.get('events.register')('trigger_lvlgains', self._lvlgains)
        self.api.get('events.register')('trigger_lvlpupgains', self._lvlgains)
        self.api.get('events.register')('trigger_lvlblesstrain',
                                        self._lvlblesstrains)
        self.api.get('events.register')('trigger_lvlbonustrains',
                                        self._lvlbonustrains)
        self.api.get('events.register')('trigger_lvlbonusstat',
                                        self._lvlbonusstat)

        self.api.get('events.register')('trigger_lvlshbadstar',
                                        self._superherobad)
        self.api.get('events.register')('trigger_lvlshbad', self._superherobad)
        self.api.get('events.register')('trigger_lvlshnogold',
                                        self._superherobad)
        self.api.get('events.register')('trigger_lvlshnoqp',
                                        self._superherobad)

        self.api.get('events.register')('watch_shloud', self.cmd_superhero)
        self.api.get('events.register')('watch_shsilent', self.cmd_superhero)
        self.api.get('events.register')('watch_shconfirm', self.cmd_superhero)
        self.api.get('events.register')('watch_shloudconfirm',
                                        self.cmd_superhero)

        self.api.get('events.register')('trigger_lvlpreremort',
                                        self._preremort)
        self.api.get('events.register')('trigger_lvlremortcomp',
                                        self._remortcomp)
        self.api.get('events.register')('trigger_lvltier', self._tier)

    def _gmcpstatus(self, _=None):
        """
    check gmcp status when tiering
    """
        state = self.api.get('GMCP.getv')('char.status.state')
        if state == 2:
            self.api.get('ouput.client')('seen2')
            self.api.get('setting.change')('seen2', True)
            self.api.get('events.unregister')('GMCP:char.status',
                                              self._gmcpstatus)
            self.api.get('events.register')('GMCP:char.base', self._gmcpbase)

    def _gmcpbase(self, _=None):
        """
    look for a new base when we remort
    """
        self.api.get('send.client')('called char.base')
        state = self.api.get('GMCP.getv')('char.status.state')
        tiering = self.api.get('setting.gets')('tiering')
        seen2 = self.api.get('setting.gets')('seen2')
        if tiering and seen2 and state == 3:
            self.api.get('send.client')('in char.base')
            self.api.get('events.unregister')('GMCP:char.base',
                                              self._gmcpstatus)
            self._lvl({'level': 1})

    def _tier(self, _=None):
        """
    about to tier
    """
        self.api.get('setting.change')('tiering', True)
        self.api.get('send.client')('tiering')
        self.api.get('events.register')('GMCP:char.status', self._gmcpstatus)

    def _remortcomp(self, _=None):
        """
    do stuff when a remort is complete
    """
        self.api.get('setting.change')('preremort', False)
        self.api.get('setting.change')('remortcomp', True)
        self._lvl({'level': 1})

    def _preremort(self, _=None):
        """
    set the preremort flag
    """
        self.api.get('setting.change')('preremort', True)
        self.api.get('events.eraise')('aard_level_preremort', {})

    def cmd_superhero(self, _=None):
        """
    figure out what is done when superhero is typed
    """
        self.api.get('send.client')('superhero was typed')
        self.api.get('triggers.togglegroup')('superhero', True)
        self._lvl({'level': 201})

    def _superherobad(self, _=None):
        """
    undo things that we typed if we didn't really superhero
    """
        self.api.get('send.client')('didn\'t sh though')
        self.api.get('triggers.togglegroup')('superhero', False)
        self.api.get('triggers.togglegroup')('linfo', False)
        self.api.get('events.unregister')('trigger_emptyline', self._finish)

    def resetlevel(self):
        """
    reset the level info, use the finishtime of the last level as
    the starttime of the next level
    """
        if 'finishtime' in self.levelinfo and self.levelinfo['finishtime'] > 0:
            starttime = self.levelinfo['finishtime']
        else:
            starttime = time.time()
        self.levelinfo.clear()
        self.levelinfo['type'] = ""
        self.levelinfo['level'] = -1
        self.levelinfo['str'] = 0
        self.levelinfo['int'] = 0
        self.levelinfo['wis'] = 0
        self.levelinfo['dex'] = 0
        self.levelinfo['con'] = 0
        self.levelinfo['luc'] = 0
        self.levelinfo['starttime'] = starttime
        self.levelinfo['hp'] = 0
        self.levelinfo['mp'] = 0
        self.levelinfo['mv'] = 0
        self.levelinfo['pracs'] = 0
        self.levelinfo['trains'] = 0
        self.levelinfo['bonustrains'] = 0
        self.levelinfo['blessingtrains'] = 0
        self.levelinfo['totallevels'] = 0

    def _lvl(self, args=None):
        """
    trigger for leveling
    """
        if not args:
            return

        self.resetlevel()
        if 'triggername' in args and (args['triggername'] == 'lvlpup' \
            or args['triggername'] == 'lvlpupbless'):
            self.levelinfo['level'] = self.api.get('GMCP.getv')(
                'char.status.level')
            self.levelinfo['totallevels'] = self.api.get(
                'aardu.getactuallevel')()
            self.levelinfo['type'] = 'pup'
        else:
            self.levelinfo['level'] = args['level']
            self.levelinfo['totallevels'] = self.api.get(
                'aardu.getactuallevel')(args['level'])
            self.levelinfo['type'] = 'level'

        self.api.get('triggers.togglegroup')('linfo', True)
        self.api.get('events.register')('trigger_emptyline', self._finish)

    def _lvlblesstrains(self, args):
        """
    trigger for blessing trains
    """
        self.levelinfo['blessingtrains'] = args['tr']

    def _lvlbonustrains(self, args):
        """
    trigger for bonus trains
    """
        self.levelinfo['bonustrains'] = args['tr']

    def _lvlbonusstat(self, args):
        """
    trigger for bonus stats
    """
        self.levelinfo[args['stat'][:3].lower()] = 1

    def _lvlgains(self, args):
        """
    trigger for level gains
    """
        self.levelinfo['trains'] = args['tr']

        if args['triggername'] == "lvlgains":
            self.levelinfo['hp'] = args['hp']
            self.levelinfo['mp'] = args['mp']
            self.levelinfo['mv'] = args['mv']
            self.levelinfo['pracs'] = args['pr']

    def _finish(self, _):
        """
    finish up and raise the level event
    """
        remortcomp = self.api.get('setting.gets')('remortcomp')
        tiering = self.api.get('setting.gets')('tiering')
        if self.levelinfo['trains'] == 0 and not remortcomp or tiering:
            return
        self.levelinfo['finishtime'] = time.time()
        self.levelinfo.sync()
        self.api.get('triggers.togglegroup')('linfo', False)
        self.api.get('events.unregister')('trigger_emptyline', self._finish)
        self.api.get('events.eraise')('aard_level_gain',
                                      copy.deepcopy(self.levelinfo))
        if self.levelinfo['level'] == 200 and self.levelinfo['type'] == 'level':
            self.api.get('send.msg')('raising hero event', 'level')
            self.api.get('events.eraise')('aard_level_hero', {})
        elif self.levelinfo['level'] == 201 and self.levelinfo[
                'type'] == 'level':
            self.api.get('send.msg')('raising superhero event', 'level')
            self.api.get('events.eraise')('aard_level_superhero', {})
        elif self.levelinfo['level'] == 1:
            if self.api.get('setting.gets')('tiering'):
                self.api.get('send.msg')('raising tier event', 'level')
                self.api.get('setting.change')('tiering', False)
                self.api.get('setting.change')('seen2', False)
                self.api.get('events.eraise')('aard_level_tier', {})
            else:
                self.api.get('send.msg')('raising remort event', 'level')
                self.api.get('setting.change')('remortcomp', False)
                self.api.get('events.eraise')('aard_level_remort', {})

    def savestate(self):
        """
    save states
    """
        AardwolfBasePlugin.savestate(self)
        self.levelinfo.sync()
Example #7
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin to handle aardwolf quest events
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.savegqfile = os.path.join(self.savedir, 'gq.txt')
    self.gqinfo = PersistentDict(self.savegqfile, 'c')
    self._gqsdeclared = {}
    self._gqsstarted = {}
    self.api('setting.add')('joined', -1, int, 'the gq number joined')
    self.api('setting.add')('maxkills', False, bool, 'no qp because of maxkills')
    self.mobsleft = []
    self.linecount = 0

  def load(self):
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)
    self.api('watch.add')('gq_check',
                          r'^(gq|gqu|gque|gques|gquest) (c|ch|che|chec|check)$')

    self.api('triggers.add')(
        'gqdeclared',
        r"^Global Quest: Global quest \# *(?P<gqnum>\d*) has been " \
          r"declared for levels (?P<lowlev>\d*) to (?P<highlev>\d*)( - .*)*\.$",
        argtypes={'gqnum':int})
    self.api('triggers.add')(
        'gqjoined',
        r"^You have now joined Global Quest \# *(?P<gqnum>\d*)\. .*$",
        argtypes={'gqnum':int})
    self.api('triggers.add')(
        'gqstarted',
        r"^Global Quest: Global quest \# *(?P<gqnum>\d*) for levels .* "\
          r"to .* has now started\.$",
        argtypes={'gqnum':int})
    self.api('triggers.add')(
        'gqcancelled',
        r"^Global Quest: Global quest \# *(?P<gqnum>\d*) has been " \
          r"cancelled due to lack of (activity|participants)\.$",
        argtypes={'gqnum':int})
    self.api('triggers.add')(
        'gqquit',
        r"^You are no longer part of Global Quest \# *(?P<gqnum>\d*) " \
          r"and will be unable to rejoin.$",
        argtypes={'gqnum':int})

    # GQ Check triggers
    self.api('triggers.add')(
        'gqnone',
        r"^You are not in a global quest\.$",
        enabled=False, group='gqcheck')
    self.api('triggers.add')(
        'gqitem',
        r"^You still have to kill (?P<num>[\d]*) \* " \
          r"(?P<mob>.*?) \((?P<location>.*?)\)(|\.)$",
        enabled=False, group='gqcheck',
        argtypes={'num':int})
    self.api('triggers.add')(
        'gqnotstarted',
        r"^Global Quest \# *(?P<gqnum>\d*) has not yet started.",
        enabled=False, group='gqcheck',
        argtypes={'gqnum':int})
    self.api('triggers.add')(
        'gqwins',
        r"^You may win .* more gquests* at this level\.$",
        enabled=False, group='gqcheck')

    self.api('triggers.add')(
        'gqreward',
        r"^\s*Reward of (?P<amount>\d+) (?P<type>.+) .+ added\.$",
        enabled=False, group='gqrew',
        argtypes={'amount':int})

    self.api('triggers.add')(
        'gqmobdead',
        r"^Congratulations, that was one of the GLOBAL QUEST mobs!$",
        enabled=False, group='gqin')

    self.api('triggers.add')(
        'gqextended',
        r"^Global Quest: Global Quest \# *(?P<gqnum>\d*) will go " \
          r"into extended time for 3 more minutes.$",
        enabled=False, group='gqin',
        argtypes={'gqnum':int})

    self.api('triggers.add')(
        'gqwon',
        r"^You were the first to complete this quest!$",
        enabled=False, group='gqin')
    self.api('triggers.add')(
        'gqextfin',
        r"^You have finished this global quest.$",
        enabled=False, group='gqin')
    self.api('triggers.add')(
        'gqwonannounce',
        r"Global Quest: Global Quest \#(?P<gqnum>.*) has been won " \
          r"by (?P<winner>.*) - (.*) win.$",
        enabled=False, group='gqin',
        argtypes={'gqnum':int})

    self.api('triggers.add')(
        'gqnote',
        r"^INFO: New post \#(?P<bdnum>.*) in forum Gquest from " \
          r"Aardwolf Subj: Lvl (?P<low>.*) to (?P<high>.*) - " \
          r"Global quest \# *(?P<gqnum>\d*)$",
        argtypes={'gqnum':int})

    self.api('triggers.add')(
        'gqmaxkills',
        r"^You have reached the " \
          r"maximum (.*) kills for which you can earn quest points this level\.$")

    self.api('events.register')('trigger_gqdeclared', self._gqdeclared)
    self.api('events.register')('trigger_gqjoined', self._gqjoined)
    self.api('events.register')('trigger_gqstarted', self._gqstarted)
    self.api('events.register')('trigger_gqcancelled', self._gqcancelled)
    self.api('events.register')('trigger_gqquit', self._gqquit)

    self.api('events.register')('trigger_gqnone', self._notstarted)
    self.api('events.register')('trigger_gqitem', self._gqitem)
    self.api('events.register')('trigger_gqnotstarted', self._notstarted)
    self.api('events.register')('trigger_gqwins', self._gqwins)

    self.api('events.register')('trigger_gqreward', self._gqreward)

    self.api('events.register')('trigger_gqmobdead', self._gqmobdead)

    self.api('events.register')('trigger_gqextended', self._gqextended)

    self.api('events.register')('trigger_gqwon', self._gqwon)
    self.api('events.register')('trigger_gqextfin', self._gqextfin)
    self.api('events.register')('trigger_gqwonannounce',
                                self._gqwonannounce)

    self.api('events.register')('trigger_gqnote', self._gqnote)
    self.api('events.register')('trigger_gqmaxkills', self._gqmaxkills)

    self.api('events.register')('watch_gq_check', self._gqcheckcmd)

    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)

  def _gqnew(self):
    """
    reset the gq info
    """
    self.mobsleft = {}
    self.gqinfo.clear()
    self.gqinfo['mobs'] = {}
    self.gqinfo['trains'] = 0
    self.gqinfo['pracs'] = 0
    self.gqinfo['gold'] = 0
    self.gqinfo['tp'] = 0
    self.gqinfo['qp'] = 0
    self.gqinfo['qpmobs'] = 0
    self.gqinfo['level'] = self.api('aardu.getactuallevel')(
        self.api('GMCP.getv')('char.status.level'))
    self.gqinfo['starttime'] = 0
    self.gqinfo['finishtime'] = 0
    self.gqinfo['length'] = 0
    self.gqinfo['won'] = 0
    self.gqinfo['completed'] = 0
    self.gqinfo['extended'] = 0
    self.api('setting.change')('maxkills', False)
    self.savestate()

  def _gqdeclared(self, args):
    """
    do something when a gq is declared
    """
    self._gqsdeclared[args['gqnum']] = True
    self._checkgqavailable()
    self._raisegq('aard_gq_declared', args)

  def _gqjoined(self, args):
    """
    do something when a gq is joined
    """
    self._gqnew()
    self.api('setting.change')('joined', args['gqnum'])

    self.mobsleft = []

    if args['gqnum'] in self._gqsstarted:
      self._gqstarted(args)
    elif args['gqnum'] not in self._gqsdeclared:
      self._gqsdeclared[args['gqnum']] = True
      self._gqstarted(args)
    self._raisegq('aard_gq_joined', args)

  def _gqstarted(self, args):
    """
    do something when a gq starts
    """
    if args['gqnum'] not in self._gqsstarted:
      self._gqsstarted[args['gqnum']] = True
      self._raisegq('aard_gq_started', args)
      self._checkgqavailable()
    if self.api('setting.gets')('joined') == args['gqnum']:
      self.gqinfo['starttime'] = time.time()
      self.api('triggers.togglegroup')("gqin", True)
      self.api('send.execute')("gq check")

  def _gqcancelled(self, args):
    """
    the gq has been cancelled
    """
    self._raisegq('aard_gq_cancelled', {'gqnum':args['gqnum']})
    if args['gqnum'] == self.api('setting.gets')('joined'):
      if self.gqinfo['qpmobs'] > 0:
        self.gqinfo['finishtime'] = time.time()
        self._raisegq('aard_gq_done', self.gqinfo)
      self._gqreset({'gqnum':args['gqnum']})

    else:
      if args['gqnum'] in self._gqsdeclared:
        del self._gqsdeclared[args['gqnum']]
      if args['gqnum'] in self._gqsstarted:
        del self._gqsstarted[args['gqnum']]
      self._checkgqavailable()

  def _gqitem(self, args):
    """
    do something with a gq item
    """
    name = args['mob']
    num = args['num']
    location = args['location']
    if not name or not location or not num:
      self.api('send.client')("error parsing line: %s" % args['line'])
    else:
      self.mobsleft.append({'name':name,
                            'nocolorname':self.api('colors.stripansi')(name),
                            'location':location, 'num':num})

  def _notstarted(self, _=None):
    """
    this will be called when a gq check returns the not started message
    """
    self.api('triggers.togglegroup')('gqcheck', False)
    self.api('triggers.togglegroup')('gqin', False)

  def _gqwins(self, _=None):
    """
    this will be enabled when gq check is enabled
    """
    if not self.gqinfo['mobs']:
      self.gqinfo['mobs'] = self.mobsleft[:]
      self.savestate()

    self.api('triggers.togglegroup')('gqcheck', False)
    self._raisegq('aard_gq_mobsleft',
                  {'mobsleft':copy.deepcopy(self.mobsleft)})

  def _gqmobdead(self, _=None):
    """
    called when a gq mob is killed
    """
    if not self.api('setting.gets')('maxkills'):
      self.gqinfo['qpmobs'] = self.gqinfo['qpmobs'] + 3
    self.api('events.register')('aard_mobkill', self._mobkillevent)

  def _gqextended(self, args):
    """
    gquest went into extended time
    """
    if args['gqnum'] == self.api('setting.gets')('joined'):
      self.gqinfo['extended'] = 1

  def _gqmaxkills(self, _=None):
    """
    didn't get xp for that last kill
    """
    self.api('setting.change')('maxkills', True)

  def _mobkillevent(self, args):
    """
    this will be registered to the mobkill hook
    """
    self.api('send.msg')('checking kill %s' % args['name'])
    self.api('events.register')('aard_mobkill', self._mobkillevent)

    found = False
    removeitem = None
    for i in range(len(self.mobsleft)):
      tmob = self.mobsleft[i]
      if tmob['name'] == args['name']:
        self.api('send.msg')('found %s' % tmob['name'])
        found = True
        if tmob['num'] == 1:
          removeitem = i
        else:
          tmob['num'] = tmob['num'] - 1

    if removeitem:
      del self.mobsleft[removeitem]

    if found:
      self._raisegq('aard_gq_mobsleft',
                    {'mobsleft':self.mobsleft})
    else:
      self.api('send.msg')("BP GQ: could not find mob: %s" % args['name'])
      self.api('send.execute')("gq check")

  def _gqwon(self, _=None):
    """
    the gquest was won
    """
    self.gqinfo['won'] = 1
    self.gqinfo['finishtime'] = time.time()
    self.api('triggers.togglegroup')("gqrew", True)

  def _gqwonannounce(self, args):
    """
    the mud announced that someone won the gquest
    """
    if self.api('GMCP.getv')('char.base.name') == args['winner']:
      # we won
      self._raisegq('aard_gq_won', self.gqinfo)
      self._gqreset(args)

  def _gqreward(self, args=None):
    """
    handle cpreward
    """
    rtype = args['type']
    ramount = args['amount']
    rewardt = self.api('aardu.rewardtable')()
    self.gqinfo[rewardt[rtype]] = ramount
    self.savestate()

  def _gqcheckcmd(self, args=None):
    """
    do something after we see a gq check
    """
    self.mobsleft = []
    self.api('triggers.togglegroup')('gqcheck', True)
    return args

  def _gqquit(self, args):
    """
    quit the gq
    """
    if self.gqinfo['qpmobs'] > 0:
      self.gqinfo['finishtime'] = time.time()
      self._raisegq('aard_gq_done', self.gqinfo)
    self._gqreset(args)

  def _gqextfin(self, _=None):
    """
    the character finished the extended gq
    """
    if self.gqinfo['qpmobs'] > 0:
      self.gqinfo['completed'] = 1
      self.gqinfo['finishtime'] = time.time()
      self._raisegq('aard_gq_completed', self.gqinfo)
      self._gqreset({'gqnum':self.api('setting.gets')('joined')})

  def _raisegq(self, event, data=None):
    """
    raise a gq event
    """
    self.api('send.msg')('raising %s with %s' % (event, data))
    self.savestate()
    if data:
      self.api('events.eraise')(event, copy.deepcopy(data))
    else:
      self.api('events.eraise')(event)

  def _gqnote(self, args):
    """
    do something on the gquest note
    """
    if args['gqnum'] == self.api('setting.gets')('joined'):
      if self.gqinfo['qpmobs'] > 0:
        self.gqinfo['finishtime'] = time.time()
        self._raisegq('aard_gq_done', self.gqinfo)
      self._gqreset(args)
    if args['gqnum'] in self._gqsdeclared:
      del self._gqsdeclared[args['gqnum']]
    if args['gqnum'] in self._gqsstarted:
      del self._gqsstarted[args['gqnum']]
    self._checkgqavailable()

  def _gqreset(self, args=None):
    """
    reset gq settings
    """
    self._gqnew()
    if args:
      if args['gqnum'] in self._gqsdeclared:
        del self._gqsdeclared[args['gqnum']]
      if args['gqnum'] in self._gqsstarted:
        del self._gqsstarted[args['gqnum']]
      self._checkgqavailable()
    self.api('triggers.togglegroup')("gqcheck", False)
    self.api('triggers.togglegroup')("gqin", False)
    self.api('triggers.togglegroup')("gqrew", False)
    self.api('events.unregister')('aard_mobkill', self._mobkillevent)
    self.api('setting.change')('joined', 'default')
    self.api('setting.change')('maxkills', False)
    self.savestate()

  def _checkgqavailable(self):
    if self._gqsdeclared:
      self._raisegq('aard_gq_available')
    else:
      self._raisegq('aard_gq_notavailable')

  def _savestate(self, _=None):
    """
    save states
    """
    self.gqinfo.sync()
Example #8
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin that does spellups
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.spellupfile = os.path.join(self.savedir, 'spellups.txt')
        self.spellups = PersistentDict(self.spellupfile, 'c')

        self.api('dependency.add')('aardwolf.skills')
        self.api('dependency.add')('aardwolf.move')

        self.initspellups()

        self.lastmana = -1
        self.lastmoves = -1

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)

        self.api('setting.add')('enabled', True, bool,
                                'auto spellup is enabled')
        self.api('setting.add')('waiting',
                                -1,
                                int,
                                'the spell that was just cast',
                                readonly=True)
        self.api('setting.add')('nocast',
                                False,
                                bool,
                                'in a nocast room',
                                readonly=True)
        self.api('setting.add')('nomoves',
                                False,
                                bool,
                                'need more moves',
                                readonly=True)
        self.api('setting.add')('nomana',
                                False,
                                bool,
                                'need more mana',
                                readonly=True)
        self.api('setting.add')('nocastrooms', {},
                                dict,
                                'list of nocast rooms',
                                readonly=True)
        self.api('setting.add')('currentroom',
                                -1,
                                int,
                                'the current room',
                                readonly=True)

        parser = argp.ArgumentParser(
            add_help=False, description='add a spellup to the self list')
        parser.add_argument(
            'spell',
            help='the spells to add, use \'all\' to add all practiced spellups',
            default=[],
            nargs='*')
        parser.add_argument(
            '-o',
            "--override",
            help="add even if the spell is not flagged as a spellup by the mud",
            action="store_true")
        self.api('commands.add')('add',
                                 self.cmd_sadd,
                                 parser=parser,
                                 group='Spellups on Self')

        parser = argp.ArgumentParser(add_help=False,
                                     description='list spellups for self')
        parser.add_argument(
            'match',
            help='list only spellups that have this argument in them',
            default='',
            nargs='?')
        self.api('commands.add')('list',
                                 self.cmd_slist,
                                 parser=parser,
                                 group='Spellups on Self')

        parser = argp.ArgumentParser(
            add_help=False, description='remove a spellup from the self list')
        parser.add_argument(
            'spell',
            help='the spells to remove, use \'all\' to remove all spellups',
            default=[],
            nargs='*')
        self.api('commands.add')('rem',
                                 self.cmd_srem,
                                 parser=parser,
                                 group='Spellups on Self')

        parser = argp.ArgumentParser(add_help=False,
                                     description='enable spellups on self')
        parser.add_argument(
            'spell',
            help='the spells to enable, use \'all\' to enable all spellups',
            default=[],
            nargs='*')
        self.api('commands.add')('en',
                                 self.cmd_en,
                                 parser=parser,
                                 group='Spellups on Self')

        parser = argp.ArgumentParser(add_help=False,
                                     description='disable spells on self')
        parser.add_argument(
            'spell',
            help='the spells to disable, use \'all\' to disable all spellups',
            default=[],
            nargs='*')
        self.api('commands.add')('dis',
                                 self.cmd_dis,
                                 shelp='disable a spellup on self',
                                 parser=parser,
                                 group='Spellups on Self')

        self.api('commands.add')('check',
                                 self.cmd_check,
                                 shelp='check data status for casting',
                                 group='Spellups on Self')

        self.api('events.register')('GMCP:char.vitals', self._charvitals)
        self.api('events.register')('GMCP:char.status', self._charstatus)
        self.api('events.register')('moved_room', self._moved)
        self.api('events.register')('skill_fail', self._skillfail)
        self.api('events.register')('aard_skill_affon', self._affon)
        self.api('events.register')('aard_skill_affoff', self._affoff)
        self.api('events.register')('aard_skill_recoff', self._recoff)
        self.api('events.register')('aard_skill_gain', self.skillgain)
        self.api('events.register')('var_su_enabled', self.enabledchange)
        self.api('events.register')('skills_affected_update', self.nextspell)
        self.api('events.register')('plugin_%s_savestate' % self.sname,
                                    self._savestate)
        self.api('events.register')('skills_uptodate', self.nextspell)

    def skillgain(self, args=None):
        """
    check skills when we gain them
    """
        if args['sn'] in self.spellups['sorder'] and args['percent'] > 50:
            self.nextspell()

    def initspellups(self):
        """
    initialize the spellups dictionary
    """
        if 'sorder' not in self.spellups:
            self.spellups['sorder'] = []
        if 'self' not in self.spellups:
            self.spellups['self'] = {}
        if 'oorder' not in self.spellups:
            self.spellups['oorder'] = []
        if 'other' not in self.spellups:
            self.spellups['other'] = {}

    def enabledchange(self, args):
        """
    do something when enabled is changed
    """
        if args['newvalue']:
            self.nextspell()

    def _affon(self, args):
        """
    catch an affon event
    """
        if args['sn'] == self.api('setting.gets')('waiting'):
            self.api('setting.change')('waiting', -1)
        self.nextspell()

    def _affoff(self, _=None):
        """
    catch an affoff event
    """
        self.nextspell()

    def _recoff(self, _=None):
        """
    catch a recoff event
    """
        self.nextspell()

    def _skillfail(self, args):  # pylint: disable=too-many-branches
        """
    catch a skill fail event
    """
        self.api('send.msg')('skillfail: %s' % args)
        spellnum = args['sn']
        skill = self.api('skills.gets')(spellnum)
        waiting = self.api('setting.gets')('waiting')
        if args['reason'] == 'nomana':
            self.api('setting.change')('waiting', -1)
            self.api('setting.change')('nomana', True)
            self.lastmana = self.api('GMCP.getv')('char.vitals.mana')
        elif args['reason'] == 'nocastroom':
            self.api('setting.change')('waiting', -1)
            self.api('setting.change')('nocast', True)
            nocastrooms = self.api('setting.gets')('nocastrooms')
            currentroom = self.api('setting.gets')('currentroom')
            nocastrooms[currentroom] = True
        elif args['reason'] == 'fighting' or args['reason'] == 'notactive':
            self.api('setting.change')('waiting', -1)
        elif args['reason'] == 'nomoves':
            self.api('setting.change')('waiting', -1)
            self.api('setting.change')('nomoves', True)
            self.lastmana = self.api('GMCP.getv')('char.vitals.moves')
        elif waiting == spellnum:
            if args['reason'] == 'lostconc':
                self.api('skills.sendcmd')(waiting)
            elif args['reason'] == 'alreadyaff':
                self.api('setting.change')('waiting', -1)
                self.api('send.client')(
                    "@BSpellup - disabled %s because you are already affected" % \
                                          skill['name'])
                if spellnum in self.spellups['self']:
                    self.spellups['self'][spellnum]['enabled'] = False
                #if spellnum in self.spellups['other']:
                #self.spellups['other'][spellnum]['enabled'] = False
                self.nextspell()
            elif args['reason'] == 'recblock':
                # do stuff when blocked by a recovery
                self.api('setting.change')('waiting', -1)
                self.nextspell()
            elif args['reason'] == 'dontknow':
                # do stuff when spell/skill isn't learned
                # don't disable it, hopefully the spell/skill has been updated and
                # won't be cast through nextspell
                self.api('setting.change')('waiting', -1)
                self.nextspell()
            elif args['reason'] == 'wrongtarget':
                # do stuff when a wrong target
                self.api('setting.change')('waiting', -1)
                self.nextspell()
            elif args['reason'] == 'disabled':
                self.api('setting.change')('waiting', -1)
                skill = self.api('skills.gets')(spellnum)
                self.api('send.client')(
                    "@BSpellup - disabled %s because it is disabled mudside" % \
                                          skill['name'])
                if spellnum in self.spellups['self']:
                    self.spellups['self'][spellnum]['enabled'] = False
                if spellnum in self.spellups['other']:
                    self.spellups['other'][spellnum]['enabled'] = False
                self.nextspell()

    def _moved(self, args):
        """
    reset stuff if we move
    """
        self.api('setting.change')('currentroom', args['to']['num'])
        nocastrooms = self.api('setting.gets')('nocastrooms')
        if args['to']['num'] in nocastrooms:
            self.api('setting.change')('nocast', True)
        else:
            lastval = self.api('setting.gets')('nocast')
            self.api('setting.change')('nocast', False)
            if lastval:
                self.nextspell()

    def _charvitals(self, _=None):
        """
    check if we have more mana and moves
    """
        if self.api('setting.gets')('nomana'):
            newmana = self.api('GMCP.getv')('char.vitals.mana')
            if newmana > self.lastmana:
                self.lastmana = -1
                self.api('setting.change')('nomana', False)
                self.nextspell()
        if self.api('setting.gets')('nomoves'):
            newmoves = self.api('GMCP.getv')('char.vitals.moves')
            if newmoves > self.lastmoves:
                self.lastmoves = -1
                self.api('setting.change')('nomoves', False)
                self.nextspell()

    def _charstatus(self, _=None):
        """
    check if we have more mana and moves
    """
        status = self.api('GMCP.getv')('char.status.state')
        if status == 3 and self.api('skills.isuptodate')():
            self.nextspell()

    @timeit
    def check(self, _=None):
        """
    check to cast the next spell
    """
        mud = self.api('managers.getm')('mud')
        if not mud or not mud.connected:
            return False
        self.api('send.msg')('waiting type: %s' % \
                          type(self.api('setting.gets')('waiting')))
        self.api('send.msg')('currentstatus = %s' % \
                          self.api('GMCP.getv')('char.status.state'))

        # pylint: disable=too-many-boolean-expressions
        if self.api('setting.gets')('nomoves') \
            or self.api('setting.gets')('nomana') \
            or self.api('setting.gets')('nocast') \
            or self.api('setting.gets')('waiting') != -1 \
            or not self.api('setting.gets')('enabled') \
            or not self.api('skills.isuptodate')() or \
            self.api('GMCP.getv')('char.status.state') != 3:
            self.api('send.msg')('checked returned False')
            return False

        self.api('send.msg')('checked returned True')
        return True

    @timeit
    def nextspell(self, _=None):
        """
    try to cast the next spell
    """
        self.api('send.msg')('nextspell')
        if self.check():
            for i in self.spellups['sorder']:
                if self.spellups['self'][i]['enabled']:
                    if self.api('skills.canuse')(i):
                        self.api('setting.change')('waiting', int(i))
                        self.api('skills.sendcmd')(i)
                        return

    def _savestate(self, _=None):
        """
    save states
    """
        self.spellups.sync()

    def _addselfspell(self, spellnum, place=-1, override=False):
        """
    add a spell internally
    """
        msg = []
        spell = self.api('skills.gets')(spellnum)

        if not spell:
            msg.append('%-20s: does not exist' % spellnum)
            return msg

        if not override and not self.api('skills.isspellup')(spell['sn']):
            msg.append('%-20s: not a spellup' % spell['name'])
            return msg

        if spell['sn'] in self.spellups['sorder']:
            msg.append('%-30s: already activated' % spell['name'])
            return msg

        self.spellups['self'][spell['sn']] = {'enabled': True}
        if place > -1:
            self.spellups['sorder'].insert(place, spell['sn'])
        else:
            self.spellups['sorder'].append(spell['sn'])
        msg.append('%-20s:  place %s' % \
            (spell['name'],
             self.spellups['sorder'].index(spell['sn'])))

        return msg

    def cmd_sadd(self, args):
        """
    add a spellup
    """
        msg = []
        if len(args['spell']) < 1:
            return False, ['Please supply a spell']

        if args['spell'][0] == 'all':
            spellups = self.api('skills.getspellups')()
            for spell in spellups:
                if spell['percent'] > 1:
                    tmsg = self._addselfspell(spell['sn'])
                    msg.extend(tmsg)

            self.nextspell()

        else:
            for aspell in args['spell']:
                tspell = aspell
                place = -1
                if ':' in aspell:
                    tlist = aspell.split(':')
                    tspell = tlist[0]
                    place = int(tlist[1])

                tmsg = self._addselfspell(tspell, place, args['override'])
                msg.extend(tmsg)

                self.nextspell()

        self.spellups.sync()
        return True, msg

    def cmd_slist(self, args):
        """
    list the spellups
    """
        msg = []
        match = args['match']
        if self.spellups['sorder']:
            msg.append('%-3s - %-30s : %2s %2s %2s %2s  %-2s  %-2s' % \
                          ('Num', 'Name', 'A', 'P', 'B', 'D', 'NP', 'NL'))
            msg.append('@B' + '-' * 60)
            for i in self.spellups['sorder']:
                skill = self.api('skills.gets')(i)
                if not skill:
                    msg.append('%-3s: please check the skills plugin' % \
                                   (self.spellups['sorder'].index(i)))
                elif not match or match in skill['name']:
                    msg.append('%-3s - %-30s : %2s %2s %2s %2s  %-2s  %-2s' % \
                                (self.spellups['sorder'].index(i),
                                 skill['name'],
                                 'A' if self.api('skills.isaffected')(i) else '',
                                 'P' if self.api('setting.gets')('waiting') == i else '',
                                 'B' if self.api('skills.isblockedbyrecovery')(i) else '',
                                 'D' if not self.spellups['self'][i]['enabled'] else '',
                                 'NP' if skill['percent'] == 1 else '',
                                 'NL' if skill['percent'] == 0 else '',))
        else:
            msg.append('There are no spellups')
        return True, msg

    def cmd_srem(self, args):
        """
    remove a spellup
    """
        if len(args['spell']) < 1:
            return True, ['Please supply a spell/skill to remove']

        msg = []
        if args['spell'][0].lower() == 'all':
            del self.spellups['sorder']
            del self.spellups['self']
            self.initspellups()
            msg.append('All spellups to be cast on self cleared')

        else:
            for spella in args['spell']:
                spell = self.api('skills.gets')(spella)

                if not spell:
                    msg.append('%s does not exist' % spella)
                    continue

                spellnum = spell['sn']
                if spellnum in self.spellups['sorder']:
                    self.spellups['sorder'].remove(spellnum)
                if spellnum in self.spellups['self']:
                    del self.spellups['self'][spellnum]

                msg.append('Removed %s from spellups to self' % spell['name'])

            self.savestate()
            return True, msg

    def cmd_en(self, args):
        """
    enable a spellup
    """
        if len(args['spell']) < 1:
            return True, ['Please supply a spell/skill to enable']

        msg = []

        if args['spell'][0].lower() == 'all':
            for i in self.spellups['self']:
                self.spellups['self'][i]['enabled'] = True

            msg.append('All spellups enabled')
            self.nextspell()
            return True, msg

        for spellnum in args['spell']:
            skill = self.api('skills.gets')(spellnum)
            if skill:
                if skill['sn'] in self.spellups['sorder']:
                    self.spellups['self'][skill['sn']]['enabled'] = True
                    msg.append('%s: enabled' % skill['name'])
                else:
                    msg.append('%s: not in self spellup list' % skill['name'])
            else:
                msg.append('%s: could not find spell' % spellnum)
        self.nextspell()
        return True, msg

    def cmd_dis(self, args):
        """
    enable a spellup
    """
        if len(args['spell']) < 1:
            return True, ['Please supply a spell/skill to enable']

        msg = []
        if args['spell'][0].lower() == 'all':
            for i in self.spellups['self']:
                self.spellups['self'][i]['enabled'] = False

            msg.append('All spellups disabled')
            return True, msg

        for spellnum in args['spell']:
            skill = self.api('skills.gets')(spellnum)
            if skill:
                if skill['sn'] in self.spellups['sorder']:
                    self.spellups['self'][skill['sn']]['enabled'] = False
                    msg.append('%s: disabled' % skill['name'])
                else:
                    msg.append('%s: not in self spellup list' % skill['name'])
            else:
                msg.append('%s: could not find spell' % spellnum)
        return True, msg

    def cmd_check(self, _=None):
        """
    list all items that are need for spellups and whether they are known
    """
        tmsg = []
        tformat = '%-25s : %-10s - %s'
        tmsg.append(tformat % \
                     ('enabled',
                      self.api('setting.gets')('enabled'),
                      'should be True to cast spells'))
        tmsg.append(tformat % \
                     ('waiting',
                      self.api('setting.gets')('waiting'),
                      'the spell that was last cast, should be -1 to cast spells'))
        tmsg.append(tformat % \
                     ('nocast',
                      self.api('setting.gets')('nocast'),
                      'the current room is nocast, should be False to cast spells'))
        tmsg.append(tformat % \
                     ('nomoves',
                      self.api('setting.gets')('nomoves'),
                      'ran out of moves, should be False to cast spells'))
        tmsg.append(tformat % \
                     ('nomana',
                      self.api('setting.gets')('nomana'),
                      'ran out of mana, should be False to cast spells'))
        tmsg.append(tformat % \
                     ('Skills are up to date',
                      self.api('skills.isuptodate')(),
                      'should be True to cast spells'))
        tmsg.append(tformat % \
                     ('Char state',
                      self.api('GMCP.getv')('char.status.state'),
                      'should be 3 to cast spells'))
        return True, tmsg

    def reset(self):
        """
    reset all spellups
    """
        AardwolfBasePlugin.reset(self)
        self.spellups.clear()
        self.initspellups()
        self.spellups.sync()
Example #9
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin to handle aardwolf quest events
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.savequestfile = os.path.join(self.savedir, 'quest.txt')
        self.queststuff = PersistentDict(self.savequestfile, 'c')

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)

        self.api('events.register')('GMCP:comm.quest', self.quest)

        self.api('events.register')('plugin_%s_savestate' % self.sname,
                                    self._savestate)

    def resetquest(self):
        """
    reset the quest info
    """
        self.queststuff.clear()
        self.queststuff['finishtime'] = -1
        self.queststuff['starttime'] = time.time()
        self.queststuff['killedtime'] = -1
        self.queststuff['mobname'] = ''
        self.queststuff['mobarea'] = ''
        self.queststuff['mobroom'] = ''
        self.queststuff['level'] = self.api('aardu.getactuallevel')(
            self.api('GMCP.getv')('char.status.level'))
        self.queststuff['failed'] = 0

    def quest(self, args):
        """
    process the quest event
    """
        questi = args['data']
        self.api('send.msg')('quest: %s' % questi)
        if questi['action'] == 'ready':
            self.api('events.eraise')('aard_quest_ready', {})
        elif questi['action'] == 'start':
            self.resetquest()
            self.queststuff['mobname'] = questi['targ']
            self.queststuff['mobarea'] = questi['area']
            self.queststuff['mobroom'] = questi['room']
            self.queststuff['stimer'] = questi['timer']
            self.api('events.eraise')('aard_quest_start', self.queststuff)
        elif questi['action'] == 'killed':
            self.queststuff['killedtime'] = time.time()
            self.api('events.eraise')('aard_quest_killed', self.queststuff)
        elif questi['action'] == 'comp':
            self.queststuff['finishtime'] = time.time()
            self.queststuff.update(questi)
            self.api('events.eraise')('aard_quest_comp',
                                      copy.deepcopy(self.queststuff))
        elif questi['action'] == 'fail' or questi['action'] == 'timeout':
            self.queststuff['finishtime'] = time.time()
            self.queststuff['failed'] = 1
            self.api('events.eraise')('aard_quest_failed',
                                      copy.deepcopy(self.queststuff))
        elif questi['action'] == 'status':
            self.api('events.eraise')('aard_quest_status', questi)
        elif questi['action'] == 'reset':
            #reset the timer to 60 seconds
            #when_required = os.time() + (stuff.timer * 60)
            #update_timer()
            self.api('events.eraise')('aard_quest_reset', {})
        self.queststuff.sync()

    def _savestate(self, _=None):
        """
    save states
    """
        self.queststuff.sync()
Example #10
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin that does spellups
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.spellupfile = os.path.join(self.savedir, 'spellups.txt')
    self.spellups = PersistentDict(self.spellupfile, 'c')

    self.api('dependency.add')('aardwolf.skills')
    self.api('dependency.add')('aardwolf.move')

    self.initspellups()

    self.lastmana = -1
    self.lastmoves = -1

  def load(self):
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)

    self.api('setting.add')('enabled', True, bool,
                            'auto spellup is enabled')
    self.api('setting.add')('waiting', -1, int,
                            'the spell that was just cast',
                            readonly=True)
    self.api('setting.add')('nocast', False, bool,
                            'in a nocast room',
                            readonly=True)
    self.api('setting.add')('nomoves', False, bool,
                            'need more moves',
                            readonly=True)
    self.api('setting.add')('nomana', False, bool,
                            'need more mana',
                            readonly=True)
    self.api('setting.add')('nocastrooms', {}, dict,
                            'list of nocast rooms',
                            readonly=True)
    self.api('setting.add')('currentroom', -1, int,
                            'the current room',
                            readonly=True)

    parser = argp.ArgumentParser(add_help=False,
                                 description='add a spellup to the self list')
    parser.add_argument(
        'spell',
        help='the spells to add, use \'all\' to add all practiced spellups',
        default=[], nargs='*')
    parser.add_argument(
        '-o', "--override",
        help="add even if the spell is not flagged as a spellup by the mud",
        action="store_true")
    self.api('commands.add')('add', self.cmd_sadd,
                             parser=parser, group='Spellups on Self')

    parser = argp.ArgumentParser(add_help=False,
                                 description='list spellups for self')
    parser.add_argument(
        'match',
        help='list only spellups that have this argument in them',
        default='', nargs='?')
    self.api('commands.add')('list', self.cmd_slist,
                             parser=parser, group='Spellups on Self')

    parser = argp.ArgumentParser(add_help=False,
                                 description='remove a spellup from the self list')
    parser.add_argument(
        'spell',
        help='the spells to remove, use \'all\' to remove all spellups',
        default=[], nargs='*')
    self.api('commands.add')('rem', self.cmd_srem,
                             parser=parser, group='Spellups on Self')

    parser = argp.ArgumentParser(add_help=False,
                                 description='enable spellups on self')
    parser.add_argument(
        'spell',
        help='the spells to enable, use \'all\' to enable all spellups',
        default=[], nargs='*')
    self.api('commands.add')('en', self.cmd_en,
                             parser=parser, group='Spellups on Self')

    parser = argp.ArgumentParser(add_help=False,
                                 description='disable spells on self')
    parser.add_argument(
        'spell',
        help='the spells to disable, use \'all\' to disable all spellups',
        default=[], nargs='*')
    self.api('commands.add')('dis', self.cmd_dis,
                             shelp='disable a spellup on self',
                             parser=parser, group='Spellups on Self')

    self.api('commands.add')('check', self.cmd_check,
                             shelp='check data status for casting',
                             group='Spellups on Self')

    self.api('events.register')('GMCP:char.vitals', self._charvitals)
    self.api('events.register')('GMCP:char.status', self._charstatus)
    self.api('events.register')('moved_room', self._moved)
    self.api('events.register')('skill_fail', self._skillfail)
    self.api('events.register')('aard_skill_affon', self._affon)
    self.api('events.register')('aard_skill_affoff', self._affoff)
    self.api('events.register')('aard_skill_recoff', self._recoff)
    self.api('events.register')('aard_skill_gain', self.skillgain)
    self.api('events.register')('var_su_enabled', self.enabledchange)
    self.api('events.register')('skills_affected_update', self.nextspell)
    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)
    self.api('events.register')('skills_uptodate', self.nextspell)

  def skillgain(self, args=None):
    """
    check skills when we gain them
    """
    if args['sn'] in self.spellups['sorder'] and args['percent'] > 50:
      self.nextspell()

  def initspellups(self):
    """
    initialize the spellups dictionary
    """
    if 'sorder' not in self.spellups:
      self.spellups['sorder'] = []
    if 'self' not in self.spellups:
      self.spellups['self'] = {}
    if 'oorder' not in self.spellups:
      self.spellups['oorder'] = []
    if 'other' not in self.spellups:
      self.spellups['other'] = {}

  def enabledchange(self, args):
    """
    do something when enabled is changed
    """
    if args['newvalue']:
      self.nextspell()

  def _affon(self, args):
    """
    catch an affon event
    """
    if args['sn'] == self.api('setting.gets')('waiting'):
      self.api('setting.change')('waiting', -1)
    self.nextspell()

  def _affoff(self, _=None):
    """
    catch an affoff event
    """
    self.nextspell()

  def _recoff(self, _=None):
    """
    catch a recoff event
    """
    self.nextspell()

  def _skillfail(self, args): # pylint: disable=too-many-branches
    """
    catch a skill fail event
    """
    self.api('send.msg')('skillfail: %s' % args)
    spellnum = args['sn']
    skill = self.api('skills.gets')(spellnum)
    waiting = self.api('setting.gets')('waiting')
    if args['reason'] == 'nomana':
      self.api('setting.change')('waiting', -1)
      self.api('setting.change')('nomana', True)
      self.lastmana = self.api('GMCP.getv')('char.vitals.mana')
    elif args['reason'] == 'nocastroom':
      self.api('setting.change')('waiting', -1)
      self.api('setting.change')('nocast', True)
      nocastrooms = self.api('setting.gets')('nocastrooms')
      currentroom = self.api('setting.gets')('currentroom')
      nocastrooms[currentroom] = True
    elif args['reason'] == 'fighting' or args['reason'] == 'notactive':
      self.api('setting.change')('waiting', -1)
    elif args['reason'] == 'nomoves':
      self.api('setting.change')('waiting', -1)
      self.api('setting.change')('nomoves', True)
      self.lastmana = self.api('GMCP.getv')('char.vitals.moves')
    elif waiting == spellnum:
      if args['reason'] == 'lostconc':
        self.api('skills.sendcmd')(waiting)
      elif args['reason'] == 'alreadyaff':
        self.api('setting.change')('waiting', -1)
        self.api('send.client')(
            "@BSpellup - disabled %s because you are already affected" % \
                                  skill['name'])
        if spellnum in self.spellups['self']:
          self.spellups['self'][spellnum]['enabled'] = False
        #if spellnum in self.spellups['other']:
          #self.spellups['other'][spellnum]['enabled'] = False
        self.nextspell()
      elif args['reason'] == 'recblock':
        # do stuff when blocked by a recovery
        self.api('setting.change')('waiting', -1)
        self.nextspell()
      elif args['reason'] == 'dontknow':
        # do stuff when spell/skill isn't learned
        # don't disable it, hopefully the spell/skill has been updated and
        # won't be cast through nextspell
        self.api('setting.change')('waiting', -1)
        self.nextspell()
      elif args['reason'] == 'wrongtarget':
        # do stuff when a wrong target
        self.api('setting.change')('waiting', -1)
        self.nextspell()
      elif args['reason'] == 'disabled':
        self.api('setting.change')('waiting', -1)
        skill = self.api('skills.gets')(spellnum)
        self.api('send.client')(
            "@BSpellup - disabled %s because it is disabled mudside" % \
                                  skill['name'])
        if spellnum in self.spellups['self']:
          self.spellups['self'][spellnum]['enabled'] = False
        if spellnum in self.spellups['other']:
          self.spellups['other'][spellnum]['enabled'] = False
        self.nextspell()

  def _moved(self, args):
    """
    reset stuff if we move
    """
    self.api('setting.change')('currentroom', args['to']['num'])
    nocastrooms = self.api('setting.gets')('nocastrooms')
    if args['to']['num'] in nocastrooms:
      self.api('setting.change')('nocast', True)
    else:
      lastval = self.api('setting.gets')('nocast')
      self.api('setting.change')('nocast', False)
      if lastval:
        self.nextspell()

  def _charvitals(self, _=None):
    """
    check if we have more mana and moves
    """
    if self.api('setting.gets')('nomana'):
      newmana = self.api('GMCP.getv')('char.vitals.mana')
      if newmana > self.lastmana:
        self.lastmana = -1
        self.api('setting.change')('nomana', False)
        self.nextspell()
    if self.api('setting.gets')('nomoves'):
      newmoves = self.api('GMCP.getv')('char.vitals.moves')
      if newmoves > self.lastmoves:
        self.lastmoves = -1
        self.api('setting.change')('nomoves', False)
        self.nextspell()

  def _charstatus(self, _=None):
    """
    check if we have more mana and moves
    """
    status = self.api('GMCP.getv')('char.status.state')
    if status == 3 and self.api('skills.isuptodate')():
      self.nextspell()

  @timeit
  def check(self, _=None):
    """
    check to cast the next spell
    """
    mud = self.api('managers.getm')('mud')
    if not mud or not mud.connected:
      return False
    self.api('send.msg')('waiting type: %s' % \
                      type(self.api('setting.gets')('waiting')))
    self.api('send.msg')('currentstatus = %s' % \
                      self.api('GMCP.getv')('char.status.state'))

    # pylint: disable=too-many-boolean-expressions
    if self.api('setting.gets')('nomoves') \
        or self.api('setting.gets')('nomana') \
        or self.api('setting.gets')('nocast') \
        or self.api('setting.gets')('waiting') != -1 \
        or not self.api('setting.gets')('enabled') \
        or not self.api('skills.isuptodate')() or \
        self.api('GMCP.getv')('char.status.state') != 3:
      self.api('send.msg')('checked returned False')
      return False

    self.api('send.msg')('checked returned True')
    return True

  @timeit
  def nextspell(self, _=None):
    """
    try to cast the next spell
    """
    self.api('send.msg')('nextspell')
    if self.check():
      for i in self.spellups['sorder']:
        if self.spellups['self'][i]['enabled']:
          if self.api('skills.canuse')(i):
            self.api('setting.change')('waiting', int(i))
            self.api('skills.sendcmd')(i)
            return

  def _savestate(self, _=None):
    """
    save states
    """
    self.spellups.sync()

  def _addselfspell(self, spellnum, place=-1, override=False):
    """
    add a spell internally
    """
    msg = []
    spell = self.api('skills.gets')(spellnum)

    if not spell:
      msg.append('%-20s: does not exist' % spellnum)
      return msg

    if not override and not self.api('skills.isspellup')(spell['sn']):
      msg.append('%-20s: not a spellup' % spell['name'])
      return msg

    if spell['sn'] in self.spellups['sorder']:
      msg.append('%-30s: already activated' % spell['name'])
      return msg

    self.spellups['self'][spell['sn']] = {'enabled':True}
    if place > -1:
      self.spellups['sorder'].insert(place, spell['sn'])
    else:
      self.spellups['sorder'].append(spell['sn'])
    msg.append('%-20s:  place %s' % \
        (spell['name'],
         self.spellups['sorder'].index(spell['sn'])))

    return msg

  def cmd_sadd(self, args):
    """
    add a spellup
    """
    msg = []
    if len(args['spell']) < 1:
      return False, ['Please supply a spell']

    if args['spell'][0] == 'all':
      spellups = self.api('skills.getspellups')()
      for spell in spellups:
        if spell['percent'] > 1:
          tmsg = self._addselfspell(spell['sn'])
          msg.extend(tmsg)

      self.nextspell()

    else:
      for aspell in args['spell']:
        tspell = aspell
        place = -1
        if ':' in aspell:
          tlist = aspell.split(':')
          tspell = tlist[0]
          place = int(tlist[1])

        tmsg = self._addselfspell(tspell, place, args['override'])
        msg.extend(tmsg)

        self.nextspell()

    self.spellups.sync()
    return True, msg

  def cmd_slist(self, args):
    """
    list the spellups
    """
    msg = []
    match = args['match']
    if self.spellups['sorder']:
      msg.append('%-3s - %-30s : %2s %2s %2s %2s  %-2s  %-2s' % \
                    ('Num', 'Name', 'A', 'P', 'B', 'D', 'NP', 'NL'))
      msg.append('@B' + '-'* 60)
      for i in self.spellups['sorder']:
        skill = self.api('skills.gets')(i)
        if not skill:
          msg.append('%-3s: please check the skills plugin' % \
                         (self.spellups['sorder'].index(i)))
        elif not match or match in skill['name']:
          msg.append('%-3s - %-30s : %2s %2s %2s %2s  %-2s  %-2s' % \
                      (self.spellups['sorder'].index(i),
                       skill['name'],
                       'A' if self.api('skills.isaffected')(i) else '',
                       'P' if self.api('setting.gets')('waiting') == i else '',
                       'B' if self.api('skills.isblockedbyrecovery')(i) else '',
                       'D' if not self.spellups['self'][i]['enabled'] else '',
                       'NP' if skill['percent'] == 1 else '',
                       'NL' if skill['percent'] == 0 else '',))
    else:
      msg.append('There are no spellups')
    return True, msg

  def cmd_srem(self, args):
    """
    remove a spellup
    """
    if len(args['spell']) < 1:
      return True, ['Please supply a spell/skill to remove']

    msg = []
    if args['spell'][0].lower() == 'all':
      del self.spellups['sorder']
      del self.spellups['self']
      self.initspellups()
      msg.append('All spellups to be cast on self cleared')

    else:
      for spella in args['spell']:
        spell = self.api('skills.gets')(spella)

        if not spell:
          msg.append('%s does not exist' % spella)
          continue

        spellnum = spell['sn']
        if spellnum in self.spellups['sorder']:
          self.spellups['sorder'].remove(spellnum)
        if spellnum in self.spellups['self']:
          del self.spellups['self'][spellnum]

        msg.append('Removed %s from spellups to self' % spell['name'])

      self.savestate()
      return True, msg

  def cmd_en(self, args):
    """
    enable a spellup
    """
    if len(args['spell']) < 1:
      return True, ['Please supply a spell/skill to enable']

    msg = []

    if args['spell'][0].lower() == 'all':
      for i in self.spellups['self']:
        self.spellups['self'][i]['enabled'] = True

      msg.append('All spellups enabled')
      self.nextspell()
      return True, msg

    for spellnum in args['spell']:
      skill = self.api('skills.gets')(spellnum)
      if skill:
        if skill['sn'] in self.spellups['sorder']:
          self.spellups['self'][skill['sn']]['enabled'] = True
          msg.append('%s: enabled' % skill['name'])
        else:
          msg.append('%s: not in self spellup list' % skill['name'])
      else:
        msg.append('%s: could not find spell' % spellnum)
    self.nextspell()
    return True, msg

  def cmd_dis(self, args):
    """
    enable a spellup
    """
    if len(args['spell']) < 1:
      return True, ['Please supply a spell/skill to enable']

    msg = []
    if args['spell'][0].lower() == 'all':
      for i in self.spellups['self']:
        self.spellups['self'][i]['enabled'] = False

      msg.append('All spellups disabled')
      return True, msg

    for spellnum in args['spell']:
      skill = self.api('skills.gets')(spellnum)
      if skill:
        if skill['sn'] in self.spellups['sorder']:
          self.spellups['self'][skill['sn']]['enabled'] = False
          msg.append('%s: disabled' % skill['name'])
        else:
          msg.append('%s: not in self spellup list' % skill['name'])
      else:
        msg.append('%s: could not find spell' % spellnum)
    return True, msg

  def cmd_check(self, _=None):
    """
    list all items that are need for spellups and whether they are known
    """
    tmsg = []
    tformat = '%-25s : %-10s - %s'
    tmsg.append(tformat % \
                 ('enabled',
                  self.api('setting.gets')('enabled'),
                  'should be True to cast spells'))
    tmsg.append(tformat % \
                 ('waiting',
                  self.api('setting.gets')('waiting'),
                  'the spell that was last cast, should be -1 to cast spells'))
    tmsg.append(tformat % \
                 ('nocast',
                  self.api('setting.gets')('nocast'),
                  'the current room is nocast, should be False to cast spells'))
    tmsg.append(tformat % \
                 ('nomoves',
                  self.api('setting.gets')('nomoves'),
                  'ran out of moves, should be False to cast spells'))
    tmsg.append(tformat % \
                 ('nomana',
                  self.api('setting.gets')('nomana'),
                  'ran out of mana, should be False to cast spells'))
    tmsg.append(tformat % \
                 ('Skills are up to date',
                  self.api('skills.isuptodate')(),
                  'should be True to cast spells'))
    tmsg.append(tformat % \
                 ('Char state',
                  self.api('GMCP.getv')('char.status.state'),
                  'should be 3 to cast spells'))
    return True, tmsg

  def reset(self):
    """
    reset all spellups
    """
    AardwolfBasePlugin.reset(self)
    self.spellups.clear()
    self.initspellups()
    self.spellups.sync()
Example #11
0
class Plugin(BasePlugin):
  """
  a plugin to handle user aliases
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    BasePlugin.__init__(self, *args, **kwargs)

    self.aliasfile = os.path.join(self.savedir, 'aliases.txt')
    self._aliases = PersistentDict(self.aliasfile, 'c')

    self.sessionhits = {}

  def load(self):
    """
    load the plugin
    """
    BasePlugin.load(self)

    self.api.get('setting.add')('nextnum', 0, int,
                                'the number of the next alias added',
                                readonly=True)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='add an alias')
    parser.add_argument('original',
                        help='the input to replace',
                        default='',
                        nargs='?')
    parser.add_argument('replacement',
                        help='the string to replace it with',
                        default='',
                        nargs='?')
    parser.add_argument('-o',
                        "--overwrite",
                        help="overwrite an alias if it already exists",
                        action="store_true")
    parser.add_argument('-d', "--disable",
                        help="disable the alias",
                        action="store_true")
    parser.add_argument('-g',
                        "--group",
                        help="the alias group",
                        default="")
    self.api.get('commands.add')('add',
                                 self.cmd_add,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='remove an alias')
    parser.add_argument('alias',
                        help='the alias to remove',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('remove',
                                 self.cmd_remove,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='list aliases')
    parser.add_argument('match',
                        help='list only aliases that have this argument in them',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('list',
                                 self.cmd_list,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='toggle enabled flag')
    parser.add_argument('alias',
                        help='the alias to toggle',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('toggle',
                                 self.cmd_toggle,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='toggle all aliases in a group')
    parser.add_argument('group',
                        help='the group to toggle',
                        default='',
                        nargs='?')
    parser.add_argument('-d',
                        "--disable",
                        help="disable the group",
                        action="store_true")
    self.api.get('commands.add')('groupt',
                                 self.cmd_grouptoggle,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='get detail for an alias')
    parser.add_argument('alias',
                        help='the alias to get details for',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('detail',
                                 self.cmd_detail,
                                 parser=parser)

    self.api.get('commands.default')('list')
    self.api.get('events.register')('from_client_event', self.checkalias,
                                    prio=2)

  def checkalias(self, args):
    """
    this function finds aliases in client input
    """
    data = args['fromdata'].strip()

    if not data:
      return args

    for mem in self._aliases.keys():
      if self._aliases[mem]['enabled']:
        datan = data
        matchd = re.match(mem, data)
        if matchd:
          self.api.get('send.msg')('matched input on %s' % mem)
          tlistn = [data]
          for i in xrange(1, len(matchd.groups()) + 1):
            tlistn.append(matchd.group(i))
          self.api.get('send.msg')('args: %s' % tlistn)
          try:
            datan = self._aliases[mem]['alias'].format(*tlistn)
          except Exception: # pylint: disable=broad-except
            self.api.get('send.traceback')('alias %s had an issue' % (mem))
        else:
          cre = re.compile('^%s' % mem)
          datan = cre.sub(self._aliases[mem]['alias'], data)
        if datan != data:
          if not 'hits' in self._aliases[mem]:
            self._aliases[mem]['hits'] = 0
          if not mem in self.sessionhits:
            self.sessionhits[mem] = 0
          self.api.get('send.msg')('incrementing hits for %s' % mem)
          self._aliases[mem]['hits'] = self._aliases[mem]['hits'] + 1
          self.sessionhits[mem] = self.sessionhits[mem] + 1
          self.api.get('send.msg')('replacing "%s" with "%s"' % \
                                          (data.strip(), datan.strip()))
          if datan[0:3] == '#bp':
            self.api.get('send.execute')(datan, history=False, fromclient=False)
            args['fromdata'] = ''
            args['history'] = False
          else:
            args['history'] = False
            args['fromclient'] = False
            args['fromdata'] = datan

    return args

  def lookup_alias(self, alias):
    """
    lookup an alias by number or name
    """
    nitem = None
    try:
      num = int(alias)
      nitem = None
      for titem in self._aliases.keys():
        if num == self._aliases[titem]['num']:
          nitem = titem
          break

    except ValueError:
      if alias in self._aliases:
        nitem = alias

    return nitem

  def cmd_add(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a alias
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
    tmsg = []
    if args['original'] and args['replacement']:
      if args['original'] in self._aliases and not args['overwrite']:
        return True, ['Alias: %s already exists.' % args['original']]
      else:
        tmsg.append("@GAdding alias@w : '%s' will be replaced by '%s'" % \
                                      (args['original'], args['replacement']))
        self.addalias(args['original'], args['replacement'],
                      args['disable'], args['group'])
      return True, tmsg
    else:
      return False, ['@RPlease include all arguments@w']

  def cmd_remove(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      Remove a alias
      @CUsage@w: rem @Y<originalstring>@w
        @Yoriginalstring@w    = The original string
    """
    tmsg = []
    if args['alias']:
      retval = self.removealias(args['alias'])
      if retval:
        tmsg.append("@GRemoving alias@w : '%s'" % (retval))
      else:
        tmsg.append("@GCould not remove alias@w : '%s'" % (args['alias']))

      return True, tmsg
    else:
      return False, ['@RPlease include an alias to remove@w']

  def cmd_toggle(self, args):
    """
    toggle the enabled flag
    """
    tmsg = []
    if args['alias']:
      retval = self.togglealias(args['alias'])
      if retval:
        if self._aliases[retval]['enabled']:
          tmsg.append("@GEnabled alias@w : '%s'" % (retval))
        else:
          tmsg.append("@GDisabled alias@w : '%s'" % (retval))
      else:
        tmsg.append("@GDoes not exist@w : '%s'" % (args['alias']))
      return True, tmsg

    else:
      return False, ['@RPlease include an alias to toggle@w']

  def cmd_detail(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a alias
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
    tmsg = []
    if args['alias']:
      alias = self.lookup_alias(args['alias'])
      if alias:
        if 'hits' not in self._aliases[alias]:
          self._aliases[alias]['hits'] = 0
        if alias not in self.sessionhits:
          self.sessionhits[alias] = 0
        tmsg.append('%-12s : %d' % ('Num', self._aliases[alias]['num']))
        tmsg.append('%-12s : %s' % \
            ('Enabled', 'Y' if self._aliases[alias]['enabled'] else 'N'))
        tmsg.append('%-12s : %d' % ('Total Hits',
                                    self._aliases[alias]['hits']))
        tmsg.append('%-12s : %d' % ('Session Hits', self.sessionhits[alias]))
        tmsg.append('%-12s : %s' % ('Alias', alias))
        tmsg.append('%-12s : %s' % ('Replacement',
                                    self._aliases[alias]['alias']))
        tmsg.append('%-12s : %s' % ('Group', self._aliases[alias]['group']))
      else:
        return True, ['@RAlias does not exits@w : \'%s\'' % (args['alias'])]

      return True, tmsg
    else:
      return False, ['@RPlease include all arguments@w']

  def cmd_list(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      List aliases
      @CUsage@w: list
    """
    tmsg = self.listaliases(args['match'])
    return True, tmsg

  def cmd_grouptoggle(self, args):
    """
    toggle all aliases in a group
    """
    tmsg = []
    togglea = []
    state = not args['disable']
    if args['group']:
      for i in self._aliases:
        if 'group' not in self._aliases[i]:
          self._aliases[i]['group'] = ''

        if self._aliases[i]['group'] == args['group']:
          self._aliases[i]['enabled'] = state
          togglea.append('%s' % self._aliases[i]['num'])

      if togglea:
        tmsg.append('The following aliases were %s: %s' % \
              ('enabled' if state else 'disabled',
               ','.join(togglea)))
      else:
        tmsg.append('No aliases were modified')

      return True, tmsg
    else:
      return False, ['@RPlease include a group to toggle@w']

  def addalias(self, item, alias, disabled, group):
    """
    internally add a alias
    """
    num = self.api.get('setting.gets')('nextnum')
    self._aliases[item] = {'alias':alias, 'enabled':not disabled,
                           'num':num, 'group':group}
    self._aliases.sync()
    self.api.get('setting.change')('nextnum', num + 1)

  def removealias(self, item):
    """
    internally remove a alias
    """
    alias = self.lookup_alias(item)
    if alias:
      del self._aliases[alias]
      self._aliases.sync()

    return alias

  def togglealias(self, item):
    """
    toggle an alias
    """
    alias = self.lookup_alias(item)
    if alias:
      self._aliases[alias]['enabled'] = not self._aliases[alias]['enabled']

    return alias

  def listaliases(self, match):
    """
    return a table of strings that list aliases
    """
    tmsg = []
    for alias in sorted(self._aliases.iteritems(),
                        key=lambda (x, y): y['num']):
      item = alias[0]
      if not match or match in item:
        lalias = self.api.get('colors.stripansi')(self._aliases[item]['alias'])
        if len(lalias) > 30:
          lalias = lalias[:27] + '...'
        tmsg.append("%4s %2s  %-10s %-20s : %s@w" % \
                     (self._aliases[item]['num'],
                      'Y' if self._aliases[item]['enabled'] else 'N',
                      self._aliases[item]['group'],
                      item,
                      lalias))
    if len(tmsg) == 0:
      tmsg = ['None']
    else:
      tmsg.insert(0, "%4s %2s  %-10s %-20s : %s@w" % ('#', 'E', 'Group',
                                                      'Alias', 'Replacement'))
      tmsg.insert(1, '@B' + '-' * 60 + '@w')

    return tmsg

  def clearaliases(self):
    """
    clear all aliases
    """
    self._aliases.clear()
    self._aliases.sync()

  def reset(self):
    """
    reset the plugin
    """
    BasePlugin.reset(self)
    self.clearaliases()

  def savestate(self):
    """
    save states
    """
    BasePlugin.savestate(self)
    self._aliases.sync()
Example #12
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin to handle aardwolf cp events
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.savewhoisfile = os.path.join(self.savedir, 'whois.txt')
    self.whois = PersistentDict(self.savewhoisfile, 'c')

  def load(self):
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)

    self.api.get('watch.add')('whois', '^(whoi|whois)$')

    self.api.get('triggers.add')('whoisheader',
      "^\[.*\]\s+.*\s*\((?P<sex>\w+)\s+\w+\)$",
      enabled=False,
      group='whois')
    self.api.get('triggers.add')('whoisclasses',
      "^\[Multiclass Player: (?P<classes>.*) \]$",
      enabled=False,
      group='whois')
    self.api.get('triggers.add')('whois1',
      "^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]\s*$",
      enabled=False,
      group='whois')
    self.api.get('triggers.add')('whois2',
      "^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]" \
        "\s*(?P<name2>[\w\s]*)\s*:\s*\[\s*(?P<val2>[\w\d\s]*)\s*\]\s*$",
      enabled=False,
      group='whois')
    self.api.get('triggers.add')('whois3',
      "^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]" \
        "\s*(?P<name2>[\w\s]*)\s*:\s*\[\s*(?P<val2>[\w\d\s]*)\s*\]" \
        "\s*(?P<name3>[\w\s]*)\s*:\s*\[\s*(?P<val3>[\w\d\s]*)\s*\]\s*$",
      enabled=False,
      group='whois')
    self.api.get('triggers.add')('whoispowerup',
      "^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]" \
        "\s*([\w\s]*)\s*:\s*\[\s*(?P<pval1>[\w\d\s]*)\s*\]\s*\[\s*" \
        "(?P<pval2>[\w\d\s]*)\s*\]\s*$",
      enabled=False,
      group='whois')
    self.api.get('triggers.add')('whoisend',
      "^-{74,74}$",
      enabled=False)

    self.api.get('events.register')('watch_whois', self._whois)
    self.api.get('events.register')('trigger_whoisheader', self._whoisheader)
    self.api.get('events.register')('trigger_whoisclasses', self._whoisclasses)
    self.api.get('events.register')('trigger_whois1', self._whoisstats)
    self.api.get('events.register')('trigger_whois2', self._whoisstats)
    self.api.get('events.register')('trigger_whois3', self._whoisstats)
    self.api.get('events.register')('trigger_whoispowerup', self._whoisstats)
    self.api.get('events.register')('trigger_whoisend', self._whoisend)

  def _whois(self, args=None):
    """
    reset the whois info when a "whois" command is sent
    """
    self.whois.clear()
    self.api.get('triggers.togglegroup')('whois', True)
    return args

  def _whoisstats(self, args=None):
    """
    parse a whois line
    """
    for i in range(1, 4):
      akey = 'name%s' % i
      aval = 'val%s' % i

      if akey in args:
        kname = args[akey].lower().strip()
        kname = kname.replace(' ', '')
        kval = args[aval].strip()

        self.whois[kname] = kval

    if 'pval1' in args:
      self.whois['powerupsall'] = args['pval1']
    if 'pval2' in args:
      self.whois['powerupsmort'] = args['pval2']

  def _whoisheader(self, args=None):
    """
    do stuff when we see the whois header
    """
    self.whois["name"] = self.api.get('GMCP.getv')('char.base.name')
    self.whois['level'] = self.api.get('GMCP.getv')('char.status.level')
    self.whois['tiers'] = self.api.get('GMCP.getv')('char.base.tier')
    self.whois['redos'] = int(self.api.get('GMCP.getv')('char.base.redos'))
    self.whois['race'] = self.api.get('GMCP.getv')('char.base.race').lower()
    self.whois['sex'] = args['sex'].lower()
    self.whois['subclass'] = self.api.get('GMCP.getv')(
                                            'char.base.subclass').lower()
    self.whois['powerupsall'] = 0
    self.whois['powerupsmort'] = 0
    self.whois['remorts'] = self.api.get('GMCP.getv')('char.base.remorts')
    if self.whois['remorts'] == 1:
      classabs = self.api.get('aardu.classabb')()
      self.whois['classes'] = []
      self.whois['classes'].append({'remort':1,
              'class':classabs[self.api.get('GMCP.getv')(
                                      'char.base.class').lower()]})

    self.api.get('triggers.toggle')('whoisend', True)

  def _whoisclasses(self, args):
    """
    add classes
    """
    classabs = self.api.get('aardu.classabb')()
    tlist = args['classes'].split("/")
    remorts = len(tlist)
    self.whois['classes'] = []
    for i in range(remorts):
      tclass = tlist[i].strip().lower()
      self.whois['classes'].append({'remort':i + 1,
                'class':classabs[tclass.lower()]})

    self.whois['remorts'] = remorts

  def _whoisend(self, _=None):
    """
    send a whois
    """
    self.whois['totallevels'] = self.api.get('aardu.getactuallevel')(
                      self.whois['level'], self.whois['remorts'],
                      self.whois['tiers'], self.whois['redos'])
    self.whois.sync()
    self.api.get('triggers.togglegroup')('whois', False)
    self.api.get('triggers.toggle')('whoisend', False)
    self.api.get('events.eraise')('aard_whois', copy.deepcopy(self.whois))
    self.api.get('send.msg')('whois: %s' % self.whois)

  def savestate(self):
    """
    save states
    """
    AardwolfBasePlugin.savestate(self)
    self.whois.sync()
Example #13
0
class Plugin(BasePlugin):
  """
  a plugin to handle global variables, if something goes through
   send.execute (this includes from the client), a variable
   can be specified with $varname and will be substituted.
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    BasePlugin.__init__(self, *args, **kwargs)

    self.variablefile = os.path.join(self.savedir, 'variables.txt')
    self._variables = PersistentDict(self.variablefile, 'c')
    self.api.get('api.add')('getv', self.api_getv)
    self.api.get('api.add')('setv', self.api_setv)
    self.api.get('api.add')('replace', self.api_replace)

  def load(self):
    """
    load the plugin
    """
    BasePlugin.load(self)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='add a variable')
    parser.add_argument('name',
                        help='the name of the variable',
                        default='',
                        nargs='?')
    parser.add_argument('value',
                        help='the value of the variable',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('add',
                                 self.cmd_add,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='remove a variable')
    parser.add_argument('name',
                        help='the variable to remove',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('remove',
                                 self.cmd_remove,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                                     description='list variables')
    parser.add_argument('match',
                        help='list only variables that have this argument in their name',
                        default='',
                        nargs='?')
    self.api.get('commands.add')('list',
                                 self.cmd_list,
                                 parser=parser)

    self.api.get('commands.default')('list')
    #self.api.get('events.register')('from_client_event', self.checkvariable,
                                        #prio=1)
    self.api.get('events.register')('from_client_event',
                                    self.checkline,
                                    prio=99)

  # get a variable
  def api_getv(self, varname):
    """  get the variable with a specified name
    @Yvarname@w  = the variable to get

    this function returns the value of variable with the name of the argument
    """
    if varname in self._variables:
      return self._variables[varname]

    return None

  # set a variable
  def api_setv(self, varname, value):
    """  set the variable with a specified name to the specified value
    @Yvarname@w  = the variable to set
    @Yvalue@w  = the value to set

    this function returns True if the value was set, False if an error was
    encountered
    """
    try:
      self._variables[varname] = value
      return True
    except Exception: # pylint: disable=broad-except
      return False

  # replace variables in data
  def api_replace(self, data):
    """replace the variables in data
    @Ydata@w  = the variable to get

    this function returns the data after variable substition
    """
    templ = Template(data)
    return templ.safe_substitute(self._variables)

  def checkline(self, args):
    """
    this function checks for variables in input
    """
    data = args['fromdata'].strip()

    datan = self.api('vars.replace')(data)

    if datan != data:
      self.api.get('send.msg')('replacing "%s" with "%s"' % (data.strip(),
                                                             datan.strip()))
      args['fromdata'] = datan
      args['beforevar'] = data

    return args

  def cmd_add(self, args):
    """
    command to add a variable
    """
    tmsg = []
    if args['name'] and args['value']:
      tmsg.append("@GAdding variable@w : '%s' will be replaced by '%s'" % \
                                              (args['name'], args['value']))
      self.addvariable(args['name'], args['value'])
      return True, tmsg
    else:
      tmsg.append("@RPlease include all arguments@w")
      return False, tmsg

  def cmd_remove(self, args):
    """
    command to remove a variable
    """
    tmsg = []
    if args['name']:
      tmsg.append("@GRemoving variable@w : '%s'" % (args['name']))
      self.removevariable(args['name'])
      return True, tmsg
    else:
      return False, ['@RPlease specifiy a variable to remove@w']

  def cmd_list(self, args):
    """
    command to list variables
    """
    tmsg = self.listvariables(args['match'])
    return True, tmsg

  def addvariable(self, item, value):
    """
    internally add a variable
    """
    self._variables[item] = value
    self._variables.sync()

  def removevariable(self, item):
    """
    internally remove a variable
    """
    if item in self._variables:
      del self._variables[item]
      self._variables.sync()

  def listvariables(self, match):
    """
    return a table of variables
    """
    tmsg = []
    for item in self._variables:
      if not match or match in item:
        tmsg.append("%-20s : %s@w" % (item, self._variables[item]))
    if len(tmsg) == 0:
      tmsg = ['None']
    return tmsg

  def clearvariables(self):
    """
    clear all variables
    """
    self._variables.clear()
    self._variables.sync()

  def reset(self):
    """
    reset the plugin
    """
    BasePlugin.reset(self)
    self.clearvariables()

  def savestate(self):
    """
    save states
    """
    BasePlugin.savestate(self)
    self._variables.sync()
Example #14
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin manage info about spells and skills
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.saveskillfile = os.path.join(self.savedir, 'skills.txt')
    self.skills = PersistentDict(self.saveskillfile, 'c')
    self.skillsnamelookup = {}
    for i in self.skills:
      self.skillsnamelookup[self.skills[i]['name']] = i

    self.saverecovfile = os.path.join(self.savedir, 'recoveries.txt')
    self.recoveries = PersistentDict(self.saverecovfile, 'c')
    self.recoveriesnamelookup = {}
    for i in self.recoveries:
      self.recoveriesnamelookup[self.recoveries[i]['name']] = i

    self.current = ''
    self.isuptodatef = False

    self.cmdqueue = None

    self.api.get('dependency.add')('cmdq')

    self.api.get('api.add')('gets', self.api_getskill)
    self.api.get('api.add')('isspellup', self.api_isspellup)
    self.api.get('api.add')('getspellups', self.api_getspellups)
    self.api.get('api.add')('sendcmd', self.api_sendcmd)
    self.api.get('api.add')('isaffected', self.api_isaffected)
    self.api.get('api.add')('isblockedbyrecovery',
                                        self.api_isblockedbyrecovery)
    self.api.get('api.add')('ispracticed', self.api_ispracticed)
    self.api.get('api.add')('canuse', self.api_canuse)
    self.api.get('api.add')('isuptodate', self.api_isuptodate)
    self.api.get('api.add')('isbad', self.api_isbad)

  def load(self):
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)

    self.api.get('send.msg')('running load function of skills')

    parser = argparse.ArgumentParser(add_help=False,
                 description='refresh skills and spells')
    self.api.get('commands.add')('refresh', self.cmd_refresh,
                                 parser=parser)

    parser = argparse.ArgumentParser(add_help=False,
                 description='lookup skill or spell by name or sn')
    parser.add_argument('skill', help='the skill to lookup',
                        default='', nargs='?')
    self.api.get('commands.add')('lu', self.cmd_lu,
                                 parser=parser)

    self.api.get('triggers.add')('spellh_noprompt',
            "^\{spellheaders noprompt\}$",
            group='slist', enabled=False, omit=True)
    self.api.get('triggers.add')('spellh_spellup_noprompt',
            "^\{spellheaders spellup noprompt\}$",
            group='slist', enabled=False, omit=True)
    self.api.get('triggers.add')('spellh_affected_noprompt',
            "^\{spellheaders affected noprompt\}$",
            group='slist', enabled=False, omit=True)
    self.api.get('triggers.add')('spellh_spellline',
            "^(?P<sn>\d+),(?P<name>.+),(?P<target>\d+)," \
              "(?P<duration>\d+),(?P<pct>\d+),(?P<rcvy>-?\d+),(?P<type>\d+)$",
            group='spellhead', enabled=False, omit=True)
    self.api.get('triggers.add')('spellh_end_noprompt',
            "^\{/spellheaders\}$",
            group='spellhead', enabled=False, omit=True)
    self.api.get('triggers.add')('affoff',
            "^\{affoff\}(?P<sn>\d+)$")
    self.api.get('triggers.add')('affon',
            "^\{affon\}(?P<sn>\d+),(?P<duration>\d+)$")
    self.api.get('triggers.add')('recov_noprompt',
            "^\{recoveries noprompt\}$",
            group='slist', enabled=False, omit=True)
    self.api.get('triggers.add')('recov_affected_noprompt',
            "^\{recoveries affected noprompt\}$",
            group='slist', enabled=False, omit=True)
    self.api.get('triggers.add')('spellh_recovline',
            "^(?P<sn>\d+),(?P<name>.+),(?P<duration>\d+)$",
            group='recoveries', enabled=False, omit=True)
    self.api.get('triggers.add')('recov_end_noprompt',
            "^\{/recoveries\}$",
            group='recoveries', enabled=False, omit=True)
    self.api.get('triggers.add')('recoff',
            "^\{recoff\}(?P<sn>\d+)$")
    self.api.get('triggers.add')('recon',
            "^\{recon\}(?P<sn>\d+),(?P<duration>\d+)$")
    self.api.get('triggers.add')('skillgain',
            "^\{skillgain\}(?P<sn>\d+),(?P<percent>\d+)$")
    self.api.get('triggers.add')('skillfail',
            "^\{sfail\}(?P<sn>\d+),(?P<target>\d+)," \
              "(?P<reason>\d+),(?P<recovery>-?\d+)$")

    self.api.get('events.register')('trigger_spellh_noprompt',
                                    self.skillstart)
    self.api.get('events.register')('trigger_spellh_spellup_noprompt',
                                    self.skillstart)
    self.api.get('events.register')('trigger_spellh_affected_noprompt',
                                    self.skillstart)
    self.api.get('events.register')('trigger_spellh_spellline',
                                    self.skillline)
    self.api.get('events.register')('trigger_spellh_end_noprompt',
                                    self.skillend)
    self.api.get('events.register')('trigger_affoff', self.affoff)
    self.api.get('events.register')('trigger_affon', self.affon)
    self.api.get('events.register')('trigger_recov_noprompt',
                                    self.recovstart)
    self.api.get('events.register')('trigger_recov_affected_noprompt',
                                    self.recovstart)
    self.api.get('events.register')('trigger_spellh_recovline',
                                    self.recovline)
    self.api.get('events.register')('trigger_recov_end_noprompt',
                                    self.recovend)
    self.api.get('events.register')('trigger_recoff', self.recoff)
    self.api.get('events.register')('trigger_recon', self.recon)

    self.api.get('events.register')('trigger_skillgain', self.skillgain)
    self.api.get('events.register')('trigger_skillfail', self.skillfail)

    self.api.get('events.register')('GMCP:char.status', self.checkskills)

    self.api.get('events.register')('aard_level_tier', self.cmd_refresh)
    self.api.get('events.register')('aard_level_remort', self.cmd_refresh)


    self.cmdqueue = self.api.get('cmdq.baseclass')()(self)
    self.cmdqueue.addcmdtype('slist', 'slist', "^slist\s*(.*)$",
                       beforef=self.slistbefore, afterf=self.slistafter)

    self.checkskills()

  def slistbefore(self):
    """
    stuff to do before doing slist command
    """
    self.api.get('triggers.togglegroup')('slist', True)

  def slistafter(self):
    """
    stuff to do after doing slist command
    """
    self.savestate()
    self.api.get('triggers.togglegroup')('slist', False)

  def afterfirstactive(self, _=None):
    """
    do something on connect
    """
    AardwolfBasePlugin.afterfirstactive(self)
    self.checkskills()

  # check if the spells/skills list is up to date
  def api_isuptodate(self):
    """
    return True if we have seen affected or all spells refresh
    """
    return self.isuptodatef

  def cmd_lu(self, args):
    """
    cmd to lookup a spell
    """
    msg = []
    skill = self.api.get('skills.gets')(args['skill'])
    if skill:
      msg.append('%-8s : %s' % ('SN', skill['sn']))
      msg.append('%-8s : %s' % ('Name', skill['name']))
      msg.append('%-8s : %s' % ('Percent', skill['percent']))
      if skill['duration'] > 0:
        msg.append('%-8s : %s' % ('Duration',
            self.api.get('utils.timedeltatostring')(time.time(),
              skill['duration'])))
      msg.append('%-8s : %s' % ('Target', skill['target']))
      msg.append('%-8s : %s' % ('Spellup', skill['spellup']))
      msg.append('%-8s : %s' % ('Type', skill['type']))
      if skill['recovery']:
        recov = skill['recovery']
        if recov['duration'] > 0:
          duration =  self.api.get('utils.timedeltatostring')(time.time(),
              recov['duration'])
          msg.append('%-8s : %s (%s)' % ('Recovery',
                                      recov['name'], duration))
        else:
          msg.append('%-8s : %s' % ('Recovery', recov['name']))
    else:
      msg.append('Could not find: %s' % args['skill'])

    return True, msg

  def cmd_refresh(self, args):
    """
    refresh spells and skills
    """
    self.skills.clear()
    self.recoveries.clear()
    self.cmdqueue.addtoqueue('slist', 'noprompt')
    self.cmdqueue.addtoqueue('slist', 'spellup noprompt')
    msg = ['Refreshing spells and skills']
    return True, msg

  def checkskills(self, _=None):
    """
    check to see if we have spells
    """
    state = self.api.get('GMCP.getv')('char.status.state')
    if state == 3:
      self.api.get('send.msg')('refreshing skills')
      self.api.get('events.unregister')('GMCP:char.status', self.checkskills)
      self.api.get('A102.toggle')('SPELLUPTAGS', True)
      self.api.get('A102.toggle')('SKILLGAINTAGS', True)
      self.api.get('A102.toggle')('QUIETTAGS', False)
      if len(self.skills) == 0:
        self.cmd_refresh({})
      else:
        self.resetskills()
        self.cmdqueue.addtoqueue('slist', 'affected noprompt')

  def resetskills(self):
    """
    reset the skills
    """
    for i in self.skills:
      self.skills[i]['duration'] = 0
    for i in self.recoveries:
      self.recoveries[i]['duration'] = 0

  def skillgain(self, args):
    """
    handle a skillgain tag
    """
    spellnum = int(args['sn'])
    pct = int(args['percent'])
    if spellnum in self.skills:
      self.skills[spellnum]['percent'] = pct
      self.api.get('events.eraise')('aard_skill_gain',
                                    {'sn':spellnum, 'percent':pct})

  def skillfail(self, args):
    """
    raise an event when we fail a skill/spell
    """
    spellnum = int(args['sn'])
    reason = FAILREASON[int(args['reason'])]
    ndict = {'sn':spellnum, 'reason':reason,
            'target':FAILTARG[int(args['target'])],
            'recovery':int(args['recovery'])}
    if reason == 'dontknow' and self.skills[spellnum]['percent'] > 0:
      self.api.get('send.msg')('refreshing spells because of an unlearned spell')
      self.cmd_refresh({})
    self.api.get('send.msg')('raising skillfail: %s' % ndict)
    self.api.get('events.eraise')('skill_fail_%s' % args['sn'], ndict)
    self.api.get('events.eraise')('skill_fail', ndict)

  def affoff(self, args):
    """
    set the affect to off for spell that wears off
    """
    spellnum = int(args['sn'])
    if spellnum in self.skills:
      self.skills[spellnum]['duration'] = 0
      self.savestate()
      self.api.get('events.eraise')('aard_skill_affoff_%s' % spellnum,
                                              {'sn':spellnum})
      self.api.get('events.eraise')('aard_skill_affoff', {'sn':spellnum})

  def affon(self, args):
    """
    set the spell's duration when we see an affon
    """
    spellnum = int(args['sn'])
    duration = int(args['duration'])
    if spellnum in self.skills:
      self.skills[spellnum]['duration'] = time.mktime(time.localtime()) + \
                                                        duration
      self.savestate()
      self.api.get('events.eraise')('aard_skill_affon_%s' % spellnum,
                                              {'sn':spellnum,
                              'duration':self.skills[spellnum]['duration']})
      self.api.get('events.eraise')('aard_skill_affon', {'sn':spellnum,
                              'duration':self.skills[spellnum]['duration']})

  def recovstart(self, args):
    """
    show that the trigger fired
    """
    if 'triggername' in args \
        and args['triggername'] == 'trigger_recov_affected_noprompt':
      self.current = 'affected'
    else:
      self.current = ''
    self.api.get('triggers.togglegroup')('recoveries', True)

  def recovline(self, args):
    """
    parse a recovery line
    """
    spellnum = int(args['sn'])
    name = args['name']
    if int(args['duration']) != 0:
      duration = time.mktime(time.localtime()) + int(args['duration'])
    else:
      duration = 0

    if not (spellnum in self.recoveries):
      self.recoveries[spellnum] = {}

    self.recoveries[spellnum]['name'] = name
    self.recoveries[spellnum]['duration'] = duration
    self.recoveries[spellnum]['sn'] = spellnum

    self.recoveriesnamelookup[name] = spellnum

  def recovend(self, args):
    """
    reset current when seeing a spellheaders ending
    """
    self.api.get('triggers.togglegroup')('recoveries', False)
    if self.current == '' or self.current == 'affected':
      self.isuptodatef = True
      self.api.get('send.msg')('sending skills_affected_update')
      self.api.get('events.eraise')('skills_affected_update', {})
    self.cmdqueue.cmddone('slist')

  def recoff(self, args):
    """
    set the affect to off for spell that wears off
    """
    spellnum = int(args['sn'])
    if spellnum in self.recoveries:
      self.recoveries[spellnum]['duration'] = 0
      self.savestate()
      self.api.get('events.eraise')('aard_skill_recoff', {'sn':spellnum})

  def recon(self, args):
    """
    set the spell's duration when we see an affon
    """
    spellnum = int(args['sn'])
    duration = int(args['duration'])
    if spellnum in self.recoveries:
      self.recoveries[spellnum]['duration'] = \
                        time.mktime(time.localtime()) + duration
      self.savestate()
      self.api.get('events.eraise')('aard_skill_recon', {'sn':spellnum,
                            'duration':self.recoveries[spellnum]['duration']})

  def skillstart(self, args):
    """
    show that the trigger fired
    """
    if 'triggername' in args \
        and args['triggername'] == 'spellh_spellup_noprompt':
      self.current = 'spellup'
    elif 'triggername' in args \
        and args['triggername'] == 'spellh_affected_noprompt':
      self.current = 'affected'
    else:
      self.current = ''
    self.api.get('triggers.togglegroup')('spellhead', True)

  def skillline(self, args):
    """
    parse spell lines
    """
    spellnum = int(args['sn'])
    name = args['name']
    target = int(args['target'])
    if int(args['duration']) != 0:
      duration = time.mktime(time.localtime()) + int(args['duration'])
    else:
      duration = 0
    percent = int(args['pct'])
    recovery = int(args['rcvy'])
    stype = int(args['type'])

    if not (spellnum in self.skills):
      self.skills[spellnum] = {}

    self.skills[spellnum]['name'] = name
    self.skills[spellnum]['target'] = TARGET[target]
    self.skills[spellnum]['duration'] = duration
    self.skills[spellnum]['percent'] = percent
    self.skills[spellnum]['recovery'] = recovery
    self.skills[spellnum]['type'] = STYPE[stype]
    self.skills[spellnum]['sn'] = spellnum
    if not ('spellup' in self.skills[spellnum]):
      self.skills[spellnum]['spellup'] = False
    if self.current == 'spellup':
      self.skills[spellnum]['spellup'] = True

    self.skillsnamelookup[name] = spellnum

  def skillend(self, args):
    """
    reset current when seeing a spellheaders ending
    """
    self.api.get('triggers.togglegroup')('spellhead', False)
    self.savestate()
    if self.current:
      evname = 'aard_skill_ref_%s' % self.current
    else:
      evname = 'aard_skill_ref'
    self.api.get('events.eraise')(evname, {})
    self.current = ''

  # get a spell/skill by number
  def api_getskill(self, tsn):
    """
    get a skill
    """
    #self.api.get('send.msg')('looking for %s' % tsn)
    spellnum = -1
    name = tsn
    try:
      spellnum = int(tsn)
    except ValueError:
      pass

    tskill = None
    if spellnum >= 1:
      #self.api.get('send.msg')('%s >= 0' % spellnum)
      if spellnum in self.skills:
        #self.api.get('send.msg')('found spellnum')
        tskill = copy.deepcopy(self.skills[spellnum])
        #tskill = self.skills[spellnum]
      else:
        self.api.get('send.msg')('did not find skill for %s' % spellnum)

    if not tskill and name:
      #self.api.get('send.msg')('trying name')
      tlist = self.api.get('utils.checklistformatch')(name,
                                                self.skillsnamelookup.keys())
      if len(tlist) == 1:
        tskill = copy.deepcopy(self.skills[self.skillsnamelookup[tlist[0]]])

    if tskill:
      if tskill['recovery'] and tskill['recovery'] != -1:
        tskill['recovery'] = copy.deepcopy(self.recoveries[tskill['recovery']])
      else:
        tskill['recovery'] = None

    return tskill

  # send the command to active a skill/spell
  def api_sendcmd(self, spellnum):
    """
    send the command to activate a skill/spell
    """
    skill = self.api.get('skills.gets')(spellnum)
    if skill:
      if skill['type'] == 'spell':
        self.api.get('send.msg')('casting %s' % skill['name'])
        self.api.get('send.execute')('cast %s' % skill['sn'])
      else:
        name = skill['name'].split()[0]
        self.api.get('send.msg')('sending skill %s' % skill['name'])
        self.api.get('send.execute')(name)

  # check if a skill/spell can be used
  def api_canuse(self, spellnum):
    """
    return True if the spell can be used
    """
    if self.api.get('skills.isaffected')(spellnum) \
        or self.api.get('skills.isblockedbyrecovery')(spellnum) \
        or not self.api.get('skills.ispracticed')(spellnum):
      return False

    return True

  # check if a skill/spell is a spellup
  def api_isspellup(self, spellnum):
    """
    return True for a spellup, else return False
    """
    spellnum = int(spellnum)
    if spellnum in self.skills:
      return self.skills[spellnum]['spellup']

    return False

  # check if a skill/spell is bad
  def api_isbad(self, spellnum):
    """
    return True for a bad spell, False for a good spell
    """
    skill = self.api.get('skill.gets')(spellnum)
    if (skill['target'] == 'attack' or skill['target'] == 'special') and \
          not skill['spellup']:
      return True

    return False

  # check if a skill/spell is active
  def api_isaffected(self, spellnum):
    """
    return True for a spellup, else return False
    """
    skill = self.api.get('skills.gets')(spellnum)
    if skill:
      return skill['duration'] > 0

    return False

  # check if a skill/spell is blocked by a recovery
  def api_isblockedbyrecovery(self, spellnum):
    """
    check to see if a spell/skill is blocked by a recovery
    """
    skill = self.api.get('skills.gets')(spellnum)
    if skill:
      if 'recovery' in skill and skill['recovery'] and \
          skill['recovery']['duration'] > 0:
        return True

    return False

  # check if a skill/spell is practiced
  def api_ispracticed(self, spellnum):
    """
    is the spell learned
    """
    skill = self.api.get('skills.gets')(spellnum)
    if skill:
      if skill['percent'] > 10:
        return True

    return False

  # get the list of spellup spells/skills
  def api_getspellups(self):
    """
    return a list of spellup spells
    """
    sus = [x for x in self.skills.values() if x['spellup']]
    return sus

  def savestate(self):
    """
    save states
    """
    AardwolfBasePlugin.savestate(self)
    self.skills.sync()
    self.recoveries.sync()
Example #15
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin to handle aardwolf cp events
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.savewhoisfile = os.path.join(self.savedir, 'whois.txt')
        self.whois = PersistentDict(self.savewhoisfile, 'c')

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)

        self.api('watch.add')('whois', '^(whoi|whois)$')

        self.api('triggers.add')('whoisheader',
                                 r"^\[.*\]\s+.*\s*\((?P<sex>\w+)\s+\w+\)$",
                                 enabled=False,
                                 group='whois')
        self.api('triggers.add')('whoisclasses',
                                 r"^\[Multiclass Player: (?P<classes>.*) \]$",
                                 enabled=False,
                                 group='whois')
        self.api('triggers.add')(
            'whois1',
            r"^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]\s*$",
            enabled=False,
            group='whois')
        self.api('triggers.add')(
            'whois2',
            r"^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]" \
              r"\s*(?P<name2>[\w\s]*)\s*:\s*\[\s*(?P<val2>[\w\d\s]*)\s*\]\s*$",
            enabled=False,
            group='whois')
        self.api('triggers.add')(
            'whois3',
            r"^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]" \
              r"\s*(?P<name2>[\w\s]*)\s*:\s*\[\s*(?P<val2>[\w\d\s]*)\s*\]" \
              r"\s*(?P<name3>[\w\s]*)\s*:\s*\[\s*(?P<val3>[\w\d\s]*)\s*\]\s*$",
            enabled=False,
            group='whois')
        self.api('triggers.add')(
            'whoispowerup',
            r"^(?P<name1>[\w\s]*)\s*:\s*\[\s*(?P<val1>[\w\d\s]*)\s*\]" \
              r"\s*([\w\s]*)\s*:\s*\[\s*(?P<pval1>[\w\d\s]*)\s*\]\s*\[\s*" \
              r"(?P<pval2>[\w\d\s]*)\s*\]\s*$",
            enabled=False,
            group='whois')
        self.api('triggers.add')('whoisend', r"^-{74,74}$", enabled=False)

        self.api('events.register')('watch_whois', self._whois)
        self.api('events.register')('trigger_whoisheader', self._whoisheader)
        self.api('events.register')('trigger_whoisclasses', self._whoisclasses)
        self.api('events.register')('trigger_whois1', self._whoisstats)
        self.api('events.register')('trigger_whois2', self._whoisstats)
        self.api('events.register')('trigger_whois3', self._whoisstats)
        self.api('events.register')('trigger_whoispowerup', self._whoisstats)
        self.api('events.register')('trigger_whoisend', self._whoisend)
        self.api('events.register')('plugin_%s_savestate' % self.sname,
                                    self._savestate)

    def _whois(self, args=None):
        """
    reset the whois info when a "whois" command is sent
    """
        self.whois.clear()
        self.api('triggers.togglegroup')('whois', True)
        return args

    def _whoisstats(self, args=None):
        """
    parse a whois line
    """
        for i in range(1, 4):
            akey = 'name%s' % i
            aval = 'val%s' % i

            if akey in args:
                kname = args[akey].lower().strip()
                kname = kname.replace(' ', '')
                kval = args[aval].strip()

                self.whois[kname] = kval

        if 'pval1' in args:
            self.whois['powerupsall'] = args['pval1']
        if 'pval2' in args:
            self.whois['powerupsmort'] = args['pval2']

    def _whoisheader(self, args=None):
        """
    do stuff when we see the whois header
    """
        self.whois["name"] = self.api('GMCP.getv')('char.base.name')
        self.whois['level'] = self.api('GMCP.getv')('char.status.level')
        self.whois['tiers'] = self.api('GMCP.getv')('char.base.tier')
        self.whois['redos'] = int(self.api('GMCP.getv')('char.base.redos'))
        self.whois['race'] = self.api('GMCP.getv')('char.base.race').lower()
        self.whois['sex'] = args['sex'].lower()
        self.whois['subclass'] = self.api('GMCP.getv')(
            'char.base.subclass').lower()
        self.whois['powerupsall'] = 0
        self.whois['powerupsmort'] = 0
        self.whois['remorts'] = self.api('GMCP.getv')('char.base.remorts')
        if self.whois['remorts'] == 1:
            classabs = self.api('aardu.classabb')()
            self.whois['classes'] = []
            self.whois['classes'].append({
                'remort':
                1,
                'class':
                classabs[self.api('GMCP.getv')('char.base.class').lower()]
            })

        self.api('triggers.toggle')('whoisend', True)

    def _whoisclasses(self, args):
        """
    add classes
    """
        classabs = self.api('aardu.classabb')()
        tlist = args['classes'].split("/")
        remorts = len(tlist)
        self.whois['classes'] = []
        for i in range(remorts):
            tclass = tlist[i].strip().lower()
            self.whois['classes'].append({
                'remort': i + 1,
                'class': classabs[tclass.lower()]
            })

        self.whois['remorts'] = remorts

    def _whoisend(self, _=None):
        """
    send a whois
    """
        self.whois['totallevels'] = self.api('aardu.getactuallevel')(
            self.whois['level'], self.whois['remorts'], self.whois['tiers'],
            self.whois['redos'])
        self.whois.sync()
        self.api('triggers.togglegroup')('whois', False)
        self.api('triggers.toggle')('whoisend', False)
        self.api('events.eraise')('aard_whois', copy.deepcopy(self.whois))
        self.api('send.msg')('whois: %s' % self.whois)

    def _savestate(self, _=None):
        """
    save states
    """
        self.whois.sync()
Example #16
0
class Plugin(BasePlugin):
    """
  a plugin to handle user aliases
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        BasePlugin.__init__(self, *args, **kwargs)

        self.aliasfile = os.path.join(self.savedir, 'aliases.txt')
        self._aliases = PersistentDict(self.aliasfile, 'c')

        self.sessionhits = {}

    def load(self):
        """
    load the plugin
    """
        BasePlugin.load(self)

        self.api('setting.add')('nextnum',
                                0,
                                int,
                                'the number of the next alias added',
                                readonly=True)

        parser = argp.ArgumentParser(add_help=False,
                                     description='add an alias')
        parser.add_argument('original',
                            help='the input to replace',
                            default='',
                            nargs='?')
        parser.add_argument('replacement',
                            help='the string to replace it with',
                            default='',
                            nargs='?')
        parser.add_argument('-o',
                            "--overwrite",
                            help="overwrite an alias if it already exists",
                            action="store_true")
        parser.add_argument('-d',
                            "--disable",
                            help="disable the alias",
                            action="store_true")
        parser.add_argument('-g',
                            "--group",
                            help="the alias group",
                            default="")
        self.api('commands.add')('add', self.cmd_add, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='remove an alias')
        parser.add_argument('alias',
                            help='the alias to remove',
                            default='',
                            nargs='?')
        self.api('commands.add')('remove', self.cmd_remove, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='list aliases')
        parser.add_argument(
            'match',
            help='list only aliases that have this argument in them',
            default='',
            nargs='?')
        self.api('commands.add')('list', self.cmd_list, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='toggle enabled flag')
        parser.add_argument('alias',
                            help='the alias to toggle',
                            default='',
                            nargs='?')
        self.api('commands.add')('toggle', self.cmd_toggle, parser=parser)

        parser = argp.ArgumentParser(
            add_help=False, description='toggle all aliases in a group')
        parser.add_argument('group',
                            help='the group to toggle',
                            default='',
                            nargs='?')
        parser.add_argument('-d',
                            "--disable",
                            help="disable the group",
                            action="store_true")
        self.api('commands.add')('groupt', self.cmd_grouptoggle, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='get detail for an alias')
        parser.add_argument('alias',
                            help='the alias to get details for',
                            default='',
                            nargs='?')
        self.api('commands.add')('detail', self.cmd_detail, parser=parser)

        self.api('commands.default')('list')
        self.api('events.register')('io_execute_event',
                                    self.checkalias,
                                    prio=2)
        self.api('events.register')('plugin_%s_savestate' % self.sname,
                                    self._savestate)

    def checkalias(self, args):  # pylint: disable=too-many-branches
        """
    this function finds aliases in client input
    """
        data = args['fromdata'].strip()

        if not data:
            return args

        for mem in self._aliases.keys():
            if self._aliases[mem]['enabled']:
                datan = data
                matchd = re.match(mem, data)
                if matchd:
                    self.api('send.msg')('matched input on %s' % mem)
                    tlistn = [data]
                    for i in xrange(1, len(matchd.groups()) + 1):
                        tlistn.append(matchd.group(i))
                    self.api('send.msg')('args: %s' % tlistn)
                    try:
                        datan = self._aliases[mem]['alias'].format(*tlistn)
                    except Exception:  # pylint: disable=broad-except
                        self.api('send.traceback')('alias %s had an issue' %
                                                   (mem))
                else:
                    cre = re.compile('^%s' % mem)
                    datan = cre.sub(self._aliases[mem]['alias'], data)
                if datan != data:
                    if 'trace' in args:
                        args['trace']['changes'].append({'flag':'Modify',
                                                         'data':'changed "%s" to "%s"' % \
                                                            (data, datan),
                                                         'plugin':self.sname})
                    if not 'hits' in self._aliases[mem]:
                        self._aliases[mem]['hits'] = 0
                    if not mem in self.sessionhits:
                        self.sessionhits[mem] = 0
                    self.api('send.msg')('incrementing hits for %s' % mem)
                    self._aliases[mem]['hits'] = self._aliases[mem]['hits'] + 1
                    self.sessionhits[mem] = self.sessionhits[mem] + 1
                    self.api('send.msg')('replacing "%s" with "%s"' % \
                                                    (data.strip(), datan.strip()))
                    if datan[0:3] == '#bp':
                        self.api('send.execute')(datan,
                                                 showinhistory=False,
                                                 fromclient=False)
                        args['fromdata'] = ''
                        args['history'] = False
                    else:
                        args['history'] = False
                        args['fromclient'] = False
                        args['fromdata'] = datan

        return args

    def lookup_alias(self, alias):
        """
    lookup an alias by number or name
    """
        nitem = None
        try:
            num = int(alias)
            nitem = None
            for titem in self._aliases.keys():
                if num == self._aliases[titem]['num']:
                    nitem = titem
                    break

        except ValueError:
            if alias in self._aliases:
                nitem = alias

        return nitem

    def cmd_add(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a alias
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
        tmsg = []
        if args['original'] and args['replacement']:
            if args['original'] in self._aliases and not args['overwrite']:
                return True, ['Alias: %s already exists.' % args['original']]
            else:
                tmsg.append("@GAdding alias@w : '%s' will be replaced by '%s'" % \
                                              (args['original'], args['replacement']))
                self.addalias(args['original'], args['replacement'],
                              args['disable'], args['group'])
            return True, tmsg
        else:
            return False, ['@RPlease include all arguments@w']

    def cmd_remove(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Remove a alias
      @CUsage@w: rem @Y<originalstring>@w
        @Yoriginalstring@w    = The original string
    """
        tmsg = []
        if args['alias']:
            retval = self.removealias(args['alias'])
            if retval:
                tmsg.append("@GRemoving alias@w : '%s'" % (retval))
            else:
                tmsg.append("@GCould not remove alias@w : '%s'" %
                            (args['alias']))

            return True, tmsg
        else:
            return False, ['@RPlease include an alias to remove@w']

    def cmd_toggle(self, args):
        """
    toggle the enabled flag
    """
        tmsg = []
        if args['alias']:
            retval = self.togglealias(args['alias'])
            if retval:
                if self._aliases[retval]['enabled']:
                    tmsg.append("@GEnabled alias@w : '%s'" % (retval))
                else:
                    tmsg.append("@GDisabled alias@w : '%s'" % (retval))
            else:
                tmsg.append("@GDoes not exist@w : '%s'" % (args['alias']))
            return True, tmsg

        else:
            return False, ['@RPlease include an alias to toggle@w']

    def cmd_detail(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a alias
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
        tmsg = []
        if args['alias']:
            alias = self.lookup_alias(args['alias'])
            if alias:
                if 'hits' not in self._aliases[alias]:
                    self._aliases[alias]['hits'] = 0
                if alias not in self.sessionhits:
                    self.sessionhits[alias] = 0
                tmsg.append('%-12s : %d' %
                            ('Num', self._aliases[alias]['num']))
                tmsg.append('%-12s : %s' % \
                    ('Enabled', 'Y' if self._aliases[alias]['enabled'] else 'N'))
                tmsg.append('%-12s : %d' %
                            ('Total Hits', self._aliases[alias]['hits']))
                tmsg.append('%-12s : %d' %
                            ('Session Hits', self.sessionhits[alias]))
                tmsg.append('%-12s : %s' % ('Alias', alias))
                tmsg.append('%-12s : %s' %
                            ('Replacement', self._aliases[alias]['alias']))
                tmsg.append('%-12s : %s' %
                            ('Group', self._aliases[alias]['group']))
            else:
                return True, [
                    '@RAlias does not exits@w : \'%s\'' % (args['alias'])
                ]

            return True, tmsg
        else:
            return False, ['@RPlease include all arguments@w']

    def cmd_list(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      List aliases
      @CUsage@w: list
    """
        tmsg = self.listaliases(args['match'])
        return True, tmsg

    def cmd_grouptoggle(self, args):
        """
    toggle all aliases in a group
    """
        tmsg = []
        togglea = []
        state = not args['disable']
        if args['group']:
            for i in self._aliases:
                if 'group' not in self._aliases[i]:
                    self._aliases[i]['group'] = ''

                if self._aliases[i]['group'] == args['group']:
                    self._aliases[i]['enabled'] = state
                    togglea.append('%s' % self._aliases[i]['num'])

            if togglea:
                tmsg.append('The following aliases were %s: %s' % \
                      ('enabled' if state else 'disabled',
                       ','.join(togglea)))
            else:
                tmsg.append('No aliases were modified')

            return True, tmsg
        else:
            return False, ['@RPlease include a group to toggle@w']

    def addalias(self, item, alias, disabled, group):
        """
    internally add a alias
    """
        num = self.api('setting.gets')('nextnum')
        self._aliases[item] = {
            'alias': alias,
            'enabled': not disabled,
            'num': num,
            'group': group
        }
        self._aliases.sync()
        self.api('setting.change')('nextnum', num + 1)

    def removealias(self, item):
        """
    internally remove a alias
    """
        alias = self.lookup_alias(item)
        if alias:
            del self._aliases[alias]
            self._aliases.sync()

        return alias

    def togglealias(self, item):
        """
    toggle an alias
    """
        alias = self.lookup_alias(item)
        if alias:
            self._aliases[alias][
                'enabled'] = not self._aliases[alias]['enabled']

        return alias

    def listaliases(self, match):
        """
    return a table of strings that list aliases
    """
        tmsg = []
        for alias in sorted(self._aliases.iteritems(),
                            key=lambda (x, y): y['num']):
            item = alias[0]
            if not match or match in item:
                lalias = self.api('colors.stripansi')(
                    self._aliases[item]['alias'])
                if len(lalias) > 30:
                    lalias = lalias[:27] + '...'
                tmsg.append("%4s %2s  %-10s %-20s : %s@w" % \
                             (self._aliases[item]['num'],
                              'Y' if self._aliases[item]['enabled'] else 'N',
                              self._aliases[item]['group'],
                              item,
                              lalias))
        if not tmsg:
            tmsg = ['None']
        else:
            tmsg.insert(
                0, "%4s %2s  %-10s %-20s : %s@w" %
                ('#', 'E', 'Group', 'Alias', 'Replacement'))
            tmsg.insert(1, '@B' + '-' * 60 + '@w')

        return tmsg

    def clearaliases(self):
        """
    clear all aliases
    """
        self._aliases.clear()
        self._aliases.sync()

    def reset(self):
        """
    reset the plugin
    """
        BasePlugin.reset(self)
        self.clearaliases()

    def _savestate(self, _=None):
        """
    save states
    """
        self._aliases.sync()
Example #17
0
class Plugin(BasePlugin):
    """
  a plugin for user actions
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        BasePlugin.__init__(self, *args, **kwargs)

        self.canreload = True

        self.regexlookup = {}
        self.actiongroups = {}
        self.compiledregex = {}
        self.sessionhits = {}

        self.saveactionsfile = os.path.join(self.savedir, 'actions.txt')
        self.actions = PersistentDict(self.saveactionsfile, 'c')

        for i in self.actions:
            self.compiledregex[i] = re.compile(self.actions[i]['regex'])

    def load(self):
        """
    load the plugin
    """
        BasePlugin.load(self)

        self.api.get('setting.add')('nextnum',
                                    0,
                                    int,
                                    'the number of the next action added',
                                    readonly=True)

        parser = argparse.ArgumentParser(add_help=False,
                                         description='add a action')
        parser.add_argument('regex',
                            help='the regex to match',
                            default='',
                            nargs='?')
        parser.add_argument('action',
                            help='the action to take',
                            default='',
                            nargs='?')
        parser.add_argument('send',
                            help='where to send the action',
                            default='execute',
                            nargs='?',
                            choices=self.api.get('api.getchildren')('send'))
        parser.add_argument('-c',
                            "--color",
                            help="match colors (@@colors)",
                            action="store_true")
        parser.add_argument('-d',
                            "--disable",
                            help="disable the action",
                            action="store_true")
        parser.add_argument('-g',
                            "--group",
                            help="the action group",
                            default="")
        parser.add_argument('-o',
                            "--overwrite",
                            help="overwrite an action if it already exists",
                            action="store_true")
        self.api.get('commands.add')('add', self.cmd_add, parser=parser)

        parser = argparse.ArgumentParser(add_help=False,
                                         description='list actions')
        parser.add_argument(
            'match',
            help='list only actions that have this argument in them',
            default='',
            nargs='?')
        self.api.get('commands.add')('list', self.cmd_list, parser=parser)

        parser = argparse.ArgumentParser(add_help=False,
                                         description='remove an action')
        parser.add_argument('action',
                            help='the action to remove',
                            default='',
                            nargs='?')
        self.api.get('commands.add')('remove', self.cmd_remove, parser=parser)

        parser = argparse.ArgumentParser(add_help=False,
                                         description='toggle enabled flag')
        parser.add_argument('action',
                            help='the action to toggle',
                            default='',
                            nargs='?')
        self.api.get('commands.add')('toggle', self.cmd_toggle, parser=parser)

        parser = argparse.ArgumentParser(
            add_help=False, description='get detail for an action')
        parser.add_argument('action',
                            help='the action to get details for',
                            default='',
                            nargs='?')
        self.api.get('commands.add')('detail', self.cmd_detail, parser=parser)

        parser = argparse.ArgumentParser(
            add_help=False, description='toggle all actions in a group')
        parser.add_argument('group',
                            help='the group to toggle',
                            default='',
                            nargs='?')
        parser.add_argument('-d',
                            "--disable",
                            help="disable the group",
                            action="store_true")
        self.api.get('commands.add')('groupt',
                                     self.cmd_grouptoggle,
                                     parser=parser)

        #self.api.get('commands.add')('stats', self.cmd_stats,
        #                             shelp='show action stats')

        self.api.get('events.register')('from_mud_event',
                                        self.checkactions,
                                        prio=5)


#    self.api.get('events.register')('plugin_stats', self.getpluginstats)

    def lookup_action(self, action):
        """
    lookup an action by number or name
    """
        nitem = None
        try:
            num = int(action)
            nitem = None
            for titem in self.actions.keys():
                if num == self.actions[titem]['num']:
                    nitem = titem
                    break

        except ValueError:
            if action in self.actions:
                nitem = action

        return nitem

    @timeit
    def checkactions(self, args):
        """
    check a line of text from the mud
    the is called whenever the from_mud_event is raised
    """
        data = args['noansi']
        colordata = args['convertansi']

        for i in self.actions:
            if self.actions[i]['enabled']:
                trigre = self.compiledregex[i]
                datatomatch = data
                if 'matchcolor' in self.actions[i] and \
                    self.actions[i]['matchcolor']:
                    datatomatch = colordata
                mat = trigre.match(datatomatch)
                self.api.get('send.msg')('attempting to match %s' %
                                         datatomatch)
                if mat:
                    if i in self.sessionhits:
                        self.sessionhits[i] = 0
                    self.sessionhits[i] = self.sessionhits[i] + 1
                    if 'hits' in self.actions[i]:
                        self.actions[i]['hits'] = 0
                    self.actions[i]['hits'] = self.actions[i]['hits'] + 1
                    self.api.get('send.msg')('matched line: %s to action %s' %
                                             (data, i))
                    templ = Template(self.actions[i]['action'])
                    newaction = templ.safe_substitute(mat.groupdict())
                    sendtype = 'send.' + self.actions[i]['send']
                    self.api.get('send.msg')('sent %s to %s' %
                                             (newaction, sendtype))
                    self.api.get(sendtype)(newaction)

        return args

    def cmd_add(self, args):
        """
    add user defined actions
    """
        if not args['regex']:
            return False, ['Please include a regex']
        if not args['action']:
            return False, ['Please include an action']

        if not args['overwrite'] and args['regex'] in self.actions:
            return True, ['Action: %s already exists.' % args['regex']]
        else:
            num = 0

            if args['regex'] in self.actions:
                num = self.actions[args['regex']]['num']
            else:
                num = self.api.get('setting.gets')('nextnum')
                self.api.get('setting.change')('nextnum', num + 1)

            self.actions[args['regex']] = {
                'num': num,
                'regex': args['regex'],
                'action': args['action'],
                'send': args['send'],
                'matchcolor': args['color'],
                'enabled': not args['disable'],
                'group': args['group']
            }
            self.actions.sync()

            self.compiledregex[args['regex']] = re.compile(args['regex'])

            return True, ['added action %s - regex: %s' % (num, args['regex'])]

        return False, ['You should never see this']

    def cmd_remove(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Remove an action
      @CUsage@w: rem @Y<originalstring>@w
        @Yoriginalstring@w    = The original string
    """
        tmsg = []
        if args['action']:
            retval = self.removeaction(args['action'])
            if retval:
                tmsg.append("@GRemoving action@w : '%s'" % (retval))
            else:
                tmsg.append("@GCould not remove action@w : '%s'" %
                            (args['action']))

            return True, tmsg
        else:
            return False, ['@RPlease include an action to remove@w']

    def cmd_list(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      List actiones
      @CUsage@w: list
    """
        tmsg = self.listactions(args['match'])
        return True, tmsg

    def cmd_toggle(self, args):
        """
    toggle the enabled flag
    """
        tmsg = []
        if args['action']:
            retval = self.toggleaction(args['action'])
            if retval:
                if self.actions[retval]['enabled']:
                    tmsg.append("@GEnabled action@w : '%s'" % (retval))
                else:
                    tmsg.append("@GDisabled action@w : '%s'" % (retval))
            else:
                tmsg.append("@GDoes not exist@w : '%s'" % (args['action']))
            return True, tmsg

        else:
            return False, ['@RPlease include an action to toggle@w']

    def cmd_grouptoggle(self, args):
        """
    toggle all actions in a group
    """
        tmsg = []
        togglea = []
        state = not args['disable']
        if args['group']:
            for i in self.actions:
                if self.actions[i]['group'] == args['group']:
                    self.actions[i]['enabled'] = state
                    togglea.append('%s' % self.actions[i]['num'])

            if togglea:
                tmsg.append('The following actions were %s: %s' % \
                      ('enabled' if state else 'disabled',
                       ','.join(togglea)))
            else:
                tmsg.append('No actions were modified')

            return True, tmsg
        else:
            return False, ['@RPlease include a group to toggle@w']

    def cmd_detail(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a action
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
        tmsg = []
        if args['action']:
            action = self.lookup_action(args['action'])
            if action:
                if 'hits' in self.actions[action]:
                    self.actions[action]['hits'] = 0
                if action in self.sessionhits:
                    self.sessionhits[action] = 0
                tmsg.append('%-12s : %d' %
                            ('Num', self.actions[action]['num']))
                tmsg.append('%-12s : %s' % \
                    ('Enabled', 'Y' if self.actions[action]['enabled'] else 'N'))
                tmsg.append('%-12s : %d' %
                            ('Total Hits', self.actions[action]['hits']))
                tmsg.append('%-12s : %d' %
                            ('Session Hits', self.sessionhits[action]))
                tmsg.append('%-12s : %s' %
                            ('Regex', self.actions[action]['regex']))
                tmsg.append('%-12s : %s' %
                            ('Action', self.actions[action]['action']))
                tmsg.append('%-12s : %s' %
                            ('Group', self.actions[action]['group']))
                tmsg.append(
                    '%-12s : %s' %
                    ('Match Color', self.actions[action]['matchcolor']))
            else:
                return True, [
                    '@RAction does not exits@w : \'%s\'' % (args['action'])
                ]

            return True, tmsg
        else:
            return False, ['@RPlease include all arguments@w']

    def listactions(self, match):
        """
    return a table of strings that list actiones
    """
        tmsg = []
        for action in sorted(self.actions.keys()):
            item = self.actions[action]
            if not match or match in item:
                regex = self.api.get('colors.stripansi')(item['regex'])
                if len(regex) > 30:
                    regex = regex[:27] + '...'
                action = self.api.get('colors.stripansi')(item['action'])
                if len(action) > 30:
                    action = action[:27] + '...'
                tmsg.append("%4s %2s  %-10s %-32s : %s@w" % \
                             (item['num'],
                              'Y' if item['enabled'] else 'N',
                              item['group'],
                              regex,
                              action))
        if len(tmsg) == 0:
            tmsg = ['None']
        else:
            tmsg.insert(
                0, "%4s %2s  %-10s %-32s : %s@w" %
                ('#', 'E', 'Group', 'Regex', 'Action'))
            tmsg.insert(1, '@B' + '-' * 60 + '@w')

        return tmsg

    def removeaction(self, item):
        """
    internally remove a action
    """
        action = self.lookup_action(item)
        print 'lookup_action', item, 'returned', action
        if action >= 0:
            del self.actions[action]
            self.actions.sync()

        return action

    def toggleaction(self, item):
        """
    toggle an action
    """
        action = self.lookup_action(item)
        if action:
            self.actions[action][
                'enabled'] = not self.actions[action]['enabled']

        return action

    def clearactions(self):
        """
    clear all actiones
    """
        self.actions.clear()
        self.actions.sync()

    def reset(self):
        """
    reset the plugin
    """
        BasePlugin.reset(self)
        self.clearactions()

    def savestate(self):
        """
    save states
    """
        BasePlugin.savestate(self)
        self.actions.sync()
Example #18
0
class Plugin(BasePlugin):
    """
  a plugin to do simple substitution
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        BasePlugin.__init__(self, *args, **kwargs)
        self.savesubfile = os.path.join(self.savedir, 'subs.txt')
        self._substitutes = PersistentDict(self.savesubfile, 'c')

    def load(self):
        """
    load the plugins
    """
        BasePlugin.load(self)

        parser = argp.ArgumentParser(add_help=False,
                                     description='add a simple substitute')
        parser.add_argument('original',
                            help='the output to substitute',
                            default='',
                            nargs='?')
        parser.add_argument('replacement',
                            help='the string to replace it with',
                            default='',
                            nargs='?')
        self.api('commands.add')('add', self.cmd_add, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='remove a substitute')
        parser.add_argument('substitute',
                            help='the substitute to remove',
                            default='',
                            nargs='?')
        self.api('commands.add')('remove', self.cmd_remove, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='list substitutes')
        parser.add_argument(
            'match',
            help='list only substitutes that have this argument in them',
            default='',
            nargs='?')
        self.api('commands.add')('list', self.cmd_list, parser=parser)

        parser = argp.ArgumentParser(add_help=False,
                                     description='clear all substitutes')
        self.api('commands.add')('clear', self.cmd_clear, parser=parser)

        self.api('commands.default')('list')
        self.api('events.register')('from_mud_event', self.findsub)

        self.api('events.register')('plugin_%s_savestate' % self.sname,
                                    self._savestate)

    def findsub(self, args):
        """
    this function finds subs in mud data
    """
        data = args['original']
        dtype = args['dtype']
        if dtype != 'fromproxy':
            for mem in self._substitutes.keys():
                if mem in data:
                    ndata = data.replace(
                        mem,
                        self.api('colors.convertcolors')(
                            self._substitutes[mem]['sub']))
                    if ndata != data:
                        args['trace']['changes'].append({'flag':'Modify',
                                                         'data':'changed "%s" to "%s"' % \
                                                             (data, ndata),
                                                         'plugin':self.sname,
                                                         'eventname':args['eventname']})
                        data = ndata
            args['original'] = data
            return args

    def cmd_add(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a substitute
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
        tmsg = []
        if args['original'] and args['replacement']:
            tmsg.append("@GAdding substitute@w : '%s' will be replaced by '%s'" % \
                                            (args['original'], args['replacement']))
            self.addsub(args['original'], args['replacement'])
            return True, tmsg

        tmsg.append("@RPlease specify all arguments@w")
        return False, tmsg

    def cmd_remove(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      Remove a substitute
      @CUsage@w: rem @Y<originalstring>@w
        @Yoriginalstring@w    = The original string
    """
        tmsg = []
        if args['substitute']:
            tmsg.append("@GRemoving substitute@w : '%s'" %
                        (args['substitute']))
            self.removesub(args['substitute'])
            return True, tmsg

        return False, tmsg

    def cmd_list(self, args):
        """
    @G%(name)s@w - @B%(cmdname)s@w
      List substitutes
      @CUsage@w: list
    """
        tmsg = self.listsubs(args['match'])
        return True, tmsg

    def cmd_clear(self, args):
        # pylint: disable=unused-argument
        """
    @G%(name)s@w - @B%(cmdname)s@w
      List substitutes
      @CUsage@w: list"""
        self.clearsubs()
        return True, ['Substitutes cleared']

    def addsub(self, item, sub):
        """
    internally add a substitute
    """
        self._substitutes[item] = {'sub': sub}
        self._substitutes.sync()

    def removesub(self, item):
        """
    internally remove a substitute
    """
        if item in self._substitutes:
            del self._substitutes[item]
            self._substitutes.sync()

    def listsubs(self, match):
        """
    return a table of strings that list subs
    """
        tmsg = []
        for item in self._substitutes:
            if not match or match in item:
                tmsg.append("%-35s : %s@w" %
                            (item, self._substitutes[item]['sub']))
        if not tmsg:
            tmsg = ['None']
        return tmsg

    def clearsubs(self):
        """
    clear all subs
    """
        self._substitutes.clear()
        self._substitutes.sync()

    def reset(self):
        """
    reset the plugin
    """
        BasePlugin.reset(self)
        self.clearsubs()

    def _savestate(self, _=None):
        """
    save states
    """
        self._substitutes.sync()
Example #19
0
class Plugin(BasePlugin):
  """
  a plugin to do simple substitution
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    BasePlugin.__init__(self, *args, **kwargs)
    self.savesubfile = os.path.join(self.savedir, 'subs.txt')
    self._substitutes = PersistentDict(self.savesubfile, 'c')

  def load(self):
    """
    load the plugins
    """
    BasePlugin.load(self)

    parser = argp.ArgumentParser(add_help=False,
                                 description='add a simple substitute')
    parser.add_argument('original',
                        help='the output to substitute',
                        default='',
                        nargs='?')
    parser.add_argument('replacement',
                        help='the string to replace it with',
                        default='',
                        nargs='?')
    self.api('commands.add')('add',
                             self.cmd_add,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='remove a substitute')
    parser.add_argument('substitute',
                        help='the substitute to remove',
                        default='',
                        nargs='?')
    self.api('commands.add')('remove',
                             self.cmd_remove,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='list substitutes')
    parser.add_argument('match',
                        help='list only substitutes that have this argument in them',
                        default='',
                        nargs='?')
    self.api('commands.add')('list',
                             self.cmd_list,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='clear all substitutes')
    self.api('commands.add')('clear',
                             self.cmd_clear,
                             parser=parser)

    self.api('commands.default')('list')
    self.api('events.register')('from_mud_event', self.findsub)

    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)

  def findsub(self, args):
    """
    this function finds subs in mud data
    """
    data = args['original']
    dtype = args['dtype']
    if dtype != 'fromproxy':
      for mem in self._substitutes.keys():
        if mem in data:
          ndata = data.replace(mem,
                               self.api('colors.convertcolors')(
                                   self._substitutes[mem]['sub']))
          if ndata != data:
            args['trace']['changes'].append({'flag':'Modify',
                                             'data':'changed "%s" to "%s"' % \
                                                 (data, ndata),
                                             'plugin':self.sname,
                                             'eventname':args['eventname']})
            data = ndata
      args['original'] = data
      return args

  def cmd_add(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      Add a substitute
      @CUsage@w: add @Y<originalstring>@w @M<replacementstring>@w
        @Yoriginalstring@w    = The original string to be replaced
        @Mreplacementstring@w = The new string
    """
    tmsg = []
    if args['original'] and args['replacement']:
      tmsg.append("@GAdding substitute@w : '%s' will be replaced by '%s'" % \
                                      (args['original'], args['replacement']))
      self.addsub(args['original'], args['replacement'])
      return True, tmsg

    tmsg.append("@RPlease specify all arguments@w")
    return False, tmsg

  def cmd_remove(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      Remove a substitute
      @CUsage@w: rem @Y<originalstring>@w
        @Yoriginalstring@w    = The original string
    """
    tmsg = []
    if args['substitute']:
      tmsg.append("@GRemoving substitute@w : '%s'" % (args['substitute']))
      self.removesub(args['substitute'])
      return True, tmsg

    return False, tmsg

  def cmd_list(self, args):
    """
    @G%(name)s@w - @B%(cmdname)s@w
      List substitutes
      @CUsage@w: list
    """
    tmsg = self.listsubs(args['match'])
    return True, tmsg

  def cmd_clear(self, args):
    # pylint: disable=unused-argument
    """
    @G%(name)s@w - @B%(cmdname)s@w
      List substitutes
      @CUsage@w: list"""
    self.clearsubs()
    return True, ['Substitutes cleared']

  def addsub(self, item, sub):
    """
    internally add a substitute
    """
    self._substitutes[item] = {'sub':sub}
    self._substitutes.sync()

  def removesub(self, item):
    """
    internally remove a substitute
    """
    if item in self._substitutes:
      del self._substitutes[item]
      self._substitutes.sync()

  def listsubs(self, match):
    """
    return a table of strings that list subs
    """
    tmsg = []
    for item in self._substitutes:
      if not match or match in item:
        tmsg.append("%-35s : %s@w" % (item, self._substitutes[item]['sub']))
    if not tmsg:
      tmsg = ['None']
    return tmsg

  def clearsubs(self):
    """
    clear all subs
    """
    self._substitutes.clear()
    self._substitutes.sync()

  def reset(self):
    """
    reset the plugin
    """
    BasePlugin.reset(self)
    self.clearsubs()

  def _savestate(self, _=None):
    """
    save states
    """
    self._substitutes.sync()
Example #20
0
class Plugin(BasePlugin):
  """
  a plugin to handle global variables, if something goes through
   send.execute (this includes from the client), a variable
   can be specified with $varname and will be substituted.
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    BasePlugin.__init__(self, *args, **kwargs)

    self.variablefile = os.path.join(self.savedir, 'variables.txt')
    self._variables = PersistentDict(self.variablefile, 'c')
    self.api('api.add')('getv', self.api_getv)
    self.api('api.add')('setv', self.api_setv)
    self.api('api.add')('replace', self.api_replace)

  def load(self):
    """
    load the plugin
    """
    BasePlugin.load(self)

    parser = argp.ArgumentParser(add_help=False,
                                 description='add a variable')
    parser.add_argument('name',
                        help='the name of the variable',
                        default='',
                        nargs='?')
    parser.add_argument('value',
                        help='the value of the variable',
                        default='',
                        nargs='?')
    self.api('commands.add')('add',
                             self.cmd_add,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='remove a variable')
    parser.add_argument('name',
                        help='the variable to remove',
                        default='',
                        nargs='?')
    self.api('commands.add')('remove',
                             self.cmd_remove,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='list variables')
    parser.add_argument('match',
                        help='list only variables that have this argument in their name',
                        default='',
                        nargs='?')
    self.api('commands.add')('list',
                             self.cmd_list,
                             parser=parser)

    self.api('commands.default')('list')

    self.api('events.register')('io_execute_event',
                                self.checkline,
                                prio=99)
    self.api('events.register')('io_execute_event',
                                self.checkline,
                                prio=1)
    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)

  # get a variable
  def api_getv(self, varname):
    """  get the variable with a specified name
    @Yvarname@w  = the variable to get

    this function returns the value of variable with the name of the argument
    """
    if varname in self._variables:
      return self._variables[varname]

    return None

  # set a variable
  def api_setv(self, varname, value):
    """  set the variable with a specified name to the specified value
    @Yvarname@w  = the variable to set
    @Yvalue@w  = the value to set

    this function returns True if the value was set, False if an error was
    encountered
    """
    try:
      self._variables[varname] = value
      return True
    except Exception: # pylint: disable=broad-except
      return False

  # replace variables in data
  def api_replace(self, data):
    """replace the variables in data
    @Ydata@w  = the variable to get

    this function returns the data after variable substition
    """
    templ = Template(data)
    return templ.safe_substitute(self._variables)

  def checkline(self, args):
    """
    this function checks for variables in input
    """
    data = args['fromdata'].strip()

    datan = self.api('vars.replace')(data)

    if datan != data:
      if 'trace' in args:
        args['trace']['changes'].append({'flag':'Modify',
                                         'data':'changed "%s" to "%s"' % (data, datan),
                                         'plugin':self.sname})

      self.api('send.msg')('replacing "%s" with "%s"' % (data.strip(),
                                                         datan.strip()))
      args['fromdata'] = datan
      args['beforevar'] = data

    return args

  def cmd_add(self, args):
    """
    command to add a variable
    """
    tmsg = []
    if args['name'] and args['value']:
      tmsg.append("@GAdding variable@w : '%s' will be replaced by '%s'" % \
                                              (args['name'], args['value']))
      self.addvariable(args['name'], args['value'])
      return True, tmsg

    tmsg.append("@RPlease include all arguments@w")
    return False, tmsg

  def cmd_remove(self, args):
    """
    command to remove a variable
    """
    tmsg = []
    if args['name']:
      tmsg.append("@GRemoving variable@w : '%s'" % (args['name']))
      self.removevariable(args['name'])
      return True, tmsg

    return False, ['@RPlease specifiy a variable to remove@w']

  def cmd_list(self, args):
    """
    command to list variables
    """
    tmsg = self.listvariables(args['match'])
    return True, tmsg

  def addvariable(self, item, value):
    """
    internally add a variable
    """
    self._variables[item] = value
    self._variables.sync()

  def removevariable(self, item):
    """
    internally remove a variable
    """
    if item in self._variables:
      del self._variables[item]
      self._variables.sync()

  def listvariables(self, match):
    """
    return a table of variables
    """
    tmsg = []
    for item in self._variables:
      if not match or match in item:
        tmsg.append("%-20s : %s@w" % (item, self._variables[item]))
    if not tmsg:
      tmsg = ['None']
    return tmsg

  def clearvariables(self):
    """
    clear all variables
    """
    self._variables.clear()
    self._variables.sync()

  def reset(self):
    """
    reset the plugin
    """
    BasePlugin.reset(self)
    self.clearvariables()

  def _savestate(self, _=None):
    """
    save states
    """
    self._variables.sync()
Example #21
0
class Plugin(AardwolfBasePlugin):
    """
  a plugin to handle aardwolf cp events
  """
    def __init__(self, *args, **kwargs):
        """
    initialize the instance
    """
        AardwolfBasePlugin.__init__(self, *args, **kwargs)
        self.savecpfile = os.path.join(self.savedir, 'cp.txt')
        self.cpinfo = PersistentDict(self.savecpfile, 'c')
        self.mobsleft = []
        self.cpinfotimer = {}
        self.nextdeath = False

        self.cmdqueue = None

        self.api.get('dependency.add')('cmdq')

    def load(self):
        """
    load the plugins
    """
        AardwolfBasePlugin.load(self)

        self.cmdqueue = self.api.get('cmdq.baseclass')()(self)

        self.cmdqueue.addcmdtype('cpcheck',
                                 'campaign check',
                                 "^campaign check$",
                                 beforef=self.cpcheckbefore,
                                 afterf=self.cpcheckafter)

        parser = argparse.ArgumentParser(add_help=False,
                                         description='show cp info')
        self.api.get('commands.add')('show', self.cmd_show, parser=parser)

        parser = argparse.ArgumentParser(add_help=False,
                                         description='refresh cp info')
        self.api.get('commands.add')('refresh',
                                     self.cmd_refresh,
                                     parser=parser)

        self.api.get('watch.add')(
            'cp_check',
            '^(cp|campa|campai|campaig|campaign) (c|ch|che|chec|check)$')

        self.api.get('triggers.add')('cpnew',
          "^Commander Barcett tells you " \
            "'Type 'campaign info' to see what you must kill.'$")
        self.api.get('triggers.add')('cpnone',
                                     "^You are not currently on a campaign.$",
                                     enabled=False,
                                     group='cpcheck',
                                     omit=True)
        self.api.get('triggers.add')(
            'cptime',
            "^You have (?P<time>.*) to finish this campaign.$",
            enabled=False,
            group='cpcheck',
            omit=True)
        self.api.get('triggers.add')('cpmob',
          "^You still have to kill \* (?P<mob>.*) " \
                "\((?P<location>.*?)(?P<dead> - Dead|)\)$",
          enabled=False, group='cpcheck', omit=True)
        self.api.get('triggers.add')('cpscramble',
          "Note: One or more target names in this " \
                "campaign might be slightly scrambled.$",
          enabled=False, group='cpcheck', omit=True)
        self.api.get('triggers.add')('cpneedtolevel',
          "^You will have to level before you" \
                    " can go on another campaign.$",
          enabled=False,
          group='cpin')
        #Note: One or more target names in this campaign might be slightly scrambled.
        self.api.get('triggers.add')(
            'cpcantake',
            "^You may take a campaign at this level.$",
            enabled=False,
            group='cpin')
        self.api.get('triggers.add')(
            'cpshnext',
            "^You cannot take another campaign for (?P<time>.*).$",
            enabled=False,
            group='cpin')
        self.api.get('triggers.add')(
            'cpmobdead',
            "^Congratulations, that was one of your CAMPAIGN mobs!$",
            enabled=False,
            group='cpin')
        self.api.get('triggers.add')(
            'cpcomplete',
            "^CONGRATULATIONS! You have completed your campaign.$",
            enabled=False,
            group='cpin')
        self.api.get('triggers.add')('cpclear',
                                     "^Campaign cleared.$",
                                     enabled=False,
                                     group='cpin')
        self.api.get('triggers.add')(
            'cpreward',
            "^\s*Reward of (?P<amount>\d+) (?P<type>.+) .+ added.$",
            enabled=False,
            group='cprew',
            argtypes={
                'amount': int
            })
        self.api.get('triggers.add')('cpcompdone',
          "^--------------------------" \
                "------------------------------------$",
          enabled=False,
          group='cpdone')

        self.api.get('events.register')('trigger_cpnew', self._cpnew)
        self.api.get('events.register')('trigger_cpnone', self._cpnone)
        self.api.get('events.register')('trigger_cptime', self._cptime)
        #self.api.get('events.register')('watch_cp_check', self._cpcheckcmd)
        self.api.get('events.register')('trigger_cpmob', self._cpmob)
        self.api.get('events.register')('trigger_cpneedtolevel',
                                        self._cpneedtolevel)
        self.api.get('events.register')('trigger_cpcantake', self._cpcantake)
        self.api.get('events.register')('trigger_cpshnext', self._cpshnext)
        self.api.get('events.register')('trigger_cpmobdead', self._cpmobdead)
        self.api.get('events.register')('trigger_cpcomplete', self._cpcomplete)
        self.api.get('events.register')('trigger_cpclear', self._cpclear)
        self.api.get('events.register')('trigger_cpreward', self._cpreward)
        self.api.get('events.register')('trigger_cpcompdone', self._cpcompdone)

    def cmd_show(self, args):
        """
    show the cp mobs
    """
        msg = []
        if self.cpinfo['oncp']:
            msg.append('Mobs left:')
            msg.append('%-40s %s' % ('Mob Name', 'Area/Room'))
            msg.append('@G' + '-' * 60)
            for i in self.mobsleft:
                color = '@w'
                if i['mobdead']:
                    color = '@R'
                msg.append('%s%-40s %s' % (color, i['name'], i['location']))
        else:
            msg.append('You are not on a cp')

        return True, msg

    def cmd_refresh(self, args):
        """
    cmd to refresh cp info
    """
        msg = []
        if self.cpinfo['oncp']:
            msg.append('Refreshing cp mobs')
            self.cmdqueue.addtoqueue('cpcheck', '')
        else:
            msg.append('You are not on a cp')

        return True, msg

    def cpcheckbefore(self):
        """
    function to run before send the command
    """
        self.mobsleft = []
        self.cpinfotimer = {}
        self.api.get('triggers.togglegroup')('cpcheck', True)

    def cpcheckafter(self):
        """
    function to run after the command is finished
    """
        self.api.get('triggers.togglegroup')("cpin", True)
        self.api.get('triggers.togglegroup')('cpcheck', False)

    def afterfirstactive(self, _=None):
        """
    do something on connect
    """
        AardwolfBasePlugin.afterfirstactive(self)
        self.cmdqueue.addtoqueue('cpcheck', '')

    def _cpreset(self):
        """
    reset the cp
    """
        self.cpinfo.clear()
        self.cpinfo['mobs'] = {}
        self.cpinfo['trains'] = 0
        self.cpinfo['pracs'] = 0
        self.cpinfo['gold'] = 0
        self.cpinfo['tp'] = 0
        self.cpinfo['qp'] = 0
        self.cpinfo['bonusqp'] = 0
        self.cpinfo['failed'] = 0
        self.cpinfo['level'] = self.api.get('aardu.getactuallevel')(
            self.api.get('GMCP.getv')('char.status.level'))
        self.cpinfo['starttime'] = time.time()
        self.cpinfo['finishtime'] = 0
        self.cpinfo['oncp'] = True
        self.cpinfo['cantake'] = False
        self.cpinfo['shtime'] = None
        self.savestate()

    def _cpnew(self, args=None):
        """
    handle a new cp
    """
        self.api.get('send.msg')('cpnew: %s' % args)
        self._cpreset()
        self.cmdqueue.addtoqueue('cpcheck', '')

    def _cpnone(self, _=None):
        """
    handle a none cp
    """
        self.api.get('send.msg')('cpnone')
        self.cpinfo['oncp'] = False
        self.savestate()
        self.api.get('triggers.togglegroup')('cpcheck', False)
        self.api.get('triggers.togglegroup')('cpin', False)
        self.api.get('triggers.togglegroup')('cprew', False)
        self.api.get('triggers.togglegroup')('cpdone', False)
        #check(EnableTimer("cp_timer", false))
        self.cpinfotimer = {}
        self.cmdqueue.cmddone('cpcheck')

    def _cptime(self, _=None):
        """
    handle cp time
    """
        self.api.get('send.msg')('handling cp time')
        self.api.get('send.msg')('%s' % self.cpinfo)
        if not self.cpinfo['mobs']:
            self.api.get('send.msg')('copying mobsleft')
            self.cpinfo['mobs'] = self.mobsleft[:]
            self.api.get('events.eraise')('aard_cp_mobsorig',
                                          copy.deepcopy(
                                              {'mobsleft': self.mobsleft}))
            self.savestate()

        self.api.get('send.msg')('raising aard_cp_mobsleft %s' % self.mobsleft)
        self.api.get('events.eraise')('aard_cp_mobsleft',
                                      copy.deepcopy(
                                          {'mobsleft': self.mobsleft}))

        self.cmdqueue.cmddone('cpcheck')

    def _cpneedtolevel(self, _=None):
        """
    handle cpneedtolevel
    """
        self.cpinfo['cantake'] = False
        self.savestate()

    def _cpcantake(self, _=None):
        """
    handle cpcantake
    """
        self.cpinfo['cantake'] = True
        self.savestate()

    def _cpshnext(self, args=None):
        """
    handle cpshnext
    """
        self.cpinfo['shtime'] = args['time']
        self.savestate()

    def _cpmob(self, args=None):
        """
    handle cpmob
    """
        name = args['mob']
        mobdead = self.api.get('utils.verify')(args['dead'], bool)
        location = args['location']

        if not name or not location:
            self.api.get('send.msg')("error parsing line: %s" % args['line'])
        else:
            self.mobsleft.append({
                'name':
                name,
                'nocolorname':
                self.api.get('colors.stripansi')(name),
                'location':
                location,
                'mobdead':
                mobdead
            })

    def _cpmobdead(self, _=None):
        """
    handle cpmobdead
    """
        self.api.get('events.register')('aard_mobkill', self._mobkillevent)
        #self.api.get('send.execute')("cp check")

    def _cpcomplete(self, _=None):
        """
    handle cpcomplete
    """
        self.api.get('triggers.togglegroup')('cprew', True)
        self.cpinfo['finishtime'] = time.time()
        self.cpinfo['oncp'] = False
        self.savestate()

    def _cpreward(self, args=None):
        """
    handle cpreward
    """
        rtype = args['type']
        ramount = int(args['amount'])
        rewardt = self.api.get('aardu.rewardtable')()
        self.cpinfo[rewardt[rtype]] = ramount
        self.savestate()
        self.api.get('triggers.togglegroup')('cpdone', True)

    def _cpcompdone(self, _=None):
        """
    handle cpcompdone
    """
        self.api.get('events.register')('trigger_all', self._triggerall)

    def _triggerall(self, args=None):
        """
    check to see if we have the bonus qp message
    """
        if 'first campaign completed today' in args['line']:
            mat = re.match('^You receive (?P<bonus>\d*) quest points bonus ' \
                        'for your first campaign completed today.$', args['line'])
            self.cpinfo['bonusqp'] = int(mat.groupdict()['bonus'])
            self.api.get('events.unregister')('trigger_all', self._triggerall)
            self.api.get('events.eraise')('aard_cp_comp',
                                          copy.deepcopy(self.cpinfo))
        elif re.match("^You have completed (\d*) campaigns today.$",
                      args['line']):
            self.api.get('events.unregister')('trigger_all', self._triggerall)
            self.api.get('events.eraise')('aard_cp_comp',
                                          copy.deepcopy(self.cpinfo))

    def _cpclear(self, _=None):
        """
    handle cpclear
    """
        self.cpinfo['failed'] = 1
        self.api.get('events.eraise')('aard_cp_failed',
                                      copy.deepcopy(self.cpinfo))
        self._cpnone()

    def _cpcheckcmd(self, args=None):
        """
    handle when we get a cp check
    """
        self.mobsleft = []
        self.cpinfotimer = {}
        self.api.get('triggers.togglegroup')('cpcheck', True)
        return args

    def _mobkillevent(self, args):
        """
    this will be registered to the mobkill hook
    """
        self.api.get('send.msg')('checking kill %s' % args['name'])
        self.api.get('events.unregister')('aard_mobkill', self._mobkillevent)

        found = False
        removeitem = None
        for i in range(len(self.mobsleft)):
            tmob = self.mobsleft[i]
            if tmob['name'] == args['name']:
                self.api.get('send.msg')('found %s' % tmob['name'])
                found = True
                removeitem = i

        if removeitem:
            del (self.mobsleft[removeitem])

        if found:
            self.api.get('events.eraise')('aard_cp_mobsleft',
                                          copy.deepcopy(
                                              {'mobsleft': self.mobsleft}))
        else:
            self.api.get('send.msg')("BP CP: could not find mob: %s" %
                                     args['name'])
            self.cmdqueue.addtoqueue('cpcheck', '')

    def savestate(self):
        """
    save states
    """
        AardwolfBasePlugin.savestate(self)
        self.cpinfo.sync()
Example #22
0
class Plugin(AardwolfBasePlugin):
  """
  a plugin to handle aardwolf cp events
  """
  def __init__(self, *args, **kwargs):
    """
    initialize the instance
    """
    AardwolfBasePlugin.__init__(self, *args, **kwargs)
    self.savecpfile = os.path.join(self.savedir, 'cp.txt')
    self.cpinfo = PersistentDict(self.savecpfile, 'c')
    self.mobsleft = []
    self.cpinfotimer = {}
    self.nextdeath = False

    self.api('dependency.add')('cmdq')
    self.api('api.add')('oncp', self.api_oncp)
    self.api('api.add')('mobsleft', self.api_cpmobsleft)

  def load(self):
    """
    load the plugins
    """
    AardwolfBasePlugin.load(self)

    self.api('cmdq.addcmdtype')('cpcheck', 'campaign check', "^campaign check$",
                                beforef=self.cpcheckbefore, afterf=self.cpcheckafter)

    parser = argp.ArgumentParser(add_help=False,
                                 description='show cp info')
    self.api('commands.add')('show', self.cmd_show,
                             parser=parser)

    parser = argp.ArgumentParser(add_help=False,
                                 description='refresh cp info')
    self.api('commands.add')('refresh', self.cmd_refresh,
                             parser=parser)

    self.api('watch.add')('cp_check',
                          '^(cp|campa|campai|campaig|campaign) (c|ch|che|chec|check)$')

    self.api('triggers.add')('cpnew',
                             "^Commander Barcett tells you " \
                               "'Type 'campaign info' to see what you must kill.'$")
    self.api('triggers.add')('cpnone',
                             "^You are not currently on a campaign.$",
                             enabled=False, group='cpcheck', omit=True)
    self.api('triggers.add')('cptime',
                             "^You have (?P<time>.*) to finish this campaign.$",
                             enabled=False, group='cpcheck', omit=True)
    self.api('triggers.add')('cpmob',
                             r"^You still have to kill \* (?P<mob>.*) " \
                               r"\((?P<location>.*?)(?P<dead> - Dead|)\)$",
                             enabled=False, group='cpcheck', omit=True)
    self.api('triggers.add')('cpscramble',
                             "Note: One or more target names in this " \
                               "campaign might be slightly scrambled.$",
                             enabled=False, group='cpcheck', omit=True)
    self.api('triggers.add')('cpneedtolevel',
                             "^You will have to level before you" \
                               " can go on another campaign.$",
                             enabled=False,
                             group='cpin')
    self.api('triggers.add')('cpcantake',
                             "^You may take a campaign at this level.$",
                             enabled=False,
                             group='cpin')
    self.api('triggers.add')('cpshnext',
                             "^You cannot take another campaign for (?P<time>.*).$",
                             enabled=False,
                             group='cpin')
    self.api('triggers.add')('cpmobdead',
                             "^Congratulations, that was one of your CAMPAIGN mobs!$",
                             enabled=False,
                             group='cpin')
    self.api('triggers.add')('cpcomplete',
                             "^CONGRATULATIONS! You have completed your campaign.$",
                             enabled=False,
                             group='cpin')
    self.api('triggers.add')('cpclear',
                             "^Campaign cleared.$",
                             enabled=False,
                             group='cpin')
    self.api('triggers.add')('cpreward',
                             r"^\s*Reward of (?P<amount>\d+) (?P<type>.+) .+ added.$",
                             enabled=False,
                             group='cprew',
                             argtypes={'amount':int})
    self.api('triggers.add')('cpcompdone',
                             "^--------------------------" \
                               "------------------------------------$",
                             enabled=False,
                             group='cpdone')

    self.api('events.register')('trigger_cpnew', self._cpnew)
    self.api('events.register')('trigger_cpnone', self._cpnone)
    self.api('events.register')('trigger_cptime', self._cptime)
    #self.api('events.register')('watch_cp_check', self._cpcheckcmd)
    self.api('events.register')('trigger_cpmob', self._cpmob)
    self.api('events.register')('trigger_cpneedtolevel',
                                self._cpneedtolevel)
    self.api('events.register')('trigger_cpcantake', self._cpcantake)
    self.api('events.register')('trigger_cpshnext', self._cpshnext)
    self.api('events.register')('trigger_cpmobdead', self._cpmobdead)
    self.api('events.register')('trigger_cpcomplete', self._cpcomplete)
    self.api('events.register')('trigger_cpclear', self._cpclear)
    self.api('events.register')('trigger_cpreward', self._cpreward)
    self.api('events.register')('trigger_cpcompdone', self._cpcompdone)

    self.api('events.register')('plugin_%s_savestate' % self.sname, self._savestate)

  def api_oncp(self):
    """
    return if we are on a cp
    """
    return self.cpinfo['oncp']

  def api_cpmobsleft(self):
    """
    return the list of cp mobs left
    """
    return copy.copy(self.mobsleft)

  def cmd_show(self, _=None):
    """
    show the cp mobs
    """
    msg = []
    if self.cpinfo['oncp']:
      msg.append('Mobs left:')
      msg.append('%-40s %s' % ('Mob Name', 'Area/Room'))
      msg.append('@G' + '-' * 60)
      for i in self.mobsleft:
        color = '@w'
        if i['mobdead']:
          color = '@R'
        msg.append('%s%-40s %s' % (color, i['name'], i['location']))
    else:
      msg.append('You are not on a cp')

    return True, msg

  def cmd_refresh(self, _=None):
    """
    cmd to refresh cp info
    """
    msg = []
    if self.cpinfo['oncp']:
      msg.append('Refreshing cp mobs')
      self.api('cmdq.addtoqueue')('cpcheck', '')
    else:
      msg.append('You are not on a cp')

    return True, msg

  def cpcheckbefore(self):
    """
    function to run before send the command
    """
    self.mobsleft = []
    self.cpinfotimer = {}
    self.api('triggers.togglegroup')('cpcheck', True)
    self.api('cmdq.cmdstart')('cpcheck')

  def cpcheckafter(self):
    """
    function to run after the command is finished
    """
    self.api('triggers.togglegroup')("cpin", True)
    self.api('triggers.togglegroup')('cpcheck', False)

  def afterfirstactive(self, _=None):
    """
    do something on connect
    """
    AardwolfBasePlugin.afterfirstactive(self)
    self.api('cmdq.addtoqueue')('cpcheck', '')

  def _cpreset(self):
    """
    reset the cp
    """
    self.cpinfo.clear()
    self.cpinfo['mobs'] = {}
    self.cpinfo['trains'] = 0
    self.cpinfo['pracs'] = 0
    self.cpinfo['gold'] = 0
    self.cpinfo['tp'] = 0
    self.cpinfo['qp'] = 0
    self.cpinfo['bonusqp'] = 0
    self.cpinfo['failed'] = 0
    self.cpinfo['level'] = self.api('aardu.getactuallevel')(
        self.api('GMCP.getv')('char.status.level'))
    self.cpinfo['starttime'] = time.time()
    self.cpinfo['finishtime'] = 0
    self.cpinfo['oncp'] = True
    self.cpinfo['cantake'] = False
    self.cpinfo['shtime'] = None
    self.savestate()

  def _cpnew(self, args=None):
    """
    handle a new cp
    """
    self.api('send.msg')('cpnew: %s' % args)
    self._cpreset()
    self.api('cmdq.addtoqueue')('cpcheck', '')

  def _cpnone(self, _=None):
    """
    handle a none cp
    """
    self.api('send.msg')('cpnone')
    self.cpinfo['oncp'] = False
    self.savestate()
    self.api('triggers.togglegroup')('cpcheck', False)
    self.api('triggers.togglegroup')('cpin', False)
    self.api('triggers.togglegroup')('cprew', False)
    self.api('triggers.togglegroup')('cpdone', False)
    self.cpinfotimer = {}
    self.api('cmdq.cmdfinish')('cpcheck')

  def _cptime(self, _=None):
    """
    handle cp time
    """
    self.api('send.msg')('handling cp time')
    self.api('send.msg')('%s' % self.cpinfo)
    if not self.cpinfo['mobs']:
      self.api('send.msg')('copying mobsleft')
      self.cpinfo['mobs'] = self.mobsleft[:]
      self.api('events.eraise')('aard_cp_mobsorig',
                                copy.deepcopy({'mobsleft':self.mobsleft}))
      self.savestate()

    self.api('send.msg')('raising aard_cp_mobsleft %s' % self.mobsleft)
    self.api('events.eraise')('aard_cp_mobsleft',
                              copy.deepcopy({'mobsleft':self.mobsleft}))

    self.api('cmdq.cmdfinish')('cpcheck')

  def _cpneedtolevel(self, _=None):
    """
    handle cpneedtolevel
    """
    self.cpinfo['cantake'] = False
    self.savestate()

  def _cpcantake(self, _=None):
    """
    handle cpcantake
    """
    self.cpinfo['cantake'] = True
    self.savestate()

  def _cpshnext(self, args=None):
    """
    handle cpshnext
    """
    self.cpinfo['shtime'] = args['time']
    self.savestate()

  def _cpmob(self, args=None):
    """
    handle cpmob
    """
    name = args['mob']
    mobdead = self.api('utils.verify')(args['dead'], bool)
    location = args['location']

    if not name or not location:
      self.api('send.msg')("error parsing line: %s" % args['line'])
    else:
      self.mobsleft.append({'name':name,
                            'nocolorname':self.api('colors.stripansi')(name),
                            'location':location, 'mobdead':mobdead})

  def _cpmobdead(self, _=None):
    """
    handle cpmobdead
    """
    self.api('events.register')('aard_mobkill', self._mobkillevent)
    #self.api('send.execute')("cp check")

  def _cpcomplete(self, _=None):
    """
    handle cpcomplete
    """
    self.api('triggers.togglegroup')('cprew', True)
    self.cpinfo['finishtime'] = time.time()
    self.cpinfo['oncp'] = False
    self.savestate()

  def _cpreward(self, args=None):
    """
    handle cpreward
    """
    rtype = args['type']
    ramount = int(args['amount'])
    rewardt = self.api('aardu.rewardtable')()
    self.cpinfo[rewardt[rtype]] = ramount
    self.savestate()
    self.api('triggers.togglegroup')('cpdone', True)

  def _cpcompdone(self, _=None):
    """
    handle cpcompdone
    """
    self.api('events.register')('trigger_all', self._triggerall)

  def _triggerall(self, args=None):
    """
    check to see if we have the bonus qp message
    """
    if 'first campaign completed today' in args['line']:
      mat = re.match(r'^You receive (?P<bonus>\d*) quest points bonus ' \
                        r'for your first campaign completed today.$',
                     args['line'])
      self.cpinfo['bonusqp'] = int(mat.groupdict()['bonus'])
      self.api('events.unregister')('trigger_all', self._triggerall)
      self.api('events.eraise')('aard_cp_comp', copy.deepcopy(self.cpinfo))
    elif re.match(r"^You have completed (\d*) campaigns today.$", args['line']):
      self.api('events.unregister')('trigger_all', self._triggerall)
      self.api('events.eraise')('aard_cp_comp', copy.deepcopy(self.cpinfo))

  def _cpclear(self, _=None):
    """
    handle cpclear
    """
    self.cpinfo['failed'] = 1
    self.api('events.eraise')('aard_cp_failed', copy.deepcopy(self.cpinfo))
    self._cpnone()

  def _cpcheckcmd(self, args=None):
    """
    handle when we get a cp check
    """
    self.mobsleft = []
    self.cpinfotimer = {}
    self.api('triggers.togglegroup')('cpcheck', True)
    return args

  def _mobkillevent(self, args):
    """
    this will be registered to the mobkill hook
    """
    self.api('send.msg')('checking kill %s' % args['name'])
    self.api('events.unregister')('aard_mobkill', self._mobkillevent)

    found = False
    removeitem = None
    for i in range(len(self.mobsleft)):
      tmob = self.mobsleft[i]
      if tmob['name'] == args['name']:
        self.api('send.msg')('found %s' % tmob['name'])
        found = True
        removeitem = i

    if removeitem:
      del self.mobsleft[removeitem]

    if found:
      self.api('events.eraise')('aard_cp_mobsleft',
                                copy.deepcopy({'mobsleft':self.mobsleft}))
    else:
      self.api('send.msg')("BP CP: could not find mob: %s" % args['name'])
      self.api('cmdq.addtoqueue')('cpcheck', '')

  def _savestate(self, _=None):
    """
    save states
    """
    self.cpinfo.sync()