コード例 #1
0
ファイル: hooks.py プロジェクト: mweinelt/lykos
def on_chghost(cli, rawnick, ident, host):
    """Handle a user changing host without a quit.

    Ordering and meaning of arguments for CHGHOST:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user switching
    2 - The new ident for the user (or same if unchanged)
    3 - The new host for the user (or same if unchanged)

    """

    user = users._get(rawnick)  # FIXME
    new = users._add(cli,
                     nick=user.nick,
                     ident=ident,
                     host=host,
                     realname=user.realname,
                     account=user.account)  # FIXME

    if user is not new:
        new.channels = user.channels.copy()
        new.timestamp = user.timestamp  # We lie, but it's ok
        for chan in set(user.channels):
            chan.remove_user(user)
            chan.users.add(new)
        user.swap(new)
コード例 #2
0
ファイル: hooks.py プロジェクト: TechnicianLP/lykos
def mode_change(cli, rawnick, chan, mode, *targets):
    """Update the channel and user modes whenever a mode change occurs.

    Ordering and meaning of arguments for a MODE change:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick of the mode setter/actor
    2 - The channel (target) of the mode change
    3 - The mode changes
    * - The targets of the modes (if any)

    This takes care of properly updating all relevant users and the
    channel modes to make sure we remain internally consistent.

    """

    actor = users._add(cli, nick=rawnick)  # FIXME
    if chan == users.Bot.nick:  # we only see user modes set to ourselves
        users.Bot.modes.update(mode)
        return

    target = channels.add(chan, cli)
    target.queue("mode_change", {
        "mode": mode,
        "targets": targets
    }, (var, actor, target))
コード例 #3
0
ファイル: hooks.py プロジェクト: TechnicianLP/lykos
def kicked_from_chan(cli, rawnick, chan, target, reason):
    """Handle a user being kicked from a channel.

    Ordering and meaning of arguments for a channel KICK:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user performing the kick
    2 - The channel the kick was performed on
    3 - The target of the kick
    4 - The reason given for the kick (always present)

    """

    ch = channels.add(chan, cli)
    actor = users._add(cli, nick=rawnick)  # FIXME
    user = users._add(cli, nick=target)  # FIXME
    Event("chan_kick", {}).dispatch(var, ch, actor, user, reason)

    if user is users.Bot:
        ch._clear()
    else:
        ch.remove_user(user)
コード例 #4
0
ファイル: hooks.py プロジェクト: lykoss/lykos
def who_reply(cli, bot_server, bot_nick, chan, ident, host, server, nick, status, hopcount_gecos):
    """Handle WHO replies for servers without WHOX support.

    Ordering and meaning of arguments for a bare WHO response:

    0 - The IRCClient instance (like everywhere else)
    1 - The server the requester (i.e. the bot) is on
    2 - The nickname of the requester (i.e. the bot)
    3 - The channel the request was made on
    4 - The ident of the user in this reply
    5 - The hostname of the user in this reply
    6 - The server the user in this reply is on
    7 - The nickname of the user in this reply
    8 - The status (H = Not away, G = Away, * = IRC operator, @ = Opped in the channel in 4, + = Voiced in the channel in 4)
    9 - The hop count and realname (gecos)

    This fires off the "who_result" event, and dispatches it with three
    arguments, the game state namespace, a Channel, and a User. Less
    important attributes can be accessed via the event.params namespace.

    """

    hop, realname = hopcount_gecos.split(" ", 1)
    hop = int(hop)
    # We throw away the information about the operness of the user, but we probably don't need to care about that
    # We also don't directly pass which modes they have, since that's already on the channel/user
    is_away = ("G" in status)

    modes = {Features["PREFIX"].get(s) for s in status} - {None}

    user = users._add(cli, nick=nick, ident=ident, host=host, realname=realname) # FIXME
    ch = None
    if not channels.predicate(chan): # returns True if it's not a channel
        ch = channels.add(chan, cli)

        if ch not in user.channels:
            user.channels[ch] = modes
            ch.users.add(user)
            for mode in modes:
                if mode not in ch.modes:
                    ch.modes[mode] = set()
                ch.modes[mode].add(user)

    event = Event("who_result", {}, away=is_away, data=0, ip_address=None, server=server, hop_count=hop, idle_time=None, extended_who=False)
    event.dispatch(var, ch, user)

    if ch is channels.Main and not users.exists(nick): # FIXME
        users.add(nick, ident=ident, host=host, account="*", inchan=True, modes=modes, moded=set())
コード例 #5
0
ファイル: hooks.py プロジェクト: TechnicianLP/lykos
def on_account_change(cli, rawnick, account):
    """Handle a user changing accounts, if enabled.

    Ordering and meaning of arguments for an ACCOUNT change:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user changing accounts
    2 - The account the user changed to

    We don't see our own account changes, so be careful!

    """

    user = users._add(cli, nick=rawnick)  # FIXME
    user.account = account  # We don't pass it to add(), since we want to grab the existing one (if any)

    Event("account_change", {}).dispatch(var, user)
コード例 #6
0
ファイル: hooks.py プロジェクト: TechnicianLP/lykos
def on_quit(cli, rawnick, reason):
    """Handle a user quitting the IRC server.

    Ordering and meaning of arguments for a server QUIT:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user quitting
    2 - The reason for the quit (always present)

    """

    user = users._add(cli, nick=rawnick)  # FIXME
    Event("server_quit", {}).dispatch(var, user, reason)

    for chan in set(user.channels):
        if user is users.Bot:
            chan._clear()
        else:
            chan.remove_user(user)
コード例 #7
0
ファイル: hooks.py プロジェクト: mweinelt/lykos
def join_chan(cli, rawnick, chan, account=None, realname=None):
    """Handle a user joining a channel, which may be the bot itself.

    Ordering and meaning of arguments for a channel JOIN:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user joining the channel
    2 - The channel the user joined

    The following two arguments are optional and only present if the
    server supports the extended-join capability (we will have requested
    it when we connected if it was supported):

    3 - The account the user is identified to, or "*" if none
    4 - The realname (gecos) of the user, or "" if none

    """

    if account == "*":
        account = None

    if realname == "":
        realname = None

    ch = channels.add(chan, cli)
    ch.state = channels._States.Joined

    user = users._add(cli, nick=rawnick, realname=realname,
                      account=account)  # FIXME
    ch.users.add(user)
    user.channels[ch] = set()
    # mark the user as here, in case they used to be connected before but left
    user.disconnected = False

    if user is users.Bot:
        ch.mode()
        ch.mode(Features["CHANMODES"][0])
        ch.who()

    Event("chan_join", {}).dispatch(var, ch, user)
コード例 #8
0
ファイル: hooks.py プロジェクト: lykoss/lykos
def on_chghost(cli, rawnick, ident, host):
    """Handle a user changing host without a quit.

    Ordering and meaning of arguments for CHGHOST:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user switching
    2 - The new ident for the user (or same if unchanged)
    3 - The new host for the user (or same if unchanged)

    """

    user = users._get(rawnick) # FIXME
    new = users._add(cli, nick=user.nick, ident=ident, host=host, realname=user.realname, account=user.account) # FIXME

    if user is not new:
        new.channels = user.channels.copy()
        new.timestamp = user.timestamp # We lie, but it's ok
        for chan in set(user.channels):
            chan.remove_user(user)
            chan.users.add(new)
        user.swap(new)
コード例 #9
0
ファイル: hooks.py プロジェクト: lykoss/lykos
def join_chan(cli, rawnick, chan, account=None, realname=None):
    """Handle a user joining a channel, which may be the bot itself.

    Ordering and meaning of arguments for a channel JOIN:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user joining the channel
    2 - The channel the user joined

    The following two arguments are optional and only present if the
    server supports the extended-join capability (we will have requested
    it when we connected if it was supported):

    3 - The account the user is identified to, or "*" if none
    4 - The realname (gecos) of the user, or "" if none

    """

    if account == "*":
        account = None

    if realname == "":
        realname = None

    ch = channels.add(chan, cli)
    ch.state = channels._States.Joined

    user = users._add(cli, nick=rawnick, realname=realname, account=account) # FIXME
    ch.users.add(user)
    user.channels[ch] = set()
    # mark the user as here, in case they used to be connected before but left
    user.disconnected = False

    if user is users.Bot:
        ch.mode()
        ch.mode(Features["CHANMODES"][0])
        ch.who()

    Event("chan_join", {}).dispatch(var, ch, user)
コード例 #10
0
ファイル: hooks.py プロジェクト: TechnicianLP/lykos
def part_chan(cli, rawnick, chan, reason=""):
    """Handle a user leaving a channel, which may be the bot itself.

    Ordering and meaning of arguments for a channel PART:

    0 - The IRCClient instance (like everywhere else)
    1 - The raw nick (nick!ident@host) of the user leaving the channel
    2 - The channel being left

    The following argument may or may not be present:

    3 - The reason the user gave for parting (if any)

    """

    ch = channels.add(chan, cli)
    user = users._add(cli, nick=rawnick)  # FIXME
    Event("chan_part", {}).dispatch(var, ch, user, reason)

    if user is users.Bot:  # oh snap! we're no longer in the channel!
        ch._clear()
    else:
        ch.remove_user(user)
コード例 #11
0
ファイル: hooks.py プロジェクト: mweinelt/lykos
def extended_who_reply(cli, bot_server, bot_nick, data, chan, ident,
                       ip_address, host, server, nick, status, hop, idle,
                       account, realname):
    """Handle WHOX responses for servers that support it.

    An extended WHO (WHOX) is caracterised by a second parameter to the request
    That parameter must be '%' followed by at least one of 'tcuihsnfdlar'
    If the 't' specifier is present, the specifiers must be followed by a comma and at most 3 bytes
    This is the ordering if all parameters are present, but not all of them are required
    If a parameter depends on a specifier, it will be stated at the front
    If a specifier is not given, the parameter will be omitted in the reply

    Ordering and meaning of arguments for an extended WHO (WHOX) response:

    0  -   - The IRCClient instance (like everywhere else)
    1  -   - The server the requester (i.e. the bot) is on
    2  -   - The nickname of the requester (i.e. the bot)
    3  - t - The data sent alongside the request
    4  - c - The channel the request was made on
    5  - u - The ident of the user in this reply
    6  - i - The IP address of the user in this reply
    7  - h - The hostname of the user in this reply
    8  - s - The server the user in this reply is on
    9  - n - The nickname of the user in this reply
    10 - f - Status (H = Not away, G = Away, * = IRC operator, @ = Opped in the channel in 5, + = Voiced in the channel in 5)
    11 - d - The hop count
    12 - l - The idle time (or 0 for users on other servers)
    13 - a - The services account name (or 0 if none/not logged in)
    14 - r - The realname (gecos)

    This fires off the "who_result" event, and dispatches it with three
    arguments, the game state namespace, a Channel, and a User. Less
    important attributes can be accessed via the event.params namespace.

    """

    if account == "0":
        account = None

    hop = int(hop)
    idle = int(idle)
    is_away = ("G" in status)

    data = int.from_bytes(data.encode(Features["CHARSET"]), "little")

    modes = {Features["PREFIX"].get(s) for s in status} - {None}

    user = users._add(cli,
                      nick=nick,
                      ident=ident,
                      host=host,
                      realname=realname,
                      account=account)  # FIXME

    ch = None
    if not channels.predicate(chan):
        ch = channels.add(chan, cli)
        if ch not in user.channels:
            user.channels[ch] = modes
            ch.users.add(user)
            for mode in modes:
                if mode not in ch.modes:
                    ch.modes[mode] = set()
                ch.modes[mode].add(user)

    event = Event("who_result", {},
                  away=is_away,
                  data=data,
                  ip_address=ip_address,
                  server=server,
                  hop_count=hop,
                  idle_time=idle,
                  extended_who=True)
    event.dispatch(var, ch, user)

    if ch is channels.Main and not users.exists(nick):  # FIXME
        users.add(nick,
                  ident=ident,
                  host=host,
                  account=account,
                  inchan=True,
                  modes=modes,
                  moded=set())
コード例 #12
0
ファイル: hooks.py プロジェクト: mweinelt/lykos
def who_reply(cli, bot_server, bot_nick, chan, ident, host, server, nick,
              status, hopcount_gecos):
    """Handle WHO replies for servers without WHOX support.

    Ordering and meaning of arguments for a bare WHO response:

    0 - The IRCClient instance (like everywhere else)
    1 - The server the requester (i.e. the bot) is on
    2 - The nickname of the requester (i.e. the bot)
    3 - The channel the request was made on
    4 - The ident of the user in this reply
    5 - The hostname of the user in this reply
    6 - The server the user in this reply is on
    7 - The nickname of the user in this reply
    8 - The status (H = Not away, G = Away, * = IRC operator, @ = Opped in the channel in 4, + = Voiced in the channel in 4)
    9 - The hop count and realname (gecos)

    This fires off the "who_result" event, and dispatches it with three
    arguments, the game state namespace, a Channel, and a User. Less
    important attributes can be accessed via the event.params namespace.

    """

    hop, realname = hopcount_gecos.split(" ", 1)
    hop = int(hop)
    # We throw away the information about the operness of the user, but we probably don't need to care about that
    # We also don't directly pass which modes they have, since that's already on the channel/user
    is_away = ("G" in status)

    modes = {Features["PREFIX"].get(s) for s in status} - {None}

    user = users._add(cli,
                      nick=nick,
                      ident=ident,
                      host=host,
                      realname=realname)  # FIXME
    ch = None
    if not channels.predicate(chan):  # returns True if it's not a channel
        ch = channels.add(chan, cli)

        if ch not in user.channels:
            user.channels[ch] = modes
            ch.users.add(user)
            for mode in modes:
                if mode not in ch.modes:
                    ch.modes[mode] = set()
                ch.modes[mode].add(user)

    event = Event("who_result", {},
                  away=is_away,
                  data=0,
                  ip_address=None,
                  server=server,
                  hop_count=hop,
                  idle_time=None,
                  extended_who=False)
    event.dispatch(var, ch, user)

    if ch is channels.Main and not users.exists(nick):  # FIXME
        users.add(nick,
                  ident=ident,
                  host=host,
                  account="*",
                  inchan=True,
                  modes=modes,
                  moded=set())
コード例 #13
0
ファイル: hooks.py プロジェクト: lykoss/lykos
def extended_who_reply(cli, bot_server, bot_nick, data, chan, ident, ip_address, host, server, nick, status, hop, idle, account, realname):
    """Handle WHOX responses for servers that support it.

    An extended WHO (WHOX) is caracterised by a second parameter to the request
    That parameter must be '%' followed by at least one of 'tcuihsnfdlar'
    If the 't' specifier is present, the specifiers must be followed by a comma and at most 3 bytes
    This is the ordering if all parameters are present, but not all of them are required
    If a parameter depends on a specifier, it will be stated at the front
    If a specifier is not given, the parameter will be omitted in the reply

    Ordering and meaning of arguments for an extended WHO (WHOX) response:

    0  -   - The IRCClient instance (like everywhere else)
    1  -   - The server the requester (i.e. the bot) is on
    2  -   - The nickname of the requester (i.e. the bot)
    3  - t - The data sent alongside the request
    4  - c - The channel the request was made on
    5  - u - The ident of the user in this reply
    6  - i - The IP address of the user in this reply
    7  - h - The hostname of the user in this reply
    8  - s - The server the user in this reply is on
    9  - n - The nickname of the user in this reply
    10 - f - Status (H = Not away, G = Away, * = IRC operator, @ = Opped in the channel in 5, + = Voiced in the channel in 5)
    11 - d - The hop count
    12 - l - The idle time (or 0 for users on other servers)
    13 - a - The services account name (or 0 if none/not logged in)
    14 - r - The realname (gecos)

    This fires off the "who_result" event, and dispatches it with three
    arguments, the game state namespace, a Channel, and a User. Less
    important attributes can be accessed via the event.params namespace.

    """

    if account == "0":
        account = None

    hop = int(hop)
    idle = int(idle)
    is_away = ("G" in status)

    data = int.from_bytes(data.encode(Features["CHARSET"]), "little")

    modes = {Features["PREFIX"].get(s) for s in status} - {None}

    user = users._add(cli, nick=nick, ident=ident, host=host, realname=realname, account=account) # FIXME

    ch = None
    if not channels.predicate(chan):
        ch = channels.add(chan, cli)
        if ch not in user.channels:
            user.channels[ch] = modes
            ch.users.add(user)
            for mode in modes:
                if mode not in ch.modes:
                    ch.modes[mode] = set()
                ch.modes[mode].add(user)

    event = Event("who_result", {}, away=is_away, data=data, ip_address=ip_address, server=server, hop_count=hop, idle_time=idle, extended_who=True)
    event.dispatch(var, ch, user)

    if ch is channels.Main and not users.exists(nick): # FIXME
        users.add(nick, ident=ident, host=host, account=account, inchan=True, modes=modes, moded=set())