From 922e6b83ab0abfc9fa6c2ee9533060c9a9d4c12b Mon Sep 17 00:00:00 2001 From: Nicolas Coevoet Date: Tue, 29 Jun 2021 20:33:01 +0200 Subject: [PATCH] added new registry entry modeD, which can be customized when using mode D, added shareable temporary patterns, and two methods to deal with them, addtmp, rmtmp --- README.md | 2 ++ config.py | 9 ++++++- plugin.py | 76 +++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 62fefd3..d9a54af 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ Note that you may need a newer version of Limnoria than your distribution provid !addregexpattern [] (qbeId) [y] [w] [d] [h] [m] [s] //) add a which triggers for if the appears more than (0 for immediate action) during in seconds !rmpattern [] [] remove patterns !lspattern [] [] return patterns in filtered by optional or + !addtmp [] add temporary pattern which follows repeat punishments + !rmtmp [] remove temporary patterns if any !cflood [] [] [] [] [] return channel protections configuration !crepeat [] [] [] [] [] [] [] [] [] [] return channel protections configuration, is a float between 0 and 1 diff --git a/config.py b/config.py index 61b7514..8303ce3 100644 --- a/config.py +++ b/config.py @@ -61,6 +61,9 @@ conf.registerGlobalValue(ChanTracker, 'announceNagInterval', conf.registerGlobalValue(ChanTracker, 'resolveIp', registry.Boolean(True, """trying to resolve host's ip with socket, could add latency""")) +conf.registerGlobalValue(ChanTracker, 'modeD', + registry.String("", """special mode if you want to use some specific stuff $hostmask (*!*@*) $klinemask (*@*) $host $channel $reason and $duration are available""")) + # per channel settings conf.registerChannelValue(ChanTracker, 'useAccountBanIfPossible', @@ -158,6 +161,9 @@ conf.registerChannelValue(ChanTracker, 'announceCtcp', conf.registerChannelValue(ChanTracker, 'announceNagMode', registry.CommaSeparatedListOfStrings([], """bot will announce that channel has such mode at announceNagInterval""")) +conf.registerChannelValue(ChanTracker, 'announceRepeatPattern', + registry.Boolean(True, """announce repeat pattern created to logChannel""")) + # others settings conf.registerChannelValue(ChanTracker, 'doNothingAboutOwnOpStatus', @@ -267,7 +273,8 @@ conf.registerChannelValue(ChanTracker, 'repeatPatternMinimum', conf.registerChannelValue(ChanTracker, 'repeatPatternLife', registry.PositiveInteger(300, """duration of pattern life""")) - +conf.registerChannelValue(ChanTracker, 'shareComputedPatternID', + registry.Integer(-1, """share computed patterns accross channels using the same ID, -1 to disable""")) # YES IT'S ANNOYING conf.registerChannelValue(ChanTracker, 'capPermit', diff --git a/plugin.py b/plugin.py index 6bc7976..f483a73 100644 --- a/plugin.py +++ b/plugin.py @@ -2342,6 +2342,26 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): irc.reply('%s' % ', '.join(results)) rmmode = wrap(rmmode, ['owner', commalist('int')]) + def rmtmp(self, irc, msg, args, channel): + """[] + + remove temporary patterns if any""" + chan = self.getChan(irc, channel) + key = 'pattern%s' % channel + if key in chan.repeatLogs: + life = self.registryValue('repeatPatternLife', channel=channel) + chan.repeatLogs[key] = utils.structures.TimeoutQueue(life) + irc.replySuccess() + rmtmp = wrap(rmtmp, ['op']) + + def addtmp(self, irc, msg, args, channel, pattern): + """[] + + add temporary pattern, which follows repeat punishments""" + self._addTemporaryPattern(irc, channel, pattern, msg.nick, True, False) + irc.replySuccess() + addtmp = wrap(addtmp, ['op', 'text']) + def cflood(self, irc, msg, args, channel, permit, life, mode, duration): """[] [] [] [] [] @@ -4540,6 +4560,19 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): # protection features def _act(self, irc, channel, mode, mask, duration, reason): + if mode == 'D': + action = self.registryValue('modeD') + if len(action): + s = s.replace('$channel', channel) + s = s.replace('$hostmask', mask) + (n, i, h) = ircutils.splitHostmask(mask) + klinemask = '%s@%s' % (i, h) + s = s.replace('$klinemask', klinemask) + s = s.replace('$host', h) + s = s.replace('$duration', duration) + s = s.replace('$reason', reason) + irc.sendQueue(ircmsgs.IrcMsg(action)) + return if mode == 'd': if self.registryValue('logChannel', channel=channel) in irc.state.channels: announce = '[%s] debug %s %s %s %s' @@ -4687,21 +4720,38 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): count = count + 1 return count > limit - def _addTemporaryPattern(self, irc, channel, pattern, level): + def _addTemporaryPattern(self, irc, channel, pattern, level, force, doNotLoop): patternLength = self.registryValue( 'repeatPatternMinimum', channel=channel) - key = 'pattern%s' % channel - if patternLength < 0: + if patternLength < 0 and not force: return - if len(pattern) < patternLength: + if len(pattern) < patternLength and not force: return + self.log.info('%s adding pattern %s' % (level, pattern)) life = self.registryValue('repeatPatternLife', channel=channel) + key = 'pattern%s' % channel chan = self.getChan(irc, channel) if not key in chan.repeatLogs or chan.repeatLogs[key].timeout != life: chan.repeatLogs[key] = utils.structures.TimeoutQueue(life) - self._logChan(irc, channel, '[%s] pattern created "%s" (%s)' % ( - channel, pattern, level)) + if self.registryValue('announceRepeatPattern', channel=channel): + if self.registryValue('useColorForAnnounces', channel=channel): + self._logChan(irc, channel, '[%s] pattern created "%s" (%s)' % ( + ircutils.bold(channel), ircutils.mircColor(pattern, 'red'), level)) + else: + self._logChan(irc, channel, '[%s] pattern created "%s" (%s)' % ( + channel, pattern, level)) chan.repeatLogs[key].enqueue(pattern) + if doNotLoop: + return + patternID = self.registryValue( + 'shareComputedPatternID', channel=channel) + if patternID < 0: + return + for c in irc.state.channels: + if irc.isChannel(c) and not channel == c: + if patternID == self.registryValue('shareComputedPatternID', channel=c): + self._addTemporaryPattern( + irc, c, pattern, level, force, doNotLoop) def _computePattern(self, message, logs, probability, patternLength): candidate = None @@ -4731,7 +4781,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): minimum = self.registryValue('repeatMinimum', channel=channel) pattern = findPattern(message, count, minimum, 100 * probability) if pattern: - self._addTemporaryPattern(irc, channel, pattern, 'single msg') + self._addTemporaryPattern( + irc, channel, pattern, 'single msg', False, False) if self._isSomething(irc, channel, key, 'repeat'): return True patternLength = self.registryValue( @@ -4745,7 +4796,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): chan.repeatLogs[key].enqueue(message) if result: if pattern: - self._addTemporaryPattern(irc, channel, pattern, 'single src') + self._addTemporaryPattern( + irc, channel, pattern, 'single src', False, False) return result if not channel in chan.repeatLogs or chan.repeatLogs[channel].timeout != timeout: chan.repeatLogs[channel] = utils.structures.TimeoutQueue(timeout) @@ -4758,7 +4810,8 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): result = self._isSomething(irc, channel, channel, 'repeat') if result: if pattern: - self._addTemporaryPattern(irc, channel, pattern, 'all src') + self._addTemporaryPattern( + irc, channel, pattern, 'all src', False, False) return result def _isCap(self, irc, channel, key, message): @@ -4774,7 +4827,10 @@ class ChanTracker(callbacks.Plugin, plugins.ChannelDBHandler): return False def die(self): - schedule.removeEvent('ChanTracker') + try: + schedule.removeEvent('ChanTracker') + except: + pass Class = ChanTracker