Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # $Id: cloneflood.tcl, v4.24.b eggdrop-1.6.17 2005/06/29 01:22:47 Exp $
- # Begin - Mass Clone Join/Part and Revolving Door Protection v4.24.b
- # Build date: 21st June 2005
- # Last updated: 29th June 2005
- # Copyright © 1999-2005 awyeah (awyeah@awyeah.org)
- # This TCL script is designed to work with eggdrop v1.6.17 or higher
- #########################################################################
- # Mass Clone Join/Part and Revolving Door Protection v4.24.b #
- # #
- # #
- # Author: awyeah 29th June 2005 #
- # Email: awyeah@awyeah.org Build version 4.24.b #
- # Copyright © 2005 awyeah All Rights Reserved http://www.awyeah.org/ #
- #########################################################################
- # #
- # ####### #
- # PURPOSE #
- # ####### #
- # #
- # This script basically serves the purpose to prevent mass joining #
- # clones and botnets to join channels. This script detects fast joining #
- # parting clones and also detects for mass join/part, fast join/part, #
- # revolving door floods by clones. It also has additional supporting #
- # modules which gives it extra features to eliminate clones. This #
- # script is very efficient and can detect almost any kind of mass join, #
- # part and revolving door floods. #
- # #
- # This type of script is most wanted on channels being flooded by bots. #
- # I made this script to eliminate floods caused by clones and bots, #
- # since they are a nuisance and hard to deal with. Generally tsunami #
- # and avalanche floods are stopped and controlled by this script since #
- # this script detects clones as they join, so they have no time to #
- # implement a flood since they are detected on join. Tsunami and #
- # avalanche floods as described by the famous sentinel.tcl are rapid #
- # floods originating from single hosts with a variety of numerous #
- # control codes and characters embedded in them. #
- # #
- # This script can be run on almost any network on IRC because it does #
- # not utilize any network services. #
- # #
- #########################################################################
- # #
- # ########### #
- # DESCRIPTION #
- # ########### #
- # #
- # This script will make your eggdrop bot detect mass joining or parting #
- # clones and bots where the script is working on and will punish them #
- # immediately and effectively. #
- # #
- # This script also checks for revolving door floods, which are defined #
- # as continuous join/part floods normally containing part messages with #
- # a variety of control codes -- another way to flood a channel. #
- # #
- # The bot owner can select the punishment level for clones. Also kick #
- # messages can be defined and the clone nick kick counter can be #
- # selected to be switched on or off. #
- # #
- # Additionally this script has 3 supporting modules, which are optional #
- # to utilize. These three modules consist of detecting fast join/parts, #
- # excessive channel clones and suspected mass joining bots and clones. #
- # #
- #########################################################################
- # #
- # ######## #
- # FEATURES #
- # ######## #
- # #
- # (1) This script has three '3' basic types of detection systems: #
- # (a) Clone Join Detection System #
- # (b) Clone Part Detection System #
- # (c) Clone Join/Part Revolving Door Detection System #
- # #
- # (2) This script has '2' settings of channels to work on. #
- # (a) Can be activated to work on user defined channels. #
- # (b) Can be activated to work on all the channels the bot is on. #
- # #
- # (3) This script has various options for clone detection such as #
- # detecting for unresolved idents, matching idents, matching hosts #
- # or similar characters in nicks. #
- # #
- # (4) This script has separate op, voice, user flag, nick and mask #
- # exemption options. It also exempt users with unresolved idents. #
- # #
- # (5) This script has 4 levels of punishment for clones - all of them #
- # being filter kicks, 1 placing sticky bans, another placing global #
- # bans and the other two general server bans. #
- # #
- # (6) You can also select to use the scripts default kick messages when #
- # punishing clones or define your own kick messages and use them. #
- # #
- # (7) This script has an effective channel locking mechanism, which can #
- # lock channels to specific modes once a clone flood has been #
- # detected. Also a lock notification notice or message can be sent #
- # to the channel to notify the users and ops that the channel has #
- # been locked since clones have been detected. #
- # #
- # (8) This script also has a kick counter, which keeps a record of how #
- # many clones are kicked by the script. The number of clones kicked #
- # are be shown in the end of each kick message if the clone kick #
- # counter has been enabled. #
- # #
- # (9) Also available are 30 types of banmasks, which can be selected #
- # with varying wilcards. There are TEN '10' normal banmasks then 10 #
- # separate banmasks for the '?' wildcard and 10 separate banmasks #
- # for the '*' wildcard. All these banmasks enforce greater range #
- # for banning clones. #
- # #
- # (10) This script also has different speed queuing options for greater #
- # kicking performance. Speed queues improve scripts effectiveness. #
- # This script has 6 different types of speed queues to select from #
- # so the kicking and banning rate can be selected upon the bot #
- # owners will so the bot doesn't get Excess Flood or doesn't kick #
- # out clones very slowly. #
- # #
- # (11) Also this script has 3 precise modules which can be loaded and #
- # unloaded optionally. These 3 modules provide more enhancements #
- # when dealing with clones. #
- # (a) Clone Join/Part Scanner (Revolving door) #
- # (b) Excessive Clone Scanner (Clones in channel) #
- # (c) Suspected Mass Join Botnet Scanner (Botnet join) #
- # #
- # (12) The EXCESSIVE CLONE SCANNER module is one of most efficient #
- # scanning system used to eliminate excessive clones residing in #
- # channels. The scan be made to execute when a user join a channel #
- # or through a timer which is executed continuously after the #
- # defined number of minutes. #
- # #
- #########################################################################
- # #
- # ############ #
- # REQUIREMENTS #
- # ############ #
- # #
- # The following requirements must be taken into consideration before #
- # utilizing this script further: #
- # #
- # (Fields marked with a '*' are compulsory) #
- # #
- # (*1) You must be running EGGDROP version 1.6.17 or higher. #
- # (*2) You must have TCL v8.3 or higher installed on the system. #
- # (3) You must have the latest TCL PATCH LEVEL for v8.3 or above. #
- # #
- # To FIND the TCL VERSION and PATCH LEVEL your shell is running: #
- # (1) At your shell prompt type: tclsh #
- # (NOTE: Select step 'a' or step 'b' in the next instruction) #
- # (a) If you have several different versions of tcl installed on #
- # your system, pick the latest version which is installed. #
- # (i) At shell prompt type: tclsh8.3 (and go to step 2) #
- # (b) If you have only one version of pick that one or continue #
- # with 'tclsh' only if it doesn't say to use another name. #
- # (2) To find your tcl version type: info tclversion #
- # (3) To find your tcl patch level type: info patchlevel #
- # (4) To exit tclsh type: exit #
- # #
- #########################################################################
- # #
- # ############ #
- # INSTALLATION #
- # ############ #
- # #
- # This quick installation tutorial consists of 6 steps. Please follow #
- # all steps correctly in order to setup your script. #
- # #
- # #
- # (1) UNZIP the zipped file cloneflood.zip and you will get the script #
- # source file cloneflood.tcl. #
- # #
- # (a) If you are unzipping the file on MICROSOFT WINDOWS and then want #
- # to upload the TCL file onto your shell you can use 'WINZIP' or #
- # any other compatible windows unzipping software. #
- # #
- # (b) If you have uploaded the zipped file onto your shell and want to #
- # unzip it. You can use the TAR package available on your shell #
- # to unzip the script file: #
- # #
- # tar zxvf cloneflood.tar.gz #
- # #
- # (Note: This file is not gziped for UNIX operating systems so only #
- # WINZIP on Microsoft Windows can be used to unzip this file) #
- # #
- # #
- # (2) PLACE the unzipped file cloneflood.tcl file in your eggdrops #
- # '/scripts' folder along with your other TCL scripts. #
- # (Note: You have to upload the script file to your shell if you #
- # have unzipped it on your hard drive) #
- # #
- # (3) OPEN your eggdrops configuration (.conf) file and add a link at #
- # the bottom of the configuration file to the path of clone flood #
- # remover script, it would be: #
- # #
- # source scripts/cloneflood.tcl #
- # #
- # #
- # (4) SAVE your bots configuration file. #
- # #
- # (5) OPEN cloneflood.tcl and start configuring script variables. #
- # (START FROM: 'Start configuring variables from here!' #
- # END AT: 'Congratulations! Script configuration is now complete') #
- # #
- # (6) RESTART your eggdrop and your done! #
- # #
- #########################################################################
- # #
- # ######## #
- # VERSIONS #
- # ######## #
- # #
- # v4.24.b - Fixed a chanset bug encoutered for setting specific #
- # (29/06/05) channel join flood settings on rehash and restart. #
- # - Added a new bind on init-server and rehash to a timely #
- # delayed procedure for it to change specific channel #
- # settings for flood-join and to check if the bot is on the #
- # channels defined for it before the settings are modified. #
- # - Added a control code stripping filter clone:strip:codes #
- # for filtering control codes. If the eggdrop version is #
- # less than 1.6.17 use a string map and regsub filter and #
- # if the eggdrop version is greater than or equal to 1.6.17 #
- # then utilize the 'stripcodes' function. #
- # - Added more descriptive comments in the settings example #
- # and explanation fields. #
- # #
- # v4.18.b - Initial release of script. #
- # (21/06/05) #
- # #
- #########################################################################
- # #
- # ######## #
- # CONTACTS #
- # ######## #
- # #
- # (*) For any suggestions, comments, questions or bugs reports feel #
- # free to email me at: #
- # #
- # awyeah@awyeah.org #
- # #
- # #
- # (*) You can also contact me on MSN Messenger. My MSN ID is: #
- # #
- # awyeah@awyeah.org #
- # #
- # #
- # (*) You can also catch me on The DALnet Network: #
- # #
- # /server irc.dal.net:6667, Nick: awyeah #
- # Channels: #eggdrops, #awyeah, #dalusers, #eleet #
- # #
- # (*) Also I am mostly available on my own IRC Network: #
- # #
- # /server irc.awyeah.org:6667, Nick: awyeah #
- # #
- # #
- # Note: I have a lot of people bothering me for scripts which they #
- # HAVEN'T configured properly themselves. So please read ALL the #
- # comments provided while configuring the variables and make sure #
- # you follow the same standard format as given in examples when #
- # setting each variable in the script. #
- # #
- #########################################################################
- # #
- # ######### #
- # COPYRIGHT #
- # ######### #
- # #
- # This program is a free software; you can distribute it under the #
- # terms of the GNU General Public License under Section 1 as published #
- # by the Free Software Foundation; either version 2 of the license, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # WARNING: #
- # This program is protected by copyright law and international #
- # treaties. Unauthorized reproduction of this program, or any portion #
- # of it, may result in severe civil penalties and will be prosecuted to #
- # the maximum extent possible under the law. #
- # #
- #########################################################################
- # #
- # ######### #
- # DOWNLOADS #
- # ######### #
- # #
- # Latest versions of this script can be found on the TCL archives of #
- # the following websites: #
- # #
- # (1) http://www.awyeah.org/ #
- # (2) http://www.egghelp.org/ #
- # (3) http://www.tclscript.com/ #
- # #
- #########################################################################
- # #
- # ####### #
- # CREDITS #
- # ####### #
- # #
- # (*) I would like to thank 'Sir_Fz' aka Opposing who helped me with #
- # this script by giving me ideas on how to improve the coding, #
- # making the script execute faster and be more efficient. #
- # #
- # (*) I give credit to 'user' for the improved banmask selector used #
- # in the script with 30 types of banmasks to choose from. #
- # #
- # (*) Also I would like to thank 'demond' for helping me with a last #
- # minute easier and effective solution for removing duplicate #
- # elements found in a list for the join and part flood protection. #
- # #
- # (*) Special thanks to 'LoVeGirL' who did the beta testing for this #
- # script and reported any pre-release bugs and errors encountered. #
- # #
- # #
- # ./awyeah #
- # #
- #########################################################################
- ##############################################
- ### Start configuring variables from here! ###
- ##############################################
- #--------------------------------------#
- # SET CHANNEL ACTIVATION OPTIONS #
- #--------------------------------------#
- #Set the type of channels you would like this script to work on.
- #USAGE: [1/2] (1=USER DEFINED CHANNELS, 2=ALL CHANNELS THE BOT IS ON)
- #Use '1' for 'user defined channels' (Will detect clone floods only on the channels defined for the script)
- #Use '2' for 'all the channels' the bot is on. (Will detect clone floods on every channel the bot is opped on)
- set clone_channel_type "2"
- ###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '1'###
- #Set this if you have set the previous setting to '1' for user defined channels, if not then you do
- #not need to configure this option. Set the channels here on which this script would work.
- #USAGE: set clone_channels "#channel1 #channel2 #channel3" (separate each element with a space)
- set clone_channels "#awyeah"
- #------------------------------------#
- # SET CLONE DETECTION SETTINGS #
- #------------------------------------#
- #NOTE: Settings in this section of the script are very important and should be configured properly,
- #for the script to work efficiently.
- ### EXPLANATION OF MECHANISM ###
- #Settings listed below the define the 'number' of clone joins, parts in less than
- #a definite interval of 'seconds'. (Please read these carefully before script setup)
- #######################################################################################
- ##[1] A value for JOIN FLOOD '3:5' can be read as: ##
- ## - '3' or more joins by a single host in less than or equal to '5' seconds. ##
- #######################################################################################
- ##[2] A value for REVOLVIND DOOR FLOOD '2:3' can be read as: ##
- ## - '2' or more join/parts by a single host in less than or equal to '3' seconds. ##
- #######################################################################################
- ### RECOMMENDED SETTINGS ###
- #Please use the recommended settings or settings similar to the recommended
- #ones for optimal results. (If you don't understand leave them as they are)
- #FORMAT: <how_many_[joins|parts|revolving_doors]>:<how_many_seconds>
- ################################################################################
- ##[1] Values recommended for JOIN FLOOD are: ##
- ## a) 2:2 b) 2:3 c) 3:3 d) 3:4 e) 4:3 f) 4:5 g) 5:3 h) 5:4 ##
- ################################################################################
- ##[2] Values recommended for PART FLOOD are: ##
- ## a) 2:1 b) 2:2 c) 2:3 d) 3:2 e) 3:3 f) 4:2 g) 4:3 h) 5:3 ##
- ################################################################################
- ##[3] Values recommended for REVOLVING DOOR FLOOD are: ##
- ## a) 2:2 b) 2:3 c) 2:4 d) 3:2 e) 3:4 f) 4:3 g) 4:4 h) 4:5 ##
- ################################################################################
- #Any 'number' and 'time limit' setting under '5' seconds would be good enough.
- ### CLONE JOIN FLOOD SETTING ###
- #Set how many 'JOINS' from a single *!*@host in how many 'SECONDS' would trigger a clone JOIN FLOOD.
- #If you want to DISABLE join flood detection, then set this value as '0' or '0:0'.
- #(Please use recommended or similar to recommended values for best performance)
- #USAGE: set clone_join_flood "number_of_joins:number_of_seconds"
- set clone_join_flood "2:2"
- ### CLONE PART FLOOD SETTING ###
- #Set how many 'PARTS' from a single *!*@host in how many 'SECONDS' would trigger a clone PART FLOOD.
- #If you want to DISABLE part flood detection, then set this value as '0' or '0:0'.
- #(Please use recommended or similar to recommended values for best performance)
- #USAGE: set clone_part_flood "number_of_parts:number_of_seconds"
- set clone_part_flood "2:2"
- ### CLONE REVOLDING DOOR (JOIN/PART) FLOOD SETTING ###
- #Set how many clone 'JOIN/PARTS' from a single *!*@host in how many 'SECONDS' would trigger a clone
- #REVOLVING DOOR FLOOD. (Please use recommended or similar to recommended values for best performance)
- #If you want to DISABLE join/part flood detection, then set this value as '0' or '0:0'.
- #USAGE: set clone_joinpart_flood "number_of_joins/parts:number_of_seconds"
- set clone_joinpart_flood "2:3"
- #-----------------------------------------#
- # SET CLONE IDENT DETECION SETTINGS #
- #-----------------------------------------#
- #Set this if you only want to detect clones with similar a *!*host who have UNRESOLVED IDENTS (idents
- #with a '~' at the front). Mostly clones are loaded from open port proxies whose idents are not
- #resolved by IRC servers and are given an asterisk '~' in the front so they can be detected easily.
- #USAGE: [0/1] (0=DON'T CARE ABOUT IDENTS, 1=ONLY DETECT CLONES WITH UNRESOLVED IDENTS)
- #Use '0' if you want to make the bot check ALL types of idents.
- #Use '1' if you ONLY want the bot to check UNRESOLVED idents (idents with a '~' sign)
- #(Note: DISABLING this would be a good option so the bot can catch all types of clones)
- set clone_unresolved_ident "0"
- #-----------------------------------------#
- # SET CLONE FLOOD MODELOCK SETTINGS #
- #-----------------------------------------#
- #Set this if you want to ENABLE 'channel mode locking' when a clone join, part or revolving door
- #flood occurs. This mode lock enforcement can prevent text/notice, avalanche and tsunami floods
- #from botnets and clones joining in fast.
- #Usage: [0/1] (0=OFF, 1=ON)
- set clone_modelock_switch "1"
- ### IMPORTANT ###
- #All the variables below for 'mode lock settings block' should ONLY be set if channel mode locking
- #has been enabled, i.e. clone_modelock_switch has been set to '1', otherwise please ignore all
- #the mode lock settings block.
- #Set this to the 'PRIMARY MODE LOCK' you wish to lock on the channel. Also remember when the bot
- #is unlocking the channel this modelock will be checked, if it is present then only it will be
- #unlocked, otherwise since other ops might have removed it already the bot wouldn't unlock it then.
- #Important: Only '1' mode lock can be used for this setting - HIGH PRIORITY MODELOCK
- #USAGE: 'm', 'M', 'R' etc. (Please do not use +l or +k)
- set clone_primary_modelock "M"
- #Set this to the 'SECONDARY MODE LOCK' you wish to lock on the channel besides the primary modelock.
- #This is an additional mode lock supporting the primary modelock, if you wish to place additional
- #modelocks on the channel. This is an OPTIONAL setting, if you do not wish to place any additional
- #modelock besides the primary modelock then please leave this setting to by empty as "".
- #Important: More than '1' modelocks can also be used for this setting.
- #USAGE: 'MR', 'Rc', 'iRM' etc. (The +l or +k modelocks can be used)
- set clone_secondary_modelock "R"
- #Set the time in SECONDS after which the modelock will be removed -- only if the primary modelock
- #is found locked on the channel and has not been already removed by other channel ops yet.
- #USAGE: A value in between '3 - 10' seconds should be good enough.
- set clone_modelock_time "5"
- #-----------------------------------------------------#
- # SET CLONE FLOOD MODELOCK NOTIFICATION OPTIONS #
- #-----------------------------------------------------#
- ### IMPORTANT ###
- #All these variables should ONLY be set if you have chosen to lock the channel on a clone flood,
- #i.e. clone_modelock_switch has been set to '1', otherwise please ignore all the 'mode lock
- #notification setting block'.
- #Set this if you want to NOTIFY channel users when the channel has been locked due a clone flood
- #in the channel. This notification will be sent by the type of sending option selected -- next setting.
- #USAGE: [0/1] - (0=NO NOTIFICATION, 1=SEND NOTIFICATION)
- set clone_notify_switch "0"
- #Set the type of message sending option to the channel to use when sending the channel modelock
- #notification message. There are 3 different sending options available to choose from.
- #USAGE: [1/2/3] - (1=CHANNEL TEXT, 2=CHANNEL NOTICE, 3=CHANNEL OP-NOTICE)
- #(Note: The default option for this setting is: '2')
- set clone_notify_message_type "2"
- #Set the TYPE of NOTIFICATION MESSAGE to use here. If you wish to use the scripts default
- #notice message with its content or your own user-defined notification message.
- #USAGE: [1/2] - (1=SCRIPTS DEFAULT MESSAGE, 2=USER DEFINFED MESSAGE)
- #(If you have selected option '2' please set your message below)
- set clone_notify_type "1"
- ###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '2'###
- #Set the modelock notification MESSAGE content here, which will be sent to the channel when the
- #channel is locked. (If you do not specify a notice then the scripts default message will be used)
- set clone_notify_message "CLONE FLOOD: Channel has been locked to +$clone_primary_modelock$clone_secondary_modelock for $clone_modelock_time seconds."
- #-----------------------------------#
- # SET CLONE PUNISHMENT METHOD #
- #-----------------------------------#
- #Set the punishment level of removing the clones.
- #USAGE: [1/2/3/4] - [1=KICK, 2=KICK/BAN, 3=STICKY KICK/BAN, 4=GLOBAL KICK/BAN]
- #Use '1' to 'kick' all clones from the channel. (Minimal punishment)
- #Use '2' to 'kick and ban' all clones from the channel. (Normal punishment)
- #Use '3' to 'kick and ban' all clones using a STICKY ban from the bots banning mechanism. (Moderate punishment)
- #Use '4' to 'kick and ban' all clones using a GLOBAL ban from all channels where users with clone *!*@host's are found on with the bot. (Extreme punishment)
- #(NOTE: Options '3' and '4' will ignore all on op, voice, flag, nick and mask exemption options set)
- set clone_punishment_type "2"
- #-----------------------------------------#
- # SET CLONE PUNISHMENT BANMASK TYPE #
- #-----------------------------------------#
- #Select the type of banmask (from the list below) to use when banning clones.
- #-----------------------------------------------------------------------------
- #RECOMMENDED SETTINGS FOR BANMASK SELECTION:
- # - It is recommend that you use setting number '2'
- # - If you want a greater range you can use settings number '12' or '22'
- # - Else other options with large ranges are settings number '4', '14' or '24'
- #-----------------------------------------------------------------------------
- # Valid types are:
- # 0 - *!user@host.domain
- # 1 - *!*user@host.domain
- # 2 - *!*@host.domain
- # 3 - *!*user@*.domain
- # 4 - *!*@*.domain
- # 5 - nick!user@host.domain
- # 6 - nick!*user@host.domain
- # 7 - nick!*@host.domain
- # 8 - nick!*user@*.domain
- # 9 - nick!*@*.domain
- # You can also specify 2 types of wild carded banmasks, 10-19 and 20-29 which correspond
- # to the types 0-9 using this sub-rule.
- #
- # For the 10-19 range, if the user's host.domain is a [name/ip]:
- # name - It will replace the numbers in the host.domain with a '?' (question mark) wildcard.
- # ip - It will mask as normal, with no '?' replacements as does hostname.
- #
- # For the 20-29 range, if the user's host.domain is a [name/ip]:
- # name - It will replace the numbers in the host.domain with a '*' (star) wildcard.
- # ip - It will mask as normal, with no '*' replacements as does hostname.
- #
- # Explanations of the "?" and "*" wildcards:
- # - The character '?' matches any single character
- # - The character '*' matches 0 or more characters of any type
- #
- # * A character can be an alphabet, a number or any other symbol on the keyboard.
- #-----------------------------------------------------------------------------------
- # Example:
- # [Mask #2] awyeah!god@125-628-dialup.mindspring.com => *!*@125-628-dialup.mindspring.com
- # [Mask #12] awyeah!god@125-628-dialup.mindspring.com => *!*@???-???-dialup.mindspring.com
- # [Mask #22] awyeah!god@125-628-dialup.mindspring.com => *!*@*-*-dialup.mindspring.com
- set clone_banmask_type "12"
- #Set the amount of time in MINUTES to ban the clones for. This will be the time in minutes the
- #clones will remain banned from the channel and then removed if the ban is not set to be permanent.
- #(NOTE: If you want the ban to be PERMANENT, set this value as '0')
- #USAGE: Any positive integer or number
- set clone_bantime "1"
- #-----------------------------------#
- # SET CLONE EXEMPTION OPTIONS #
- #-----------------------------------#
- ### IMPORTANT - PLEASE READ THIS ###
- #When channel OP/VOICE exemption is enabled only current channel OPS/VOICES residing in the channel
- #would be exempted, since new joining-in ops/voices will take a second or so to get opped/voiced through
- #ChanServ or any other IRC service running on your network. All these exemption settings will be valid
- #if the clone punishment type is set to '1' or '2'. This is because 'sticky' and 'global' bans are bot's
- #internal banning mechanisms and the bot doesn't exempt ops/voices with its internal banning mechanism.
- #### EXEMPT CHANNEL OPERATORS FROM CLONE PUNISHMENTS ####
- #Set this if you want the bot to exempt all currently residing OPS even though their *!*@host matches
- #that of the clones banned. (This is a useful setting for not punishing 'OPS' matching clone hosts)
- #USAGE: [0/1] - (0=WILL NOT EXEMPT OPS, 1=WILL EXEMPT OPS)
- #If set to '0' channel OPS *will be kicked* if their *!*@host matches that of the clones.
- #If set to '1' channel OPS *will NOT be kicked* even if their *!*@host matches that of the clones.
- set clone_exempt_ops "1"
- #### EXEMPT CHANNEL VOICES FROM CLONE PUNISHMENTS ####
- #Set this if you want the bot to exempt all current residing VOICES even though their *!*@host matches
- #that of the clones banned. (This is a useful setting for not punishing 'VOICES' matching clone hosts)
- #USAGE: [0/1] - (0=WILL NOT EXEMPT VOICES, 1=WILL EXEMPT VOICES)
- #If set to '0' channel VOICES *will be kicked* if their *!*@host matches that of the clones.
- #If set to '1' channel VOICES *will NOT be kicked* even if their *!*@host matches that of the clones.
- set clone_exempt_voices "1"
- #### EXEMPT SPECIFIC USER FLAGS FROM CLONE PUNISHMENTS ####
- #Set this if you have enabled to exempt user's with certain 'user flags' on the bots userlist even
- #if their *!*@host matches that of the clones banned. Set the 'flags' for bot owners, masters, ops,
- #voices, friends etc which will be exempted from clone punishments.
- #USAGE: "mnf|mnf", "mn|o", "ovbf|-" etc. ("-" means no flags)
- #(Note: If you want to exempt no flags set this to '-|-')
- #FORMAT: "GLOBAL_FLAGS|CHANNEL_FLAGS"
- set clone_exempt_flags "mn|fbov"
- #### EXEMPT SPECIFIC NICKS FROM CLONE PUNISHMENTS ####
- #Set the list of nicks here you want the script to exempt even if their *!*@host matches that of the
- #clones banned. If any of these nicks are detected as clones then they will NOT be punished by the
- #clone detector. This is a good option for exempting certain nicks, characters or specific
- #keywords in nicks which you don't want the clone nick to punish.
- #(NOTE: Wildcards such as '*' and '?' can be used for each entry within the list)
- #Guidelines for ADDING and MODIFYING the nick exemption list:
- #-------------------------------------------------------------------------------
- #1) Please make sure every nick pattern is enclosed within " " quotation marks.
- #2) Please make sure each nick pattern is separated by a SPACE or is placed in a NEW LINE.
- #3) Please add suitable nick patterns, which effect small patterns, ranges, if you use wildcards.
- #4) You can add an entire nick, part of a nick or specific word of a nick to exempt.
- #5) You can also add a nick, with the '?' wildcard in it also or the '*' wildcard surrounding the nick.
- #-------------------------------------------------------------------------------------------------------
- #Explanation of the wildcards masks:
- # - The character '*' matches 0 or more characters of any type
- # - The character '?' matches any single character
- #-----------------------------------------------------------------
- #If you do not have any nick to exempt: set clone_exempt_nicks ""
- set clone_exempt_nicks {
- "nick1"
- "nick2"
- "nick3"
- }
- #### EXEMPT SPECIFIC MASKS FROM CLONE PUNISHMENTS ####
- #Set the list of masks here you want the script to exempt even if their *!*@host matches that of the
- #clones banned. If any of these masks are detected as clones then they will NOT be punished by the
- #clone detector. This is a good option for exempting certain masks, characters or specific
- #keywords in user masks which you don't want the clone detector to punish.
- #(NOTE: Wildcards such as '*' and '?' can be used for each entry within the list)
- #Guidelines for ADDING and MODIFYING the mask exemption list:
- #----------------------------------------------------------------------------------
- #1) Please remember all masks should are in the format: nick!ident@host.domain.com
- #2) Please make sure every mask pattern is enclosed within " " quotation marks.
- #3) Please make sure each mask pattern is separated by a SPACE or is placed in a NEW LINE.
- #4) Please add suitable mask patterns, which effect small patterns, ranges, if you use wildcards.
- #5) You can add an entire mask 'nick!user@host.domain' or a part of a mask to exempt.
- #6) You can also add a mask, with the '?' wildcard in it also or the '*' wildcard surrounding the mask.
- #-------------------------------------------------------------------------------------------------------
- #Explanation of the wildcards masks:
- # - The character '*' matches 0 or more characters of any type
- # - The character '?' matches any single character
- #-----------------------------------------------------------------
- #If you do not have any nick to exempt: set clone_exempt_masks ""
- set clone_exempt_masks {
- "nick!ident@host.domain.com"
- "*!*@host.domain.com"
- "*!*@*.domain.com"
- }
- #----------------------------------------#
- # SET CLONE PUNIHSMENT SPEED QUEUE #
- #----------------------------------------#
- ###NOTE: ONLY SET this block if PUNISHMENT TYPE has been SET to '1' or '2'###
- #Select the type of speed queue to use for kicking and banning the clones. This option has been
- #given because the bots banning and kicking mechanism has separate queues so it doesn't get flooded
- #of the server (Excess flood), since some queues are delayed and some are fast. There are 7 types of
- #queues available to select from depending upon the speed/rate you wish to remove the clones at.
- #------------------------------------------------------------------------------------------------
- #SPEED: The speed of listed queues is from '1 - 7' (given in the order: slowest ---> fastest)
- #USAGE: [1/2/3/4/6/7] (There are 7 types of queues available to choose from)
- #1 - puthelp (BAN: 1-2 second delayed queue, KICK: 1-2 second delayed queue)
- #2 - pushmode (BAN: Default speed queue, KICK: 1 combines number channel modes into one line as possible)
- #3 - putkick (BAN: Default speed queue, KICK: combines number of kicks into one line as possible)
- #4 - putserv (BAN: Default speed queue, KICK: Default speed queue)
- #5 - putquick (BAN: Fast speed queue, KICK: Fast speed queue)
- #6 - putdccraw (BAN: Fastest speed without queuing, KICK: Fastest speed without queuing)
- #(WARNING: Speed number 7 uses no queues, so it can flood your bot off the server at most times)
- #If you are not sure which speed queue to use, use the default speed queue i.e., speed number '4'.
- set clone_kick_queue "5"
- ###USE THIS 'ONLY' IF YOU HAVE SELECTED THE SPEED QUEUE OPTION TO BE '1', '2', '4' OR '5'###
- #Set this if you have only selected one of the 'puthelp', 'putserv' or 'putquick' speed queues. This
- #option will add a '-next' option in front of the speed queues making execution more faster. The '-next'
- #switch option pushes messages to the front of the queue so they are executed as faster as possible.
- #USAGE: [0/1] (0=DISABLE THE '-NEXT' OPTION, 1=ENABLE THE '-NEXT' OPTION)
- #Use '0' if you DO NOT wish to use the '-next' option in your speed queues.
- #Use '1' if you WISH to use the '-next' option in your speed queues for faster performance.
- #(NOTE: If you DO NOT use the '-next' option with the 1, 2, 4 or 5 speed queues the speed of placing
- #bans and the speed of kicking users can slow down a bit)
- set clone_queue_next_option "1"
- #-------------------------------------#
- # SETUP CLONE KICK MESSAGE TYPE #
- #-------------------------------------#
- #Set this if you would like to use your OWN kick messages for kicking clones or wish to use the
- #DEFAULT script kick messages for kicking clones. (The scripts default kick message is more informative)
- #(NOTE: If you want to define your own kick messages -- you will have to define 6 separate ones)
- #USAGE: [0/1] (O=SCRIPT DEFAULT KICK MESSAGES, 1=USER DEFINED KICK MESSAGES)
- set clone_kick_msg_type "0"
- ###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '1'###
- #Set these to your customizable user defined KICK messages. These kick messages will be shown when clone
- #are kicked out by the bot. These kick messages can contain all types of control codes, which are
- #supported on IRC such as colors, bolds, underlines, reverses and etc.
- #(NOTE: Listed below are '6' different types of kick messages for the clone detector)
- ###################################################################################################################################
- ##1) Set the kick message for MASS JOINING CLONES
- set clone_kick_user1_msg "Expulsado por ingreso de clones masivos"
- ###################################################################################################################################
- ##2) Set the kick message for MASS PARTING CLONES
- set clone_kick_user2_msg "Expulsado por ingreso de clones masivos"
- ###################################################################################################################################
- ##3) Set the kick message for MASS JOINING/PARTING CLONES, REVOLVING DOOR FLOOD
- set clone_kick_user3_msg "Expulsado por ingreso de clones masivos"
- ###################################################################################################################################
- ##4) Set the kick message for FAST JOINING/PARTING CLONES
- set clone_kick_user4_msg "Expulsado por ingreso de clones masivos"
- ###################################################################################################################################
- ##5) Set the kick message for EXCESSIVE RESIDING CLONES IN A CHANNEL
- set clone_kick_user5_msg "Expulsado por ingreso de clones masivos"
- ###################################################################################################################################
- ##6) Set the kick message for SUSPECTED MASS JOINING CLONE BOTNET
- set clone_kick_user6_msg "Expulsado por ingreso de clones masivos"
- ###################################################################################################################################
- #(HINT: The smaller the kick message and the less control codes the kick message contains the more faster kicks will be placed)
- #------------------------------#
- # SET CLONE KICK COUNTER #
- #------------------------------#
- #Set this if you wish to use a kick counter in every clone kick message. The number of kicks done
- #by the clone detector will be displayed at the end of each clone kick message.
- #(NOTE: The clone kick counter can slow down script's kicking performance)
- #USAGE: [0/1] (0=DISABLED, 1=ENABLED)
- set clone_kick_counter_type "0"
- ###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '1'###
- #Set the FILENAME and PATH here in which you want to store the clone nicks KICK COUNTING DATABASE in.
- #If you do not know which path to specify just type in a filename for your clone nick kick counting database.
- #CHECKING CURRENT PATH: To see your current directory path type 'pwd' at your shell prompt
- #(Note: The filename and extension [*.file] of the file can be named as anything)
- #Example: set clone_kick_counter_file "/usr/home/awyeah/eggdrop/clonekicks.dat"
- set clone_kick_counter_file "clonekicks.dat"
- ############################
- ##### OPTIONAL MODULES #####
- ############################
- #This script contains 3 additional modules, which can be turned ON and OFF depending upon the desired
- #will of the bot owner. The 3 modules are listed below as follows:
- ######################################################
- #[1] CLONE FAST JOIN/PART SCANNER (REVOLVING DOOR)
- #[2] EXCESSIVE CLONE SCANNER (CLONES IN CHANNEL)
- #[3] SUSPECTED MASS JOIN BOTNET SCANNER (BOTNET JOIN)
- ######################################################
- #(NOTE: As default all modules are set OFF)
- ############################################################
- #### (1) ADDITIONAL MODULE: CLONE FAST JOIN/PART SCANNER ###
- ############################################################
- #Set this if you want to enable punishing users who join and then quickly part a channel. This module
- #punishes users who do fast join/parts and revolving doors. This is a good protection against multiple
- #join/parts from a single host to eliminate bots who flood through part messages.
- #USAGE: [0/1] (0=DISABLED, 1=ENABLED)
- set clone_flyby_type "0"
- ### IMPORTANT ###
- #All the variables below for 'clone fast join/part scanner module' should ONLY be set if clone fast
- #join/part scanner module has been enabled, i.e. clone_flyby_type has been set to '1', otherwise please
- #ignore all the mode lock settings block.
- #Set the time in SECONDS for which the clone fast join/part scanner module will check for fast joins
- #and parts. If a join and part is done within this time then it would be counted as a revolving door
- #otherwise it will be detected as a normal join and part.
- #USAGE: Any positive integer (Recommended: 2 - 5 secs)
- set clone_flyby_time "2"
- #Set this if you only want to check for fast joins/parts which only contain a part message and have
- #joined and parted within the defined number of seconds which is defined above. Set the length of
- #the part message here. If the part message is less than this then it will not be counted as
- #as a fast join and part, but if it is equal or greater to this number then it will be detected.
- #TURN OFF: To turn off this setting, set the value as '0'
- #USAGE: Any positive integer or number
- set clone_flyby_reason_length "0"
- ######################################################
- ### (2) ADDITIONAL MODULE: EXCESSIVE CLONE SCANNER ###
- ######################################################
- #Set this if you want the bot to check the channel for clones. Clones will be detect based upon
- #similar *!*@hosts of users residing in the channel. This module can slow the bot down a bit based
- #upon which type of excessive clone checking is used.
- #USAGE: [0/1/2/3] - (0=OFF, 1=CHECK ON-JOIN, 2=FULL SCAN ON-JOIN, 3=FULL SCAN EVERY 'X' MINUTES)
- #Use '0' if you want to DISABLE checking the channel for clones. (DISABLE clone scanner module)
- #Use '1' if you want to scan a channel for clones for the user who joined in.
- #Use '2' if you want to fully scan a channel for all clones when a user joins in.
- #Use '3' if you want to fully scan a channel for all clones when a user joins in every 'x' minutes.
- #(Note: Setting '1' and '2' can be slow the bot down if the channel has a lot of joins and parts)
- set clone_remover_type "0"
- ###SET THIS ONLY IF THE ABOVE SETTING HAS BEEN SET TO '3'###
- #Set this to the time in MINUTES, which will be executed continuously for a scan of all the
- #clones in the channel. (NOTE: Please do not set this value very low as it can make the bot slow
- #if the channel has a lot of users residing)
- #USAGE: Any positive integer or number
- set clone_remover_time "10"
- #Set the maximum number of clones you would like to allow in a channel. If the limit of clones
- #exceeds this number then all the users with matching similar *!*@host's i.e. clones residing in
- #the channel would be removed from the channel.
- #USAGE: Any positive number greater than 1
- set clone_max_allowed "2"
- #################################################################
- ### (3) ADDITIONAL MODULE: SUSPECTED MASS JOIN BOTNET SCANNER ###
- #################################################################
- ###NOTE: THIS IS AN ADVANCED SETTING - IF YOU DON'T UNDERSTAND THEN DON'T ENABLE THIS###
- #Set this if you want to detect suspected mass joining botnet nicks. Suspected mass joining botnet
- #nicks will be detected through regular expression matching patterns defined in the list given below.
- #USAGE: [0/1/2] (0=OFF, 1=DETECT ALL TYPES OF IDENTS, 2=ONLY DETECT IDENTS WITH ASTERISKS '~')
- #Use '0' if you want to DISABLE checking the channel suspecting mass joining botnets.
- #Use '1' if you want to scan all idents for suspecting mass joining botnets.
- #Use '2' if you want to scan all unresolved idents (idents with '~') for suspecting mass joining botnets.
- #(Recommended: Setting '2' is recommended to be used)
- set clone_regexp_match_switch "0"
- #Set the maximum number of mass joining botnet clones you would like to allow to join in a channel.
- #If the number of clones exceeds this limit then all the detected patterns of nicks will be punished
- #from the channel. (Recommended: The recommended setting is '1')
- #USAGE: Any positive number
- set clone_regexp_clones "1"
- #Set the list of REGULAR EXPRESSION matching patterns that will detect randomly generated, drone,
- #botnet nicks which will be detected for mass joining clones. IF YOU DO NOT UNDERSTAND HOW TO EDIT
- #OR ADD NEW REGULAR EXPRESSION PATTERNS THEN PLEASE LEAVE THIS SETTING ALONE.
- set clone_regexp_matches {
- { [a-z]{1}[0-9]{1}[a-z]{1}[0-9]{1}[a-z]{1} }
- { [a-z]{2}[0-9]{2}[a-z]{2}[0-9]{2} }
- { [a-z]{1}[0-9]{4,8}[a-z]{1} }
- { [A-Z]{1}[0-9]{4,8}[A-Z]{1} }
- { [a-z]{2,8}-[0-9]{3,6} }
- { [a-z]{2,8}_[0-9]{3,6} }
- { [a-z]{2,8}[0-9]{3,6} }
- { [a-z]{4,}[0-9]{4,5} }
- { \[[a-z]{4,}\]-{3,} }
- { \[[a-z]{4,}\]_{3,} }
- { \[[a-z]{4,}\]{3,} }
- { \[[A-Z]{4,}\]{3,} }
- }
- #############################################################
- ### Congratulations! Script configuration is now complete ###
- #############################################################
- ##############################################################################
- ### Don't edit anything else from this point onwards even if you know tcl! ###
- ##############################################################################
- bind join - "*" clone:join:chan:type
- bind part - "*" clone:part:chan:type
- bind join - "*" clone:remover:module
- bind flud - join clone:join:flood:check
- bind evnt - rehash clone:delay:settings
- bind evnt - prerehash clone:clear:utimers
- bind evnt - init-server clone:delay:settings
- if {$clone_kick_counter_type == 1} { bind kick - "*" clone:kick:counter }
- if {($clone_remover_type == 3) && ![string match "*clone:remover:scan*" [timers]]} { timer $clone_remover_time clone:remover:scan }
- if {($clone_exempt_ops == 0) && ($clone_exempt_voices == 0)} { set clone_exempt_ops_voices "1"
- } elseif {($clone_exempt_ops == 0) && ($clone_exempt_voices == 1)} { set clone_exempt_ops_voices "2"
- } elseif {($clone_exempt_ops == 1) && ($clone_exempt_voices == 0)} { set clone_exempt_ops_voices "3"
- } elseif {($clone_exempt_ops == 1) && ($clone_exempt_voices == 1)} { set clone_exempt_ops_voices "4"
- } else { set clone_exempt_ops_voices "1" }
- proc clone:delay:settings {type} {
- timer 3 [list clone:modify:settings $type]
- }
- proc clone:modify:settings {type} {
- global clone_channel_type clone_channels clone_join_flood
- switch -- $clone_channel_type {
- 1 { set clone_working_channels [split $clone_channels] }
- 2 { set clone_working_channels [channels] }
- default { set clone_working_channels [channels] }
- }
- foreach clone_channel $clone_working_channels {
- if {[botonchan $clone_channel]} {
- channel set $clone_channel flood-join $clone_join_flood
- }
- }
- putlog "\002MASS JOIN/PART CLONE PROTECTION\002: Configuring channel flood-join settings."
- save
- }
- proc clone:join:chan:type {nick uhost hand chan} {
- global clone_channel_type clone_channels
- if {![isbotnick $nick] && [botisop $chan]} {
- switch -- $clone_channel_type {
- 1 {
- if {[lsearch -exact [split [string tolower $clone_channels]] [string tolower $chan]] != -1} {
- clone:join:check $nick $uhost $hand $chan
- }
- }
- 2 {
- if {[string equal "#" [string index $chan 0]]} {
- clone:join:check $nick $uhost $hand $chan
- }
- }
- default { putlog "\002MASS JOIN/PART CLONE PROTECTION\002: No channel type selected."; return 0 }
- }
- }
- }
- proc clone:part:chan:type {nick uhost hand chan {reason ""}} {
- global clone_channel_type clone_channels
- if {![isbotnick $nick] && [botisop $chan]} {
- switch -- $clone_channel_type {
- 1 {
- if {[lsearch -exact [split [string tolower $clone_channels]] [string tolower $chan]] != -1} {
- clone:part:check $nick $uhost $hand $chan $reason
- }
- }
- 2 {
- if {[string equal "#" [string index $chan 0]]} {
- clone:part:check $nick $uhost $hand $chan $reason
- }
- }
- default { putlog "\002MASS JOIN/PART CLONE PROTECTION\002: No channel type selected."; return 0 }
- }
- }
- }
- proc clone:join:check {nick uhost hand chan} {
- global clone_exempt_nicks clone_unresolved_ident clone_banmask_type clone_nicks_joinpart clone_regexp_clones
- global clone_nicks_join clone_modelock_switch clone_exempt_masks clone_bantime clone_regexp_match_switch
- global clone_join_flood clone_joinpart_flood clone_type1_count clone_type3_count clone_regexp_matches
- global clone_exempt_flags clone_flyby_type clone_flyby clone_flyby_time clone_punishment_type
- set nickuhost [string tolower $nick:$uhost]; set hostchan [lindex [split [string tolower $uhost] @] 1]:[string tolower $chan]
- if {($clone_unresolved_ident == 1) && ![string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { return 0 }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 0]]]} { foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] { if {[matchattr $hand $clone_exempt_global_flag]} { return 0 } } }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 1]]]} { foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] { if {[matchattr $hand $clone_exempt_local_flag $chan]} { return 0 } } }
- if {$clone_exempt_nicks != ""} { foreach clone_exempt_nick $clone_exempt_nicks { if {[string match -nocase $clone_exempt_nick $nick]} { return 0 } } }
- if {$clone_exempt_masks != ""} { foreach clone_exempt_mask $clone_exempt_masks { if {[string match -nocase $clone_exempt_mask "${nick}![getchanhost $nick $chan]"]} { return 0 } } }
- if {![info exists clone_type1_count($hostchan)]} { set clone_type1_count($hostchan) 0 }
- lappend clone_nicks_join($hostchan) $nickuhost
- if {[incr clone_type1_count($hostchan)] >= [lindex [split $clone_join_flood :] 0]} {
- if {$clone_modelock_switch == 1} { clone:channel:lock $chan }; set clone_number 0
- foreach person $clone_nicks_join($hostchan) {
- lappend clone_list $person
- }
- set clone_list [list]
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split [getchanhost $user $chan] @] 1] [lindex [split $uhost @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- set clone_list [lsort -unique $clone_list]
- if {[llength $clone_list] > 1} {
- foreach clone $clone_list {
- if {$clone_punishment_type == 2} {
- set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- if {[onchan [lindex [split $clone :] 0] $chan]} {
- incr clone_number; clone:punishment $clone $chan $clone_number [llength $clone_list] 1
- }
- }
- }
- utimer 1 [list clone:delay:check [lindex [split $uhost @] 1] $chan $clone_number [llength $clone_list] 1]
- }
- utimer [lindex [split $clone_join_flood :] 1] [list clone_expire_join $hostchan $nickuhost]
- if {![info exists clone_type3_count($hostchan)]} { set clone_type3_count($hostchan) 0 }
- lappend clone_nicks_joinpart($hostchan) $nickuhost
- if {[incr clone_type3_count($hostchan)] >= [expr [lindex [split $clone_joinpart_flood :] 0]*2]} {
- if {$clone_modelock_switch == 1} { clone:channel:lock $chan }
- foreach person $clone_nicks_joinpart($hostchan) {
- lappend clone_list $person
- }
- set clone_list [list]
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split [getchanhost $user $chan] @] 1] [lindex [split $uhost @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- foreach clone $clone_list {
- if {$clone_punishment_type == 2} {
- set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- if {[onchan [lindex [split $clone :] 0] $chan]} {
- clone:punishment $clone $chan 0 0 3
- }
- }
- utimer 1 [list clone:delay:check:flud [lindex [split $uhost @] 1] $chan 3]
- }
- utimer [lindex [split $clone_joinpart_flood :] 1] [list clone_expire_joinpart $hostchan $nickuhost]
- if {$clone_flyby_type == 1} {
- if {![info exists clone_flyby([string tolower $nick:$chan])]} {
- set clone_flyby([string tolower $nick:$chan]) 1
- }
- if {[info exists clone_flyby([string tolower $nick:$chan])]} {
- utimer $clone_flyby_time [list unset clone_flyby([string tolower $nick:$chan])]
- }
- }
- if {$clone_regexp_match_switch == 1} {
- foreach clone_regexp_match $clone_regexp_matches {
- if {[regexp {^$clone_regexp_match$} $nick]} {
- break; set clone_regexp_match_pattern $clone_regexp_match
- }
- }
- set clone_number 0; set clone_list [list]
- foreach user [chanlist $chan] {
- if {[regexp {^$clone_regexp_match_pattern$} $user]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- foreach person [chanlist $chan] {
- if {[string equal [lindex [split $uhost @] 1] [lindex [split [getchanhost $person $chan] @] 0]] && ([lsearch -exact [string tolower $clone_list] [string tolower $person]] == -1)} {
- lappend clone_list $person:[getchanhost $person $chan]
- }
- }
- if {[llength $clone_list] > $clone_regexp_clones} {
- foreach clone $clone_list {
- incr clone_number; set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next; clone:punishment $clone $chan $clone_number [llength $clone_list] 6
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- }
- } elseif {$clone_regexp_match_switch == 2} {
- foreach clone_regexp_match $clone_regexp_matches {
- if {[regexp {^$clone_regexp_match$} $nick]} {
- break; set clone_regexp_match_pattern $clone_regexp_match
- }
- }
- set clone_number 0; set clone_list [list]
- foreach user [chanlist $chan] {
- if {[regexp {^$clone_regexp_match_pattern$} $user] && [string equal "~" [string equal [string index [lindex [split [getchanhost $user $chan] @] 0] 0]]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- foreach person [chanlist $chan] {
- if {[string equal [lindex [split $uhost @] 1] [lindex [split [getchanhost $person $chan] @] 0]] && [string equal "~" [string equal [string index [lindex [split [getchanhost $person $chan] @] 0] 0]]] && ([lsearch -exact [string tolower $clone_list] [string tolower $person]] == -1)} {
- lappend clone_list $person:[getchanhost $person $chan]
- }
- }
- if {[llength $clone_list] > $clone_regexp_clones} {
- foreach clone $clone_list {
- incr clone_number; set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next; clone:punishment $clone $chan $clone_number [llength $clone_list] 6
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- }
- }
- }
- proc clone:part:check {nick uhost hand chan reason} {
- global clone_nicks_part clone_modelock_switch clone_exempt_masks clone_bantime clone_flyby_reason_length
- global clone_exempt_flags clone_flyby_type clone_flyby clone_flyby_time clone_punishment_type
- global clone_exempt_nicks clone_unresolved_ident clone_banmask_type clone_nicks_joinpart
- global clone_part_flood clone_joinpart_flood clone_type2_count clone_type3_count
- set nickuhost [string tolower $nick:$uhost]; set hostchan [lindex [split [string tolower $uhost] @] 1]:[string tolower $chan]
- if {($clone_unresolved_ident == 1) && ![string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { return 0 }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 0]]]} { foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] { if {[matchattr $hand $clone_exempt_global_flag]} { return 0 } } }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 1]]]} { foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] { if {[matchattr $hand $clone_exempt_local_flag $chan]} { return 0 } } }
- foreach clone_exempt_nick $clone_exempt_nicks { if {[string match -nocase $clone_exempt_nick $nick]} { return 0 } }
- foreach clone_exempt_mask $clone_exempt_masks { if {[string match -nocase $clone_exempt_mask "${nick}![getchanhost $nick $chan]"]} { return 0 } }
- if {![info exists clone_type2_count($hostchan)]} { set clone_type2_count($hostchan) 0 }
- lappend clone_nicks_part($hostchan) $nickuhost
- if {[incr clone_type2_count($hostchan)] >= [lindex [split $clone_part_flood :] 0]} {
- set clone_number 0
- foreach person $clone_nicks_part($hostchan) {
- lappend clone_list $person
- }
- set clone_list [list]
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split [getchanhost $user $chan] @] 1] [lindex [split $uhost @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- set clone_list [lsort -unique $clone_list]
- if {[llength $clone_list] > 0} {
- foreach clone $clone_list {
- if {$clone_punishment_type == 2} {
- set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- if {[onchan [lindex [split $clone :] 0] $chan]} {
- incr clone_number; clone:punishment $clone $chan $clone_number [llength $clone_list] 2
- }
- }
- }
- utimer 1 [list clone:delay:check [lindex [split $uhost @] 1] $chan $clone_number [llength $clone_list] 2]
- }
- utimer [lindex [split $clone_part_flood :] 1] [list clone_expire_part $hostchan $nickuhost]
- if {![info exists clone_type3_count($hostchan)]} { set clone_type3_count($hostchan) 0 }
- lappend clone_nicks_joinpart($hostchan) $nickuhost
- if {[incr clone_type3_count($hostchan)] >= [expr [lindex [split $clone_joinpart_flood :] 0]*2]} {
- if {$clone_modelock_switch == 1} { clone:channel:lock $chan }
- foreach person $clone_nicks_joinpart($hostchan) {
- lappend clone_list $person
- }
- set clone_list [list]
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split [getchanhost $user $chan] @] 1] [lindex [split $uhost @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- foreach clone $clone_list {
- if {$clone_punishment_type == 2} {
- set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- if {[onchan [lindex [split $clone :] 0] $chan]} {
- clone:punishment $clone $chan 0 0 3
- }
- }
- utimer 1 [list clone:delay:check:flud [lindex [split $uhost @] 1] $chan 3]
- }
- utimer [lindex [split $clone_joinpart_flood :] 1] [list clone_expire_joinpart $hostchan $nickuhost]
- if {$clone_flyby_type == 1} {
- if {[getchanjoin $nick $chan] >= [expr [clock seconds] - $clone_flyby_time]} {
- if {[string trim [string length $reason]] < $clone_flyby_reason_length} { return 0 }
- if {$clone_punishment_type == 2} {
- set clone_banmask [clone:banmask $nick!$uhost $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- if {[onchan $nick $chan]} {
- clone:punishment $nick:$uhost $chan 0 0 4
- }
- set clone_list [list]
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split [getchanhost $user $chan] @] 1] [lindex [split $uhost @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- if {[llength $clone_list] > 0} {
- foreach clone $clone_list {
- clone:punishment $nick:$uhost $chan 0 0 4
- }
- }
- utimer 1 [clone:delay:check:flud [lindex [split $uhost @] 1] $chan 4]
- }
- if {[info exists clone_flyby([string tolower $nick:$chan])]} {
- putquick "MODE $chan +b [clone:banmask $nick!$uhost $clone_banmask_type]" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- if {[info exists clone_flyby([string tolower $nick:$chan])]} {
- unset clone_flyby([string tolower $nick:$chan])
- }
- if {[onchan $nick $chan]} {
- clone:punishment $nick:$uhost $chan 0 0 4
- }
- set clone_list [list]
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split [getchanhost $user $chan] @] 1] [lindex [split $uhost @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- if {[llength $clone_list] > 0} {
- foreach clone $clone_list {
- clone:punishment $nick:$uhost $chan 0 0 4
- }
- }
- utimer 1 [clone:delay:check:flud [lindex [split $uhost @] 1] $chan 4]
- }
- }
- }
- proc clone:delay:check {mask chan number total type} {
- foreach clone [chanlist $chan] {
- if {[string equal -nocase $mask [lindex [split [getchanhost $clone $chan] @] 1]]} {
- incr number; incr total; clone:punishment $clone:[getchanhost $clone $chan] $chan $number $total $type
- }
- }
- }
- proc clone:delay:check:flud {mask chan type} {
- foreach clone [chanlist $chan] {
- if {[string equal -nocase $mask [lindex [split [getchanhost $clone $chan] @] 1]]} {
- clone:punishment $clone:[getchanhost $clone $chan] $chan 0 0 $type
- }
- }
- }
- proc clone:channel:lock {chan} {
- global clone_primary_modelock clone_secondary_modelock clone_modelock_time clone_channel_locked
- global clone_notify_switch clone_notify_message_type clone_notify_type clone_notify_message
- if {$clone_primary_modelock == ""} { set clone_primary_modelock m }
- if {![info exists clone_channel_locked($chan)] && ![string match *$clone_primary_modelock* [getchanmode $chan]]} {
- putquick "MODE $chan +$clone_primary_modelock$clone_secondary_modelock" -next
- utimer $clone_modelock_time [list putquick "MODE $chan -$clone_primary_modelock$clone_secondary_modelock" -next]
- utimer [expr $clone_modelock_time + 3] [list unset clone_channel_locked($chan)]
- set clone_channel_locked($chan) "locked"
- if {$clone_notify_switch == 1} {
- switch -- $clone_notify_message_type {
- 1 { set clone_notify "PRIVMSG $chan" }
- 2 { set clone_notify "NOTICE $chan" }
- 3 { set clone_notify "NOTICE @$chan" }
- default { set clone_notify "NOTICE $chan" }
- }
- if {$clone_notify_type == 1} { set clone_notify_string "$clone_notify :CLONE FLOOD: Channel has been locked to +$clone_primary_lockmode$clone_secondary_modelock for $clone_modelock_time seconds as suspected clones are detected."; putquick $clone_notify_string -next
- } elseif {($clone_notify_type == 2) && ($clonelocknotice != "")} { set clone_notify_string "$clone_notify :$clone_notify_message"; putquick $clone_notify_string -next
- } else { set clone_notify_string "$clone_notify :CLONE FLOOD: Channel has been locked to +$clone_primary_lockmode$clone_secondary_modelock for $clone_modelock_time seconds as suspected clones are detected."; putquick $clone_notify_string -next
- }
- }
- }
- }
- proc clone_expire_join {hostchan nickuhost} {
- global clone_type1_count clone_nicks_join
- incr clone_type1_count($hostchan) -1
- set clone_nicks_join($hostchan) [lreplace $clone_nicks_join($hostchan) [lsearch -exact $clone_nicks_join($hostchan) $nickuhost] [lsearch -exact $clone_nicks_join($hostchan) $nickuhost]]
- return
- }
- proc clone_expire_part {hostchan nickuhost} {
- global clone_type2_count clone_nicks_part
- incr clone_type2_count($hostchan) -1
- set clone_nicks_part($hostchan) [lreplace $clone_nicks_part($hostchan) [lsearch -exact $clone_nicks_part($hostchan) $nickuhost] [lsearch -exact $clone_nicks_part($hostchan) $nickuhost]]
- return
- }
- proc clone_expire_joinpart {hostchan nickuhost} {
- global clone_type3_count clone_nicks_joinpart
- incr clone_type3_count($hostchan) -1
- set clone_nicks_joinpart($hostchan) [lreplace $clone_nicks_joinpart($hostchan) [lsearch -exact $clone_nicks_joinpart($hostchan) $nickuhost] [lsearch -exact $clone_nicks_joinpart($hostchan) $nickuhost]]
- return
- }
- proc clone:remover:module {nick uhost hand chan} {
- global clone_banmask_type clone_punishment_type clone_bantime clone_unresolved_ident clone_channels
- global clone_channel_type clone_remover_type clone_max_allowed clone_exempt_flags clone_exempt_nicks clone_exempt_masks
- if {[isbotnick $nick] || ![botisop $chan] || ($clone_channel_type == 1) && ([lsearch -exact [split [string tolower $clone_channels]] [string tolower $chan]] == -1)} { return 0 }
- if {($clone_unresolved_ident == 1) && ![string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { return 0 }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 0]]]} { foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] { if {[matchattr $hand $clone_exempt_global_flag]} { return 0 } } }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 1]]]} { foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] { if {[matchattr $hand $clone_exempt_local_flag $chan]} { return 0 } } }
- foreach clone_exempt_nick $clone_exempt_nicks { if {[string match -nocase $clone_exempt_nick $nick]} { return 0 } }
- foreach clone_exempt_mask $clone_exempt_masks { if {[string match -nocase $clone_exempt_mask "${nick}![getchanhost $nick $chan]"]} { return 0 } }
- switch -- $clone_remover_type {
- 1 {
- set clone_list [list]; set clone_banmask [clone:banmask $nick!$uhost $clone_banmask_type]
- foreach user [chanlist $chan] {
- if {[string match -nocase *$clone_banmask* "${nick}![getchanhost $user $chan]"]} {
- lappend clone_list $user:$uhost
- }
- }
- if {[llength $clone_list] > $clone_max_allowed} {
- set clone_number 0
- foreach person $clone_list {
- if {$clone_punishment_type == 2} {
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- incr clone_number; clone:punishment $person $chan $clone_number [llength $clone_list] 5
- }; set clone_list ""
- }
- }
- 2 {
- set clone_list [list]
- foreach user [chanlist $chan] {
- foreach person [chanlist $chan] {
- if {[string match -nocase *[clone:banmask $person![getchanhost $person $chan] $clone_banmask_type]* "${user}![getchanhost $user $chan]"] && ![string equal -nocase $person $user]} {
- lappend clone_list $person:[getchanhost $person $chan]; set clone_banmask [clone:banmask $person![getchanhost $person $chan] $clone_banmask_type]
- }
- }
- if {[llength $clone_list] > $clone_max_allowed} {
- set clone_number 0
- foreach person $clone_list {
- if {$clone_punishment_type == 2} {
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- incr clone_number; clone:punishment $person $chan $clone_number [llength $clone_list] 5
- }
- }; set clone_list ""
- }; unset clone_list
- }
- default { return 0 }
- }
- }
- proc clone:remover:scan {} {
- global clone_remover_type clone_max_allowed clone_exempt_flags clone_exempt_nicks clone_exempt_masks
- global clone_remover_time clone_banmask_type clone_remover_type clone_unresolved_ident
- global clone_channel_type clone_channels clone_max_allowed clone_punishment_type
- switch -- $clone_channel_type {
- 1 { set channels [channels] }
- 2 { set channels [split $clone_channels] }
- default { return 0 }
- }
- set clone_list [list]
- foreach chan $channels {
- foreach user [chanlist $chan] {
- foreach person [chanlist $chan] {
- if {[info exists clone_ident]} { unset clone_ident }; if {[info exists clone_global_flag]} { unset clone_global_flag }; if {[info exists clone_local_flag]} { unset clone_local_flag }
- if {[info exists clone_nick]} { unset clone_nick }; if {[info exists clone_mask]} { unset clone_mask }
- if {[string match -nocase *[clone:banmask $person![getchanhost $person $chan] $clone_banmask_type]* "${user}![getchanhost $user $chan]"] && ![string equal -nocase $person $user]} {
- lappend clone_list $person:[getchanhost $person $chan]; set clone_banmask [clone:banmask $person![getchanhost $person $chan] $clone_banmask_type]
- } elseif {($clone_unresolved_ident == 1) && ![string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { set clone_ident 1
- } elseif {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 0]]]} { foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] { if {[matchattr $hand $clone_exempt_global_flag]} { set clone_global_flag 1 } }
- } elseif {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 1]]]} { foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] { if {[matchattr $hand $clone_exempt_local_flag $chan]} { set clone_local_flag 1 } }
- } elseif {$clone_exempt_nicks != ""} { foreach clone_exempt_nick $clone_exempt_nicks { if {[string match -nocase $clone_exempt_nick $nick]} { set clone_nick 1 } }
- } elseif {$clone_exempt_masks != ""} { foreach clone_exempt_mask $clone_exempt_masks { if {[string match -nocase $clone_exempt_mask "${nick}![getchanhost $nick $chan]"]} { set clone_mask 1 } }
- }
- if {![info exists clone_ident]} { set clone_ident 0 }; if {![info exists clone_global_flag]} { set clone_global_flag 0 }; if {![info exists clone_local_flag]} { set clone_local_flag 0 }
- if {![info exists clone_nick]} { set clone_nick 0 }; if {![info exists clone_mask]} { set clone_mask 0 }
- if {($clone_ident == 0) && ($clone_global_flag == 0) && ($clone_local_flag == 0) && ($clone_nick == 0) && ($clone_mask == 0) && ([llength $clone_list] > $clone_max_allowed)} {
- set clone_number 0
- foreach person $clone_list {
- if {$clone_punishment_type == 2} {
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- incr clone_number; clone:punishment $person $chan $clone_number [llength $clone_list] 5
- }
- }; set clone_list ""
- }; unset clone_list
- }
- }
- if {($clone_remover_type == 3) && ![string match "*clone:remover:scan*" [timers]]} { timer $clone_remover_time clone:remover:scan }
- }
- proc clone:punishment {clone chan number total type} {
- global clone_kick_user2_msg clone_banmask_type clone_bantime clone_kick_counter_type clone_kick_user6_msg
- global clone_kick_counter_file clone_punishment_type clone_exempt_ops_voices clone_kick_user1_msg
- global clone_kick_msg_type clone_kick_user3_msg clone_kick_user4_msg clone_kick_user5_msg
- global clone_unresolved_ident clone_exempt_flags clone_exempt_masks clone_exempt_nicks
- if {$clone_kick_counter_type == 1} {
- if {![file exists $clone_kick_counter_file]} {
- create:clone:kick:file $clone_kick_counter_file
- } else {
- set file [open $clone_kick_counter_file "r"]; set current_kicks [gets $file]
- if {$current_kicks == ""} { set current_kicks 1 }
- close $file; set clone_kicks $current_kicks
- }
- }
- set nick [lindex [split $clone :] 0]; set uhost [lindex [split $clone :] 1]
- set clone_banmask [clone:banmask [string map {: !} $clone] $clone_banmask_type]
- switch -- $type {
- 1 {
- switch -- $clone_kick_msg_type {
- 0 { set clone_kick_msg "$clone_kick_user1_msg" }
- 1 { set clone_kick_msg $clone_kick_user1_msg }
- default { set clone_kick_msg "clone_kick_user1_msg" }
- }
- }
- 2 {
- switch -- $clone_kick_msg_type {
- 0 { set clone_kick_msg "$clone_kick_user1_msg" }
- 1 { set clone_kick_msg $clone_kick_user2_msg }
- default { set clone_kick_msg "$clone_kick_user1_msg" }
- }
- }
- 3 {
- switch -- $clone_kick_msg_type {
- 0 { set clone_kick_msg "$clone_kick_user1_msg" }
- 1 { set clone_kick_msg $clone_kick_user3_msg }
- default { set clone_kick_msg "0,1 Clone Join/Part Flood 12,0 - 12Mass 2join/part revolving door flood 12detected 2from 12host 6$clone_banmask" }
- }
- }
- 4 {
- switch -- $clone_kick_msg_type {
- 0 { set clone_kick_msg "0,1 Excessive Clones 12,0 - Excessive 2clones residing 12in channel 12detected 2from 12host 6$clone_banmask" }
- 1 { set clone_kick_msg $clone_kick_user4_msg }
- default { set clone_kick_msg "0,1 Excessive Clones 12,0 - Excessive 2clones residing 12in channel 12detected 2from 12host 6$clone_banmask" }
- }
- }
- 5 {
- switch -- $clone_kick_msg_type {
- 0 { set clone_kick_msg "0,1 Fast Join/Part Flood 12,0 - Fast 2join/part flood 12detected 2from 12host 6$clone_banmask" }
- 1 { set clone_kick_msg $clone_kick_user5_msg }
- default { set clone_kick_msg "0,1 Fast Join/Part Flood 12,0 - Fast 2join/part flood 12detected 2from 12host 6$clone_banmask" }
- }
- }
- 6 {
- switch -- $clone_kick_msg_type {
- 0 { set clone_kick_msg "0,1 Suspected Mass Joining Clones 12,0 - Suspected 2ordered nick 12botnet 12detected 2from 12host 6$clone_banmask" }
- 1 { set clone_kick_msg $clone_kick_user6_msg }
- default { set clone_kick_msg "0,1 Suspected Mass Joining Clones 12,0 - Suspected 2ordered nick 12botnet 12detected 2from 12host 6$clone_banmask" }
- }
- }
- default { set clone_kick_msg "0,1 Clone Flood 12,0 - Mass 2join, join/part, revolving door, excessive clones 12flood 2from 12host 6$clone_banmask" }
- }
- if {$total > 1} { set clone_kick_msg "$clone_kick_msg -2 (Clone 12$number 2of 12$total2)" }
- if {[string match "*(Clone * of *)*" [clone:strip:codes $clone_kick_msg]]} {
- switch -- $clone_kick_counter_type {
- 0 { set clone_kick_msg $clone_kick_msg }
- 1 { set clone_kick_msg "$clone_kick_msg 2,0(Kick #$clone_kicks)" }
- default { set clone_kick_msg $clone_kick_msg }
- }
- } else {
- switch -- $clone_kick_counter_type {
- 0 { set clone_kick_msg $clone_kick_msg }
- 1 { set clone_kick_msg "$clone_kick_msg 2,0- (Kick #$clone_kicks)" }
- default { set clone_kick_msg $clone_kick_msg }
- }
- }
- set message $clone_kick_msg
- if {($clone_punishment_type == 1) || ($clone_punishment_type == 2)} {
- if {($clone_exempt_ops_voices == 1) || ($clone_exempt_ops_voices == 2) && ![isvoice $nick $chan] || ($clone_exempt_ops_voices == 3) && ![isop $nick $chan] || ($clone_exempt_ops_voices == 4) && ![isvoice $nick $chan] && ![isop $nick $chan]} {
- if {[info exists clone_ident]} { unset clone_ident }; if {[info exists clone_global_flag]} { unset clone_global_flag }; if {[info exists clone_local_flag]} { unset clone_local_flag }
- if {[info exists clone_nick]} { unset clone_nick }; if {[info exists clone_mask]} { unset clone_mask }
- if {($clone_unresolved_ident == 1) && [string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { set clone_ident 1 }
- if {([string trim [lindex [split $clone_exempt_flags |] 0]] != "-") && ([string trim [lindex [split $clone_exempt_flags |] 0]] != "")} {
- foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] {
- if {[matchattr [nick2hand $nick $chan] $clone_exempt_global_flag]} {
- break; set clone_global_flag 1
- }
- }
- }
- if {([string trim [lindex [split $clone_exempt_flags |] 1]] != "-") && ([string trim [lindex [split $clone_exempt_flags |] 1]] != "")} {
- foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] {
- if {[matchattr [nick2hand $nick $chan] $clone_exempt_local_flag $chan]} {
- break; set clone_local_flag 1
- }
- }
- }
- if {$clone_exempt_nicks != ""} {
- foreach clone_exempt_nick $clone_exempt_nicks {
- if {[string match -nocase $clone_exempt_nick $nick]} {
- break; set clone_nick 1
- }
- }
- }
- if {$clone_exempt_masks != ""} {
- foreach clone_exempt_mask $clone_exempt_masks {
- if {[string match -nocase *$clone_exempt_mask* "${nick}![getchanhost $nick $chan]"]} {
- break; set clone_mask 1
- }
- }
- }
- if {![info exists clone_ident]} { set clone_ident 0 }; if {![info exists clone_global_flag]} { set clone_global_flag 0 }; if {![info exists clone_local_flag]} { set clone_local_flag 0 }
- if {![info exists clone_nick]} { set clone_nick 0 }; if {![info exists clone_mask]} { set clone_mask 0 }
- if {($clone_ident == 0) && ($clone_global_flag == 0) && ($clone_local_flag == 0) && ($clone_nick == 0) && ($clone_mask == 0)} {
- do:clone:kick $nick $chan $message
- }
- }
- } elseif {$clone_punishment_type == 3} {
- newchanban $chan $clone_banmask clones $message $clone_bantime; return 0
- } elseif {$clone_punishment_type == 4} {
- newban $clone_banmask clones $message $clone_bantime; return 0
- } else {
- if {($clone_exempt_ops_voices == 1) || ($clone_exempt_ops_voices == 2) && ![isvoice $nick $chan] || ($clone_exempt_ops_voices == 3) && ![isop $nick $chan] || ($clone_exempt_ops_voices == 4) && ![isvoice $nick $chan] && ![isop $nick $chan]} {
- if {[info exists clone_ident]} { unset clone_ident }; if {[info exists clone_global_flag]} { unset clone_global_flag }; if {[info exists clone_local_flag]} { unset clone_local_flag }
- if {[info exists clone_nick]} { unset clone_nick }; if {[info exists clone_mask]} { unset clone_mask }
- if {($clone_unresolved_ident == 1) && [string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { set clone_ident 1 }
- if {([string trim [lindex [split $clone_exempt_flags |] 0]] != "-") && ([string trim [lindex [split $clone_exempt_flags |] 0]] != "")} {
- foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] {
- if {[matchattr [nick2hand $nick $chan] $clone_exempt_global_flag]} {
- break; set clone_global_flag 1
- }
- }
- }
- if {([string trim [lindex [split $clone_exempt_flags |] 1]] != "-") && ([string trim [lindex [split $clone_exempt_flags |] 1]] != "")} {
- foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] {
- if {[matchattr [nick2hand $nick $chan] $clone_exempt_local_flag $chan]} {
- break; set clone_local_flag 1
- }
- }
- }
- if {$clone_exempt_nicks != ""} {
- foreach clone_exempt_nick $clone_exempt_nicks {
- if {[string match -nocase $clone_exempt_nick $nick]} {
- break; set clone_nick 1
- }
- }
- }
- if {$clone_exempt_masks != ""} {
- foreach clone_exempt_mask $clone_exempt_masks {
- if {[string match -nocase *$clone_exempt_mask* "${nick}![getchanhost $nick $chan]"]} {
- break; set clone_mask 1
- }
- }
- }
- if {![info exists clone_ident]} { set clone_ident 0 }; if {![info exists clone_global_flag]} { set clone_global_flag 0 }; if {![info exists clone_local_flag]} { set clone_local_flag 0 }
- if {![info exists clone_nick]} { set clone_nick 0 }; if {![info exists clone_mask]} { set clone_mask 0 }
- if {($clone_ident == 0) && ($clone_global_flag == 0) && ($clone_local_flag == 0) && ($clone_nick == 0) && ($clone_mask == 0)} {
- putquick "MODE $chan +b $clone_banmask" -next
- do:clone:kick $nick $chan $message
- }
- }
- }
- }
- proc do:clone:kick {nick chan message} {
- global clone_kick_queue clone_queue_next_option
- switch -- $clone_kick_queue {
- 1 {
- switch -- $clone_queue_next_option {
- 0 { puthelp "KICK $chan $nick :$message" }
- 1 { puthelp "KICK $chan $nick :$message" -next }
- default { puthelp "KICK $chan $nick :$message" -next }
- }
- }
- 2 {
- switch -- $clone_queue_next_option {
- 0 { putserv "KICK $chan $nick :$message" }
- 1 { putserv "KICK $chan $nick :$message" -next }
- default { putserv "KICK $chan $nick :$message" -next }
- }
- }
- 3 {
- putkick $chan $nick $message
- }
- 4 {
- switch -- $clone_queue_next_option {
- 0 { putserv "KICK $chan $nick :$message" }
- 1 { putserv "KICK $chan $nick :$message" -next }
- default { putserv "KICK $chan $nick :$message" -next }
- }
- }
- 5 {
- switch -- $clone_queue_next_option {
- 0 { putquick "KICK $chan $nick :$message" }
- 1 { putquick "KICK $chan $nick :$message" -next }
- default { putquick "KICK $chan $nick :$message" -next }
- }
- }
- 6 { putdccraw 0 [string length "KICK $chan $nick :$message\n"] "KICK $chan $nick :$message\n" }
- default {
- switch -- $clone_queue_next_option {
- 0 { putquick "KICK $chan $nick :$message" }
- 1 { putquick "KICK $chan $nick :$message" -next }
- default { putquick "KICK $chan $nick :$message" -next }
- }
- }
- }
- }
- proc clone:channel:unban {mask chan} {
- if {[botisop $chan] && [ischanban $mask $chan]} {
- pushmode $chan -b $mask
- }
- }
- proc clone:clear:utimers {type} {
- foreach utimer [utimers] {
- if {[string match -nocase "*clone_*_count*" [lindex $utimer 1]]} {
- killutimer [lindex $utimer 2]
- }
- }
- }
- proc clone:join:flood:check {nick uhost hand chan} {
- global clone_channels clone_modelock_switch clone_kick_type clone_kick_msg_type clone_exempt_hosts clone_channel_type clone_banmask_type
- global clone_exempt_hosts clone_exempt_flags clone_exempt_ops clone_exempt_voices clone_unresolved_ident clone_punishment_type clone_bantime
- if {[isbotnick $nick] || ![botisop $chan] || ($clone_channel_type == 1) && ([lsearch -exact [split [string tolower $clone_channels]] [string tolower $chan]] == -1)} { return 1 }
- if {($clone_unresolved_ident == 1) && ![string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { return 1 }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 0]]]} { foreach clone_exempt_global_flag [split [string trim [lindex [split $clone_exempt_flags |] 0]] ""] { if {[matchattr $hand $clone_exempt_global_flag]} { return 1 } } }
- if {![string equal "-" [string trim [lindex [split $clone_exempt_flags |] 1]]]} { foreach clone_exempt_local_flag [split [string trim [lindex [split $clone_exempt_flags |] 1]] ""] { if {[matchattr $hand $clone_exempt_local_flag $chan]} { return 1 } } }
- if {$clone_exempt_nicks != ""} { foreach clone_exempt_nick $clone_exempt_nicks { if {[string match -nocase $clone_exempt_nick $nick]} { return 1 } } }
- if {$clone_exempt_masks != ""} { foreach clone_exempt_mask $clone_exempt_masks { if {[string match -nocase $clone_exempt_mask "${nick}![getchanhost $nick $chan]"]} { return 1 } } }
- if {$clone_modelock_switch == 1} { clone:channel:lock $chan }
- if {$clone_punishment_type == 2} {
- set clone_banmask [clone:banmask $nick!$uhost $clone_banmask_type]
- putquick "MODE $chan +b $clone_banmask" -next
- if {$clone_bantime > 0} { timer $clone_bantime [list clone:channel:unban $clone_banmask $chan] }
- }
- set clone_list [list]; set clone_number 0
- foreach user [chanlist $chan] {
- if {[string equal -nocase [lindex [split $uhost @] 1] [lindex [split [getchanhost $user $chan] @] 1]]} {
- lappend clone_list $user:[getchanhost $user $chan]
- }
- }
- foreach clone $clone_list {
- if {[llength $clone_list] > 1} {
- incr clone_number; clone:punishment $clone $chan $clone_number [llength $clone_list] 1
- } else {
- clone:punishment $clone $chan 0 0 1
- }
- }
- utimer 1 [list clone:delay:check:flud [lindex [split $uhost @] 1] $chan 1]; return 1
- }
- proc clone:strip:codes {string} {
- global numversion
- if {$numversion >= 1061700} {
- set string [stripcodes bcruag $string]
- } else {
- regsub -all -- {\003([0-9]{1,2}(,[0-9]{1,2})?)?} $string "" string
- set string [string map {"\017" "" "\037" "" "\002" "" "\026" "" "\006" "" "\007" ""} $string]
- }
- }
- proc clone:banmask [list name [list type $clone_banmask_type]] {
- if {[scan $name {%[^!]!%[^@]@%s} nick user host]!=3} {
- error "Usage: clone:banmask <nick!user@host> \[type\]"
- }
- if {![string is int -strict $type] || $type < 0 || $type > 29} {
- error "Invalid ban type."
- }
- set ip [string match {*[0-9]} $host]
- if {$type < 10 || $ip} {
- if {[string match {[3489]} [expr {$type%10}]]} {
- if $ip {
- set host [join [lrange [split $host .] 0 2] .].*
- } elseif {[string match *.*.* $host]} {
- set host *.[join [lrange [split $host .] end-1 end] .]
- }
- }
- } elseif {$type > 19} {
- regsub -all {[0-9]+} $host * host
- } else {
- regsub -all {[0-9]} $host ? host
- }
- set type [expr {$type%10}]
- if [string match {[1368]} $type] {
- set user *[string trimleft $user ~]
- } elseif {[string match {[2479]} $type]} {
- set user *
- }
- if [string match {[01234]} $type] {
- set nick *
- }
- return $nick!$user@$host
- }
- proc create:clone:kick:file {clonekickfile} {
- putlog "\[MASS JOIN/PART CLONE PROTECTION\] ERROR: The \002clone 'kick counter' file\002 does not exist!"
- putlog "Creating clone kick counter file: \002$clonekickfile\002"
- set file [open $clonekickfile "w"]
- puts $file 1; close $file
- }
- proc clone:kick:counter {nick uhost handle chan target reason} {
- global clone_kick_counter_file clone_kick_counter_type
- if {[isbotnick $nick] && ![isbotnick $target] && ($clone_kick_counter_type == 1)} {
- if {![file exists $clone_kick_counter_file]} {
- create:clone:kick:file $clone_kick_counter_file
- } elseif {[string match -nocase "*(Clone * of *)*" $reason]} {
- set file [open $clone_kick_counter_file "r"]
- set currentkicks [gets $file]; close $file
- set file [open $clone_kick_counter_file "w"]
- puts $file [expr $currentkicks + 1]; close $file
- }
- }
- }
- putlog "\[LOADED\] Mass Clone Join/Part and Revolving Door Protection v4.24.b by \002awyeah (awyeah@awyeah.org)\002"
- if {$clone_channel_type == 1} { putlog "ACTIVE: Mass Clone Join/Part and Revolving Door Protection is ENABLED on: \002[split [string tolower $clone_channels]]\002"
- } elseif {$clone_channel_type == 2} { putlog "ACTIVE: Mass Clone Join/Part and Revolving Door Protection is ENABLED on: \002All channels the bot is on\002"
- } else { putlog "\[UNLOADED\] Mass Clone Join/Part and Revolving Door Protection: \002No channel type selected.\002" }
- putlog "--------------------------------------------------------"
- putlog " MASS CLONE JOIN/PART PROTECTION - MAIN SCRIPT SETTINGS"
- putlog "--------------------------------------------------------"
- if {[string match *0* $clone_join_flood] || ($clone_join_flood == "")} {
- putlog "Clone join protection: \002Disabled\002"
- } else {
- putlog "Clone join protection: \002[lindex [split $clone_join_flood :] 0] or more joins in less than [lindex [split $clone_join_flood :] 1] seconds\002"
- }
- if {[string match *0* $clone_part_flood] || ($clone_part_flood == "")} {
- putlog "Clone part protection: \002Disabled\002"
- } else {
- putlog "Clone part protection: \002[lindex [split $clone_part_flood :] 0] or more parts in less than [lindex [split $clone_part_flood :] 1] seconds\002"
- }
- if {[string match *0* $clone_joinpart_flood] || ($clone_joinpart_flood == "")} {
- putlog "Clone revolving door protection: \002Disabled\002"
- } else {
- putlog "Clone revolving door protection: \002[lindex [split $clone_joinpart_flood :] 0] or more join/part cycles in less than [lindex [split $clone_joinpart_flood :] 1] seconds\002"
- }
- if {$clone_modelock_switch == 0} {
- putlog "Channel lock protection: \002Disabled\002"
- } elseif {$clone_modelock_switch == 1} {
- putlog "Channel lock protection: \002Enabled\002"
- if {$clone_primary_modelock != ""} {
- putlog "Channel mode lock: \002+$clone_primary_modelock$clone_secondary_modelock\002"
- } else {
- putlog "Channel mode lock: \002+m\002"
- }
- }
- if {$clone_notify_switch == 0} {
- putlog "Channel lock notification: \002Disabled\002"
- } elseif {$clone_notify_switch == 1} {
- putlog "Channel lock notification: \002Enabled\002"
- if {$clone_notify_message_type == 1} {
- putlog "Channel lock notification type: \002CHANNEL TEXT\002"
- } elseif {$clone_notify_message_type == 2} {
- putlog "Channel lock notification type: \002CHANNEL NOTICE\002"
- } elseif {$clone_notify_message_type == 3} {
- putlog "Channel lock notification type: \002CHANNEL OP-NOTICE\002"
- }
- }
- if {$clone_exempt_ops == 0} {
- putlog "Channel operators exemption: \002Disabled\002"
- } elseif {$clone_exempt_ops == 1} {
- putlog "Channel operators exemption: \002Enabled\002"
- }
- if {$clone_exempt_voices == 0} {
- putlog "Channel voices exemption: \002Disabled\002"
- } elseif {$clone_exempt_voices == 1} {
- putlog "Channel voices exemption: \002Enabled\002"
- }
- if {[string equal "-" $clone_exempt_flags] || [string equal "-|-" $clone_exempt_flags] || ($clone_exempt_flags == "")} {
- putlog "User flags exemption: \002Disabled\002"
- } else {
- putlog "User flags exemption: \002Enabled\002"
- putlog "User flags: \002$clone_exempt_flags\002"
- }
- if {$clone_banmask_type > 0} {
- if {[string equal "1" [string length $clone_banmask_type]]} {
- if {$clone_banmask_type == 0} {
- putlog "Banmask type: \002*!user@host.domain\002"
- } elseif {$clone_banmask_type == 1} {
- putlog "Banmask type: \002*!*user@host.domain\002"
- } elseif {$clone_banmask_type == 2} {
- putlog "Banmask type: \002*!*@host.domain\002"
- } elseif {$clone_banmask_type == 3} {
- putlog "Banmask type: \002*!*user@*.domain\002"
- } elseif {$clone_banmask_type == 4} {
- putlog "Banmask type: \002*!*@*.domain\002"
- } elseif {$clone_banmask_type == 5} {
- putlog "Banmask type: \002nick!user@host.domain\002"
- } elseif {$clone_banmask_type == 6} {
- putlog "Banmask type: \002nick!*user@host.domain\002"
- } elseif {$clone_banmask_type == 7} {
- putlog "Banmask type: \002nick!*@host.domain\002"
- } elseif {$clone_banmask_type == 8} {
- putlog "Banmask type: \002nick!*user@*.domain\002"
- } elseif {$clone_banmask_type == 9} {
- putlog "Banmask type: \002nick!*@*.domain\002"
- }
- } elseif {[string equal "2" [string length $clone_banmask_type]]} {
- if {[string equal "0" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002*!user@host.domain\002"
- } elseif {[string equal "1" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002*!*user@host.domain\002"
- } elseif {[string equal "2" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002*!*@host.domain\002"
- } elseif {[string equal "3" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002*!*user@*.domain\002"
- } elseif {[string equal "4" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002*!*@*.domain\002"
- } elseif {[string equal "5" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002nick!user@host.domain\002"
- } elseif {[string equal "6" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002nick!*user@host.domain\002"
- } elseif {[string equal "7" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002nick!*@host.domain\002"
- } elseif {[string equal "8" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002nick!*user@*.domain\002"
- } elseif {[string equal "9" [string index $clone_banmask_type 1]]} {
- set clone_display_banmask "Banmask type: \002nick!*@*.domain\002"
- }
- if {[string equal "1" [string index $clone_banmask_type 0]]} {
- set clone_banmask_wildcard "?"
- } elseif {[string equal "2" [string index $clone_banmask_type 0]]} {
- set clone_banmask_wildcard "*"
- }
- putlog "$clone_display_banmask \002(replacing numbers in the *!*@host with the '$clone_banmask_wildcard' wildcard)\002"
- }
- }
- if {$clone_punishment_type == 1} {
- putlog "Punishment type: \002Kick all clones from the channel\002"
- } elseif {$clone_punishment_type == 2} {
- putlog "Punishment type: \002Kick and ban all clones from the channel\002"
- } elseif {$clone_punishment_type == 3} {
- putlog "Punishment type: \002Kick and ban all clones from the channel - STICKY BAN\002"
- } elseif {$clone_punishment_type == 4} {
- putlog "Punishment type: \002Kick and ban all clones and users matching clones *!*@host from all channels found on matching with the bot - GLOBAL BAN\002"
- } else {
- putlog "Punishment type: \002Kick and ban all clones from the channel\002"
- }
- if {$clone_bantime == 0} {
- putlog "Ban time: \002PERMANENT\002"
- } else {
- putlog "Ban time: \002$clone_bantime minutes\002"
- }
- if {$clone_kick_msg_type == 1} {
- putlog "Kick messages: \002User defined\002"
- } else {
- putlog "Kick messages: \002Script defaults\002"
- }
- if {$clone_kick_counter_type == 0} {
- putlog "Kick counter: \002Disabled\002"
- } elseif {$clone_kick_counter_type == 1} {
- putlog "Kick counter: \002Enabled\002"
- }
- putlog "------------------------------------------------------"
- if {$clone_flyby_type == 0} {
- putlog "Flyby module: \002Disabled\002"
- } elseif {$clone_flyby_type == 1} {
- putlog "Flyby module: \002Enabled\002"
- putlog "Maximum flyby time: \002$clone_flyby_time seconds\002"
- if {$clone_flyby_reason_length > 0} {
- putlog "Flyby part message length: \002$clone_flyby_reason_length characters\002"
- } else {
- putlog "Flyby part message length: \002Disabled\002"
- }
- }
- putlog "------------------------------------------------------"
- if {$clone_remover_type == 0} {
- putlog "Clone remover module: \002Disabled\002"
- } elseif {$clone_remover_type == 1} {
- putlog "Clone remover module: \002Scan channel for clones on user joins\002"
- } elseif {$clone_remover_type == 2} {
- putlog "Clone remover module: \002Full channel scan for clones on user joins\002"
- } elseif {($clone_remover_type == 3) && ($clone_remover_time > 0)} {
- putlog "Clone remover module: \002Full channel scan for clones every $clone_remover_time minutes\002"
- }
- if {$clone_max_allowed > 0} {
- putlog "Maximum clones allowed: \002$clone_max_allowed\002"
- }
- putlog "------------------------------------------------------"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement