3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-12-28 13:42:37 +01:00

clientbot: implement ban list enumeration on JOIN

Closes #530.
This commit is contained in:
James Lu 2017-09-23 21:25:48 -07:00
parent b52082ed05
commit 6e89dbed24
2 changed files with 66 additions and 0 deletions

View File

@ -441,6 +441,13 @@ servers:
# "relay:" configuration block, and defaults to True for consistency with older releases.
#relay_weird_senders: false
# Determines whether the bot should enumerate ban/banexception/invex modes when joining channels.
# This is required for relay mode sync to work properly, because the bot will otherwise refuse to
# relay unbans (Clientbot only removes modes that it knows are set).
# This defaults to False because it causes extra MODE messages to be sent on connect, which can
# drastically slow down startup if the bot joins a lot of channels.
#fetch_ban_lists: true
# Plugins to load (omit the .py extension)
plugins:
# Commands plugin: Provides simple commands to check login status, show info on users and

View File

@ -861,6 +861,13 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
if self.pseudoclient and source == self.pseudoclient.uid:
self.send('MODE %s' % channel)
self._send_who(channel)
if self.serverdata.get('fetch_ban_lists', False):
self.send('MODE %s +b' % channel)
for m in ('banexception', 'invex'):
if m in self.cmodes:
self.send('MODE %s +%s' % (channel, self.cmodes[m]))
else:
self.call_hooks([source, 'CLIENTBOT_JOIN', {'channel': channel}])
return {'channel': channel, 'users': [source], 'modes': self._channels[channel].modes}
@ -1058,4 +1065,56 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
# 492: ERR_NOCTCP on Hybrid
handle_492 = handle_404
def handle_367(self, source, command, args, banmode='b'):
"""
Handles RPL_BANLIST, used to enumerate bans.
"""
# <- :irc3.lose-the-game.nat 367 james #test *!*@1.2.3.4 james 1504560159
channel = args[1]
target = args[2]
if channel not in self.channels:
log.warning('(%s) got ban mode +%s %s on unknown channel %s?', self.name, banmode, target)
else:
# Just apply the mode; we send out a mode hook only when the corresponding ban list has finished sending.
self.apply_modes(channel, [('+%s' % banmode, target)])
def handle_368(self, source, command, args, banmode='b'):
"""
Handles RPL_ENDOFBANLIST, used to end off ban lists.
"""
# <- :irc3.lose-the-game.nat 368 james #test :End of Channel Ban List
channel = args[1]
# Send out the hook. We don't worry about repeats since these modes don't need to be
# enumerated more than once per JOIN anyways.
return {'target': channel, 'parse_as': 'MODE',
'modes': [('+%s' % banmode, m[1]) for m in self.channels[channel].modes if m[0] == banmode]}
def handle_346(self, *args):
"""
Handles RPL_INVITELIST, used to enumerate invite exceptions.
"""
return self.handle_367(*args, banmode=self.cmodes.get('invex', 'I'))
def handle_347(self, *args):
"""
Handles RPL_ENDOFINVITELIST, used to end off invite exception lists.
"""
if 'invex' not in self.cmodes:
log.warning('(%s) Got 347 / RPL_ENDOFINVITELIST even though invex is not a registered mode?', self.name)
return self.handle_368(*args, banmode=self.cmodes.get('invex', 'I'))
def handle_348(self, *args):
"""
Handles RPL_EXCEPTLIST, used to enumerate ban exceptions.
"""
return self.handle_367(*args, banmode=self.cmodes.get('banexception', 'e'))
def handle_349(self, *args):
"""
Handles RPL_ENDOFEXCEPTLIST, used to end off ban exception lists.
"""
if 'banexception' not in self.cmodes:
log.warning('(%s) Got 349 / RPL_ENDOFEXCEPTLIST even though banexception is not a registered mode?', self.name)
return self.handle_368(*args, banmode=self.cmodes.get('banexception', 'e'))
Class = ClientbotWrapperProtocol