This commit is contained in:
Nicolas Coevoet 2014-04-15 20:40:25 +02:00
commit aeab44de5a
3 changed files with 184 additions and 132 deletions

157
README.md
View File

@ -1,6 +1,6 @@
### ChanTracker : a supybot plugin which do ban tracker ###
# ChanTracker : a supybot plugin for ban tracking #
This supybot plugin keeps records of channel mode changes, in a sqlite database and permits to manage them over time. It stores affected users, permits to do deep search on them, review actives ones, edit duration, show log, mark them, etc
This supybot plugin keeps records of channel mode changes in a sqlite database and permits management of them over time. It stores affected users, enabling deep searching through them, reviewing actives, editing duration, showing logs, marking/annotating them, etc
## Commands ##
@ -10,105 +10,160 @@ This supybot plugin keeps records of channel mode changes, in a sqlite database
!check [<channel>] <pattern> returns list of users who will be affected by such pattern
!edit <id> [,<id>] [<years>y] [<weeks>w] [<days>d] [<hours>h] [<minutes>m] [<seconds>s] [<-1>] means forever) -- change expiration of some active modes
!info <id> returns information about a mode change
!mark id> [,<id>] <message> add a comment about a mode change
!pending [<channel>] (pending [--mode=<e|b|q|l>] [--oper=<nick|hostmask>] [--never] [<channel>] ) -- returns active items for --mode if given filtered by --oper if given, --never never expire only if given
!query [--deep] [--never] [--active] [--channel=<channel>] <pattern|hostmask|comment>) -- search inside ban database, --deep to search on log, --never returns items setted forever and active, --active returns only active modes, --channel reduces results to a specific channel
!mark <id> [,<id>] <message> add a comment about a mode change
!pending [<channel>] (pending [--mode=<e|b|q|l>] [--oper=<nick|hostmask>] [--never] [<channel>] ) -- returns active items for --mode if given, filtered by --oper if given, --never never expire only if given
!query [--deep] [--never] [--active] [--channel=<channel>] <pattern|hostmask|comment>) -- search inside ban database, --deep to search on log, --never returns items set forever and active, --active returns only active modes, --channel reduces results to a specific channel
!match [<channel>] <nick|hostmask> returns list of modes that affects the nick,hostmask given
!detail <id> returns log from a mode change
!remove [<channel>] <nick> [<reason>] do a force part on <nick> in <channel> with <reason> if provided
## General Usage ##
The bot can be used to place and remove bans (rather than the the op setting channel modes directly). For example, to quiet the argumentative user 'ian' for 10 minutes and ban the spammer 'ham' for a month:
!q ian 10m argumentative again
!b ham 30d silly spammer
These can also be done via a private message to the bot, although you must include the channel in the message:
/msg mybigbadbot q #myChannel ian 10m argumentative again
/msg mybigbadbot b #myChannel ham 30d silly spammer
For each of these bans, the nick is used to generate a *!*@host ban. The desired mask can be given directly to the bot instead of the nick. Also note that, by default, the bot will also kick users that have a +b set against them (details below).
Alternatively, the bot can be used just to track the mode changes, with ops using the capabilities of their own irc clients to set bans. The same sequence as before:
/msg chanserv #myChannel op
/mode #myChannel +q *!*@ranty.ian.home
/msg mybigbadbot 10m argumentative again
/mode #myChannel +b *!*@ham.spam
/kick ham
/msg mybigbadbot 30d silly spammer
If you annotate the bans within 3 minutes of setting them, then you can do so without any additional syntax as above; if you miss that window or are otherwise not not setting bans via the bot, the `pending`, `edit` and `mark` commands can be used to provide annotations and expiration information. For example, if you had not immediately annotated the
/msg mybigbadbot pending #myChannel
<mybigbadbot> [#18 +q ian!*@* by me!~me@example.net on 2014-04-13 13:28:16 GMT]
/msg bigbadbot edit 18 20m
/msg bigbadbot mark 18 even more argumentative and EXTREMELY ANGRY
ChanTracker also allows you to work out which users would be affected by a ban before it is placed and which bans affect a given user.
/msg bigbadbot check #myChannel *!*@*.com <-- oops?
/msg bigbadbot match #myChannel ian <-- will return
<bigbadbot> [#21 +b ian!*@* by me!~me@example.net expires at 2014-04-13 15:20:03 GMT] "even angrier"
## Settings ##
You should increase ping interval, as on channel join bot asks many things and sometimes server takes lot of time to answer
You should increase the ping interval because when the bot joins a channel, it requests lots of data and sometimes the server takes time to answer
!config supybot.protocols.irc.ping.interval 3600
By default, **bot will not stay opped**, but you can configure that globaly or per channel :
By default, **bot will not stay opped**, but you can configure that globally or per channel:
!config supybot.plugins.ChanTracker.keepOp False
!config channel #myChannel supybot.plugins.ChanTracker.keepOp True
If you don't want the bot to manage his own op status, you can change the config value :
If you don't want the bot to manage its own op status, you can change the config value :
!config supybot.plugins.ChanTracker.doNothingAboutOwnOpStatus True
!config channel #myChannel supybot.plugins.ChanTracker.doNothingAboutOwnOpStatus False
Tracked modes are currently defined here ( +qb, and eI if opped ):
The channel modes that will be tracked are currently defined here (qb, and eI if opped -- only ops can see the e and I lists for a channel):
!config supybot.plugins.ChanTracker.modesToAsk
!config supybot.plugins.ChanTracker.modesToAskWhenOpped
The command used by the bot to op itself is editeable here :
The command used by the bot to op itself is editable here:
!config supybot.plugins.ChanTracker.opCommand by default it's "CS OP $channel $nick"
Where $channel and $nick will be replaced by targeted channel and bot's nick at runtime
where $channel and $nick will be replaced by targeted channel and bot's nick at runtime
For more readable date, you should change this :
For more readable date information in output, you should change this:
!config supybot.reply.format.time.elapsed.short True
Bot can forward a lot of important informations about channel activity into a secret channel, like an -ops channel, you can set it globaly or per channel:
The bot can have a "reporting channel" like an -ops channel, where it forwards a lot of important information about channel activity. You can set it globally or per channel:
!config supybot.plugins.ChanTracker.logChannel #myGeneralSecretChannel
!config channel #myChannel supybot.plugins.ChanTracker.logChannel #myChannel-ops
You can tweak which informations you would like to be forwarded, some are activated by default like topic changes, mode changes, etc, some not, like bot's ban/quiet edit / mark etc, take a look at :
You can tweak which information you would like to be forwarded to the reporting channel. Some reporting is activated by default like topic changes, mode changes, etc, some not, like bot's ban/quiet edit/mark etc, take a look at:
!search supybot.plugins.ChanTracker.announce
Bot can send a private message to an op who sets a tracked mode, if configured for, note the op must be know as channel's op by the bot :
If desired, the bot can send a private message to the op that sets a tracked mode. Note the op must be known as channel's op by the bot; the bot owner automatically has that capability:
!config channel #myChannel supybot.plugins.ChanTracker.askOpAboutMode True
Bot can set a duration for new tracked mode changes, in order to auto remove them :
You can add op capability to someone that way:
!user register opaccount password
!hostmask add opaccount *!*@something
!admin capability add opaccount #myChannel,op
!config channel #myChannel supybot.plugins.ChanTracker.autoExpire 3600 ( 1h )
The bot can set a default duration for new tracked mode changes, in order to auto remove them:
Has bot can check on join if user matchs bans filled via channel add #channel *!*@mask ( see config useChannelBansForPermanentBan ), and ban the user if he matchs,
with autoExpire enabled, it allows you to manage a larger bans list than what the ircd can provide, with rotated bans, and without reveals the pattern used for match ( the only restriction there is that it doesn't support extended bans due to supybot)
!config channel #myChannel supybot.plugins.ChanTracker.autoExpire 3600 (1h)
If ircd is great, bot can track account changes and get gecos/username informations when someone joins a channel, it supports ircd CAP features, details can be found here : http://tools.ietf.org/html/draft-mitchell-irc-capabilities-01
The plugin can create persistent bans to help manage large ban lists that exceed the ircd's limits on the length of ban lists. The plugin can remove bans from the ircd ban list while checking all joining users against its own lists. If a user matches, then the ircd ban is reinstated:
Bot also supports extended bans/quiets like $r,$x,$a, etc if you want it to support your ircd extended bans, please, fill an issue or contact me
!config channel #myChannel supybot.plugins.ChanTracker.useChannelBansForPermanentBan true
!channel ban add #myChannel *!*@mask
It has a lot of channel build in protection features, which can be enabled individualy and per channel, or globaly :
With autoExpire enabled, the ircd list is pruned as appropriate and bans are rotated in a way to not reveal the pattern used for the match. Due to a supybot limitation, extended bans are not supported with this feature.
If supported by the ircd, the bot can track account changes and get GECOS and username information when a user joins the channel. This requires ircd CAP features: http://tools.ietf.org/html/draft-mitchell-irc-capabilities-01
The plugin also supports extended bans/quiets including $r, $x, $a (real name, full match and account name, respectively). If you want the plugin to support your ircd extended bans, please, report a bug or contact me directly.
By default, if the bot is asked to set a ban (+b), it will also kick affected users (Note: bot will only kick people if the ban was set by the bot -- if an op places the ban, the bot will not kick affected users). See:
!config supybot.plugins.ChanTracker.kickMode
!config supybot.plugins.ChanTracker.kickMessage
The bot will remove exception modes (that is exempt e, or invite exempt I) for people banned if 'doActionAgainstAffected' for given channel is True.
## Channel Protection ##
The plugin has a lot of built-in channel protection features that can be enabled either individually and per channel, or globally:
- flood detection
- low flood detection
- low-rate flood detection: flooding but with client rate-limiting
- repeat detection
- massRepeat detection ( when same message comes from differents users )
- capslock detection
- ctcp : channel's ctcp detection
- notices : channel's notices detection
- hilight : nick spam
- nick : nick changes spam
- cycle : join/part flood
- massRepeat detection: when same message comes from different users
- capslock: detect people who are EXTREMELY ANGRY
- ctcp: detect sending CTCP to the channel
- notices: detect sending notices to the channel
- hilight: nick spam
- nick: nick change spam
- cycle: join/part flood
- massJoin
each of those detection works with the same kind of settings, there is *Permit ( -1 to disable ), *Life ( which means during how long the bot will keep in mind previous messages/behaviour ),
*Mode ( which allows you to select which action you want to do against the user :
Each of those detections has the same kind of settings: there is *Permit (-1 to disable), *Life (which is the time interval over which the bot will track previous messages/behaviour), *Mode (which allows you to select which action you want to use against the user). The action modes that can be set are:
- q : quiet the user
- b : ban the user
- k : kick the user
- r : force part the user ( if the ircd has the feature ) 'REMOVE $channel $nick :$reason'
- r : remove (force part) the user, if the ircd has the feature. 'REMOVE $channel $nick :$reason'
for each of those, but only relevant with bq mode, you can choose the *Duration of the quiet/ban, and add a *Mark on the related quiet/ban.
For bans (b and q mode), you can choose the *Duration of the quiet/ban, and add a *Mark on the related quiet/ban. The 'bad' settings, when enabled (badPermit > -1) keeps track of users who did something wrong during badLife, and can end to badMode if the user exceeds the limit.
An example about flood control, You want to quiet for 1 minute anyone that send more than 4 messages in 7 seconds in #channel, and if the user continue to flood, after 2 times he will be banned
Example: flood control: to quiet for 1 minute anyone who sends more than 4 messages in 7 seconds to #channel; if the user continues to flood, after 2 times they will be banned
!config channel #channel supybot.plugins.ChanTracker.floodPermit 4 <-- max number of messages allowed
!config channel #channel supybot.plugins.ChanTracker.floodLife 7 <-- in 7 seconds
!config channel #channel supybot.plugins.ChanTracker.floodMode q <-- quiet the user
!config channel #channel supybot.plugins.ChanTracker.floodDuration 60 <-- for 60 seconds
!config channel #channel supybot.plugins.ChanTracker.badPermit 2 <-- if user does that 3 times,
!config channel #channel supybot.plugins.ChanTracker.badMode b <-- ban him
!config channel #channel supybot.plugins.ChanTracker.badMode b <-- ban them
bad* when enabled ( badPermit > -1 ) keeps track of user who did something wrong during badLife, and can end to banMode if the user exceeds the limit.
attack* when enabled keeps track of bad actions, and if channel count of bad actions during attackLife exceeds attackPermit, it sets some specific channels mode during a attackDuration
Additionally, the can track how many bad actions occur over a period of time and if a threshold is passed, this constitutes an attack on the channel. The attack* settings, when enabled keeps track of bad actions, and if the number exceeds attackPermit within attackLife, some specific channel modes are set for an attackDuration.
Another example, you got sometimes a wave of bots which sends the same message from differents hosts:
Example: not flooding: catch a wave of bots which sends the same message from different hosts:
!config channel #channel supybot.plugins.ChanTracker.massRepeatChars 200 <-- enable check only if there is at least 200 chars
!config channel #channel supybot.plugins.ChanTracker.massRepeatPermit 0 <-- that means if first message matchs the seconds, it will trigger it
@ -117,7 +172,7 @@ Another example, you got sometimes a wave of bots which sends the same message f
!config channel #channel supybot.plugins.ChanTracker.massRepeatMode b
!config channel #channel supybot.plugins.ChanTracker.massRepeatDuration 1800
On regular spam purpose, you should not use massRepeat feature, but simply repeat detection:
Example: a user repeating the same thing: (use repeat detection rather than massRepeat for this):
!config channel #channel supybot.plugins.ChanTracker.repeatPermit 3 <-- triggered after 3 similar message
!config channel #channel supybot.plugins.ChanTracker.repeatLife 40 <-- keep previous messages during 60 seconds
@ -125,22 +180,20 @@ On regular spam purpose, you should not use massRepeat feature, but simply repea
!config channel #channel supybot.plugins.ChanTracker.repeatMode q <-- quiet
!config channel #channel supybot.plugins.ChanTracker.repeatDuration 180 <-- for 3 minutes
Bot will do nothing against user with protected capabilities ( #channel,protected ) with those protection features enabled.
Even with all these channel protection features, the bot will do nothing against users with protected capabilities (#channel,protected).
Bot will kick by users affected by +b see :
!config supybot.plugins.ChanTracker.kickMode
!config supybot.plugins.ChanTracker.kickMessage
## Other tips ##
Bot will remove exempt, or Invite exempted for people banned if 'doActionAgainstAffected' for given channel is True
Note : bot will only kick people if the ban was set by itself, if an op place a ban, bot will not kick affected users
Maintaining separate bots for the banning/bantracking functions and other factoid, snarfing or amusement functions is good practice.
If the main purpose of your bot is to manage bans etc, and never interacts with users you should, as owner remove all plugin with 'owner defaultcapabilities remove <pluginname>', it will prevent the bot to answer to various command, and being used as a flood tool by others. ( like !echo SPAM )
If the main purpose of your bot is to manage bans etc, and never interacts with users you should, as owner remove all plugin with 'owner defaultcapabilities remove <pluginname>', it will prevent the bot to answer to various command, and being used as a flood tool by others. (like !echo SPAM)
If your bot manage differents channels or community, remove all User.action from defaultcapabilities, create one user per channel/community, and add ops's hostmasks into it, it's easier to manage that way. Until you have someone with rights in 2 community/channels who will need a separate account.
It works with any version of supybot, vannila, limnoria etc
It works with any version of supybot, vanilla, limnoria etc
BUGS & FEATURES requests can be reported on https://github.com/ncoevoet/ChanTracker or in private message to niko, on chat.freenode.net
## Bugs and Features ##
Requests can be made via https://github.com/ncoevoet/ChanTracker or in private message to niko on chat.freenode.net.

104
config.py
View File

@ -43,84 +43,84 @@ def configure(advanced):
ChanTracker = conf.registerPlugin('ChanTracker')
conf.registerGlobalValue(ChanTracker, 'pool',
registry.Integer(60, """delay between two check about mode removal, in seconds, note, it's also based on irc activity, so removal may be delayed a bit"""))
registry.Integer(60, """delay between two checks about mode removal, in seconds. Note, check is also based on irc activity, so removal may be delayed a bit"""))
conf.registerGlobalValue(ChanTracker, 'CAPS',
registry.CommaSeparatedListOfStrings(['account-notify','extended-join'], """CAP asked to ircd, that permits to track username and account changes"""))
registry.CommaSeparatedListOfStrings(['account-notify','extended-join'], """CAP asked of ircd that permits tracking username and account changes"""))
conf.registerGlobalValue(ChanTracker, 'logsSize',
registry.PositiveInteger(60, """number of messages to keep, per nick - not per nick per channel"""))
registry.PositiveInteger(60, """number of messages to keep in logs. Note, this is per nick - not per nick per channel"""))
conf.registerGlobalValue(ChanTracker, 'quietCommand',
registry.String("CS QUIET $channel $hostmask","""$channel and $hostmask will be replaced at runtime"""))
registry.String("CS QUIET $channel $hostmask","""command issued to quiet a user; $channel and $hostmask will be replaced at runtime"""))
conf.registerGlobalValue(ChanTracker, 'unquietCommand',
registry.String("CS UNQUIET $channel $hostmask","""$channel and $hostmask will be replaced at runtime"""))
registry.String("CS UNQUIET $channel $hostmask","""command issued to unquiet a user $channel and $hostmask will be replaced at runtime"""))
#now per channel
conf.registerChannelValue(ChanTracker, 'opCommand',
registry.String("CS OP $channel $nick", """command used by the op to grant op"""))
registry.String("CS OP $channel $nick", """command used to obtain channel operator mode"""))
conf.registerChannelValue(ChanTracker, 'modesToAsk',
registry.CommaSeparatedListOfStrings(['b','q'], """sync lists for those modes on join"""))
registry.CommaSeparatedListOfStrings(['b','q'], """list of channel modes to sync into the bot's tracking database when it joins the channel"""))
conf.registerChannelValue(ChanTracker, 'modesToAskWhenOpped',
registry.CommaSeparatedListOfStrings(['e','I'], """sync lists for those modes when opped, only asked one time"""))
registry.CommaSeparatedListOfStrings(['e','I'], """list of channel modes to sync into the bot's tracking database when it is opped"""))
# per channel settings
# related to ban tracking
conf.registerChannelValue(ChanTracker, 'autoExpire',
registry.Integer(-1, """-1 means disabled, otherwise it's in seconds, only affects new change"""))
registry.Integer(-1, """default expiration time for newly placed bans; -1 disables auto-expiration, otherwise it's in seconds"""))
# related to logChannel
conf.registerChannelValue(ChanTracker, 'logChannel',
registry.String("", """where bot annonces op's actions, various usefull messages are send, you should set one"""))
registry.String("", """where bot announces op's actions; it is highly recommended to set an appropriate operator's channel to receive the various useful messages"""))
conf.registerChannelValue(ChanTracker, 'announceOthers',
registry.Boolean(True,"""forward quieted/banned users messages to logChannel, used when bot stay opped and channel is +z,
messages from user flagged as bad, or when channel is under attack will not be forwarded"""))
registry.Boolean(True,"""forward messages from quieted/banned users to logChannel; used when bot stays opped and channel is +z (reduced moderation).
Messages from users flagged as bad, or when channel is under attack will not be forwarded"""))
conf.registerChannelValue(ChanTracker, 'announceMode',
registry.Boolean(True,"""announce mode changes to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceVoiceAndOpMode',
registry.Boolean(True,"""announce mode changes to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceWithNotice',
registry.Boolean(False,"""use NOTICE instead of PRIVMSG to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceModes',
registry.CommaSeparatedListOfStrings(['b','q','e','I','r','l','v','o','h','k','n','t','F','i','t'],"""announce modes listed to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceModeSync',
registry.Boolean(False,"""announce mode sync to logChannel"""))
registry.Boolean(False,"""announce to logChannel that synchronisation of channel modes to tracking database has completed"""))
conf.registerChannelValue(ChanTracker, 'announceKick',
registry.Boolean(True,"""announce kick,remove,kill and kline to logChannel"""))
registry.Boolean(True,"""announce kick, remove, kill and kline to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceTopic',
registry.Boolean(True,"""announce topic changes to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceEdit',
registry.Boolean(True,"""announce item edit to logChannel"""))
registry.Boolean(True,"""announce tracker item description edits to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceMark',
registry.Boolean(True,"""announce item mark to logChannel"""))
registry.Boolean(True,"""announce item expiration settings (marks) to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceInTimeEditAndMark',
registry.Boolean(False,"""announce just placed edit and mark to logChannel when using do, q, b, e, i commands"""))
registry.Boolean(False,"""announce new comments (edits) and expiries (marks) to logChannel when they are created by the do, q, b, e, i commands"""))
conf.registerChannelValue(ChanTracker, 'announceMassRemoval',
registry.Boolean(False,"""announce undo * ( edit ) changes to logChannel"""))
registry.Boolean(False,"""announce mass ban removals 'undo *', 'uq *', 'ub *' to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceBotEdit',
registry.Boolean(False,"""announce item autoExpire, bot's triggered protection to logChannel"""))
registry.Boolean(False,"""when banning based on a channel protection trigger (such as flood prevention), announce the items comment (edit) to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceBotMark',
registry.Boolean(False,"""announce item autoExpire, bot's triggered protection to logChannel"""))
registry.Boolean(False,"""when banning based on a channel protection trigger (such as flood prevention), announce the items expiry (mark) to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceNotice',
registry.Boolean(True,"""announce channel's notices to logChannel"""))
registry.Boolean(True,"""announce channel notices to logChannel"""))
conf.registerChannelValue(ChanTracker, 'announceCtcp',
registry.Boolean(True,"""announce channel's ctcps to logChannel"""))
registry.Boolean(True,"""announce channel ctcps to logChannel"""))
# others settings
@ -132,22 +132,22 @@ conf.registerChannelValue(ChanTracker, 'keepOp',
conf.registerChannelValue(ChanTracker, 'kickMode',
registry.CommaSeparatedListOfStrings(['b'], """bot will kick affected users when mode is triggered,
use if with caution, if an op ban *!*@*, bot will kick everyone on the channel"""))
use if with caution, if an op bans *!*@*, bot will kick everyone on the channel"""))
conf.registerChannelValue(ChanTracker, 'kickMessage',
registry.String("You are banned from this channel", """bot kick reason"""))
conf.registerChannelValue(ChanTracker, 'doActionAgainstAffected',
registry.Boolean(True, """devoice,deop,dehalfop affected user by a mode change"""))
registry.Boolean(True, """devoice, deop, dehalfop user affected by a mode change"""))
conf.registerChannelValue(ChanTracker, 'useChannelBansForPermanentBan',
registry.Boolean(True, """do check onjoin if someone matchs a permanent ban"""))
registry.Boolean(True, """when users join the channel, check if the match a permanent ban"""))
conf.registerChannelValue(ChanTracker, 'addKickMessageInComment',
registry.Boolean(False, """add kick message to mode comment"""))
registry.Boolean(False, """add kick message to mode comment in tracking database"""))
conf.registerChannelValue(ChanTracker, 'askOpAboutMode',
registry.Boolean(False,"""Ask the op who added a mode changes in pm about duration and comment"""))
registry.Boolean(False,"""In a private message, ask the op who added a mode about the duration of the ban and a comment on why it was set"""))
conf.registerChannelValue(ChanTracker, 'checkEvade',
registry.Boolean(True,"""bot will apply same duration and mode than the ban evaded, currently only work when someone identify to an account, and has ip computed"""))
@ -161,11 +161,11 @@ conf.registerChannelValue(ChanTracker, 'useChanServForQuiets',
conf.registerChannelValue(ChanTracker, 'floodPermit',
registry.Integer(-1,"""Number of messages allowed during floodLife, -1 to disable, advice 4"""))
conf.registerChannelValue(ChanTracker, 'floodLife',
registry.PositiveInteger(7,"""Duration of messages's life in flood counter, advice 7, in seconds"""))
registry.PositiveInteger(7,"""Duration of messages's life in flood counter, in seconds, advice 7"""))
conf.registerChannelValue(ChanTracker, 'floodMode',
registry.String('q',"""mode used by the bot when flood detection is triggered"""))
conf.registerChannelValue(ChanTracker, 'floodDuration',
registry.PositiveInteger(60,"""punition in seconds"""))
registry.PositiveInteger(60,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'floodComment',
registry.String('flood detected',"""comment added on mode changes database, empty for no comment"""))
@ -173,11 +173,11 @@ registry.String('flood detected',"""comment added on mode changes database, empt
conf.registerChannelValue(ChanTracker, 'lowFloodPermit',
registry.Integer(-1,"""Number of messages allowed during lowFloodLife, -1 to disable, advice 5"""))
conf.registerChannelValue(ChanTracker, 'lowFloodLife',
registry.Integer(13,"""Duration of messages's life in lowFlood counter, advice 13, in seconds"""))
registry.Integer(13,"""Duration of messages's life in lowFlood counter, in seconds, advice 13"""))
conf.registerChannelValue(ChanTracker, 'lowFloodMode',
registry.String('q',"""mode used by the bot when low flood detection is triggered"""))
conf.registerChannelValue(ChanTracker, 'lowFloodDuration',
registry.PositiveInteger(180,"""punition in seconds"""))
registry.PositiveInteger(180,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'lowFloodComment',
registry.String('low flood detected',"""comment added on mode changes database, empty for no comment"""))
@ -186,13 +186,13 @@ conf.registerChannelValue(ChanTracker, 'repeatPermit',
registry.Integer(-1,"""Number of repeated text allowed, -1 to disable, note, first message doesn't count,
so if you want to trigger it after 3 repeat, you must set it to 1, advice 4"""))
conf.registerChannelValue(ChanTracker, 'repeatLife',
registry.PositiveInteger(120,"""Duration of messages's life in lowFlood counter, advice 120, in seconds"""))
registry.PositiveInteger(120,"""Duration of messages's life in lowFlood counter in seconds, advice 120"""))
conf.registerChannelValue(ChanTracker, 'repeatPercent',
registry.Probability(0.85,"""percent of similarity needed between previous and current message to trigger a repeat count"""))
conf.registerChannelValue(ChanTracker, 'repeatMode',
registry.String('q',"""mode used by the bot when repeat detection is triggered"""))
conf.registerChannelValue(ChanTracker, 'repeatDuration',
registry.PositiveInteger(180,"""punition in seconds"""))
registry.PositiveInteger(180,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'repeatComment',
registry.String('repeat detected',"""comment added on mode changes database, empty for no comment"""))
@ -205,9 +205,9 @@ if repeat comes from differences sources that helps, it also add a pattern that
during massRepeatDuration, note, the first two message doesn't count,
so if you want to trigger it after 3 repeat, you must set it to 1"""))
conf.registerChannelValue(ChanTracker, 'massRepeatLife',
registry.PositiveInteger(60,"""Duration of messages's life in massRepeat counter, advice 120, in seconds"""))
registry.PositiveInteger(60,"""Duration of messages's life in massRepeat counter, in seconds, advice 120"""))
conf.registerChannelValue(ChanTracker, 'massRepeatPercent',
registry.Probability(0.95,"""percent of similarity needed between previous and current message to trigger a repeat count"""))
registry.Probability(0.95,"""percentage similarity between previous and current message to trigger a repeat count"""))
conf.registerChannelValue(ChanTracker, 'massRepeatMode',
registry.String('q',"""mode used by the bot when repeat detection is triggered"""))
conf.registerChannelValue(ChanTracker, 'massRepeatDuration',
@ -217,11 +217,11 @@ registry.String('mass repeat detected',"""comment added on mode changes database
# YES IT'S ANNOYING
conf.registerChannelValue(ChanTracker, 'capPermit',
registry.Integer(-1,"""Number of UPPER text allowed, -1 to disable, advice 3"""))
registry.Integer(-1,"""Number of UPPERCASE messages allowed, -1 to disable, advice 3; see capPercent for definition of an UPPERCASE message"""))
conf.registerChannelValue(ChanTracker, 'capLife',
registry.PositiveInteger(120,"""Duration in seconds before messages are removed from count, advice 120"""))
conf.registerChannelValue(ChanTracker, 'capPercent',
registry.Probability(0.75,"""percent of upper chars in a message to trigger a cap count"""))
registry.Probability(0.75,"""percentage of uppercase chars in a message to trigger a cap count"""))
conf.registerChannelValue(ChanTracker, 'capMode',
registry.String('q',"""mode used by the bot when cap is triggered"""))
conf.registerChannelValue(ChanTracker, 'capDuration',
@ -235,7 +235,7 @@ registry.Integer(-1,"""Number of nick allowed per message, -1 to disable, advice
conf.registerChannelValue(ChanTracker, 'hilightMode',
registry.String('q',"""mode used by the bot when cap is triggered"""))
conf.registerChannelValue(ChanTracker, 'hilightDuration',
registry.PositiveInteger(180,"""punition in seconds"""))
registry.PositiveInteger(180,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'hilightComment',
registry.String('hilight detected',"""comment added on mode changes database, empty for no comment"""))
@ -247,7 +247,7 @@ registry.PositiveInteger(3,"""Duration in seconds before messages are removed fr
conf.registerChannelValue(ChanTracker, 'noticeMode',
registry.String('q',"""mode used by the bot when notice is triggered"""))
conf.registerChannelValue(ChanTracker, 'noticeDuration',
registry.PositiveInteger(300,"""punition in seconds"""))
registry.PositiveInteger(300,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'noticeComment',
registry.String('notice detected',"""comment added on mode changes database, empty for no comment"""))
@ -259,19 +259,19 @@ registry.PositiveInteger(3,"""Duration in seconds before messages are removed fr
conf.registerChannelValue(ChanTracker, 'ctcpMode',
registry.String('b',"""mode used by the bot when ctcp is triggered"""))
conf.registerChannelValue(ChanTracker, 'ctcpDuration',
registry.PositiveInteger(1800,"""punition in seconds"""))
registry.PositiveInteger(1800,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'ctcpComment',
registry.String('ctcp detected',"""comment added on mode changes database, empty for no comment"""))
# channel join/part flood
conf.registerChannelValue(ChanTracker, 'cyclePermit',
registry.Integer(-1,"""Number of messages allowed, -1 to disable, count part and quit"""))
registry.Integer(-1,"""Number of cycles allowed, -1 to disable, count part and quit"""))
conf.registerChannelValue(ChanTracker, 'cycleLife',
registry.PositiveInteger(180,"""Duration in seconds before messages are removed from count, advice 180"""))
registry.PositiveInteger(180,"""Duration in seconds before cycles are removed from count, advice 180"""))
conf.registerChannelValue(ChanTracker, 'cycleMode',
registry.String('b',"""mode used by the bot when ctcp is triggered"""))
conf.registerChannelValue(ChanTracker, 'cycleDuration',
registry.PositiveInteger(1800,"""punition in seconds"""))
registry.PositiveInteger(1800,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'cycleComment',
registry.String('cycle detected',"""comment added on mode changes database, empty for no comment"""))
@ -283,7 +283,7 @@ registry.PositiveInteger(60,"""Duration in seconds before messages are removed f
conf.registerChannelValue(ChanTracker, 'massJoinMode',
registry.String('+rq-z $~a',"""mode used by the bot when massjoin is triggered"""))
conf.registerChannelValue(ChanTracker, 'massJoinDuration',
registry.PositiveInteger(300,"""punition in seconds"""))
registry.PositiveInteger(300,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'massJoinUnMode',
registry.String('-rq+z $~a',"""mode used by the bot when massJoinDuration is finished"""))
@ -295,7 +295,7 @@ registry.Integer(300,"""Duration in seconds before messages are removed from cou
conf.registerChannelValue(ChanTracker, 'nickMode',
registry.String('q',"""mode used by the bot when nick is triggered"""))
conf.registerChannelValue(ChanTracker, 'nickDuration',
registry.PositiveInteger(300,"""punition in seconds"""))
registry.PositiveInteger(300,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'nickComment',
registry.String('nick changes flood detected',"""comment added on mode changes database, empty for no comment"""))
@ -307,7 +307,7 @@ registry.Integer(600,"""Duration in seconds before item are removed from count,
conf.registerChannelValue(ChanTracker, 'badMode',
registry.String('b',"""mode used by the bot when bad is triggered"""))
conf.registerChannelValue(ChanTracker, 'badDuration',
registry.PositiveInteger(86400,"""punition in seconds"""))
registry.PositiveInteger(86400,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'badComment',
registry.String('bad detected',"""comment added on mode changes database, empty for no comment"""))
@ -317,7 +317,7 @@ registry.Integer(-1,"""Number of bad action allowed, -1 to disable, advice 2, ea
conf.registerChannelValue(ChanTracker, 'attackLife',
registry.Integer(600,"""Duration in seconds before item are removed from count, advice 600"""))
conf.registerChannelValue(ChanTracker, 'attackDuration',
registry.PositiveInteger(1800,"""punition in seconds"""))
registry.PositiveInteger(1800,"""punishment duration in seconds"""))
conf.registerChannelValue(ChanTracker, 'attackMode',
registry.String('+rq-z $~a',"""mode used by the bot when attack is triggered"""))
conf.registerChannelValue(ChanTracker, 'attackUnMode',

View File

@ -54,12 +54,11 @@ ircutils._hostmaskPatternEqualCache = utils.structures.CacheDict(4000)
cache = utils.structures.CacheDict(4000)
def applymodes(channel, args=(), prefix='', msg=None):
"""Returns a MODE that applies changes on channel."""
modes = args
if msg and not prefix:
prefix = msg.prefix
return ircmsgs.IrcMsg(prefix=prefix, command='MODE',
args=[channel] + ircutils.joinModes(modes), msg=msg)
"""Returns a MODE that applies changes on channel."""
modes = args
if msg and not prefix:
prefix = msg.prefix
return ircmsgs.IrcMsg(prefix=prefix, command='MODE', args=[channel] + ircutils.joinModes(modes), msg=msg)
def matchHostmask (pattern,n):
# return the machted pattern for Nick
@ -1974,7 +1973,10 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
logChannel = self.registryValue('logChannel',channel=channel)
if logChannel in irc.state.channels:
i = self.getIrc(irc)
i.lowQueue.enqueue(ircmsgs.privmsg(logChannel,message))
if self.registryValue ('announceWithNotice',channel=channel):
i.lowQueue.enqueue(ircmsgs.notice(logChannel,message))
else:
i.lowQueue.enqueue(ircmsgs.privmsg(logChannel,message))
self.forceTickle = True
def doJoin (self,irc,msg):
@ -2670,14 +2672,15 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
modes = ircutils.separateModes(msg.args[1:])
chan = self.getChan(irc,channel)
msgs = []
announces = list(self.registryValue('announceModes',channel=channel))
overexpire = self.registryValue('autoExpire',channel=channel)
for change in modes:
(mode,value) = change
m = mode[1:]
if value:
value = value.lstrip().rstrip()
value = str(value).lstrip().rstrip()
item = None
if '+' in mode:
m = mode[1:]
if m in self.registryValue('modesToAskWhenOpped',channel=channel) or m in self.registryValue('modesToAsk',channel=channel):
item = chan.addItem(m,value,msg.prefix,now,self.getDb(irc.network))
if msg.nick != irc.nick and self.registryValue('askOpAboutMode',channel=channel) and ircdb.checkCapability(msg.prefix, '%s,op' % channel):
@ -2729,7 +2732,6 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
# flush pending queue, if items are waiting
self.forceTickle = True
else:
m = mode[1:]
if m == 'o' and value == irc.nick:
# prevent bot to sent many -o modes when server takes time to reply
chan.deopAsked = False
@ -2741,40 +2743,38 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
if item:
if '+' in mode:
if not len(item.affects):
if self.registryValue('announceMode',channel=channel):
if m in announces:
msgs.append('[#%s %s %s]' % (str(item.uid),mode,value))
elif len(item.affects) != 1:
if self.registryValue('announceMode',channel=channel):
if m in announces:
msgs.append('[#%s %s %s - %s users]' % (str(item.uid),mode,value,str(len(item.affects))))
else:
if self.registryValue('announceMode',channel=channel):
if m in announces:
msgs.append('[#%s %s %s - %s]' % (str(item.uid),mode,value,item.affects[0]))
else:
if not len(item.affects):
if self.registryValue('announceMode',channel=channel):
if m in announces:
msgs.append('[#%s %s %s %s]' % (str(item.uid),mode,value,str(utils.timeElapsed(item.removed_at-item.when))))
elif len(item.affects) != 1:
if self.registryValue('announceMode',channel=channel):
if m in announces:
msgs.append('[#%s %s %s - %s users, %s]' % (str(item.uid),mode,value,str(len(item.affects)),str(utils.timeElapsed(item.removed_at-item.when))))
else:
if self.registryValue('announceMode',channel=channel):
if m in announces:
msgs.append('[#%s %s %s - %s, %s]' % (str(item.uid),mode,value,item.affects[0],str(utils.timeElapsed(item.removed_at-item.when))))
else:
if mode.find ('o') != -1 or mode.find('h') != -1 or mode.find ('v') != -1:
if self.registryValue('announceVoiceAndOpMode',channel=channel):
msgs.append('[%s %s]' % (mode,value))
else:
if m in announces:
msgs.append('[%s %s]' % (mode,value))
else:
if n:
n.addLog(channel,'sets %s' % mode)
msgs.append(mode)
if m in announces:
msgs.append(mode)
if toCommit:
db.commit()
c.close()
if irc.nick in irc.state.channels[channel].ops and not self.registryValue('keepOp',channel=channel):
self.forceTickle = True
if self.registryValue('announceMode',channel=channel) and len(msgs):
if len(self.registryValue('announceModes',channel=channel)) and len(msgs):
self._logChan(irc,channel,'[%s] %s sets %s' % (channel,msg.nick,' '.join(msgs)))
self.forceTickle = True
if len(toexpire):
@ -2802,12 +2802,11 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
def do478(self,irc,msg):
# message when ban list is full after adding something to eqIb list
(nick,channel,ban,info) = msg.args
if info == 'Channel ban list is full':
if self.registryValue('logChannel',channel=channel) in irc.state.channels:
L = []
for user in list(irc.state.channels[self.registryValue('logChannel',channel=channel)].users):
L.append(user)
self._logChan(irc,channel,'[%s] %s : %s' % (channel,info,' '.join(L)))
if self.registryValue('logChannel',channel=channel) in irc.state.channels:
L = []
for user in list(irc.state.channels[self.registryValue('logChannel',channel=channel)].users):
L.append(user)
self._logChan(irc,channel,'[%s] %s : %s' % (channel,info,' '.join(L)))
self._tickle(irc)
# protection features