You can see the original script request here http://forum.egghelp.org/viewtopic.php?t=20951
Code: Select all
#####################################################################################
# Public Kick/Ban Script (with stored nick!uhost info & extended mute bans)
#
# pkb.tcl version 1.5 by SpiKe^^ (29July2021)
#####################################################################################
# This script saves the nick!uhost of everyone leaving the channel (quit/part/kick).
# The info is saved for 15 minutes & allows for setting a ban on a nick that is gone.
#
# This script will not target any protected nicks. Protected nicks are anyone who:
# a) is/was op or halfop in the target channel
# b) has a +o or +b access flag in the eggdrop userfile
# c) is/was in any one of the admin channels
#
# This script has 6 basic public commands (all 6 can be prefixed with a . or a !)
# !kb nick :kick and ban nick from the channel the command was typed in
# !k nick :kick nick from the channel the command was typed in
# !b nick :set a ban on nick in the command channel (use default ban_masktype)
# !m nick :set an extended mute ban on nick (use default mute_masktype)
# !ub nick :remove any and all bans/mutes keeping nick from joining/talking
# !um nick :remove any and all mutes keeping nick from talking
#
# There are also several command options for all of the public commands
# !kb nick nick2 nick3 :kick and ban all listed nicks from the command channel
# .k nick .A new reason :set a new custom kick reason for this kick command
# !b nick nick2 10 :set the ban time for these two bans to 10 minutes
# .m #sumchannel nick :change the target channel for this mute to #sumchannel
# !kb #chan #chan2 nick :kick/ban nick from both #chan and #chan2
#
# You can also set and remove specific ban masks
# .kb nick!*@ahost.com *!me@*.host.org :set 2 bans and kick any nicks that match
# !b bart! @host.org 30 :set bans bart!*@* and *!*@host.org for 30 minutes
#
#####################################################################################
#### Script Settings ####
# set default ban/mute times (in minutes) #
# 0 = this script doesn't remove bans/mutes #
set pkb(kb_bantime) 60
set pkb(b_bantime) 5
set pkb(m_mutetime) 60
# set the default kick reason for the .k and .kb commands #
# note: set empty to not use any defailt kick reason #
set pkb(kreason) "Stop that."
set pkb(kbreason) "Go away."
# set mask type for bans and mutes #
# https://docs.eggheads.org/mainDocs/tcl-commands.html#maskhost-nick-user-host-masktype #
set pkb(ban_masktype) 2
set pkb(mute_masktype) 4
# set the extended mute ban prefix for your network (set empty for no mute prefix) #
set pkb(mute_maskpre) "~q:"
# max number of bans/devoice to stack in one mode command (1 or more) #
set pkb(maxban) 6
# max number of kicks to stack in one kick command (1 or more) #
set pkb(maxkick) 3
# protected hosts #
# set only username bans on these domains (ex. *!uid123457@*) #
set pkb(phosts) "*.irccloud.com *.mibbit.com *.kiwiirc.com *.8C39393E.IP"
# set one or more admin channels (or leave empty for no admin chan) #
# note: these channels must be limited access! everyone in these channels #
# will have access to all the commands in this script. #
# note: all pkb commands done in these channels will apply to pkb(main_chan) #
set pkb(admin_chan) ""
# set one or more default target channels (or leave empty for no default chan) #
# note: these apply to all pkb commands done in a pkb(admin_chan) #
set pkb(main_chan) ""
# change the number of minutes to store nick!uhost info (default = 15 minutes) #
# note: leave empty for default 15 min (set 0 to not store any nick!uhost info) #
set pkb(store_time) ""
# when setting a ban, this script will check if isvoiced nick, and -v if needed #
# 0 = never mix modes -v and +b in the same mode command to the server #
# 1 = when possible, mix modes -v and +b in the same mode command to the server #
set pkb(mix_mode) 1
#############################################################
##################### END OF SETTINGS #####################
#############################################################
bind pub -|- !k pub:kick
bind pub -|- .k pub:kick
proc pub:kick {nk uh hn ch tx} { pub:kickban $nk $uh $hn $ch $tx k }
bind pub -|- !b pub:ban
bind pub -|- .b pub:ban
proc pub:ban {nk uh hn ch tx} { pub:kickban $nk $uh $hn $ch $tx b }
bind pub -|- !m pub:muteban
bind pub -|- .m pub:muteban
proc pub:muteban {nk uh hn ch tx} { pub:kickban $nk $uh $hn $ch $tx m }
bind pub -|- !ub pub:unban
bind pub -|- .ub pub:unban
proc pub:unban {nk uh hn ch tx} { pub:kickban $nk $uh $hn $ch $tx ub }
bind pub -|- !um pub:unmute
bind pub -|- .um pub:unmute
proc pub:unmute {nk uh hn ch tx} { pub:kickban $nk $uh $hn $ch $tx um }
bind pub -|- !kb pub:kickban
bind pub -|- .kb pub:kickban
proc pub:kickban {nk uh hn ch tx {do kb} } {
global pkb storehosts
if {$uh ne "Timer" && ![is:allowed $nk $hn $ch]} { return 0 }
set reason [string trim $pkb(kreason)]
if {$do eq "kb"} { set reason [string trim $pkb(kbreason)] }
if {[set idx [string first " ." $tx]] > -1} {
set txls [split [string trim [string range $tx 0 $idx]]]
set reason [string trim [string range $tx [incr idx 2] end]]
} else { set txls [split [string trim $tx]] }
set mmpre $pkb(mute_maskpre)
set nickls "" ; set tchan ""
foreach item $txls {
if {[string match "#*" $item]} {
if {[lsearch -nocase $tchan $item] == -1} { lappend tchan $item }
} elseif {[string is digit -strict $item]} { set btime $item
} elseif {[string match {*[!@]*} $item]} {
if {[string match u* $do]} { set orig $item }
set item [regsub -all -- {\*{2,}} $item {*}]
set len [llength [set ils [split $item "!@"]]]
if {$len == 2} { incr len
if {[string first "!" $item] > -1} { lappend ils "*"
} else { set ils [linsert $ils 0 "*"] }
}
if {$len == 3} { lassign $ils n u h
if {$n eq $mmpre} { set n "${n}*"
} elseif {$n eq ""} { set n "*" }
if {$u eq ""} { set u "*" }
if {$h eq ""} { set h "*" }
set bmask $n!$u@$h
} else { set bmask $item }
if {![string match u* $do]} {
if {$len > 3 || $bmask eq "*!*@*" || $bmask eq "$mmpre*!*@*"} {
putserv "NOTICE $nk :Error: $item is not a valid user mask."
} else { lappend nickls $bmask }
} else {
if {$bmask eq $orig} { lappend nickls $orig
} else { lappend nickls "$orig $bmask" }
}
} elseif {$item ne ""} { lappend nickls $item }
}
if {$tchan ne ""} {
foreach c $tchan {
if {![validchan $c]} {
putserv "NOTICE $nk :Error: $c is not a valid channel."
} elseif {[lsearch -nocase $pkb(admin_chan) $c] > -1} {
putserv "NOTICE $nk :Error: You can't target an admin channel: $c."
} elseif {![is:allowed $nk $hn $c]} {
putserv "NOTICE $nk :Error: You don't have proper permissions in $c."
} else { lappend chlist $c }
}
} elseif {[lsearch -nocase $pkb(admin_chan) $ch] > -1} {
if {![llength $pkb(main_chan)]} {
putserv "NOTICE $nk :No default channel set. You must specify a channel."
} else {
foreach c $pkb(main_chan) {
if {![validchan $c]} {
putserv "NOTICE $nk :Error: $c is not a valid channel."
} elseif {[lsearch -nocase $pkb(admin_chan) $c] > -1} {
putserv "NOTICE $nk :Error: (main_chan) can't target an admin channel: $c."
} else { lappend chlist $c }
}
}
} else { lappend chlist $ch }
if {![info exists chlist]} { return 0 }
if {![llength $nickls]} {
putserv "NOTICE $nk :Error: You must specify at least one nick or user mask."
return 0
}
if {[string match u* $do]} { set plus "-" } else { set plus "+" }
set seconds 0
if {[info exists btime]} {
if {[string match {[bm]} $do] || ($do eq "kb")} {
set seconds [expr {$btime * 60}]
}
} elseif {$do eq "m"} { set seconds [expr {$pkb(m_mutetime) * 60}]
} elseif {$do eq "b"} { set seconds [expr {$pkb(b_bantime) * 60}]
} elseif {$do eq "kb"} { set seconds [expr {$pkb(kb_bantime) * 60}] }
set masktype $pkb(ban_masktype)
if {[string match *m $do]} { set masktype $pkb(mute_masktype) }
## Begin : foreach ch $chlist ####
foreach ch $chlist {
if {[info exists userls]} { unset userls }
set bmasks "" ; set knicks "" ; set dvnicks ""
foreach nick [lsort -unique -nocase $nickls] {
set bmask ""
############ Begin: if [string match {*[!@]*} $nick] #################
if {[string match {*[!@]*} $nick]} {
set bmask $nick ; set nick ""
if {[string match u* $do]} { set got 0 ; set bmls [split $bmask]
foreach bmask $bmls {
if {($do eq "um") && ![string match $mmpre* $bmask]} {
set bmask $mmpre$bmask
}
if {[ischanban $bmask $ch]} { incr got
if {[lsearch -nocase $bmasks $bmask] == -1} { lappend bmasks $bmask }
}
}
if {$uh ne "Timer" && $got == 0} {
putserv "NOTICE $nk :[lindex $bmls 0] is not a current ban on $ch"
}
continue
}
if {![info exists userls]} { set clist [chanlist $ch]
foreach n $clist {
lappend userls [string tolower $n![getchanhost $n $ch]]
}
foreach {aname avalue} [array get storehosts [string tolower *@$ch]] {
set x [lindex [split $aname @] 0]![string tolower [lindex $avalue 0]]
if {$x ni $userls} { lappend userls $x }
}
}
set m $bmask
if {$mmpre ne "" && [string match $mmpre* $m]} {
set m [string range $m [string length $mmpre] end]
}
set ok "" ; set err ""
foreach user $userls {
if {[matchaddr $m $user]} { lassign [split $user !@] n u h
if {[onchan $n $ch]} { set hand [nick2hand $n $ch]
if {[is:exempt $n $hand $ch]} { set err $n ; break }
lappend ok $n
} else { set aname [string tolower "$n@$ch"]
if {![info exists storehosts($aname)]} { continue }
if {[lindex $storehosts($aname) 3] == 1} { set err $n ; break }
lappend ok $n
}
}
}
if {$err ne ""} {
putserv "NOTICE $nk :You can't target an exempt user on $ch: $err ($u@$h)"
continue
}
if {[string match {*[bm]} $do]} {
if {$do eq "m" || [string match $mmpre* $bmask]} { set m $mmpre$m }
if {[ischanban $m $ch]} {
putserv "NOTICE $nk :$m is already an active ban on $ch"
} elseif {[lsearch -nocase $bmasks $m] == -1} { lappend bmasks $m }
if {$do ne "kb"} {
foreach n $ok {
if {[isvoice $n $ch] && [lsearch -nocase $dvnicks $n] == -1} {
lappend dvnicks $n
}
}
}
}
if {[string match k* $do]} {
foreach n $ok {
if {[onchan $n $ch] && [lsearch -nocase $knicks $n] == -1} {
lappend knicks $n
}
}
}
continue
} ;############ END: if [string match {*[!@]*} $nick] ################
set aname [string tolower "$nick@$ch"]
if {[onchan $nick $ch]} {
set chost [getchanhost $nick $ch]
set hand [nick2hand $nick $ch]
set exempt [is:exempt $nick $hand $ch]
} elseif {[info exists storehosts($aname)] && ($do ne "k")} {
lassign $storehosts($aname) chost expire hand exempt
} else { putserv "NOTICE $nk :$nick is not on channel $ch" ; continue }
if {$exempt == 1} {
putserv "NOTICE $nk :You can't target an exempt user on $ch: $nick ($chost)"
continue
}
if {[string match u* $do]} { set found 0
foreach binfols [chanbans $ch] { set ban [lindex $binfols 0]
if {$do eq "um" && ![string match $mmpre* $ban]} { continue }
set m $ban
if {$mmpre ne "" && [string match $mmpre* $m]} {
set m [string range $m [string length $mmpre] end]
}
if {[matchaddr $m $nick!$chost]} { incr found
if {[lsearch -nocase $bmasks $ban] == -1} { lappend bmasks $ban }
}
}
if {$found == 0} {
if {$do eq "um"} { set x "mutes" } else { set x "bans" }
putserv "NOTICE $nk :No $x found for $nick on $ch"
}
continue
}
if {[string match {*[bm]} $do]} {
set bmask [mask:host $nick $chost $masktype $do]
if {[ischanban $bmask $ch]} {
putserv "NOTICE $nk :$bmask \[$nick\] is already a ban on $ch"
} elseif {[lsearch -nocase $bmasks $bmask] == -1} { lappend bmasks $bmask }
if {($do ne "kb") && [isvoice $nick $ch]} {
if {[lsearch -nocase $dvnicks $nick] == -1} { lappend dvnicks $nick }
}
}
if {[string match k* $do] && [onchan $nick $ch]} {
if {[lsearch -nocase $knicks $nick] == -1} { lappend knicks $nick }
}
}
if {$dvnicks ne ""} {
while {[set len [llength $dvnicks]] > 0} {
if {$len > $pkb(maxban)} {
set mode [string repeat "v" $pkb(maxban)]
set nicks [join [lrange $dvnicks 0 [expr {$pkb(maxban) - 1}]]]
set dvnicks [lrange $dvnicks $pkb(maxban) end]
} else {
set mode [string repeat "v" $len]
set nicks [join $dvnicks]
set dvnicks ""
if {$pkb(mix_mode) != 0 && $len < $pkb(maxban) && $bmasks ne ""} {
if {($len + [set blen [llength $bmasks]]) <= $pkb(maxban)} {
set mode ${mode}+[string repeat "b" $blen]
set nicks "$nicks [join $bmasks]"
set bmasks ""
}
}
}
putquick "MODE $ch -$mode $nicks"
}
}
if {$bmasks ne ""} {
if {$seconds > 0} {
utimer $seconds [list pub:kickban $nk Timer $hn $ch [join $bmasks] ub]
}
while {[set len [llength $bmasks]] > 0} {
if {$len > $pkb(maxban)} {
set mode [string repeat "b" $pkb(maxban)]
set masks [join [lrange $bmasks 0 [expr {$pkb(maxban) - 1}]]]
set bmasks [lrange $bmasks $pkb(maxban) end]
} else {
set mode [string repeat "b" $len]
set masks [join $bmasks]
set bmasks ""
}
putquick "MODE $ch $plus$mode $masks"
}
}
if {$knicks ne ""} {
while {[set len [llength $knicks]] > 0} {
if {$len > $pkb(maxkick)} {
set nicks [join [lrange $knicks 0 [expr {$pkb(maxkick) - 1}]] ","]
set knicks [lrange $knicks $pkb(maxkick) end]
} else {
set nicks [join $knicks ","]
set knicks ""
}
if {$reason eq ""} { putserv "KICK $ch $nicks"
} else { putserv "KICK $ch $nicks :$reason" }
}
}
} ;## END : foreach ch $chlist ####
}
set pkb(admin_chan) [split [string trim $pkb(admin_chan)] ", "]
set pkb(admin_chan) [lsort -unique -nocase $pkb(admin_chan)]
set pkb(main_chan) [split [string trim $pkb(main_chan)] ", "]
set pkb(main_chan) [lsort -unique -nocase $pkb(main_chan)]
#### code for who is allowed to use the public commands
proc is:allowed {nk hn ch} {
if {[isop $nk $ch] || [ishalfop $nk $ch] || [matchattr $hn o|o $ch]} { return 1 }
foreach achan $::pkb(admin_chan) {
if {[validchan $achan] && [onchan $nk $achan]} { return 1 }
}
return 0
}
#### code for who is exempt from the public commands
proc is:exempt {nk hn ch} {
if {[isop $nk $ch] || [ishalfop $nk $ch]} { return 1 }
if {[isbotnick $nk] || [matchattr $hn bo|bo $ch]} { return 1 }
foreach achan $::pkb(admin_chan) {
if {[validchan $achan] && [onchan $nk $achan]} { return 1 }
}
return 0
}
#### protected hosts & mask hosts code
set pkb(phosts) [split [string trim $pkb(phosts)]]
proc mask:host {nick chost masktype do} {
set bmask [maskhost "$nick!$chost" $masktype]
foreach phost $::pkb(phosts) {
if {[string match -nocase $phost $chost]} {
set bmask "*![lindex [split $chost @] 0]@*"
break
}
}
if {[string match *m $do]} { set bmask $::pkb(mute_maskpre)$bmask }
return $bmask
}
#### stored nicks & uhosts code
if {![string is digit -strict $pkb(store_time)]} { set pkb(stime) 900
} else { set pkb(stime) [expr {$pkb(store_time) * 60}] }
if {$pkb(stime) > 0} {
bind part - * store:hosts ; bind sign - * store:hosts
bind kick - * store:kick ; bind time - * expire:hosts
} elseif {[llength [binds store:hosts]]} {
unbind part - * store:hosts ; unbind sign - * store:hosts
unbind kick - * store:kick ; unbind time - * expire:hosts
array unset storehosts
}
proc store:hosts {nk uh hn ch msg} {
set allowed [is:allowed $nk $hn $ch]
set aname [string tolower $nk@$ch]
set ::storehosts($aname) [list $uh [expr {[unixtime]+$::pkb(stime)}] $hn $allowed]
}
proc store:kick {nk uh hn ch target reason} {
set uhost [getchanhost $target $ch]
set hand [finduser $target!$uhost]
store:hosts $target $uhost $hand $ch pkb.tcl
}
proc expire:hosts {mn hr da mo yr} {
global storehosts
set ut [unixtime]
foreach {aname avalue} [array get storehosts] {
if {$ut >= [lindex $avalue 1]} { unset storehosts($aname) }
}
}
putlog "Loaded pkb.tcl version 1.5"