mirror of
https://github.com/jlu5/PyLink.git
synced 2025-01-12 05:02:33 +01:00
relay: factorize getLocalUser, introduce MODE (experimental) and PRIVMSG handler
This commit is contained in:
parent
f74e704733
commit
7de8f1509d
124
plugins/relay.py
124
plugins/relay.py
@ -97,6 +97,29 @@ def getRemoteUser(irc, remoteirc, user):
|
|||||||
remoteirc.users[u].remote = irc.name
|
remoteirc.users[u].remote = irc.name
|
||||||
return u
|
return u
|
||||||
|
|
||||||
|
def getLocalUser(irc, user):
|
||||||
|
# Our target is an internal client, which means someone
|
||||||
|
# is kicking a remote user over the relay.
|
||||||
|
# We have to find the real target for the KICK. This is like
|
||||||
|
# findRemoteUser, but in reverse.
|
||||||
|
# First, iterate over everyone!
|
||||||
|
for k, v in relayusers.items():
|
||||||
|
log.debug('(%s) getLocalUser: processing %s, %s in relayusers', irc.name, k, v)
|
||||||
|
if k[0] == irc.name:
|
||||||
|
# We don't need to do anything if the target users is on
|
||||||
|
# the same network as us.
|
||||||
|
log.debug('(%s) getLocalUser: skipping %s since the target network matches the source network.', irc.name, k)
|
||||||
|
continue
|
||||||
|
if v[irc.name] == user:
|
||||||
|
# If the stored pseudoclient UID for the kicked user on
|
||||||
|
# this network matches the target we have, set that user
|
||||||
|
# as the one we're kicking! It's a handful, but remember
|
||||||
|
# we're mapping (home network, UID) pairs to their
|
||||||
|
# respective relay pseudoclients on other networks.
|
||||||
|
remoteuser = k
|
||||||
|
log.debug('(%s) getLocalUser: found %s to correspond to %s.', irc.name, v, k)
|
||||||
|
return remoteuser
|
||||||
|
|
||||||
def findRelay(chanpair):
|
def findRelay(chanpair):
|
||||||
if chanpair in db: # This chanpair is a shared channel; others link to it
|
if chanpair in db: # This chanpair is a shared channel; others link to it
|
||||||
return chanpair
|
return chanpair
|
||||||
@ -148,6 +171,8 @@ def initializeChannel(irc, channel):
|
|||||||
queued_users.append(userpair)
|
queued_users.append(userpair)
|
||||||
if queued_users:
|
if queued_users:
|
||||||
irc.proto.sjoinServer(irc, irc.sid, channel, queued_users, ts=rc.ts)
|
irc.proto.sjoinServer(irc, irc.sid, channel, queued_users, ts=rc.ts)
|
||||||
|
relayModes(remoteirc, irc, remoteirc.sid, remotechan)
|
||||||
|
relayModes(irc, remoteirc, irc.sid, channel)
|
||||||
|
|
||||||
log.debug('(%s) initializeChannel: joining our users: %s', irc.name, c.users)
|
log.debug('(%s) initializeChannel: joining our users: %s', irc.name, c.users)
|
||||||
relayJoins(irc, channel, c.users, c.ts, c.modes)
|
relayJoins(irc, channel, c.users, c.ts, c.modes)
|
||||||
@ -188,6 +213,28 @@ def handle_part(irc, numeric, command, args):
|
|||||||
remoteirc.proto.partClient(remoteirc, user, remotechan, text)
|
remoteirc.proto.partClient(remoteirc, user, remotechan, text)
|
||||||
utils.add_hook(handle_part, 'PART')
|
utils.add_hook(handle_part, 'PART')
|
||||||
|
|
||||||
|
def handle_privmsg(irc, numeric, command, args):
|
||||||
|
notice = (command == 'NOTICE')
|
||||||
|
target = args['target']
|
||||||
|
text = args['text']
|
||||||
|
for netname, user in relayusers[(irc.name, numeric)].items():
|
||||||
|
remoteirc = utils.networkobjects[netname]
|
||||||
|
if utils.isChannel(target):
|
||||||
|
real_target = findRemoteChan(irc, remoteirc, target)
|
||||||
|
if not real_target:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
real_target = getLocalUser(irc, target)[1]
|
||||||
|
except TypeError:
|
||||||
|
real_target = getRemoteUser(irc, remoteirc, target)
|
||||||
|
if notice:
|
||||||
|
remoteirc.proto.noticeClient(remoteirc, user, real_target, text)
|
||||||
|
else:
|
||||||
|
remoteirc.proto.messageClient(remoteirc, user, real_target, text)
|
||||||
|
utils.add_hook(handle_privmsg, 'PRIVMSG')
|
||||||
|
utils.add_hook(handle_privmsg, 'NOTICE')
|
||||||
|
|
||||||
def handle_kick(irc, source, command, args):
|
def handle_kick(irc, source, command, args):
|
||||||
channel = args['channel']
|
channel = args['channel']
|
||||||
target = args['target']
|
target = args['target']
|
||||||
@ -218,27 +265,7 @@ def handle_kick(irc, source, command, args):
|
|||||||
remotechan, real_target, args['text'])
|
remotechan, real_target, args['text'])
|
||||||
else:
|
else:
|
||||||
log.debug('(%s) Relay kick: target %s is an internal client, going to look up the real user', irc.name, target)
|
log.debug('(%s) Relay kick: target %s is an internal client, going to look up the real user', irc.name, target)
|
||||||
# Our target is an internal client, which means someone
|
real_target = getLocalUser(irc, target)[1]
|
||||||
# is kicking a remote user over the relay.
|
|
||||||
# We have to find the real target for the KICK. This is like
|
|
||||||
# findRemoteUser, but in reverse.
|
|
||||||
# First, iterate over everyone!
|
|
||||||
for k, v in relayusers.items():
|
|
||||||
log.debug('(%s) Relay kick: processing %s, %s in relayusers', irc.name, k, v)
|
|
||||||
if k[0] == irc.name:
|
|
||||||
# We don't need to do anything if the target users is on
|
|
||||||
# the same network as us.
|
|
||||||
log.debug('(%s) Relay kick: skipping %s since the target network matches the source network.', irc.name, k)
|
|
||||||
continue
|
|
||||||
if v[irc.name] == target:
|
|
||||||
# If the stored pseudoclient UID for the kicked user on
|
|
||||||
# this network matches the target we have, set that user
|
|
||||||
# as the one we're kicking! It's a handful, but remember
|
|
||||||
# we're mapping (home network, UID) pairs to their
|
|
||||||
# respective relay pseudoclients on other networks.
|
|
||||||
real_target = k[1]
|
|
||||||
log.debug('(%s) Relay kick: found %s to correspond to %s.', irc.name, v, k)
|
|
||||||
break
|
|
||||||
log.debug('(%s) Relay kick: kicker_modes are %r', irc.name, kicker_modes)
|
log.debug('(%s) Relay kick: kicker_modes are %r', irc.name, kicker_modes)
|
||||||
if irc.name not in db[relay]['claim'] and not \
|
if irc.name not in db[relay]['claim'] and not \
|
||||||
any([mode in kicker_modes for mode in ('q', 'a', 'o', 'h')]):
|
any([mode in kicker_modes for mode in ('q', 'a', 'o', 'h')]):
|
||||||
@ -260,6 +287,60 @@ def handle_kick(irc, source, command, args):
|
|||||||
remotechan, real_target, args['text'])
|
remotechan, real_target, args['text'])
|
||||||
utils.add_hook(handle_kick, 'KICK')
|
utils.add_hook(handle_kick, 'KICK')
|
||||||
|
|
||||||
|
def relayModes(irc, remoteirc, sender, channel, modes=None):
|
||||||
|
remotechan = findRemoteChan(irc, remoteirc, channel)
|
||||||
|
log.debug('(%s) Relay mode: remotechan for %s on %s is %s', irc.name, channel, irc.name, remotechan)
|
||||||
|
if remotechan is None:
|
||||||
|
return
|
||||||
|
if modes is None:
|
||||||
|
modes = remoteirc.channels[remotechan].modes
|
||||||
|
log.debug('(%s) Relay mode: channel data for %s%s: %s', irc.name, remoteirc.name, remotechan, remoteirc.channels[remotechan])
|
||||||
|
supported_modes = []
|
||||||
|
log.debug('(%s) Relay mode: initial modelist for %s is %s', irc.name, channel, modes)
|
||||||
|
for modepair in modes:
|
||||||
|
try:
|
||||||
|
prefix, modechar = modepair[0]
|
||||||
|
except ValueError:
|
||||||
|
modechar = modepair[0]
|
||||||
|
prefix = '+'
|
||||||
|
arg = modepair[1]
|
||||||
|
# Iterate over every mode see whether the remote IRCd supports
|
||||||
|
# this mode, and what its mode char for it is (if it is different).
|
||||||
|
for name, m in irc.cmodes.items():
|
||||||
|
supported_char = None
|
||||||
|
if modechar == m:
|
||||||
|
if modechar in irc.prefixmodes:
|
||||||
|
# This is a prefix mode (e.g. +o). We must coerse the argument
|
||||||
|
# so that the target exists on the remote relay network.
|
||||||
|
try:
|
||||||
|
arg = getLocalUser(irc, arg)[1]
|
||||||
|
except TypeError:
|
||||||
|
# getLocalUser returns None, raises None when trying to
|
||||||
|
# get [1] from it.
|
||||||
|
arg = getRemoteUser(irc, remoteirc, arg)
|
||||||
|
supported_char = remoteirc.cmodes.get(name)
|
||||||
|
if supported_char:
|
||||||
|
supported_modes.append((prefix+supported_char, arg))
|
||||||
|
log.debug('(%s) Relay mode: final modelist (sending to %s%s) is %s', irc.name, remoteirc.name, remotechan, supported_modes)
|
||||||
|
# Check if the sender is a user; remember servers are allowed to set modes too.
|
||||||
|
if sender in irc.users:
|
||||||
|
u = getRemoteUser(irc, remoteirc, sender)
|
||||||
|
remoteirc.proto.modeClient(remoteirc, u, channel, supported_modes)
|
||||||
|
else:
|
||||||
|
remoteirc.proto.modeServer(remoteirc, remoteirc.sid, channel, supported_modes)
|
||||||
|
|
||||||
|
def handle_mode(irc, numeric, command, args):
|
||||||
|
target = args['target']
|
||||||
|
if not utils.isChannel(target):
|
||||||
|
### TODO: handle user mode changes too
|
||||||
|
return
|
||||||
|
modes = args['modes']
|
||||||
|
for name, remoteirc in utils.networkobjects.items():
|
||||||
|
if irc.name == name:
|
||||||
|
continue
|
||||||
|
relayModes(irc, remoteirc, numeric, target, modes)
|
||||||
|
utils.add_hook(handle_mode, 'MODE')
|
||||||
|
|
||||||
def relayJoins(irc, channel, users, ts, modes):
|
def relayJoins(irc, channel, users, ts, modes):
|
||||||
queued_users = []
|
queued_users = []
|
||||||
for user in users.copy():
|
for user in users.copy():
|
||||||
@ -289,6 +370,7 @@ def relayJoins(irc, channel, users, ts, modes):
|
|||||||
userpair = (prefixes, u)
|
userpair = (prefixes, u)
|
||||||
log.debug('(%s) relayJoin: joining %s to %s%s', irc.name, userpair, remoteirc.name, remotechan)
|
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)
|
remoteirc.proto.sjoinServer(remoteirc, remoteirc.sid, remotechan, [userpair], ts=ts)
|
||||||
|
relayModes(irc, remoteirc, irc.sid, channel, modes)
|
||||||
|
|
||||||
def relayPart(irc, channel, user):
|
def relayPart(irc, channel, user):
|
||||||
for name, remoteirc in utils.networkobjects.items():
|
for name, remoteirc in utils.networkobjects.items():
|
||||||
|
Loading…
Reference in New Issue
Block a user