Ejemplo n.º 1
0
def join(bot, id, chans, *args):
    for chan in chans.split(','):
        yield sign('SOME_JOIN', bot, id, chan)
        if (id.nick.lower() == bot.nick.lower()):
            yield sign('SELF_JOIN', bot, chan)
        else:
            yield sign('OTHER_JOIN', bot, id, chan)
Ejemplo n.º 2
0
def h_command(bot, id, target, event, body, full_msg, action):
    bot.activity = False

    #=================================================================
    # (This should be in bridge.py.)
    s_event = ('SIMPLE', 'ACTION', event) if action else \
              ('SIMPLE',           event)
    no_echo = [False]
    replies = []
    def cmd_reply(rmsg=None, from_name=None, no_bridge=False, **kwds):
        if rmsg is not None or from_name is not None:
            if rmsg is None: rmsg = from_name(id.nick)
            replies.append(((bot, id, target, rmsg), kwds))
        no_echo[0] = no_echo[0] or no_bridge
    yield sign(s_event, bot, id.nick, target, body, cmd_reply)
    if not no_echo[0]:
        cmsg = ('* %s %s' if action else '<%s> %s') % (id.nick, full_msg)
        yield sign('IRC', bot, target, cmsg)
    for rargs, rkwds in replies:
        reply(*rargs, **rkwds)       
    #=================================================================
        
    if limit.mark_activity(bot, id, notify=target):
        return
    if action:
        event = ('ACTION', event)
    yield sign(event, bot, id, target, body, full_msg)
    if bot.activity: return
    yield sign('CMD_IGNORED', event, bot, id, target, body, full_msg)
Ejemplo n.º 3
0
def nick(bot, id, new_nick, *args):
    if id.nick.lower() == bot.nick.lower():
        yield sign('SELF_NICK', bot, new_nick)
        bot.nick = new_nick
    else:
        yield sign('OTHER_NICK', bot, id, new_nick)
    yield sign('SOME_NICK', bot, id, new_nick)
Ejemplo n.º 4
0
def h_general(bot, *args, **kwds):
    e, id = kwds['e'], kwds['a'](*args)
    for chan, names in track_channels.iteritems():
        if id and id.nick.lower() not in map(str.lower, names): continue
        eargs = args + (chan,)
        yield sign(e,            bot, *eargs)
        yield sign(e + '_FINAL', bot, *eargs)
Ejemplo n.º 5
0
def kicked(bot, op_id, chan, other_nick, msg=None, *args):
    yield sign('SOME_KICKED', bot, other_nick, op_id, chan, msg)
    if (other_nick.lower() == bot.nick.lower()):
        yield sign('SELF_KICKED', bot, chan, op_id, msg)
        yield sign('SELF_KICKED_FINAL', bot, chan, op_id, msg)
    else:
        yield sign('OTHER_KICKED', bot, other_nick, op_id, chan, msg)
        yield sign('OTHER_KICKED_FINAL', bot, other_nick, op_id, chan, msg)
Ejemplo n.º 6
0
def privmsg(bot, source, target, msg, *args):
    if target.lower() == bot.nick.lower(): target = None
    if isinstance(source, tuple):
        bot.activity = False
        yield sign('MESSAGE', bot, source, target, msg)
        if bot.activity: return
        yield sign('MESSAGE_IGNORED', bot, source, target, msg)
    elif isinstance(source, str):
        yield sign('SMESSAGE', bot, source, target, msg)
Ejemplo n.º 7
0
def part(bot, id, chans, msg=None, *args):
    for chan in chans.split(','):
        yield sign('SOME_PART', bot, id, chan, msg)
        if (id.nick.lower() == bot.nick.lower()):
            yield sign('SELF_PART', bot, chan, msg)
            yield sign('SELF_PART_FINAL', bot, chan, msg)
        else:
            yield sign('OTHER_PART', bot, id, chan, msg)
            yield sign('OTHER_PART_FINAL', bot, id, chan, msg)
Ejemplo n.º 8
0
def privmsg(bot, nick, user, host, target, msg, *args):
    #    msg = re.sub('^:', '', msg) # not needed since xirclib updated
    if target == bot.nick:
        target = None
    id = ID(nick, user, host)
    yield sign("MESSAGE", bot, id, target, msg)
    yield sign(("MESSAGE", target), bot, id, msg)
    match = re.match("(?P<cmd>!\S+)\s*(?P<arg>.*)$", msg)
    if match:
        cmd, arg = match.group("cmd", "arg")
        yield sign(cmd, bot, id, target, arg)
        yield sign((cmd, target), bot, id, arg)
Ejemplo n.º 9
0
def h_buffer(work, data):
    if work.terraria_protocol.version_number > 155:
        while len(data) > 2:
            length, type = struct.unpack('<hB', data[:3])
            if len(data) < length: break
            yield sign('MESSAGE', work, type, data[:length][3:])
            data = data[length:]
    else:
        while len(data) > 4:
            length, type = struct.unpack('<iB', data[:5])
            if len(data) < length + 4: break
            yield sign('MESSAGE', work, type, data[4:][1:length])
            data = data[4:][length:]
    work.stack = data
Ejemplo n.º 10
0
def h_url(bot, id, target, args, full_msg, reply):
    channel = (target or ('%s!%s@%s' % id)).lower()

    if args:
        dice = sys.modules.get('dice')
        match = re.match(r'!r(oll)?\s+(?P<args>.*)', args)
        if match and dice and bot in dice.link.installed_modes:
            args = match.group('args')
            args = dice.roll(bot, id, target, args, error_reply=reply)
            if args is None: return
            reply(args)

        urls = url_collect.extract_urls(args)
        yield sign('URL_CMD_URLS', bot, urls, target, id, full_msg)
    elif url_collect.history[channel]:
        urls = url_collect.history[channel].pop(-1)
    else:
        urls = None

    if not urls:
        reply('No URL found.')
        return

    for url in urls:
        try:
            result = get_title_proxy(url)
            reply(result['title'])

            # Generate a URL-suppressed proxy message for the basic component.
            btitle = result['title_bare']
            p_target = '%s!%s@%s' % id if target is None else target
            if isinstance(btitle, unicode):
                btitle = btitle.encode('utf-8')
            yield later(sign('PROXY_MSG', bot, None, p_target, btitle,
                             no_url=True))

            if result.get('proxy'):
                # Generate a quiet proxy message for the parenthetical component.
                pmsg, fmsg = result['proxy'], result['proxy_full']
                if isinstance(pmsg, unicode): pmsg = pmsg.encode('utf-8')
                if isinstance(fmsg, unicode): fmsg = fmsg.encode('utf-8')
                yield later(sign('PROXY_MSG', bot, None, p_target, pmsg,
                                 full_msg=fmsg, quiet=True, no_url=True))

            yield runtime.sleep(0.01)
        except Exception as e:
            traceback.print_exc()
            url, is_nsfw = url_collect.url_nsfw(url)
            reply('Error: %s [%s%s]' %
                (e, abbrev_url(url), ' \2NSFW\2' if is_nsfw else ''))
Ejemplo n.º 11
0
def h_help(bot, name, target, args, reply, bridge):
    lines = []
    callback = lambda *args: lines.append(args)

    def header(str):
        return '\2%s%s\2' % ('!' if bot.conf['bang_cmd'] else '', str)

    if args:
        # Display help for a particular command.
        cmd, args = re.match(r'!?(\S+)\s*(.*)', args).groups()
        cmd = cmd.lower()
        yield sign(('BRIDGE', 'HELP', cmd) if bridge else ('HELP', cmd),
            bot, callback, args)
        if not lines:
            reply('Error: no help is available for "%s".' % cmd, no_bridge=True)
            return
        for line in lines:
            if line[0]: reply(header(line[0]), prefix=False, no_bridge=True)
            for para in line[1:]:
                if para: reply(para, prefix=False, no_bridge=True)

    elif not bridge:
        # Display general help and a summary of all commands.
        reply(
            'Commands are issued by saying%s "%s: !COMMAND",'
            ' where COMMAND is the command and its parameters.'
            ' The following commands are available:'
            % (' "!COMMAND" or' if bot.conf['bang_cmd'] else '', bot.nick),
            prefix=False, no_bridge=True)

        yield sign('HELP*', bot, callback, args)
        lines = map(lambda l: (header(l[0]),) + l[1:], lines)
        for line in util.align_table(lines):
            reply(line, prefix=False, no_bridge=True)

        del lines[:]
        yield sign('HELP', bot, callback, args)
        if lines: reply('Other commands: %s.' % ', '.join(
            '\2%s\2' % l[0].split()[0] for l in lines),
            prefix=False, no_bridge=True)

    else:
        yield sign(('BRIDGE', 'HELP*'), bot, callback, args)
        yield sign(('BRIDGE', 'HELP'), bot, callback, args)
        if lines:
            reply('Available commands: %s.' % ', '.join(
                '\2%s\2' % l[0].split()[0] for l in lines),
                prefix=False, no_bridge=True)
Ejemplo n.º 12
0
def te_chat(work, slot, colour, text):
    no_echo = [False]
    echo_lines = []
    event_type = None
    agent = work.terraria.user

    if slot == 255:
        match = re.match(r'((?P<sn>\[\S+\])|\*(?P<an>\S+))\s*(?P<m>.*)', text)
        if match:
            event_type = 'MESSAGE' if match.group('sn') else 'ACTION'
            event_name = match.group('sn') or match.group('an')
            event_text = match.group('m')
    else:
        event_type = 'MESSAGE'
        event_name = work.terraria_protocol.players.get(slot, slot)
        event_text = text

    if event_type is not None:
        reply = bridge.substitute_reply(
            context       = work.terraria.name,
            local_name    = event_name,
            msg_local     = lambda m: terraria_protocol.chat(work, strip_codes(m)),
            msg_bridge    = lambda m: echo_lines.append('<%s> %s' % (agent, m)),
            cancel_bridge = lambda: operator.setitem(no_echo, 0, True))
        yield util.msign(ab_mode, ('BRIDGE', event_type), ab_mode,
            event_name, work.terraria.name, event_text, reply)

    if not no_echo[0] and slot != work.terraria_protocol.slot:
        if slot != 255:
            text = '<%s> %s' % (name, text)
        echo_lines.insert(0, text)

    for line in echo_lines:
        line = bridge.substitute_text(work.terraria.name, line)
        yield sign('TERRARIA', work, line)
Ejemplo n.º 13
0
def message(bot, id, target, msg):
    while True:
        match = re.match(r'\x01ACTION (.*?)\x01?$', msg)
        if match:
            msg = match.group(1)
            action = True
        else:
            action = False

        # !CMD [ARGS...]
        if bot.conf['bang_cmd']:
            match = re.match(r'!(?P<head>\S*)\s*(?P<body>.*)', msg)
            if match: break

        # NICK: !CMD [ARGS...]
        match = re.match(r'(?P<addr>\S+):\s*!(?P<head>\S*)\s*(?P<body>.*)', msg)
        if match and match.group('addr').lower() == bot.nick.lower(): break

        return
    
    event = '!' + match.group('head').lower()
    body = match.group('body').strip()
    type = 'ACTION_COMMAND' if action else 'COMMAND'
    yield sign(type, bot, id, target, event, body, msg)
    bot.activity = True

    from untwisted.usual import Stop
    raise Stop
Ejemplo n.º 14
0
    def refresh(self, bot):
        try:
            quotes, title = self.quotes_title()
            url_state = state.get(self.index_url, {})
            chan_state = url_state.get(self.channel.lower(), {})
            last_quote = chan_state.get('last_quote')

            quotes = sorted(
                (qid, quote) for (qid, quote) in quotes if qid > last_quote)
            sample = quotes if len(quotes) <= MAX_REPORT else \
                     quotes[:MAX_REPORT-1]
            for qid, quote in sample:
                quote_url = '%s?%s' % (self.remote_index_url, qid)
                fquote = format_quote(quote)
                msg = '%s: new quote added: %s "%s"' % (title, quote_url, fquote)
                bot.send_msg(self.channel, msg)
                yield later(sign('PROXY_MSG', bot, None, self.channel, fquote,
                                 quiet=True))

            if len(quotes) > len(sample):
                msg = '%s: ...and %d others. See: <%s>.' % (
                    title, len(quotes)-len(sample), self.remote_index_url)
                bot.send_msg(self.channel, msg)

            if quotes:
                last_quote = max(
                    last_quote, max(qid for (qid, quote) in quotes))
                chan_state['last_quote'] = last_quote
                url_state[self.channel.lower()] = chan_state
                state[self.index_url] = url_state
                write_state(state)
        except:
            traceback.print_exc()
Ejemplo n.º 15
0
    def refresh(self, bot):
        try:
            quotes = self.quotes()
            if not quotes: return

            url_state = state.get(self.admin_url, {})
            name_state = url_state.get(self.access_name.lower(), {})
            last_quote = name_state.get('last_quote')
    
            nicks = yield identity.enum_access(bot, self.access_name)
            if not nicks: return

            for nick in nicks:
                for qid, quote in sorted(quotes):
                    if qid > last_quote:
                        fquote = format_quote(quote)
                        msg = '[QdbS] New quote #%d <%s>: "%s"' % (
                            qid, self.remote_admin_url, fquote)
                        if type(msg) is unicode:
                            msg = msg.encode('utf8')
                        bot.send_msg(nick, msg)
                        hm = yield identity.get_hostmask(bot, nick)
                        yield later(sign('PROXY_MSG', bot, None, hm, fquote, quiet=True))
    
            last_quote = max(
                last_quote, max(qid for (qid, quote) in quotes))
            name_state['last_quote'] = last_quote
            url_state[self.access_name.lower()] = name_state
            state[self.admin_url] = url_state
            write_state(state)
        except:
            traceback.print_exc()
Ejemplo n.º 16
0
def h_bridge(bot, target_chan, msg, source, no_proxy=False, **kwds):
    if not target_chan.startswith('#'): return
    bot.send_msg(target_chan, msg, no_bridge=True)
    if isinstance(msg, unicode): msg = msg.encode('utf-8')
    if not no_proxy:
        yield later(sign('PROXY_MSG', bot, None, target_chan, msg,
                         no_auto = source.startswith('#')))
Ejemplo n.º 17
0
def h_names(bot, chan, include_prefix):
    if chan.lower() in track_channels and chan.lower() in umode_channels:
        # Return the cached names if they exist.
        nicks = track_channels[chan.lower()]
        umode = umode_channels[chan.lower()]
    else:
        # Otherwise, retrieves the names from the server.
        bot.send_cmd('NAMES %s' % chan)
        while True:
            event, data = yield hold(bot, 'NAMES_SYNC')
            e_bot, e_chan, nicks, umode = data
            if e_chan.lower() == chan.lower(): break
    # Reconstruct the nick prefixes from the nicks and their modes.
    pre_ms, pre_cs = bot.isupport['PREFIX']
    names = []
    for nick in nicks:
        for pre_m, pre_c in izip(pre_ms, pre_cs):
            if pre_m in umode.get(nick.lower(), ''):
                prefix, sort_key = pre_c, (-pre_cs.index(pre_c), nick.lower())
                break
        else:
            prefix, sort_key = '', (None, nick.lower())
        names.append((sort_key, prefix+nick if include_prefix else nick))
    names = [n for (_,n) in sorted(names, reverse=True)]
    yield sign(('channel.names', bot, chan, include_prefix), names)
Ejemplo n.º 18
0
def h_names(bot, chan, new_names):
    chan = chan.lower()
    track_names = track_channels[chan]
    umode_names = umode_channels[chan]

    pre_ms, pre_cs = bot.isupport['PREFIX']
    for prefix, nick in (split_name(bot,n) for n in new_names):
        # Update track_channels
        if nick.lower() not in map(str.lower, track_names):
            track_names.append(nick)
        elif nick not in track_names:
            track_names = [n for n in track_names if n.lower() != nick.lower()]
            track_names.append(nick)

        # Update umode_channels
        if len(prefix)==1 and nick.lower() in umode_names and prefix in pre_cs:
            # Add the mode and remove all known higher modes.
            i = pre_cs.index(prefix)
            umode_names[nick.lower()] = pre_ms[i] + ''.join(
                m for m in umode_names[nick.lower()] if m not in pre_ms[:i])
        else:
            # Set to exactly the given modes.
            umode_names[nick.lower()] = ''.join(
                m for c in prefix if c in pre_cs
                  for i in [pre_cs.index(c)]
                  for m in pre_ms[i:i+1])

    track_channels[chan] = track_names
    umode_channels[chan] = umode_names
    yield sign('NAMES_SYNC', bot, chan, track_names, umode_names)
Ejemplo n.º 19
0
def h_message(work, head, body):
    if head == 0x02:
        yield sign('DISCONNECT', work, body)
    elif head == 0x03:
        slot, = struct.unpack('<B', body[:1])
        yield sign('CONNECTION_APPROVED', work, slot)
    elif head == 0x04:
        slot, = struct.unpack('<B', body[:1])
        if work.terraria_protocol.version_number < 156:
            name = body[25:]
        else:
            name = unpack_string(work, body[3:])
        yield sign('PLAYER_APPEARANCE', work, slot, name)
    elif head == 0x09:
        count, = struct.unpack('<i', body[:4])
        text = unpack_string(work, body[4:])
        yield sign('STATUSBAR_TEXT', work, count, text)
    elif head == 0x0E:
        slot, active = struct.unpack('<B?', body)
        yield sign('SET_PLAYER_ACTIVITY', work, slot, active)
#    elif head == 0x0D:
#        slot, cflags, islot, x,y, dx,dy, flags \
#            = struct.unpack('<BBBffffB', body)
#        yield sign('PLAYER_CONTROL', work, slot, (x, y))
    elif head == 0x19:
        slot, = struct.unpack('<B', body[:1])
        colour = struct.unpack('<BBB', body[1:4])
        text = unpack_string(work, body[4:])
        yield sign('CHAT', work, slot, colour, text)
    elif head == 0x31:
        yield sign('SPAWN', work)
    elif head == 0x07:
        if work.terraria_protocol.version_number < 69:
            spawn = struct.unpack('<ii', body[15:23])
            world_name = body[36:]
        elif work.terraria_protocol.version_number < 156:
            spawn = struct.unpack('<ii', body[16:24])
            world_name = body[91:]
        else:
            spawn = struct.unpack('<hh', body[10:14])
            world_name = unpack_string(work, body[22:])
        yield sign('WORLD_INFORMATION', work, spawn, world_name)
    elif head == 0x25:
        yield sign('REQUEST_PASSWORD', work)
    elif head not in (0x0a, 0x14, 0x17, 0x1a, 0x1b, 0x1c, 0x1d):
        yield sign('UNKNOWN', work, '$%02X' % head, body)
Ejemplo n.º 20
0
def kakasi(bot, id, target, msg, prefix=True, auto=False, **kwds):
    if auto and not kakasi_lib.is_ja(msg): return
    raw_reply = kakasi_lib.kakasi(msg)
    if auto and len(raw_reply) > 200: return
    reply = ('<%s> %s' % (id.nick, raw_reply)) if prefix and id else raw_reply
    bot.send_msg(target, reply)
    bot.drive('runtime.later', sign(
        'PROXY_MSG', bot, id, target, raw_reply, **dict(kwds, no_kakasi=True)))
Ejemplo n.º 21
0
def h_msg(bot, source, msg, source_name=None):
    if source is None:
        return
    if type(msg) is unicode:
        msg = msg.encode('utf8')
    for source, target in targets(source):
        name = source_name or source
        yield sign('BRIDGE', bot, target, '%s: %s' % (name, msg))
Ejemplo n.º 22
0
def nickserv_notice(bot, id, msg):
    if conf('prompt') and conf('password') and msg.startswith(conf('prompt')):
        bot.send_msg(id.nick, 'IDENTIFY %s' % conf('password'))
        return
    final = conf('final')
    if final and msg.startswith(final):
        yield sign('NICKSERV_REGISTERED', bot)
        return
Ejemplo n.º 23
0
def tick(bot):
    global ping_sent
    elapsed = time.time() - last_ping
    if elapsed > bot.conf['timeout']/2 and not ping_sent:
        bot.dump('PING :%s\r\n' % bot.nick)
        ping_sent = True
    elif elapsed > bot.conf['timeout']:
        print '! ping timeout: %ss' % elapsed
        yield sign(CLOSE, bot)
Ejemplo n.º 24
0
def h_message(*args, **kwds):
    bot, nick, chan, msg = kwds['a'](*args)
    if chan is None: return
    match = re.match(r'\x01ACTION (?P<msg>.*)', msg)
    if match:
        cmsg = '* %s %s' % (nick, match.group('msg'))
    else:
        cmsg = '<%s> %s' % (nick, msg)
    yield sign('IRC', bot, chan, cmsg)
Ejemplo n.º 25
0
def notice(bot, id, target, msg):
    if target is not None: return
    if not conf('nickserv'): return
    nickserv = conf('nickserv')
    if id.nick.lower() != nickserv.nick.lower(): return
    if (id.user, id.host) != (nickserv.user, nickserv.host):
        raise Exception('%s is %s@%s; %s@%s expected.'
            % (id.nick, id.user, id.host, nickserv.user, nickserv.host))
    yield sign('NICKSERV_NOTICE', bot, id, msg)
Ejemplo n.º 26
0
 def further_fun(bot, id, target, args, full_msg):
     match = re.search(r'(?P<cmd>!\S+)\s*(?P<args>.*)', args)
     if match:
         scmd = match.group('cmd')
         sargs = match.group('args')
         args = args[:match.start()]
         cont = sign('COMMAND', bot, id, target, scmd, sargs, full_msg)
         return func(bot, id, target, args, full_msg, cont)
     else:
         return func(bot, id, target, args, full_msg, lambda *args: None)
Ejemplo n.º 27
0
def examine_message(bot, id, source, message, full_msg=None):
    if isinstance(source, tuple): source = '%s!%s@%s' % source
    source = source.lower()
    urls = extract_urls(message, full_msg=full_msg)
    if not urls: return

    history[source].append(urls)
    del history[source][:-HISTORY_SIZE]

    yield sign('URL_COLLECT_URLS', bot, urls, source, id, message)
Ejemplo n.º 28
0
 def further_fun(bot, id, target, args, full_msg):
     match = re.search(r'(^|(?<=\s))(?P<cmd>!\S+)\s*(?P<args>.*)', args)
     if match:
         scmd = match.group('cmd').lower()
         if scmd in bot._base or ('SIMPLE', scmd) in bot._base:
             sargs = match.group('args')
             args = args[:match.start()]
             cont = sign('COMMAND', bot, id, target, scmd, sargs, full_msg)
             return func(bot, id, target, args, full_msg, cont)
     return func(bot, id, target, args, full_msg, lambda *args: None)
Ejemplo n.º 29
0
def h_spawn(work):
    if not hasattr(work, 'terraria_protocol'): return
    if work.terraria_protocol.stage != 2: return
    work.terraria_protocol.stage = 3
    spawn = (0, 9999)
    send_spawn_player(work, work.terraria_protocol.slot, *spawn)
    for text in work.terraria_protocol.chat_queue:
        chat(work, text)
    work.terraria_protocol.chat_queue = []
    yield sign('HEARTBEAT', work)
Ejemplo n.º 30
0
def h_message(*args, **kwds):
    bot, nick, id, chan, msg = kwds['a'](*args)
    if not chan or chan.lower() not in links: return
    chan = channel.capitalisation.get(chan.lower(), chan)
    p_nick = channel.prefix_nick(bot, nick, chan)
    match = re.match(r'\x01ACTION (?P<act>.*?)\x01?$', msg)
    msg = '%s: * %s %s' % (chan, nick, match.group('act')) if match else \
          '%s: <%s> %s' % (chan, p_nick, msg)
    for lchan in links[chan.lower()]:
        bot.send_msg(lchan, msg, no_link=True)
        if id is not None:
            yield sign('PROXY_MSG', bot, id, lchan, msg, no_link=True)