mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-27 21:19:31 +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!
|
# been connected yet... Oh well!
|
||||||
return
|
return
|
||||||
nick = normalizeNick(remoteirc, irc.name, userobj.nick)
|
nick = normalizeNick(remoteirc, irc.name, userobj.nick)
|
||||||
ident = userobj.ident
|
# Truncate idents at 10 characters, because TS6 won't like them otherwise!
|
||||||
host = userobj.host
|
ident = userobj.ident[:10]
|
||||||
|
# Ditto hostname at 64 chars.
|
||||||
|
host = userobj.host[:64]
|
||||||
realname = userobj.realname
|
realname = userobj.realname
|
||||||
modes = getSupportedUmodes(irc, remoteirc, userobj.modes)
|
modes = getSupportedUmodes(irc, remoteirc, userobj.modes)
|
||||||
u = remoteirc.proto.spawnClient(remoteirc, nick, ident=ident,
|
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)
|
log.debug('(%s) initializeChannel: relay pair found to be %s', irc.name, relay)
|
||||||
queued_users = []
|
queued_users = []
|
||||||
if relay:
|
if relay:
|
||||||
irc.proto.joinClient(irc, irc.pseudoclient.uid, channel)
|
|
||||||
all_links = db[relay]['links'].copy()
|
all_links = db[relay]['links'].copy()
|
||||||
all_links.update((relay,))
|
all_links.update((relay,))
|
||||||
log.debug('(%s) initializeChannel: all_links: %s', irc.name, all_links)
|
log.debug('(%s) initializeChannel: all_links: %s', irc.name, all_links)
|
||||||
@ -197,7 +198,9 @@ def initializeChannel(irc, channel):
|
|||||||
remotenet, remotechan = link
|
remotenet, remotechan = link
|
||||||
if remotenet == irc.name:
|
if remotenet == irc.name:
|
||||||
continue
|
continue
|
||||||
remoteirc = utils.networkobjects[remotenet]
|
remoteirc = utils.networkobjects.get(remotenet)
|
||||||
|
if remoteirc is None:
|
||||||
|
continue
|
||||||
rc = remoteirc.channels[remotechan]
|
rc = remoteirc.channels[remotechan]
|
||||||
if not (remoteirc.connected and findRemoteChan(remoteirc, irc, remotechan)):
|
if not (remoteirc.connected and findRemoteChan(remoteirc, irc, remotechan)):
|
||||||
continue # They aren't connected, don't bother!
|
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:
|
if remoteirc.channels[channel].topicset and topic != irc.channels[channel].topic:
|
||||||
irc.proto.topicServer(irc, irc.sid, channel, topic)
|
irc.proto.topicServer(irc, irc.sid, channel, topic)
|
||||||
|
|
||||||
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)
|
||||||
|
irc.proto.joinClient(irc, irc.pseudoclient.uid, channel)
|
||||||
|
|
||||||
def handle_join(irc, numeric, command, args):
|
def handle_join(irc, numeric, command, args):
|
||||||
channel = args['channel']
|
channel = args['channel']
|
||||||
@ -539,6 +543,9 @@ utils.add_hook(handle_topic, 'TOPIC')
|
|||||||
def handle_kill(irc, numeric, command, args):
|
def handle_kill(irc, numeric, command, args):
|
||||||
target = args['target']
|
target = args['target']
|
||||||
userdata = args['userdata']
|
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.
|
# We don't allow killing over the relay, so we must spawn the client.
|
||||||
# all over again and rejoin it to its channels.
|
# all over again and rejoin it to its channels.
|
||||||
realuser = getLocalUser(irc, target)
|
realuser = getLocalUser(irc, target)
|
||||||
@ -559,28 +566,28 @@ utils.add_hook(handle_kill, 'KILL')
|
|||||||
|
|
||||||
def relayJoins(irc, channel, users, ts, modes):
|
def relayJoins(irc, channel, users, ts, modes):
|
||||||
queued_users = []
|
queued_users = []
|
||||||
for user in users.copy():
|
for name, remoteirc in utils.networkobjects.items():
|
||||||
try:
|
if name == irc.name:
|
||||||
if irc.users[user].remote:
|
# Don't relay things to their source network...
|
||||||
# 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
|
continue
|
||||||
log.debug('Okay, spawning %s/%s everywhere', user, irc.name)
|
remotechan = findRemoteChan(irc, remoteirc, channel)
|
||||||
for name, remoteirc in utils.networkobjects.items():
|
if remotechan is None:
|
||||||
if name == irc.name:
|
# If there is no link on our network for the user, don't
|
||||||
# Don't relay things to their source network...
|
# bother spawning it.
|
||||||
continue
|
continue
|
||||||
remotechan = findRemoteChan(irc, remoteirc, channel)
|
for user in users.copy():
|
||||||
if remotechan is None:
|
try:
|
||||||
# If there is no link on our network for the user, don't
|
if irc.users[user].remote:
|
||||||
# bother spawning it.
|
# 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
|
continue
|
||||||
|
log.debug('Okay, spawning %s/%s everywhere', user, irc.name)
|
||||||
u = getRemoteUser(irc, remoteirc, user)
|
u = getRemoteUser(irc, remoteirc, user)
|
||||||
if u is None:
|
if u is None:
|
||||||
continue
|
continue
|
||||||
@ -588,9 +595,10 @@ def relayJoins(irc, channel, users, ts, modes):
|
|||||||
# TODO: join users in batches with SJOIN, not one by one.
|
# TODO: join users in batches with SJOIN, not one by one.
|
||||||
prefixes = getPrefixModes(irc, remoteirc, channel, user)
|
prefixes = getPrefixModes(irc, remoteirc, channel, user)
|
||||||
userpair = (prefixes, u)
|
userpair = (prefixes, u)
|
||||||
|
queued_users.append(userpair)
|
||||||
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, queued_users, ts=ts)
|
||||||
relayModes(irc, remoteirc, irc.sid, channel, modes)
|
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():
|
||||||
@ -610,6 +618,8 @@ def relayPart(irc, channel, user):
|
|||||||
del relayusers[(irc.name, user)][remoteirc.name]
|
del relayusers[(irc.name, user)][remoteirc.name]
|
||||||
|
|
||||||
def removeChannel(irc, channel):
|
def removeChannel(irc, channel):
|
||||||
|
if irc is None:
|
||||||
|
return
|
||||||
if channel not in map(str.lower, irc.serverdata['channels']):
|
if channel not in map(str.lower, irc.serverdata['channels']):
|
||||||
irc.proto.partClient(irc, irc.pseudoclient.uid, channel)
|
irc.proto.partClient(irc, irc.pseudoclient.uid, channel)
|
||||||
relay = findRelay((irc.name, channel))
|
relay = findRelay((irc.name, channel))
|
||||||
@ -625,12 +635,16 @@ def removeChannel(irc, channel):
|
|||||||
# Don't relay things to their source network...
|
# Don't relay things to their source network...
|
||||||
continue
|
continue
|
||||||
remotenet, remotechan = link
|
remotenet, remotechan = link
|
||||||
remoteirc = utils.networkobjects[remotenet]
|
try:
|
||||||
rc = remoteirc.channels[remotechan]
|
remoteirc = utils.networkobjects[remotenet]
|
||||||
for user in remoteirc.channels[remotechan].users.copy():
|
except KeyError:
|
||||||
log.debug('(%s) removeChannel: part user %s/%s from %s', irc.name, user, remotenet, remotechan)
|
pass
|
||||||
if not utils.isInternalClient(remoteirc, user):
|
else:
|
||||||
relayPart(remoteirc, remotechan, user)
|
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
|
@utils.add_cmd
|
||||||
def create(irc, source, args):
|
def create(irc, source, args):
|
||||||
@ -675,7 +689,7 @@ def destroy(irc, source, args):
|
|||||||
entry = (irc.name, channel)
|
entry = (irc.name, channel)
|
||||||
if entry in db:
|
if entry in db:
|
||||||
for link in db[entry]['links']:
|
for link in db[entry]['links']:
|
||||||
removeChannel(utils.networkobjects[link[0]], link[1])
|
removeChannel(utils.networkobjects.get(link[0]), link[1])
|
||||||
removeChannel(irc, channel)
|
removeChannel(irc, channel)
|
||||||
del db[entry]
|
del db[entry]
|
||||||
utils.msg(irc, source, 'Done.')
|
utils.msg(irc, source, 'Done.')
|
||||||
@ -762,7 +776,7 @@ def delink(irc, source, args):
|
|||||||
else:
|
else:
|
||||||
for link in db[entry]['links'].copy():
|
for link in db[entry]['links'].copy():
|
||||||
if link[0] == remotenet:
|
if link[0] == remotenet:
|
||||||
removeChannel(utils.networkobjects[remotenet], link[1])
|
removeChannel(utils.networkobjects.get(remotenet), link[1])
|
||||||
db[entry]['links'].remove(link)
|
db[entry]['links'].remove(link)
|
||||||
else:
|
else:
|
||||||
removeChannel(irc, channel)
|
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_quit, handle_nick, handle_save, handle_squit, handle_mode, handle_topic, \
|
||||||
handle_notice
|
handle_notice
|
||||||
|
|
||||||
hook_map = {'SJOIN': 'JOIN'}
|
hook_map = {'SJOIN': 'JOIN', 'TB': 'TOPIC'}
|
||||||
|
|
||||||
def _send(irc, sid, msg):
|
def _send(irc, sid, msg):
|
||||||
irc.send(':%s %s' % (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):
|
def joinClient(irc, client, channel):
|
||||||
channel = channel.lower()
|
channel = channel.lower()
|
||||||
server = utils.isInternalClient(irc, client)
|
|
||||||
# JOIN:
|
# JOIN:
|
||||||
# parameters: channelTS, channel, '+' (a plus sign)
|
# 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)
|
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.')
|
raise LookupError('No such PyLink PseudoClient exists.')
|
||||||
_send(irc, client, "JOIN {ts} {channel} +".format(
|
_send(irc, client, "JOIN {ts} {channel} +".format(ts=irc.channels[channel].ts, channel=channel))
|
||||||
ts=int(time.time()), channel=channel))
|
|
||||||
irc.channels[channel].users.add(client)
|
irc.channels[channel].users.add(client)
|
||||||
irc.users[client].channels.add(channel)
|
irc.users[client].channels.add(channel)
|
||||||
|
|
||||||
@ -80,7 +78,7 @@ def sjoinServer(irc, server, channel, users, ts=None):
|
|||||||
ts = irc.channels[channel].ts
|
ts = irc.channels[channel].ts
|
||||||
log.debug("sending SJOIN to %s%s with ts %s (that's %r)", channel, irc.name, ts,
|
log.debug("sending SJOIN to %s%s with ts %s (that's %r)", channel, irc.name, ts,
|
||||||
time.strftime("%c", time.localtime(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 = []
|
uids = []
|
||||||
changedmodes = []
|
changedmodes = []
|
||||||
namelist = []
|
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,
|
# On output, at most ten cmode parameters should be sent; if there are more,
|
||||||
# multiple TMODE messages should be sent.
|
# multiple TMODE messages should be sent.
|
||||||
while modes[:10]:
|
while modes[:9]:
|
||||||
joinedmodes = utils.joinModes(modes[:10])
|
joinedmodes = utils.joinModes(modes = [m for m in modes[:9] if m[0] not in irc.cmodes['*A']])
|
||||||
modes = modes[10:]
|
modes = modes[9:]
|
||||||
_send(irc, numeric, 'TMODE %s %s %s' % (ts, target, joinedmodes))
|
_send(irc, numeric, 'TMODE %s %s %s' % (ts, target, joinedmodes))
|
||||||
else:
|
else:
|
||||||
joinedmodes = utils.joinModes(modes)
|
joinedmodes = utils.joinModes(modes)
|
||||||
@ -326,6 +324,12 @@ def handle_sjoin(irc, servernumeric, command, args):
|
|||||||
def handle_join(irc, numeric, command, args):
|
def handle_join(irc, numeric, command, args):
|
||||||
# parameters: channelTS, channel, '+' (a plus sign)
|
# parameters: channelTS, channel, '+' (a plus sign)
|
||||||
ts = int(args[0])
|
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':
|
if args[0] == '0':
|
||||||
# /join 0; part the user from all channels
|
# /join 0; part the user from all channels
|
||||||
oldchans = list(irc.users[numeric].channels)
|
oldchans = list(irc.users[numeric].channels)
|
||||||
@ -457,6 +461,7 @@ def handle_events(irc, data):
|
|||||||
irc.umodes.update(chary_umodes)
|
irc.umodes.update(chary_umodes)
|
||||||
# TODO: support module-created modes like +O, +S, etc.
|
# TODO: support module-created modes like +O, +S, etc.
|
||||||
# Does charybdis propagate these? If so, how?
|
# Does charybdis propagate these? If so, how?
|
||||||
|
log.debug('(%s) irc.connected set!', irc.name)
|
||||||
irc.connected.set()
|
irc.connected.set()
|
||||||
try:
|
try:
|
||||||
real_args = []
|
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
|
# We don't actually need to process this; it's just something plugins/hooks can use
|
||||||
return {'target': target, 'channel': channel}
|
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):
|
def handle_chghost(irc, numeric, command, args):
|
||||||
target = args[0]
|
target = args[0]
|
||||||
irc.users[target].host = newhost = args[1]
|
irc.users[target].host = newhost = args[1]
|
||||||
|
Loading…
Reference in New Issue
Block a user