mirror of
https://github.com/jlu5/PyLink.git
synced 2025-01-11 20:52:42 +01:00
core: make inbound SJOINs also respect the updateTS() rules
This commit is contained in:
parent
90ee20ee8b
commit
f2b139c828
46
classes.py
46
classes.py
@ -497,10 +497,6 @@ class Irc():
|
|||||||
else:
|
else:
|
||||||
log.debug('(%s) Using self.cmodes for this query: %s', self.name, self.cmodes)
|
log.debug('(%s) Using self.cmodes for this query: %s', self.name, self.cmodes)
|
||||||
|
|
||||||
if target not in self.channels:
|
|
||||||
log.warning('(%s) Possible desync! Mode target %s is not in the channels index.', self.name, target)
|
|
||||||
return []
|
|
||||||
|
|
||||||
supported_modes = self.cmodes
|
supported_modes = self.cmodes
|
||||||
oldmodes = self.channels[target].modes
|
oldmodes = self.channels[target].modes
|
||||||
res = []
|
res = []
|
||||||
@ -1067,17 +1063,12 @@ class Protocol():
|
|||||||
log.debug('Removing client %s from self.irc.servers[%s].users', numeric, sid)
|
log.debug('Removing client %s from self.irc.servers[%s].users', numeric, sid)
|
||||||
self.irc.servers[sid].users.discard(numeric)
|
self.irc.servers[sid].users.discard(numeric)
|
||||||
|
|
||||||
def updateTS(self, channel, their_ts, modes=[]):
|
def updateTS(self, channel, their_ts, modes=[], outbound=True):
|
||||||
"""
|
"""
|
||||||
Merges modes of a channel given the remote TS and a list of modes.
|
Merges modes of a channel given the remote TS and a list of modes.
|
||||||
|
|
||||||
This returns True when our modes apply (our TS <= theirs)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
our_ts = self.irc.channels[channel].ts
|
def _clear():
|
||||||
|
|
||||||
if their_ts < our_ts:
|
|
||||||
# Their TS is older than ours. Clear all modes.
|
|
||||||
log.debug('(%s) Setting channel TS of %s to %s from %s',
|
log.debug('(%s) Setting channel TS of %s to %s from %s',
|
||||||
self.irc.name, channel, their_ts, our_ts)
|
self.irc.name, channel, their_ts, our_ts)
|
||||||
self.irc.channels[channel].ts = their_ts
|
self.irc.channels[channel].ts = their_ts
|
||||||
@ -1086,17 +1077,36 @@ class Protocol():
|
|||||||
for p in self.irc.channels[channel].prefixmodes.values():
|
for p in self.irc.channels[channel].prefixmodes.values():
|
||||||
p.clear()
|
p.clear()
|
||||||
|
|
||||||
return False
|
def _apply():
|
||||||
|
self.irc.applyModes(channel, modes)
|
||||||
|
|
||||||
|
our_ts = self.irc.channels[channel].ts
|
||||||
|
|
||||||
|
if their_ts < our_ts:
|
||||||
|
# Their TS is older than ours. If we're receiving a mode change, we should
|
||||||
|
# clear our stored modes for the channel and apply theirs. Otherwise, if we're
|
||||||
|
# the one setting modes, just drop them.
|
||||||
|
log.debug("(%s/%s) remote TS of %s is lower than ours %s; outbound mode: %s; setting modes %s",
|
||||||
|
self.irc.name, channel, their_ts, our_ts, outbound, modes)
|
||||||
|
if not outbound:
|
||||||
|
_clear()
|
||||||
|
_apply()
|
||||||
|
|
||||||
elif their_ts == our_ts:
|
elif their_ts == our_ts:
|
||||||
|
log.debug("(%s/%s) remote TS of %s is equal to ours %s; outbound mode: %s; setting modes %s",
|
||||||
|
self.irc.name, channel, their_ts, our_ts, outbound, modes)
|
||||||
# Their TS is equal to ours. Merge modes.
|
# Their TS is equal to ours. Merge modes.
|
||||||
self.irc.applyModes(channel, modes)
|
_apply()
|
||||||
return True
|
|
||||||
elif their_ts > our_ts:
|
elif their_ts > our_ts:
|
||||||
# Their TS is younger than ours. Replace their modes with ours.
|
log.debug("(%s/%s) remote TS of %s is higher than ours %s; outbound mode: %s; setting modes %s",
|
||||||
self.irc.channels[channel].modes.clear()
|
self.irc.name, channel, their_ts, our_ts, outbound, modes)
|
||||||
self.irc.applyModes(channel, modes)
|
# Their TS is younger than ours. If we're setting modes, clear the state
|
||||||
return True
|
# and replace the modes for the channel with ours. Otherwise, just ignore the
|
||||||
|
# remote's changes.
|
||||||
|
if outbound:
|
||||||
|
_clear()
|
||||||
|
_apply()
|
||||||
|
|
||||||
def _getSid(self, sname):
|
def _getSid(self, sname):
|
||||||
"""Returns the SID of a server with the given name, if present."""
|
"""Returns the SID of a server with the given name, if present."""
|
||||||
|
@ -498,14 +498,14 @@ class InspIRCdProtocol(TS6BaseProtocol):
|
|||||||
# InspIRCd sends each channel's users in the form of 'modeprefix(es),UID'
|
# InspIRCd sends each channel's users in the form of 'modeprefix(es),UID'
|
||||||
userlist = args[-1].split()
|
userlist = args[-1].split()
|
||||||
|
|
||||||
their_ts = int(args[1])
|
|
||||||
our_ts = self.irc.channels[channel].ts
|
|
||||||
self.updateTS(channel, their_ts)
|
|
||||||
|
|
||||||
modestring = args[2:-1] or args[2]
|
modestring = args[2:-1] or args[2]
|
||||||
parsedmodes = self.irc.parseModes(channel, modestring)
|
parsedmodes = self.irc.parseModes(channel, modestring)
|
||||||
self.irc.applyModes(channel, parsedmodes)
|
self.irc.applyModes(channel, parsedmodes)
|
||||||
namelist = []
|
namelist = []
|
||||||
|
|
||||||
|
# Keep track of other modes that are added due to prefix modes being joined too.
|
||||||
|
changedmodes = set(parsedmodes)
|
||||||
|
|
||||||
for user in userlist:
|
for user in userlist:
|
||||||
modeprefix, user = user.split(',', 1)
|
modeprefix, user = user.split(',', 1)
|
||||||
|
|
||||||
@ -517,9 +517,17 @@ class InspIRCdProtocol(TS6BaseProtocol):
|
|||||||
|
|
||||||
namelist.append(user)
|
namelist.append(user)
|
||||||
self.irc.users[user].channels.add(channel)
|
self.irc.users[user].channels.add(channel)
|
||||||
if their_ts <= our_ts:
|
|
||||||
self.irc.applyModes(channel, [('+%s' % mode, user) for mode in modeprefix])
|
# Only save mode changes if the remote has lower TS than us.
|
||||||
|
changedmodes |= {('+%s' % mode, user) for mode in modeprefix}
|
||||||
|
|
||||||
self.irc.channels[channel].users.add(user)
|
self.irc.channels[channel].users.add(user)
|
||||||
|
|
||||||
|
# Statekeeping with timestamps
|
||||||
|
their_ts = int(args[1])
|
||||||
|
our_ts = self.irc.channels[channel].ts
|
||||||
|
self.updateTS(channel, their_ts, changedmodes, outbound=False)
|
||||||
|
|
||||||
return {'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts}
|
return {'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts}
|
||||||
|
|
||||||
def handle_uid(self, numeric, command, args):
|
def handle_uid(self, numeric, command, args):
|
||||||
|
@ -938,10 +938,6 @@ class P10Protocol(Protocol):
|
|||||||
|
|
||||||
channel = self.irc.toLower(args[0])
|
channel = self.irc.toLower(args[0])
|
||||||
userlist = args[-1].split()
|
userlist = args[-1].split()
|
||||||
their_ts = int(args[1])
|
|
||||||
our_ts = self.irc.channels[channel].ts
|
|
||||||
|
|
||||||
self.updateTS(channel, their_ts)
|
|
||||||
|
|
||||||
bans = []
|
bans = []
|
||||||
if args[-1].startswith('%'):
|
if args[-1].startswith('%'):
|
||||||
@ -972,6 +968,9 @@ class P10Protocol(Protocol):
|
|||||||
else:
|
else:
|
||||||
parsedmodes = []
|
parsedmodes = []
|
||||||
|
|
||||||
|
# Keep track of other modes that are added due to prefix modes being joined too.
|
||||||
|
changedmodes = set(parsedmodes)
|
||||||
|
|
||||||
# Add the ban list to the list of modes to process.
|
# Add the ban list to the list of modes to process.
|
||||||
parsedmodes.extend(bans)
|
parsedmodes.extend(bans)
|
||||||
|
|
||||||
@ -1006,11 +1005,16 @@ class P10Protocol(Protocol):
|
|||||||
|
|
||||||
self.irc.users[user].channels.add(channel)
|
self.irc.users[user].channels.add(channel)
|
||||||
|
|
||||||
if their_ts <= our_ts:
|
# Only save mode changes if the remote has lower TS than us.
|
||||||
self.irc.applyModes(channel, [('+%s' % mode, user) for mode in prefixes])
|
changedmodes |= {('+%s' % mode, user) for mode in prefixes}
|
||||||
|
|
||||||
self.irc.channels[channel].users.add(user)
|
self.irc.channels[channel].users.add(user)
|
||||||
|
|
||||||
|
# Statekeeping with timestamps
|
||||||
|
their_ts = int(args[1])
|
||||||
|
our_ts = self.irc.channels[channel].ts
|
||||||
|
self.updateTS(channel, their_ts, changedmodes, outbound=False)
|
||||||
|
|
||||||
return {'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts}
|
return {'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts}
|
||||||
|
|
||||||
def handle_join(self, source, command, args):
|
def handle_join(self, source, command, args):
|
||||||
|
@ -436,15 +436,15 @@ class TS6Protocol(TS6BaseProtocol):
|
|||||||
# <- :0UY SJOIN 1451041566 #channel +nt :@0UYAAAAAB
|
# <- :0UY SJOIN 1451041566 #channel +nt :@0UYAAAAAB
|
||||||
channel = self.irc.toLower(args[1])
|
channel = self.irc.toLower(args[1])
|
||||||
userlist = args[-1].split()
|
userlist = args[-1].split()
|
||||||
their_ts = int(args[0])
|
|
||||||
our_ts = self.irc.channels[channel].ts
|
|
||||||
|
|
||||||
self.updateTS(channel, their_ts)
|
|
||||||
|
|
||||||
modestring = args[2:-1] or args[2]
|
modestring = args[2:-1] or args[2]
|
||||||
parsedmodes = self.irc.parseModes(channel, modestring)
|
parsedmodes = self.irc.parseModes(channel, modestring)
|
||||||
self.irc.applyModes(channel, parsedmodes)
|
self.irc.applyModes(channel, parsedmodes)
|
||||||
namelist = []
|
namelist = []
|
||||||
|
|
||||||
|
# Keep track of other modes that are added due to prefix modes being joined too.
|
||||||
|
changedmodes = set(parsedmodes)
|
||||||
|
|
||||||
log.debug('(%s) handle_sjoin: got userlist %r for %r', self.irc.name, userlist, channel)
|
log.debug('(%s) handle_sjoin: got userlist %r for %r', self.irc.name, userlist, channel)
|
||||||
for userpair in userlist:
|
for userpair in userlist:
|
||||||
# charybdis sends this in the form "@+UID1, +UID2, UID3, @UID4"
|
# charybdis sends this in the form "@+UID1, +UID2, UID3, @UID4"
|
||||||
@ -469,9 +469,16 @@ class TS6Protocol(TS6BaseProtocol):
|
|||||||
finalprefix += char
|
finalprefix += char
|
||||||
namelist.append(user)
|
namelist.append(user)
|
||||||
self.irc.users[user].channels.add(channel)
|
self.irc.users[user].channels.add(channel)
|
||||||
if their_ts <= our_ts:
|
|
||||||
self.irc.applyModes(channel, [('+%s' % mode, user) for mode in finalprefix])
|
# Only save mode changes if the remote has lower TS than us.
|
||||||
|
changedmodes |= {('+%s' % mode, user) for mode in finalprefix}
|
||||||
self.irc.channels[channel].users.add(user)
|
self.irc.channels[channel].users.add(user)
|
||||||
|
|
||||||
|
# Statekeeping with timestamps
|
||||||
|
their_ts = int(args[0])
|
||||||
|
our_ts = self.irc.channels[channel].ts
|
||||||
|
self.updateTS(channel, their_ts, changedmodes, outbound=False)
|
||||||
|
|
||||||
return {'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts}
|
return {'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts}
|
||||||
|
|
||||||
def handle_join(self, numeric, command, args):
|
def handle_join(self, numeric, command, args):
|
||||||
|
@ -556,12 +556,12 @@ class UnrealProtocol(TS6BaseProtocol):
|
|||||||
channel = self.irc.toLower(args[1])
|
channel = self.irc.toLower(args[1])
|
||||||
userlist = args[-1].split()
|
userlist = args[-1].split()
|
||||||
|
|
||||||
our_ts = self.irc.channels[channel].ts
|
|
||||||
their_ts = int(args[0])
|
|
||||||
self.updateTS(channel, their_ts)
|
|
||||||
|
|
||||||
namelist = []
|
namelist = []
|
||||||
log.debug('(%s) handle_sjoin: got userlist %r for %r', self.irc.name, userlist, channel)
|
log.debug('(%s) handle_sjoin: got userlist %r for %r', self.irc.name, userlist, channel)
|
||||||
|
|
||||||
|
# Keep track of other modes that are added due to prefix modes being joined too.
|
||||||
|
changedmodes = set(self.irc.channels[channel].modes)
|
||||||
|
|
||||||
for userpair in userlist:
|
for userpair in userlist:
|
||||||
if userpair.startswith("&\"'"): # TODO: handle ban bursts too
|
if userpair.startswith("&\"'"): # TODO: handle ban bursts too
|
||||||
# &, ", and ' entries are used for bursting bans:
|
# &, ", and ' entries are used for bursting bans:
|
||||||
@ -583,10 +583,16 @@ class UnrealProtocol(TS6BaseProtocol):
|
|||||||
finalprefix += char
|
finalprefix += char
|
||||||
namelist.append(user)
|
namelist.append(user)
|
||||||
self.irc.users[user].channels.add(channel)
|
self.irc.users[user].channels.add(channel)
|
||||||
|
|
||||||
# Only merge the remote's prefix modes if their TS is smaller or equal to ours.
|
# Only merge the remote's prefix modes if their TS is smaller or equal to ours.
|
||||||
if their_ts <= our_ts:
|
changedmodes |= {('+%s' % mode, user) for mode in finalprefix}
|
||||||
self.irc.applyModes(channel, [('+%s' % mode, user) for mode in finalprefix])
|
|
||||||
self.irc.channels[channel].users.add(user)
|
self.irc.channels[channel].users.add(user)
|
||||||
|
|
||||||
|
our_ts = self.irc.channels[channel].ts
|
||||||
|
their_ts = int(args[0])
|
||||||
|
self.updateTS(channel, their_ts, changedmodes, outbound=False)
|
||||||
|
|
||||||
return {'channel': channel, 'users': namelist, 'modes': self.irc.channels[channel].modes, 'ts': their_ts}
|
return {'channel': channel, 'users': namelist, 'modes': self.irc.channels[channel].modes, 'ts': their_ts}
|
||||||
|
|
||||||
def handle_nick(self, numeric, command, args):
|
def handle_nick(self, numeric, command, args):
|
||||||
|
Loading…
Reference in New Issue
Block a user