Add channel-specific 'enabled' setting.

This allows easier and more thorough disabling
of the plugin features per channel.
This commit is contained in:
Krytarik Raido 2023-10-22 21:03:10 +02:00
parent d2d25f94d2
commit acde82892a
2 changed files with 83 additions and 46 deletions

View File

@ -67,6 +67,9 @@ conf.registerGlobalValue(ChanTracker, 'resolveIp',
## per-channel settings ## per-channel settings
conf.registerChannelValue(ChanTracker, 'enabled',
registry.Boolean(False, """monitor the channel and act following the rest of the settings"""))
conf.registerChannelValue(ChanTracker, 'modeD', conf.registerChannelValue(ChanTracker, 'modeD',
registry.String("", """special mode if you want to use some specific stuff; registry.String("", """special mode if you want to use some specific stuff;
$hostmask (*!*@*), $klinemask (*@*), $host, $channel, $reason, $nick and $duration are available""")) $hostmask (*!*@*), $klinemask (*@*), $host, $channel, $reason, $nick and $duration are available"""))

126
plugin.py
View File

@ -1505,7 +1505,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if world: if world:
if world.ircs: if world.ircs:
for irc in world.ircs: for irc in world.ircs:
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
logChannel = self.registryValue('logChannel', channel=channel, network=irc.network) logChannel = self.registryValue('logChannel', channel=channel, network=irc.network)
if logChannel and logChannel in irc.state.channels: if logChannel and logChannel in irc.state.channels:
toNag = '' toNag = ''
@ -2817,7 +2819,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
# restore channel state, load lists # restore channel state, load lists
modesToAsk = ''.join(self.registryValue('modesToAsk', channel=channel, network=irc.network)) modesToAsk = ''.join(self.registryValue('modesToAsk', channel=channel, network=irc.network))
modesWhenOpped = ''.join(self.registryValue('modesToAskWhenOpped', channel=channel, network=irc.network)) modesWhenOpped = ''.join(self.registryValue('modesToAskWhenOpped', channel=channel, network=irc.network))
if channel in irc.state.channels: if channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
if len(modesWhenOpped) and irc.state.channels[channel].isHalfopPlus(irc.nick): if len(modesWhenOpped) and irc.state.channels[channel].isHalfopPlus(irc.nick):
for m in modesWhenOpped: for m in modesWhenOpped:
i.queue.enqueue(ircmsgs.mode(channel, args=(m,))) i.queue.enqueue(ircmsgs.mode(channel, args=(m,)))
@ -2924,6 +2927,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if not i.whoxpending: if not i.whoxpending:
candidate = None candidate = None
for channel in list(irc.state.channels.keys()): for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
if not chan.syn: if not chan.syn:
candidate = channel candidate = channel
@ -2961,6 +2966,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
def f(L): def f(L):
return ircmsgs.modes(channel, L) return ircmsgs.modes(channel, L)
for channel in list(irc.state.channels.keys()): for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
# check expired items # check expired items
for mode in list(chan.getItems().keys()): for mode in list(chan.getItems().keys()):
@ -3318,7 +3325,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
elif utils.net.isIP(msg.prefix.split('@')[1]): elif utils.net.isIP(msg.prefix.split('@')[1]):
n.setIp(msg.prefix.split('@')[1]) n.setIp(msg.prefix.split('@')[1])
for channel in channels: for channel in channels:
if ircutils.isChannel(channel) and channel in irc.state.channels: if ircutils.isChannel(channel) and channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
bests = getBestPattern(n, irc, self.registryValue( bests = getBestPattern(n, irc, self.registryValue(
'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp')) 'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp'))
best = bests[0] best = bests[0]
@ -3417,7 +3425,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if isBot and channel in i.channels: if isBot and channel in i.channels:
del i.channels[channel] del i.channels[channel]
continue continue
if ircutils.isChannel(channel) and channel in irc.state.channels: if ircutils.isChannel(channel) and channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
bests = getBestPattern(n, irc, self.registryValue( bests = getBestPattern(n, irc, self.registryValue(
'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp')) 'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp'))
best = bests[0] best = bests[0]
@ -3499,35 +3508,36 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
return return
n = self.getNick(irc, target) n = self.getNick(irc, target)
n.addLog(channel, 'kicked by %s (%s)' % (msg.prefix, reason)) n.addLog(channel, 'kicked by %s (%s)' % (msg.prefix, reason))
if self.registryValue('announceKick', channel=channel, network=irc.network): if self.registryValue('enabled', channel=channel, network=irc.network):
if self.registryValue('useColorForAnnounces', channel=channel, network=irc.network): if self.registryValue('announceKick', channel=channel, network=irc.network):
self._logChan(irc, channel, '[%s] %s kicks %s (%s)' % ( if self.registryValue('useColorForAnnounces', channel=channel, network=irc.network):
ircutils.bold(channel), msg.nick, self._logChan(irc, channel, '[%s] %s kicks %s (%s)' % (
ircutils.mircColor(n.prefix, 'light blue'), reason)) ircutils.bold(channel), msg.nick,
else: ircutils.mircColor(n.prefix, 'light blue'), reason))
self._logChan(irc, channel, '[%s] %s kicks %s (%s)' % ( else:
channel, msg.nick, n.prefix, reason)) self._logChan(irc, channel, '[%s] %s kicks %s (%s)' % (
if len(reason) and msg.prefix != irc.prefix \ channel, msg.nick, n.prefix, reason))
and self.registryValue('addKickMessageInComment', channel=channel, network=irc.network): if len(reason) and msg.prefix != irc.prefix \
chan = self.getChan(irc, channel) and self.registryValue('addKickMessageInComment', channel=channel, network=irc.network):
found = None chan = self.getChan(irc, channel)
for mode in self.registryValue('modesToAsk', channel=channel, network=irc.network): found = None
items = chan.getItemsFor(mode) for mode in self.registryValue('modesToAsk', channel=channel, network=irc.network):
for k in items: items = chan.getItemsFor(mode)
item = items[k] for k in items:
f = match(item.value, n, irc, self.registryValue('resolveIp')) item = items[k]
if f: f = match(item.value, n, irc, self.registryValue('resolveIp'))
found = item if f:
found = item
break
if found:
break break
if found: if found:
break f = None
if found: if self.registryValue('announceBotMark', channel=channel, network=irc.network):
f = None f = self._logChan
if self.registryValue('announceBotMark', channel=channel, network=irc.network): i = self.getIrc(irc)
f = self._logChan i.mark(irc, found.uid, 'kicked by %s (%s)' % (
i = self.getIrc(irc) msg.nick, reason), irc.prefix, self.getDb(irc.network), f, self)
i.mark(irc, found.uid, 'kicked by %s (%s)' % (
msg.nick, reason), irc.prefix, self.getDb(irc.network), f, self)
if not isBot: if not isBot:
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
if target in chan.nicks: if target in chan.nicks:
@ -3543,13 +3553,15 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
return return
found = False found = False
(nick, ident, hostmask) = ircutils.splitHostmask(n.prefix) (nick, ident, hostmask) = ircutils.splitHostmask(n.prefix)
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if nick in irc.state.channels[channel].users: if nick in irc.state.channels[channel].users:
found = True found = True
if not found: if not found:
if nick in i.nicks: if nick in i.nicks:
del i.nicks[nick] del i.nicks[nick]
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
bests = getBestPattern(n, irc, self.registryValue( bests = getBestPattern(n, irc, self.registryValue(
'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp')) 'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp'))
best = bests[0] best = bests[0]
@ -3611,7 +3623,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if len(msg.args) == 1: if len(msg.args) == 1:
reason = msg.args[0].strip() reason = msg.args[0].strip()
if reason and reason == '*.net *.split': if reason and reason == '*.net *.split':
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
if msg.nick in chan.nicks and not chan.netsplit: if msg.nick in chan.nicks and not chan.netsplit:
self._split(irc, channel) self._split(irc, channel)
@ -3643,7 +3657,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if not ('Nickname regained by services' in reason if not ('Nickname regained by services' in reason
or 'NickServ (GHOST command used by ' in reason or 'NickServ (GHOST command used by ' in reason
or 'NickServ (Forcing logout ' in reason): or 'NickServ (Forcing logout ' in reason):
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
if msg.nick in chan.nicks: if msg.nick in chan.nicks:
if self.registryValue('announceKick', channel=channel, network=irc.network): if self.registryValue('announceKick', channel=channel, network=irc.network):
@ -3655,7 +3671,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
else: else:
self._logChan(irc, channel, '[%s] %s has quit (%s)' % ( self._logChan(irc, channel, '[%s] %s has quit (%s)' % (
channel, msg.prefix, reason)) channel, msg.prefix, reason))
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
if msg.nick in chan.nicks: if msg.nick in chan.nicks:
if not self._isVip(irc, channel, n): if not self._isVip(irc, channel, n):
@ -3667,8 +3685,7 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if p.startswith('$a:'): if p.startswith('$a:'):
best = p best = p
break break
isCycle = self._isSomething( isCycle = self._isSomething(irc, channel, best, 'cycle')
irc, channel, best, 'cycle')
if isCycle: if isCycle:
isBad = self._isSomething(irc, channel, best, 'bad') isBad = self._isSomething(irc, channel, best, 'bad')
if isBad: if isBad:
@ -3710,7 +3727,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
best = patterns[0] best = patterns[0]
if not best: if not best:
return return
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
bests = getBestPattern(n, irc, self.registryValue( bests = getBestPattern(n, irc, self.registryValue(
'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp')) 'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp'))
best = bests[0] best = bests[0]
@ -3764,8 +3783,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
return return
if nick and n and n.account and n.ip: if nick and n and n.account and n.ip:
i = self.getIrc(irc) i = self.getIrc(irc)
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if self.registryValue('checkEvade', channel=channel, network=irc.network): if self.registryValue('enabled', channel=channel, network=irc.network) \
and self.registryValue('checkEvade', channel=channel, network=irc.network):
if nick in irc.state.channels[channel].users: if nick in irc.state.channels[channel].users:
modes = self.registryValue('modesToAsk', channel=channel, network=irc.network) modes = self.registryValue('modesToAsk', channel=channel, network=irc.network)
found = None found = None
@ -3826,7 +3846,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
channel = channel.replace('@', '', 1) channel = channel.replace('@', '', 1)
if channel.startswith('+'): if channel.startswith('+'):
channel = channel.replace('+', '', 1) channel = channel.replace('+', '', 1)
if irc.isChannel(channel) and channel in irc.state.channels: if irc.isChannel(channel) and channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
bests = getBestPattern(n, irc, self.registryValue( bests = getBestPattern(n, irc, self.registryValue(
'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp')) 'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp'))
best = bests[0] best = bests[0]
@ -3924,7 +3945,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
channel = channel.replace('@', '', 1) channel = channel.replace('@', '', 1)
if channel.startswith('+'): if channel.startswith('+'):
channel = channel.replace('+', '', 1) channel = channel.replace('+', '', 1)
if irc.isChannel(channel) and channel in irc.state.channels: if irc.isChannel(channel) and channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
bests = getBestPattern(n, irc, self.registryValue( bests = getBestPattern(n, irc, self.registryValue(
'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp')) 'useIpForGateway', channel=channel, network=irc.network), self.registryValue('resolveIp'))
best = bests[0] best = bests[0]
@ -4185,7 +4207,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
if 'account' in msg.server_tags: if 'account' in msg.server_tags:
n.setAccount(msg.server_tags['account']) n.setAccount(msg.server_tags['account'])
channel = msg.args[0] channel = msg.args[0]
if channel in irc.state.channels: if channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
if n: if n:
n.addLog(channel, 'sets topic "%s"' % msg.args[1]) n.addLog(channel, 'sets topic "%s"' % msg.args[1])
if self.registryValue('announceTopic', channel=channel, network=irc.network): if self.registryValue('announceTopic', channel=channel, network=irc.network):
@ -4227,7 +4250,9 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
# TODO: add support for other ircds if possible, currently only freenode # TODO: add support for other ircds if possible, currently only freenode
b = '%sj:%s' % (self.getIrcdExtbansPrefix(irc), fromChannel) b = '%sj:%s' % (self.getIrcdExtbansPrefix(irc), fromChannel)
kicks = [] kicks = []
for channel in irc.state.channels: for channel in list(irc.state.channels.keys()):
if not self.registryValue('enabled', channel=channel, network=irc.network):
continue
if b in irc.state.channels[channel].bans \ if b in irc.state.channels[channel].bans \
and mode in self.registryValue('kickMode', channel=channel, network=irc.network) \ and mode in self.registryValue('kickMode', channel=channel, network=irc.network) \
and self.registryValue('kickOnMode', channel=channel, network=irc.network): and self.registryValue('kickOnMode', channel=channel, network=irc.network):
@ -4265,7 +4290,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
toexpire = [] toexpire = []
tolift = [] tolift = []
toremove = [] toremove = []
if irc.isChannel(channel) and msg.args[1:] and channel in irc.state.channels: if irc.isChannel(channel) and msg.args[1:] and channel in irc.state.channels \
and self.registryValue('enabled', channel=channel, network=irc.network):
modes = ircutils.separateModes(msg.args[1:]) modes = ircutils.separateModes(msg.args[1:])
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
msgs = [] msgs = []
@ -4670,6 +4696,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
log.error('%s %s %s %s %s unsupported mode' % (channel, mode, mask, duration, reason)) log.error('%s %s %s %s %s unsupported mode' % (channel, mode, mask, duration, reason))
def _isSomething(self, irc, channel, key, prop): def _isSomething(self, irc, channel, key, prop):
if not self.registryValue('enabled', channel=channel, network=irc.network):
return False
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
if prop == 'massJoin' or prop == 'cycle': if prop == 'massJoin' or prop == 'cycle':
if chan.netsplit: if chan.netsplit:
@ -4725,6 +4753,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
return b return b
def _isHilight(self, irc, channel, key, message): def _isHilight(self, irc, channel, key, message):
if not self.registryValue('enabled', channel=channel, network=irc.network):
return False
limit = self.registryValue('hilightPermit', channel=channel, network=irc.network) limit = self.registryValue('hilightPermit', channel=channel, network=irc.network)
if limit < 0: if limit < 0:
return False return False
@ -4787,6 +4817,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
return (bad, candidate) return (bad, candidate)
def _isRepeat(self, irc, channel, key, message): def _isRepeat(self, irc, channel, key, message):
if not self.registryValue('enabled', channel=channel, network=irc.network):
return False
if self.registryValue('repeatPermit', channel=channel, network=irc.network) < 0: if self.registryValue('repeatPermit', channel=channel, network=irc.network) < 0:
return False return False
chan = self.getChan(irc, channel) chan = self.getChan(irc, channel)
@ -4826,6 +4858,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler):
return result return result
def _isCap(self, irc, channel, key, message): def _isCap(self, irc, channel, key, message):
if not self.registryValue('enabled', channel=channel, network=irc.network):
return False
if self.registryValue('capPermit', channel=channel, network=irc.network) < 0: if self.registryValue('capPermit', channel=channel, network=irc.network) < 0:
return False return False
trigger = self.registryValue('capPercent', channel=channel, network=irc.network) trigger = self.registryValue('capPercent', channel=channel, network=irc.network)