##############################################
### 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 drone nicks only on the channels defined for the script)
#Use '2' for 'all the channels' the bot is on. (Will detect drone nicks on every channel the bot is opped on)
set dronechantype "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 please
#leave this as it is or leave this as empty/blank. (Set the channels on which this script would work)
#USAGE: set dronechannels "#channel1 #channel2 #mychannel"
set dronechannels ""


#--------------------------------------#
#    SET ON OP DRONE NICK DETECTION    #
#--------------------------------------#

#Set this if you want the bot to scan all users for drone nicks in a channel when it gets opped.
#This setting is useful if the bot joins the channel, gets opped, so all drone nicks currently
#present in the channel can be detected and immediately removed by the bot.
#USAGE: [0/1] (0=NO SCAN ON OP, 1=SCAN ON OP)  (This setting is recommended to be enabled)
#Use '0' to prevent the bot from scanning channels when it gets opped.
#Use '1' to make the bot scan the channel for drone nicks when it gets opped.
set dronebotopchecktype "0"


#--------------------------------------------#
#    SET NICK CHANGE DRONE NICK DETECTION    #
#--------------------------------------------#

#Set this if you want the bot to check for drone nicks when users change their nicks on channels
#which the bot is monitoring for drone nicks. This setting is useful setting and would make
#the bot detect anyone, which has switched their nick to a random/drone nick.
#USAGE: [0/1] (0=NO CHECK ON NICK CHANGE, 1=CHECK ON NICK CHANGE)  (This setting is useful)
#Use '0' to prevent the bot from checking users who change their nicks.
#Use '1' to make the bot check users who change their nicks for drone nicks.
set dronenickchangecheck "1"


#----------------------------------------#
#    SET DRONE NICK DETECTION OPTIONS    #
#----------------------------------------#

#Set the minimum:maximum length of idents which should be used to detect drone nicks. User idents
#between these two ranges will be ONLY detected for drone nicks. Idents less than the first value
#and greater than the last value will NOT be scanned for drone nicks.
#(Note: The MAXIMUM ident length allowed on almost all IRCd's is not more than 10 -- so leave it as it is!)
#USAGE: set droneidentlength "MINIMUM_IDENT_LENGTH:MAXIMUM_IDENT_LENGTH"
set droneidentlength "4:10"


#Set the minimum:maximum length of nicks which should be used to detect drone nicks. Nicks
#between these two ranges will be ONLY detected for drone nicks. Nicks less than the first value
#and greater than the last value will NOT be scanned for drone nicks.
#(Note: The maximum nick length allowed on most IRCd's is not more than 32)
#USAGE: set dronenicklength "MINIMUM_NICK_LENGTH:MAXIMUM_NICK_LENGTH"
set dronenicklength "5:12"


#Set this if you only want to detect users with UNRESOLVED IDENTS (idents with and '~' at the front)
#for drone nicks. Mostly drone nick idents are not resolved by IRC servers so they can detected.
#USAGE: [0/1] (0=DON'T CARE ABOUT IDENTS, 1=ONLY DETECT 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 since more random nicks would be detected)
set droneunresolvedident "1"


#Set this if you only want to detect users with RANDOM IDENTS for drone nicks. Idents which
#match one or more of the patterns in the big list given below for the SEARCH MODULE or have no
#numbers and vowels present in their idents. (Please remember you enable this you should have
#random patterns in the big list below for "dronematches" for this setting to work)
#USAGE: [0/1] (0=DON'T CARE ABOUT IDENTS, 1=ONLY DETECT RANDOM IDENTS)
#Use '0' if you DO NOT bother if the ident is random or not.
#Use '1' if you ONLY want the bot to check RANDOM idents from drone nicks.
#(Note: DISABLING this would be a good option since more random nicks would be detected)
set dronerandomident "1"


#Set this if you only want exempt users which have '2 or more CONTINUOUSLY REPEATING ALPHABETS' or
#'2 or more CONTINUOUSLY REPEATING NUMBERS' in their nicks. These types of nicks are not considered
#random, as random nicks do not have occurrence of a same character repeated continuously.
#Examples: "awyeaah", "go000od", "yeahhhh", "baby00", "l00zEEr", "sweeti33h", "satan_666" etc
#USAGE: [0/1] (0=DON'T CARE ABOUT CONTINUOUS CHARS, 1=ONLY DETECT NICKS WITHOUT CONTINUOUS CHARS)
#Use '0' if you DO NOT bother if a character is being 3 times or more in a nick.
#Use '1' if you ONLY want the bot to detect nicks which do not have 3 or more characters continuously repeating.
#(Note: ENABLING this would definitely be a good option since random nicks do not contain continuous characters)
set dronenotrandom "1"


#-------------------------------------------#
#    SET DRONE NICK MODULE DETECTION TYPE   #
#-------------------------------------------#

#This script consists of '3' separate drone nick matching modules. Each module can be enabled or
#disabled separate depending upon the owners wish. The modules are listed as below:
#MODULE 1: DRONE NICK SCORE MATCHING MODULE.
#MODULE 2: DRONE NICK SEARCH PATTERN MODULE.
#MODULE 3: DRONE NICK REGULAR EXPRESSION MATCHING MODULE.
#----------------------------------------------------------
#Use '1' if you only want to enable the 'NICK SCORE' matching module.
#Use '2' if you only want to enable the 'NICK PATTERN' matching module.
#Use '3' if you only want to enable the 'REGULAR EXPRESSION' matching module.
#Use '4' if you want to enable the 'NICK SCORE' and 'NICK PATTERN' matching module.
#Use '5' if you want to enable the 'NICK SCORE' and 'REGULAR EXPRESSION' matching module.
#Use '6' if you want to enable the 'NICK PATTERN' and 'REGULAR EXPRESSION' matching module.
#Use '7' if you want to enable 'ALL three' matching modules. (Recommended)
#(Note: Try to enable all '3' modules if possible -- for better efficiency)
set dronemoduletype "7"


#-------------------------------------------------------#
#    SET THRESHOLD FREQUENIES FOR NICK SCORER MODULE    #
#-------------------------------------------------------#

#Set the THRESHOLD FREQUENIES for the NICK SCORER module here. Based on these numbers nicks or idents
#will be detected for randomness. These frequencies vary the threshold of the nick scorer module.
#NOTE: If the nick scorer module kicks a lot of innocent people without random/drone nicks or idents you
#can increase the score threshold, or if it misses a lot of random nicks/idents you can lower the threshold.
#(If you do not know how to use this setting, leave it as it is or use the default setting)
##################################################################
#-----------------------                                         #
# THRESHOLD FREQUENCY 1                                          #
#-----------------------                                         #
#(1) MINIMUM: 12                                                 #
#(2) MAXIMUM: 20                                                 #
#(3) DEFAULT: 17                                                 #
#USAGE: Increase/decrease value in multiples of '1' or more.     #
#EXAMPLES of values: 14, 16, 17, 18, 20                          #
set dronethresholdfrequency1 "17"
##################################################################
#-----------------------                                         #
# THRESHOLD FREQUENCY 2                                          #
#-----------------------                                         #
#(1) MINIMUM: 40                                                 #
#(2) MAXIMUM: 80                                                 #
#(3) DEFAULT: 50                                                 #
#USAGE: Increase/decrease value in multiples of '5' only.        #
#EXAMPLES of values: 45, 50, 55, 60, 65                          #
set dronethresholdfrequency2 "50"
##################################################################
#WARNING: Going VERY LOW below the default threshold value can   #
#cause CATASTROPHE and the bot can start kicking innocent users. #
##################################################################
#RECOMMENDATIONS:                                                #
#                                                                #
#LOW VALUE LIMITS:                                               #
#(1) For FREQUENCY 1: Setting lower than 14 can make the bot     #
#                     detect a lot of innocent users for random  #
#                     nicks and idents.                          #
#(2) For FREQUENCY 2: Setting lower than 45 can make the bot     #
#                     detect a lot of innocent users for random  #
#                     nicks and idents.                          #
#                                                                #
#HIGH VALUE LIMITS:                                              #
#(1) For FREQUENCY 1: Setting higher than 18 can make the bot    #
#                     not detect crucial random nicks or idents. #
#                                                                #
#(2) For FREQUENCY 2: Setting higher than 18 can make the bot    #
#                     not detect crucial random nicks or idents. #
##################################################################


#--------------------------------------------------#
#    SET SEARCH MODULE DRONE NICK MATCHING LIST    #
#--------------------------------------------------#

#Set random drone nick matching keywords for the SEARCH module.
#Guidelines for modifying the random pattern matching list for drone nicks:
#----------------------------------------------------------------------------
#1) Please DO NOT include VOWELS (a,e,i,o,u) since drone nicks seldomly contain vowels.
#2) Please make sure LENGTH of matching patters does not go BELOW 2.
#3) Please make sure every pattern enclosed within "" quotation marks.
#4) Please make sure each pattern is separated by a SPACE.
#5) When adding new patterns make sure they are not already covered by old patterns.
#6) You can add CAPITAL or LOWER case match patterns, since case is ignored while matching.
#-------------------------------------------------------------------------------------------
#NOTE: Most random and drone nick patterns have already been added. If you feel like
#you do not know how to modify these then please DO NO EDIT this list.
#-----------------------------------------------------
#LIST OF PATTERNS FOR MATCHING RANDOM AND DRONE NICKS
set dronematches {
"lx" "lk" "jw" "gf" "gv" "gz" "qb" "qc" "qd" "qf" "qg" "qh" "qk" "qm" "qn" "qp" "qj"
"qr" "qs" "qt" "qw" "qv" "qx" "qz" "xd" "xf" "xg" "xh" "xk" "xm" "xn" "xq" "xr" "xt"
"xv" "xz" "zb" "zc" "zd" "zf" "zh" "zm" "zq" "zr" "zt" "zv" "zx" "kz" "lx" "vb" "vf"
"vg" "vh" "vk" "vm" "vn" "vq" "vx" "vw" "wj" "ql" "qy" "xb" "xc" "xj" "xl" "xp" "xs"
"xw" "zg" "zj" "zk" "zl" "zn" "zp" "zs" "zw" "zx" "zy" "vc" "vd" "wx" "vp" "vs" "vt"
"vp" "vy" "vz" "wq" "wx" "wz" "lkm" "jwm" "bgb" "bgp" "dfg" "zxc" "cvb" "sdsf" "sdf"
"dsfg" "sgd" "hgf" "lkm" "ljn" "lfdw" "lfq" "jzx" "jcx" "kpq" "cq" "tnw" "gsfg" "dsdf"
"dsdg" "dsdh" "dsds" "lpqs" "yc" "yf" "yk" "yq" "yw" "hdn" "zqs" "nbq" "jmj" "jkj" "jkp"
"hzk" "fdg" "zfg" "lvfz" "lxd" "dtk" "hng" "klg" "kcn" "tcd" "mhw" "rfd" "fns" "lkj" "znh"
"jqd" "vdv" "sdv" "nkd" "jxf" "hxl" "qjj" "nzw" "slmk" "jzc" "jch" "xfn" "vzh" "zjd" "cgj"
"xrp" "npv" "zls" "vkw" "qmr" "jkp" "zwc" "btg" "nxm" "kkw" "fgq" "mfm" "hlk" "jmh" "dfgsd"
"cbq" "dfg" "sdg" "yng" "wyx" "krc" "zrt" "hgc" "sfgf" "ghk" "lhg" "hfd" "tjk" "hfgs" "dgsg"
"djgh" "jlf" "dgt" "hgds" "gsfd" "dshf" "fhk" "tfgs" "jmhf" "grqw" "wdcs" "gyrz" "pwc" "ghdfs"
"qsj" "lhj" "dgy" "wpj" "fzm" "blc" "kqb" "mnh" "tns" "xpl" "lcv" "bph" "hqg" "cdg" "dkr" "grs"
"wld" "vxz" "gcg" "nks" "njk" "knj" "lpm" "mjt" "jtb" "cxf" "tdx" "gkn" "lwp" "gks" "wnh" "xsg"
"vqz" "kkj" "kpk" "lqs" "lqr" "ftg" "xcg" "gjl" "dwn" "nxf" "vml" "lcb" "tpv" "vhc" "wfx" "mhj"
"grz" "jdz" "yxd" "dqm" "mrg" "wrf" "gjh" "qfp" "nrw" "fxt" "fjq" "bvh" "bqn" "ply" "wsx" "qgf"
"bhk" "jvb" "skj" "jvb" "yzq" "jxd" "wpx" "jfl" "kmr" "gmk" "ktk" "klk" "wgh" "cqs" "ptc" "hkd"
"jpm" "znr" "dch" "qmh" "vjg" "ghk" "trb" "bng" "plt" "tsg" "fxq" "xlg" "kjv" "kgk" "bgw" "kgx"
"lgg" "hxw" "hzx" "dgs" "vht" "hsh" "sqv" "xyb" "kxl" "sfn" "ryc" "nmc" "xjt" "tqz" "ypn" "qyg"
"wgh" "lkj" "krj" "kmb" "wfr" "wrw" "hpv" "fqm" "fqy" "hfh" "ftr" "fdg" "jfg" "gjh" "hwk" "shs"
"wnk" "lxc" "dfh" "kjv" "cfd" "mvg" "rdc" "dfg" "ghj" "bny" "fxr" "fgh" "bvn" "krv" "zlj" "chc"
"fnm" "hjk" "ksh" "sdb" "sbd" "znd" "wmc" "qpc" "sfk" "nrg" "fpt" "wlp" "fhw" "twz" "dsm" "sjd"
"jjb" "klp" "kkc" "skx" "szf" "tft" "tds" "whb" "gxq" "kkj" "tnh" "cbl" "fds" "blk" "wds" "wsx"
"rhc" "csv" "qxr" "qvr" "nxl" "xlc" "fgy" "ydl" "bgt" "kpk" "bjy" "tvq" "kjw" "qxc" "xcq" "cqb"
"lyf" "gct" "pgh" "sbd" "sbd" "ykl" "swl" "vys" "syz" "qtl" "tlq" "vnf" "khw" "cln" "krr" "krx"
"xpy" "lyx" "yxh" "dpd" "dbz" "kkp" "yyz" "dvv" "fhd" "fdl" "dlh" "dsg" "sgn" "sbn" "sfx" "xym"
"bdl" "qnx" "xxq" "qny" "dph" "kjg" "rgt" "hxv" "rdf" "pyf" "byn" "sfy" "chc" "jbs" "kdg" "jrk"
"yrf" "rfp" "vwx" "nrc" "rtk" "xlx" "nmw" "hjg" "yjs" "jsf" "jwj" "ytt" "fth" "xnf" "tgf" "kcb"
"sfd" "zlv" "vpj" "dpg" "pgg" "pnj" "njs" "tgt" "jkf" "kxj" "xzt" "rdy" "yry" "rys" "ptq" "ykn"
"wqh" "dth" "thv" "nzp" "zpt" "xzl" "xcz" "czw" "xnp" "npy" "ypj" "bfj" "hqx" "xbz" "xyl" "xlw"
"yrf" "rfp" "pvw" "dgr" "ryh" "rtk" "xlx" "yjh" "jsf" "tcx" "wjk" "ytt" "fth" "xnf" "fdz" "tgf"
"kcb" "cwj" "dsf" "sdg" "zpn" "njs" "tgt" "smp" "jkf" "jbj" "htz" "xzt" "rdy" "gvw" "rys" "ysr"
"ptq" "ykn" "wqh" "nzp" "zpt" "yzl" "xcz" "kcz" "zwv" "jtw" "xyy" "xnp" "npy" "bfj" "xyl" "ylv"
"ylw" "hft" "tjk" "gtc" "dzr" "hdy" "ynm" "cfm" "zmv" "hdf" "dfq" "zmr" "pjx" "yqm" "mzg" "gng"
"zdg" "npr" "rzx" "wgm" "gmk" "ygs" "png" "dwb" "jqy" "kjw" "ywd" "drj" "hhf" "jwt" "mxl" "pjx"
"xyb" "lzf" "flj" "sth" "shj" "rmn" "dkl" "tnm" "cqy" "qyv" "gfh" "cgs" "sfr" "bpb" "pbw" "wgn"
"yqt" "qtr" "jsd" "whd" "hds" "bln" "tzn" "bch" "chs" "wvn" "khz" "mjs" "frn" "nsb" "vqm" "xhs"
"dlx" "dvb" "kbt" "csn" "ksb" "kpk" "mwz" "sdg" "lks" "shg" "rbd" "rqz" "bkv" "ckp" "kpw" "wgs"
"hjd" "pyl" "sht" "fby" "wlk" "psm" "vkm" "dfs" "yyf" "fpr" "krh" "rhj" "hpx" "pxq" "qmh" "mhy"
"pcv" "cvj" "bzf" "zxr" "lrn" "nqq" "jct" "tnm" "sln" "gsm" "tth" "xrf" "dlz" "zdq" "ggc" "rhp"
"kbz" "zfv" "fxq" "xqf" "bhd" "bcx" "cxt" "wzv" "vzp" "cqy" "gqx" "qxt" "pqf" "rhj" "mxf" "ysb"
"qwj" "jtr" "wvn" "gcl" "jrw" "tkl" "klg" "lsq" "fkn" "vbh" "bht" "rtv" "vhq" "smk" "kzq" "bhz"
"srl" "lrf" "lrb" "cnt" "dfd" "fdf" "ryh" "tjh" "qxj" "tkv" "ghx" "prk" "qby" "cml" "pwq" "dxt"
"tdm" "skf" "dgs" "fds" "hfz" "hfp" "pvn" "lxf" "xfd" "jbf" "bfr" "fth" "cwc" "fdc" "cxw" "hpb"
"bcd" "tlk" "khq" "bvp" "gvz" "xzy" "hvq" "spf" "vhs" "rdf" "kgt" "kzw" "wvn" "xcq" "lfq" "gfg"
"kfk" "snj" "njm" "xnd" "dmx" "mxj" "rhr" "rpq" "yvz" "rhw" "tjc" "fgw" "fyx" "xlg" "lgf" "lkf"
"pfk" "nhv" "lfr" "sxq" "lsh" "jdt" "nfk" "pfz" "zcp" "wpq" "hmj" "qgl" "ypw" "dwf" "fvp" "rfm"
"lfv" "kmh" "kbs" "xln" "dls" "rlc" "cgy" "mkt" "gzq" "nvj" "vjk" "nbp" "kny" "ylz" "vzx" "lks"
"sdj" "hzn" "nkc" "wnp" "sph" "rsk" "knr" "qzr" "wjm" "mwp" "bjj" "ply" "syf" "vwh" "hyl" "mcl"
"qmj" "gnw" "rtd" "cnt" "phw" "vrx" "rdy" "vfl" "rwb" "gpg" "wqd" "fns" "dpx" "jkh" "hkj" "fdr"
"bgs" "dgs" "mfy" "ktk" "pfm" "ktp" "cfk" "bdr" "gvp" "pzq" "gnr" "zsc" "chn" "ndr" "fgj" "jxn"
"tps" "vgl" "hgj" "jhm" "sgw" "tqs" "ybq" "twb" "mzz" "ykh" "hdl" "rlc" "jmg" "qpq" "tmr" "rns"
"rnr" "pqv" "qvh" "dpb" "fbw" "fxf" "fqd" "sdf" "gsd" "sdg" "lgk" "wmh" "sbl" "ltz" "gvr" "rjn"
"kym" "ymh" "qdw" "gsg" "vhf" "pkm" "tdb" "rkm" "vls" "gqt" "qtz" "tzs" "dmg" "kjm" "lqk" "kxk"
"tjg" "jgf" "twr" "vnz" "cdg" "lmc" "qsg" "qvw" "qxr" "mxv" "xvp" "xyv" "vpm" "sgf" "fpd" "gwl"
"fnv" "krl" "fbn" "tqh" "fdq" "kzx" "nrz" "zjr" "bwy" "whl" "tnz" "hwd" "vfm" "lxq" "yxl" "tdb"
"wcn" "nmb" "kcv" "qxj" "xjq" "rqd" "lnc" "xbr" "rsj" "jwm" "vkt" "vxh" "tkw" "fsd" "fsf" "gzn"
"wnv" "ndr" "snm" "hsn" "mhd" "jkh" "jnt" "dvw" "vmh" "tgl" "ljn" "ntj" "psf" "knh" "ndj" "bjz"
"zyf" "dyn" "rfd" "djl" "dgq" "bqf" "qfj" "rhx" "kfm" "mvk" "gqr" "rqn" "qnz" "zjx" "dky" "xtv"
"vck" "dsx" "xlf" "rzm" "gfb" "kcq" "cqp" "dbx" "vzf" "fpw" "lmh" "fkt" "wnr" "rcd" "lmg" "wmv"
"fgn" "cxv" "vbj" "wcp" "pfd" "cns" "lnm" "mnt" "nzl" "lqx" "bxd" "dsw" "xmn" "dqt" "qtj" "dgh"
"vdx" "rmk" "dbr" "brp" "hsk" "lnr" "nrt" "knl" "lpg" "pws" "wsb" "pqd" "dyn" "lrd" "njk" "jkz"
"btj" "znv" "nxq" "bfk" "fkl" "psf" "cfh" "hyj" "wct" "pnb" "ckp" "jvg" "dvf" "fdn" "ftb" "rkj"
"qxl" "wdr" "rwp" "wpl" "gst" "wvg" "gzn" "mzb" "zbg" "bgc" "gcy" "cyw" "ywd" "jkn" "knw" "wrc"
"bzh" "zdh" "dhm" "lbn" "gfp" "slk" "dqm" "bmt" "fkz" "kld" "wwc" "bkr" "nrt" "gqt" "qtz" "vgr"
"ndm" "msw" "nsm" "mgv" "twz" "nxw" "kdn" "vxm" "jrb" "bfp" "fpg" "qfy" "fym" "hjb" "pmh" "mhx"
"btg" "bsr" "dsw" "jhx" "fdf" "ygc" "cjf" "jxm" "mxd" "rtg" "hdh" "hgh" "stl" "ldw" "ylc" "xng"
"jkd" "pmb" "rkh" "khd" "lxj" "cfs" "lsf" "zfg" "fgx" "cwd" "bzw" "wsg" "pqd" "njn" "jnb" "rby"
"byh" "rph" "phz" "fzp" "fzs" "ctw" "fhd" "dbt" "nsj" "jdh" "cnt" "mbn" "crh" "rhk" "pfj" "jsg"
"dsf" "fds" "jhf" "ljn" "nwx" "gzy" "zyn" "qzl" "bhv" "rht" "tdm" "sdf" "dfd" "ptw" "wtz" "yqb"
"bwg" "kyx" "cjp" "dzh" "zqj" "klq" "hxm" "xmr" "lnv" "vrg" "ynt" "gty" "ptk" "ctk" "tkv" "twl"
"jtg" "gsk" "dms" "dvr" "rhc" "wgp" "pnb" "bfz" "zyb" "djr" "rlz" "xrq" "rqs" "lnr" "hpf" "spc"
"cgz" "cpm" "nyw" "wxf" "jvs" "lbm" "nrd" "mjk" "xzl" "qys" "wky" "kyz" "rpx" "xcb" "mzr" "zrn"
"xmh" "wlm" "zyh" "bkh" "dpr" "ndh" "tvx" "xnr" "jgh" "rcq" "kwd" "dph" "hdg" "dgs" "tqz" "zhr"
"rbn" "cwt" "sjg" "lfg" "fgm" "zvg" "qvc" "wjc" "cht" "ndb" "gbt" "jvd" "sfz" "szl" "jvm" "zjr"
"rxg" "qfs" "gbq" "skj" "wvc" "xzd" "zdb" "fbk" "ksv" "bvn" "bft" "tnr" "vfs" "slh" "vzb" "kbl"
"blv" "jkh" "knl" "plg" "vhd" "tqn" "nwk" "bwj" "dfw" "psn" "ntq" "bhm" "lgh" "mtf" "tfd" "mtk"
}


#Set the type of search pattern detection (module #2) and integrity level checking to use while
#detecting random and drone nicks. There are 4 options available to choose from. These options
#are in the manner: 1 - 4 (minimum checking ---> maximum checking).
#USAGE: [1/2/3/4] (1=NO VOWELS, 2=NO VOWELS & MATCH NICK, 3=NO VOWELS & MATCH IDENT, 4=NO VOWELS & MATCH NICK/IDENT)
#Use '1' to check if 'no vowels' are present in a nick
#Use '2' to check if 'no vowels' are present in a nick or if 'search list pattern matches the nick'
#Use '3' to check if 'no vowels' are present in a nick or if 'search list pattern matches the ident'
#Use '4' to check if 'no vowels' are present in a nick or if 'search list pattern matches the nick' or the 'ident'.
set dronesearchpatterntype "4"


#--------------------------------------------------#
#    SET DRONE NICK SPECIAL CHARACTER EXEMPTION    #
#--------------------------------------------------#

#Set this if you want to only detect nicks WITHOUT special characters. Nicks with special characters
#such as, [, ], {, }, \, _, ^ etc will not be detected for drone nicks, since randomly generated
#drone nicks normally do not contain characters such characters. Special characters are non-alphabetical,
#non-numerical, characters leftover on the keyboard that can be used in nicknames.
#USAGE: [0/1] (0=DON'T CARE ABOUT SPECIAL CHARS, 1=ONLY DETECT NICKS WITH SPECIAL CHARS)
#Use '0' if you want the bot to detect drones for all types of nicks.
#Use '1' if you want the bot to ONLY detect nicks which DO NOT have special characters.
#(Note: If you have selected option '1' you can set your special characters below)
set dronespecialcharstype "1"


###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '1'###
#Set the special characters here, which if detected in a nickname, that nickname will
#be exempted from drone nick checking. The current special characters available can be:
#SPECIAL CHARACTERS: [, ], {, }, \, /, _, |, -, `, ^ (only any of these can be used)
#-------------------------------------------------------------------------------------
#1) Please make sure each character is placed within quotation "" marks.
#2) Only one character can be placed inside one quotation mark.
#3) Please make sure every pattern is separated by a SPACE.
#4) Please make sure you add an EXTRA "\\\" 3 slashes ONLY in front of the [, ] and \ characters.
#------------------------------------------------------------------------------------------------
#(NOTE: If you do not now how to modify this setting, leave it as it is)
#Please remove the characters from the list, which you do not wish to detect for drone nicks.
set dronespecialchars { "{" "}" "\\\[" "\\\]" "-" "_" "^" "`" "|" "/" "\\\\" }


#---------------------------------------#
#    SET DRONE NICK PUNISHMENT LEVEL    #
#---------------------------------------#

#Select the punishment level type for random or drone nicks.
#USAGE: [1/2/3/4/5/6] (1=KICK, 2=FILTER KICK, 3=KICK/BAN, 4=FILTER KICK/BAN, 5=STICKY KICK/BAN, 6=GLOBAL KICK/BAN)
#Use '1' to 'kick' that user from the channel.
#Use '2' to 'kick' that user and everyone matching the user's *!*@host.domain from the channel.
#Use '3' to 'kick and ban' that user from the channel.
#Use '4' to 'kick and ban' that user and everyone matching the user's *!*@host.domain from the channel.
#Use '5' to 'kick ban' that user using a STICKY ban from the bots ban list.
#Use '6' to 'kick ban' that user using a GLOBAL ban from all channels where the user is found on with the bot.
#(NOTE: Options '5' and '6' will ignore all on op, voice, flag, nick and mask exemption options set)
set dronepunishtype "3"


#----------------------------------------#
#    SET DRONE NICK SPEED QUEUE LEVEL    #
#----------------------------------------#

#Select the type of speed queue to use for kicking and banning the drone. The bots banning
#and kicking system has queues so it doesn't get flooded of the server, some queues are delayed
#and some are fast. There are 7 types of queues available to select from depending upon the speed
#you wish to remove the random and nick drone. These queues a have variety of speeds and functions.
#---------------------------------------------------------------------------------------------------
#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 - pushqueue  (BAN: Combines bans into one line as possible, KICK: Combines kicks into one line as possible)
#5 - putserv  (BAN: Default speed queue, KICK: Default speed queue)
#6 - putquick  (BAN: Fast speed queue, KICK: Fast speed queue)
#7 - 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 fast speed queue i.e. number 6.
set dronekickbanqueue "6"


###USE THIS 'ONLY' IF YOU HAVE SELECTED THE SPEED QUEUE OPTIONS TO BE '1', '5' OR '6'###
#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 queues making commands execute 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 2, 3 or 4 speed queues, the speed of placing bans and
#the speed of kicking users can slow down a bit)
set dronequeuenextoption "1"


###USE THIS 'ONLY' IF YOU HAVE SELECTED THE SPEED QUEUE OPTIONS TO BE '2', '3' OR '4'###
#Set this if you have only selected one of the 'pushmode', 'putkick' or 'pushqueue' speed queues. This
#'flushmode' option is called directly after a pushmode, a putquick has been executed. The flushmode
#option forces all previously pushed channel mode changes or kicks to be sent to the server, instead
#of when the script is finished, to allow maximum number of modes and kicks to be sent in a single line.
#USAGE: [0/1] (0=DISABLE THE FLUSHMODE OPTION, 1=ENABLE THE FLUSHMODE OPTION)
#Use '0' if you DO NOT wish to call the 'flushmode' option in your speed queues.
#Use '1' if you WISH to call the 'flushmode' option in your speed queues for faster performance.
#(Note: If you DO NOT call flushmode with the 2, 3 or 4 speed queues, the speed of placing bans and
#the speed of kicking users can slow down a bit)
set dronequeueflushmodeoption "1"


#-----------------------------------#
#    SET DRONE NICK BANMASK TYPE    #
#-----------------------------------#

#Select the type of banmask to use when banning the
#(Note: Options '2' and '4' in the punishment type, work on this same banmask)
# 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 dronebanmasktype "2"


#Set the amount of time in minutes to ban the user for IN MINUTES. This will
#be the time in minutes the user will remained banned for from the channel.
#(NOTE: If you want the ban to be PERMANENT, set this value as '0')
#USAGE: Any positive integer or number greater than zero
set dronebantime "60"


#-----------------------------------------#
#    SET DRONE NICK MODE LOCK SETTINGS    #
#-----------------------------------------#

#Set this if you want to ENABLE 'channel mode locking' when a clone join, part, cycle or mass
#join flood occurs. This mode lock enforcement can prevent text/notice and avalanche floods
#from botnets and clones. (This setting is the same for mass join flood and clone floods)
#Usage: [0/1] (0=OFF, 1=ON)
set dronelockswitch "1"

### IMPORTANT ###
#All the variables below for 'mode lock settings block' should ONLY be set if channel mode
#locking has been enabled, i.e. dronelockswitch 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 won'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 dronemlock1 "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 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 dronemlock2 "MR"

#Set the time in SECONDS after which the modelocks will be removed, if the primary modelock
#is found on the channel and has not been already removed by other channel ops.
#USAGE: A value from '3 to 10' seconds should be fine on most channels.
set droneremovelock "5"


#-----------------------------------------#
#    SET MODE LOCK NOTIFICATION OPTIONS   #
#-----------------------------------------#

### IMPORTANT ###
#All these variables should ONLY be set if you have chosen to lock the channel, i.e. dronelockswitch
#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 drone
#nick which has joined. This notification will be sent by NOTICING the channel.
#USAGE: [0/1] - (0=NO NOTIFICATION, 1=SEND NOTIFICATION)
set dronelocknoticeswitch "1"

#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 dronelocknoticetype "2"


###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '2'###
#Set the NOTICE MESSAGE, content which will be noticed to the channel when the channel has been
#locked. (If you do not specify a notice then the scripts default message will be used)
set dronelocknotice "This channel has been locked to +$dronemlock1$dronemlock2 for $droneremovelock seconds as suspected drones have been detected."


#---------------------------------------#
#    SET DRONE NICK EXEMPTION OPTIONS   #
#---------------------------------------#

#### EXEMPT CHANNEL OPERATORS ####
#Set this to make the bot to exempt channel OPERATORS even if they are detected with a drone nick.
#USAGE: [0/1] (0=OFF, 1=ON) - (0=DO NOT EXEMPT OPS, 1=EXEMPT OPS)
#If set to '0' channel operators will be punished if they are detected with a drone nick.
#If set to '1' channel operators will be NOT be punished even if they are detected with a drone nick.
set droneexemptops "1"

#### EXEMPT CHANNEL VOICES ####
#Set this to make the bot to exempt channel VOICES even if they are detected with a drone nick.
#USAGE: [0/1] (0=OFF, 1=ON) - (0=DO NOT EXEMPT VOICES, 1=EXEMPT VOICES)
#If set to '0' channel voices will be punished if they are detected with a drone nick.
#If set to '1' channel voices will be NOT be punished even if they are detected with a drone nick.
set droneexemptvoices "1"

#### EXEMPT SPECIFIC USER FLAGS ####
#Set this if you want the bot to exempt USER FLAGS listed the bots user file. Users with specific flags
#will be exempted by the bot and will not be punished, even if they are detected with a drone nick.
#Set the 'flags' for bot owners, masters, ops, voices, users etc which will be exempted from drone
#nick checking. All channel and global flags will be matched with the handle.
#USAGE: "mnf|mnf", "mn|o", "ovbf|-", "-|ov" etc. ("-" means no flags)
#(Note: If you want to exempt no flags set this to '-|-')
#FORMAT: "GLOBAL_FLAGS|CHANNEL_FLAGS"
set droneexemptflags "nm|ovf"


#### EXEMPT SPECIFIC NICKS ####
#Set the list of matching nicks you want the script to exempt. If any of these nicks are detected by
#the bot then they will not be checked by the drone nick detector. This is a good option for exempting
#certain nicks or characters in nicks, which you don't want the drone nick detector to detect.
#(Note: Wildcards such as '*' and '?' can be used for each element 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.
#3) Please add suitable nick patterns, which effect small patterns -- if you use wildcards.
#4) You can add an entire nick or a part of a nick to exempt.
#5) You can also add a nick with the '?' or '*' wilcard in it or surrounding the nick on any side.
#--------------------------------------------------------------------------------------------------
#Explanation of the wildcards masks:
# - The character '*' matches 0 or more characters of any type
# - The character '?' matches any single character
#----------------------------------------------------------------------
#NOTE: I have already added some nicks which the bot kicks innocently.
#If you do not have any nick to exempt: set droneexemptnicks ""
set droneexemptnicks {
"mrs*"
"mr*"
"*xyz*"
"dj*"
"*chr*"
"fr*"
"msn*"
"*str*"
"dr*"
"*sly*"
"*nxt*"
"frnd*"
"rhythm*"
"knack*"
"*gay*"
"*sup*"
"*nish*"
"sizling*"
"*dandy*"
"light*"
"vend*"
"*ugly*"
"*ight*"
"*flash*"
"*kork*"
"*hunt*"
"*isha*"
"*dodo*"
"*arco*"
"global*"
"*eva*"
"bugs*"
"*age"
"alex*"
"*ash*"
"*all*"
"*erik*"
"farah*"
"*friend*"
"*control*"
"*girl*"
"*gurl*"
"*guy*"
"*boy*"
"*hot*"
"*man*"
"*woman*"
"*lady*"
"*gypsy*"
"*soul*"
"psybnc*"
"d3vil*"
"*template*"
}


#### EXEMPT SPECIFIC MASKS ####
#Set this to the list of nick!user@host.domain MASKS you want the bot to exempt. If any of these masks are
#detected by the bot then will not be checked by the drone nick detector. This is a good option
#for exempt users with specific masks such as static ip address, common idents, virtual hosts etc.
#(Note: Wildcards such as "*" and "?" can be used for each element within the list)
#Guidelines for adding and modifying the mask exemption list:
#---------------------------------------------------------------------------------
#1) Please remember all masks should be 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.
#4) Please add suitable mask patterns, which effect small patterns -- 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 '?' or '*' wilcard in it or surrounding the mask on any side.
#--------------------------------------------------------------------------------------------------
#Explanation of the wildcards masks:
# - The character '*' matches 0 or more characters of any type
# - The character '?' matches any single character
#----------------------------------------------------------------------
#NOTE: I have already added some masks which the bot kicks innocently.
#If you DO NOT have any host to exempt: set droneexemptmasks ""
set droneexemptmasks {
"nick!ident@host.domain.com"
"*!awyeah@bot.awyeah.org"
"*!*@255.255.255.*"
"*!*talking*@*"
"*!*street*@*"
"*!*psybnc*@*"
"*!*april*@*"
"*!*berry*@*"
"*!*phone*@*"
"*!*ezbnc*@*"
"*!*frend*@*"
"*!*ging*@*"
"*!*jack*@*"
"*!*xbox*@*"
"*!*tity*@*"
"*!*user*@*"
"*!*jvc*@*"
"*!*nika@*"
"*!*ask*@*"
"*!*all*@*"
}


#----------------------------------------#
#    SET DRONE NICK KICK MESSAGE TYPE    #
#----------------------------------------#

#Set this if you would like to use your OWN kick message for kicking drone nicks or wish to use the
#DEFAULT script kick message for drone nicks. (The scripts default kick message is a bit more informative)
#USAGE: [0/1] (O=DEFAULT KICK MESSAGE, 1=USER DEFINED KICK MESSAGE)
set dronekickmsgtype "0"

###USE THIS ONLY IF YOU HAVE SET THE PREVIOUS SETTING TO '1'###
#Set this to your customizable user defined KICK message. This kick message will be shown at the end of each
#kick message when the bot kicks users with drone nicks. This kick message can contain all types of control
#codes, which are supported on IRC such as colors, bolds, underlines, reverses and etc.
set dronekickusermsg "10-14ap4n10- 12,0 Random Drone Nick/Ident Kick 12,0 - 2Drone 12or 2random pattern 12nick/ident detected. 12User 2infected 12with a possible 2trojan/virus."


#------------------------------------------#
#    SET DRONE NICK KICK COUNTER OPTION    #
#------------------------------------------#

#Set this if you wish to use a kick counter in every drone nick kick message. #The drone nick kick detector
#will display the total number of drone nicks kicked at the end of each drone nick kick message.
#USAGE: [0/1] (0=DISABLED, 1=ENABLED)
set dronekickcountertype "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 drone nicks KICK COUNTING DATABASE in. If
#you do not know which path to specify just type in a filename for your drone nick kick counting database.
#CHECK CURRENT PATH: To see your current directory path type 'pwd' at shell prompt
#(Note: The name and extension [*.file] the file can be named anything)
#Example: set dronekickfile "/usr/home/icha/eggdrop/scripts/dronekicks.dat"
set dronekickfile "dronekicks.dat"


#######################
### OPTIONAL MODULE ###
#######################

#----------------------------------------#
#    SET DRONE RANDOM IDENT DETECTION    #
#----------------------------------------#

###NOTE: THIS MODULE WILL ONLY WORK IF THE 'NICK SEARCH PATTERN' MODULE HAS BEEN ENABLED###

#Set this if you want the bot to detect users with RANDOM IDENTS. Users with random idents will be
#detected through this module. If the nick is not a random neither a drone nick and the ident is
#detected to be random, even then that user with the drone/random ident will be punished.
#(CAUTION: Please enable this setting wisely -- it is not recommended or compulsory)
#USAGE: [0/1] (0=DON'T DETECT RANDOM IDENTS, 1=DETECT RANDOM IDENTS)
set dronerandomidentdetect "0"


#############################################################
### Congratulations! Script configuration is now complete ###
#############################################################


##############################################################################
### Don't edit anything else from this point onwards even if you know tcl! ###
##############################################################################

bind join - "*" drone:chan:type
if {$dronekickcountertype == 1} { bind kick - "*" drone:kick:counter }
if {$dronebotopchecktype == 1} { bind mode - "*+o*" drone:botop:check }
if {$dronenickchangecheck == 1} { bind nick - "*" drone:nick:change:check }
if {($droneexemptops == 0) && ($droneexemptvoices == 0)} { set droneexemptopsvoices 1
} elseif {($droneexemptops == 0) && ($droneexemptvoices == 1)} { set droneexemptopsvoices 2
} elseif {($droneexemptops == 1) && ($droneexemptvoices == 0)} { set droneexemptopsvoices 3
} elseif {($droneexemptops == 1) && ($droneexemptvoices == 1)} { set droneexemptopsvoices 4
} else { set droneexemptopsvoices 1 }

if {![info exists dronethresholdfrequency1]} { set dronethresholdfrequency1 17
} elseif {$dronethresholdfrequency1 < 12} { set dronethresholdfrequency1 12
} elseif {$dronethresholdfrequency1 > 20} { set dronethresholdfrequency1 20
} else { set dronethresholdfrequency1 17 }

if {![info exists dronethresholdfrequency2]} { set dronethresholdfrequency2 50
} elseif {$dronethresholdfrequency2 < 40} { set dronethresholdfrequency2 40
} elseif {$dronethresholdfrequency2 > 80} { set dronethresholdfrequency2 80
} else { set dronethresholdfrequency2 50 }


proc drone:chan:type {nick uhost hand chan} {
 global dronechantype dronechannels droneexemptops droneexemptvoices
  if {![isbotnick $nick] && [botisop $chan]} {
  if {($droneexemptops == 1) && [isop $nick $chan] || ($droneexemptvoices == 1) && [isvoice $nick $chan]} { return 0 }
   switch -- $dronechantype {
    1 {
        if {[lsearch -exact [split [string tolower $dronechannels]] [string tolower $chan]] != -1} {
         drone:nick:check $nick $uhost $hand $chan
         }
    }
    2 {
        if {[string equal "#" [string index $chan 0]]} {
         drone:nick:check $nick $uhost $hand $chan
         }
    }
    default { putlog "\002RANDOM DRONE NICK REMOVER:\002 No channel type selected."; return 0 }
    }
  }
}

proc drone:botop:check {nick uhost hand chan mode target} {
 global dronechantype dronechannels
  if {[isbotnick $target] && [botisop $chan]} {
   switch -- $dronechantype {
    1 {
        if {[lsearch -exact [split [string tolower $dronechannels]] [string tolower $chan]] != -1} {
         timer 1 [list drone:check:chanlist $nick $uhost $chan]
         }
    }
    2 {
        if {[string equal "#" [string index $chan 0]]} {
         timer 1 [list drone:check:chanlist $nick $uhost $chan]
         }
    }
    default { putlog "\002RANDOM DRONE NICK REMOVER:\002 No channel type selected."; return 0 }
    }
  }
}

proc drone:nick:change:check {oldnick uhost hand chan nick} {
 global dronechantype dronechannels droneexemptops droneexemptvoices
  if {![isbotnick $oldnick] && ![isbotnick $nick] && [botisop $chan]} {
  if {($droneexemptops == 1) && [isop $nick $chan] || ($droneexemptvoices == 1) && [isvoice $nick $chan]} { return 0 }
   switch -- $dronechantype {
    1 {
        if {[lsearch -exact [split [string tolower $dronechannels]] [string tolower $chan]] != -1} {
         drone:nick:check $nick $uhost $hand $chan
         }
    }
    2 {
        if {[string equal "#" [string index $chan 0]]} {
         drone:nick:check $nick $uhost $hand $chan
         }
    }
    default { putlog "\002RANDOM DRONE NICK REMOVER:\002 No channel type selected."; return 0 }
    }
  }
}

proc drone:check:chanlist {nick uhost chan} {
 global droneexemptops droneexemptvoices
 putlog "\002RANDOM DRONE NICK REMOVER:\002 Scanning \002[string tolower $chan]\002, since got opped by $nick!$uhost."
 foreach nick [chanlist $chan] {
  if {[info exists drone_wasop_or_wasvoice]} { unset drone_wasop_or_wasvoice }
  if {($droneexemptops == 1) && [isop $nick $chan] || ($droneexemptvoices == 1) && [isvoice $nick $chan]} {
   set drone_wasop_or_wasvoice 1
  } elseif {![info exists drone_wasop_or_wasvoice] && ([getchanhost $nick $chan] != "") && ([nick2hand $nick $chan] != "")} {
    drone:nick:check $nick [getchanhost $nick $chan] [nick2hand $nick $chan] $chan
    }
  }
}


proc drone:nick:check {nick uhost hand chan} {
 global dronespecialcharstype dronerandomident droneexemptflags dronesearchpatterntype dronethresholdfrequency2
 global dronenotrandom dronemoduletype dronematches droneexemptnicks droneexemptmasks dronethresholdfrequency1
 global droneidentlength dronenicklength droneunresolvedident dronespecialchars dronerandomidentdetect
  set ident [lindex [split $uhost @] 0]; set host [lindex [split $uhost @] 1]; set trimident [string trimleft $ident ~]
  if {[string equal -nocase $trimident $nick] || [string match -nocase "*$trimident*" $nick]} { return 0 }
  if {([regexp -all \[.\] $host] <= 2) || ([regexp -all \[.\] $host] >= 7) || ([regexp -all {[0-9]} $host] <= 2) || ([regexp -all {[0-9]} $nick] > 2) || ([regexp -all {[0-9]} $ident] > 2) || ([regexp -all \[{}\\\[\\\]-_./|\\\\^`\] $ident] > 0)} { return 0 }
  if {([string length $trimident] >= [lindex [split $droneidentlength :] 0]) && ([string length $trimident] <= [lindex [split $droneidentlength :] 1]) && ([string length $nick] >= [lindex [split $dronenicklength :] 0]) && ([string length $nick] <= [lindex [split $dronenicklength :] 1])} {
  if {($droneunresolvedident == 1) && ![string equal "~" [string index $ident 0]]} { return 0 }
  if {$dronespecialcharstype == 1} { foreach dronespecialchar $dronespecialchars { if {[string match *$dronespecialchar* $nick]} { return 0 } } }
  if {$dronerandomident == 1} { foreach dronematch $dronematches { if {[string match -nocase *$dronematch* $ident]} { return 0 } } }
  if {![string equal "-" [string trim [lindex [split $droneexemptflags |] 0]]]} { foreach droneexemptglobflag [split [string trim [lindex [split $droneexemptflags |] 0]] ""] { if {[matchattr $hand $droneexemptglobflag]} { return 0 } } }
  if {![string equal "-" [string trim [lindex [split $droneexemptflags |] 1]]]} { foreach droneexemptlocflag [split [string trim [lindex [split $droneexemptflags |] 1]] ""] { if {[matchattr $hand $droneexemptlocflag $chan]} { return 0 } } }
  if {$droneexemptnicks != ""} { foreach droneexemptnick $droneexemptnicks { if {[string match -nocase $droneexemptnick $nick]} { return 0 } } }
  if {$droneexemptmasks != ""} { foreach droneexemptmask $droneexemptmasks { if {[string match -nocase *$droneexemptmask* "${nick}![getchanhost $nick $chan]"]} { return 0 } } }
  if {$dronenotrandom == 1} { if {([regexp -nocase -all {aa|bb|cc|dd|ee|ff|gg|hh|ii|jj|kk|ll|mm|nn|oo|pp|qq|rr|ss|tt|uu|vv|ww|xx|yy|zz} $nick] > 0) || ([regexp -nocase -all {aa|bb|cc|dd|ee|ff|gg|hh|ii|jj|kk|ll|mm|nn|oo|pp|qq|rr|ss|tt|uu|vv|ww|xx|yy|zz} $trimident] > 0) || [string match {*[0-9][0-9]*} $nick] || [string match {*[0-9][0-9]*} $trimident] || [string match "*{{*" $nick] || [string match "*}}*" $nick] || [string match "*\\\[\\\[*" $nick] || [string match "*\\\]\\\]*" $nick] || [string match "*--*" $nick] || [string match "*__*" $nick] || [string match "*..*" $nick] || [string match "*^^*" $nick] || [string match "*``*" $nick] || [string match "*||*" $nick] || [string match "*//*" $nick] || [string match "*\\\\\\\\*" $nick]} { return 0 } }
  if {[string equal [string length $trimident] [regexp -all {[A-Z]} $ident]] && ![string equal [string length $nick] [regexp -all {[A-Z]} $nick]] || [string equal [string length $nick] [regexp -all {[A-Z]} $nick]] && ![string equal [string length $trimident] [regexp -all {[A-Z]} $ident]] || ([regexp -all {[A-Z]} $nick] < 3) && ([regexp -all {[a-z]} $nick] >= 3) && ([string length $nick] >= 5)} { return 0 }
  switch -- $dronemoduletype {
    0 { return 0 }
    1 {
        if {([drone:nick:score:1 "$nick!$ident"] > $dronethresholdfrequency1) || ([drone:nick:score:2 "$nick!$ident"] >= $dronethresholdfrequency2)} {
          drone:do:module $nick $uhost $chan 1
          }
    }
    2 {
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
              if {[regexp -all {[0-9]} $nick] < 3} {
                drone:do:module $nick $uhost $chan 2
                }
             }
         }
         2 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
              break; drone:do:module $nick $uhost $chan 2
              }
            }
          }
        }
      }
      if {$dronerandomidentdetect == 1} {
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
              if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
                drone:do:module $nick $uhost $chan 2
                }
             }
         }
         2 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
               if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                break; drone:do:module $nick $uhost $chan 2
                }
              }
            }
          }
        }
      }
    }
    3 {
        if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
          if {([regexp -all {[0-9]} $nick] < 3) || ([regexp -nocase -all {[aeiou]} $nick] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
       }
       if {([drone:nick:regexp:match:1 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:2 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:3 "$nick!$ident"] == 1)} {
         drone:do:module $nick $uhost $chan 3
       }
       if {$dronerandomidentdetect == 1} {
        if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
         if {([regexp -all {[0-9]} [string trimleft $ident ~]] < 3) || ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
        }
      }
    }
    4 {
        if {([drone:nick:score:1 "$nick!$ident"] > $dronethresholdfrequency1) || ([drone:nick:score:2 "$nick!$ident"] >= $dronethresholdfrequency2)} {
          drone:do:module $nick $uhost $chan 1
        }
        switch -- $dronesearchpatterntype {
         1 {
            if {[regexp -all {[0-9]} $nick] < 3} {
             if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
               }
            }
         }
         2 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
              break; drone:do:module $nick $uhost $chan 2
              }
            }
          }
        }
      }
      if {$dronerandomidentdetect == 1} {
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
              if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
                drone:do:module $nick $uhost $chan 2
                }
             }
         }
         2 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
               if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                break; drone:do:module $nick $uhost $chan 2
                }
              }
            }
          }
        }
      }
    }
    5 {
        if {([drone:nick:score:1 "$nick!$ident"] > $dronethresholdfrequency1) || ([drone:nick:score:2 "$nick!$ident"] >= $dronethresholdfrequency2)} {
          drone:do:module $nick $uhost $chan 1
        }
        if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
         if {([regexp -all {[0-9]} $nick] < 3) || ([regexp -nocase -all {[aeiou]} $nick] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
        }
        if {([drone:nick:regexp:match:1 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:2 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:3 "$nick!$ident"] == 1)} {
         drone:do:module $nick $uhost $chan 3
        }
        if {$dronerandomidentdetect == 1} {
         if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
         if {([regexp -all {[0-9]} [string trimleft $ident ~]] < 3) || ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
        }
      }
    }
    6 {
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
               }
            }
         }
         2 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                   break; drone:do:module $nick $uhost $chan 2
                   }
                }
             }
          }
       }
       if {$dronerandomidentdetect == 1} {
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
              if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
                drone:do:module $nick $uhost $chan 2
                }
             }
         }
         2 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
               if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                break; drone:do:module $nick $uhost $chan 2
                }
              }
            }
          }
        }
      }
      if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
        if {([regexp -all {[0-9]} $nick] < 3) || ([regexp -nocase -all {[aeiou]} $nick] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
       }
       if {([drone:nick:regexp:match:1 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:2 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:3 "$nick!$ident"] == 1)} {
         drone:do:module $nick $uhost $chan 3
       }
       if {$dronerandomidentdetect == 1} {
        if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
         if {([regexp -all {[0-9]} [string trimleft $ident ~]] < 3) || ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
        }
      }
    }
    7 {
        if {([drone:nick:score:1 "$nick!$ident"] > $dronethresholdfrequency1) || ([drone:nick:score:2 "$nick!$ident"] >= $dronethresholdfrequency2)} {
          drone:do:module $nick $uhost $chan 1
        }
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
               }
            }
         }
         2 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         default {
             if {[regexp -all {[0-9]} $nick] < 3} {
              if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* $nick] && ([regexp -nocase -all {[aeiou]} $nick] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
       }
       if {$dronerandomidentdetect == 1} {
        switch -- $dronesearchpatterntype {
         1 {
             if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
              if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
                drone:do:module $nick $uhost $chan 2
                }
             }
         }
         2 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         3 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
             }
           }
         }
         4 {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
                if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                  break; drone:do:module $nick $uhost $chan 2
                  }
               }
            }
         }
         default {
             if {[regexp -all {[0-9]} [string trimleft $ident ~]] < 3} {
              if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
               drone:do:module $nick $uhost $chan 2
              }
              foreach dronematch $dronematches {
              if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
               break; drone:do:module $nick $uhost $chan 2
               }
              }
              foreach dronematch $dronematches {
               if {[string match -nocase *$dronematch* [string trimleft $ident ~]] && ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] < 3)} {
                break; drone:do:module $nick $uhost $chan 2
                }
              }
            }
          }
        }
      }
      if {[regexp -nocase -all {[aeiou]} $nick] == 0} {
        if {([regexp -all {[0-9]} $nick] < 3) || ([regexp -nocase -all {[aeiou]} $nick] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
       }
       if {([drone:nick:regexp:match:1 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:2 "$nick!$ident"] == 1) || ([drone:nick:regexp:match:3 "$nick!$ident"] == 1)} {
         drone:do:module $nick $uhost $chan 3
       }
       if {$dronerandomidentdetect == 1} {
        if {[regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0} {
         if {([regexp -all {[0-9]} [string trimleft $ident ~]] < 3) || ([regexp -nocase -all {[aeiou]} [string trimleft $ident ~]] == 0)} {
          drone:do:module $nick $uhost $chan 3
          }
        }
      }
    }
    default { putlog "\002RANDOM DRONE NICK REMOVER:\002 No drone nick module selected."; return 0 }
    }
  }
}


proc drone:enforce:mlock {chan} {
 global dronechanlocked dronemlock1 dronemlock2 dronelocknotice
 global dronelocknoticetype droneremovelock dronelocknoticeswitch
  if {$dronemlock1 == ""} { set dronemlock1 m }
  if {![info exists dronechanlocked($chan)] && ![string match *$dronemlock1* [getchanmode $chan]]} {
   putquick "MODE $chan +$dronemlock1$dronemlock2" -next; set dronechanlocked($chan) "locked"
   utimer $droneremovelock [list putquick "MODE $chan -$dronemlock1$dronemlock2" -next]
   utimer [expr $droneremovelock + 2] [list unset dronechanlocked($chan)]
   if {$dronelocknoticeswitch == 1} {
    if {$dronelocknoticetype == 1} { putquick "NOTICE $chan :This channel has been locked to +$dronemlock1$dronemlock2 for $droneremovelock seconds as suspected drones have been detected." -next
    } elseif {($dronelocknoticetype == 2) && ($dronelocknotice != "")} { putquick "NOTICE $chan :$dronelocknotice" -next
    } else { putquick "NOTICE $chan :This channel has been locked to +$dronemlock1$dronemlock2 for $droneremovelock seconds as suspected drones have been detected." -next
      }
    }
  }; return
}


proc drone:do:module {nick uhost chan type} {
 global dronelockswitch
  if {$dronelockswitch == 1} { drone:enforce:mlock $chan }
  drone:nick:punishment $nick $uhost $chan $type
}

proc drone:nick:punishment {nick uhost chan type} {
 global dronespecialchars droneexemptflags droneexemptnicks droneexemptmasks dronebanmasktype
 global dronekickfile dronepunishtype droneexemptopsvoices dronebantime dronekickcountertype
 global dronekickmsgtype dronekickusermsg droneunresolvedident dronespecialcharstype
 if {$dronekickcountertype == 1} {
  if {![file exists $dronekickfile]} {
   create:drone:kick:file $dronekickfile
  }
  set file [open $dronekickfile "r"]; set currentkicks [gets $file]
  if {$currentkicks == ""} { set currentkicks 1 }
  close $file; set dronekicks $currentkicks
  }
  switch -- $type {
   1 { set type "Nick score generator matching" }
   2 { set type "Random search pattern matching" }
   3 { set type "Regular expression matching" }
  }
  switch -- $dronekickcountertype {
   0 {
     switch -- $dronekickmsgtype {
      0 { set dronekickmsg "0,1 Random Drone Nick/Ident Kick 12,0 - 2Drone 12or 2random pattern 12nick/ident detected. 12User 2infected 12with a possible 2trojan/virus. 12Drone module:2 $type" }
      1 { set dronekickmsg "$dronekickusermsg. 12Drone module:2 $type" }
      default { set dronekickmsg "0,1 Random Drone Nick/Ident Kick 12,0 - 2Drone 12or 2random pattern 12nick/ident detected. 12User 2infected 12with a possible 2trojan/virus. 12Drone module:2 $type" }
      }
   }
   1 {
     switch -- $dronekickmsgtype {
      0 { set dronekickmsg "10-14ap4n10- 12,0 Random Drone Nick/Ident Kick 12,0 - 2Drone 12or 2random pattern 12nick/ident detected. 12User 2infected 12with a possible 2trojan/virus.". 12Drone module:2 $type - (Kick #$dronekicks)" }
      1 { set dronekickmsg "$dronekickusermsg. 12Drone module:2 $type - (Kick #$dronekicks)" }
      default { set dronekickmsg "10-14ap4n10- 12,0 Random Drone Nick/Ident Kick 12,0 - 2Drone 12or 2random pattern 12nick/ident detected. 12User 2infected 12with a possible 2trojan/virus.". 12User 2infected 12with a possible 2trojan/virus. 12Drone module:2 $type - (Kick #$dronekicks)" }
      }
   }
   default { set dronekickmsg " 10-14ap4n10- 12,0 Random Drone Nick/Ident Kick 12,0 - 2Drone 12or 2random pattern 12nick/ident detected. 12User 2infected 12with a possible 2trojan/virus. 12User 2infected 12with a possible 2trojan/virus. 12Drone module:2 $type" }
  }
  set dronebanmask [drone:banmask $nick!$uhost $dronebanmasktype]
  switch -- $dronepunishtype {
    1 {
        switch -- $droneexemptopsvoices {
         1 {
             do:drone:kick $nick $chan $dronebanmask $dronekickmsg 1
         }
         2 {
             if {![isvoice $nick $chan]} {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 1
              }
         }
         3 {
             if {![isop $nick $chan]} {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 1
              }
         }
         4 {
             if {![isvoice $nick $chan] && ![isop $nick $chan]} {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 1
              }
         }
         default {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 1
              }
         }
    }
    2 {
        foreach user [chanlist $chan] {
         if {($droneexemptopsvoices == 1) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] || ($droneexemptopsvoices == 2) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] && ![isvoice $user $chan] || ($droneexemptopsvoices == 3) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] && ![isop $user $chan] || ($droneexemptopsvoices == 4) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] && ![isvoice $user $chan] && ![isop $user $chan]} {
         if {[info exists droneident]} { unset droneident }; if {[info exists dronespecialcharacter]} { unset dronespecialcharacter }; if {[info exists droneglobalflag]} { unset droneglobalflag }
         if {[info exists dronelocalflag]} { unset dronelocalflag }; if {[info exists dronenick]} { unset dronenick }; if {[info exists dronemask]} { unset dronemask }
         if {($droneunresolvedident == 1) && [string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { set droneident 1 }
         if {$dronespecialcharstype == 1} {
         foreach dronespecialchar $dronespecialchars {
          if {[string match -nocase *$dronespecialchar* $user]} {
           break; set dronespecialcharacter 1
           }
          }
         }
         if {([string trim [lindex [split $droneexemptflags |] 0]] != "-") && ([string trim [lindex [split $droneexemptflags |] 0]] != "")} {
          foreach droneexemptglobflag [split [string trim [lindex [split $droneexemptflags |] 0]] ""] {
           if {[matchattr [nick2hand $user $chan] $droneexemptglobflag]} {
            break; set droneglobalflag 1
            }
           }
          }
          if {([string trim [lindex [split $droneexemptflags |] 1]] != "-") && ([string trim [lindex [split $droneexemptflags |] 1]] != "")} {
           foreach droneexemptlocflag [split [string trim [lindex [split $droneexemptflags |] 1]] ""] {
            if {[matchattr [nick2hand $user $chan] $droneexemptlocflag $chan]} {
            break; set dronelocalflag 1
            }
           }
          }
          if {$droneexemptnicks != ""} {
           foreach droneexemptnick $droneexemptnicks {
            if {[string match -nocase $droneexemptnick $user]} {
             break; set dronenick 1
             }
            }
           }
           if {$droneexemptmasks != ""} {
            foreach droneexemptmask $droneexemptmasks {
             if {[string match -nocase *$droneexemptmask* "${user}![getchanhost $user $chan]"]} {
              break; set dronemask 1
              }
             }
            }
            if {![info exists droneident]} { set droneident 0 }; if {![info exists dronespecialcharacter]} { set dronespecialcharacter 0 }; if {![info exists droneglobalflag]} { set droneglobalflag 0 }
            if {![info exists dronelocalflag]} { set dronelocalflag 0 }; if {![info exists dronenick]} { set dronenick 0 }; if {![info exists dronemask]} { set dronemask 0 }
            if {($droneident == 0) && ($dronespecialcharacter == 0) && ($droneglobalflag == 0) && ($dronelocalflag == 0) && ($dronenick == 0) && ($dronemask == 0)} {
             do:drone:kick $user $chan $dronebanmask $dronekickmsg 1
             }
          }
       }
    }
    3 {
        switch -- $droneexemptopsvoices {
         1 {
             do:drone:kick $nick $chan $dronebanmask $dronekickmsg 2
             if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
         }
         2 {
             if {![isvoice $nick $chan]} {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 2
              if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
              }
         }
         3 {
             if {![isop $nick $chan]} {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 2
              if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
              }
         }
         4 {
             if {![isvoice $nick $chan] && ![isop $nick $chan]} {
              do:drone:kick $nick $chan $dronebanmask $dronekickmsg 2
              if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
              }
         }
         default {
                   do:drone:kick $nick $chan $dronebanmask $dronekickmsg 2
                   if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
                   }
            }
    }
    4 {
        foreach user [chanlist $chan] {
         if {($droneexemptopsvoices == 1) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] || ($droneexemptopsvoices == 2) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] && ![isvoice $user $chan] || ($droneexemptopsvoices == 3) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] && ![isop $user $chan] || ($droneexemptopsvoices == 4) && [string match -nocase *$dronebanmask* "${user}![getchanhost $user $chan]"] && ![isvoice $user $chan] && ![isop $user $chan]} {
         if {[info exists droneident]} { unset droneident }; if {[info exists dronespecialcharacter]} { unset dronespecialcharacter }; if {[info exists droneglobalflag]} { unset droneglobalflag }
         if {[info exists dronelocalflag]} { unset dronelocalflag }; if {[info exists dronenick]} { unset dronenick }; if {[info exists dronemask]} { unset dronemask }
         if {($droneunresolvedident == 1) && [string equal "~" [string index [lindex [split $uhost @] 0] 0]]} { set droneident 1 }
         if {$dronespecialcharstype == 1} {
         foreach dronespecialchar $dronespecialchars {
          if {[string match -nocase *$dronespecialchar* $user]} {
           break; set dronespecialcharacter 1
           }
          }
         }
         if {([string trim [lindex [split $droneexemptflags |] 0]] != "-") && ([string trim [lindex [split $droneexemptflags |] 0]] != "")} {
          foreach droneexemptglobflag [split [string trim [lindex [split $droneexemptflags |] 0]] ""] {
           if {[matchattr [nick2hand $user $chan] $droneexemptglobflag]} {
            break; set droneglobalflag 1
            }
           }
          }
          if {([string trim [lindex [split $droneexemptflags |] 1]] != "-") && ([string trim [lindex [split $droneexemptflags |] 1]] != "")} {
           foreach droneexemptlocflag [split [string trim [lindex [split $droneexemptflags |] 1]] ""] {
            if {[matchattr [nick2hand $user $chan] $droneexemptlocflag $chan]} {
            break; set dronelocalflag 1
            }
           }
          }
          if {$droneexemptnicks != ""} {
           foreach droneexemptnick $droneexemptnicks {
            if {[string match -nocase $droneexemptnick $user]} {
             break; set dronenick 1
             }
            }
           }
           if {$droneexemptmasks != ""} {
            foreach droneexemptmask $droneexemptmasks {
             if {[string match -nocase *$droneexemptmask* "${user}![getchanhost $user $chan]"]} {
              break; set dronemask 1
              }
             }
            }
            if {![info exists droneident]} { set droneident 0 }; if {![info exists dronespecialcharacter]} { set dronespecialcharacter 0 }; if {![info exists droneglobalflag]} { set droneglobalflag 0 }
            if {![info exists dronelocalflag]} { set dronelocalflag 0 }; if {![info exists dronenick]} { set dronenick 0 }; if {![info exists dronemask]} { set dronemask 0 }
            if {($droneident == 0) && ($dronespecialcharacter == 0) && ($droneglobalflag == 0) && ($dronelocalflag == 0) && ($dronenick == 0) && ($dronemask == 0)} {
             do:drone:kick $user $chan $dronebanmask $dronekickmsg 2
             if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
             }
          }
       }
    }
    5 {
        newchanban $chan $dronebanmask drone $dronekickmsg $dronebantime; return 0
    }
    6 {
        newban $dronebanmask drone $dronekickmsg $dronebantime; return 0
    }
    default {
        do:drone:kick $nick $chan $dronebanmask $dronekickmsg 2
        if {$dronebantime > 0} { timer $dronebantime [list drone:unban $dronebanmask $chan] }
        }
    }; return 0
}


proc do:drone:kick {nick chan mask message type} {
 global dronekickbanqueue dronequeuenextoption dronequeueflushmodeoption
  switch -- $type {
   1 {
       switch -- $dronekickbanqueue {
        1 {
            switch -- $dronequeuenextoption {
             0 { puthelp "KICK $chan $nick :$message" }
             1 { puthelp "KICK $chan $nick :$message" -next }
             default { puthelp "KICK $chan $nick :$message" -next }
             }
        }
        2 {
            switch -- $dronequeuenextoption {
             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 {
            putkick $chan $nick $message
        }
        5 {
            switch -- $dronequeuenextoption {
             0 { putserv "KICK $chan $nick :$message" }
             1 { putserv "KICK $chan $nick :$message" -next }
             default { putserv "KICK $chan $nick :$message" -next }
             }
        }
        6 {
            switch -- $dronequeuenextoption {
             0 { putquick "KICK $chan $nick :$message" }
             1 { putquick "KICK $chan $nick :$message" -next }
             default { putquick "KICK $chan $nick :$message" -next }
             }
        }
        7 {
            putdccraw 0 [string length "KICK $chan $nick :$message\n"] "KICK $chan $nick :$message\n"
        }
        default {
           switch -- $dronequeuenextoption {
            0 { putquick "KICK $chan $nick :$message" }
            1 { putquick "KICK $chan $nick :$message" -next }
            default { putquick "KICK $chan $nick :$message" -next }
            }
         }
      }
   }
   2 {
       switch -- $dronekickbanqueue {
        1 {
            switch -- $dronequeuenextoption {
             0 { puthelp "MODE $chan +b $mask"; puthelp "KICK $chan $nick :$message" }
             1 { puthelp "MODE $chan +b $mask" -next; puthelp "KICK $chan $nick :$message" -next }
             default { puthelp "MODE $chan +b $mask" -next; puthelp "KICK $chan $nick :$message" -next }
             }
        }
        2 {
            switch -- $dronequeuenextoption {
             0 { pushmode $chan +b $mask; putserv "KICK $chan $nick :$message" }
             1 { pushmode $chan +b $mask; flushmode $chan; putserv "KICK $chan $nick :$message" -next }
             default { pushmode $chan +b $mask; flushmode $chan; putserv "KICK $chan $nick :$message" -next }
             }
        }
        3 {
            switch -- $dronequeueflushmodeoption {
             0 { putserv "MODE $chan +b $mask"; putkick $chan $nick $message }
             1 { putserv "MODE $chan +b $mask"; putkick $chan $nick $message }
             default { putserv "MODE $chan +b $mask"; putkick $chan $nick $message }
             }
        }
        4 {
            switch -- $dronequeueflushmodeoption {
             0 { pushmode $chan +b $mask; putkick $chan $nick $message }
             1 { pushmode $chan +b $mask; flushmode $chan; putkick $chan $nick $message }
             default { pushmode $chan +b $mask; flushmode $chan; putkick $chan $nick $message }
             }
        }
        5 {
            switch -- $dronequeuenextoption {
             0 { putserv "MODE $chan +b $mask"; putserv "KICK $chan $nick :$message" }
             1 { putserv "MODE $chan +b $mask" -next; putserv "KICK $chan $nick :$message" -next }
             default { putserv "MODE $chan +b $mask" -next; putserv "KICK $chan $nick :$message" -next }
             }
        }
        6 {
            switch -- $dronequeuenextoption {
             0 { putquick "MODE $chan +b $mask"; putquick "KICK $chan $nick :$message" }
             1 { putquick "MODE $chan +b $mask" -next; putquick "KICK $chan $nick :$message" -next }
             default { putquick "MODE $chan +b $mask" -next; putquick "KICK $chan $nick :$message" -next }
             }
        }
        7 {
            putdccraw 0 [string length "MODE $chan +b $mask\n"] "MODE $chan +b $mask\n"
            putdccraw 0 [string length "KICK $chan $nick :$message\n"] "KICK $chan $nick :$message\n"
        }
        default {
         switch -- $dronequeuenextoption {
          0 { putquick "MODE $chan +b $mask"; putquick "KICK $chan $nick :$message" }
          1 { putquick "MODE $chan +b $mask" -next; putquick "KICK $chan $nick :$message" -next }
          default { putquick "MODE $chan +b $mask" -next; putquick "KICK $chan $nick :$message" -next }
          }
        }
      }
    }
  }; return
}


proc drone:unban {mask chan} {
 if {[botisop $chan] && [ischanban $mask $chan]} {
  pushmode $chan -b $mask
  }
}

### Thanks to 'demond' for this drone nick scorer ###
proc drone:nick:score:1 {string} {
 set score 0
 set vowel "aeiouy"
 set digit "0123456789"
 set cnant "bcdfghjklmnpqrstvwxz"
 set other "{}\\\[\\\]-_./|\\\\^`"
 set str [string tolower $string]
 incr score [regexp -nocase -all \[$vowel\]{3,} $string]
 incr score [regexp -nocase -all \[$cnant\]{3,} $string]
 incr score [regexp -nocase -all \[$other\]{2,} $string]
 incr score [regexp -nocase -all \[$digit\]{2,} $string]
 incr score [regexp -nocase -all \[$vowel$other\]{4,} $string]
 incr score [regexp -nocase -all \[$cnant$other\]{4,} $string]
 incr score [regexp -nocase -all \[$vowel$digit\]{4,} $string]
 incr score [regexp -nocase -all \[$cnant$digit\]{4,} $string]
 incr score [regexp -nocase -all \[$other$digit\]{3,} $string]
 incr score $score
}

proc drone:nick:score:2 {string} {
 set score 0
 set chars "{}\\\[\\\]-_./|\\\\^`"
 set nick [lindex [split $string !] 0]
 set ident [lindex [split $string !] 1]
 set trimident [string trimleft $ident ~]
 if {([regexp -all \[{}\\\[\\\]-_./|\\\\^`\] $nick] == 0) && ([regexp -all {[0-9]} $nick] <= 1)} { incr score 10 }
 if {([regexp -all \[{}\\\[\\\]-_./|\\\\^`\] $trimident] == 0) && ([regexp -all {[0-9]} $trimident] <= 1)} { incr score 10 }
 if {![string equal "20" $score]} { return 0 }
 if {[string equal "~" [string index $ident 0]]} { incr score 5 }
 incr score [expr [regexp -nocase -all {[zxq]} $nick] * 10]
 incr score [expr [regexp -nocase -all {[zxq]} $trimident] * 10]
 incr score [expr [regexp -nocase -all {[jwgvhk]} $nick] * 5]
 incr score [expr [regexp -nocase -all {[jwgvhk]} $trimident] * 5]
 if {[regexp -nocase -all {[aeiouy]} $nick] == 0} { incr score 30
 } elseif {[regexp -nocase -all {[aeiouy]} $nick] == 1} { incr score 15
 } elseif {([regexp -nocase -all {[aeiouy]} $nick] == 2) && ([string length $nick] >= 8)} { incr score 5
 } elseif {([regexp -nocase -all {[aeiouy]} $nick] >= 3)} { return 0 }
 if {[regexp -nocase -all {[aeiouy]} $trimident] == 0} { incr score 25
 } elseif {[regexp -nocase -all {[aeiouy]} $trimident] == 1} { incr score 10
 } elseif {([regexp -nocase -all {[aeiouy]} $trimident] == 2) && ([string length $trimident] >= 6)} { incr score 5
 } elseif {([regexp -nocase -all {[aeiouy]} $trimident] >= 3)} { return 0 }
 return $score
}


### Thanks to 'nANDu' for this drone nick regular expression logic ###
proc drone:nick:regexp:match:1 {string} {
 set nick [string tolower [lindex [split $string !] 0]]
 set ident [string tolower [string trimleft [lindex [split $string !] 1] ~]]
 if {([string length $nick] > 10) || ([string length $nick] < 4) || ([string length $ident] < 4) || [string match {*[0-9]*} $nick] || [regexp -all \[{}\\\[\\\]-_./|\\\\^`\] $nick]} { return 0 }
 if {([drone:nick:regexp:check [string range $nick 0 2]] == 1) || ([drone:nick:regexp:check [string range $nick [expr [string length $nick] - 3] [string length $nick]]] == 1) && ([drone:nick:regexp:check [string range $ident 0 2]] == 1) || ([drone:nick:regexp:check [string range $ident [expr [string length $ident] - 3] [string length $ident]]] == 1) } { return 1
 } else { return 0 }
}

proc drone:nick:regexp:check {string} {
 if {([string length $string] < 3) || [string match {*[0-9]*} $string] || [regexp -all \[{}\\\[\\\]-_./|\\\\^`\] $string] || [regexp -nocase -all {[aeiou]} $string]} { return 0 }
 if {[regexp -nocase -all {yst|rth|dj|cks|pwr|sky|ply|mr|mrs|jbc|nth|nxt|frn|rth|chr|dhr|nd|str|htz} $string]} { return 0 }
 return 1
}

proc drone:nick:regexp:match:2 {string} {
 global dronerandomidentdetect
  set nick [string tolower [lindex [split $string !] 0]]
  set ident [string tolower [string trimleft [lindex [split $string !] 1] ~]]
  if {[info exists drone_detected]} { unset drone_detected }
  if {([regexp -all {[aeiouy]} $nick] > 3) || ([regexp -all {[aeiouy]} $ident] > 3) || ([regexp -all {[0-9]} $nick] > 2) || ([regexp -all {[0-9]} $ident] > 2)} { return 0 }
  if {[string match "*q*" $nick] && ([regexp -all {[cdfghknprsvwx]} $nick] > 1) || [string match "*x*" $nick] && ([regexp -all {[fhkmjqwrvz]} $nick] > 1) || [string match "*z*" $nick] && ([regexp -all {[cdqvx]} $nick] > 1) || [string match "*v*" $nick] && ([regexp -all {[fhqx]} $nick] > 1)} { set drone_detected 1 }
  if {$dronerandomidentdetect == 1} { if {[string match "*q*" $ident] && ([regexp -all {[cdfghknprsvwx]} $ident] > 1) || [string match "*x*" $ident] && ([regexp -all {[fhkmjqwrvz]} $ident] > 1) || [string match "*z*" $ident] && ([regexp -all {[cdqvx]} $ident] > 1) || [string match "*v*" $ident] && ([regexp -all {[fhqx]} $ident] > 1)} { set drone_detected 1 } }
  if {![info exists drone_detected]} { return 0
  } else { unset drone_detected; return 1 }
}


### Thanks to 'Sir_Fz' for this drone nick regular expression logic ###
proc drone:nick:regexp:match:3 {string} {
 set nick [lindex [split $string !] 0]
 set ident [string trimleft [lindex [split $string !] 1] ~]
 set caps_in_ident [regexp -all {[A-Z]} $ident]
 if {[string match {*[-_^`|.]*} $string]} { return 0 }
 if {[info exists no_repeating_characters]} { unset no_repeating_characters }
 if {([regexp -all {[A-Z]} $nick] == 1) && ([regexp -all {[0-9]} $string] == 0) && [string isupper [string index $nick 0]]} { return 0 }
 if {[regexp \[\\\[\\\]\\\\{}\] $string] && ($caps_in_ident > 1)} { incr caps_in_ident -1 }
 for {set i 0} {$i < 20} {incr i} {
  if {([regexp -nocase all [string index "bcdfghjklmnpqrstvwxz" $i] $nick] > 2) || ([regexp -nocase all [string index "bcdfghjklmnpqrstvwxz" $i] $ident] > 3)} {
   set no_repeating_characters 0; break
   }
 }
 if {![info exists no_repeating_characters]} { set no_repeating_characters 1 }
 if {([regexp -all \[bcdfghjklmnpqrstvwxz\\\[\\\]\\\\{}\]{3,} $string] > 0) && ([regexp -all {[A-Z]} $nick] < 2) && ($caps_in_ident < 2) && ([regexp -nocase -all {[aeiouy]} $string] < 6) && ([regexp -nocase -all {[0-9]} $string] < 3) && ($no_repeating_characters == 1)} { return 1
 } else { return 0 }
}


proc create:drone:kick:file {dronekickfile} {
  putlog "\[RANDOM DRONE NICK REMOVER\] ERROR: The \002drone nick 'kick counter' file\002 does not exist!"
  putlog "Creating drone kick counter file: \002$dronekickfile\002"
  set file [open $dronekickfile "w"]
  puts $file 1; close $file
}

proc drone:kick:counter {nick uhost handle chan target reason} {
 global dronekickfile dronekickcountertype
  if {[isbotnick $nick] && ![isbotnick $target] && ($dronekickcountertype == 1)} {
   if {![file exists $dronekickfile]} {
    create:drone:kick:file $dronekickfile
   } elseif {[string match -nocase "*random*" $reason] || [string match -nocase "*drone*" $reason]} {
    set file [open $dronekickfile "r"]
    set currentkicks [gets $file]; close $file
    set file [open $dronekickfile "w"]
    puts $file [expr $currentkicks + 1]; close $file
    }
  }
}


### Thanks to 'user' for this banmask selector ###
proc drone:banmask [list name [list type $dronebanmasktype]] {
   if {[scan $name {%[^!]!%[^@]@%s} nick user host]!=3} {
      error "Usage: drone: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
}


putlog "\[LOADED\] Random Drone Nick Remover v8.19.b by \002awyeah (awyeah@awyeah.org)\002"
if {$dronechantype == 1} { putlog "ACTIVE: Random Drone Nick Remover is enabled on: \002[string tolower $dronechannels]\002"
} elseif {$dronechantype == 2} { putlog "ACTIVE: Random Drone Nick Remover is enabled on: \002All the channels the bot is on\002"
} else { putlog "\[UNLOADED\] Random Drone Nick Remover: \002No channel type selected.\002" }

if {($dronechantype == 1) || ($dronechantype == 2)} {
if {$dronemoduletype == 1} { putlog "RANDOM DRONE NICK REMOVER: \002NICK SCORE\002 module enabled."
} elseif {$dronemoduletype == 2} { putlog "RANDOM DRONE NICK REMOVER: \002NICK PATTERN\002 module enabled."
} elseif {$dronemoduletype == 3} { putlog "RANDOM DRONE NICK REMOVER: \002REGULAR EXPRESSION\002 module enabled."
} elseif {$dronemoduletype == 4} { putlog "RANDOM DRONE NICK REMOVER: \002NICK SCORE\002 and \002NICK PATTERN\002 modules enabled."
} elseif {$dronemoduletype == 5} { putlog "RANDOM DRONE NICK REMOVER: \002NICK SCORE\002 and \002REGULAR EXPRESSION\002 modules enabled."
} elseif {$dronemoduletype == 6} { putlog "RANDOM DRONE NICK REMOVER: \002NICK PATTERN\002 and \002REGULAR EXPRESSION\002 modules enabled."
} elseif {$dronemoduletype == 7} { putlog "RANDOM DRONE NICK REMOVER: \002NICK SCORE\002, \002NICK PATTERN\002 and \002REGULAR EXPRESSION\002 modules enabled."
} else { putlog "\002RANDOM DRONE NICK REMOVER:\002 No drone nick module selected." }
}

return
