Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ###########################[ ALL PROTECTION 4.7 ]############################
- # #
- # Author : Opposing (Fz_Egg@yahoo.com) #
- # a.k.a Sir_Fz (Fayez Zouheiry) #
- # Version : 4.7 #
- # Released: December 21, 2010 #
- # Source: http://Sir-Fz.blogspot.com #
- ## #
- # Description: Has all kinds of channel protections + Botnet channel flood #
- # protections and private protections. #
- # #
- # Commands: #
- # DCC: #
- # .ap:import <oldchan> <*/newchan> (This sets the AP settings #
- # of <oldchan> on <newchan> or all chans if *) #
- # .ap:reset <*/chan> (This will reset the AP settings of chan #
- # or all chans if * to the default settings) #
- # .ap:disable <*/chan> (This will disable all protections on #
- # chan or all chans if *) #
- # .ap:monitor (displays info about followed punishments) #
- # .ap:add <list> <chan/global> <elements> #
- # .ap:rem <list> <chan/global> <elements> #
- # .ap:list <list> <chan/global> #
- # .ap:priv <set/list> <setting> <value> (priv flood settings) #
- # ** Available lists: bchans, bnicks, bidents, bwords, adexempts, #
- # droneexempts, adwords, bctcrs & greetexempts. #
- # #
- # All protections are enabled via .chanset DCC command. #
- # Use: .chaninfo to know AllProtection's settings (ap:<setting>) #
- # NOTE: To set an AP channel setting use: (* means all channels) #
- # .chanset <chan> <setting> <value> <btime> <punish> <btype> #
- # #
- # Credits: #
- # - Thanks to my friend Salah Rifai who introduced me to Eggdrops #
- # & *nix. He is the person who guided me to Eggdrops' resources. He #
- # also was the founder of nexushells.net which was my first shell #
- # which hosted my Eggdrop (Shrider). #
- # - Thanks to http://forum.egghelp.org which was and still is my #
- # tcl toutor, I've learned tcl through this community. #
- # - Thanks to slennox for adding a link on the main page of #
- # www.egghelp.org to the topic of AllProtection, and for hosting #
- # the script on his site when my site went down. #
- # - Thanks Silence, Marcel, dotslasher & others for reporting bugs #
- # which was an important step for the developement of this script. #
- # - Thanks to all who suggested ideas & features at egghelp.org. #
- # - Used maskhost & wordwrap procs by user from the egghelp forum. #
- # Edited wordwrap slightly to suite its purpose in the script. #
- # - Used massmode proc's algorithm for ban-queueing (by user). #
- # - Used checkbcd proc by Marcel (edited by me). #
- # #
- # History: #
- # - 4.7: Stable release of the 4.6 series. Got the bad nicks/idents #
- # & perhaps other fixes I haven't logged. It was a good ride :) #
- # - 4.6b9: The script would not ban if a channel was not added in #
- # lower case; fixed now. Fixed other issues... #
- # - 4.6b8: Integrated queues, enhanced AntiSpamBot, modulated #
- # exempt types, scanning bad/excess chans and bad CTCP replies #
- # when bot gains ops, flexible warn method (notice or privmsg), #
- # fixed AntiSpamBot IP problem, added ability to exempt hostmasks #
- # from greets by antispambot, AntiSpam bans spammers only if on #
- # chan (optional), ability to immediately ban thru X, enable or #
- # disable bad words/ads ban for quit/part, queue for bad/excess #
- # chans scan. Punish bad chan users in all channels. #
- # - 4.6b7: Throttle kicking (halt redundant kicks). Bad words/ads #
- # now detected in notices, parts & quits. Choose CTCP requests 4 #
- # bad ctcp replies (bad version before). Ability to ban thru X. #
- # Following now occurs in 1 array (less memory). All flood types #
- # now have a punishment method. Added AntiSpamBot. Enhancements #
- # made over code. #
- # - 4.6b6: Adding drone exempts via .ap:add cmd. Fixed undiscovered #
- # exploit in string splitting (string2list). Added extra 2 ban #
- # types. Added exemption for part msgs in revdoor protection. #
- # Bad version-reply kick, set private flood settings via DCC, log #
- # everyday (configurable), scan channels in intervals for bad or #
- # excess chans or bad version-replies and ability to add custom #
- # advertising words. #
- # - 4.6b5: Fixed bugs in badchan and clones protections. Enhanced #
- # advertisement detection to avoid false detections. #
- # - 4.6b4: Fixed lists saving, uninstalling error. Added ability to #
- # remove bans on full banlist + enhanced the drones detecting #
- # procedure and the ap:import DCC command to accept *. #
- # - 4.6b3: More code fixes and enhancements. You can now add words #
- # to be exempted from advertising (channel specific as well) and #
- # log bot's kicks and bans. Join flood can now check joins from #
- # same idents if enabled. Implemented queueing bans. #
- # - 4.6b2: Major coding changes, changed style of binding and procs #
- # for better and faster performance. Reduced code & implemented #
- # the use of namespaces in order not to conflict with other #
- # scripts. Added excess chans protection + several bug fixes. #
- # - 4.6b1: Major coding changes, added bad chans protections + bug #
- # fixes. #
- # #
- # Report bugs/suggestions to Fz_Egg@yahoo.com #
- # #
- # Copyright © 2005 Opposing (aka Sir_Fz) #
- # #
- # This program is free software; you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation; either version 2 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program; if not, write to the Free Software #
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
- # #
- #############################################################################
- #
- ##############################
- # Configurations start here: #
- # __________________________ #
- ########################
- # SETTINGS & iNFO #
- ########################
- ### READ THIS FIRST:
- # * AllProtection works best with eggdrop1.6.18 and above. (so upgrade)
- #
- # * AllProtection exempts channel ops, friends (+f) and masters (+mo) from protection by default.
- # That means users with the +f or +mo flags will not be affected by any protection.
- # (You can add hosts to the +f handle if you don't want the bot to ban them). To prevent from banning
- # ChanServ, add chanserv to your bot with the +f or +mo flag.
- #
- # * AllProtection does not use the internal banlist of the bot so you will not have to worry
- # about other ops not being able to remove the bans, they can! (feature or bug, I dont care :P)
- #
- # * AllProtection will not trigger protection on a channel where the bot is not oped, so your
- # bot will not send redundant commands to the server. (good for the lag)
- #
- # * AllProtection strips control-codes (i.e. bold, underline, colors...etc) from text when checking for
- # repeats, bad words or advertising.
- #
- # * All settings are enabled via .chanset DCC command. Example: .chanset #channel ap:textl 5:2 15 w:k:kb 2
- # this will enable the text flood (lines) protection on #channel (punish on 5 lines or more in 2 seconds)
- # 1st warn - 2nd kick - 3rd kickban. ban is 15 minutes and ban type is 2.
- #
- # * You can use mode lock modes such as "mR-k type.flood" which will work fine with AllProtection.
- #
- # * Adding elements to the lists (bad words, chans...etc) can ONLY be done via the DCC commands.
- #
- # * Read all the comments during configuration so you won't miss any important info.
- ### Enjoy configuring...
- # You can change the name of the namespace (AllProtection).
- namespace eval AllProtection {
- # Basic declarations: (don't touch)
- variable declr
- foreach declr {textl textc notcl notcc capsp repeatf codesf adexempts adwords greetexempts adv antispam bwords
- swear ctcpf massdeop massdeop masskick massb joinflood pmsgf revdoor nickflood eclones bnick bnicks drone
- bident bidents droneexempts bchans bchan bctcrs bctcr apfp ptextl ptextc pnotil pnotic pctcpf NumKicks apudef
- apqueue banthruX ap:udefs logkbs btclocked kckcount cbcd serv kline kcfop} { variable $declr }
- unset declr
- # Do you want your bot to queue bans? set here the time in seconds before dumping bans:
- # NOTE: 0 means the bot will set the ban immediately
- # The modes-per-line setting in eggdrop.conf is the number of modes allowed per command.
- set apqueue(time) 1
- # Set here the numbers of last bans to be removed on full banlist? (0: remove none)
- # NOTE: Full banlist is when the channel has max-bans bans set. (from eggdrop.conf)
- variable removebs 20
- # Do you want the bot to ban through services?
- # 0: Never
- # 1: Only when banlist is full (determined by max-bans)
- # 2: always
- set banthruX(do) 0
- # If banthruX is 1/2, set the command here to ban through services:
- # %nick = nickname
- # %ban = ban-mask
- set banthruX(cmd) "privmsg X :ban %chan %ban %btime %level %reason"
- # If banthruX is 1/2, set here the default level to be used on all channels
- lappend ap:udefs {ap:level 75}
- # Do you want AP to log all the kicks/bans done by the bot? (0: no, 1: daily, 2: forever)
- set logkbs(do) 0
- # If yes, set the logfile here: (will be reset everyday at 3:00 a.m.)
- set logkbs(file) "logs/aplogs.log"
- # Set here any additional exempts, you can exempt the following:
- # ops: Channel ops
- # halfops: Channel halfops
- # voices: Channel voices
- # +flags|+flags: Users with global or channel specific flags (e.g. +fm friends and masters...)
- # -flags&-flags: Users which do not have the specified flags (e.g. -k&-k)
- variable exmptype {ops voices +fmo|+fmo}
- # Set here the handles of the users you want to notify when the bots locks a channel
- # for mass (botnet) flood.
- # example: set notifyusers {TheOwner LamerDude}
- variable notifyusers {vuffster vuffie}
- # Set here the notice to be sent to the channel when the bot locks the channel because of a
- # Botnet flood. leave "" if you don't wish the notice to be sent.
- set btclocked(lnotc) ""
- # What info do you wanna add to your kick message?
- # After setting this variable, you can use $kckcount(form) to add a these info to the bot's
- # kick msg.
- ### NOTE:
- ## %kcount = number of kicks.
- ## %btime = ban time
- ## %chan = channel name
- ## %date = kick date
- ## %rate = offenses in seconds, bad words/nicks/idents/chans/ads or clone/clones (depends on type of offense)
- ### PS: You can use the above directly in the kick message (not only here)
- set kckcount(form) " ·%kcount·"
- # Set the file in which the number of kicks will be stored.
- set kckcount(file) "scripts/kcount.txt"
- # Do you want the bot to check for bad nicks/idents and clones when it first joins the channels
- # and gains op ? (0: no , 1: yes)
- # NOTE: This may be CPU intensive if your bot is on big channels or on alot of channels.
- # NOTE: This may (probably will) cause huge self-lag on the bot.
- set cbcd(check) 0
- # If cbcd(check) is set to 1, change this if you want the bot to only check for certain types
- # of protection in the nicklist.
- # drones : Random drones
- # clones : Excess clones and kick them
- # bnicks : Bad nicks
- # bidents: Bad idents.
- # bchans : Bad/Excess channels.
- # bctcrs : Bad CTCP replies
- set cbcd(procs) {drones clones bnicks bidents bchans bctcrs}
- # If cbcd(check) is set to 1, on what channels do you want it to be applied ? (use "*" to make it work on all chans)
- # example: set cbcd(chans) "#chan1 #chan2"
- set cbcd(chans) "#CafeChat"
- # Your service's chanserv nick.
- # example: set serv(nick) "ChanServ" or "PRIVMSG X@channels.undernet.org"
- set serv(nick) "ChanServ"
- # Chanserv deop command.
- # use %nick for the nick you want to deop and %chan for the channel name.
- # example: set serv(deop) "deop %chan %nick"
- set serv(command) "deop %chan %nick"
- # Set the time in seconds to wait before reseting the punishment monitor:
- # Note: this setting means the bot will apply the punishment steps on each user
- # within this period of time, otherwise it'll trigger steps from the beginning.
- variable pwait 180
- # Set here the warning method you wish to use: (PRIVMSG or NOTICE)
- variable wmeth NOTICE
- # Edit this only if your bot is an ircop and will use the kline command:
- # Set here the kline command used on your server.
- # for example some ircds user:
- # kline %mask %time %reason
- # others use:
- # kline %time %mask %reason
- ## NOTE:
- # %mask = the klined mask.
- # %time = the kline time.
- # %reason = the kline reason.
- ##
- set kline(cmd) "kline %time %mask :%reason"
- # set the default kline time. (seconds or minutes depends on your ircd)
- set kline(time) 30
- ## Available punishment methods:
- # v : Void - do nothing
- # w : Warn offender
- # k : Kick offender
- # b : Ban offender
- # kb : Kick + Ban offender
- # kl : KLine offender
- # kil: Kill offender
- #
- ## You can use them like this for example:
- # w:k:kb
- # this means, first Warn then Kick then Kickban. (if offence is repeated ofcourse)
- ## these steps will be triggered if the offences happend during <pwait> seconds.
- # NOTE: These methods are not applicable on all flood types. I only applied this
- # feature on the flood types I think they're needed.
- ## Available ban types:
- # 0 : *!user@full.host.tld
- # 1 : *!*user@full.host.tld
- # 2 : *!*@full.host.tld
- # 3 : *!*user@*.host.tld
- # 4 : *!*@*.host.tld
- # 5 : nick!user@full.host.tld
- # 6 : nick!*user@full.host.tld
- # 7 : nick!*@full.host.tld
- # 8 : nick!*user@*.host.tld
- # 9 : nick!*@*.host.tld
- # 10: *!user@*
- # 11: nick!*@*
- ## Available kline mask types:
- # 0 : user@full.host.tld
- # 1 : *user@full.host.tld
- # 2 : *@full.host.tld
- # 3 : *user@*.host.tld
- # 4 : *@*.host.tld
- # 5 : user@full.host.tld
- # 6 : *user@full.host.tld
- # 7 : *@full.host.tld
- # 8 : *user@*.host.tld
- # 9 : *@*.host.tld
- # 10: user@*
- ##########################
- # TEXT FLOOD #
- ##########################
- #
- ## 1 ## Text flood (lines)
- #
- # use .chanset #channel ap:textl <lines>:<seconds> <btime> <pmeth> <btype> (in DCC, 0:0 to disable)
- # Set default rate here:
- lappend ap:udefs {ap:textl "5:2 60 k:kb 2"}
- # Text flood (lines) kick msg.
- set textl(kmsg) "Text flood detected. $kckcount(form)"
- # Text flood (lines) warn msg.
- set textl(wmsg) "Warning: You've triggered text flood (lines) protection, slow down your typing."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- # Text flood (lines) kline mask type.
- set textl(ktype) 2
- # Text flood (lines) kline/kill reason.
- set textl(klmsg) "Text flooding is not permissable on this network."
- # Text flood (lines) kline time (seconds or minutes depends on your ircd).
- set textl(ktime) 0
- #
- ## 2 ## Text flood (chars)
- #
- lappend ap:udefs {ap:textc "215:3 120 kb 2"}
- set textc(kmsg) "Excess chars detected. $kckcount(form)"
- set textc(wmsg) "Warning: You've triggered text flood (chars) protection, decrease your text legnth."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set textc(ktype) 2
- set textc(klmsg) "Text flooding (chars) is not permissable on this network."
- set textc(ktime) 0
- #
- ## 3 ## Notice flood (lines)
- #
- lappend ap:udefs {ap:notcl "1:10 120 kb 2"}
- set notcl(kmsg) "Notice not allowed. $kckcount(form)"
- set notcl(wmsg) "Warning: you've triggered notice flood (lines) protection, slow down your notices."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set notcl(ktype) 2
- set notcl(klmsg) "Notice flooding is not permissable on this network."
- set notcl(ktime) 0
- #
- ## 4 ## Notice flood (chars)
- #
- lappend ap:udefs {ap:notcc "200:3 180 kb 2"}
- set notcc(kmsg) "Excess chars (notice) detected. $kckcount(form)"
- set notcc(wmsg) "Warning: you've triggered notice flood (chars) protection, decrease your text length."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set notcc(ktype) 2
- set notcc(klmsg) "Notice flooding (chars) is not permissable on this network."
- set notcc(ktime) 0
- ###################
- # TEXT #
- ###################
- #
- ## 5 ## Caps flood.
- #
- # Use .chanset #channel ap:caps <percent>:<line-length> <btime> <pmeth> <btype> (in DCC, 0:0 to disable)
- # Set default rate here:
- lappend ap:udefs {ap:caps "60:90 120 kb 2"}
- set capsp(kmsg) "Excess CAPS detected. $kckcount(form)"
- set capsp(wmsg) "Warning: You've triggered caps flood protection, release your caps."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set capsp(ktype) 2
- set capsp(klmsg) "Caps flooding is not permissable on this network."
- set capsp(ktime) 0
- #
- ## 6 ## Text repeating.
- #
- lappend ap:udefs {ap:repeatl "3:10 60 k:kb 2"}
- ## Text repeating Kick on how many consecutive repeated letters?
- ## Example: if this is set to 5 then the bot will kick any user who types (example):
- # Hellooooo (5 consecutive o's)
- # Hello!!!!!!!!! (5 and more consecutive ! marks)
- ## Use .chanset #channel ap:repeatc <number-of-letters> <btime> <pmeth> <btype> (in DCC, 0 to disable)
- # Set default value here:
- lappend ap:udefs {ap:repeatc "25 30 w:k:kb 2"}
- set repeatf(kmsg) "Text repeating detected. $kckcount(form)"
- set repeatf(lkmsg) "Letter repeats detected, do not use excess consecutive letters. $kckcount(form)"
- set repeatf(wmsg) "Warning: You've triggered %type repeating protection, stop repeating."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set repeatf(ktype) 2
- set repeatf(klmsg) "Constant repeating is not permissable on this network."
- set repeatf(ktime) 0
- #
- ## 7 ## Control codes.
- #
- # Use .chanset #channel ap:codes r:<n> b:<n> u:<n> c:<n> <btime> <pmeth> <btype> (in DCC)
- # Example: If you set ap:codes to: r:35 b:35 u:35 c:35
- # Then 35 (or more) characters affected by Reverse or Bold or Underline or Color
- # will be considered an offence.
- # Set default rate here:
- lappend ap:udefs {ap:codes "r:35 b:80 u:80 c:80 90 kb 2"}
- set codesf(kmsg) "Excess codes detected. $kckcount(form)"
- set codesf(wmsg) "Warning: You've triggered control codes protection, release your msgs from codes."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set codesf(ktype) 2
- set codesf(klmsg) "Excess use of control codes is not permissable on this network."
- set codesf(ktime) 0
- #
- ## 8 ## Advertising.
- #
- # NOTE: This protection also works for private advertising.
- # Use .chanset #channel ap:adv + <btime> <pmeth> <btype> (to enable)
- # set default value here: (+ enabled, - disabled)
- lappend ap:udefs {ap:adv "-"}
- # Set here the string you want to exempt (don't consider as spam):
- # Note: %chan = current channel. Also, you can change these for every channel via DCC
- # using the .ap:add command. (no wildcards used)
- set adexempts(global) { %chan www.egghelp.org }
- set adwords(global) { "*join *" "*plz visit*" }
- set adv(kmsg) "Advertising detected. $kckcount(form)"
- set adv(wmsg) "Warning: You've triggered adverting protection, advertisements are not allowed."
- # ANTI SPAM BOT: (NOTE: Some networks may not allow such bots.)
- # Use: .chanset #channel ap:antispam + <greet> <cycle-time> <idle-time> (to enable)
- # the antispam bot will not cycle a channel where last join occured in <idle-time> or more minutes.
- # <greet> is either + or - which will enable or disable the on-join message.
- # set default value here:
- lappend ap:udefs {ap:antispam "- + 10 10"}
- # AntiSpamBot basic settings
- # You can edit all these settings as you wish
- # example: set antispam(nick) AntiSpamBot
- set antispam(nick) $altnick
- set antispam(altnick) ${altnick}1
- # Antispam ident & real name
- set antispam(user) AP
- set antispam(realname) "AllProtection Anti-Spam"
- # example: set antispam(ip) 127.0.0.1
- #set antispam(ip) ${my-ip}
- # example: set antispam(host) my.lame.vhost.net
- #set antispam(host) ${my-hostname}
- # Ban spammer in all channels or only in channels it's in? (0: It's in, 1: All)
- set antispam(banall) 1
- # Exempt list from greets:
- set greetexempts(global) { *example*!*@* *!*example*@*.example.net }
- # If you want your bot to reply to users with random message, set messages here:
- set antispam(r) {
- }
- # On what messages do you want the bot to reply:
- set antispam(t) {
- }
- # Do you want the bot to msg users on join? (leave "" if no)
- set antispam(greet) "Hello %nick, checking for spam. Please do not reply..."
- # Stop greeting after how many joins in secs:
- set antispam(jprot) 4:2
- # Stop replying to messages after how many msgs in secs:
- set antispam(mprot) 8:4
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set adv(ktype) 2
- set adv(klmsg) "Constant advertising is not permissable on this network."
- set adv(ktime) 0
- #
- ## 9 ## Swearing.
- #
- lappend ap:udefs {ap:swear "-"}
- set bwords(global) {
- }
- set swear(kmsg) "Bad word detected. $kckcount(form)"
- set swear(wmsg) "Warning: You've triggered swearing protection, cussing is prohibited."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set swear(ktype) 2
- set swear(klmsg) "Swearing is not permissable on this network."
- set swear(ktime) 0
- #
- ## 8-9 ## Swearing/Advertising in part/quit messages
- #
- # Exampl: "s:1 a:1" Enables banning of users with part/quit msgs containing swear/advertisement
- lappend ap:udefs {ap:pqsadv "s:0:0"}
- ###################
- # CTCP #
- ###################
- #
- ## 10 ## CTCP/CTCR flood
- #
- lappend ap:udefs {ap:ctcps "2:30 180 kb 2"}
- set ctcpf(kmsg) "CTCP flood detected. $kckcount(form)"
- set ctcpf(wmsg) "Warning: You've triggered CTCP/CTCR flood protection, decrease your ctcps."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set ctcpf(ktype) 2
- set ctcpf(klmsg) "CTCP/CTCR floods are not permissable on this network."
- set ctcpf(ktime) 0
- ###################
- # TAKEOVER #
- ###################
- #
- ## 11 ## Mass deop.
- #
- lappend ap:udefs {ap:massd "-"}
- # Mass deop: deop abuser ? (0: no , 1: yes)
- set massdeop(deop) 0
- set massdeop(kmsg) "Mass deop detected. $kckcount(form)"
- set massdeop(wmsg) "Warning: You've triggered the mass deop protection, do not repeat this action."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set massdeop(ktype) 2
- set massdeop(klmsg) "Mass deops are not allowed on this network."
- set massdeop(ktime) 0
- #
- ## 12 ## Mass kick.
- #
- lappend ap:udefs {ap:massk "-"}
- # Mass kick: deop abuser ? (0: no , 1: yes)
- set masskick(deop) 1
- set masskick(kmsg) "Mass kick detected. $kckcount(form)"
- set masskick(wmsg) "Warning: You've triggered mass kick protection, do not repeat this action."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set masskick(ktype) 2
- set masskick(klmsg) "Mass kicks are prohibited on this network."
- set masskick(ktime) 0
- #
- ## 13 ## Mass ban (bans).
- #
- lappend ap:udefs {ap:massb "-"}
- # Mass ban (bans) deop abuser ? (1: yes , 0: no)
- set massb(deop) 1
- set massb(kmsg) "Mass ban is not allowed. $kckcount(form)"
- set massb(wmsg) "Warning: You've triggered mass ban protection, do not repeat this action."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set massb(ktype) 2
- set massb(klmsg) "Mass banning (bans) is prohibited on this network."
- set massb(ktime) 0
- #
- ## 14 ## Channel limit.
- #
- # Use .chanset #channel ap:limit <limit> (in DCC, 0 to disable)
- # Note: this be the number that will be added to the channel's limit.
- # Set default limit here:
- lappend ap:udefs {ap:limit 0}
- ###################
- # MISCELLANEOUS #
- ###################
- #
- ## 15 ## Join flood.
- #
- lappend ap:udefs {ap:cjoin "4:2 120 kb 2"}
- # Join flood: Check for join flood from same idents as well? (0: no, 1: yes)
- set joinflood(checkident) 1
- # Join flood: Lock channel when triggered ? (1: yes , 0: no)
- set joinflood(lockchan) 1
- # Join flood: If lock channel is enable, what modes ?
- set joinflood(lockmode) "MR-k clone.join.flood"
- # Join flood: lock time in seconds.
- set joinflood(locktime) 45
- set joinflood(kmsg) "Join flood detected. $kckcount(form)"
- set joinflood(wmsg) "Warning: you've triggered join flood protection, further offence will cause harsher actions."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set joinflood(ktype) 2
- set joinflood(klmsg) "Join floods are not permissable on this network."
- set joinflood(ktime) 0
- #
- ## 16 ## Part msg flood.
- #
- # Use .chanset #channel ap:partmsgs <message-length> <btime> <pmeth> <btype> (in DCC, 0 to disable)
- # Set default value here:
- lappend ap:udefs {ap:partmsgs "0"}
- # Also, you can ban if excess codes are used in a part msg:
- # Use .chanset #channel ap:partmsgc r:<n> b:<n> u:<n> c:<n> <btime> <pmeth> <btype> (in DCC)
- # Note: check codes protection to understand how codes checking work.
- # r = reverse, b = bold, u = underline and c = colors.
- # Set default rate here:
- lappend ap:udefs {ap:partmsgc "0"}
- set pmsgf(kmsg) "Part msg flood detected. $kckcount(form)"
- set pmsgf(wmsg) "Warning: You've triggered part msg flood protection, decrease text in your part reason."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set pmsgf(ktype) 2
- set pmsgf(klmsg) "Part msg floods are not permissable on this network."
- set pmsgf(ktime) 0
- #
- ## 17 ## Revolving door.
- #
- # Use .chanset #channel ap:revdoor <seconds> <btime> <pmeth> <btype> (in DCC)
- # example: setting this to 3 will make the bot ban whoever joins and parts/quits in 3 or less seconds.
- # Set default value here:
- lappend ap:udefs {ap:revdoor "3 120 kb 2"}
- set revdoor(kmsg) "Join-part revolving door attempt detected. $kckcount(form)"
- # Part messages that should not be considered as revdoor: (can use wildcards)
- # Example: set revdoor(exempt) {"Registered."}
- set revdoor(exempt) {}
- set revdoor(wmsg) "Warning! you have triggered revolving-door protection, do not join-part channels."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set revdoor(ktype) 2
- set revdoor(klmsg) "Revolving-door bots are not allowed on this network."
- set revdoor(ktime) 0
- #
- ## 18 ## Nick flood.
- #
- lappend ap:udefs {ap:nickf "4:12 60 w:k:kb 2"}
- set nickflood(kmsg) "Nick flood detected. $kckcount(form)"
- set nickflood(wmsg) "Warning: You've triggered nick flood protection, slow down your nick changes."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set nickflood(ktype) 2
- set nickflood(klmsg) "Nick floods are not permissable on this network."
- set nickflood(ktime) 0
- #
- ## 19 ## Clones.
- #
- # Use .chanset #channel ap:clones <clones-number> <btime> <pmeth> <btype> (in DCC)
- # Note: This will be the number of clones that triggers punishment.
- # Set default value here:
- lappend ap:udefs {ap:clones "8 120 kb 2"}
- set eclones(kmsg) "Excess clones detected. $kckcount(form)"
- set eclones(wmsg) "Warning: You've exceeded the maximum number of clones, remove your clones now."
- # Do you want to check if the clones are still excess after warn?
- # if yes then set this to the number of seconds to wait before checking again. (0 means no)
- # NOTE: This should be less than <pwait> (at the beginning of the configuration).
- set eclones(caw) 60
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set eclones(ktype) 2
- set eclones(klmsg) "Excess clones are not allowed on this network."
- set eclones(ktime) 0
- #
- ## 20 ## Bad nick.
- #
- # Use .chanset #channel ap:bnicks + <btime> <pmeth> <btype> (in DCC to enable)
- # Set default value here: (+ enabled, - disabled)
- lappend ap:udefs {ap:bnicks "-"}
- set bnicks(global) {
- }
- set bnick(kmsg) "Unwanted person's nickname detected. $kckcount(form)"
- set bnick(wmsg) "Warning! you are using a bad nick, type /nick <nick> to change it."
- set bnick(caw) 60
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set bnick(ktype) 2
- set bnick(klmsg) "Bad nicks are not allowed on this network."
- set bnick(ktime) 0
- #
- ## 21 ## Random drones.
- #
- # Use .chanset #channel ap:drones + <btime> <pmeth> <btype> (in DCC to enable)
- # Set default value here: (+ enabled, - disabled)
- # If you set <pmeth> to a positive-integer then the bot will only kick the drone once.
- # So if the drone rejoins within this amount of seconds it won't be kicked again.
- lappend ap:udefs {ap:drones "-"}
- # Random drones: What masks to exempt? (remember to change these or remoce them)
- set droneexempts(global) { *example1*!*@* *!*example2*@* *!*@example3.net }
- set drone(kmsg) "Possible random drone detected. $kckcount(form)"
- set drone(wmsg) "Warning: You've triggered random drones protection, change your nick now."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set drone(ktype) 2
- set drone(klmsg) "Random drones are not allowed on this network."
- set drone(ktime) 0
- #
- ## 22 ## Bad ident.
- #
- # Use .chanset #channel ap:bidents + <btime> <pmeth> <btype> (in DCC to enable)
- # Set default value here: (+ enabled, - disabled)
- lappend ap:udefs {ap:bidents "-"}
- set bidents(global) {
- }
- set bident(kmsg) "Bad ident detected. $kckcount(form)"
- set bident(wmsg) "Warning! you're using a bad ident. Disconnect, change it and then connect again."
- set bident(caw) 60
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set bident(ktype) 2
- set bident(klmsg) "Bad idents are not allowed on this network."
- set bident(ktime) 0
- #
- ## 23 ## Bad chans/Excess chans.
- #
- # Use .chanset #channel ap:bchans + <btime> <pmeth> <btype> <scan-time> (in DCC to enable)
- # <scan-time> is the time in minutes in which the bot will scan the channel for users in bad chans. (0 disable)
- # Set default value here: (+ enabled, - disabled)
- lappend ap:udefs {ap:bchans "+ 60 w:kb 2 0"}
- # For excess channels use:
- # .chanset #channel ap:echans <excess-chan-number> <btime> <pmeth> <btype> <scan-time> (in DCC to enable)
- # if <excess-chan-number> is 0, then it is disabled.
- lappend ap:udefs {ap:echans "0 60 w:kb 2 0"}
- # Set default global badchan list here:
- set bchans(global) { #butteryfly #jackinchat }
- # Bad chans flood protect, stop whois/ctcp incase of x joins in y seconds: (applies on bad versions too)
- set bchan(floodprot) 4:10
- # Bad chans kick message:
- set bchan(kmsg) "Bad chan detected. $kckcount(form)"
- # Excess chans kick message:
- set bchan(ekmsg) "Excess chans detected. $kckcount(form)"
- # Bad/Excess chans check after warning time in seconds.
- # Incase you chose to warn the offender (punish method), this is the time in seconds to wait
- # before checking again. (keep it 0 if you're not using warn)
- # Setting this to 50 or less will be useless, also make sure this is less than pwait.
- set bchan(caw) 60
- # Bad chans warning message:
- set bchan(wmsg) "Warning: You're on a bad chan %bchan, leave it or you'll be kicked from %chan. You have $bchan(caw) seconds to leave %bchan."
- # Excess chans warning message:
- set bchan(ewmsg) "Warning: You're on excess chans (%echan), maximum allowed is %max. You have $bchan(caw) seconds to leave excess chans."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set bchan(ktype) 2
- set bchan(klmsg) "Joining bad channels is prohibited on this network."
- set bchan(ktime) 0
- #
- ## 24 ## Bad CTCP reply
- #
- # Use .chanset #channel ap:bctcrs + <btime> <pmeth> <btype> <scan-time> (in DCC to enable)
- # Set default value here: (+ enabled, - disabled)
- lappend ap:udefs {ap:bctcrs "- 120 kb 2 0"}
- # Use .chanset #channel ap:ctcpchecks <ctcp-types>
- # Set default CTCP replies to check for: (example: "VERSION TIME FINGER")
- lappend ap:udefs {ap:ctcpchecks "VERSION"}
- set bctcrs(global) {
- "*exploitation script*"
- }
- # %rtype is the CTCP reply type.
- set bctcr(kmsg) "Bad %rtype reply detected. $kckcount(form)"
- # Bad version check after warning time in seconds.
- # Same as check for bad/excess chans.
- set bctcr(caw) 60
- set bctcr(wmsg) "Warning: You replied with \"%vers\" for %rtype request, if you don't change your script you'll be kicked from %chan. You have $bctcr(caw) seconds."
- ## Edit the following only if you choose a punish method above 5 (oper commands):
- set bctcr(ktype) 2
- set bctcr(klmsg) "Using bad scripts is prohibited on this network."
- set bctcr(ktime) 0
- #########################################
- # BOTNET FLOOD PROTECTION (MASS FLOODS) #
- #########################################
- #
- ## 1 ## Botnet Text flood (lines).
- #
- # Use .chanset #channel ap:btextl <lines>:<seconds> <lockmode> <locktime> (in DCC, 0:0 to disable)
- # Set default rate here:
- lappend ap:udefs {ap:btextl "15:7 M-k lines.flood 60"}
- #
- ## 2 ## Botnet Text flood (chars).
- #
- lappend ap:udefs {ap:btextc "550:3 M-k chars.flood 60"}
- #
- ## 3 ## Botnet Notice flood (lines).
- #
- lappend ap:udefs {ap:bnotcl "4:2 M-k lines.flood 60"}
- #
- ## 4 ## Botnet Notice flood (chars).
- #
- lappend ap:udefs {ap:bnotcc "500:3 M-k chars.flood 60"}
- #
- ## 5 ## Botnet CTCP/CTCR flood.
- #
- lappend ap:udefs {ap:bctcp "4:60 M-k ctcp.flood 60"}
- #
- ## 6 ## Botnet join flood.
- #
- lappend ap:udefs {ap:massjoin "9:3 MR-k join.flood 60"}
- #
- ## 7 ## Botnet revolving door flood.
- #
- ## Note: ap:revdoor must be set for this to work.
- lappend ap:udefs {ap:brevdoor "5:3 MR-k revdoor.flood 60"}
- #
- ## 8 ## Botnet part msg flood.
- #
- ## Note: ap:partmsgs or ap:partmsgc (or both) must be enabled for this to work.
- lappend ap:udefs {ap:bpartmsg "5:3 MR-k partmsg.flood 60"}
- #
- ## 9 ## Botnet Nick flood.
- #
- lappend ap:udefs {ap:bnickf "5:30 M-k nick.flood 60"}
- #
- ## 10 ## Botnet Codes flood.
- #
- lappend ap:udefs {ap:bcodes "25:3 cM-k codes.flood 60"}
- ###########################
- # PRIVATE PROTECTIONS #
- ###########################
- # Set here if you want the bot to set a restriction mode on itself when flooded.
- # example: +R is used on DALnet so only registered users can send to the bot.
- # set this to "" if you don't wish to change your bot's modes during a flood.
- # NOTE: Maximum 1 mode, less or more means it's disabled.
- set apfp(rmode) RC
- # Set here the time you want to keep the restriction mode in seconds.
- set apfp(rtime) 30
- # How many seconds do you want to stop answering data from server?
- set apfp(itime) 45
- #
- ## 1 ## Private text floods.
- #
- # Private text (lines) flood <lines>:<seconds>. (0:0 to disable)
- set ptextl(punish) 12:6
- # Private text (chars) flood <chars>:<seconds>. (0:0 to disable)
- set ptextc(punish) 750:6
- #
- ## 2 ## Private notice floods.
- #
- set pnotil(punish) 6:3
- set pnotic(punish) 600:4
- #
- ## 3 ## Private CTCP/CTCR flood.
- #
- set pctcpf(punish) 4:20
- # Configurations end here. #
- ############################
- #
- ######################################################################
- # Code starts here, please do not edit anything unless you know TCL: #
- # __________________________________________________________________ #
- proc istimer {arg {t timers}} {
- set a ""
- foreach rt [$t] {
- if {[string equal -nocase $arg [lindex $rt 1]]} {
- set a [lindex $rt 2] ; break
- }
- }
- set a
- }
- if {![info exists NumKicks]} {
- if {![file exists $kckcount(file)]} {set NumKicks 0} {
- set NumKicks [read -nonewline [set kcfop [open $kckcount(file)]]][close $kcfop][unset kcfop]
- if {![string is integer -strict $NumKicks]} {set NumKicks 0}
- }
- }
- variable bred 0
- variable sfluds 0
- foreach apudef ${ap:udefs} {
- if {[lindex $apudef 0] == "ap:level" && !$banthruX(do)} {continue}
- setudef str [lindex $apudef 0]
- }
- unset apudef
- proc load {{b bind}} {
- if {$b == "loaded"} { set b bind }
- set nsc [namespace current]
- foreach joinb {cjoin massjoin bchans bctcrs drones bnicks bidents clones} {
- $b join - * "${nsc}::joins $joinb"
- }
- foreach pubmb {textl textc btextl btextc bcodes adv swear repeatl codes caps} {
- $b pubm - * "${nsc}::pubms $pubmb"
- }
- foreach notcb {notcl notcc bnotcl bnotcc bcodes adv swear codes} {
- $b notc - * "${nsc}::notc $notcb"
- }
- foreach ctcpb {textl textc btextl btextc bcodes adv swear repeatl codes caps} {
- $b ctcp - ACTION "${nsc}::ctcps $ctcpb"
- }
- foreach {modem modeb} {"* -b" rembs "* +b" massb "* -o" massd "* +o" cbcd} {
- $b mode - $modem "${nsc}::modes $modeb"
- }
- foreach partb {revdoor partmsgs adv swear} {
- $b part - * "${nsc}::parts $partb"
- }
- foreach signb {revdoor adv swear} {
- $b sign - * "${nsc}::parts $signb"
- }
- $b ctcp - * "${nsc}::ctcps ctcps"
- $b ctcp - * "${nsc}::ctcps bctcp"
- $b nick - * "${nsc}::joins bnicks"
- $b nick - * "${nsc}::nicks nickf"
- $b nick - * "${nsc}::nicks bnickf"
- $b ctcr - * ${nsc}::bctcrs
- $b ctcr - * ${nsc}::ctcr
- $b kick - * ${nsc}::massk
- $b raw - 319 ${nsc}::bchansgw
- $b msgm - * "${nsc}::ptext f"
- $b msgm - * "${nsc}::ptext adv"
- $b ctcp - ACTION "${nsc}::pctcp text"
- $b ctcp - * "${nsc}::pctcp ctcp"
- $b notc - * ${nsc}::pnotc
- $b ctcr - * ${nsc}::pctcr
- $b flud - * ${nsc}::pflud
- $b time - * ${nsc}::core
- $b time - * ${nsc}::antispamcore
- $b evnt - prerehash ${nsc}::unload
- $b evnt - prerestart ${nsc}::unload
- foreach apdccb {import reset disable add rem list monitor priv} {
- $b dcc n|n ap:$apdccb "${nsc}::cmd $apdccb"
- }
- if {$b == "bind"} {
- rd; variable logkbs
- foreach c [channels] { init $c }
- if {![info exists logkbs(logs)] && $logkbs(do)} {
- lappend logkbs(logs) "\$Log started [ctime [unixtime]]\$"
- if {[file exists $logkbs(file)]} {
- append logkbs(logs) " [lrange [split [read [set f [open $logkbs(file)]]] \n][close $f] 1 end]"
- }
- }
- checkscans
- if {[lsearch -glob [binds loaded] "* ${nsc}::load"] != -1} {
- unbind evnt - loaded ${nsc}::load
- }
- upvar #0 [ezilamn noisrev-pctc] cvar
- if {![string match "* [ezilamn "noitcetorP lennahC"] *" $cvar]} {
- set cvar "$cvar [ezilamn "noitcetorP lennahC -"]"
- }
- putlog "Chan Protection v2"
- }
- }
- proc joins {flood nick uhost hand chan {nn ""}} {
- if {[isbotnick $nick]} {init $chan ; return 0}
- if {[set chan [string tolower $chan]] == "*" || [invalid:apc $nick $hand $chan]} {return 0}
- if {$flood != "bchans" && ![vcg $chan ap:$flood]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- switch -- $flood {
- "cjoin" {
- variable joinflood; variable apjoinfn
- foreach {j s} [cgsplit $off] {break}
- if {[invalid:apf $j $s]} {return 0}
- Nfollow $s apjoinfn([set h jnf:[string tolower [set f [lindex [split $uhost @] 1]]:$chan]]) $nick $uhost
- if {$joinflood(checkident)} {
- Nfollow $s apjoinfn([set hi jif:[string tolower [lindex [split $uhost @] 0]:$chan]]) $nick $uhost
- }
- if {[set ts [follow $s $h $j 1 1]] != -1 || ($joinflood(checkident) && [set ts2 [follow $s $hi $j 1 1]] != -1)} {
- if {[info exists ts2]} { set f [lindex [split $uhost @] 0]; set ts $ts2 ; set h $hi }
- if {$joinflood(lockchan)} {lockc $chan $joinflood(lockmode) $joinflood(locktime) "Join flood from $f"}
- punish $pmeth $apjoinfn($h) $chan [mapr $joinflood(kmsg) "$j joins in $ts secs"] $joinflood(wmsg) $btype $btime $joinflood(klmsg) $joinflood(ktime) $joinflood(ktype) [string tolower $f]:joinflood
- }
- }
- "massjoin" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s] || [isbotnick $nick]} {return 0}
- checklc $s mjf:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] join
- }
- "bnicks" {
- variable bnick; variable bnicks
- if {$nn == ""} { set nn $nick }
- if {[string first # $chan] != 0 || [invalid:apc $nn $hand $chan]} {return 0}
- if {$off != "+"} {return 0}
- if {![info exists bnicks($chan)]} { set l $bnicks(global) } { set l $bnicks($chan) }
- set isbn 0
- foreach bn $l { if {[string match -nocase $bn $nn]} {set isbn 1; break} }
- if {$isbn} {
- if {$bnick(caw) > 0 && [string match -nocase *w* $pmeth]} {
- set bnick([set ch $chan:[string tolower $uhost]]) 1
- if {[istimer "[namespace current]::followrem bnick($ch)" utimers]==""} {
- utimer [expr {$bnick(caw) + 1}] [list [namespace current]::followrem bnick($ch)]
- }
- }
- punish $pmeth [list $nn $uhost] $chan [mapr $bnick(kmsg) $bn] $bnick(wmsg) $btype $btime $bnick(klmsg) $bnick(ktime) $bnick(ktype) [string tolower $uhost]:bnick
- }
- }
- "drones" {
- variable droneexempts
- if {$off != "+"} {return 0}
- set Nod 0
- if {[info exists droneexempts([set chan [string tolower $chan]])]} { set l $droneexempts($chan) } { set l $droneexempts(global) }
- foreach e $l { if {[string match -nocase $e $nick!$uhost]} {set Nod 1 ; break} }
- if {$Nod} {return 0}
- set id [string trimleft [lindex [split $uhost @] 0] ~]
- if {[follow 2 dr:$chan 3] != -1} {return 0}
- if {[regexp {^[a-z]{4,}![a-z]{4,}$} $nick!$id]} {
- if {(![string match {*[aeiou]*} $nick]) || ([regexp {^[^aeiou]{4}|[aeiou]{4}|q[^ua]|[^aeioux]x[^aeiouyx]|[^aeiouy]{5}} $nick dronm] && ![regexp {a{3}|e{3}|i{3}|o{3}|u{3}} $nick])} {
- if {![info exists dronm]} { set dronm "no vowels" }
- droneb $nick $uhost $chan $btime $pmeth $btype *$dronm*
- } elseif {![string match *$id* $nick] && [regexp {q[bcdfghknpqrstwzxv]|x[dfghkmnqrvz]|z[bcdfhmqrtvx]|v[bfghkmnqxw]|g[zv]|kz|bgb|wj|lx|jwm} $nick dronm]} {
- droneb $nick $uhost $chan $btime $pmeth $btype *$dronm*
- }
- }
- }
- "bidents" {
- variable bident; variable bidents
- if {[invalid:apc $nick $hand $chan]} {return 0}
- if {$off != "+"} {return 0}
- scan $uhost {%[^@]} ident
- if {![info exists bidents($chan)]} { set l $bidents(global) } { set l $bidents($chan) }
- set isbi 0
- foreach bi $l { if {[string match -nocase $bi $ident]} {set isbi 1; break} }
- if {$isbi} {
- if {$bident(caw) > 0 && [string match -nocase *w* $pmeth]} {
- set bident([set ch $chan:[string tolower $uhost]]) 1
- if {[istimer "[namespace current]::followrem bident($ch)" utimers]==""} {
- utimer [expr {$bident(caw) + 1}] [list [namespace current]::followrem bident($ch)]
- }
- }
- punish $pmeth [list $nick $uhost] $chan [mapr $bident(kmsg) $bi] $bident(wmsg) $btype $btime $bident(klmsg) $bident(ktime) $bident(ktype) [string tolower $uhost]:bident
- }
- }
- "clones" {
- variable eclones
- if {![string is integer $off] || $off <= 0} {return 0}
- set c 0
- foreach ccheck [chanlist $chan] {
- if {[string equal -nocase [scan $uhost {%*[^@]@%s}] [scan [set chost [getchanhost $ccheck $chan]] {%*[^@]@%s}]]} {
- incr c ; lappend cn $ccheck ; lappend cn $chost
- }
- }
- if {$c >= $off} {
- if {$eclones(caw) > 0 && [string match -nocase *w* $pmeth]} {
- set eclones([set ch $chan:[string tolower [lindex [split $uhost @] 1]]]) 1
- if {[istimer "[namespace current]::followrem eclones($ch)" utimers]==""} {
- utimer [expr {$eclones(caw) + 1}] [list [namespace current]::followrem eclones($ch)]
- }
- }
- punish $pmeth $cn $chan [mapr $eclones(kmsg) %ic/$c] $eclones(wmsg) $btype $btime $eclones(klmsg) $eclones(ktime) $eclones(ktype) [string tolower [scan $uhost {%*[^@]@%s}]]:eclones
- }
- }
- "bchans" {
- if {[vcg $chan ap:bchans] || [vcg $chan ap:echans]} {
- set off1 [lindex [split [channel get $chan ap:echans]] 0]
- if {![string is integer -strict $off1]} {set off1 0}
- if {$off == "+" || $off1 > 0} {
- bchansw $nick $uhost $hand $chan 0
- }
- }
- }
- "bctcrs" {
- if {$off == "+"} { bchansw $nick $uhost $hand $chan 1 }
- }
- }
- }
- proc pubms {flood nick uhost hand chan arg} {
- if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
- if {![vcg $chan ap:$flood]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- switch -- $flood {
- "textl" - "textc" {
- foreach {o s} [cgsplit $off] {break}
- seqflood $flood $o $s $nick $uhost $chan $pmeth $btype $btime [string length $arg]
- }
- "btextl" - "btextc" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checklc $s $flood:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] "text ([expr {$flood=="btextl"?"lines":"chars"}])" [expr {$flood=="btextl"?1:[string length $arg]}]
- }
- "repeatl" {
- variable repeatf
- foreach {o s} [cgsplit $off] {break}
- set arg [cf $arg]
- if {![invalid:apf $o $s]} {
- if {[set ts [follow $s rpt:[md5 [string tolower $uhost:$arg:$chan]] $o]] != -1} {
- set kmsg [mapr $repeatf(kmsg) "$o repeats in $ts secs"]
- set wmsg [string map {%type text} $repeatf(wmsg)] ; set reptype repeatl
- }
- }
- if {![info exists kmsg] && [vcg $chan ap:repeatc]} {
- set cgotc [split [channel get $chan ap:repeatc]]
- if {[string is integer [set i [lindex $cgotc 0]]] && $i > 0} {
- set cl "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&"
- for {set c 0} {$c < [string length $cl]} {incr c} {
- if {[string match -nocase *[string repeat [string index $cl $c] $i]* $arg]} {
- foreach {btime pmeth btype} [lrange $cgotc 1 end] {break}
- set kmsg [mapr $repeatf(lkmsg) "${i}+ consecutive [string index $cl $c]'s"]
- set wmsg [string map {%type letter} $repeatf(wmsg)] ; set reptype repeatc ; break
- }
- }
- }
- }
- if {[info exists kmsg]} {
- punish $pmeth [list $nick $uhost] $chan $kmsg $wmsg $btype $btime $repeatf(klmsg) $repeatf(ktime) $repeatf(ktype) [string tolower $uhost]:$reptype
- }
- }
- "codes" {
- variable codesf
- if {[string is integer [set cc [ccodes $chan $arg ap:codes]]] && $cc > 0} {
- punish [lindex $cgot 5] [list $nick $uhost] $chan [mapr $codesf(kmsg) "$cc chars affected"] $codesf(wmsg) [lindex $cgot 6] [lindex $cgot 4] $codesf(klmsg) $codesf(ktime) $codesf(ktype) [string tolower $uhost]:codesf
- }
- }
- "bcodes" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checklc $s bcodes:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] "control codes" [regexp -all {\002|\003\d{1,2}(,\d{1,2})?|\017|\026|\037} $arg]
- }
- "adv" {
- if {$off != "+"} {return 0}
- variable adv
- if {[set advword [isspam $arg $chan]] != ""} {
- punish $pmeth [list $nick $uhost] $chan [mapr $adv(kmsg) *$advword*] $adv(wmsg) $btype $btime $adv(klmsg) $adv(ktime) $adv(ktype) [string tolower $uhost]:adv
- }
- }
- "swear" {
- variable swear ; variable bwords
- if {$off != "+"} {return 0}
- set arg [cf $arg]
- if {![info exists bwords($chan)]} { set l $bwords(global) } { set l $bwords($chan) }
- foreach bw $l {
- if {[string match -nocase $bw $arg]} {
- punish $pmeth [list $nick $uhost] $chan [mapr $swear(kmsg) $bw] $swear(wmsg) $btype $btime $swear(klmsg) $swear(ktime) $swear(ktype) [string tolower $uhost]:swear
- break
- }
- }
- }
- "caps" {
- variable capsp
- set linelen [string length [set arg [cf $arg]]]
- foreach {p l} [cgsplit $off] {break}
- if {[invalid:apf $p $l] || $linelen < $l} {return 0}
- if {[set caps [regexp -all {[A-Z]} $arg]] > 0} {
- if {[set pl [expr {$caps * 100 / $linelen}]] >= $p} {
- punish $pmeth [list $nick $uhost] $chan [mapr $capsp(kmsg) "${pl}% of $linelen chars"] $capsp(wmsg) $btype $btime $capsp(klmsg) $capsp(ktime) $capsp(ktype) [string tolower $uhost]:capsp
- }
- }
- }
- }
- }
- proc notc {flood nick uhost hand arg chan} {
- if {[isbotnick [lindex [split $chan @] 0]] || [string first @ $chan] == 0 || ![regexp {.+!.+@.+} $nick!$uhost]} {return 0}
- if {![vcg $chan ap:$flood]} {return 0}
- if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- switch -- $flood {
- "notcl" - "notcc" {
- foreach {o s} [cgsplit $off] {break}
- seqflood $flood $o $s $nick $uhost $chan $pmeth $btype $btime [string length $arg]
- }
- "codes" - "bcodes" - "adv" - "swear" {
- pubms $flood $nick $uhost $hand $chan $arg
- }
- "bnotcl" - "bnotcc" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checklc $s $flood:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] "notice ([expr {$flood=="bnotcl"?"lines":"chars"}])" [expr {$flood=="bnotcl"?1:[string length $arg]}]
- }
- }
- }
- proc ctcps {flood nick uhost hand chan kw arg} {
- if {[isbotnick [lindex [split $chan @] 0]] || [string equal -nocase chat $kw]} {return 0}
- if {[string equal -nocase action $kw]} {
- pubms $flood $nick $uhost $hand $chan $arg
- } {
- if {![vcg $chan ap:$flood]} {return 0}
- if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- switch -- $flood {
- "ctcps" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checkf $s $o ctcpc:[string tolower $uhost:$chan] $uhost $chan $pmeth $nick {$o CTCPs} $btype $btime ctcpf
- }
- "bctcp" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checklc $s bctcpc:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] CTCP
- }
- }
- }
- }
- proc modes {flood nick uhost hand chan mc targ} {
- if {$flood == "cbcd" && [isbotnick $targ] && [follow 5 botoped:$chan 2 1 1] == -1} {
- checkbcd $chan
- } elseif {$flood == "rembs"} {
- if {[set t [istimer "pushmode $chan -b $targ"]]!=""} { killtimer $t }
- } elseif {$flood != "cbcd"} {
- if {[isbotnick $nick] && $flood == "massb"} {
- variable logkbs
- if {$logkbs(do)} { aplog "\[[clock format [clock seconds] -format %T]\] Banned $targ on $chan" }
- }
- if {![vcg $chan ap:$flood] || [isbotnick $nick] || [matchattr $hand fmo|fmo $chan]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- variable serv
- switch -- $flood {
- "massb" {
- variable massb
- foreach {o s} [cgsplit $off] {break}
- if {$nick == "" || $nick == $targ || [invalid:apf $o $s]} {return 0}
- if {[set ts [follow $s mssb:[string tolower $uhost:$chan] $o]] != -1} {
- if {$massb(deop)} {
- putquick "$serv(nick) :[string map [list %nick $nick %chan $chan] $serv(command)]"
- if {[botisop $chan]} { putquick "MODE $chan -o $nick" }
- }
- punish $pmeth [list $nick $uhost] $chan [mapr $massb(kmsg) "$o bans in $ts secs"] $massb(wmsg) $btype $btime $massb(klmsg) $massb(ktime) $massb(ktype) [string tolower $uhost]:massb
- }
- }
- "massd" {
- variable massdeop
- foreach {o s} [cgsplit $off] {break}
- if {$nick == "" || $nick == $targ || [invalid:apf $o $s]} {return 0}
- if {[set ts [follow $s mssd:[string tolower $uhost:$chan] $o]] != -1} {
- if {$massdeop(deop)} {
- putquick "$serv(nick) :[string map [list %chan $chan %nick $nick] $serv(command)]"
- if {[botisop $chan]} { putquick "MODE $chan -o $nick" }
- }
- punish $pmeth [list $nick $uhost] $chan [mapr $massdeop(kmsg) "$o deops in $ts secs"] $massdeop(wmsg) $btype $btime $massdeop(klmsg) $massdeop(ktime) $massdeop(ktype) [string tolower $uhost]:massdeop
- }
- }
- }
- }
- }
- proc parts {flood nick uhost hand chan arg} {
- if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
- if {![vcg $chan ap:$flood]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- switch -- $flood {
- "revdoor" {
- variable revdoor ; variable banthruX ; variable ::max-bans
- if {![string is integer $off] || $off <= 0} {return 0}
- if {[set gcj [getchanjoin $nick $chan]] >= [set ut [unixtime]]-$off} {
- if {[vcg $chan ap:brevdoor]} {
- foreach {o s} [cgsplit [lindex [set cgot2 [split [channel get $chan ap:brevdoor]]] 0]] {break}
- if {![invalid:apf $o $s]} {
- checklc $s brevdc:$chan $o $chan [join [lrange $cgot2 1 end-1]] [lindex $cgot2 end] "revolving door"
- }
- }
- set rvne 0
- foreach rve $revdoor(exempt) { if {[string match -nocase $rve $arg]} {set rvne 1 ; break} }
- if {$rvne} {return 0}
- punish $pmeth [list $nick $uhost] $chan [mapr $revdoor(kmsg) "[expr {$ut-$gcj}] sec(s) revolution"] $revdoor(wmsg) $btype $btime $revdoor(klmsg) $revdoor(ktime) $revdoor(ktype) [string tolower $uhost]:revdoor
- }
- }
- "partmsgs" {
- variable pmsgf
- if {($off > 0 && [set al [string length $arg]] >= $off) || [set cl [ccodes $chan $arg ap:partmsgc]] > 0} {
- if {[vcg $chan ap:bpartmsg]} {
- foreach {o s} [cgsplit [lindex [set cgot2 [split [channel get $chan ap:bpartmsg]]] 0]] {break}
- if {![invalid:apf $o $s]} {
- checklc $s bpmsgc:$chan $o $chan [join [lrange $cgot2 1 end-1]] [lindex $cgot2 end] "part msg"
- }
- }
- if {[info exists cl]} {
- set kmsg [mapr $pmsgf(kmsg) "$cl chars affected by codes"]
- foreach {fo1 fo2 fo3 fo4 btime pmeth btype} [split [channel get $chan ap:partmsgc]] {break}
- } {
- set kmsg [mapr $pmsgf(kmsg) "$al chars"]
- }
- punish $pmeth [list $nick $uhost] $chan $kmsg $pmsgf(wmsg) $btype $btime $pmsgf(klmsg) $pmsgf(ktime) $pmsgf(ktype) [string tolower $uhost]:pmsgf
- }
- }
- "adv" - "swear" {
- if {![vcg $chan ap:pqsadv]} {return 0}
- foreach {s a} [split [channel get $chan ap:pqsadv]] {
- set s [lindex [split $s :] 1]
- set a [lindex [split $a :] 1]
- break
- }
- if {($flood == "adv" && $a) || ($flood == "swear" && $s)} {
- pubms $flood $nick $uhost $hand $chan $arg
- }
- }
- }
- }
- proc nicks {flood nick uhost hand chan nn} {
- if {[string first # $chan] != 0 || [invalid:apc $nn $hand [set chan [string tolower $chan]]]} {return 0}
- if {![vcg $chan ap:$flood]} {return 0}
- foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
- switch -- $flood {
- "nickf" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checkf $s $o nckflood:[string tolower $uhost:$chan] $uhost $chan $pmeth $nick {$o changes} $btype $btime nickflood
- }
- "bnickf" {
- foreach {o s} [cgsplit $off] {break}
- if {[invalid:apf $o $s]} {return 0}
- checklc $s bnickc:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] nick
- }
- }
- }
- proc massk {nick uhost hand chan targ arg} {
- variable masskick ; variable serv
- if {![isbotnick $nick]} {
- if {![vcg $chan ap:massk]} {return 0}
- foreach {off btime pmeth btype} [split [channel get $chan ap:massk]] {break}
- foreach {o s} [cgsplit $off] {break}
- if {$nick == $targ || [invalid:apf $o $s] || [matchattr $hand fmo|fmo $chan]} {return 0}
- if {[set ts [follow $s mssk:[string tolower $uhost:$chan] $o]] != -1} {
- if {$masskick(deop)} {
- putquick "$serv(nick) :[string map [list %chan $chan %nick $nick] $serv(command)]"
- if {[botisop $chan]} { putquick "MODE $chan -o $nick" }
- }
- punish $pmeth [list $nick $uhost] $chan [mapr $masskick(kmsg) "$o kicks in $ts secs"] $masskick(wmsg) $btype $btime $masskick(klmsg) $masskick(ktime) $masskick(ktype) [string tolower $uhost]:masskick
- }
- } {
- variable logkbs
- if {$logkbs(do)} { aplog "\[[clock format [clock seconds] -format %T]\] Kicked $targ from $chan for reason: $arg" }
- }
- }
- proc lim {} {
- foreach c [channels] {
- if {![vcg $c ap:limit]} {continue}
- if {[set l [channel get $c ap:limit]] > 0 && [botisop $c]} {
- if {[string match *l* [lindex [split [getchanmode $c]] 0]]} {
- if {abs($l - ([set cl [lindex [split [getchanmode $c]] end]] - [set ccl [llength [chanlist $c]]])) >= ceil($l * 30 / 100.0)} {
- pushmode $c +l [expr {$ccl + $l}]
- }
- } {pushmode $c +l [expr {[llength [chanlist $c]] + $l}]}
- }
- }
- }
- proc ctcr {nick uhost hand chan kw arg} {
- if {[isbotnick [lindex [split $chan "@"] 0]] || [lindex [split $chan "@"] 1] != ""} {return 0}
- ctcps bctcp $nick $uhost $hand $chan $kw $arg
- ctcps ctcp $nick $uhost $hand $chan $kw $arg
- }
- proc ccodes {ch a f} {
- if {![vcg $ch $f]} {return 0}
- foreach {r b u c btime pmeth btype} [split [channel get $ch $f]] {break}
- if {![icodes [set codes "$r $b $u $c"]]} {return 0}
- set p 0
- foreach cg [split $codes] {
- scan $cg {%[^:]:%s} t v
- if {$v <= 0} {continue}
- set t [string map {r \026 b \002 u \037 c \003} $t]
- if {![info exists fc($t)]} {set fc($t) 0}
- foreach l [lrange [split $a $t] 1 end] {
- set l [string range [set l [cf $l]] 0 [expr {[set fo [string first \017 $l]] == -1?"end":"$fo"}]]
- if {$t == "\003"} {
- if {[regsub {^\d{1,2}(,\d{1,2})?} $l "" l]} {
- if {[incr fc($t) [string length $l]] >= $v} {set p 1; break}
- continue
- }
- }
- if {![info exists cc($t)]} {set cc($t) 0}
- if {!($cc($t) % 2)} { if {[incr fc($t) [string length $l]] >= $v} {set p 1; break} }
- incr cc($t)
- }
- if {$p} {break}
- }
- if {$p} {return $fc($t)}
- return 0
- }
- proc isspam {arg {chan ""}} {
- variable adexempts; variable adwords
- set arg [string tolower [cf $arg]]; set advword ""
- if {$chan != "" && [info exists adexempts($chan)]} {set l $adexempts($chan)} {set l $adexempts(global)}
- foreach ade $l {set arg [string map [list [string map [list %chan $chan] $ade] ""] $arg]}
- if {![regexp {(^|\s)((www\.|#)[^\s]|ftp://|http://|(/server|//(\.?)write)\s)} $arg advword]} {
- if {$chan != "" && [info exists adwords($chan)]} {set l $adwords($chan)} {set l $adwords(global)}
- set isad 0
- foreach advword $l { if {[string match -nocase $advword $arg]} {set isad 1; break} }
- if {!$isad} {set advword ""}
- }
- return $advword
- }
- proc bchansw {nick uhost hand chan type} {
- variable bchan; variable apbcnick; variable apbvnick
- foreach {o s} [split $bchan(floodprot) :] {break}
- if {!$type && [follow $s bchw:[set chan [string tolower $chan]] $o] == -1 && ([vcg $chan ap:bchans] || [vcg $chan ap:echans])} {
- set apbcnick([string tolower $nick]) $chan
- putserv "whois $nick"
- } elseif {$type && [follow $s ctcrr:$chan $o] == -1 && [vcg $chan ap:bctcrs]} {
- foreach bctcr [split [channel get $chan ap:ctcpchecks]] {
- if {[set bctcr [string toupper $bctcr]] != ""} {
- set apbvnick([string tolower $nick]:$bctcr) $chan
- putserv "privmsg $nick :\001$bctcr\001"
- }
- }
- }
- }
- proc bchansgw {from key arg} {
- variable bchan ; variable bchans ; variable apbcnick
- set arg [string trim $arg]
- if {![info exists apbcnick([set nick [string tolower [lindex [split $arg] 1]]])]} {return 0}
- set chan $apbcnick($nick)
- if {[vcg $chan ap:bchans]} {
- foreach {off btime pmeth btype} [split [channel get $chan ap:bchans]] {break}
- }
- if {[info exists off] && $off == "+"} {
- if {![info exists bchans($chan)]} { set l $bchans(global) } { set l $bchans($chan) }
- foreach c [split [string tolower [join [lrange [split $arg] 2 end]]]] {
- set c [string trimleft $c ":@%+"]
- foreach bc $l {
- if {[string match $bc $c]} {
- set uhost [getchanhost $nick $chan]
- if {$uhost != ""} {
- set kmsg [mapr $bchan(kmsg) $c]
- set wmsg [string map [list %chan $chan %bchan $c] $bchan(wmsg)]
- putlog "\002AP\002: Bchans: Detected \002$nick\002 on (\002$c\002) joining \002$chan\002."
- }
- break
- }
- }
- if {[info exists uhost]} {break}
- }
- }
- if {![info exists kmsg] && [vcg $chan ap:echans]} {
- foreach {off btime pmeth btype} [split [channel get $chan ap:echans]] {break}
- if {$off > 0 && [set ecs [llength [lrange [split $arg] 2 end]]] >= $off} {
- set uhost [getchanhost $nick $chan]
- if {$uhost != ""} {
- set kmsg [mapr $bchan(ekmsg) "$ecs chans"]
- set wmsg [string map [list %echan "$ecs chans" %max [expr {$off-1}]] $bchan(ewmsg)]
- putlog "\002AP\002: Echans: Detected \002$nick\002 on \002$ecs\002 channels."
- }
- }
- }
- if {[info exists kmsg]} {
- if {$bchan(caw) > 0 && [string match -nocase *w* $pmeth]} {
- set bchan([set ch $chan:[string tolower $uhost]]) 1
- if {[istimer "[namespace current]::followrem bchan($ch)" utimers]==""} {
- utimer [expr {$bchan(caw) + 1}] [list [namespace current]::followrem bchan($ch)]
- }
- }
- foreach aChan [channels] {
- if {[onchan $nick $aChan]} {
- if {![string equal -nocase $aChan $chan]} {
- if {[string is integer -strict $off] && [vcg $aChan ap:echans]} {
- foreach {off btime pmeth btype} [split [channel get $aChan ap:echans]] {break}
- } elseif {[vcg $aChan ap:bchans]} {
- foreach {off btime pmeth btype} [split [channel get $aChan ap:bchans]] {break}
- } {
- continue
- }
- }
- punish $pmeth [list $nick $uhost] $aChan $kmsg $wmsg $btype $btime $bchan(klmsg) $bchan(ktime) $bchan(ktype) [string tolower $uhost]:badchan
- }
- }
- }
- return 0
- }
- proc bctcrs {nick uhost hand targ kw arg} {
- variable bctcr; variable bctcrs; variable apbvnick
- if {![isbotnick $targ] || ![info exists apbvnick([set nkw [string tolower $nick]:[set kw [string toupper $kw]]])]} {return 0}
- set chan $apbvnick($nkw); unset apbvnick($nkw)
- if {![vcg $chan ap:bctcrs]} {return 0}
- foreach {off btime pmeth btype} [split [channel get $chan ap:bctcrs]] {break}
- if {![info exists bctcrs($chan)]} { set l $bctcrs(global) } { set l $bctcrs($chan) }
- set m 0
- foreach bv $l { if {[string match -nocase $bv $arg]} {set m 1; break} }
- if {$m} {
- if {$bctcr(caw) > 0 && [string match -nocase *w* $pmeth]} {
- set bctcr([set ch $chan:[string tolower $uhost]]) 1
- if {[istimer "[namespace current]::followrem bctcr($ch)" utimers]==""} {
- utimer [expr {$bctcr(caw) + 1}] [list [namespace current]::followrem bctcr($ch)]
- }
- }
- punish $pmeth [list $nick $uhost] $chan [string map [list %rtype $kw] [mapr $bctcr(kmsg) $bv]] [string map [list %rtype $kw] [mapr $bctcr(wmsg) $bv]] $btype $btime $bctcr(klmsg) $bctcr(ktime) $bctcr(ktype) [string tolower $uhost]:bctcrs
- }
- }
- proc checkbcd c {
- variable cbcd
- if {!$cbcd(check) || [nap:chan $c $cbcd(chans)]} {return 0}
- foreach n [chanlist $c] {
- foreach sc $cbcd(procs) {
- joins [string map {echans bchans} $sc] $n [getchanhost $n $c] [nick2hand $n $c] $c
- }
- }
- }
- proc core {m h args} {
- lim; checkscans
- variable NumKicks; variable kckcount; variable ptrig; variable pwait; variable logkbs
- variable removebs; variable ::max-bans
- if {[regexp {03:00} $h:$m] && [info exists logkbs(logs)]} {
- if {$logkbs(do) == 1} {
- set f [open $logkbs(file).yesterday w]
- } elseif {$logkbs(do) == 2} {
- set f [open $logkbs(file).[clock format [expr {[unixtime]-86400}] -format "%d.%m.%y"] w]
- }
- if {[info exists logkbs(logs)]} { foreach log $logkbs(logs) { if {$log != ""} { puts $f $log } } }
- close $f
- set logkbs(logs) [list "\$Log started [ctime [unixtime]]\$"]
- }
- if {$removebs} {
- foreach c [channels] {
- if {[botisop $c] && [llength [set cl [chanbans $c]]] >= ${max-bans}} {
- foreach b [lrange $cl 0 [expr {$removebs-1}]] { pushmode $c -b [lindex $b 0] }
- }
- }
- }
- if {[scan $m %d]%2} {return 0}
- foreach {pn pe} [array get ptrig] { if {[unixtime]-[lindex $pe 1] > $pwait} {unset ptrig($pn)} }
- if {[regexp {\d0} $m]} {
- set kc [open $kckcount(file) w]
- puts $kc $NumKicks ; close $kc
- variable following
- foreach {an ae} [array get following] {
- if {([clock clicks -milliseconds]-[lindex $ae 1])/1000 > $pwait} {
- unset following($an)
- }
- }
- variable punishing
- foreach {i s} [array get punishing] {if {[clock clicks -milliseconds] >= $s} {unset punishing($i)}}
- if {$logkbs(do)} {
- set f [open $logkbs(file) w]
- foreach log $logkbs(logs) { if {$log != ""} { puts $f $log } }
- close $f
- }
- }
- }
- set antispam(next) -1
- #set antispam(tip) ${my-ip}
- #set antispam(thost) ${my-hostname}
- proc antispamcore {m h args} {
- variable antispam; variable Sec
- if {![info exists antispam(idx)] || ![valididx $antispam(idx)]} {
- if {[info exists antispam(idx)]} {unset antispam(idx)}
- if {[info exists antispam(cnick)]} {unset antispam(cnick)}
- foreach {s p} [split [lindex [lindex $::servers [expr {[incr antispam(next)]%[llength $::servers]}]] 0] :] {break}
- foreach c [channels] {
- if {[vcg $c ap:antispam] && [lindex [split [channel get $c ap:antispam]] 0] == "+"} {
- set ::my-ip $antispam(ip); set ::my-hostname $antispam(host)
- control [connect $s $p] [namespace current]::antispambot
- putlog "\002AP\002: AntiSpamBot: Connecting to $s:$p..."
- break
- }
- }
- return
- }
- set asbc 0
- foreach c [channels] {
- set mins [expr {[scan $m %d]+([scan $h %d]*60)}]
- foreach {off greet cycle idle} [split [channel get $c ap:antispam]] {break}
- if {$off == "+"} {incr asbc}
- if {[onchan $antispam(cnick) $c] && $off != "+"} {
- putdcc $antispam(idx) "part $c"
- } elseif {$cycle != 0 && $mins%$cycle == 0 && [onchan $antispam(cnick) $c]} {
- if {![info exists antispam([set e [string tolower $c]:idle])]} {set antispam($e) [unixtime]}
- if {[unixtime]-$antispam($e) < $idle*60 && [botisop $c]} {
- putlog "\002AP\002: AntiSpamBot: Cycling $c..."
- putdcc $antispam(idx) "part $c"
- putdcc $antispam(idx) "join $c"
- }
- } {if {![onchan $antispam(cnick) $c] && $off == "+"} {putdcc $antispam(idx) "join $c"}}
- }
- if {!$asbc} {
- putdcc $antispam(idx) quit
- putlog "\002AP\002: AntiSpamBot: Disconnected (disabled on all channels)..."
- }
- }
- proc antispambot {idx arg} {
- variable antispam; variable adv; variable greetexempts; variable antiSpamOnline
- if {${::my-ip} != $antispam(tip)} {set ::my-hostname $antispam(thost); set ::my-ip $antispam(tip)}
- if {$arg == ""} {
- if {[info exists antispam(idx)]} {unset antispam(idx)}
- if {[info exists antispam(cnick)]} {unset antispam(cnick)}
- if {[info exists antiSmapOnline]} {unset antiSpamOnline}
- if {[info exists antispam(qrsn)]} {set rsn $antispam(qrsn); unset antispam(qrsn)} {set rsn (dead)}
- putlog "\002AP\002: AntiSpamBot: Disconnected $rsn..."
- return
- }
- if {![info exists antispam(idx)] && ![info exists antispam(cnick)]} {
- set antispam(idx) $idx ; set antispam(cnick) $antispam(nick)
- putdcc $idx "user $antispam(user) 8 * :$antispam(realname)"
- putdcc $idx "nick $antispam(cnick)"
- return
- }
- if {![info exists antiSpamOnline]} {
- set antiSpamOnline 1
- if {[istimer [namespace current]::dumpqueues utimers]==""} {
- variable Sec -1
- utimer 1 [namespace current]::dumpqueues
- }
- }
- switch -- [string tolower [lindex [split $arg] 0]] {
- "ping" {putdcc $idx "pong [lindex [split $arg] 1]"}
- "error" {set antispam(qrsn) [join [lrange [split $arg] 4 end]]; return}
- }
- switch -- [set raw [string tolower [lindex [split $arg] 1]]] {
- "privmsg" - "notice" {
- set src [lindex [split $arg] 0]
- set asbn [lindex [split $arg] 2]
- if {![string equal -nocase $asbn $antispam(cnick)]} {return}
- if {[scan $src {:%[^!]!%s} nick uhost] != 2} {return}
- set text [join [lrange [split $arg] 3 end]]
- if {[set advword [isspam $text]] == ""} {
- if {$raw == "privmsg" && [string match ":\001DCC Send *\001" $text]} {set advword "DCC SEND"}
- }
- if {$advword == ""} {
- foreach {o s} [split $antispam(mprot) :] {break}
- if {[follow $s asbm $o 1 1] != -1} {return}
- set ism 0
- foreach t $antispam(t) {if {[string match -nocase $t $text]} {set ism 1; break}}
- set l $greetexempts(global)
- set f 0; foreach ge $l { if {[string match -nocase $ge $nick!$uhost]} {set f 1;break} }
- if {$ism && !$f} {asb:queue $nick [lindex $antispam(r) [rand [llength $antispam(r)]]]}
- }
- }
- "invite" {
- set src [lindex [split $arg] 0]
- if {[scan $src {:%[^!]!%s} nick uhost] != 2} {return}
- set advword "INVITE"
- }
- "001" {
- putlog "\002AP\002: AntiSpamBot: Connected and registered as $antispam(cnick)."
- set antispam(pong) 1; set antispam(idx) $idx
- foreach c [channels] {
- if {![vcg $c ap:antispam]} {continue}
- if {[lindex [split [channel get $c ap:antispam]] 0] == "+"} {
- putdcc $idx "join $c"
- }
- }
- }
- "433" {
- if {$antispam(cnick) == $antispam(nick)} {set antispam(cnick) $antispam(altnick)} {
- set antispam(cnick) [string replace $antispam(nick) end end [rand 10]]
- }
- putdcc $idx "nick $antispam(cnick)"
- }
- "nick" {
- if {[string trimleft [lindex [split [lindex [split $arg] 0] @] 0] :] == $antispam(cnick)} {
- set antispam(cnick) [string trimleft [lindex [split $arg] 2] :]
- }
- }
- "join" {
- foreach {o s} [split $antispam(jprot) :] {break}
- set c [string trim [string tolower [string trimleft [lindex [split $arg] end] :]]]
- if {![validchan $c]} {return}
- foreach {off greet cy i} [split [channel get $c ap:antispam]] {break}
- if {[vcg $c ap:antispam] && $off == "+"} {
- if {[scan [lindex [split $arg] 0] {:%[^!]!%s} nick uhost] != 2} {return}
- if {[string equal -nocase $nick $antispam(cnick)] || [follow $s asbj:$c $o 1 1] != -1} {return}
- set antispam($c:idle) [unixtime]
- if {[info exists greetexempts($c)]} {set l $greetexempts($c)} {set l $greetexempts(global)}
- set f 0; foreach ge $l { if {[string match -nocase $ge $nick!$uhost]} {set f 1;break} }
- if {!$f && $greet == "+" && ![invalid:apc $nick [finduser $nick!$uhost] $c]} {
- asb:queue $nick [string map [list %nick $nick] $antispam(greet)]
- }
- }
- }
- }
- if {[info exists advword] && $advword != ""} {
- set hand [finduser [string trimleft $src :]]
- foreach c [channels] {
- if {![vcg $c ap:antispam] || ![vcg $c ap:adv] || [invalid:apc $nick $hand $c]} {continue}
- if {[lindex [split [channel get $c ap:antispam]] 0] == "+"} {
- foreach {off btime pmeth btype} [split [channel get $c ap:adv]] {break}
- if {$off == "+"} {
- if {$antispam(banall) || [onchan $nick $c]} {
- punish $pmeth [list $nick $uhost] $c [mapr $adv(kmsg) *$advword*] $adv(wmsg) $btype $btime $adv(klmsg) $adv(ktime) $adv(ktype) [string tolower $uhost]:adv
- }
- }
- }
- }
- }
- }
- proc cmd {cmd hand idx arg} {
- variable banthruX
- set arg [string tolower $arg]
- if {[regexp {add|rem|list} $cmd]} {
- set lists {bchans bnicks bidents bwords adexempts droneexempts bctcrs adwords greetexempts}
- if {[regexp {add|rem} $cmd]} {
- set synp " <bad chans/nicks/idents/bwords/adexempts/droneexempts/bctcrs/adwords/greetexempts>"
- set sl [join [lrange [split $arg] 2 end]]
- if {[join [set l [cl $sl]]]==""} {
- putdcc $idx "\002AP\002: SYNTAX: .ap:$cmd <[join $lists /]> <#chan/global>$synp."
- return 0
- }
- } {set synp ""}
- if {[scan $arg "%s %s" t c] != 2} {
- putdcc $idx "\002AP\002: SYNTAX: .ap:$cmd <[join $lists /]> <#chan/global>$synp."
- return 0
- }
- if {[lsearch -exact $lists $t] == -1} {
- putdcc $idx "\002AP\002: Invalid list \002$t\002, should be one of: [join $lists ", "]."
- return 0
- }
- if {[set ti [string first # $c]] != 0 && $c != "global"} {
- putdcc $idx "\002AP\002: Invalid chan \002$c\002, either use a valid chan or 'global'."
- return 0
- }
- upvar [namespace current]::$t aptv
- } elseif {[regexp {reset|disable} $cmd]} {
- if {[set chans [string map [list * [channels]] [lindex [split $arg] 0]]] == ""} {
- putdcc $idx "\002AP\002: SYNTAX: .ap:$cmd <#channel>"
- return 0
- }
- variable ap:udefs
- }
- switch -- $cmd {
- "add" {
- if {$ti == 0} {
- if {[validchan $c]} {
- if {![info exists aptv($c)]} {
- set aptv($c) $l
- set unfound $l
- } {
- foreach bs $l {
- if {[lsearch -exact $aptv($c) $bs] != -1} { lappend found $bs } {
- if {[string equal bchans $t] && [string first # $bs] != 0} {
- putdcc $idx "\002AP\002: Invalid channel $bs, not adding..."
- continue
- }
- lappend unfound $bs
- lappend aptv($c) $bs
- }
- }
- }
- } {
- putdcc $idx "\002AP\002: Invalid chan \002$c\002, either use a valid chan or 'global'."
- return 0
- }
- } {
- foreach bs $l {
- if {[lsearch -exact $aptv($c) $bs] != -1} { lappend found $bs } {
- if {[string equal bchans $t] && [string first # $bs] != 0} {
- putdcc $idx "\002AP\002: Invalid channel $bs, not adding..."
- continue
- }
- lappend unfound $bs
- lappend aptv($c) $bs
- }
- }
- }
- if {[info exists unfound]} {
- foreach unfou [ww $unfound] {
- putdcc $idx "\002AP\002: Succesfully added [join $unfou ,] to $c $t list."
- }
- sv
- }
- if {[info exists found]} {
- foreach fou [ww $found] {
- putdcc $idx "\002AP\002: [join $fou ,] already exist in $c $t list."
- }
- }
- }
- "rem" {
- if {$ti == 0} {
- if {[validchan $c]} {
- if {![info exists aptv($c)]} {
- putdcc $idx "\002AP\002: $c $t list is empty."
- return 0
- } {
- foreach bs $l {
- if {[set sbs [lsearch -exact $aptv($c) $bs]] != -1} {
- set aptv($c) [lreplace $aptv($c) $sbs $sbs]
- lappend found $bs
- if {$aptv($c) == {}} {unset aptv($c) ; break}
- } { lappend unfound $bs }
- }
- }
- } {
- putdcc $idx "\002AP\002: $c is an invalid channel, either use a valid chan or 'global'."
- return 0
- }
- } {
- foreach bs $l {
- if {[set sbs [lsearch -exact $aptv($c) $bs]] != -1} {
- set aptv($c) [lreplace $aptv($c) $sbs $sbs]
- lappend found $bs
- } { lappend unfound $bs }
- }
- }
- if {[info exists unfound]} {
- foreach unfou [ww $unfound] {putdcc $idx "\002AP\002: [join $unfou ,] was not found in $c $t list."}
- }
- if {[info exists found]} {
- foreach fou [ww $found] {putdcc $idx "\002AP\002: Succesfully removed [join $fou ,] from $c $t list."}
- sv
- }
- }
- "list" {
- if {$ti == 0} {
- if {[validchan $c]} {
- if {[info exists aptv($c)] && $aptv($c) != {}} {
- foreach aplist [ww $aptv($c)] {putdcc $idx "\002AP\002: $c $t list: [join $aplist ,]"}
- } {putdcc $idx "\002AP\002: $c $t list is empty." ; return 0}
- } {putdcc $idx "\002AP\002: Invalid chan \002$c\002, either use a valid chan or 'global'." ; return 0}
- } {
- if {$aptv($c) != {}} {
- foreach aplist [ww $aptv($c)] {putdcc $idx "\002AP\002: $c $t list: [join $aplist ,]"}
- } {putdcc $idx "\002AP\002: $c $t list is empty."}
- }
- }
- "import" {
- if {[scan $arg "%s %s" oc ncs] != 2} {
- putdcc $idx "\002AP\002: SYNTAX: .ap:import <oldchan> <newchan>" ; return 0
- }
- foreach nc [string map [list * [channels]] $ncs] {
- if {[validchan $oc] && [validchan $nc]} {
- foreach ci [channel info $oc] {
- if {[string match ap:* [lindex $ci 0]]} {channel set $nc [lindex $ci 0] [lindex $ci 1]}
- }
- putdcc $idx "\002AP\002: Imported all AllProtection settings from $oc to $nc."
- } {putdcc $idx "\002AP\002: Failed! Make sure that $oc and $nc are valid channels."}
- }
- }
- "reset" {
- foreach c $chans {
- if {[validchan $c]} {
- foreach u ${ap:udefs} {
- if {[lindex $u 0] == "ap:level" && !$banthruX(do)} {continue}
- channel set $c [lindex $u 0] [lindex $u 1]
- }
- putdcc $idx "\002AP\002: Reset all AllProtection settings on $c."
- } {putdcc $idx "\002AP\002: Failed! Make sure that $c is a valid channel."}
- }
- }
- "disable" {
- set OZ {ap:repeatc ap:clones ap:echans ap:partmsgs}
- set NV {ap:adv ap:swear ap:bnicks ap:drones ap:bidents ap:bchans ap:bctcrs ap:antispam}
- set CC {ap:codes ap:partmsgc}
- foreach c $chans {
- if {[validchan $c]} {
- foreach u ${ap:udefs} {
- if {[set ud [lindex $u 0]] == "ap:level" && !$banthruX(do)} {continue}
- set rest [join [lrange [split [channel get $c $ud]] 1 end]]
- if {[lsearch -exact $OZ $ud] != -1} {
- channel set $c $ud "0 $rest"
- } elseif {[lsearch -exact $NV $ud] != -1} {
- channel set $c $ud "- $rest"
- } elseif {[lsearch -exact $CC $ud] != -1} {
- channel set $c $ud "r:0 b:0 u:0 c:0 [join [lrange [split [channel get $c $ud]] 4 end]]"
- } elseif {[regexp {ap:(limit|level)} $u]} {
- channel set $c $ud 0
- } elseif {$ud == "ap:pqsadv"} {
- channel set $c $ud "s:0 a:0"
- } elseif {$ud != "ap:ctcpchecks"} {
- channel set $c $ud "0:0 $rest"
- }
- }
- putdcc $idx "\002AP\002: Succesfully disabled all AP protections on $c."
- } {putdcc $idx "\002AP\002: $c is an invalid channel (not in my chanlist)."}
- }
- }
- "monitor" {
- variable ptrig ; variable pwait
- if {[set pta [array get ptrig]]==""} {putdcc $idx "\002AP\002: No users currently under punishment."} {
- set fm 0
- foreach {uf ot} $pta {
- foreach {c u f} [split $uf :] {break} ; foreach {o t} $ot {break}
- if {[set dur [expr {$pwait-([unixtime]-$t)}]]>0} {
- putdcc $idx "\002AP\002: \002$u\002 followed for \002$f\002 on \002$c\002. Offense: \002$o\002 (expires in \002$dur\002 secs)."
- if {!$fm} {set fm 1}
- }
- }
- if {!$fm} {putdcc $idx "\002AP\002: No users currently under punishment."}
- }
- }
- "priv" {
- set ptypes {ptextl ptextc pnotil pnotic pctcpf}
- switch -- [string tolower [lindex [split $arg] 0]] {
- "set" {
- set pt [string tolower [lindex [split $arg] 1]]
- if {[lsearch -exact $ptypes $pt] == -1 || ![regexp {^\d+:\d+$} [set v [lindex [split $arg] 2]]]} {
- putdcc $idx "\002AP\002: SYNTAX: .ap:priv set <[join $ptypes /]> #:#" ; return 0
- }
- upvar [namespace current]::$pt privt
- set privt(punish) $v
- putdcc $idx "\002AP\002: Successfully set \002$pt\002 to \002$v\002."
- sv
- }
- "list" {
- foreach pt $ptypes {
- upvar [namespace current]::$pt privt
- putdcc $idx "\002AP\002: ${pt}: $privt(punish)"
- }
- }
- default {putdcc $idx "\002AP\002: SYNTAX: .ap:priv <set/list> \[[join $ptypes /]\]."}
- }
- }
- }
- }
- proc sv {} {
- set apf [open scripts/aplists w]
- set lists {bchans bnicks bidents bwords adexempts droneexempts bctcrs adwords
- greetexempts ptextl ptextc pnotil pnotic pctcpf}
- foreach list $lists {
- variable $list
- foreach {apc apbc} [array get $list] {
- if {$apc != "global" && $apbc == {}} {continue}
- puts $apf "$list $apc [string trim [regsub -all {\s{1,}} $apbc " "]]"
- }
- }
- close $apf
- }
- proc rd {} {
- if {[file exists scripts/aplists]} {
- foreach apl [split [string tolower [read [set apf [open scripts/aplists]]]] \n][close $apf] {
- upvar [namespace current]::[lindex [split $apl] 0] apt
- set apt([set p [lindex [split $apl] 1]]) [set e [lrange $apl 2 end]]
- if {[regexp {^\d+:\d+$} [join $e]]} {set apt($p) [join $e]}
- }
- } {sv}
- }
- proc ptext {flood nick uhost hand arg} {
- switch -- $flood {
- "f" {
- variable ptextl ; variable ptextc
- foreach {ptxtll ptxtls} [split $ptextl(punish) :] {break}
- foreach {ptxtcl ptxtcs} [split $ptextc(punish) :] {break}
- if {[matchattr $hand fmo]} {return 0}
- if {($ptxtll > 0 && [follow $ptxtls ptxtl $ptxtll] != -1) || ($ptxtcl > 0 && \
- [follow $ptxtcs ptxtc $ptxtcl [string length $arg]] != -1)} {
- privl MSG
- }
- }
- "adv" {
- foreach chan [channels] {
- if {[onchan $nick $chan]} { pubms adv $nick $uhost $hand $chan $arg }
- }
- }
- }
- }
- proc pctcp {flood nick uhost hand dest kw arg} {
- if {![isbotnick [lindex [split $dest @] 0]] || [string equal -nocase chat $kw]} {return 0}
- switch -- $flood {
- "text" {if {[isbotnick [lindex [split $dest @] 0]]} { ptext f $nick $uhost $hand $arg }}
- "ctcp" {
- variable pctcpf
- foreach {pctcpl pctcps} [split $pctcpf(punish) :] {break}
- if {$pctcpl <= 0 || [string equal -nocase action $kw] || [matchattr $hand fmo]} {return 0}
- if {[follow $pctcps pfctcp $pctcpl] != -1} {privl CTCP}
- }
- }
- }
- proc pnotc {nick uhost hand arg dest} {
- variable pnotil; variable pnotic
- foreach {pntll pntls} [split $pnotil(punish) :] {break}
- foreach {pntcl pntcs} [split $pnotic(punish) :] {break}
- if {[isbotnick [lindex [split $dest @] 0]] && ![matchattr $hand fmo]} {
- if {($pntll > 0 && [follow $pntls pnotl $pntll] != -1) || ($pntcl > 0 && \
- [follow $pntcs pnotc $pntcl [string length $arg]] != -1)} {
- privl NOTICE
- }
- }
- }
- proc pctcr {nick uhost hand dest kw arg} {
- if {![isbotnick [lindex [split $dest "@"] 0]]} {return 0}
- pctcp ctcp $nick $uhost $hand $dest $kw $arg
- }
- proc pflud {nick uhost hand type chan} {
- variable sfluds
- expr {$chan == "*" && $sfluds}
- }
- proc privl t {
- variable sfluds ; variable apfp ; variable bred ; variable ::botnick
- if {!$sfluds} {
- if {[string length $apfp(rmode)]==1} {
- if {!$bred} {
- putquick "MODE $botnick +$apfp(rmode)" -next
- if {$apfp(rtime) > 0} {
- utimer $apfp(rtime) [namespace current]::remr
- }
- set bred 1
- putlog "\002AP\002: Set mode +$apfp(rmode) on me. ($t flood on me!)"
- }
- }
- set sfluds 1
- utimer $apfp(itime) [list set [namespace current]::sfluds 0]
- putlog "\002AP\002: Private botnet flood detected. Temporarly stopped answering recieved data."
- }
- }
- proc punish {pm nl c km wm bty bti klm kti kty fv} {
- variable pwait; variable kline; variable ptrig; variable banthruX; variable ::max-bans
- if {$kti < 0} { set kti $kline(time) }
- set fv $c:$fv
- if {![info exists ptrig($fv)] || [unixtime]-[lindex $ptrig($fv) 1] > $pwait} {
- set ptrig($fv) [list 0 [unixtime]]
- }
- set o [lindex $ptrig($fv) 0]
- set ol [llength [split $pm :]]
- if {$o > $ol - 1} { set o [expr {$ol - 1}] }
- set p [string tolower [lindex [split $pm :] $o]]
- pcount $pwait ptrig($fv)
- set cc 0
- switch -- $p {
- "kb" {
- foreach {jn ju} $nl {
- if {[onchan $jn $c] && ![punishing k:$jn:$c]} {
- putquick "KICK $c $jn :[clonemap [mapall $km $c $bti] [incr cc]]"
- }
- if {[punishing b:[set bm [masktype $jn!$ju $bty]]:$c]} {continue}
- if {![info exists arb($bm)]} {
- if {$banthruX(do)==2 || ($banthruX(do) && [llength [chanbans $c]] >= ${max-bans})} {
- putquick [mapXcmd $banthruX(cmd) $jn $ju $c [clonemap [mapall $km $c $bti] $cc] $bty $bti]
- } {
- queue $c $bm
- if {$bti > 0 && [istimer "pushmode $c -b $bm"] == ""} {
- timer $bti [list pushmode $c -b $bm]
- }
- set arb($bm) 1
- }
- }
- }
- }
- "k" {
- foreach {jn ju} $nl {
- if {[onchan $jn $c] && ![punishing k:$jn:$c]} {
- putquick "KICK $c $jn :[clonemap [mapall $km $c 0] [incr cc]]"
- }
- }
- }
- "b" {
- foreach {jn ju} $nl {
- if {[punishing b:[set bm [masktype $jn!$ju $bty]]:$c]} {continue}
- if {![info exists arb($bm)]} {
- if {$banthruX(do)==2 || ($banthruX(do) && [llength [chanbans $c]] >= ${max-bans})} {
- putquick [mapXcmd $banthruX(cmd) $jn $ju $c [clonemap [mapall $km $c $bti] [incr cc]] $bty $bti]
- } {
- queue $c $bm
- if {$bti > 0 && [istimer "pushmode $c -b $bm"] == ""} {
- timer $bti [list pushmode $c -b $bm]
- }
- set arb($bm) 1
- }
- }
- }
- }
- "w" {
- variable wmeth; variable bnick; variable bident; variable eclones; variable bchan; variable bctcr
- set nsc [namespace current]
- if {[info exists eclones([string tolower $c:[lindex [split [lindex $nl 1] @] 1]])]} {
- utimer $eclones(caw) [list ${nsc}::joins clones [set tempn [lindex $nl end-1]] [lindex $nl end] [nick2hand $tempn $c] $c]
- }
- foreach {jn ju} $nl {
- if {[info exists bchan([set ch [string tolower $c:$ju]])]} {
- utimer $bchan(caw) [list ${nsc}::bchansw $jn $ju [nick2hand $jn $c] $c 0]
- } elseif {[info exists bctcr($ch)]} {
- utimer $bctcr(caw) [list ${nsc}::bchansw $jn $ju [nick2hand $jn $c] $c 1]
- } elseif {[info exists bnick($ch)]} {
- utimer $bnick(caw) [list ${nsc}::joins bnicks $jn $ju [nick2hand $jn $c] $c]
- } elseif {[info exists bident($ch)]} {
- utimer $bident(caw) [list ${nsc}::joins bidents $jn $ju [nick2hand $jn $c] $c]
- }
- if {[punishing w:$jn:$c]} {continue}
- puthelp "$wmeth $jn :$wm"
- lappend offenders $jn
- }
- if {[info exists offenders]} { putlog "\002AP\002: Warned [join $offenders \002,\002] on $c: $wm" }
- }
- "kl" {
- foreach {jn ju} $nl {
- if {[punishing kl:[set klmask [scan [masktype $jn!$ju $kty] {%*[^!]!%s}]]:$c]} {continue}
- if {![info exists ark($klmask)]} {
- putquick [string map [list %mask $klmask %time $kti %reason $klm] $kline(cmd)]
- set ark($klmask) 1
- }
- }
- }
- "kil" {
- foreach {jn ju} $nl {
- if {[punishing kil:$jn:$c]} {continue}
- putquick "kill $jn $klm"
- }
- }
- "v" {}
- default {
- error "\002AP\002: Invalid punishment method, must be either v, w, k, b, kb, kl or kil."
- }
- }
- return 0
- }
- proc checkscans {} {
- variable Sec; variable apqueue; variable antiSpamOnline
- if {[istimer [namespace current]::dumpqueues utimers]==""} {
- set startTimer 0
- if {$apqueue(time) > 0 || [info exists antiSpamOnline]} {
- set startTimer 1
- }
- if {$startTimer} {
- set Sec -1
- utimer 1 [namespace current]::dumpqueues
- }
- }
- foreach ss {ap:bctcrs ap:bchans ap:echans} {
- foreach c [channels] {
- if {![info exists scanned($c)]} {set scanned($c) 0}
- if {!$scanned($c)} {set scanned($c) [activt [string tolower $c] $ss]}
- }
- }
- }
- proc activt {c ss} {
- set got [split [channel get $c $ss]]
- set i 0
- set ns [namespace current]
- if {[vcg $c $ss]} {
- if {![string is integer -strict [set ce [lindex $got 0]]]} {
- if {$ce == "+" && [set t [lindex $got end]] > 0} {
- set st 1
- if {[istimer "${ns}::scanc $c $ss"]==""} { timer $t [list ${ns}::scanc $c $ss]; set i 1 }
- }
- } elseif {$ce > 0 && [set t [lindex $got end]] > 0} {
- set st 1
- if {[istimer "${ns}::scanc $c $ss"]==""} { timer $t [list ${ns}::scanc $c $ss] }
- }
- }
- if {[info exists st] && [istimer [namespace current]::dumpqueues utimers]==""} {
- variable Sec
- set Sec -1
- utimer 1 [namespace current]::dumpqueues
- }
- set i
- }
- proc scanc {c ss} {
- variable scanq
- set got [split [channel get $c $ss]]
- set scan 0
- if {[vcg $c $ss]} {
- if {![string is integer -strict [set ce [lindex $got 0]]]} {
- if {$ce == "+" && [lindex $got end] > 0} {set scan 1}
- } elseif {$ce > 0 && [lindex $got end] > 0} {set scan 1}
- if {$scan} {
- set scanq($c) {}
- foreach n [chanlist $c] {
- if {[invalid:apc $n [set h [nick2hand $n $c]] $c]} {continue}
- lappend scanq($c) [list $n [getchanhost $n $c] $h [expr {[regexp {ap:[be]chans} $ss]?0:1}]]
- }
- activt $c $ss
- }
- }
- }
- proc ezilamn str {
- set str2 ""
- for {set i [string length $str]} {$i > 0} {incr i -1} {
- append str2 [string index $str [expr {$i - 1}]]
- }
- set str2
- }
- proc vcg {c cg} {
- if {$cg == "ap:ctcpchecks"} {return [expr {[channel get $c $cg] != ""}]}
- if {$cg == "ap:pqsadv"} {return [string match -nocase {s:[01] a:[01]} [channel get $c $cg]]}
- set L5 {ap:bchans ap:echans ap:bctcrs}
- set L7 {ap:codes ap:partmsgc}
- set lgot [llength [set got [split [channel get $c $cg]]]]
- if {[lsearch $L5 $cg] != -1} {
- if {$lgot != 5} {return 0} ; set i 1
- } elseif {[lsearch $L7 $cg] != -1} {
- if {$lgot != 7} {return 0} ; set i 4
- } elseif {[regexp {ap:(limit|level)} $cg]} {
- if {$lgot != 1} {return 0} ; set i 0
- } {
- if {![regexp {ap:(b[^i]|massj)} $cg] || $cg == "ap:bnicks"} {
- if {$lgot != 4} {return 0} ; set i 1
- if {$cg == "ap:antispam"} {
- set i 2
- } elseif {[regexp {ap:(repeatc|partmsgs|revdoor|clones|echans)} $cg] && ![string is integer -strict [lindex $got 0]]} {
- return 0
- }
- } {set i end}
- }
- expr {[string is integer -strict [lindex $got $i]]&&[string is integer -strict [lindex $got end]]}
- }
- proc init c {
- variable ap:udefs; variable banthruX
- foreach u ${ap:udefs} {
- if {[lindex $u 0] == "ap:level" && !$banthruX(do)} {continue}
- if {![vcg $c [lindex $u 0]]} {channel set $c [lindex $u 0] [lindex $u 1]}
- }
- foreach budef {ap:btextl ap:btextc ap:bnotcl ap:bnotcc ap:bctcp ap:massjoin ap:brevdoor
- ap:bpartmsg ap:bnickf ap:bcodes} {
- append olm [lindex [split [lindex [split [channel get $c $budef]] 1] -] 0]
- }
- foreach lm [lsort -unique [split $olm ""]] {
- if {[lsearch [binds mode] "* {\\\* -$lm} *"] == -1} {
- bind mode - "* -$lm" [namespace current]::resetbtc
- }
- }
- }
- proc remr {} {
- variable bred; variable apfp; variable ::botnick
- puthelp "MODE $botnick -$apfp(rmode)"
- putlog "\002AP\002: Removed +$apfp(rmode) from me."
- set bred 0
- }
- proc lockc {c m tl ty} {
- variable btclocked; variable notifyusers
- if {![info exists btclocked($c)]} {set btclocked($c) 0}
- if {!$btclocked($c)} {
- dolock $c $m
- if {$tl > 0} {
- utimer $tl [list [namespace current]::btcunlock $c $m btclocked($c)]
- } {utimer 90 [list [namespace current]::resetbtc * * * $c]}
- set btclocked($c) 1
- if {$btclocked(lnotc) != ""} {
- puthelp "NOTICE $c :$btclocked(lnotc)"
- }
- putlog "\002AP\002: Locked $c due to $ty."
- if {$notifyusers != {}} {foreach nuser $notifyusers {sendnote AP $nuser "$ty detected on $c."}}
- }
- }
- proc dolock {c lm} {
- set mode "MODE $c +"
- foreach m [split $lm] {append mode "$m "}
- putquick [string trim $mode] -next
- }
- proc resetbtc args {
- variable btclocked
- set btclocked([string tolower [lindex $args 3]]) 0
- }
- proc btcunlock {c ms lv} {
- upvar [namespace current]::$lv locked
- if {![info exists locked] || $locked} {set locked 0}
- foreach mode [split $ms ""] {
- if {[string equal "-" $mode]} {break}
- if {[regexp $mode [lindex [split [getchanmode $c]] 0]]} {pushmode $c -$mode}
- }
- }
- proc droneb {n u c bti pm bty mapr} {
- variable drone
- if {![string is integer -strict $pm]} {
- punish $pm [list $n $u] $c [mapr $drone(kmsg) $mapr] $drone(wmsg) $bty $bti $drone(klmsg) $drone(ktime) $drone(ktype) [string tolower $u]:drone
- } {
- if {![punishing k:$n:$c $pm]} {putquick "KICK $c $n :[mapall [mapr $drone(kmsg) $mapr] $c 0]"}
- }
- putlog "\002AP\002: DRONE: Detected \002$n\002!\002[scan $u {%[^@]}]\002 on \002$c\002."
- }
- proc seqflood {f o s n u c pm bty bti sla} {
- variable following
- if {[invalid:apf $o $s]} {return 0}
- set uhc $f:[string tolower $u:$c]
- if {[regexp {textc|notcc} $f]} {
- if {[info exists following($uhc)]} {set myo [lindex $following($uhc) 0]}
- set i $sla ; set rsn {$myo chars}
- } {set i 1; set rsn {$o lines}}
- checkf $s $o $uhc $u $c $pm $n $rsn $bty $bti $f $i [expr {[info exists myo]?$myo:""}]
- }
- proc follow {s fv pun {v 1} {ty 0}} {
- variable following
- if {![info exists following($fv)]} {
- set o $v
- set t [clock clicks -milliseconds]
- } {
- foreach {o t} $following($fv) {break}
- incr o $v
- }
- if {[set z [expr {([clock clicks -milliseconds]-$t)/1000.}]] >= $s} {
- set o $v
- set t [clock clicks -milliseconds]
- }
- set following($fv) [list $o $t]
- if {$o >= $pun} {if {!$ty} {followrem following($fv)} ; return [expr {$z>=$s?0.0:$z}]}
- return -1
- }
- proc pcount {v var} {
- upvar [namespace current]::$var p
- foreach {o t} $p {break}
- set p [expr {[unixtime]-$t <= $v?[list [incr o] [unixtime]]:[list 1 [unixtime]]}]
- }
- proc punishing {i {s 0.25}} {
- variable punishing
- set s [expr {int($s*1000)}]
- set i [string tolower $i]; set t [clock clicks -milliseconds]
- if {[info exists punishing($i)] && $punishing($i) > $t} {set i 1} {
- set punishing($i) [expr {$t+$s}]
- set i 0
- }
- }
- proc followrem fv {
- upvar [namespace current]::$fv f
- if {[info exists f]} {unset f}
- }
- proc Nfollow {t tl n u} {
- upvar [namespace current]::$tl f
- lappend f $n $u
- utimer $t [list [namespace current]::Nfollowrem $tl $n $u]
- }
- proc Nfollowrem {tl n u} {
- upvar [namespace current]::$tl bl
- if {[info exists bl]} {
- set bl [lreplace $bl [set i [lsearch -exact $bl $n]] $i]
- set bl [lreplace $bl [set i [lsearch -exact $bl $u]] $i]
- if {$bl == {}} {unset bl}
- }
- }
- proc asb:queue {n t} {variable antispam; lappend antispam(q) $n $t}
- proc mapall {s c b} {
- string map [list %date [ctime [unixtime]] %chan $c %kcount [getkcount] %btime $b] $s
- }
- proc clonemap {k c} { string map [list %ic $c] $k }
- proc mapr {m r} { string map [list %rate $r] $m }
- proc getkcount {} {incr [namespace current]::NumKicks}
- proc cgsplit off {
- foreach {o s} [split $off :] {break}
- expr {([info exists o]&&[info exists s])?[list $o $s]:{0 0}}
- }
- proc invalid:apf {o s} {
- expr {![string is integer -strict $o] || $o <= 0 || ![string is double -strict $s] || $s <= 0}
- }
- proc icodes str { regexp {r:\d{1,3}\sb:\d{1,3}\su:\d{1,3}\sc:\d{1,3}} $str }
- proc invalid:apc {n h c} {
- variable exmptype
- if {[isbotnick $n] || ![botisop $c] || [matchattr $h n|n $c]} {return 1}
- set true 0
- foreach t $exmptype {
- switch -- [string tolower $t] {
- "ops" {set true [isop $n $c]}
- "voices" {set true [isvoice $n $c]}
- "halfops" {set true [ishalfop $n $c]}
- default {set e $t}
- }
- if {$true} {break}
- if {[info exists e]&&[regexp {[+-].+[|&][+-].+} $e]} {
- if {[set true [matchattr $h $e $c]]} {break}
- } elseif {[info exists e]} {
- error "Invalid exempt type ($e)."
- }
- }
- set true
- }
- proc nap:chan {c cl} {
- expr {!($cl == "*" || [lsearch -exact [split [string tolower $cl]] [string tolower $c]] != -1)}
- }
- proc masktype {nuh {t 3}} {
- if {[scan $nuh {%[^!]!%[^@]@%s} n u h]!=3} {
- error "Usage: masktype <nick!user@host> \[type\]"
- }
- if {$t == 10} {return *!$u@*}
- if {$t == 11} {return $n!*@*}
- if {[string match {[3489]} $t]} {set h [lindex [split [maskhost $h] @] 1]}
- if {[string match {[1368]} $t]} {set u *[string trimleft $u ~]} elseif {[string match {[2479]} $t]} {set u *}
- if {[string match {[01234]} $t]} {set n *}
- set nuh $n!$u@$h
- }
- proc ww l {
- set cur {}
- foreach word [set l][unset l] {
- if {[llength $cur]==10} {
- lappend out $cur
- set cur [list $word]
- } { lappend cur $word }
- }
- lappend out $cur
- }
- proc cf str { string map {\017 ""} [stripcodes bcruag $str] }
- proc queue {c b} {
- variable apqueue
- if {$apqueue(time) < 1} {putquick "MODE $c +b $b"} {
- lappend apqueue([string tolower $c]) $b
- }
- }
- proc mapXcmd {cmd n u c k ty ti} {
- string map [list %reason $k %level [channel get $c ap:level] %btime [expr {$ti/60}] \
- %ban [masktype $n!$u $ty] %nick $n %chan $c] $cmd
- }
- proc dumpqueues {} {
- variable apqueue; variable Sec; variable antispam
- if {[incr Sec]>59} {set Sec 0}
- if {$apqueue(time) > 0 && $Sec % $apqueue(time) == 0} {
- variable ::modes-per-line
- foreach c [channels] {
- if {![info exists apqueue([set c [string tolower $c]])] || $apqueue($c) == {}} {continue}
- for {set i 0} {$i<[llength [set apqueue($c) [lsort -unique $apqueue($c)]]]} {incr i} {
- set bans [lrange $apqueue($c) $i [incr i [expr {${modes-per-line}-1}]]]
- putquick "MODE $c +[string repeat b [llength $bans]] [join $bans]" -next
- }
- set apqueue($c) {}
- }
- }
- if {$Sec % 2 == 0 && [info exists antispam(idx)] && [valididx $antispam(idx)]} {
- if {[info exists antispam(q)]} {
- foreach {n t} $antispam(q) {
- putdcc $antispam(idx) "privmsg $n :$t"
- }
- }
- set antispam(q) {}
- }
- if {$Sec % 3 == 0} {
- variable scanq
- foreach {c l} [array get scanq] {
- set i 0
- foreach e $l {
- foreach {n u h t} $e {break}
- set scanq($c) [lrange $l [incr i] end]
- bchansw $n $u $h $c $t
- if {$i == 10} {break}
- }
- }
- }
- utimer 1 [namespace current]::dumpqueues
- }
- proc checkf {s o var u c pm n mapr bty bti ft {v 1} {myo ""}} {
- upvar [namespace current]::$ft myvar
- if {[set ts [follow $s $var $o $v]] != -1} {
- if {$myo == ""} {set myo $v} {incr myo $v}
- punish $pm [list $n $u] $c [mapr $myvar(kmsg) "[subst $mapr] in $ts secs"] $myvar(wmsg) $bty $bti $myvar(klmsg) $myvar(ktime) $myvar(ktype) [string tolower $u]:$ft
- }
- }
- proc checklc {s var o c ms lt r {v 1}} {if {[follow $s $var $o $v] != -1} {lockc $c $ms $lt "Botnet $r flood"}}
- proc cl s {
- set is 0; set res [set tem ""]
- foreach e [split $s] {
- if {!$is} {
- if {![regexp {^"} $e]} { lappend res $e } {
- if {[regexp {"$} $e]} {lappend res [string range $e 1 end-1]} {
- append tem "[string range $e 1 end] "
- set is 1
- }
- }
- } {
- if {[regexp {"$} $e]} {
- append tem [string range $e 0 end-1]
- lappend res $tem ; set tem ""; set is 0
- } {append tem "$e "}
- }
- }
- set res
- }
- proc aplog str {
- variable logkbs
- lappend logkbs(logs) $str
- }
- proc unload type {
- variable logkbs; variable antispam
- foreach t {timer utimer} {
- foreach ti [${t}s] {
- if {[string match [namespace current]::* [lindex $ti 1]]} {kill$t [lindex $ti 2]}
- }
- }
- if {[info exists logkbs(logs)]} {
- set f [open $logkbs(file) w]
- foreach log $logkbs(logs) { if {$log != ""} { puts $f $log } }
- close $f
- }
- if {[info exists antispam(idx)] && [valididx $antispam(idx)]} {
- putdcc $antispam(idx) "part ,"
- killdcc $antispam(idx)
- }
- load unbind
- namespace delete [namespace current]
- putlog "\002A\002ll\002P\002rotection v4.7 successfully unloaded..."
- }
- if {[llength [channels]] == 0 && [llength [userlist]] == 0} {
- bind evnt - loaded [namespace current]::load
- } {
- load
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement