Advertisement
Guest User

apmondino

a guest
Mar 22nd, 2018
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 97.83 KB | None | 0 0
  1. ###########################[ ALL PROTECTION 4.7 ]############################
  2. # #
  3. # Author : Opposing (Fz_Egg@yahoo.com) #
  4. # a.k.a Sir_Fz (Fayez Zouheiry) #
  5. # Version : 4.7 #
  6. # Released: December 21, 2010 #
  7. # Source: http://Sir-Fz.blogspot.com #
  8. ## #
  9. # Description: Has all kinds of channel protections + Botnet channel flood #
  10. # protections and private protections. #
  11. # #
  12. # Commands: #
  13. # DCC: #
  14. # .ap:import <oldchan> <*/newchan> (This sets the AP settings #
  15. # of <oldchan> on <newchan> or all chans if *) #
  16. # .ap:reset <*/chan> (This will reset the AP settings of chan #
  17. # or all chans if * to the default settings) #
  18. # .ap:disable <*/chan> (This will disable all protections on #
  19. # chan or all chans if *) #
  20. # .ap:monitor (displays info about followed punishments) #
  21. # .ap:add <list> <chan/global> <elements> #
  22. # .ap:rem <list> <chan/global> <elements> #
  23. # .ap:list <list> <chan/global> #
  24. # .ap:priv <set/list> <setting> <value> (priv flood settings) #
  25. # ** Available lists: bchans, bnicks, bidents, bwords, adexempts, #
  26. # droneexempts, adwords, bctcrs & greetexempts. #
  27. # #
  28. # All protections are enabled via .chanset DCC command. #
  29. # Use: .chaninfo to know AllProtection's settings (ap:<setting>) #
  30. # NOTE: To set an AP channel setting use: (* means all channels) #
  31. # .chanset <chan> <setting> <value> <btime> <punish> <btype> #
  32. # #
  33. # Credits: #
  34. # - Thanks to my friend Salah Rifai who introduced me to Eggdrops #
  35. # & *nix. He is the person who guided me to Eggdrops' resources. He #
  36. # also was the founder of nexushells.net which was my first shell #
  37. # which hosted my Eggdrop (Shrider). #
  38. # - Thanks to http://forum.egghelp.org which was and still is my #
  39. # tcl toutor, I've learned tcl through this community. #
  40. # - Thanks to slennox for adding a link on the main page of #
  41. # www.egghelp.org to the topic of AllProtection, and for hosting #
  42. # the script on his site when my site went down. #
  43. # - Thanks Silence, Marcel, dotslasher & others for reporting bugs #
  44. # which was an important step for the developement of this script. #
  45. # - Thanks to all who suggested ideas & features at egghelp.org. #
  46. # - Used maskhost & wordwrap procs by user from the egghelp forum. #
  47. # Edited wordwrap slightly to suite its purpose in the script. #
  48. # - Used massmode proc's algorithm for ban-queueing (by user). #
  49. # - Used checkbcd proc by Marcel (edited by me). #
  50. # #
  51. # History: #
  52. # - 4.7: Stable release of the 4.6 series. Got the bad nicks/idents #
  53. # & perhaps other fixes I haven't logged. It was a good ride :) #
  54. # - 4.6b9: The script would not ban if a channel was not added in #
  55. # lower case; fixed now. Fixed other issues... #
  56. # - 4.6b8: Integrated queues, enhanced AntiSpamBot, modulated #
  57. # exempt types, scanning bad/excess chans and bad CTCP replies #
  58. # when bot gains ops, flexible warn method (notice or privmsg), #
  59. # fixed AntiSpamBot IP problem, added ability to exempt hostmasks #
  60. # from greets by antispambot, AntiSpam bans spammers only if on #
  61. # chan (optional), ability to immediately ban thru X, enable or #
  62. # disable bad words/ads ban for quit/part, queue for bad/excess #
  63. # chans scan. Punish bad chan users in all channels. #
  64. # - 4.6b7: Throttle kicking (halt redundant kicks). Bad words/ads #
  65. # now detected in notices, parts & quits. Choose CTCP requests 4 #
  66. # bad ctcp replies (bad version before). Ability to ban thru X. #
  67. # Following now occurs in 1 array (less memory). All flood types #
  68. # now have a punishment method. Added AntiSpamBot. Enhancements #
  69. # made over code. #
  70. # - 4.6b6: Adding drone exempts via .ap:add cmd. Fixed undiscovered #
  71. # exploit in string splitting (string2list). Added extra 2 ban #
  72. # types. Added exemption for part msgs in revdoor protection. #
  73. # Bad version-reply kick, set private flood settings via DCC, log #
  74. # everyday (configurable), scan channels in intervals for bad or #
  75. # excess chans or bad version-replies and ability to add custom #
  76. # advertising words. #
  77. # - 4.6b5: Fixed bugs in badchan and clones protections. Enhanced #
  78. # advertisement detection to avoid false detections. #
  79. # - 4.6b4: Fixed lists saving, uninstalling error. Added ability to #
  80. # remove bans on full banlist + enhanced the drones detecting #
  81. # procedure and the ap:import DCC command to accept *. #
  82. # - 4.6b3: More code fixes and enhancements. You can now add words #
  83. # to be exempted from advertising (channel specific as well) and #
  84. # log bot's kicks and bans. Join flood can now check joins from #
  85. # same idents if enabled. Implemented queueing bans. #
  86. # - 4.6b2: Major coding changes, changed style of binding and procs #
  87. # for better and faster performance. Reduced code & implemented #
  88. # the use of namespaces in order not to conflict with other #
  89. # scripts. Added excess chans protection + several bug fixes. #
  90. # - 4.6b1: Major coding changes, added bad chans protections + bug #
  91. # fixes. #
  92. # #
  93. # Report bugs/suggestions to Fz_Egg@yahoo.com #
  94. # #
  95. # Copyright © 2005 Opposing (aka Sir_Fz) #
  96. # #
  97. # This program is free software; you can redistribute it and/or modify #
  98. # it under the terms of the GNU General Public License as published by #
  99. # the Free Software Foundation; either version 2 of the License, or #
  100. # (at your option) any later version. #
  101. # #
  102. # This program is distributed in the hope that it will be useful, #
  103. # but WITHOUT ANY WARRANTY; without even the implied warranty of #
  104. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  105. # GNU General Public License for more details. #
  106. # #
  107. # You should have received a copy of the GNU General Public License #
  108. # along with this program; if not, write to the Free Software #
  109. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
  110. # #
  111. #############################################################################
  112. #
  113. ##############################
  114. # Configurations start here: #
  115. # __________________________ #
  116.  
  117.  
  118. ########################
  119. # SETTINGS & iNFO #
  120. ########################
  121.  
  122. ### READ THIS FIRST:
  123. # * AllProtection works best with eggdrop1.6.18 and above. (so upgrade)
  124. #
  125. # * AllProtection exempts channel ops, friends (+f) and masters (+mo) from protection by default.
  126. # That means users with the +f or +mo flags will not be affected by any protection.
  127. # (You can add hosts to the +f handle if you don't want the bot to ban them). To prevent from banning
  128. # ChanServ, add chanserv to your bot with the +f or +mo flag.
  129. #
  130. # * AllProtection does not use the internal banlist of the bot so you will not have to worry
  131. # about other ops not being able to remove the bans, they can! (feature or bug, I dont care :P)
  132. #
  133. # * AllProtection will not trigger protection on a channel where the bot is not oped, so your
  134. # bot will not send redundant commands to the server. (good for the lag)
  135. #
  136. # * AllProtection strips control-codes (i.e. bold, underline, colors...etc) from text when checking for
  137. # repeats, bad words or advertising.
  138. #
  139. # * All settings are enabled via .chanset DCC command. Example: .chanset #channel ap:textl 5:2 15 w:k:kb 2
  140. # this will enable the text flood (lines) protection on #channel (punish on 5 lines or more in 2 seconds)
  141. # 1st warn - 2nd kick - 3rd kickban. ban is 15 minutes and ban type is 2.
  142. #
  143. # * You can use mode lock modes such as "mR-k type.flood" which will work fine with AllProtection.
  144. #
  145. # * Adding elements to the lists (bad words, chans...etc) can ONLY be done via the DCC commands.
  146. #
  147. # * Read all the comments during configuration so you won't miss any important info.
  148. ### Enjoy configuring...
  149.  
  150. # You can change the name of the namespace (AllProtection).
  151. namespace eval AllProtection {
  152.  
  153. # Basic declarations: (don't touch)
  154. variable declr
  155. foreach declr {textl textc notcl notcc capsp repeatf codesf adexempts adwords greetexempts adv antispam bwords
  156. swear ctcpf massdeop massdeop masskick massb joinflood pmsgf revdoor nickflood eclones bnick bnicks drone
  157. bident bidents droneexempts bchans bchan bctcrs bctcr apfp ptextl ptextc pnotil pnotic pctcpf NumKicks apudef
  158. apqueue banthruX ap:udefs logkbs btclocked kckcount cbcd serv kline kcfop} { variable $declr }
  159. unset declr
  160.  
  161. # Do you want your bot to queue bans? set here the time in seconds before dumping bans:
  162. # NOTE: 0 means the bot will set the ban immediately
  163. # The modes-per-line setting in eggdrop.conf is the number of modes allowed per command.
  164. set apqueue(time) 1
  165.  
  166. # Set here the numbers of last bans to be removed on full banlist? (0: remove none)
  167. # NOTE: Full banlist is when the channel has max-bans bans set. (from eggdrop.conf)
  168. variable removebs 20
  169.  
  170. # Do you want the bot to ban through services?
  171. # 0: Never
  172. # 1: Only when banlist is full (determined by max-bans)
  173. # 2: always
  174. set banthruX(do) 0
  175.  
  176. # If banthruX is 1/2, set the command here to ban through services:
  177. # %nick = nickname
  178. # %ban = ban-mask
  179. set banthruX(cmd) "privmsg X :ban %chan %ban %btime %level %reason"
  180.  
  181. # If banthruX is 1/2, set here the default level to be used on all channels
  182. lappend ap:udefs {ap:level 75}
  183.  
  184. # Do you want AP to log all the kicks/bans done by the bot? (0: no, 1: daily, 2: forever)
  185. set logkbs(do) 0
  186.  
  187. # If yes, set the logfile here: (will be reset everyday at 3:00 a.m.)
  188. set logkbs(file) "logs/aplogs.log"
  189.  
  190. # Set here any additional exempts, you can exempt the following:
  191. # ops: Channel ops
  192. # halfops: Channel halfops
  193. # voices: Channel voices
  194. # +flags|+flags: Users with global or channel specific flags (e.g. +fm friends and masters...)
  195. # -flags&-flags: Users which do not have the specified flags (e.g. -k&-k)
  196. variable exmptype {ops voices +fmo|+fmo}
  197.  
  198. # Set here the handles of the users you want to notify when the bots locks a channel
  199. # for mass (botnet) flood.
  200. # example: set notifyusers {TheOwner LamerDude}
  201. variable notifyusers {vuffster vuffie}
  202.  
  203. # Set here the notice to be sent to the channel when the bot locks the channel because of a
  204. # Botnet flood. leave "" if you don't wish the notice to be sent.
  205. set btclocked(lnotc) ""
  206.  
  207. # What info do you wanna add to your kick message?
  208. # After setting this variable, you can use $kckcount(form) to add a these info to the bot's
  209. # kick msg.
  210. ### NOTE:
  211. ## %kcount = number of kicks.
  212. ## %btime = ban time
  213. ## %chan = channel name
  214. ## %date = kick date
  215. ## %rate = offenses in seconds, bad words/nicks/idents/chans/ads or clone/clones (depends on type of offense)
  216. ### PS: You can use the above directly in the kick message (not only here)
  217. set kckcount(form) " ·%kcount·"
  218.  
  219. # Set the file in which the number of kicks will be stored.
  220. set kckcount(file) "scripts/kcount.txt"
  221.  
  222. # Do you want the bot to check for bad nicks/idents and clones when it first joins the channels
  223. # and gains op ? (0: no , 1: yes)
  224. # NOTE: This may be CPU intensive if your bot is on big channels or on alot of channels.
  225. # NOTE: This may (probably will) cause huge self-lag on the bot.
  226. set cbcd(check) 0
  227.  
  228. # If cbcd(check) is set to 1, change this if you want the bot to only check for certain types
  229. # of protection in the nicklist.
  230. # drones : Random drones
  231. # clones : Excess clones and kick them
  232. # bnicks : Bad nicks
  233. # bidents: Bad idents.
  234. # bchans : Bad/Excess channels.
  235. # bctcrs : Bad CTCP replies
  236. set cbcd(procs) {drones clones bnicks bidents bchans bctcrs}
  237.  
  238. # 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)
  239. # example: set cbcd(chans) "#chan1 #chan2"
  240. set cbcd(chans) "#CafeChat"
  241.  
  242. # Your service's chanserv nick.
  243. # example: set serv(nick) "ChanServ" or "PRIVMSG X@channels.undernet.org"
  244. set serv(nick) "ChanServ"
  245.  
  246. # Chanserv deop command.
  247. # use %nick for the nick you want to deop and %chan for the channel name.
  248. # example: set serv(deop) "deop %chan %nick"
  249. set serv(command) "deop %chan %nick"
  250.  
  251. # Set the time in seconds to wait before reseting the punishment monitor:
  252. # Note: this setting means the bot will apply the punishment steps on each user
  253. # within this period of time, otherwise it'll trigger steps from the beginning.
  254. variable pwait 180
  255.  
  256. # Set here the warning method you wish to use: (PRIVMSG or NOTICE)
  257. variable wmeth NOTICE
  258.  
  259. # Edit this only if your bot is an ircop and will use the kline command:
  260. # Set here the kline command used on your server.
  261. # for example some ircds user:
  262. # kline %mask %time %reason
  263. # others use:
  264. # kline %time %mask %reason
  265. ## NOTE:
  266. # %mask = the klined mask.
  267. # %time = the kline time.
  268. # %reason = the kline reason.
  269. ##
  270. set kline(cmd) "kline %time %mask :%reason"
  271.  
  272. # set the default kline time. (seconds or minutes depends on your ircd)
  273. set kline(time) 30
  274.  
  275. ## Available punishment methods:
  276. # v : Void - do nothing
  277. # w : Warn offender
  278. # k : Kick offender
  279. # b : Ban offender
  280. # kb : Kick + Ban offender
  281. # kl : KLine offender
  282. # kil: Kill offender
  283. #
  284. ## You can use them like this for example:
  285. # w:k:kb
  286. # this means, first Warn then Kick then Kickban. (if offence is repeated ofcourse)
  287. ## these steps will be triggered if the offences happend during <pwait> seconds.
  288. # NOTE: These methods are not applicable on all flood types. I only applied this
  289. # feature on the flood types I think they're needed.
  290.  
  291. ## Available ban types:
  292. # 0 : *!user@full.host.tld
  293. # 1 : *!*user@full.host.tld
  294. # 2 : *!*@full.host.tld
  295. # 3 : *!*user@*.host.tld
  296. # 4 : *!*@*.host.tld
  297. # 5 : nick!user@full.host.tld
  298. # 6 : nick!*user@full.host.tld
  299. # 7 : nick!*@full.host.tld
  300. # 8 : nick!*user@*.host.tld
  301. # 9 : nick!*@*.host.tld
  302. # 10: *!user@*
  303. # 11: nick!*@*
  304.  
  305. ## Available kline mask types:
  306. # 0 : user@full.host.tld
  307. # 1 : *user@full.host.tld
  308. # 2 : *@full.host.tld
  309. # 3 : *user@*.host.tld
  310. # 4 : *@*.host.tld
  311. # 5 : user@full.host.tld
  312. # 6 : *user@full.host.tld
  313. # 7 : *@full.host.tld
  314. # 8 : *user@*.host.tld
  315. # 9 : *@*.host.tld
  316. # 10: user@*
  317.  
  318. ##########################
  319. # TEXT FLOOD #
  320. ##########################
  321.  
  322. #
  323. ## 1 ## Text flood (lines)
  324. #
  325.  
  326. # use .chanset #channel ap:textl <lines>:<seconds> <btime> <pmeth> <btype> (in DCC, 0:0 to disable)
  327. # Set default rate here:
  328. lappend ap:udefs {ap:textl "5:2 60 k:kb 2"}
  329.  
  330. # Text flood (lines) kick msg.
  331. set textl(kmsg) "Text flood detected. $kckcount(form)"
  332.  
  333. # Text flood (lines) warn msg.
  334. set textl(wmsg) "Warning: You've triggered text flood (lines) protection, slow down your typing."
  335.  
  336. ## Edit the following only if you choose a punish method above 5 (oper commands):
  337.  
  338. # Text flood (lines) kline mask type.
  339. set textl(ktype) 2
  340.  
  341. # Text flood (lines) kline/kill reason.
  342. set textl(klmsg) "Text flooding is not permissable on this network."
  343.  
  344. # Text flood (lines) kline time (seconds or minutes depends on your ircd).
  345. set textl(ktime) 0
  346.  
  347. #
  348. ## 2 ## Text flood (chars)
  349. #
  350.  
  351. lappend ap:udefs {ap:textc "215:3 120 kb 2"}
  352.  
  353. set textc(kmsg) "Excess chars detected. $kckcount(form)"
  354.  
  355. set textc(wmsg) "Warning: You've triggered text flood (chars) protection, decrease your text legnth."
  356.  
  357. ## Edit the following only if you choose a punish method above 5 (oper commands):
  358.  
  359. set textc(ktype) 2
  360.  
  361. set textc(klmsg) "Text flooding (chars) is not permissable on this network."
  362.  
  363. set textc(ktime) 0
  364.  
  365. #
  366. ## 3 ## Notice flood (lines)
  367. #
  368.  
  369. lappend ap:udefs {ap:notcl "1:10 120 kb 2"}
  370.  
  371. set notcl(kmsg) "Notice not allowed. $kckcount(form)"
  372.  
  373. set notcl(wmsg) "Warning: you've triggered notice flood (lines) protection, slow down your notices."
  374.  
  375. ## Edit the following only if you choose a punish method above 5 (oper commands):
  376.  
  377. set notcl(ktype) 2
  378.  
  379. set notcl(klmsg) "Notice flooding is not permissable on this network."
  380.  
  381. set notcl(ktime) 0
  382.  
  383. #
  384. ## 4 ## Notice flood (chars)
  385. #
  386.  
  387. lappend ap:udefs {ap:notcc "200:3 180 kb 2"}
  388.  
  389. set notcc(kmsg) "Excess chars (notice) detected. $kckcount(form)"
  390.  
  391. set notcc(wmsg) "Warning: you've triggered notice flood (chars) protection, decrease your text length."
  392.  
  393. ## Edit the following only if you choose a punish method above 5 (oper commands):
  394.  
  395. set notcc(ktype) 2
  396.  
  397. set notcc(klmsg) "Notice flooding (chars) is not permissable on this network."
  398.  
  399. set notcc(ktime) 0
  400.  
  401. ###################
  402. # TEXT #
  403. ###################
  404.  
  405. #
  406. ## 5 ## Caps flood.
  407. #
  408.  
  409. # Use .chanset #channel ap:caps <percent>:<line-length> <btime> <pmeth> <btype> (in DCC, 0:0 to disable)
  410. # Set default rate here:
  411. lappend ap:udefs {ap:caps "60:90 120 kb 2"}
  412.  
  413. set capsp(kmsg) "Excess CAPS detected. $kckcount(form)"
  414.  
  415. set capsp(wmsg) "Warning: You've triggered caps flood protection, release your caps."
  416.  
  417. ## Edit the following only if you choose a punish method above 5 (oper commands):
  418.  
  419. set capsp(ktype) 2
  420.  
  421. set capsp(klmsg) "Caps flooding is not permissable on this network."
  422.  
  423. set capsp(ktime) 0
  424.  
  425. #
  426. ## 6 ## Text repeating.
  427. #
  428.  
  429. lappend ap:udefs {ap:repeatl "3:10 60 k:kb 2"}
  430.  
  431. ## Text repeating Kick on how many consecutive repeated letters?
  432. ## Example: if this is set to 5 then the bot will kick any user who types (example):
  433. # Hellooooo (5 consecutive o's)
  434. # Hello!!!!!!!!! (5 and more consecutive ! marks)
  435. ## Use .chanset #channel ap:repeatc <number-of-letters> <btime> <pmeth> <btype> (in DCC, 0 to disable)
  436. # Set default value here:
  437. lappend ap:udefs {ap:repeatc "25 30 w:k:kb 2"}
  438.  
  439. set repeatf(kmsg) "Text repeating detected. $kckcount(form)"
  440.  
  441. set repeatf(lkmsg) "Letter repeats detected, do not use excess consecutive letters. $kckcount(form)"
  442.  
  443. set repeatf(wmsg) "Warning: You've triggered %type repeating protection, stop repeating."
  444.  
  445. ## Edit the following only if you choose a punish method above 5 (oper commands):
  446.  
  447. set repeatf(ktype) 2
  448.  
  449. set repeatf(klmsg) "Constant repeating is not permissable on this network."
  450.  
  451. set repeatf(ktime) 0
  452.  
  453. #
  454. ## 7 ## Control codes.
  455. #
  456.  
  457. # Use .chanset #channel ap:codes r:<n> b:<n> u:<n> c:<n> <btime> <pmeth> <btype> (in DCC)
  458. # Example: If you set ap:codes to: r:35 b:35 u:35 c:35
  459. # Then 35 (or more) characters affected by Reverse or Bold or Underline or Color
  460. # will be considered an offence.
  461. # Set default rate here:
  462. lappend ap:udefs {ap:codes "r:35 b:80 u:80 c:80 90 kb 2"}
  463.  
  464. set codesf(kmsg) "Excess codes detected. $kckcount(form)"
  465.  
  466. set codesf(wmsg) "Warning: You've triggered control codes protection, release your msgs from codes."
  467.  
  468. ## Edit the following only if you choose a punish method above 5 (oper commands):
  469.  
  470. set codesf(ktype) 2
  471.  
  472. set codesf(klmsg) "Excess use of control codes is not permissable on this network."
  473.  
  474. set codesf(ktime) 0
  475.  
  476. #
  477. ## 8 ## Advertising.
  478. #
  479.  
  480. # NOTE: This protection also works for private advertising.
  481.  
  482. # Use .chanset #channel ap:adv + <btime> <pmeth> <btype> (to enable)
  483. # set default value here: (+ enabled, - disabled)
  484. lappend ap:udefs {ap:adv "-"}
  485.  
  486. # Set here the string you want to exempt (don't consider as spam):
  487. # Note: %chan = current channel. Also, you can change these for every channel via DCC
  488. # using the .ap:add command. (no wildcards used)
  489. set adexempts(global) { %chan www.egghelp.org }
  490.  
  491. set adwords(global) { "*join *" "*plz visit*" }
  492.  
  493. set adv(kmsg) "Advertising detected. $kckcount(form)"
  494.  
  495. set adv(wmsg) "Warning: You've triggered adverting protection, advertisements are not allowed."
  496.  
  497. # ANTI SPAM BOT: (NOTE: Some networks may not allow such bots.)
  498.  
  499. # Use: .chanset #channel ap:antispam + <greet> <cycle-time> <idle-time> (to enable)
  500. # the antispam bot will not cycle a channel where last join occured in <idle-time> or more minutes.
  501. # <greet> is either + or - which will enable or disable the on-join message.
  502. # set default value here:
  503. lappend ap:udefs {ap:antispam "- + 10 10"}
  504.  
  505. # AntiSpamBot basic settings
  506. # You can edit all these settings as you wish
  507. # example: set antispam(nick) AntiSpamBot
  508. set antispam(nick) $altnick
  509. set antispam(altnick) ${altnick}1
  510. # Antispam ident & real name
  511. set antispam(user) AP
  512. set antispam(realname) "AllProtection Anti-Spam"
  513. # example: set antispam(ip) 127.0.0.1
  514. #set antispam(ip) ${my-ip}
  515. # example: set antispam(host) my.lame.vhost.net
  516. #set antispam(host) ${my-hostname}
  517.  
  518. # Ban spammer in all channels or only in channels it's in? (0: It's in, 1: All)
  519. set antispam(banall) 1
  520.  
  521. # Exempt list from greets:
  522. set greetexempts(global) { *example*!*@* *!*example*@*.example.net }
  523.  
  524. # If you want your bot to reply to users with random message, set messages here:
  525. set antispam(r) {
  526.  
  527. }
  528.  
  529. # On what messages do you want the bot to reply:
  530. set antispam(t) {
  531.  
  532. }
  533.  
  534. # Do you want the bot to msg users on join? (leave "" if no)
  535. set antispam(greet) "Hello %nick, checking for spam. Please do not reply..."
  536.  
  537. # Stop greeting after how many joins in secs:
  538. set antispam(jprot) 4:2
  539.  
  540. # Stop replying to messages after how many msgs in secs:
  541. set antispam(mprot) 8:4
  542.  
  543. ## Edit the following only if you choose a punish method above 5 (oper commands):
  544.  
  545. set adv(ktype) 2
  546.  
  547. set adv(klmsg) "Constant advertising is not permissable on this network."
  548.  
  549. set adv(ktime) 0
  550.  
  551. #
  552. ## 9 ## Swearing.
  553. #
  554.  
  555. lappend ap:udefs {ap:swear "-"}
  556.  
  557. set bwords(global) {
  558.  
  559. }
  560.  
  561. set swear(kmsg) "Bad word detected. $kckcount(form)"
  562.  
  563. set swear(wmsg) "Warning: You've triggered swearing protection, cussing is prohibited."
  564.  
  565. ## Edit the following only if you choose a punish method above 5 (oper commands):
  566.  
  567. set swear(ktype) 2
  568.  
  569. set swear(klmsg) "Swearing is not permissable on this network."
  570.  
  571. set swear(ktime) 0
  572.  
  573. #
  574. ## 8-9 ## Swearing/Advertising in part/quit messages
  575. #
  576. # Exampl: "s:1 a:1" Enables banning of users with part/quit msgs containing swear/advertisement
  577. lappend ap:udefs {ap:pqsadv "s:0:0"}
  578.  
  579. ###################
  580. # CTCP #
  581. ###################
  582.  
  583. #
  584. ## 10 ## CTCP/CTCR flood
  585. #
  586.  
  587. lappend ap:udefs {ap:ctcps "2:30 180 kb 2"}
  588.  
  589. set ctcpf(kmsg) "CTCP flood detected. $kckcount(form)"
  590.  
  591. set ctcpf(wmsg) "Warning: You've triggered CTCP/CTCR flood protection, decrease your ctcps."
  592.  
  593. ## Edit the following only if you choose a punish method above 5 (oper commands):
  594.  
  595. set ctcpf(ktype) 2
  596.  
  597. set ctcpf(klmsg) "CTCP/CTCR floods are not permissable on this network."
  598.  
  599. set ctcpf(ktime) 0
  600.  
  601. ###################
  602. # TAKEOVER #
  603. ###################
  604.  
  605. #
  606. ## 11 ## Mass deop.
  607. #
  608.  
  609. lappend ap:udefs {ap:massd "-"}
  610.  
  611. # Mass deop: deop abuser ? (0: no , 1: yes)
  612. set massdeop(deop) 0
  613.  
  614. set massdeop(kmsg) "Mass deop detected. $kckcount(form)"
  615.  
  616. set massdeop(wmsg) "Warning: You've triggered the mass deop protection, do not repeat this action."
  617.  
  618. ## Edit the following only if you choose a punish method above 5 (oper commands):
  619.  
  620. set massdeop(ktype) 2
  621.  
  622. set massdeop(klmsg) "Mass deops are not allowed on this network."
  623.  
  624. set massdeop(ktime) 0
  625.  
  626. #
  627. ## 12 ## Mass kick.
  628. #
  629.  
  630. lappend ap:udefs {ap:massk "-"}
  631.  
  632. # Mass kick: deop abuser ? (0: no , 1: yes)
  633. set masskick(deop) 1
  634.  
  635. set masskick(kmsg) "Mass kick detected. $kckcount(form)"
  636.  
  637. set masskick(wmsg) "Warning: You've triggered mass kick protection, do not repeat this action."
  638.  
  639. ## Edit the following only if you choose a punish method above 5 (oper commands):
  640.  
  641. set masskick(ktype) 2
  642.  
  643. set masskick(klmsg) "Mass kicks are prohibited on this network."
  644.  
  645. set masskick(ktime) 0
  646.  
  647. #
  648. ## 13 ## Mass ban (bans).
  649. #
  650.  
  651. lappend ap:udefs {ap:massb "-"}
  652.  
  653. # Mass ban (bans) deop abuser ? (1: yes , 0: no)
  654. set massb(deop) 1
  655.  
  656. set massb(kmsg) "Mass ban is not allowed. $kckcount(form)"
  657.  
  658. set massb(wmsg) "Warning: You've triggered mass ban protection, do not repeat this action."
  659.  
  660. ## Edit the following only if you choose a punish method above 5 (oper commands):
  661.  
  662. set massb(ktype) 2
  663.  
  664. set massb(klmsg) "Mass banning (bans) is prohibited on this network."
  665.  
  666. set massb(ktime) 0
  667.  
  668. #
  669. ## 14 ## Channel limit.
  670. #
  671.  
  672. # Use .chanset #channel ap:limit <limit> (in DCC, 0 to disable)
  673. # Note: this be the number that will be added to the channel's limit.
  674. # Set default limit here:
  675. lappend ap:udefs {ap:limit 0}
  676.  
  677. ###################
  678. # MISCELLANEOUS #
  679. ###################
  680.  
  681. #
  682. ## 15 ## Join flood.
  683. #
  684.  
  685. lappend ap:udefs {ap:cjoin "4:2 120 kb 2"}
  686.  
  687. # Join flood: Check for join flood from same idents as well? (0: no, 1: yes)
  688. set joinflood(checkident) 1
  689.  
  690. # Join flood: Lock channel when triggered ? (1: yes , 0: no)
  691. set joinflood(lockchan) 1
  692.  
  693. # Join flood: If lock channel is enable, what modes ?
  694. set joinflood(lockmode) "MR-k clone.join.flood"
  695.  
  696. # Join flood: lock time in seconds.
  697. set joinflood(locktime) 45
  698.  
  699. set joinflood(kmsg) "Join flood detected. $kckcount(form)"
  700.  
  701. set joinflood(wmsg) "Warning: you've triggered join flood protection, further offence will cause harsher actions."
  702.  
  703. ## Edit the following only if you choose a punish method above 5 (oper commands):
  704.  
  705. set joinflood(ktype) 2
  706.  
  707. set joinflood(klmsg) "Join floods are not permissable on this network."
  708.  
  709. set joinflood(ktime) 0
  710.  
  711. #
  712. ## 16 ## Part msg flood.
  713. #
  714.  
  715. # Use .chanset #channel ap:partmsgs <message-length> <btime> <pmeth> <btype> (in DCC, 0 to disable)
  716. # Set default value here:
  717. lappend ap:udefs {ap:partmsgs "0"}
  718.  
  719. # Also, you can ban if excess codes are used in a part msg:
  720. # Use .chanset #channel ap:partmsgc r:<n> b:<n> u:<n> c:<n> <btime> <pmeth> <btype> (in DCC)
  721. # Note: check codes protection to understand how codes checking work.
  722. # r = reverse, b = bold, u = underline and c = colors.
  723. # Set default rate here:
  724. lappend ap:udefs {ap:partmsgc "0"}
  725.  
  726. set pmsgf(kmsg) "Part msg flood detected. $kckcount(form)"
  727.  
  728. set pmsgf(wmsg) "Warning: You've triggered part msg flood protection, decrease text in your part reason."
  729.  
  730. ## Edit the following only if you choose a punish method above 5 (oper commands):
  731.  
  732. set pmsgf(ktype) 2
  733.  
  734. set pmsgf(klmsg) "Part msg floods are not permissable on this network."
  735.  
  736. set pmsgf(ktime) 0
  737.  
  738. #
  739. ## 17 ## Revolving door.
  740. #
  741.  
  742. # Use .chanset #channel ap:revdoor <seconds> <btime> <pmeth> <btype> (in DCC)
  743. # example: setting this to 3 will make the bot ban whoever joins and parts/quits in 3 or less seconds.
  744. # Set default value here:
  745. lappend ap:udefs {ap:revdoor "3 120 kb 2"}
  746.  
  747. set revdoor(kmsg) "Join-part revolving door attempt detected. $kckcount(form)"
  748.  
  749. # Part messages that should not be considered as revdoor: (can use wildcards)
  750. # Example: set revdoor(exempt) {"Registered."}
  751. set revdoor(exempt) {}
  752.  
  753. set revdoor(wmsg) "Warning! you have triggered revolving-door protection, do not join-part channels."
  754.  
  755. ## Edit the following only if you choose a punish method above 5 (oper commands):
  756.  
  757. set revdoor(ktype) 2
  758.  
  759. set revdoor(klmsg) "Revolving-door bots are not allowed on this network."
  760.  
  761. set revdoor(ktime) 0
  762.  
  763. #
  764. ## 18 ## Nick flood.
  765. #
  766.  
  767. lappend ap:udefs {ap:nickf "4:12 60 w:k:kb 2"}
  768.  
  769. set nickflood(kmsg) "Nick flood detected. $kckcount(form)"
  770.  
  771. set nickflood(wmsg) "Warning: You've triggered nick flood protection, slow down your nick changes."
  772.  
  773. ## Edit the following only if you choose a punish method above 5 (oper commands):
  774.  
  775. set nickflood(ktype) 2
  776.  
  777. set nickflood(klmsg) "Nick floods are not permissable on this network."
  778.  
  779. set nickflood(ktime) 0
  780.  
  781. #
  782. ## 19 ## Clones.
  783. #
  784.  
  785. # Use .chanset #channel ap:clones <clones-number> <btime> <pmeth> <btype> (in DCC)
  786. # Note: This will be the number of clones that triggers punishment.
  787. # Set default value here:
  788. lappend ap:udefs {ap:clones "8 120 kb 2"}
  789.  
  790. set eclones(kmsg) "Excess clones detected. $kckcount(form)"
  791.  
  792. set eclones(wmsg) "Warning: You've exceeded the maximum number of clones, remove your clones now."
  793.  
  794. # Do you want to check if the clones are still excess after warn?
  795. # if yes then set this to the number of seconds to wait before checking again. (0 means no)
  796. # NOTE: This should be less than <pwait> (at the beginning of the configuration).
  797. set eclones(caw) 60
  798.  
  799. ## Edit the following only if you choose a punish method above 5 (oper commands):
  800.  
  801. set eclones(ktype) 2
  802.  
  803. set eclones(klmsg) "Excess clones are not allowed on this network."
  804.  
  805. set eclones(ktime) 0
  806.  
  807. #
  808. ## 20 ## Bad nick.
  809. #
  810.  
  811. # Use .chanset #channel ap:bnicks + <btime> <pmeth> <btype> (in DCC to enable)
  812. # Set default value here: (+ enabled, - disabled)
  813. lappend ap:udefs {ap:bnicks "-"}
  814.  
  815. set bnicks(global) {
  816.  
  817. }
  818.  
  819. set bnick(kmsg) "Unwanted person's nickname detected. $kckcount(form)"
  820.  
  821. set bnick(wmsg) "Warning! you are using a bad nick, type /nick <nick> to change it."
  822.  
  823. set bnick(caw) 60
  824.  
  825. ## Edit the following only if you choose a punish method above 5 (oper commands):
  826.  
  827. set bnick(ktype) 2
  828.  
  829. set bnick(klmsg) "Bad nicks are not allowed on this network."
  830.  
  831. set bnick(ktime) 0
  832.  
  833. #
  834. ## 21 ## Random drones.
  835. #
  836.  
  837. # Use .chanset #channel ap:drones + <btime> <pmeth> <btype> (in DCC to enable)
  838. # Set default value here: (+ enabled, - disabled)
  839. # If you set <pmeth> to a positive-integer then the bot will only kick the drone once.
  840. # So if the drone rejoins within this amount of seconds it won't be kicked again.
  841. lappend ap:udefs {ap:drones "-"}
  842.  
  843. # Random drones: What masks to exempt? (remember to change these or remoce them)
  844. set droneexempts(global) { *example1*!*@* *!*example2*@* *!*@example3.net }
  845.  
  846. set drone(kmsg) "Possible random drone detected. $kckcount(form)"
  847.  
  848. set drone(wmsg) "Warning: You've triggered random drones protection, change your nick now."
  849.  
  850. ## Edit the following only if you choose a punish method above 5 (oper commands):
  851.  
  852. set drone(ktype) 2
  853.  
  854. set drone(klmsg) "Random drones are not allowed on this network."
  855.  
  856. set drone(ktime) 0
  857.  
  858. #
  859. ## 22 ## Bad ident.
  860. #
  861.  
  862. # Use .chanset #channel ap:bidents + <btime> <pmeth> <btype> (in DCC to enable)
  863. # Set default value here: (+ enabled, - disabled)
  864. lappend ap:udefs {ap:bidents "-"}
  865.  
  866. set bidents(global) {
  867.  
  868. }
  869.  
  870. set bident(kmsg) "Bad ident detected. $kckcount(form)"
  871.  
  872. set bident(wmsg) "Warning! you're using a bad ident. Disconnect, change it and then connect again."
  873.  
  874. set bident(caw) 60
  875.  
  876. ## Edit the following only if you choose a punish method above 5 (oper commands):
  877.  
  878. set bident(ktype) 2
  879.  
  880. set bident(klmsg) "Bad idents are not allowed on this network."
  881.  
  882. set bident(ktime) 0
  883.  
  884. #
  885. ## 23 ## Bad chans/Excess chans.
  886. #
  887.  
  888. # Use .chanset #channel ap:bchans + <btime> <pmeth> <btype> <scan-time> (in DCC to enable)
  889. # <scan-time> is the time in minutes in which the bot will scan the channel for users in bad chans. (0 disable)
  890. # Set default value here: (+ enabled, - disabled)
  891. lappend ap:udefs {ap:bchans "+ 60 w:kb 2 0"}
  892.  
  893. # For excess channels use:
  894. # .chanset #channel ap:echans <excess-chan-number> <btime> <pmeth> <btype> <scan-time> (in DCC to enable)
  895. # if <excess-chan-number> is 0, then it is disabled.
  896. lappend ap:udefs {ap:echans "0 60 w:kb 2 0"}
  897.  
  898. # Set default global badchan list here:
  899. set bchans(global) { #butteryfly #jackinchat }
  900.  
  901. # Bad chans flood protect, stop whois/ctcp incase of x joins in y seconds: (applies on bad versions too)
  902. set bchan(floodprot) 4:10
  903.  
  904. # Bad chans kick message:
  905. set bchan(kmsg) "Bad chan detected. $kckcount(form)"
  906.  
  907. # Excess chans kick message:
  908. set bchan(ekmsg) "Excess chans detected. $kckcount(form)"
  909.  
  910. # Bad/Excess chans check after warning time in seconds.
  911. # Incase you chose to warn the offender (punish method), this is the time in seconds to wait
  912. # before checking again. (keep it 0 if you're not using warn)
  913. # Setting this to 50 or less will be useless, also make sure this is less than pwait.
  914. set bchan(caw) 60
  915.  
  916. # Bad chans warning message:
  917. 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."
  918.  
  919. # Excess chans warning message:
  920. set bchan(ewmsg) "Warning: You're on excess chans (%echan), maximum allowed is %max. You have $bchan(caw) seconds to leave excess chans."
  921.  
  922. ## Edit the following only if you choose a punish method above 5 (oper commands):
  923.  
  924. set bchan(ktype) 2
  925.  
  926. set bchan(klmsg) "Joining bad channels is prohibited on this network."
  927.  
  928. set bchan(ktime) 0
  929.  
  930. #
  931. ## 24 ## Bad CTCP reply
  932. #
  933.  
  934. # Use .chanset #channel ap:bctcrs + <btime> <pmeth> <btype> <scan-time> (in DCC to enable)
  935. # Set default value here: (+ enabled, - disabled)
  936. lappend ap:udefs {ap:bctcrs "- 120 kb 2 0"}
  937.  
  938. # Use .chanset #channel ap:ctcpchecks <ctcp-types>
  939. # Set default CTCP replies to check for: (example: "VERSION TIME FINGER")
  940. lappend ap:udefs {ap:ctcpchecks "VERSION"}
  941.  
  942. set bctcrs(global) {
  943. "*exploitation script*"
  944. }
  945.  
  946. # %rtype is the CTCP reply type.
  947. set bctcr(kmsg) "Bad %rtype reply detected. $kckcount(form)"
  948.  
  949. # Bad version check after warning time in seconds.
  950. # Same as check for bad/excess chans.
  951. set bctcr(caw) 60
  952.  
  953. 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."
  954.  
  955. ## Edit the following only if you choose a punish method above 5 (oper commands):
  956.  
  957. set bctcr(ktype) 2
  958.  
  959. set bctcr(klmsg) "Using bad scripts is prohibited on this network."
  960.  
  961. set bctcr(ktime) 0
  962.  
  963. #########################################
  964. # BOTNET FLOOD PROTECTION (MASS FLOODS) #
  965. #########################################
  966.  
  967. #
  968. ## 1 ## Botnet Text flood (lines).
  969. #
  970.  
  971. # Use .chanset #channel ap:btextl <lines>:<seconds> <lockmode> <locktime> (in DCC, 0:0 to disable)
  972. # Set default rate here:
  973. lappend ap:udefs {ap:btextl "15:7 M-k lines.flood 60"}
  974.  
  975. #
  976. ## 2 ## Botnet Text flood (chars).
  977. #
  978.  
  979. lappend ap:udefs {ap:btextc "550:3 M-k chars.flood 60"}
  980.  
  981. #
  982. ## 3 ## Botnet Notice flood (lines).
  983. #
  984.  
  985. lappend ap:udefs {ap:bnotcl "4:2 M-k lines.flood 60"}
  986.  
  987. #
  988. ## 4 ## Botnet Notice flood (chars).
  989. #
  990.  
  991. lappend ap:udefs {ap:bnotcc "500:3 M-k chars.flood 60"}
  992.  
  993. #
  994. ## 5 ## Botnet CTCP/CTCR flood.
  995. #
  996.  
  997. lappend ap:udefs {ap:bctcp "4:60 M-k ctcp.flood 60"}
  998.  
  999. #
  1000. ## 6 ## Botnet join flood.
  1001. #
  1002.  
  1003. lappend ap:udefs {ap:massjoin "9:3 MR-k join.flood 60"}
  1004.  
  1005. #
  1006. ## 7 ## Botnet revolving door flood.
  1007. #
  1008.  
  1009. ## Note: ap:revdoor must be set for this to work.
  1010.  
  1011. lappend ap:udefs {ap:brevdoor "5:3 MR-k revdoor.flood 60"}
  1012.  
  1013. #
  1014. ## 8 ## Botnet part msg flood.
  1015. #
  1016.  
  1017. ## Note: ap:partmsgs or ap:partmsgc (or both) must be enabled for this to work.
  1018.  
  1019. lappend ap:udefs {ap:bpartmsg "5:3 MR-k partmsg.flood 60"}
  1020.  
  1021. #
  1022. ## 9 ## Botnet Nick flood.
  1023. #
  1024.  
  1025. lappend ap:udefs {ap:bnickf "5:30 M-k nick.flood 60"}
  1026.  
  1027. #
  1028. ## 10 ## Botnet Codes flood.
  1029. #
  1030.  
  1031. lappend ap:udefs {ap:bcodes "25:3 cM-k codes.flood 60"}
  1032.  
  1033. ###########################
  1034. # PRIVATE PROTECTIONS #
  1035. ###########################
  1036.  
  1037. # Set here if you want the bot to set a restriction mode on itself when flooded.
  1038. # example: +R is used on DALnet so only registered users can send to the bot.
  1039. # set this to "" if you don't wish to change your bot's modes during a flood.
  1040. # NOTE: Maximum 1 mode, less or more means it's disabled.
  1041. set apfp(rmode) RC
  1042.  
  1043. # Set here the time you want to keep the restriction mode in seconds.
  1044. set apfp(rtime) 30
  1045.  
  1046. # How many seconds do you want to stop answering data from server?
  1047. set apfp(itime) 45
  1048.  
  1049. #
  1050. ## 1 ## Private text floods.
  1051. #
  1052.  
  1053. # Private text (lines) flood <lines>:<seconds>. (0:0 to disable)
  1054. set ptextl(punish) 12:6
  1055.  
  1056. # Private text (chars) flood <chars>:<seconds>. (0:0 to disable)
  1057. set ptextc(punish) 750:6
  1058.  
  1059. #
  1060. ## 2 ## Private notice floods.
  1061. #
  1062.  
  1063. set pnotil(punish) 6:3
  1064.  
  1065. set pnotic(punish) 600:4
  1066.  
  1067. #
  1068. ## 3 ## Private CTCP/CTCR flood.
  1069. #
  1070.  
  1071. set pctcpf(punish) 4:20
  1072.  
  1073. # Configurations end here. #
  1074. ############################
  1075. #
  1076. ######################################################################
  1077. # Code starts here, please do not edit anything unless you know TCL: #
  1078. # __________________________________________________________________ #
  1079.  
  1080. proc istimer {arg {t timers}} {
  1081. set a ""
  1082. foreach rt [$t] {
  1083. if {[string equal -nocase $arg [lindex $rt 1]]} {
  1084. set a [lindex $rt 2] ; break
  1085. }
  1086. }
  1087. set a
  1088. }
  1089.  
  1090. if {![info exists NumKicks]} {
  1091. if {![file exists $kckcount(file)]} {set NumKicks 0} {
  1092. set NumKicks [read -nonewline [set kcfop [open $kckcount(file)]]][close $kcfop][unset kcfop]
  1093. if {![string is integer -strict $NumKicks]} {set NumKicks 0}
  1094. }
  1095. }
  1096.  
  1097. variable bred 0
  1098. variable sfluds 0
  1099. foreach apudef ${ap:udefs} {
  1100. if {[lindex $apudef 0] == "ap:level" && !$banthruX(do)} {continue}
  1101. setudef str [lindex $apudef 0]
  1102. }
  1103. unset apudef
  1104.  
  1105. proc load {{b bind}} {
  1106. if {$b == "loaded"} { set b bind }
  1107. set nsc [namespace current]
  1108. foreach joinb {cjoin massjoin bchans bctcrs drones bnicks bidents clones} {
  1109. $b join - * "${nsc}::joins $joinb"
  1110. }
  1111. foreach pubmb {textl textc btextl btextc bcodes adv swear repeatl codes caps} {
  1112. $b pubm - * "${nsc}::pubms $pubmb"
  1113. }
  1114. foreach notcb {notcl notcc bnotcl bnotcc bcodes adv swear codes} {
  1115. $b notc - * "${nsc}::notc $notcb"
  1116. }
  1117. foreach ctcpb {textl textc btextl btextc bcodes adv swear repeatl codes caps} {
  1118. $b ctcp - ACTION "${nsc}::ctcps $ctcpb"
  1119. }
  1120. foreach {modem modeb} {"* -b" rembs "* +b" massb "* -o" massd "* +o" cbcd} {
  1121. $b mode - $modem "${nsc}::modes $modeb"
  1122. }
  1123. foreach partb {revdoor partmsgs adv swear} {
  1124. $b part - * "${nsc}::parts $partb"
  1125. }
  1126. foreach signb {revdoor adv swear} {
  1127. $b sign - * "${nsc}::parts $signb"
  1128. }
  1129. $b ctcp - * "${nsc}::ctcps ctcps"
  1130. $b ctcp - * "${nsc}::ctcps bctcp"
  1131. $b nick - * "${nsc}::joins bnicks"
  1132. $b nick - * "${nsc}::nicks nickf"
  1133. $b nick - * "${nsc}::nicks bnickf"
  1134. $b ctcr - * ${nsc}::bctcrs
  1135. $b ctcr - * ${nsc}::ctcr
  1136. $b kick - * ${nsc}::massk
  1137. $b raw - 319 ${nsc}::bchansgw
  1138. $b msgm - * "${nsc}::ptext f"
  1139. $b msgm - * "${nsc}::ptext adv"
  1140. $b ctcp - ACTION "${nsc}::pctcp text"
  1141. $b ctcp - * "${nsc}::pctcp ctcp"
  1142. $b notc - * ${nsc}::pnotc
  1143. $b ctcr - * ${nsc}::pctcr
  1144. $b flud - * ${nsc}::pflud
  1145. $b time - * ${nsc}::core
  1146. $b time - * ${nsc}::antispamcore
  1147. $b evnt - prerehash ${nsc}::unload
  1148. $b evnt - prerestart ${nsc}::unload
  1149. foreach apdccb {import reset disable add rem list monitor priv} {
  1150. $b dcc n|n ap:$apdccb "${nsc}::cmd $apdccb"
  1151. }
  1152. if {$b == "bind"} {
  1153. rd; variable logkbs
  1154. foreach c [channels] { init $c }
  1155. if {![info exists logkbs(logs)] && $logkbs(do)} {
  1156. lappend logkbs(logs) "\$Log started [ctime [unixtime]]\$"
  1157. if {[file exists $logkbs(file)]} {
  1158. append logkbs(logs) " [lrange [split [read [set f [open $logkbs(file)]]] \n][close $f] 1 end]"
  1159. }
  1160. }
  1161. checkscans
  1162. if {[lsearch -glob [binds loaded] "* ${nsc}::load"] != -1} {
  1163. unbind evnt - loaded ${nsc}::load
  1164. }
  1165. upvar #0 [ezilamn noisrev-pctc] cvar
  1166. if {![string match "* [ezilamn "noitcetorP lennahC"] *" $cvar]} {
  1167. set cvar "$cvar [ezilamn "noitcetorP lennahC -"]"
  1168. }
  1169. putlog "Chan Protection v2"
  1170. }
  1171. }
  1172.  
  1173. proc joins {flood nick uhost hand chan {nn ""}} {
  1174. if {[isbotnick $nick]} {init $chan ; return 0}
  1175. if {[set chan [string tolower $chan]] == "*" || [invalid:apc $nick $hand $chan]} {return 0}
  1176. if {$flood != "bchans" && ![vcg $chan ap:$flood]} {return 0}
  1177. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1178. switch -- $flood {
  1179. "cjoin" {
  1180. variable joinflood; variable apjoinfn
  1181. foreach {j s} [cgsplit $off] {break}
  1182. if {[invalid:apf $j $s]} {return 0}
  1183. Nfollow $s apjoinfn([set h jnf:[string tolower [set f [lindex [split $uhost @] 1]]:$chan]]) $nick $uhost
  1184. if {$joinflood(checkident)} {
  1185. Nfollow $s apjoinfn([set hi jif:[string tolower [lindex [split $uhost @] 0]:$chan]]) $nick $uhost
  1186. }
  1187. if {[set ts [follow $s $h $j 1 1]] != -1 || ($joinflood(checkident) && [set ts2 [follow $s $hi $j 1 1]] != -1)} {
  1188. if {[info exists ts2]} { set f [lindex [split $uhost @] 0]; set ts $ts2 ; set h $hi }
  1189. if {$joinflood(lockchan)} {lockc $chan $joinflood(lockmode) $joinflood(locktime) "Join flood from $f"}
  1190. 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
  1191. }
  1192. }
  1193. "massjoin" {
  1194. foreach {o s} [cgsplit $off] {break}
  1195. if {[invalid:apf $o $s] || [isbotnick $nick]} {return 0}
  1196. checklc $s mjf:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] join
  1197. }
  1198. "bnicks" {
  1199. variable bnick; variable bnicks
  1200. if {$nn == ""} { set nn $nick }
  1201. if {[string first # $chan] != 0 || [invalid:apc $nn $hand $chan]} {return 0}
  1202. if {$off != "+"} {return 0}
  1203. if {![info exists bnicks($chan)]} { set l $bnicks(global) } { set l $bnicks($chan) }
  1204. set isbn 0
  1205. foreach bn $l { if {[string match -nocase $bn $nn]} {set isbn 1; break} }
  1206. if {$isbn} {
  1207. if {$bnick(caw) > 0 && [string match -nocase *w* $pmeth]} {
  1208. set bnick([set ch $chan:[string tolower $uhost]]) 1
  1209. if {[istimer "[namespace current]::followrem bnick($ch)" utimers]==""} {
  1210. utimer [expr {$bnick(caw) + 1}] [list [namespace current]::followrem bnick($ch)]
  1211. }
  1212. }
  1213. punish $pmeth [list $nn $uhost] $chan [mapr $bnick(kmsg) $bn] $bnick(wmsg) $btype $btime $bnick(klmsg) $bnick(ktime) $bnick(ktype) [string tolower $uhost]:bnick
  1214. }
  1215. }
  1216. "drones" {
  1217. variable droneexempts
  1218. if {$off != "+"} {return 0}
  1219. set Nod 0
  1220. if {[info exists droneexempts([set chan [string tolower $chan]])]} { set l $droneexempts($chan) } { set l $droneexempts(global) }
  1221. foreach e $l { if {[string match -nocase $e $nick!$uhost]} {set Nod 1 ; break} }
  1222. if {$Nod} {return 0}
  1223. set id [string trimleft [lindex [split $uhost @] 0] ~]
  1224. if {[follow 2 dr:$chan 3] != -1} {return 0}
  1225. if {[regexp {^[a-z]{4,}![a-z]{4,}$} $nick!$id]} {
  1226. 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])} {
  1227. if {![info exists dronm]} { set dronm "no vowels" }
  1228. droneb $nick $uhost $chan $btime $pmeth $btype *$dronm*
  1229. } elseif {![string match *$id* $nick] && [regexp {q[bcdfghknpqrstwzxv]|x[dfghkmnqrvz]|z[bcdfhmqrtvx]|v[bfghkmnqxw]|g[zv]|kz|bgb|wj|lx|jwm} $nick dronm]} {
  1230. droneb $nick $uhost $chan $btime $pmeth $btype *$dronm*
  1231. }
  1232. }
  1233. }
  1234. "bidents" {
  1235. variable bident; variable bidents
  1236. if {[invalid:apc $nick $hand $chan]} {return 0}
  1237. if {$off != "+"} {return 0}
  1238. scan $uhost {%[^@]} ident
  1239. if {![info exists bidents($chan)]} { set l $bidents(global) } { set l $bidents($chan) }
  1240. set isbi 0
  1241. foreach bi $l { if {[string match -nocase $bi $ident]} {set isbi 1; break} }
  1242. if {$isbi} {
  1243. if {$bident(caw) > 0 && [string match -nocase *w* $pmeth]} {
  1244. set bident([set ch $chan:[string tolower $uhost]]) 1
  1245. if {[istimer "[namespace current]::followrem bident($ch)" utimers]==""} {
  1246. utimer [expr {$bident(caw) + 1}] [list [namespace current]::followrem bident($ch)]
  1247. }
  1248. }
  1249. punish $pmeth [list $nick $uhost] $chan [mapr $bident(kmsg) $bi] $bident(wmsg) $btype $btime $bident(klmsg) $bident(ktime) $bident(ktype) [string tolower $uhost]:bident
  1250. }
  1251. }
  1252. "clones" {
  1253. variable eclones
  1254. if {![string is integer $off] || $off <= 0} {return 0}
  1255. set c 0
  1256. foreach ccheck [chanlist $chan] {
  1257. if {[string equal -nocase [scan $uhost {%*[^@]@%s}] [scan [set chost [getchanhost $ccheck $chan]] {%*[^@]@%s}]]} {
  1258. incr c ; lappend cn $ccheck ; lappend cn $chost
  1259. }
  1260. }
  1261. if {$c >= $off} {
  1262. if {$eclones(caw) > 0 && [string match -nocase *w* $pmeth]} {
  1263. set eclones([set ch $chan:[string tolower [lindex [split $uhost @] 1]]]) 1
  1264. if {[istimer "[namespace current]::followrem eclones($ch)" utimers]==""} {
  1265. utimer [expr {$eclones(caw) + 1}] [list [namespace current]::followrem eclones($ch)]
  1266. }
  1267. }
  1268. 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
  1269. }
  1270. }
  1271. "bchans" {
  1272. if {[vcg $chan ap:bchans] || [vcg $chan ap:echans]} {
  1273. set off1 [lindex [split [channel get $chan ap:echans]] 0]
  1274. if {![string is integer -strict $off1]} {set off1 0}
  1275. if {$off == "+" || $off1 > 0} {
  1276. bchansw $nick $uhost $hand $chan 0
  1277. }
  1278. }
  1279. }
  1280. "bctcrs" {
  1281. if {$off == "+"} { bchansw $nick $uhost $hand $chan 1 }
  1282. }
  1283. }
  1284. }
  1285.  
  1286. proc pubms {flood nick uhost hand chan arg} {
  1287. if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
  1288. if {![vcg $chan ap:$flood]} {return 0}
  1289. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1290. switch -- $flood {
  1291. "textl" - "textc" {
  1292. foreach {o s} [cgsplit $off] {break}
  1293. seqflood $flood $o $s $nick $uhost $chan $pmeth $btype $btime [string length $arg]
  1294. }
  1295. "btextl" - "btextc" {
  1296. foreach {o s} [cgsplit $off] {break}
  1297. if {[invalid:apf $o $s]} {return 0}
  1298. 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]}]
  1299. }
  1300. "repeatl" {
  1301. variable repeatf
  1302. foreach {o s} [cgsplit $off] {break}
  1303. set arg [cf $arg]
  1304. if {![invalid:apf $o $s]} {
  1305. if {[set ts [follow $s rpt:[md5 [string tolower $uhost:$arg:$chan]] $o]] != -1} {
  1306. set kmsg [mapr $repeatf(kmsg) "$o repeats in $ts secs"]
  1307. set wmsg [string map {%type text} $repeatf(wmsg)] ; set reptype repeatl
  1308. }
  1309. }
  1310. if {![info exists kmsg] && [vcg $chan ap:repeatc]} {
  1311. set cgotc [split [channel get $chan ap:repeatc]]
  1312. if {[string is integer [set i [lindex $cgotc 0]]] && $i > 0} {
  1313. set cl "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&"
  1314. for {set c 0} {$c < [string length $cl]} {incr c} {
  1315. if {[string match -nocase *[string repeat [string index $cl $c] $i]* $arg]} {
  1316. foreach {btime pmeth btype} [lrange $cgotc 1 end] {break}
  1317. set kmsg [mapr $repeatf(lkmsg) "${i}+ consecutive [string index $cl $c]'s"]
  1318. set wmsg [string map {%type letter} $repeatf(wmsg)] ; set reptype repeatc ; break
  1319. }
  1320. }
  1321. }
  1322. }
  1323. if {[info exists kmsg]} {
  1324. punish $pmeth [list $nick $uhost] $chan $kmsg $wmsg $btype $btime $repeatf(klmsg) $repeatf(ktime) $repeatf(ktype) [string tolower $uhost]:$reptype
  1325. }
  1326. }
  1327. "codes" {
  1328. variable codesf
  1329. if {[string is integer [set cc [ccodes $chan $arg ap:codes]]] && $cc > 0} {
  1330. 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
  1331. }
  1332. }
  1333. "bcodes" {
  1334. foreach {o s} [cgsplit $off] {break}
  1335. if {[invalid:apf $o $s]} {return 0}
  1336. 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]
  1337. }
  1338. "adv" {
  1339. if {$off != "+"} {return 0}
  1340. variable adv
  1341. if {[set advword [isspam $arg $chan]] != ""} {
  1342. punish $pmeth [list $nick $uhost] $chan [mapr $adv(kmsg) *$advword*] $adv(wmsg) $btype $btime $adv(klmsg) $adv(ktime) $adv(ktype) [string tolower $uhost]:adv
  1343. }
  1344. }
  1345. "swear" {
  1346. variable swear ; variable bwords
  1347. if {$off != "+"} {return 0}
  1348. set arg [cf $arg]
  1349. if {![info exists bwords($chan)]} { set l $bwords(global) } { set l $bwords($chan) }
  1350. foreach bw $l {
  1351. if {[string match -nocase $bw $arg]} {
  1352. punish $pmeth [list $nick $uhost] $chan [mapr $swear(kmsg) $bw] $swear(wmsg) $btype $btime $swear(klmsg) $swear(ktime) $swear(ktype) [string tolower $uhost]:swear
  1353. break
  1354. }
  1355. }
  1356. }
  1357. "caps" {
  1358. variable capsp
  1359. set linelen [string length [set arg [cf $arg]]]
  1360. foreach {p l} [cgsplit $off] {break}
  1361. if {[invalid:apf $p $l] || $linelen < $l} {return 0}
  1362. if {[set caps [regexp -all {[A-Z]} $arg]] > 0} {
  1363. if {[set pl [expr {$caps * 100 / $linelen}]] >= $p} {
  1364. 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
  1365. }
  1366. }
  1367. }
  1368. }
  1369. }
  1370.  
  1371. proc notc {flood nick uhost hand arg chan} {
  1372. if {[isbotnick [lindex [split $chan @] 0]] || [string first @ $chan] == 0 || ![regexp {.+!.+@.+} $nick!$uhost]} {return 0}
  1373. if {![vcg $chan ap:$flood]} {return 0}
  1374. if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
  1375. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1376. switch -- $flood {
  1377. "notcl" - "notcc" {
  1378. foreach {o s} [cgsplit $off] {break}
  1379. seqflood $flood $o $s $nick $uhost $chan $pmeth $btype $btime [string length $arg]
  1380. }
  1381. "codes" - "bcodes" - "adv" - "swear" {
  1382. pubms $flood $nick $uhost $hand $chan $arg
  1383. }
  1384. "bnotcl" - "bnotcc" {
  1385. foreach {o s} [cgsplit $off] {break}
  1386. if {[invalid:apf $o $s]} {return 0}
  1387. 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]}]
  1388. }
  1389. }
  1390. }
  1391.  
  1392. proc ctcps {flood nick uhost hand chan kw arg} {
  1393. if {[isbotnick [lindex [split $chan @] 0]] || [string equal -nocase chat $kw]} {return 0}
  1394. if {[string equal -nocase action $kw]} {
  1395. pubms $flood $nick $uhost $hand $chan $arg
  1396. } {
  1397. if {![vcg $chan ap:$flood]} {return 0}
  1398. if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
  1399. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1400. switch -- $flood {
  1401. "ctcps" {
  1402. foreach {o s} [cgsplit $off] {break}
  1403. if {[invalid:apf $o $s]} {return 0}
  1404. checkf $s $o ctcpc:[string tolower $uhost:$chan] $uhost $chan $pmeth $nick {$o CTCPs} $btype $btime ctcpf
  1405. }
  1406. "bctcp" {
  1407. foreach {o s} [cgsplit $off] {break}
  1408. if {[invalid:apf $o $s]} {return 0}
  1409. checklc $s bctcpc:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] CTCP
  1410. }
  1411. }
  1412. }
  1413. }
  1414.  
  1415. proc modes {flood nick uhost hand chan mc targ} {
  1416. if {$flood == "cbcd" && [isbotnick $targ] && [follow 5 botoped:$chan 2 1 1] == -1} {
  1417. checkbcd $chan
  1418. } elseif {$flood == "rembs"} {
  1419. if {[set t [istimer "pushmode $chan -b $targ"]]!=""} { killtimer $t }
  1420. } elseif {$flood != "cbcd"} {
  1421. if {[isbotnick $nick] && $flood == "massb"} {
  1422. variable logkbs
  1423. if {$logkbs(do)} { aplog "\[[clock format [clock seconds] -format %T]\] Banned $targ on $chan" }
  1424. }
  1425. if {![vcg $chan ap:$flood] || [isbotnick $nick] || [matchattr $hand fmo|fmo $chan]} {return 0}
  1426. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1427. variable serv
  1428. switch -- $flood {
  1429. "massb" {
  1430. variable massb
  1431. foreach {o s} [cgsplit $off] {break}
  1432. if {$nick == "" || $nick == $targ || [invalid:apf $o $s]} {return 0}
  1433. if {[set ts [follow $s mssb:[string tolower $uhost:$chan] $o]] != -1} {
  1434. if {$massb(deop)} {
  1435. putquick "$serv(nick) :[string map [list %nick $nick %chan $chan] $serv(command)]"
  1436. if {[botisop $chan]} { putquick "MODE $chan -o $nick" }
  1437. }
  1438. 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
  1439. }
  1440. }
  1441. "massd" {
  1442. variable massdeop
  1443. foreach {o s} [cgsplit $off] {break}
  1444. if {$nick == "" || $nick == $targ || [invalid:apf $o $s]} {return 0}
  1445. if {[set ts [follow $s mssd:[string tolower $uhost:$chan] $o]] != -1} {
  1446. if {$massdeop(deop)} {
  1447. putquick "$serv(nick) :[string map [list %chan $chan %nick $nick] $serv(command)]"
  1448. if {[botisop $chan]} { putquick "MODE $chan -o $nick" }
  1449. }
  1450. 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
  1451. }
  1452. }
  1453. }
  1454. }
  1455. }
  1456.  
  1457. proc parts {flood nick uhost hand chan arg} {
  1458. if {[invalid:apc $nick $hand [set chan [string tolower $chan]]]} {return 0}
  1459. if {![vcg $chan ap:$flood]} {return 0}
  1460. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1461. switch -- $flood {
  1462. "revdoor" {
  1463. variable revdoor ; variable banthruX ; variable ::max-bans
  1464. if {![string is integer $off] || $off <= 0} {return 0}
  1465. if {[set gcj [getchanjoin $nick $chan]] >= [set ut [unixtime]]-$off} {
  1466. if {[vcg $chan ap:brevdoor]} {
  1467. foreach {o s} [cgsplit [lindex [set cgot2 [split [channel get $chan ap:brevdoor]]] 0]] {break}
  1468. if {![invalid:apf $o $s]} {
  1469. checklc $s brevdc:$chan $o $chan [join [lrange $cgot2 1 end-1]] [lindex $cgot2 end] "revolving door"
  1470. }
  1471. }
  1472. set rvne 0
  1473. foreach rve $revdoor(exempt) { if {[string match -nocase $rve $arg]} {set rvne 1 ; break} }
  1474. if {$rvne} {return 0}
  1475. 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
  1476. }
  1477. }
  1478. "partmsgs" {
  1479. variable pmsgf
  1480. if {($off > 0 && [set al [string length $arg]] >= $off) || [set cl [ccodes $chan $arg ap:partmsgc]] > 0} {
  1481. if {[vcg $chan ap:bpartmsg]} {
  1482. foreach {o s} [cgsplit [lindex [set cgot2 [split [channel get $chan ap:bpartmsg]]] 0]] {break}
  1483. if {![invalid:apf $o $s]} {
  1484. checklc $s bpmsgc:$chan $o $chan [join [lrange $cgot2 1 end-1]] [lindex $cgot2 end] "part msg"
  1485. }
  1486. }
  1487. if {[info exists cl]} {
  1488. set kmsg [mapr $pmsgf(kmsg) "$cl chars affected by codes"]
  1489. foreach {fo1 fo2 fo3 fo4 btime pmeth btype} [split [channel get $chan ap:partmsgc]] {break}
  1490. } {
  1491. set kmsg [mapr $pmsgf(kmsg) "$al chars"]
  1492. }
  1493. punish $pmeth [list $nick $uhost] $chan $kmsg $pmsgf(wmsg) $btype $btime $pmsgf(klmsg) $pmsgf(ktime) $pmsgf(ktype) [string tolower $uhost]:pmsgf
  1494. }
  1495. }
  1496. "adv" - "swear" {
  1497. if {![vcg $chan ap:pqsadv]} {return 0}
  1498. foreach {s a} [split [channel get $chan ap:pqsadv]] {
  1499. set s [lindex [split $s :] 1]
  1500. set a [lindex [split $a :] 1]
  1501. break
  1502. }
  1503. if {($flood == "adv" && $a) || ($flood == "swear" && $s)} {
  1504. pubms $flood $nick $uhost $hand $chan $arg
  1505. }
  1506. }
  1507. }
  1508. }
  1509.  
  1510. proc nicks {flood nick uhost hand chan nn} {
  1511. if {[string first # $chan] != 0 || [invalid:apc $nn $hand [set chan [string tolower $chan]]]} {return 0}
  1512. if {![vcg $chan ap:$flood]} {return 0}
  1513. foreach {off btime pmeth btype} [set cgot [split [channel get $chan ap:$flood]]] {break}
  1514. switch -- $flood {
  1515. "nickf" {
  1516. foreach {o s} [cgsplit $off] {break}
  1517. if {[invalid:apf $o $s]} {return 0}
  1518. checkf $s $o nckflood:[string tolower $uhost:$chan] $uhost $chan $pmeth $nick {$o changes} $btype $btime nickflood
  1519. }
  1520. "bnickf" {
  1521. foreach {o s} [cgsplit $off] {break}
  1522. if {[invalid:apf $o $s]} {return 0}
  1523. checklc $s bnickc:$chan $o $chan [join [lrange $cgot 1 end-1]] [lindex $cgot end] nick
  1524. }
  1525. }
  1526. }
  1527.  
  1528. proc massk {nick uhost hand chan targ arg} {
  1529. variable masskick ; variable serv
  1530. if {![isbotnick $nick]} {
  1531. if {![vcg $chan ap:massk]} {return 0}
  1532. foreach {off btime pmeth btype} [split [channel get $chan ap:massk]] {break}
  1533. foreach {o s} [cgsplit $off] {break}
  1534. if {$nick == $targ || [invalid:apf $o $s] || [matchattr $hand fmo|fmo $chan]} {return 0}
  1535. if {[set ts [follow $s mssk:[string tolower $uhost:$chan] $o]] != -1} {
  1536. if {$masskick(deop)} {
  1537. putquick "$serv(nick) :[string map [list %chan $chan %nick $nick] $serv(command)]"
  1538. if {[botisop $chan]} { putquick "MODE $chan -o $nick" }
  1539. }
  1540. 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
  1541. }
  1542. } {
  1543. variable logkbs
  1544. if {$logkbs(do)} { aplog "\[[clock format [clock seconds] -format %T]\] Kicked $targ from $chan for reason: $arg" }
  1545. }
  1546. }
  1547.  
  1548. proc lim {} {
  1549. foreach c [channels] {
  1550. if {![vcg $c ap:limit]} {continue}
  1551. if {[set l [channel get $c ap:limit]] > 0 && [botisop $c]} {
  1552. if {[string match *l* [lindex [split [getchanmode $c]] 0]]} {
  1553. if {abs($l - ([set cl [lindex [split [getchanmode $c]] end]] - [set ccl [llength [chanlist $c]]])) >= ceil($l * 30 / 100.0)} {
  1554. pushmode $c +l [expr {$ccl + $l}]
  1555. }
  1556. } {pushmode $c +l [expr {[llength [chanlist $c]] + $l}]}
  1557. }
  1558. }
  1559. }
  1560.  
  1561. proc ctcr {nick uhost hand chan kw arg} {
  1562. if {[isbotnick [lindex [split $chan "@"] 0]] || [lindex [split $chan "@"] 1] != ""} {return 0}
  1563. ctcps bctcp $nick $uhost $hand $chan $kw $arg
  1564. ctcps ctcp $nick $uhost $hand $chan $kw $arg
  1565. }
  1566.  
  1567. proc ccodes {ch a f} {
  1568. if {![vcg $ch $f]} {return 0}
  1569. foreach {r b u c btime pmeth btype} [split [channel get $ch $f]] {break}
  1570. if {![icodes [set codes "$r $b $u $c"]]} {return 0}
  1571. set p 0
  1572. foreach cg [split $codes] {
  1573. scan $cg {%[^:]:%s} t v
  1574. if {$v <= 0} {continue}
  1575. set t [string map {r \026 b \002 u \037 c \003} $t]
  1576. if {![info exists fc($t)]} {set fc($t) 0}
  1577. foreach l [lrange [split $a $t] 1 end] {
  1578. set l [string range [set l [cf $l]] 0 [expr {[set fo [string first \017 $l]] == -1?"end":"$fo"}]]
  1579. if {$t == "\003"} {
  1580. if {[regsub {^\d{1,2}(,\d{1,2})?} $l "" l]} {
  1581. if {[incr fc($t) [string length $l]] >= $v} {set p 1; break}
  1582. continue
  1583. }
  1584. }
  1585. if {![info exists cc($t)]} {set cc($t) 0}
  1586. if {!($cc($t) % 2)} { if {[incr fc($t) [string length $l]] >= $v} {set p 1; break} }
  1587. incr cc($t)
  1588. }
  1589. if {$p} {break}
  1590. }
  1591. if {$p} {return $fc($t)}
  1592. return 0
  1593. }
  1594.  
  1595. proc isspam {arg {chan ""}} {
  1596. variable adexempts; variable adwords
  1597. set arg [string tolower [cf $arg]]; set advword ""
  1598. if {$chan != "" && [info exists adexempts($chan)]} {set l $adexempts($chan)} {set l $adexempts(global)}
  1599. foreach ade $l {set arg [string map [list [string map [list %chan $chan] $ade] ""] $arg]}
  1600. if {![regexp {(^|\s)((www\.|#)[^\s]|ftp://|http://|(/server|//(\.?)write)\s)} $arg advword]} {
  1601. if {$chan != "" && [info exists adwords($chan)]} {set l $adwords($chan)} {set l $adwords(global)}
  1602. set isad 0
  1603. foreach advword $l { if {[string match -nocase $advword $arg]} {set isad 1; break} }
  1604. if {!$isad} {set advword ""}
  1605. }
  1606. return $advword
  1607. }
  1608.  
  1609. proc bchansw {nick uhost hand chan type} {
  1610. variable bchan; variable apbcnick; variable apbvnick
  1611. foreach {o s} [split $bchan(floodprot) :] {break}
  1612. if {!$type && [follow $s bchw:[set chan [string tolower $chan]] $o] == -1 && ([vcg $chan ap:bchans] || [vcg $chan ap:echans])} {
  1613. set apbcnick([string tolower $nick]) $chan
  1614. putserv "whois $nick"
  1615. } elseif {$type && [follow $s ctcrr:$chan $o] == -1 && [vcg $chan ap:bctcrs]} {
  1616. foreach bctcr [split [channel get $chan ap:ctcpchecks]] {
  1617. if {[set bctcr [string toupper $bctcr]] != ""} {
  1618. set apbvnick([string tolower $nick]:$bctcr) $chan
  1619. putserv "privmsg $nick :\001$bctcr\001"
  1620. }
  1621. }
  1622. }
  1623. }
  1624.  
  1625. proc bchansgw {from key arg} {
  1626. variable bchan ; variable bchans ; variable apbcnick
  1627. set arg [string trim $arg]
  1628. if {![info exists apbcnick([set nick [string tolower [lindex [split $arg] 1]]])]} {return 0}
  1629. set chan $apbcnick($nick)
  1630. if {[vcg $chan ap:bchans]} {
  1631. foreach {off btime pmeth btype} [split [channel get $chan ap:bchans]] {break}
  1632. }
  1633. if {[info exists off] && $off == "+"} {
  1634. if {![info exists bchans($chan)]} { set l $bchans(global) } { set l $bchans($chan) }
  1635. foreach c [split [string tolower [join [lrange [split $arg] 2 end]]]] {
  1636. set c [string trimleft $c ":@%+"]
  1637. foreach bc $l {
  1638. if {[string match $bc $c]} {
  1639. set uhost [getchanhost $nick $chan]
  1640. if {$uhost != ""} {
  1641. set kmsg [mapr $bchan(kmsg) $c]
  1642. set wmsg [string map [list %chan $chan %bchan $c] $bchan(wmsg)]
  1643. putlog "\002AP\002: Bchans: Detected \002$nick\002 on (\002$c\002) joining \002$chan\002."
  1644. }
  1645. break
  1646. }
  1647. }
  1648. if {[info exists uhost]} {break}
  1649. }
  1650. }
  1651. if {![info exists kmsg] && [vcg $chan ap:echans]} {
  1652. foreach {off btime pmeth btype} [split [channel get $chan ap:echans]] {break}
  1653. if {$off > 0 && [set ecs [llength [lrange [split $arg] 2 end]]] >= $off} {
  1654. set uhost [getchanhost $nick $chan]
  1655. if {$uhost != ""} {
  1656. set kmsg [mapr $bchan(ekmsg) "$ecs chans"]
  1657. set wmsg [string map [list %echan "$ecs chans" %max [expr {$off-1}]] $bchan(ewmsg)]
  1658. putlog "\002AP\002: Echans: Detected \002$nick\002 on \002$ecs\002 channels."
  1659. }
  1660. }
  1661. }
  1662. if {[info exists kmsg]} {
  1663. if {$bchan(caw) > 0 && [string match -nocase *w* $pmeth]} {
  1664. set bchan([set ch $chan:[string tolower $uhost]]) 1
  1665. if {[istimer "[namespace current]::followrem bchan($ch)" utimers]==""} {
  1666. utimer [expr {$bchan(caw) + 1}] [list [namespace current]::followrem bchan($ch)]
  1667. }
  1668. }
  1669. foreach aChan [channels] {
  1670. if {[onchan $nick $aChan]} {
  1671. if {![string equal -nocase $aChan $chan]} {
  1672. if {[string is integer -strict $off] && [vcg $aChan ap:echans]} {
  1673. foreach {off btime pmeth btype} [split [channel get $aChan ap:echans]] {break}
  1674. } elseif {[vcg $aChan ap:bchans]} {
  1675. foreach {off btime pmeth btype} [split [channel get $aChan ap:bchans]] {break}
  1676. } {
  1677. continue
  1678. }
  1679. }
  1680. punish $pmeth [list $nick $uhost] $aChan $kmsg $wmsg $btype $btime $bchan(klmsg) $bchan(ktime) $bchan(ktype) [string tolower $uhost]:badchan
  1681. }
  1682. }
  1683. }
  1684. return 0
  1685. }
  1686.  
  1687. proc bctcrs {nick uhost hand targ kw arg} {
  1688. variable bctcr; variable bctcrs; variable apbvnick
  1689. if {![isbotnick $targ] || ![info exists apbvnick([set nkw [string tolower $nick]:[set kw [string toupper $kw]]])]} {return 0}
  1690. set chan $apbvnick($nkw); unset apbvnick($nkw)
  1691. if {![vcg $chan ap:bctcrs]} {return 0}
  1692. foreach {off btime pmeth btype} [split [channel get $chan ap:bctcrs]] {break}
  1693. if {![info exists bctcrs($chan)]} { set l $bctcrs(global) } { set l $bctcrs($chan) }
  1694. set m 0
  1695. foreach bv $l { if {[string match -nocase $bv $arg]} {set m 1; break} }
  1696. if {$m} {
  1697. if {$bctcr(caw) > 0 && [string match -nocase *w* $pmeth]} {
  1698. set bctcr([set ch $chan:[string tolower $uhost]]) 1
  1699. if {[istimer "[namespace current]::followrem bctcr($ch)" utimers]==""} {
  1700. utimer [expr {$bctcr(caw) + 1}] [list [namespace current]::followrem bctcr($ch)]
  1701. }
  1702. }
  1703. 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
  1704. }
  1705. }
  1706.  
  1707. proc checkbcd c {
  1708. variable cbcd
  1709. if {!$cbcd(check) || [nap:chan $c $cbcd(chans)]} {return 0}
  1710. foreach n [chanlist $c] {
  1711. foreach sc $cbcd(procs) {
  1712. joins [string map {echans bchans} $sc] $n [getchanhost $n $c] [nick2hand $n $c] $c
  1713. }
  1714. }
  1715. }
  1716.  
  1717. proc core {m h args} {
  1718. lim; checkscans
  1719. variable NumKicks; variable kckcount; variable ptrig; variable pwait; variable logkbs
  1720. variable removebs; variable ::max-bans
  1721. if {[regexp {03:00} $h:$m] && [info exists logkbs(logs)]} {
  1722. if {$logkbs(do) == 1} {
  1723. set f [open $logkbs(file).yesterday w]
  1724. } elseif {$logkbs(do) == 2} {
  1725. set f [open $logkbs(file).[clock format [expr {[unixtime]-86400}] -format "%d.%m.%y"] w]
  1726. }
  1727. if {[info exists logkbs(logs)]} { foreach log $logkbs(logs) { if {$log != ""} { puts $f $log } } }
  1728. close $f
  1729. set logkbs(logs) [list "\$Log started [ctime [unixtime]]\$"]
  1730. }
  1731. if {$removebs} {
  1732. foreach c [channels] {
  1733. if {[botisop $c] && [llength [set cl [chanbans $c]]] >= ${max-bans}} {
  1734. foreach b [lrange $cl 0 [expr {$removebs-1}]] { pushmode $c -b [lindex $b 0] }
  1735. }
  1736. }
  1737. }
  1738. if {[scan $m %d]%2} {return 0}
  1739. foreach {pn pe} [array get ptrig] { if {[unixtime]-[lindex $pe 1] > $pwait} {unset ptrig($pn)} }
  1740. if {[regexp {\d0} $m]} {
  1741. set kc [open $kckcount(file) w]
  1742. puts $kc $NumKicks ; close $kc
  1743. variable following
  1744. foreach {an ae} [array get following] {
  1745. if {([clock clicks -milliseconds]-[lindex $ae 1])/1000 > $pwait} {
  1746. unset following($an)
  1747. }
  1748. }
  1749. variable punishing
  1750. foreach {i s} [array get punishing] {if {[clock clicks -milliseconds] >= $s} {unset punishing($i)}}
  1751. if {$logkbs(do)} {
  1752. set f [open $logkbs(file) w]
  1753. foreach log $logkbs(logs) { if {$log != ""} { puts $f $log } }
  1754. close $f
  1755. }
  1756. }
  1757. }
  1758.  
  1759. set antispam(next) -1
  1760. #set antispam(tip) ${my-ip}
  1761. #set antispam(thost) ${my-hostname}
  1762.  
  1763. proc antispamcore {m h args} {
  1764. variable antispam; variable Sec
  1765. if {![info exists antispam(idx)] || ![valididx $antispam(idx)]} {
  1766. if {[info exists antispam(idx)]} {unset antispam(idx)}
  1767. if {[info exists antispam(cnick)]} {unset antispam(cnick)}
  1768. foreach {s p} [split [lindex [lindex $::servers [expr {[incr antispam(next)]%[llength $::servers]}]] 0] :] {break}
  1769. foreach c [channels] {
  1770. if {[vcg $c ap:antispam] && [lindex [split [channel get $c ap:antispam]] 0] == "+"} {
  1771. set ::my-ip $antispam(ip); set ::my-hostname $antispam(host)
  1772. control [connect $s $p] [namespace current]::antispambot
  1773. putlog "\002AP\002: AntiSpamBot: Connecting to $s:$p..."
  1774. break
  1775. }
  1776. }
  1777. return
  1778. }
  1779. set asbc 0
  1780. foreach c [channels] {
  1781. set mins [expr {[scan $m %d]+([scan $h %d]*60)}]
  1782. foreach {off greet cycle idle} [split [channel get $c ap:antispam]] {break}
  1783. if {$off == "+"} {incr asbc}
  1784. if {[onchan $antispam(cnick) $c] && $off != "+"} {
  1785. putdcc $antispam(idx) "part $c"
  1786. } elseif {$cycle != 0 && $mins%$cycle == 0 && [onchan $antispam(cnick) $c]} {
  1787. if {![info exists antispam([set e [string tolower $c]:idle])]} {set antispam($e) [unixtime]}
  1788. if {[unixtime]-$antispam($e) < $idle*60 && [botisop $c]} {
  1789. putlog "\002AP\002: AntiSpamBot: Cycling $c..."
  1790. putdcc $antispam(idx) "part $c"
  1791. putdcc $antispam(idx) "join $c"
  1792. }
  1793. } {if {![onchan $antispam(cnick) $c] && $off == "+"} {putdcc $antispam(idx) "join $c"}}
  1794. }
  1795. if {!$asbc} {
  1796. putdcc $antispam(idx) quit
  1797. putlog "\002AP\002: AntiSpamBot: Disconnected (disabled on all channels)..."
  1798. }
  1799. }
  1800.  
  1801. proc antispambot {idx arg} {
  1802. variable antispam; variable adv; variable greetexempts; variable antiSpamOnline
  1803. if {${::my-ip} != $antispam(tip)} {set ::my-hostname $antispam(thost); set ::my-ip $antispam(tip)}
  1804. if {$arg == ""} {
  1805. if {[info exists antispam(idx)]} {unset antispam(idx)}
  1806. if {[info exists antispam(cnick)]} {unset antispam(cnick)}
  1807. if {[info exists antiSmapOnline]} {unset antiSpamOnline}
  1808. if {[info exists antispam(qrsn)]} {set rsn $antispam(qrsn); unset antispam(qrsn)} {set rsn (dead)}
  1809. putlog "\002AP\002: AntiSpamBot: Disconnected $rsn..."
  1810. return
  1811. }
  1812. if {![info exists antispam(idx)] && ![info exists antispam(cnick)]} {
  1813. set antispam(idx) $idx ; set antispam(cnick) $antispam(nick)
  1814. putdcc $idx "user $antispam(user) 8 * :$antispam(realname)"
  1815. putdcc $idx "nick $antispam(cnick)"
  1816. return
  1817. }
  1818. if {![info exists antiSpamOnline]} {
  1819. set antiSpamOnline 1
  1820. if {[istimer [namespace current]::dumpqueues utimers]==""} {
  1821. variable Sec -1
  1822. utimer 1 [namespace current]::dumpqueues
  1823. }
  1824. }
  1825. switch -- [string tolower [lindex [split $arg] 0]] {
  1826. "ping" {putdcc $idx "pong [lindex [split $arg] 1]"}
  1827. "error" {set antispam(qrsn) [join [lrange [split $arg] 4 end]]; return}
  1828. }
  1829. switch -- [set raw [string tolower [lindex [split $arg] 1]]] {
  1830. "privmsg" - "notice" {
  1831. set src [lindex [split $arg] 0]
  1832. set asbn [lindex [split $arg] 2]
  1833. if {![string equal -nocase $asbn $antispam(cnick)]} {return}
  1834. if {[scan $src {:%[^!]!%s} nick uhost] != 2} {return}
  1835. set text [join [lrange [split $arg] 3 end]]
  1836. if {[set advword [isspam $text]] == ""} {
  1837. if {$raw == "privmsg" && [string match ":\001DCC Send *\001" $text]} {set advword "DCC SEND"}
  1838. }
  1839. if {$advword == ""} {
  1840. foreach {o s} [split $antispam(mprot) :] {break}
  1841. if {[follow $s asbm $o 1 1] != -1} {return}
  1842. set ism 0
  1843. foreach t $antispam(t) {if {[string match -nocase $t $text]} {set ism 1; break}}
  1844. set l $greetexempts(global)
  1845. set f 0; foreach ge $l { if {[string match -nocase $ge $nick!$uhost]} {set f 1;break} }
  1846. if {$ism && !$f} {asb:queue $nick [lindex $antispam(r) [rand [llength $antispam(r)]]]}
  1847. }
  1848. }
  1849. "invite" {
  1850. set src [lindex [split $arg] 0]
  1851. if {[scan $src {:%[^!]!%s} nick uhost] != 2} {return}
  1852. set advword "INVITE"
  1853. }
  1854. "001" {
  1855. putlog "\002AP\002: AntiSpamBot: Connected and registered as $antispam(cnick)."
  1856. set antispam(pong) 1; set antispam(idx) $idx
  1857. foreach c [channels] {
  1858. if {![vcg $c ap:antispam]} {continue}
  1859. if {[lindex [split [channel get $c ap:antispam]] 0] == "+"} {
  1860. putdcc $idx "join $c"
  1861. }
  1862. }
  1863. }
  1864. "433" {
  1865. if {$antispam(cnick) == $antispam(nick)} {set antispam(cnick) $antispam(altnick)} {
  1866. set antispam(cnick) [string replace $antispam(nick) end end [rand 10]]
  1867. }
  1868. putdcc $idx "nick $antispam(cnick)"
  1869. }
  1870. "nick" {
  1871. if {[string trimleft [lindex [split [lindex [split $arg] 0] @] 0] :] == $antispam(cnick)} {
  1872. set antispam(cnick) [string trimleft [lindex [split $arg] 2] :]
  1873. }
  1874. }
  1875. "join" {
  1876. foreach {o s} [split $antispam(jprot) :] {break}
  1877. set c [string trim [string tolower [string trimleft [lindex [split $arg] end] :]]]
  1878. if {![validchan $c]} {return}
  1879. foreach {off greet cy i} [split [channel get $c ap:antispam]] {break}
  1880. if {[vcg $c ap:antispam] && $off == "+"} {
  1881. if {[scan [lindex [split $arg] 0] {:%[^!]!%s} nick uhost] != 2} {return}
  1882. if {[string equal -nocase $nick $antispam(cnick)] || [follow $s asbj:$c $o 1 1] != -1} {return}
  1883. set antispam($c:idle) [unixtime]
  1884. if {[info exists greetexempts($c)]} {set l $greetexempts($c)} {set l $greetexempts(global)}
  1885. set f 0; foreach ge $l { if {[string match -nocase $ge $nick!$uhost]} {set f 1;break} }
  1886. if {!$f && $greet == "+" && ![invalid:apc $nick [finduser $nick!$uhost] $c]} {
  1887. asb:queue $nick [string map [list %nick $nick] $antispam(greet)]
  1888. }
  1889. }
  1890. }
  1891. }
  1892. if {[info exists advword] && $advword != ""} {
  1893. set hand [finduser [string trimleft $src :]]
  1894. foreach c [channels] {
  1895. if {![vcg $c ap:antispam] || ![vcg $c ap:adv] || [invalid:apc $nick $hand $c]} {continue}
  1896. if {[lindex [split [channel get $c ap:antispam]] 0] == "+"} {
  1897. foreach {off btime pmeth btype} [split [channel get $c ap:adv]] {break}
  1898. if {$off == "+"} {
  1899. if {$antispam(banall) || [onchan $nick $c]} {
  1900. punish $pmeth [list $nick $uhost] $c [mapr $adv(kmsg) *$advword*] $adv(wmsg) $btype $btime $adv(klmsg) $adv(ktime) $adv(ktype) [string tolower $uhost]:adv
  1901. }
  1902. }
  1903. }
  1904. }
  1905. }
  1906. }
  1907.  
  1908. proc cmd {cmd hand idx arg} {
  1909. variable banthruX
  1910. set arg [string tolower $arg]
  1911. if {[regexp {add|rem|list} $cmd]} {
  1912. set lists {bchans bnicks bidents bwords adexempts droneexempts bctcrs adwords greetexempts}
  1913. if {[regexp {add|rem} $cmd]} {
  1914. set synp " <bad chans/nicks/idents/bwords/adexempts/droneexempts/bctcrs/adwords/greetexempts>"
  1915. set sl [join [lrange [split $arg] 2 end]]
  1916. if {[join [set l [cl $sl]]]==""} {
  1917. putdcc $idx "\002AP\002: SYNTAX: .ap:$cmd <[join $lists /]> <#chan/global>$synp."
  1918. return 0
  1919. }
  1920. } {set synp ""}
  1921. if {[scan $arg "%s %s" t c] != 2} {
  1922. putdcc $idx "\002AP\002: SYNTAX: .ap:$cmd <[join $lists /]> <#chan/global>$synp."
  1923. return 0
  1924. }
  1925. if {[lsearch -exact $lists $t] == -1} {
  1926. putdcc $idx "\002AP\002: Invalid list \002$t\002, should be one of: [join $lists ", "]."
  1927. return 0
  1928. }
  1929. if {[set ti [string first # $c]] != 0 && $c != "global"} {
  1930. putdcc $idx "\002AP\002: Invalid chan \002$c\002, either use a valid chan or 'global'."
  1931. return 0
  1932. }
  1933. upvar [namespace current]::$t aptv
  1934. } elseif {[regexp {reset|disable} $cmd]} {
  1935. if {[set chans [string map [list * [channels]] [lindex [split $arg] 0]]] == ""} {
  1936. putdcc $idx "\002AP\002: SYNTAX: .ap:$cmd <#channel>"
  1937. return 0
  1938. }
  1939. variable ap:udefs
  1940. }
  1941. switch -- $cmd {
  1942. "add" {
  1943. if {$ti == 0} {
  1944. if {[validchan $c]} {
  1945. if {![info exists aptv($c)]} {
  1946. set aptv($c) $l
  1947. set unfound $l
  1948. } {
  1949. foreach bs $l {
  1950. if {[lsearch -exact $aptv($c) $bs] != -1} { lappend found $bs } {
  1951. if {[string equal bchans $t] && [string first # $bs] != 0} {
  1952. putdcc $idx "\002AP\002: Invalid channel $bs, not adding..."
  1953. continue
  1954. }
  1955. lappend unfound $bs
  1956. lappend aptv($c) $bs
  1957. }
  1958. }
  1959. }
  1960. } {
  1961. putdcc $idx "\002AP\002: Invalid chan \002$c\002, either use a valid chan or 'global'."
  1962. return 0
  1963. }
  1964. } {
  1965. foreach bs $l {
  1966. if {[lsearch -exact $aptv($c) $bs] != -1} { lappend found $bs } {
  1967. if {[string equal bchans $t] && [string first # $bs] != 0} {
  1968. putdcc $idx "\002AP\002: Invalid channel $bs, not adding..."
  1969. continue
  1970. }
  1971. lappend unfound $bs
  1972. lappend aptv($c) $bs
  1973. }
  1974. }
  1975. }
  1976. if {[info exists unfound]} {
  1977. foreach unfou [ww $unfound] {
  1978. putdcc $idx "\002AP\002: Succesfully added [join $unfou ,] to $c $t list."
  1979. }
  1980. sv
  1981. }
  1982. if {[info exists found]} {
  1983. foreach fou [ww $found] {
  1984. putdcc $idx "\002AP\002: [join $fou ,] already exist in $c $t list."
  1985. }
  1986. }
  1987. }
  1988. "rem" {
  1989. if {$ti == 0} {
  1990. if {[validchan $c]} {
  1991. if {![info exists aptv($c)]} {
  1992. putdcc $idx "\002AP\002: $c $t list is empty."
  1993. return 0
  1994. } {
  1995. foreach bs $l {
  1996. if {[set sbs [lsearch -exact $aptv($c) $bs]] != -1} {
  1997. set aptv($c) [lreplace $aptv($c) $sbs $sbs]
  1998. lappend found $bs
  1999. if {$aptv($c) == {}} {unset aptv($c) ; break}
  2000. } { lappend unfound $bs }
  2001. }
  2002. }
  2003. } {
  2004. putdcc $idx "\002AP\002: $c is an invalid channel, either use a valid chan or 'global'."
  2005. return 0
  2006. }
  2007. } {
  2008. foreach bs $l {
  2009. if {[set sbs [lsearch -exact $aptv($c) $bs]] != -1} {
  2010. set aptv($c) [lreplace $aptv($c) $sbs $sbs]
  2011. lappend found $bs
  2012. } { lappend unfound $bs }
  2013. }
  2014. }
  2015. if {[info exists unfound]} {
  2016. foreach unfou [ww $unfound] {putdcc $idx "\002AP\002: [join $unfou ,] was not found in $c $t list."}
  2017. }
  2018. if {[info exists found]} {
  2019. foreach fou [ww $found] {putdcc $idx "\002AP\002: Succesfully removed [join $fou ,] from $c $t list."}
  2020. sv
  2021. }
  2022. }
  2023. "list" {
  2024. if {$ti == 0} {
  2025. if {[validchan $c]} {
  2026. if {[info exists aptv($c)] && $aptv($c) != {}} {
  2027. foreach aplist [ww $aptv($c)] {putdcc $idx "\002AP\002: $c $t list: [join $aplist ,]"}
  2028. } {putdcc $idx "\002AP\002: $c $t list is empty." ; return 0}
  2029. } {putdcc $idx "\002AP\002: Invalid chan \002$c\002, either use a valid chan or 'global'." ; return 0}
  2030. } {
  2031. if {$aptv($c) != {}} {
  2032. foreach aplist [ww $aptv($c)] {putdcc $idx "\002AP\002: $c $t list: [join $aplist ,]"}
  2033. } {putdcc $idx "\002AP\002: $c $t list is empty."}
  2034. }
  2035. }
  2036. "import" {
  2037. if {[scan $arg "%s %s" oc ncs] != 2} {
  2038. putdcc $idx "\002AP\002: SYNTAX: .ap:import <oldchan> <newchan>" ; return 0
  2039. }
  2040. foreach nc [string map [list * [channels]] $ncs] {
  2041. if {[validchan $oc] && [validchan $nc]} {
  2042. foreach ci [channel info $oc] {
  2043. if {[string match ap:* [lindex $ci 0]]} {channel set $nc [lindex $ci 0] [lindex $ci 1]}
  2044. }
  2045. putdcc $idx "\002AP\002: Imported all AllProtection settings from $oc to $nc."
  2046. } {putdcc $idx "\002AP\002: Failed! Make sure that $oc and $nc are valid channels."}
  2047. }
  2048. }
  2049. "reset" {
  2050. foreach c $chans {
  2051. if {[validchan $c]} {
  2052. foreach u ${ap:udefs} {
  2053. if {[lindex $u 0] == "ap:level" && !$banthruX(do)} {continue}
  2054. channel set $c [lindex $u 0] [lindex $u 1]
  2055. }
  2056. putdcc $idx "\002AP\002: Reset all AllProtection settings on $c."
  2057. } {putdcc $idx "\002AP\002: Failed! Make sure that $c is a valid channel."}
  2058. }
  2059. }
  2060. "disable" {
  2061. set OZ {ap:repeatc ap:clones ap:echans ap:partmsgs}
  2062. set NV {ap:adv ap:swear ap:bnicks ap:drones ap:bidents ap:bchans ap:bctcrs ap:antispam}
  2063. set CC {ap:codes ap:partmsgc}
  2064. foreach c $chans {
  2065. if {[validchan $c]} {
  2066. foreach u ${ap:udefs} {
  2067. if {[set ud [lindex $u 0]] == "ap:level" && !$banthruX(do)} {continue}
  2068. set rest [join [lrange [split [channel get $c $ud]] 1 end]]
  2069. if {[lsearch -exact $OZ $ud] != -1} {
  2070. channel set $c $ud "0 $rest"
  2071. } elseif {[lsearch -exact $NV $ud] != -1} {
  2072. channel set $c $ud "- $rest"
  2073. } elseif {[lsearch -exact $CC $ud] != -1} {
  2074. channel set $c $ud "r:0 b:0 u:0 c:0 [join [lrange [split [channel get $c $ud]] 4 end]]"
  2075. } elseif {[regexp {ap:(limit|level)} $u]} {
  2076. channel set $c $ud 0
  2077. } elseif {$ud == "ap:pqsadv"} {
  2078. channel set $c $ud "s:0 a:0"
  2079. } elseif {$ud != "ap:ctcpchecks"} {
  2080. channel set $c $ud "0:0 $rest"
  2081. }
  2082. }
  2083. putdcc $idx "\002AP\002: Succesfully disabled all AP protections on $c."
  2084. } {putdcc $idx "\002AP\002: $c is an invalid channel (not in my chanlist)."}
  2085. }
  2086. }
  2087. "monitor" {
  2088. variable ptrig ; variable pwait
  2089. if {[set pta [array get ptrig]]==""} {putdcc $idx "\002AP\002: No users currently under punishment."} {
  2090. set fm 0
  2091. foreach {uf ot} $pta {
  2092. foreach {c u f} [split $uf :] {break} ; foreach {o t} $ot {break}
  2093. if {[set dur [expr {$pwait-([unixtime]-$t)}]]>0} {
  2094. 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)."
  2095. if {!$fm} {set fm 1}
  2096. }
  2097. }
  2098. if {!$fm} {putdcc $idx "\002AP\002: No users currently under punishment."}
  2099. }
  2100. }
  2101. "priv" {
  2102. set ptypes {ptextl ptextc pnotil pnotic pctcpf}
  2103. switch -- [string tolower [lindex [split $arg] 0]] {
  2104. "set" {
  2105. set pt [string tolower [lindex [split $arg] 1]]
  2106. if {[lsearch -exact $ptypes $pt] == -1 || ![regexp {^\d+:\d+$} [set v [lindex [split $arg] 2]]]} {
  2107. putdcc $idx "\002AP\002: SYNTAX: .ap:priv set <[join $ptypes /]> #:#" ; return 0
  2108. }
  2109. upvar [namespace current]::$pt privt
  2110. set privt(punish) $v
  2111. putdcc $idx "\002AP\002: Successfully set \002$pt\002 to \002$v\002."
  2112. sv
  2113. }
  2114. "list" {
  2115. foreach pt $ptypes {
  2116. upvar [namespace current]::$pt privt
  2117. putdcc $idx "\002AP\002: ${pt}: $privt(punish)"
  2118. }
  2119. }
  2120. default {putdcc $idx "\002AP\002: SYNTAX: .ap:priv <set/list> \[[join $ptypes /]\]."}
  2121. }
  2122. }
  2123. }
  2124. }
  2125.  
  2126. proc sv {} {
  2127. set apf [open scripts/aplists w]
  2128. set lists {bchans bnicks bidents bwords adexempts droneexempts bctcrs adwords
  2129. greetexempts ptextl ptextc pnotil pnotic pctcpf}
  2130. foreach list $lists {
  2131. variable $list
  2132. foreach {apc apbc} [array get $list] {
  2133. if {$apc != "global" && $apbc == {}} {continue}
  2134. puts $apf "$list $apc [string trim [regsub -all {\s{1,}} $apbc " "]]"
  2135. }
  2136. }
  2137. close $apf
  2138. }
  2139.  
  2140. proc rd {} {
  2141. if {[file exists scripts/aplists]} {
  2142. foreach apl [split [string tolower [read [set apf [open scripts/aplists]]]] \n][close $apf] {
  2143. upvar [namespace current]::[lindex [split $apl] 0] apt
  2144. set apt([set p [lindex [split $apl] 1]]) [set e [lrange $apl 2 end]]
  2145. if {[regexp {^\d+:\d+$} [join $e]]} {set apt($p) [join $e]}
  2146. }
  2147. } {sv}
  2148. }
  2149.  
  2150. proc ptext {flood nick uhost hand arg} {
  2151. switch -- $flood {
  2152. "f" {
  2153. variable ptextl ; variable ptextc
  2154. foreach {ptxtll ptxtls} [split $ptextl(punish) :] {break}
  2155. foreach {ptxtcl ptxtcs} [split $ptextc(punish) :] {break}
  2156. if {[matchattr $hand fmo]} {return 0}
  2157. if {($ptxtll > 0 && [follow $ptxtls ptxtl $ptxtll] != -1) || ($ptxtcl > 0 && \
  2158. [follow $ptxtcs ptxtc $ptxtcl [string length $arg]] != -1)} {
  2159. privl MSG
  2160. }
  2161. }
  2162. "adv" {
  2163. foreach chan [channels] {
  2164. if {[onchan $nick $chan]} { pubms adv $nick $uhost $hand $chan $arg }
  2165. }
  2166. }
  2167. }
  2168. }
  2169.  
  2170. proc pctcp {flood nick uhost hand dest kw arg} {
  2171. if {![isbotnick [lindex [split $dest @] 0]] || [string equal -nocase chat $kw]} {return 0}
  2172. switch -- $flood {
  2173. "text" {if {[isbotnick [lindex [split $dest @] 0]]} { ptext f $nick $uhost $hand $arg }}
  2174. "ctcp" {
  2175. variable pctcpf
  2176. foreach {pctcpl pctcps} [split $pctcpf(punish) :] {break}
  2177. if {$pctcpl <= 0 || [string equal -nocase action $kw] || [matchattr $hand fmo]} {return 0}
  2178. if {[follow $pctcps pfctcp $pctcpl] != -1} {privl CTCP}
  2179. }
  2180. }
  2181. }
  2182.  
  2183. proc pnotc {nick uhost hand arg dest} {
  2184. variable pnotil; variable pnotic
  2185. foreach {pntll pntls} [split $pnotil(punish) :] {break}
  2186. foreach {pntcl pntcs} [split $pnotic(punish) :] {break}
  2187. if {[isbotnick [lindex [split $dest @] 0]] && ![matchattr $hand fmo]} {
  2188. if {($pntll > 0 && [follow $pntls pnotl $pntll] != -1) || ($pntcl > 0 && \
  2189. [follow $pntcs pnotc $pntcl [string length $arg]] != -1)} {
  2190. privl NOTICE
  2191. }
  2192. }
  2193. }
  2194.  
  2195. proc pctcr {nick uhost hand dest kw arg} {
  2196. if {![isbotnick [lindex [split $dest "@"] 0]]} {return 0}
  2197. pctcp ctcp $nick $uhost $hand $dest $kw $arg
  2198. }
  2199.  
  2200. proc pflud {nick uhost hand type chan} {
  2201. variable sfluds
  2202. expr {$chan == "*" && $sfluds}
  2203. }
  2204.  
  2205. proc privl t {
  2206. variable sfluds ; variable apfp ; variable bred ; variable ::botnick
  2207. if {!$sfluds} {
  2208. if {[string length $apfp(rmode)]==1} {
  2209. if {!$bred} {
  2210. putquick "MODE $botnick +$apfp(rmode)" -next
  2211. if {$apfp(rtime) > 0} {
  2212. utimer $apfp(rtime) [namespace current]::remr
  2213. }
  2214. set bred 1
  2215. putlog "\002AP\002: Set mode +$apfp(rmode) on me. ($t flood on me!)"
  2216. }
  2217. }
  2218. set sfluds 1
  2219. utimer $apfp(itime) [list set [namespace current]::sfluds 0]
  2220. putlog "\002AP\002: Private botnet flood detected. Temporarly stopped answering recieved data."
  2221. }
  2222. }
  2223.  
  2224. proc punish {pm nl c km wm bty bti klm kti kty fv} {
  2225. variable pwait; variable kline; variable ptrig; variable banthruX; variable ::max-bans
  2226. if {$kti < 0} { set kti $kline(time) }
  2227. set fv $c:$fv
  2228. if {![info exists ptrig($fv)] || [unixtime]-[lindex $ptrig($fv) 1] > $pwait} {
  2229. set ptrig($fv) [list 0 [unixtime]]
  2230. }
  2231. set o [lindex $ptrig($fv) 0]
  2232. set ol [llength [split $pm :]]
  2233. if {$o > $ol - 1} { set o [expr {$ol - 1}] }
  2234. set p [string tolower [lindex [split $pm :] $o]]
  2235. pcount $pwait ptrig($fv)
  2236. set cc 0
  2237. switch -- $p {
  2238. "kb" {
  2239. foreach {jn ju} $nl {
  2240. if {[onchan $jn $c] && ![punishing k:$jn:$c]} {
  2241. putquick "KICK $c $jn :[clonemap [mapall $km $c $bti] [incr cc]]"
  2242. }
  2243. if {[punishing b:[set bm [masktype $jn!$ju $bty]]:$c]} {continue}
  2244. if {![info exists arb($bm)]} {
  2245. if {$banthruX(do)==2 || ($banthruX(do) && [llength [chanbans $c]] >= ${max-bans})} {
  2246. putquick [mapXcmd $banthruX(cmd) $jn $ju $c [clonemap [mapall $km $c $bti] $cc] $bty $bti]
  2247. } {
  2248. queue $c $bm
  2249. if {$bti > 0 && [istimer "pushmode $c -b $bm"] == ""} {
  2250. timer $bti [list pushmode $c -b $bm]
  2251. }
  2252. set arb($bm) 1
  2253. }
  2254. }
  2255. }
  2256. }
  2257. "k" {
  2258. foreach {jn ju} $nl {
  2259. if {[onchan $jn $c] && ![punishing k:$jn:$c]} {
  2260. putquick "KICK $c $jn :[clonemap [mapall $km $c 0] [incr cc]]"
  2261. }
  2262. }
  2263. }
  2264. "b" {
  2265. foreach {jn ju} $nl {
  2266. if {[punishing b:[set bm [masktype $jn!$ju $bty]]:$c]} {continue}
  2267. if {![info exists arb($bm)]} {
  2268. if {$banthruX(do)==2 || ($banthruX(do) && [llength [chanbans $c]] >= ${max-bans})} {
  2269. putquick [mapXcmd $banthruX(cmd) $jn $ju $c [clonemap [mapall $km $c $bti] [incr cc]] $bty $bti]
  2270. } {
  2271. queue $c $bm
  2272. if {$bti > 0 && [istimer "pushmode $c -b $bm"] == ""} {
  2273. timer $bti [list pushmode $c -b $bm]
  2274. }
  2275. set arb($bm) 1
  2276. }
  2277. }
  2278. }
  2279. }
  2280. "w" {
  2281. variable wmeth; variable bnick; variable bident; variable eclones; variable bchan; variable bctcr
  2282. set nsc [namespace current]
  2283. if {[info exists eclones([string tolower $c:[lindex [split [lindex $nl 1] @] 1]])]} {
  2284. utimer $eclones(caw) [list ${nsc}::joins clones [set tempn [lindex $nl end-1]] [lindex $nl end] [nick2hand $tempn $c] $c]
  2285. }
  2286. foreach {jn ju} $nl {
  2287. if {[info exists bchan([set ch [string tolower $c:$ju]])]} {
  2288. utimer $bchan(caw) [list ${nsc}::bchansw $jn $ju [nick2hand $jn $c] $c 0]
  2289. } elseif {[info exists bctcr($ch)]} {
  2290. utimer $bctcr(caw) [list ${nsc}::bchansw $jn $ju [nick2hand $jn $c] $c 1]
  2291. } elseif {[info exists bnick($ch)]} {
  2292. utimer $bnick(caw) [list ${nsc}::joins bnicks $jn $ju [nick2hand $jn $c] $c]
  2293. } elseif {[info exists bident($ch)]} {
  2294. utimer $bident(caw) [list ${nsc}::joins bidents $jn $ju [nick2hand $jn $c] $c]
  2295. }
  2296. if {[punishing w:$jn:$c]} {continue}
  2297. puthelp "$wmeth $jn :$wm"
  2298. lappend offenders $jn
  2299. }
  2300. if {[info exists offenders]} { putlog "\002AP\002: Warned [join $offenders \002,\002] on $c: $wm" }
  2301. }
  2302. "kl" {
  2303. foreach {jn ju} $nl {
  2304. if {[punishing kl:[set klmask [scan [masktype $jn!$ju $kty] {%*[^!]!%s}]]:$c]} {continue}
  2305. if {![info exists ark($klmask)]} {
  2306. putquick [string map [list %mask $klmask %time $kti %reason $klm] $kline(cmd)]
  2307. set ark($klmask) 1
  2308. }
  2309. }
  2310. }
  2311. "kil" {
  2312. foreach {jn ju} $nl {
  2313. if {[punishing kil:$jn:$c]} {continue}
  2314. putquick "kill $jn $klm"
  2315. }
  2316. }
  2317. "v" {}
  2318. default {
  2319. error "\002AP\002: Invalid punishment method, must be either v, w, k, b, kb, kl or kil."
  2320. }
  2321. }
  2322. return 0
  2323. }
  2324.  
  2325. proc checkscans {} {
  2326. variable Sec; variable apqueue; variable antiSpamOnline
  2327. if {[istimer [namespace current]::dumpqueues utimers]==""} {
  2328. set startTimer 0
  2329. if {$apqueue(time) > 0 || [info exists antiSpamOnline]} {
  2330. set startTimer 1
  2331. }
  2332. if {$startTimer} {
  2333. set Sec -1
  2334. utimer 1 [namespace current]::dumpqueues
  2335. }
  2336. }
  2337. foreach ss {ap:bctcrs ap:bchans ap:echans} {
  2338. foreach c [channels] {
  2339. if {![info exists scanned($c)]} {set scanned($c) 0}
  2340. if {!$scanned($c)} {set scanned($c) [activt [string tolower $c] $ss]}
  2341. }
  2342. }
  2343. }
  2344.  
  2345. proc activt {c ss} {
  2346. set got [split [channel get $c $ss]]
  2347. set i 0
  2348. set ns [namespace current]
  2349. if {[vcg $c $ss]} {
  2350. if {![string is integer -strict [set ce [lindex $got 0]]]} {
  2351. if {$ce == "+" && [set t [lindex $got end]] > 0} {
  2352. set st 1
  2353. if {[istimer "${ns}::scanc $c $ss"]==""} { timer $t [list ${ns}::scanc $c $ss]; set i 1 }
  2354. }
  2355. } elseif {$ce > 0 && [set t [lindex $got end]] > 0} {
  2356. set st 1
  2357. if {[istimer "${ns}::scanc $c $ss"]==""} { timer $t [list ${ns}::scanc $c $ss] }
  2358. }
  2359. }
  2360. if {[info exists st] && [istimer [namespace current]::dumpqueues utimers]==""} {
  2361. variable Sec
  2362. set Sec -1
  2363. utimer 1 [namespace current]::dumpqueues
  2364. }
  2365. set i
  2366. }
  2367.  
  2368. proc scanc {c ss} {
  2369. variable scanq
  2370. set got [split [channel get $c $ss]]
  2371. set scan 0
  2372. if {[vcg $c $ss]} {
  2373. if {![string is integer -strict [set ce [lindex $got 0]]]} {
  2374. if {$ce == "+" && [lindex $got end] > 0} {set scan 1}
  2375. } elseif {$ce > 0 && [lindex $got end] > 0} {set scan 1}
  2376. if {$scan} {
  2377. set scanq($c) {}
  2378. foreach n [chanlist $c] {
  2379. if {[invalid:apc $n [set h [nick2hand $n $c]] $c]} {continue}
  2380. lappend scanq($c) [list $n [getchanhost $n $c] $h [expr {[regexp {ap:[be]chans} $ss]?0:1}]]
  2381. }
  2382. activt $c $ss
  2383. }
  2384. }
  2385. }
  2386.  
  2387. proc ezilamn str {
  2388. set str2 ""
  2389. for {set i [string length $str]} {$i > 0} {incr i -1} {
  2390. append str2 [string index $str [expr {$i - 1}]]
  2391. }
  2392. set str2
  2393. }
  2394.  
  2395. proc vcg {c cg} {
  2396. if {$cg == "ap:ctcpchecks"} {return [expr {[channel get $c $cg] != ""}]}
  2397. if {$cg == "ap:pqsadv"} {return [string match -nocase {s:[01] a:[01]} [channel get $c $cg]]}
  2398. set L5 {ap:bchans ap:echans ap:bctcrs}
  2399. set L7 {ap:codes ap:partmsgc}
  2400. set lgot [llength [set got [split [channel get $c $cg]]]]
  2401. if {[lsearch $L5 $cg] != -1} {
  2402. if {$lgot != 5} {return 0} ; set i 1
  2403. } elseif {[lsearch $L7 $cg] != -1} {
  2404. if {$lgot != 7} {return 0} ; set i 4
  2405. } elseif {[regexp {ap:(limit|level)} $cg]} {
  2406. if {$lgot != 1} {return 0} ; set i 0
  2407. } {
  2408. if {![regexp {ap:(b[^i]|massj)} $cg] || $cg == "ap:bnicks"} {
  2409. if {$lgot != 4} {return 0} ; set i 1
  2410. if {$cg == "ap:antispam"} {
  2411. set i 2
  2412. } elseif {[regexp {ap:(repeatc|partmsgs|revdoor|clones|echans)} $cg] && ![string is integer -strict [lindex $got 0]]} {
  2413. return 0
  2414. }
  2415. } {set i end}
  2416. }
  2417. expr {[string is integer -strict [lindex $got $i]]&&[string is integer -strict [lindex $got end]]}
  2418. }
  2419.  
  2420. proc init c {
  2421. variable ap:udefs; variable banthruX
  2422. foreach u ${ap:udefs} {
  2423. if {[lindex $u 0] == "ap:level" && !$banthruX(do)} {continue}
  2424. if {![vcg $c [lindex $u 0]]} {channel set $c [lindex $u 0] [lindex $u 1]}
  2425. }
  2426. foreach budef {ap:btextl ap:btextc ap:bnotcl ap:bnotcc ap:bctcp ap:massjoin ap:brevdoor
  2427. ap:bpartmsg ap:bnickf ap:bcodes} {
  2428. append olm [lindex [split [lindex [split [channel get $c $budef]] 1] -] 0]
  2429. }
  2430. foreach lm [lsort -unique [split $olm ""]] {
  2431. if {[lsearch [binds mode] "* {\\\* -$lm} *"] == -1} {
  2432. bind mode - "* -$lm" [namespace current]::resetbtc
  2433. }
  2434. }
  2435. }
  2436.  
  2437. proc remr {} {
  2438. variable bred; variable apfp; variable ::botnick
  2439. puthelp "MODE $botnick -$apfp(rmode)"
  2440. putlog "\002AP\002: Removed +$apfp(rmode) from me."
  2441. set bred 0
  2442. }
  2443.  
  2444. proc lockc {c m tl ty} {
  2445. variable btclocked; variable notifyusers
  2446. if {![info exists btclocked($c)]} {set btclocked($c) 0}
  2447. if {!$btclocked($c)} {
  2448. dolock $c $m
  2449. if {$tl > 0} {
  2450. utimer $tl [list [namespace current]::btcunlock $c $m btclocked($c)]
  2451. } {utimer 90 [list [namespace current]::resetbtc * * * $c]}
  2452. set btclocked($c) 1
  2453. if {$btclocked(lnotc) != ""} {
  2454. puthelp "NOTICE $c :$btclocked(lnotc)"
  2455. }
  2456. putlog "\002AP\002: Locked $c due to $ty."
  2457. if {$notifyusers != {}} {foreach nuser $notifyusers {sendnote AP $nuser "$ty detected on $c."}}
  2458. }
  2459. }
  2460.  
  2461. proc dolock {c lm} {
  2462. set mode "MODE $c +"
  2463. foreach m [split $lm] {append mode "$m "}
  2464. putquick [string trim $mode] -next
  2465. }
  2466.  
  2467. proc resetbtc args {
  2468. variable btclocked
  2469. set btclocked([string tolower [lindex $args 3]]) 0
  2470. }
  2471.  
  2472. proc btcunlock {c ms lv} {
  2473. upvar [namespace current]::$lv locked
  2474. if {![info exists locked] || $locked} {set locked 0}
  2475. foreach mode [split $ms ""] {
  2476. if {[string equal "-" $mode]} {break}
  2477. if {[regexp $mode [lindex [split [getchanmode $c]] 0]]} {pushmode $c -$mode}
  2478. }
  2479. }
  2480.  
  2481. proc droneb {n u c bti pm bty mapr} {
  2482. variable drone
  2483. if {![string is integer -strict $pm]} {
  2484. punish $pm [list $n $u] $c [mapr $drone(kmsg) $mapr] $drone(wmsg) $bty $bti $drone(klmsg) $drone(ktime) $drone(ktype) [string tolower $u]:drone
  2485. } {
  2486. if {![punishing k:$n:$c $pm]} {putquick "KICK $c $n :[mapall [mapr $drone(kmsg) $mapr] $c 0]"}
  2487. }
  2488. putlog "\002AP\002: DRONE: Detected \002$n\002!\002[scan $u {%[^@]}]\002 on \002$c\002."
  2489. }
  2490.  
  2491. proc seqflood {f o s n u c pm bty bti sla} {
  2492. variable following
  2493. if {[invalid:apf $o $s]} {return 0}
  2494. set uhc $f:[string tolower $u:$c]
  2495. if {[regexp {textc|notcc} $f]} {
  2496. if {[info exists following($uhc)]} {set myo [lindex $following($uhc) 0]}
  2497. set i $sla ; set rsn {$myo chars}
  2498. } {set i 1; set rsn {$o lines}}
  2499. checkf $s $o $uhc $u $c $pm $n $rsn $bty $bti $f $i [expr {[info exists myo]?$myo:""}]
  2500. }
  2501.  
  2502. proc follow {s fv pun {v 1} {ty 0}} {
  2503. variable following
  2504. if {![info exists following($fv)]} {
  2505. set o $v
  2506. set t [clock clicks -milliseconds]
  2507. } {
  2508. foreach {o t} $following($fv) {break}
  2509. incr o $v
  2510. }
  2511. if {[set z [expr {([clock clicks -milliseconds]-$t)/1000.}]] >= $s} {
  2512. set o $v
  2513. set t [clock clicks -milliseconds]
  2514. }
  2515. set following($fv) [list $o $t]
  2516. if {$o >= $pun} {if {!$ty} {followrem following($fv)} ; return [expr {$z>=$s?0.0:$z}]}
  2517. return -1
  2518. }
  2519.  
  2520. proc pcount {v var} {
  2521. upvar [namespace current]::$var p
  2522. foreach {o t} $p {break}
  2523. set p [expr {[unixtime]-$t <= $v?[list [incr o] [unixtime]]:[list 1 [unixtime]]}]
  2524. }
  2525.  
  2526. proc punishing {i {s 0.25}} {
  2527. variable punishing
  2528. set s [expr {int($s*1000)}]
  2529. set i [string tolower $i]; set t [clock clicks -milliseconds]
  2530. if {[info exists punishing($i)] && $punishing($i) > $t} {set i 1} {
  2531. set punishing($i) [expr {$t+$s}]
  2532. set i 0
  2533. }
  2534. }
  2535.  
  2536. proc followrem fv {
  2537. upvar [namespace current]::$fv f
  2538. if {[info exists f]} {unset f}
  2539. }
  2540.  
  2541. proc Nfollow {t tl n u} {
  2542. upvar [namespace current]::$tl f
  2543. lappend f $n $u
  2544. utimer $t [list [namespace current]::Nfollowrem $tl $n $u]
  2545. }
  2546.  
  2547. proc Nfollowrem {tl n u} {
  2548. upvar [namespace current]::$tl bl
  2549. if {[info exists bl]} {
  2550. set bl [lreplace $bl [set i [lsearch -exact $bl $n]] $i]
  2551. set bl [lreplace $bl [set i [lsearch -exact $bl $u]] $i]
  2552. if {$bl == {}} {unset bl}
  2553. }
  2554. }
  2555.  
  2556. proc asb:queue {n t} {variable antispam; lappend antispam(q) $n $t}
  2557.  
  2558. proc mapall {s c b} {
  2559. string map [list %date [ctime [unixtime]] %chan $c %kcount [getkcount] %btime $b] $s
  2560. }
  2561.  
  2562. proc clonemap {k c} { string map [list %ic $c] $k }
  2563.  
  2564. proc mapr {m r} { string map [list %rate $r] $m }
  2565.  
  2566. proc getkcount {} {incr [namespace current]::NumKicks}
  2567.  
  2568. proc cgsplit off {
  2569. foreach {o s} [split $off :] {break}
  2570. expr {([info exists o]&&[info exists s])?[list $o $s]:{0 0}}
  2571. }
  2572.  
  2573. proc invalid:apf {o s} {
  2574. expr {![string is integer -strict $o] || $o <= 0 || ![string is double -strict $s] || $s <= 0}
  2575. }
  2576.  
  2577. proc icodes str { regexp {r:\d{1,3}\sb:\d{1,3}\su:\d{1,3}\sc:\d{1,3}} $str }
  2578.  
  2579. proc invalid:apc {n h c} {
  2580. variable exmptype
  2581. if {[isbotnick $n] || ![botisop $c] || [matchattr $h n|n $c]} {return 1}
  2582. set true 0
  2583. foreach t $exmptype {
  2584. switch -- [string tolower $t] {
  2585. "ops" {set true [isop $n $c]}
  2586. "voices" {set true [isvoice $n $c]}
  2587. "halfops" {set true [ishalfop $n $c]}
  2588. default {set e $t}
  2589. }
  2590. if {$true} {break}
  2591. if {[info exists e]&&[regexp {[+-].+[|&][+-].+} $e]} {
  2592. if {[set true [matchattr $h $e $c]]} {break}
  2593. } elseif {[info exists e]} {
  2594. error "Invalid exempt type ($e)."
  2595. }
  2596. }
  2597. set true
  2598. }
  2599.  
  2600. proc nap:chan {c cl} {
  2601. expr {!($cl == "*" || [lsearch -exact [split [string tolower $cl]] [string tolower $c]] != -1)}
  2602. }
  2603.  
  2604. proc masktype {nuh {t 3}} {
  2605. if {[scan $nuh {%[^!]!%[^@]@%s} n u h]!=3} {
  2606. error "Usage: masktype <nick!user@host> \[type\]"
  2607. }
  2608. if {$t == 10} {return *!$u@*}
  2609. if {$t == 11} {return $n!*@*}
  2610. if {[string match {[3489]} $t]} {set h [lindex [split [maskhost $h] @] 1]}
  2611. if {[string match {[1368]} $t]} {set u *[string trimleft $u ~]} elseif {[string match {[2479]} $t]} {set u *}
  2612. if {[string match {[01234]} $t]} {set n *}
  2613. set nuh $n!$u@$h
  2614. }
  2615.  
  2616. proc ww l {
  2617. set cur {}
  2618. foreach word [set l][unset l] {
  2619. if {[llength $cur]==10} {
  2620. lappend out $cur
  2621. set cur [list $word]
  2622. } { lappend cur $word }
  2623. }
  2624. lappend out $cur
  2625. }
  2626.  
  2627. proc cf str { string map {\017 ""} [stripcodes bcruag $str] }
  2628.  
  2629. proc queue {c b} {
  2630. variable apqueue
  2631. if {$apqueue(time) < 1} {putquick "MODE $c +b $b"} {
  2632. lappend apqueue([string tolower $c]) $b
  2633. }
  2634. }
  2635.  
  2636. proc mapXcmd {cmd n u c k ty ti} {
  2637. string map [list %reason $k %level [channel get $c ap:level] %btime [expr {$ti/60}] \
  2638. %ban [masktype $n!$u $ty] %nick $n %chan $c] $cmd
  2639. }
  2640.  
  2641. proc dumpqueues {} {
  2642. variable apqueue; variable Sec; variable antispam
  2643. if {[incr Sec]>59} {set Sec 0}
  2644. if {$apqueue(time) > 0 && $Sec % $apqueue(time) == 0} {
  2645. variable ::modes-per-line
  2646. foreach c [channels] {
  2647. if {![info exists apqueue([set c [string tolower $c]])] || $apqueue($c) == {}} {continue}
  2648. for {set i 0} {$i<[llength [set apqueue($c) [lsort -unique $apqueue($c)]]]} {incr i} {
  2649. set bans [lrange $apqueue($c) $i [incr i [expr {${modes-per-line}-1}]]]
  2650. putquick "MODE $c +[string repeat b [llength $bans]] [join $bans]" -next
  2651. }
  2652. set apqueue($c) {}
  2653. }
  2654. }
  2655. if {$Sec % 2 == 0 && [info exists antispam(idx)] && [valididx $antispam(idx)]} {
  2656. if {[info exists antispam(q)]} {
  2657. foreach {n t} $antispam(q) {
  2658. putdcc $antispam(idx) "privmsg $n :$t"
  2659. }
  2660. }
  2661. set antispam(q) {}
  2662. }
  2663. if {$Sec % 3 == 0} {
  2664. variable scanq
  2665. foreach {c l} [array get scanq] {
  2666. set i 0
  2667. foreach e $l {
  2668. foreach {n u h t} $e {break}
  2669. set scanq($c) [lrange $l [incr i] end]
  2670. bchansw $n $u $h $c $t
  2671. if {$i == 10} {break}
  2672. }
  2673. }
  2674. }
  2675. utimer 1 [namespace current]::dumpqueues
  2676. }
  2677.  
  2678. proc checkf {s o var u c pm n mapr bty bti ft {v 1} {myo ""}} {
  2679. upvar [namespace current]::$ft myvar
  2680. if {[set ts [follow $s $var $o $v]] != -1} {
  2681. if {$myo == ""} {set myo $v} {incr myo $v}
  2682. 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
  2683. }
  2684. }
  2685.  
  2686. 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"}}
  2687.  
  2688. proc cl s {
  2689. set is 0; set res [set tem ""]
  2690. foreach e [split $s] {
  2691. if {!$is} {
  2692. if {![regexp {^"} $e]} { lappend res $e } {
  2693. if {[regexp {"$} $e]} {lappend res [string range $e 1 end-1]} {
  2694. append tem "[string range $e 1 end] "
  2695. set is 1
  2696. }
  2697. }
  2698. } {
  2699. if {[regexp {"$} $e]} {
  2700. append tem [string range $e 0 end-1]
  2701. lappend res $tem ; set tem ""; set is 0
  2702. } {append tem "$e "}
  2703. }
  2704. }
  2705. set res
  2706. }
  2707.  
  2708. proc aplog str {
  2709. variable logkbs
  2710. lappend logkbs(logs) $str
  2711. }
  2712.  
  2713. proc unload type {
  2714. variable logkbs; variable antispam
  2715. foreach t {timer utimer} {
  2716. foreach ti [${t}s] {
  2717. if {[string match [namespace current]::* [lindex $ti 1]]} {kill$t [lindex $ti 2]}
  2718. }
  2719. }
  2720. if {[info exists logkbs(logs)]} {
  2721. set f [open $logkbs(file) w]
  2722. foreach log $logkbs(logs) { if {$log != ""} { puts $f $log } }
  2723. close $f
  2724. }
  2725. if {[info exists antispam(idx)] && [valididx $antispam(idx)]} {
  2726. putdcc $antispam(idx) "part ,"
  2727. killdcc $antispam(idx)
  2728. }
  2729. load unbind
  2730. namespace delete [namespace current]
  2731. putlog "\002A\002ll\002P\002rotection v4.7 successfully unloaded..."
  2732. }
  2733.  
  2734. if {[llength [channels]] == 0 && [llength [userlist]] == 0} {
  2735. bind evnt - loaded [namespace current]::load
  2736. } {
  2737. load
  2738. }
  2739. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement