mirror of
				https://github.com/jlu5/PyLink.git
				synced 2025-11-04 00:47:21 +01:00 
			
		
		
		
	relay & ts6: miscellaneous fixes?
This commit is contained in:
		
							parent
							
								
									88dbe3cde9
								
							
						
					
					
						commit
						73c41b4363
					
				@ -123,8 +123,10 @@ def getRemoteUser(irc, remoteirc, user, spawnIfMissing=True):
 | 
			
		||||
            # been connected yet... Oh well!
 | 
			
		||||
            return
 | 
			
		||||
        nick = normalizeNick(remoteirc, irc.name, userobj.nick)
 | 
			
		||||
        ident = userobj.ident
 | 
			
		||||
        host = userobj.host
 | 
			
		||||
        # Truncate idents at 10 characters, because TS6 won't like them otherwise!
 | 
			
		||||
        ident = userobj.ident[:10]
 | 
			
		||||
        # Ditto hostname at 64 chars.
 | 
			
		||||
        host = userobj.host[:64]
 | 
			
		||||
        realname = userobj.realname
 | 
			
		||||
        modes = getSupportedUmodes(irc, remoteirc, userobj.modes)
 | 
			
		||||
        u = remoteirc.proto.spawnClient(remoteirc, nick, ident=ident,
 | 
			
		||||
@ -188,7 +190,6 @@ def initializeChannel(irc, channel):
 | 
			
		||||
    log.debug('(%s) initializeChannel: relay pair found to be %s', irc.name, relay)
 | 
			
		||||
    queued_users = []
 | 
			
		||||
    if relay:
 | 
			
		||||
        irc.proto.joinClient(irc, irc.pseudoclient.uid, channel)
 | 
			
		||||
        all_links = db[relay]['links'].copy()
 | 
			
		||||
        all_links.update((relay,))
 | 
			
		||||
        log.debug('(%s) initializeChannel: all_links: %s', irc.name, all_links)
 | 
			
		||||
@ -197,7 +198,9 @@ def initializeChannel(irc, channel):
 | 
			
		||||
            remotenet, remotechan = link
 | 
			
		||||
            if remotenet == irc.name:
 | 
			
		||||
                continue
 | 
			
		||||
            remoteirc = utils.networkobjects[remotenet]
 | 
			
		||||
            remoteirc = utils.networkobjects.get(remotenet)
 | 
			
		||||
            if remoteirc is None:
 | 
			
		||||
                continue
 | 
			
		||||
            rc = remoteirc.channels[remotechan]
 | 
			
		||||
            if not (remoteirc.connected and findRemoteChan(remoteirc, irc, remotechan)):
 | 
			
		||||
                continue  # They aren't connected, don't bother!
 | 
			
		||||
@ -219,8 +222,9 @@ def initializeChannel(irc, channel):
 | 
			
		||||
            if remoteirc.channels[channel].topicset and topic != irc.channels[channel].topic:
 | 
			
		||||
                irc.proto.topicServer(irc, irc.sid, channel, topic)
 | 
			
		||||
 | 
			
		||||
    log.debug('(%s) initializeChannel: joining our users: %s', irc.name, c.users)
 | 
			
		||||
    relayJoins(irc, channel, c.users, c.ts, c.modes)
 | 
			
		||||
        log.debug('(%s) initializeChannel: joining our users: %s', irc.name, c.users)
 | 
			
		||||
        relayJoins(irc, channel, c.users, c.ts, c.modes)
 | 
			
		||||
        irc.proto.joinClient(irc, irc.pseudoclient.uid, channel)
 | 
			
		||||
 | 
			
		||||
def handle_join(irc, numeric, command, args):
 | 
			
		||||
    channel = args['channel']
 | 
			
		||||
@ -539,6 +543,9 @@ utils.add_hook(handle_topic, 'TOPIC')
 | 
			
		||||
def handle_kill(irc, numeric, command, args):
 | 
			
		||||
    target = args['target']
 | 
			
		||||
    userdata = args['userdata']
 | 
			
		||||
    if numeric not in irc.users:
 | 
			
		||||
        # A server's sending kill? Uh oh, this can't be good.
 | 
			
		||||
        return
 | 
			
		||||
    # We don't allow killing over the relay, so we must spawn the client.
 | 
			
		||||
    # all over again and rejoin it to its channels.
 | 
			
		||||
    realuser = getLocalUser(irc, target)
 | 
			
		||||
@ -559,28 +566,28 @@ utils.add_hook(handle_kill, 'KILL')
 | 
			
		||||
 | 
			
		||||
def relayJoins(irc, channel, users, ts, modes):
 | 
			
		||||
    queued_users = []
 | 
			
		||||
    for user in users.copy():
 | 
			
		||||
        try:
 | 
			
		||||
            if irc.users[user].remote:
 | 
			
		||||
                # Is the .remote attribute set? If so, don't relay already
 | 
			
		||||
                # relayed clients; that'll trigger an endless loop!
 | 
			
		||||
                continue
 | 
			
		||||
        except AttributeError:  # Nope, it isn't.
 | 
			
		||||
            pass
 | 
			
		||||
        if user == irc.pseudoclient.uid:
 | 
			
		||||
            # We don't need to clone the PyLink pseudoclient... That's
 | 
			
		||||
            # meaningless.
 | 
			
		||||
    for name, remoteirc in utils.networkobjects.items():
 | 
			
		||||
        if name == irc.name:
 | 
			
		||||
            # Don't relay things to their source network...
 | 
			
		||||
            continue
 | 
			
		||||
        log.debug('Okay, spawning %s/%s everywhere', user, irc.name)
 | 
			
		||||
        for name, remoteirc in utils.networkobjects.items():
 | 
			
		||||
            if name == irc.name:
 | 
			
		||||
                # Don't relay things to their source network...
 | 
			
		||||
                continue
 | 
			
		||||
            remotechan = findRemoteChan(irc, remoteirc, channel)
 | 
			
		||||
            if remotechan is None:
 | 
			
		||||
                # If there is no link on our network for the user, don't
 | 
			
		||||
                # bother spawning it.
 | 
			
		||||
        remotechan = findRemoteChan(irc, remoteirc, channel)
 | 
			
		||||
        if remotechan is None:
 | 
			
		||||
            # If there is no link on our network for the user, don't
 | 
			
		||||
            # bother spawning it.
 | 
			
		||||
            continue
 | 
			
		||||
        for user in users.copy():
 | 
			
		||||
            try:
 | 
			
		||||
                if irc.users[user].remote:
 | 
			
		||||
                    # Is the .remote attribute set? If so, don't relay already
 | 
			
		||||
                    # relayed clients; that'll trigger an endless loop!
 | 
			
		||||
                    continue
 | 
			
		||||
            except AttributeError:  # Nope, it isn't.
 | 
			
		||||
                pass
 | 
			
		||||
            if user == irc.pseudoclient.uid:
 | 
			
		||||
                # We don't need to clone the PyLink pseudoclient... That's
 | 
			
		||||
                # meaningless.
 | 
			
		||||
                continue
 | 
			
		||||
            log.debug('Okay, spawning %s/%s everywhere', user, irc.name)
 | 
			
		||||
            u = getRemoteUser(irc, remoteirc, user)
 | 
			
		||||
            if u is None:
 | 
			
		||||
                continue
 | 
			
		||||
@ -588,9 +595,10 @@ def relayJoins(irc, channel, users, ts, modes):
 | 
			
		||||
            # TODO: join users in batches with SJOIN, not one by one.
 | 
			
		||||
            prefixes = getPrefixModes(irc, remoteirc, channel, user)
 | 
			
		||||
            userpair = (prefixes, u)
 | 
			
		||||
            queued_users.append(userpair)
 | 
			
		||||
            log.debug('(%s) relayJoin: joining %s to %s%s', irc.name, userpair, remoteirc.name, remotechan)
 | 
			
		||||
            remoteirc.proto.sjoinServer(remoteirc, remoteirc.sid, remotechan, [userpair], ts=ts)
 | 
			
		||||
            relayModes(irc, remoteirc, irc.sid, channel, modes)
 | 
			
		||||
        remoteirc.proto.sjoinServer(remoteirc, remoteirc.sid, remotechan, queued_users, ts=ts)
 | 
			
		||||
        relayModes(irc, remoteirc, irc.sid, channel, modes)
 | 
			
		||||
 | 
			
		||||
def relayPart(irc, channel, user):
 | 
			
		||||
    for name, remoteirc in utils.networkobjects.items():
 | 
			
		||||
@ -610,6 +618,8 @@ def relayPart(irc, channel, user):
 | 
			
		||||
            del relayusers[(irc.name, user)][remoteirc.name]
 | 
			
		||||
 | 
			
		||||
def removeChannel(irc, channel):
 | 
			
		||||
    if irc is None:
 | 
			
		||||
        return
 | 
			
		||||
    if channel not in map(str.lower, irc.serverdata['channels']):
 | 
			
		||||
        irc.proto.partClient(irc, irc.pseudoclient.uid, channel)
 | 
			
		||||
    relay = findRelay((irc.name, channel))
 | 
			
		||||
@ -625,12 +635,16 @@ def removeChannel(irc, channel):
 | 
			
		||||
                # Don't relay things to their source network...
 | 
			
		||||
                continue
 | 
			
		||||
            remotenet, remotechan = link
 | 
			
		||||
            remoteirc = utils.networkobjects[remotenet]
 | 
			
		||||
            rc = remoteirc.channels[remotechan]
 | 
			
		||||
            for user in remoteirc.channels[remotechan].users.copy():
 | 
			
		||||
                log.debug('(%s) removeChannel: part user %s/%s from %s', irc.name, user, remotenet, remotechan)
 | 
			
		||||
                if not utils.isInternalClient(remoteirc, user):
 | 
			
		||||
                    relayPart(remoteirc, remotechan, user)
 | 
			
		||||
            try:
 | 
			
		||||
                remoteirc = utils.networkobjects[remotenet]
 | 
			
		||||
            except KeyError:
 | 
			
		||||
                pass
 | 
			
		||||
            else:
 | 
			
		||||
                rc = remoteirc.channels[remotechan]
 | 
			
		||||
                for user in remoteirc.channels[remotechan].users.copy():
 | 
			
		||||
                    log.debug('(%s) removeChannel: part user %s/%s from %s', irc.name, user, remotenet, remotechan)
 | 
			
		||||
                    if not utils.isInternalClient(remoteirc, user):
 | 
			
		||||
                        relayPart(remoteirc, remotechan, user)
 | 
			
		||||
 | 
			
		||||
@utils.add_cmd
 | 
			
		||||
def create(irc, source, args):
 | 
			
		||||
@ -675,7 +689,7 @@ def destroy(irc, source, args):
 | 
			
		||||
    entry = (irc.name, channel)
 | 
			
		||||
    if entry in db:
 | 
			
		||||
        for link in db[entry]['links']:
 | 
			
		||||
            removeChannel(utils.networkobjects[link[0]], link[1])
 | 
			
		||||
            removeChannel(utils.networkobjects.get(link[0]), link[1])
 | 
			
		||||
        removeChannel(irc, channel)
 | 
			
		||||
        del db[entry]
 | 
			
		||||
        utils.msg(irc, source, 'Done.')
 | 
			
		||||
@ -762,7 +776,7 @@ def delink(irc, source, args):
 | 
			
		||||
            else:
 | 
			
		||||
               for link in db[entry]['links'].copy():
 | 
			
		||||
                    if link[0] == remotenet:
 | 
			
		||||
                        removeChannel(utils.networkobjects[remotenet], link[1])
 | 
			
		||||
                        removeChannel(utils.networkobjects.get(remotenet), link[1])
 | 
			
		||||
                        db[entry]['links'].remove(link)
 | 
			
		||||
        else:
 | 
			
		||||
            removeChannel(irc, channel)
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ from inspircd import handle_privmsg, handle_kill, handle_kick, handle_error, \
 | 
			
		||||
    handle_quit, handle_nick, handle_save, handle_squit, handle_mode, handle_topic, \
 | 
			
		||||
    handle_notice
 | 
			
		||||
 | 
			
		||||
hook_map = {'SJOIN': 'JOIN'}
 | 
			
		||||
hook_map = {'SJOIN': 'JOIN', 'TB': 'TOPIC'}
 | 
			
		||||
 | 
			
		||||
def _send(irc, sid, msg):
 | 
			
		||||
    irc.send(':%s %s' % (sid, msg))
 | 
			
		||||
@ -50,14 +50,12 @@ def spawnClient(irc, nick, ident='null', host='null', realhost=None, modes=set()
 | 
			
		||||
 | 
			
		||||
def joinClient(irc, client, channel):
 | 
			
		||||
    channel = channel.lower()
 | 
			
		||||
    server = utils.isInternalClient(irc, client)
 | 
			
		||||
    # JOIN:
 | 
			
		||||
    # parameters: channelTS, channel, '+' (a plus sign)
 | 
			
		||||
    if not server:
 | 
			
		||||
    if not utils.isInternalClient(irc, client):
 | 
			
		||||
        log.error('(%s) Error trying to join client %r to %r (no such pseudoclient exists)', irc.name, client, channel)
 | 
			
		||||
        raise LookupError('No such PyLink PseudoClient exists.')
 | 
			
		||||
    _send(irc, client, "JOIN {ts} {channel} +".format(
 | 
			
		||||
            ts=int(time.time()), channel=channel))
 | 
			
		||||
    _send(irc, client, "JOIN {ts} {channel} +".format(ts=irc.channels[channel].ts, channel=channel))
 | 
			
		||||
    irc.channels[channel].users.add(client)
 | 
			
		||||
    irc.users[client].channels.add(channel)
 | 
			
		||||
 | 
			
		||||
@ -80,7 +78,7 @@ def sjoinServer(irc, server, channel, users, ts=None):
 | 
			
		||||
        ts = irc.channels[channel].ts
 | 
			
		||||
    log.debug("sending SJOIN to %s%s with ts %s (that's %r)", channel, irc.name, ts, 
 | 
			
		||||
              time.strftime("%c", time.localtime(ts)))
 | 
			
		||||
    modes = irc.channels[channel].modes
 | 
			
		||||
    modes = [m for m in irc.channels[channel].modes if m[0] not in irc.cmodes['*A']]
 | 
			
		||||
    uids = []
 | 
			
		||||
    changedmodes = []
 | 
			
		||||
    namelist = []
 | 
			
		||||
@ -113,9 +111,9 @@ def _sendModes(irc, numeric, target, modes, ts=None):
 | 
			
		||||
        
 | 
			
		||||
        # On output, at most ten cmode parameters should be sent; if there are more,
 | 
			
		||||
        # multiple TMODE messages should be sent.
 | 
			
		||||
        while modes[:10]:
 | 
			
		||||
            joinedmodes = utils.joinModes(modes[:10])
 | 
			
		||||
            modes = modes[10:]
 | 
			
		||||
        while modes[:9]:
 | 
			
		||||
            joinedmodes = utils.joinModes(modes = [m for m in modes[:9] if m[0] not in irc.cmodes['*A']])
 | 
			
		||||
            modes = modes[9:]
 | 
			
		||||
            _send(irc, numeric, 'TMODE %s %s %s' % (ts, target, joinedmodes))
 | 
			
		||||
    else:
 | 
			
		||||
        joinedmodes = utils.joinModes(modes)
 | 
			
		||||
@ -326,6 +324,12 @@ def handle_sjoin(irc, servernumeric, command, args):
 | 
			
		||||
def handle_join(irc, numeric, command, args):
 | 
			
		||||
    # parameters: channelTS, channel, '+' (a plus sign)
 | 
			
		||||
    ts = int(args[0])
 | 
			
		||||
    our_ts = irc.channels[channel].ts
 | 
			
		||||
    if ts < our_ts:
 | 
			
		||||
        # Channel timestamp was reset on burst
 | 
			
		||||
        log.debug('(%s) Setting channel TS of %s to %s from %s',
 | 
			
		||||
                  irc.name, channel, ts, our_ts)
 | 
			
		||||
        irc.channels[channel].ts = ts
 | 
			
		||||
    if args[0] == '0':
 | 
			
		||||
        # /join 0; part the user from all channels
 | 
			
		||||
        oldchans = list(irc.users[numeric].channels)
 | 
			
		||||
@ -457,6 +461,7 @@ def handle_events(irc, data):
 | 
			
		||||
        irc.umodes.update(chary_umodes)
 | 
			
		||||
        # TODO: support module-created modes like +O, +S, etc.
 | 
			
		||||
        # Does charybdis propagate these? If so, how?
 | 
			
		||||
        log.debug('(%s) irc.connected set!', irc.name)
 | 
			
		||||
        irc.connected.set()
 | 
			
		||||
    try:
 | 
			
		||||
        real_args = []
 | 
			
		||||
@ -538,21 +543,6 @@ def handle_invite(irc, numeric, command, args):
 | 
			
		||||
    # We don't actually need to process this; it's just something plugins/hooks can use
 | 
			
		||||
    return {'target': target, 'channel': channel}
 | 
			
		||||
 | 
			
		||||
def handle_opertype(irc, numeric, command, args):
 | 
			
		||||
    # This is used by InspIRCd to denote an oper up; there is no MODE
 | 
			
		||||
    # command sent for it.
 | 
			
		||||
    # <- :70MAAAAAB OPERTYPE Network_Owner
 | 
			
		||||
    omode = [('+o', None)]
 | 
			
		||||
    utils.applyModes(irc, numeric, omode)
 | 
			
		||||
    return {'target': numeric, 'modes': omode}
 | 
			
		||||
 | 
			
		||||
def handle_fident(irc, numeric, command, args):
 | 
			
		||||
    # :70MAAAAAB FHOST test
 | 
			
		||||
    # :70MAAAAAB FNAME :afdsafasf
 | 
			
		||||
    # :70MAAAAAB FIDENT test
 | 
			
		||||
    irc.users[numeric].ident = newident = args[0]
 | 
			
		||||
    return {'target': numeric, 'newident': newident}
 | 
			
		||||
 | 
			
		||||
def handle_chghost(irc, numeric, command, args):
 | 
			
		||||
    target = args[0]
 | 
			
		||||
    irc.users[target].host = newhost = args[1]
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user