mirror of
				https://github.com/jlu5/PyLink.git
				synced 2025-11-04 00:47:21 +01:00 
			
		
		
		
	relay: support relaying kills (#520)
Instead of always bouncing, kills to a relay client are now handled as follows:
1) If the target and source networks are both in any killshare pool, relay the kill entirely
2) Otherwise, iterate over all channels the kill target is in:
    3) If the killer has claim access in a channel, forward the KILL as a kick
    4) Otherwise, bounce the kill (so far, silently)
TODO: kill messages are currently very cluttered, we should make our parser deliver more concise strings...
* GL|unreal has quit (Killed (chary.relay (KILL from GL/chary: Killed (GL (test)))))
			
			
This commit is contained in:
		
							parent
							
								
									9466813ba1
								
							
						
					
					
						commit
						73d0e153cf
					
				@ -659,6 +659,15 @@ relay:
 | 
			
		||||
    #    - ["net1", "net2", "net3"]
 | 
			
		||||
    #    - ["net1", "meganet"]
 | 
			
		||||
 | 
			
		||||
    # This option defines lists of networks that kills should be relayed between.
 | 
			
		||||
    # If a network is in a pool (case-SENSITIVE), they will be able to kill users
 | 
			
		||||
    # on other networks in the pool, and will also receive kills from other networks
 | 
			
		||||
    # in the pool.
 | 
			
		||||
    # You should generally have a consensus among your linked networks as to which
 | 
			
		||||
    # network should be in which pool.
 | 
			
		||||
    #kill_share_pools:
 | 
			
		||||
    #    - ["net1", "net2", "net3"]
 | 
			
		||||
 | 
			
		||||
    # Determines whether NickServ login info should be shown in the /whois output for
 | 
			
		||||
    # relay users.
 | 
			
		||||
    # Valid options include "all" (show this to everyone), "opers" (show only to
 | 
			
		||||
 | 
			
		||||
@ -326,7 +326,7 @@ def _has_common_pool(sourcenet, targetnet, namespace):
 | 
			
		||||
    if 'relay' not in conf.conf:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    for pool in conf.conf['relay'].get(namespace, []):
 | 
			
		||||
    for pool in (conf.conf['relay'].get(namespace) or []):
 | 
			
		||||
        if sourcenet in pool and targetnet in pool:
 | 
			
		||||
            log.debug('relay._has_common_pool: found networks %r and %r in %s pool %r', sourcenet, targetnet,
 | 
			
		||||
                      namespace, pool)
 | 
			
		||||
@ -1905,30 +1905,54 @@ def handle_kill(irc, numeric, command, args):
 | 
			
		||||
 | 
			
		||||
    # Target user was remote:
 | 
			
		||||
    if realuser and realuser[0] != irc.name:
 | 
			
		||||
        # We don't allow killing over the relay, so we must respawn the affected
 | 
			
		||||
        # client and rejoin it to its channels.
 | 
			
		||||
        del relayusers[realuser][irc.name]
 | 
			
		||||
        remoteirc = world.networkobjects[realuser[0]]
 | 
			
		||||
        for remotechan in remoteirc.users[realuser[1]].channels:
 | 
			
		||||
            localchan = get_remote_channel(remoteirc, irc, remotechan)
 | 
			
		||||
            if localchan:
 | 
			
		||||
                modes = get_prefix_modes(remoteirc, irc, remotechan, realuser[1])
 | 
			
		||||
                log.debug('(%s) relay.handle_kill: userpair: %s, %s', irc.name, modes, realuser)
 | 
			
		||||
                client = get_remote_user(remoteirc, irc, realuser[1], times_tagged=1)
 | 
			
		||||
                irc.sjoin(get_relay_server_sid(irc, remoteirc), localchan, [(modes, client)])
 | 
			
		||||
        fwd_reason = 'KILL from %s/%s: %s' % (irc.get_friendly_name(numeric), irc.name, args['text'])
 | 
			
		||||
 | 
			
		||||
        if userdata and numeric in irc.users:
 | 
			
		||||
            log.info('(%s) relay.handle_kill: Blocked KILL (reason %r) from %s to relay client %s/%s.',
 | 
			
		||||
                     irc.name, args['text'], irc.users[numeric].nick,
 | 
			
		||||
                     remoteirc.users[realuser[1]].nick, realuser[0])
 | 
			
		||||
            irc.msg(numeric, "Your kill to %s has been blocked "
 | 
			
		||||
                             "because PyLink does not allow killing"
 | 
			
		||||
                             " users over the relay at this time." % \
 | 
			
		||||
                             userdata.nick, notice=True)
 | 
			
		||||
        origirc = world.networkobjects[realuser[0]]
 | 
			
		||||
 | 
			
		||||
        # If we're allowed to forward kills, then do so.
 | 
			
		||||
        if _has_common_pool(irc.name, realuser[0], 'kill_share_pools'):
 | 
			
		||||
            def _relay_kill_loop(irc, remoteirc):
 | 
			
		||||
                if remoteirc == origirc:
 | 
			
		||||
                    # Don't bother with get_orig_user when we relay onto the target's home net
 | 
			
		||||
                    rtarget = realuser[1]
 | 
			
		||||
                else:
 | 
			
		||||
                    rtarget = get_remote_user(origirc, remoteirc, realuser[1])
 | 
			
		||||
 | 
			
		||||
                if rtarget:
 | 
			
		||||
                    # Forward the kill from the relay server when available
 | 
			
		||||
                    rsender = get_relay_server_sid(remoteirc, irc, spawn_if_missing=False) or \
 | 
			
		||||
                              remoteirc.sid
 | 
			
		||||
                    remoteirc.kill(rsender, rtarget, fwd_reason)
 | 
			
		||||
 | 
			
		||||
            iterate_all(irc, _relay_kill_loop)
 | 
			
		||||
 | 
			
		||||
            del relayusers[realuser]
 | 
			
		||||
        else:
 | 
			
		||||
            log.info('(%s) relay.handle_kill: Blocked KILL (reason %r) from server %s to relay client %s/%s.',
 | 
			
		||||
                     irc.name, args['text'], irc.servers[numeric].name,
 | 
			
		||||
                     remoteirc.users[realuser[1]].nick, realuser[0])
 | 
			
		||||
            # Otherwise, forward kills as kicks where applicable.
 | 
			
		||||
            for remotechan in origirc.users[realuser[1]].channels.copy():
 | 
			
		||||
                localchan = get_remote_channel(origirc, irc, remotechan)
 | 
			
		||||
 | 
			
		||||
                if localchan:
 | 
			
		||||
                    # Forward kills as kicks in all channels that the sender has CLAIM access to.
 | 
			
		||||
                    if check_claim(irc, localchan, numeric):
 | 
			
		||||
                        rsid = get_relay_server_sid(origirc, irc)
 | 
			
		||||
                        log.debug('(%s) relay.handle_kill: forwarding kill to %s/%s@%s as '
 | 
			
		||||
                                  'kick on %s', irc.name, realuser[1],
 | 
			
		||||
                                  origirc.get_friendly_name(realuser[1]), realuser[0], remotechan)
 | 
			
		||||
 | 
			
		||||
                        origirc.kick(rsid, remotechan, realuser[1], fwd_reason)
 | 
			
		||||
                        origirc.call_hooks([rsid, 'RELAY_KILLFORWARD_KICK',
 | 
			
		||||
                            {'target': realuser[1], 'channel': remotechan, 'text': fwd_reason,
 | 
			
		||||
                             'parse_as': 'KICK'}])
 | 
			
		||||
 | 
			
		||||
                    # If we have no access in a channel, rejoin the target.
 | 
			
		||||
                    else:
 | 
			
		||||
                        modes = get_prefix_modes(origirc, irc, remotechan, realuser[1])
 | 
			
		||||
                        log.debug('(%s) relay.handle_kill: rejoining target userpair: (%r, %r)', irc.name, modes, realuser)
 | 
			
		||||
                        # Set times_tagged=1 to forcetag the target when they return.
 | 
			
		||||
                        client = get_remote_user(origirc, irc, realuser[1], times_tagged=1)
 | 
			
		||||
                        irc.sjoin(irc.sid, localchan, [(modes, client)])
 | 
			
		||||
 | 
			
		||||
    # Target user was local.
 | 
			
		||||
    else:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user