diff --git a/plugins/relay.py b/plugins/relay.py index 7b65f3f..5187571 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -479,9 +479,15 @@ def relayModes(irc, remoteirc, sender, channel, modes=None): log.debug('(%s) Relay mode: remotechan for %s on %s is %s', irc.name, channel, irc.name, remotechan) if remotechan is None: return + rc = remoteirc.channels[remotechan] + c = irc.channels[channel] if modes is None: - modes = irc.channels[channel].modes - log.debug('(%s) Relay mode: channel data for %s%s: %s', irc.name, remoteirc.name, remotechan, remoteirc.channels[remotechan]) + modes = c.modes + log.debug('(%s) Relay mode: channel data for %s%s: %s', irc.name, remoteirc.name, remotechan, rc) + if c.ts > rc.ts: + log.debug('(%s) Relay mode: dropping relaying modes %r to %s%s, since our TS (%s) is greater than theirs (%s)', + irc.name, modes, remoteirc.name, remotechan, c.ts, rc.ts) + return supported_modes = [] log.debug('(%s) Relay mode: initial modelist for %s is %s', irc.name, channel, modes) for modepair in modes: @@ -660,6 +666,8 @@ def relayJoins(irc, channel, users, ts, modes): # bother spawning it. continue log.debug('(%s) relayJoins: got %r for users', irc.name, users) + ts = irc.channels[channel].ts + rts = remoteirc.channels[remotechan].ts for user in users.copy(): if utils.isInternalClient(irc, user) or user not in irc.users: # We don't need to clone PyLink pseudoclients... That's @@ -678,8 +686,10 @@ def relayJoins(irc, channel, users, ts, modes): # Only join users if they aren't already joined. This prevents op floods # on charybdis from all the SJOINing. if u not in remoteirc.channels[channel].users: - ts = irc.channels[channel].ts - prefixes = getPrefixModes(irc, remoteirc, channel, user) + if ts < rts: + prefixes = getPrefixModes(irc, remoteirc, channel, user) + else: + prefixes = '' userpair = (prefixes, u) queued_users.append(userpair) log.debug('(%s) relayJoins: joining %s to %s%s', irc.name, userpair, remoteirc.name, remotechan) diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 995dc6c..b88e9f5 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -367,6 +367,9 @@ def handle_fjoin(irc, servernumeric, command, args): log.debug('(%s) Setting channel TS of %s to %s from %s', irc.name, channel, their_ts, our_ts) irc.channels[channel].ts = their_ts + irc.channels[channel].modes.clear() + for p in irc.channels[channel].prefixmodes.values(): + p.clear() modestring = args[2:-1] or args[2] parsedmodes = utils.parseModes(irc, channel, modestring) utils.applyModes(irc, channel, parsedmodes) diff --git a/protocols/ts6.py b/protocols/ts6.py index 6a4f4e5..d4f617b 100644 --- a/protocols/ts6.py +++ b/protocols/ts6.py @@ -82,7 +82,6 @@ def sjoinServer(irc, server, channel, users, ts=None): log.debug("sending SJOIN to %s%s with ts %s (that's %r)", channel, irc.name, ts, time.strftime("%c", time.localtime(ts))) modes = [m for m in irc.channels[channel].modes if m[0] not in irc.cmodes['*A']] - changedmodes = [] while users[:10]: uids = [] namelist = [] @@ -107,7 +106,7 @@ def sjoinServer(irc, server, channel, users, ts=None): ts=ts, users=namelist, channel=channel, modes=utils.joinModes(modes))) irc.channels[channel].users.update(uids) - utils.applyModes(irc, channel, changedmodes) + utils.applyModes(irc, channel, modes) def _sendModes(irc, numeric, target, modes, ts=None): utils.applyModes(irc, target, modes) @@ -372,6 +371,9 @@ def handle_sjoin(irc, servernumeric, command, args): log.debug('(%s) Setting channel TS of %s to %s from %s', irc.name, channel, their_ts, our_ts) irc.channels[channel].ts = their_ts + irc.channels[channel].modes.clear() + for p in irc.channels[channel].prefixmodes.values(): + p.clear() modestring = args[2:-1] or args[2] parsedmodes = utils.parseModes(irc, channel, modestring) utils.applyModes(irc, channel, parsedmodes)