Recently, I have been getting a lot of spam from IRCCloud as they have static IPs and it is impossible to detect it as a proxy or VPN connection.
That's why I am looking for a TCL that adds specific nicknames or hostnames to the IRCCloud exception list so the rest of the IRCCloud users can be kicked or banned until they are added to the IRCCloud exception list.
For this filter, I would choose hostnames as they are more static than nicknames. Something in this format;
uid*****@uid*****.irccloud.com
########## cloudGuard version 0.1 by SpiKe^^ (15Nov2022) ##########
## !! Add +cloudguard to channel(s) you want to protect: .chanset #channel +cloudguard ##
namespace eval clouded { variable cg
##### begin settings #####
#
set cg(badlist) { *!uid*@* *!~uid*@* }
#
set cg(goodlist) { }
# Set to 1 to ban users from the channel. (0 = no ban)
set cg(doban) 0
# Set to 1 to kick users from the channel. (0 = no kick)
set cg(dokick) 1
# Set the nick to get progress messages. ("" = don't send messages)
set cg(owner) ""
###### end settings ######
bind join - * [namespace current]::cloudguard_join
setudef flag cloudguard
set cg(badlist) [split [string trim $cg(badlist)]]
set cg(goodlist) [split [string trim $cg(goodlist)]]
if {$cg(doban) != 0} { set cg(doban) 1 }
if {$cg(dokick) != 0} { set cg(dokick) 1 }
set cg(owner) [string trim $cg(owner)]
proc cloudguard_join {nk uh hn ch} { variable cg
if {[isbotnick $nk] || ![channel get $ch cloudguard]} { return 0 }
if {$hn ne "*"} { return 0 } ;# exempt everyone with a handle #
if {![botisop $ch]} {
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :HELP! I do not have ops in $ch ($nk has joined)."
}
return 0
}
if {![llength $cg(badlist)]} {
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :The cg(badlist) setting is empty! cloudGuard script disabled."
}
return 0
}
set isbad 0 ; set nkuh "$nk!$uh"
foreach m $cg(badlist) {
if {[matchaddr $m $nkuh]} { set isbad 1 ; break }
}
if {$isbad == 0} { return 0 }
foreach m $cg(goodlist) {
if {[matchaddr $m $nkuh]} { return 0 }
}
if {$cg(doban) > 0} {
set usr [split $uh "@"]
pushmode $ch +b "*!${usr}@*"
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :Kicked $nk from $ch"
}
}
if {$cg(dokick) > 0} {
putkick $ch $nk
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :Banned $nk from $ch"
}
}
return 0
}
putlog "Loaded cloudGuard version 0.1"
} ;## end of: namespace eval ##
########## cloudGuard version 0.2 by SpiKe^^ (cg.tcl) 25Nov2022 ##########
###### cloudGuard Public Commands (eggdrop userfile flags ofn|ofn): ######
##
## !cg on :Enable cloudGuard in this channel
## !cg off :Disable cloudGuard in this channel
##
## !cg +bad <mask(s)> :Add badMasks to the badList
## !cg +good <mask(s)> :Add goodMasks to the goodList
## !cg -bad <mask(s)> :Remove badMasks from the badList
## !cg -good <mask(s)> :Remove goodMasks from the goodList
##
## !cg lbad :List the badMasks in the badList
## !cg lgood :List the goodMasks in the goodList
## Note: Add <mask(s)> can be full irc nk!usr@host masks or any part of that.
## Masks without a ! or @ will be treated as a nick mask (nick!*@*).
## All other masks are referenced by the location(s) of the ! and/or @.
## Examples:
## !cguard addbad bart :adds the badMask: bart!*@*
## !cg +bad tom jerry :adds the badMasks: tom!*@* & jerry!*@*
## !cg +b @*.irccloud.com :adds the badMask: *!*@*.irccloud.com
## !cg +b !uid* ~uid*@* :adds the badMasks: *!uid*@* *!~uid*@*
## !cg +good !~george :adds the goodMask: *!~george@*
## !cg +g uid487201@ :adds the goodMask: *!uid487201@*
namespace eval cloudguard { variable cg
########### begin settings ###########
# Set to 1 to ban users from the channel. (0 = no ban)
set cg(doban) 0
# Set to 1 to kick users from the channel. (0 = no kick)
set cg(dokick) 1
# Set one nick to get progress messages. ("" = don't send messages)
set cg(owner) ""
############ end settings ############ end settings ############
setudef flag [string trim [namespace current] :]
###################################
###### Public admin commands ######
bind pubm ofn|ofn "#% !cg*" [namespace current]::cg_onpub
bind pubm ofn|ofn "#% !cloud*" [namespace current]::cg_onpub
proc cg_onpub {nk uh hn ch tx} { variable cg
set tx [regsub -all -- {\s{2,}} [string trim $tx] { }]
set argls [lassign [split $tx] cmd opt]
if {[string tolower $cmd] ni {!cg !cguard !cloud !cloudg !cloudguard}} { return 0 }
set o [string tolower $opt]
set uflag [string trim [namespace current] :]
#putlog "proc cg_onpub:: uflag=($uflag)"
if {$o in {+bad +b addbad addb}} { set y "+" ; set x "b"
} elseif {$o in {+good +g addgood addg}} { set y "+" ; set x "g"
} elseif {$o in {-bad -b delbad delb}} { set y "-" ; set x "b"
} elseif {$o in {-good -g delgood delg}} { set y "-" ; set x "g"
} elseif {$o in {lbad lb listbad listb}} { set y "l" ; set x "b"
} elseif {$o in {lgood lg listgood listg}} { set y "l" ; set x "g"
} elseif {$o in {on}} {
if {[channel get $ch $uflag]} {
puthelp "PRIVMSG $ch :The cloudGuard script is already enabled on $ch"
} else { channel set $ch +$uflag
puthelp "PRIVMSG $ch :The cloudGuard script is now enabled on $ch"
}
return 0
} elseif {$o in {off}} {
if {![channel get $ch $uflag]} {
puthelp "PRIVMSG $ch :The cloudGuard script is already disabled on $ch"
} else { channel set $ch -$uflag
puthelp "PRIVMSG $ch :The cloudGuard script is now disabled on $ch"
}
return 0
}
if {[info exists x]} {
if {![channel get $ch $uflag]} { return 0 }
if {$x eq "b"} { set z "bad" } else { set z "good" }
if {$y eq "+" || $y eq "-"} {
if {![llength $argls]} {
puthelp "PRIVMSG $ch :Command syntax: \002!cg $o <mask(s)>\002"
return 0
}
###### ADD Masks ######
if {$y eq "+"} { set addls {} ; set err {} ; set e2 {}
foreach m $argls { set m [regsub -all -- {\*{2,}} $m "*"]
if {[matchstr *!*!* $m] || [matchstr *@*@* $m] || $m eq "*"} { lappend err $m
} else { set m2 $m ;# fix/complete partial addMasks #
if {![string match {*[!@]*} $m]} { append m2 "!" }
set nuhls [split $m2 "!@"]
if {![matchstr *!* $m2]} { set n "" ; lassign $nuhls u h
} else { lassign $nuhls n u h }
foreach p {n u h} { if {[set $p] eq ""} { set $p "*" } }
set m2 ${n}!${u}@$h
if {$m2 eq "*!*@*"} { lappend err $m
} else {
if {[lsearch -nocase -exact $cg(_${x}list) $m2] >= 0} { lappend e2 $m2
} else { lappend addls $m2 ; lappend cg(_${x}list) $m2 }
}
}
} ;# end of foreach #
if {[set len [llength $addls]] > 0} { cg_savefile $x ;# update the file #
if {$len > 1} { set tm "${z}Masks" } else { set tm "${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard> Added $len new ${tm}: [join $addls]"
}
if {[set len [llength $err]] > 0} {
if {$len > 1} { set tm "${z}Masks" } else { set tm "${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard Error> Found $len invalid ${tm}: [join $err]"
}
if {[set len [llength $e2]] > 0} {
if {$len > 1} { set tm "$len ${z}Masks" } else { set tm "one ${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard Error> Found ${tm} already listed: [join $e2]"
}
return 0
} ;# end if is + #
######
###### DEL Masks ######
if {$y eq "-"} { set dells {} ; set err {}
if {![llength $cg(_${x}list)]} {
puthelp "PRIVMSG $ch :<cloudGuard> The ${z}List is empty."
return 0
}
foreach m $argls {
if {[set id [lsearch -nocase -exact $cg(_${x}list) $m]] < 0} { lappend err $m
} else { lappend dells $m
set cg(_${x}list) [lreplace $cg(_${x}list) $id $id]
}
}
if {[set len [llength $dells]] > 0} { cg_savefile $x ;# update the file #
if {$len > 1} { set tm "$len ${z}Masks" } else { set tm "one ${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard> Removed ${tm}: [join $dells]"
}
if {[set len [llength $err]] > 0} {
if {$len==1} { set tm "One ${z}Mask doesn't" } { set tm "$len ${z}Masks don't" }
puthelp "PRIVMSG $ch :<cloudGuard Error> ${tm} exist: [join $err]"
}
return 0
} ;# end if is - #
######
} ;# end if $y eq "+" || $y eq "-" #
###### LIST Masks ######
if {$y eq "l"} { set cls $cg(_${x}list)
if {[set len [llength $cls]] == 0} {
puthelp "PRIVMSG $ch :<cloudGuard> The ${z}List is empty."
return 0
}
if {$len > 1} { set tm "$len ${z}Masks" } else { set tm "One ${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard> ${tm} in the list: [join $cls]"
return 0
} ;# end if is l #
######
} ;# end if info exists x #
return 0
}
##################################
###### Onjoin user checking ######
bind join - * [namespace current]::cg_onjoin
proc cg_onjoin {nk uh hn ch} { variable cg
if {[isbotnick $nk] || ![channel get $ch [string trim [namespace current] :]]} { return 0 }
if {$hn ne "*"} { return 0 } ;# exempt everyone with a handle #
if {![botisop $ch]} {
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :HELP! $nk ($uh) has joined $ch & I don't have ops there."
}
return 0
}
if {![llength $cg(_blist)]} {
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :The badMask list is empty! cloudGuard script is disabled."
puthelp "PRIVMSG $cg(owner) :To add a badMask now, use: \002!cg +bad <mask(s)>\002"
}
return 0
}
set isbad 0 ; set nkuh "$nk!$uh"
foreach m $cg(_blist) {
if {[matchaddr $m $nkuh]} { set isbad 1 ; break }
}
if {$isbad == 0} { return 0 }
foreach m $cg(_glist) {
if {[matchaddr $m $nkuh]} { return 0 }
}
if {$cg(doban) > 0} { set usr [lindex [split $uh "@"] 0]
pushmode $ch +b "*!${usr}@*"
if {$cg(owner) ne "" && $cg(dokick) == 0} {
puthelp "PRIVMSG $cg(owner) :Banned $nk ($uh) from $ch"
}
}
if {$cg(dokick) > 0} {
putkick $ch $nk
if {$cg(owner) ne "" && $cg(doban) == 0} {
puthelp "PRIVMSG $cg(owner) :Kicked $nk ($uh) from $ch"
}
}
if {$cg(doban) > 0 && $cg(dokick) > 0 && $cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :Kick/banned $nk ($uh) from $ch"
}
return 0
}
#########################
# cleanup some settings #
if {$cg(doban) != 0} { set cg(doban) 1 }
if {$cg(dokick) != 0} { set cg(dokick) 1 }
set cg(owner) [string trim $cg(owner)]
########################
###### file stuff ######
#Name of badList file.
set cg(bfile) "scripts/cg_[string trim [namespace current] :]_badlist.txt"
#Name of goodList file.
set cg(gfile) "scripts/cg_[string trim [namespace current] :]_goodlist.txt"
proc cg_onload {} { variable cg
foreach x {b g} {
set cg(${x}file) [string trim $cg(${x}file)]
if {![file exists $cg(${x}file)]} {
set openfile [open $cg(${x}file) a] ;## cg(bfile) || cg(gfile) ##
close $openfile
set cg(_${x}list) {} ;## sets var: cg(_blist) || cg(_glist) ##
}
if {![info exists cg(_${x}list)]} {
set openfile [open $cg(${x}file) r]
set cg(_${x}list) [split [read -nonewline $openfile] "\n"]
close $openfile
}
}
}
cg_onload
proc cg_savefile { {x g} } { variable cg ;## $x can be: (b || g) ##
set openfile [open $cg(${x}file) w]
puts $openfile [join $cg(_${x}list) "\n"]
close $openfile
}
putlog "Loaded cloudGuard version 0.2 25Nov2022"
} ;## end of: namespace eval ##
This is the next ver script with the public commands 99% done.
No further work has been done to the onjoin functions yet.
Read the script header for all of the public commands functions.
######### cloudGuard version 0.3 by SpiKe^^ (cg.tcl) ###### 12Dec2022 ##########
# #
# cg.tcl is: "A Blacklist Script (badList), with an Exemption List (goodList)." #
# #
# When any user joins a valid cloudGuard channel: #
# 1) Everyone joining the channel is first checked against the badList, and if no #
# matching badMask is found, that user is exempt from this script entirely. #
# 2) Users that were matched by a badMask, are next checked against the goodList. #
# If a matching goodMask is found, that user is also exempt from this script. #
# 3) All users that still are not exempt, may be banned/kicked/or something else. #
# #
# - The script has public commands to enable/disabel this protection by channel. #
# - Script also has public commands to edit and view the badList/goodList files. #
# #
#####################################################################################
######## Public Admin Commands (eggdrop userfile flags ofn|ofn): ########
##
## !cg on :Enable cloudGuard in this channel
## !cg off :Disable cloudGuard in this channel
##
## !cg +bad <mask(s)> :Add badMasks to the badList
## !cg +good <mask(s)> :Add goodMasks to the goodList
## !cg -bad <mask(s)> :Remove badMasks from the badList
## !cg -good <mask(s)> :Remove goodMasks from the goodList
##
## !cg listb :List the badMasks in the badList
## !cg listg :List the goodMasks in the goodList
## !cg findb <mask> :Do a wildcard search of the badList
## !cg findg <mask> :Do a wildcard search of the goodList
##
## Notes for Add/Remove Masks commands:
## <mask(s)> can be full irc nk!usr@host masks or any part of that.
## Masks without a ! or @ will be treated as a username mask (*!username@*).
## All other masks are referenced by the location(s) of the ! and/or @.
## Examples:
## !cguard +good uid487201 :adds the goodMask: *!uid487201@*
## !cg +g uid84725 uid58739 :adds the goodMasks: *!uid86725@* & *!uid58739@*
## !cg +bad !uid* ~uid*@ :adds the badMasks: *!uid*@* & *!~uid*@*
## !cg -b @*.irccloud.com :remove the badMask: *!*@*.irccloud.com
## !cg -g tom! dick! harry! :remove the goodMasks: tom!*@*, dick!*@* & harry!*@*
##
## Notes for the Delete-by-Number commands only:
## You can remove masks by the numbers assigned to each in your last list/find.
## Saved results expire after a while of inactivity (change in the settings).
## Examples:
## !cg -bad 4 :remove the badMask numbered [4] on your last saved list/find
## !cg -g 7 4 12 :remove the goodMasks currently numbered [4] [7] and [12]
##
namespace eval cloudguard { variable cg ; variable lists
########### begin settings ###########
# Set to 1 to ban users from the channel. (0 = no ban)
set cg(doban) 0
# Set to 1 to kick users from the channel. (0 = no kick)
set cg(dokick) 0
# Set one nick to get progress messages. ("" = don't send messages)
set cg(owner) ""
# For public add/remove commands: masks without a ! or @ will be treated as...
set cg(def_amask) 2 ;# 1 = nick || (default) 2 = username || 3 = host #
# For public list/find commands: ...
set cg(max_masks) 10
set cg(max_chars) 250 ;# max length of the text only (before colors/bolds) #
set cg(max_msg) 410 ;# server max length for all messages (including colors/bolds) #
# Saved find/list results expire after is idle for this long.
set cg(xpire_list) 5 ;# time in minutes #
############ end settings ############ end settings ############
setudef flag [string trim [namespace current] :]
###################################
###### Public admin commands ######
bind pubm ofn|ofn "#% !cg*" [namespace current]::cg_onpub
bind pubm ofn|ofn "#% !cloud*" [namespace current]::cg_onpub
proc cg_onpub {nk uh hn ch tx} { variable cg ; variable lists
set tx [regsub -all -- {\s{2,}} [string trim $tx] { }]
set argls [lassign [split $tx] cmd opt]
if {[string tolower $cmd] ni {!cg !cguard !cloud !cloudg !cloudguard}} { return 0 }
set o [string tolower $opt]
set arg0 [string tolower [lindex $argls 0]]
set uflag [string trim [namespace current] :]
set idx [string tolower $nk] ; set ut [unixtime]
if {$o in {on enable}} {
if {[channel get $ch $uflag]} {
puthelp "PRIVMSG $ch :The cloudGuard script is already enabled on $ch"
} else { channel set $ch +$uflag
puthelp "PRIVMSG $ch :The cloudGuard script is now enabled on $ch"
}
return 0
}
if {$o in {off disable}} {
if {![channel get $ch $uflag]} {
puthelp "PRIVMSG $ch :The cloudGuard script is already disabled on $ch"
} else { channel set $ch -$uflag
puthelp "PRIVMSG $ch :The cloudGuard script is now disabled on $ch"
}
return 0
}
if {$o in {+bad +b ab addb addbad}} { set y "+" ; set x "b"
} elseif {$o in {+good +g ag addg addgood}} { set y "+" ; set x "g"
} elseif {$o in {-bad -b db delb delbad}} { set y "-" ; set x "b"
} elseif {$o in {-good -g dg delg delgood}} { set y "-" ; set x "g"
} elseif {$o in {listb lb lbad listbad}} { set y "l" ; set x "b"
} elseif {$o in {listg lg lgood listgood}} { set y "l" ; set x "g"
} elseif {$o in {findb fb fbad findbad}} { set y "f" ; set x "b"
} elseif {$o in {findg fg fgood findgood}} { set y "f" ; set x "g" }
if {[info exists x]} {
if {![channel get $ch $uflag]} { return 0 }
if {$x eq "b"} { set z "bad" } else { set z "good" }
set mls $cg(_${x}list)
set fullls {}
if {[info exists lists($idx)]} { set q [lindex $lists($idx) end]
if {($q +($cg(xpire_list)*60)) <= $ut} { array unset lists $idx ;# expire old #
} else { set _x [lindex $lists($idx) 1]
if {$_x eq $x} { set fullls [lindex $lists($idx) 7] }
}
}
######################################
if {$y eq "+" || $y eq "-"} {
if {![llength $argls]} {
puthelp "PRIVMSG $ch :<cloudGuard> Command syntax: \002!cg $o <mask(s)>\002"
return 0
}
if {$y eq "-" && ![llength $mls]} {
puthelp "PRIVMSG $ch :<cloudGuard> The ${z}List is empty."
return 0
}
if {$y eq "-"} { set llen [llength $mls]
if {[llength $fullls]} { set llen [llength $fullls] }
set over [expr {$llen / 2}]
if {$over < 20} { set over 20 } elseif {$over > 60} { set over 60 }
incr over $llen
}
set newls {} ; set err {} ; set e2 {}
set numls {} ; set e3 {} ; set e4 {}
#### page thru the raw command arguments. ## Sort input into several lists #
foreach m $argls { set m [regsub -all -- {\*{2,}} $m "*"]
if {$y eq "-" && [string is digit $m] && [string index $m 0] > 0} {
if {$m <= $over} {
if {$fullls eq ""} { lappend e3 $m ;# no saved list || wrong list #
} elseif {$m > $llen} { lappend e4 $m ;# input number out or range #
} elseif {[lsearch $numls $m] < 0} {
lappend numls $m ; lappend newls $m
}
continue
}
}
if {[matchstr *!*!* $m] || [matchstr *@*@* $m] || $m eq "*"} { lappend err $m
} else { set m2 $m ;# fix/complete partial add/remove masks #
if {![string match {*[!@]*} $m]} {
if {$cg(def_amask) == 2} { append m2 "@"
} elseif {$cg(def_amask) == 3} { set m2 "@$m2"
} else { append m2 "!" }
}
set nuhls [split $m2 "!@"]
if {![matchstr *!* $m2]} { set n "" ; lassign $nuhls u h
} else { lassign $nuhls n u h }
foreach p {n u h} { if {[set $p] eq ""} { set $p "*" } }
set m2 ${n}!${u}@$h
if {$m2 eq "*!*@*"} { lappend err $m ;# input mask is not valid #
} elseif {[lsearch -nocase -exact $newls $m2] < 0} { lappend newls $m2 }
}
}
####
###### ADD Masks and say what. ######
if {$y eq "+"} { set addls {}
foreach m $newls {
if {[lsearch -nocase -exact $cg(_${x}list) $m] >= 0} { lappend e2 $m ;#mask already exists
} else { lappend addls $m ; lappend cg(_${x}list) $m }
}
if {[set len [llength $addls]] > 0} { cg_savefile $x ;# update the file #
if {$len > 1} { set tm "${z}Masks" } else { set tm "${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard> Added $len new ${tm}: [join $addls]"
}
if {[set len [llength $err]] > 0} {
if {$len > 1} { set tm "${z}Masks" } else { set tm "${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard Error> Found $len invalid ${tm}: [join $err]"
}
if {[set len [llength $e2]] > 0} {
if {$len > 1} { set tm "$len ${z}Masks" } else { set tm "one ${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard Error> Found ${tm} already listed: [join $e2]"
}
return 0
} ;# end if is + #
######
###### DEL Masks and say what. ######
if {$y eq "-"} { set dells {}
if {[llength $numls]} { set nls {}
foreach m $newls {
if {![string is digit $m]} { set m2 $m
} else { set m2 [lindex [split [lsearch -inline $fullls "$m *"]] 1] }
if {[lsearch -nocase -exact $nls $m2] < 0} { lappend nls $m2 }
}
set newls $nls
lset lists($idx) end $ut
}
foreach m $newls {
if {[set id [lsearch -nocase -exact $cg(_${x}list) $m]] >= 0} {
lappend dells $m ; set cg(_${x}list) [lreplace $cg(_${x}list) $id $id]
} else { lappend e2 $m } ;# mask already deleted #
}
if {[set len [llength $dells]] > 0} { cg_savefile $x ;# update the file #
if {$len > 1} { set tm "$len ${z}Masks" } else { set tm "one ${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard> Removed ${tm}: [join $dells]"
}
if {[set len [llength $err]] > 0} {
if {$len > 1} { set tm "${z}Masks" } else { set tm "${z}Mask" }
puthelp "PRIVMSG $ch :<cloudGuard Error> Found $len invalid ${tm}: [join $err]"
}
if {[set len [llength $e2]] > 0} {
if {$len==1} { set tm "This ${z}Mask doesn't"} { set tm "$len ${z}Masks don't"}
puthelp "PRIVMSG $ch :<cloudGuard Error> ${tm} exist: [join $e2]"
}
if {[set len [llength $e3]] > 0} {
set tm "Can't delete-by-number, you have no saved ${z}List results."
if {$len==1} { set q "one mask number" } else { set q "$len mask numbers" }
puthelp "PRIVMSG $ch :<cloudGuard Error> ${tm} Ignored ${q}: [join $e3]"
}
if {[set len [llength $e4]] > 0} {
set tm "Delete-by-number out of range ([llength $fullls])."
if {$len==1} { set q "one mask number" } else { set q "$len mask numbers" }
puthelp "PRIVMSG $ch :<cloudGuard Error> ${tm} Ignored ${q}: [join $e4]"
}
return 0
} ;# end if is - #
######
} ;# end if $y eq "+" || $y eq "-" #
######################################
######################################
###### LIST/FIND Masks ######
if {$y eq "l" || $y eq "f"} {
if {[set len [llength $mls]] == 0} {
puthelp "PRIVMSG $ch :<cloudGuard> The ${z}List is empty."
return 0
}
if {$y eq "f"} {
set find [regsub -all -- {\*{2,}} "*${arg0}*" "*"]
if {$find eq "*"} { set find "" }
} else { set find "" }
if {[info exists lists($idx)]} {
lassign $lists($idx) _y _x _nk _uh _hn _ch _find _tls _tl2 _ut _u2
if {$_y ne $y || $_x ne $x} { array unset lists $idx
} elseif {$y eq "l" && $arg0 eq "new"} { array unset lists $idx
} elseif {$find ne "" && $find ne $_find} { array unset lists $idx
} elseif {![llength $_tl2]} { ;# run the Same list/search again... #
set issamels $lists($idx) ; array unset lists $idx
}
}
#### if this nk doesnt have a saved list: Make a New saved List/search var #
if {![info exists lists($idx)]} { set new $ut
if {[info exists issamels]} { set find $_find ; set new $_ut }
if {$y eq "f" && $find eq ""} {
puthelp "PRIVMSG $ch :<cloudGuard> Command syntax: \002!cg $o <searchstring>\002"
return 0
}
if {$y eq "f"} { set lsnow {}
foreach m $mls { if {[matchstr $find $m]} { lappend lsnow $m } }
if {![llength $lsnow]} {
puthelp "PRIVMSG $ch :<cloudGuard> Found no ${z}Masks matching: $find"
return 0
}
} else { set lsnow $mls }
set cnt 0 ; set tls {} ; set tl2 {} ; set isnewls 1
foreach m $lsnow { incr cnt
lappend tls "$cnt $m" ; lappend tl2 $cnt
}
lappend lists($idx) $y $x $nk $uh $hn $ch $find $tls $tl2 $new $ut
} ;# 0 1 2 3 4 5 6 7 8 9 10 #
####
#### Build the say Text: first add a list-line header #
lassign $lists($idx) _y _x _nk _uh _hn _ch _find fullls restls new last
set say "<cloudGuard> " ; set wo "$say " ;# say = text w/ bolds # wo = without bolds
set cnt [llength $fullls] ;# cnt = total masks in this list or search results #
if {[info exists issamels]} {
if {$y eq "f"} { puthelp "PRIVMSG $ch :=> Re-searching the ${z}List..."
} else { puthelp "PRIVMSG $ch :=> Re-listing All ${z}Masks..." }
}
if {[info exists isnewls]} { ;# if this is a New List/search #
if {$y eq "f"} {
if {$cnt == 1} { set tm "one matching ${z}Mask"
} else { set tm "$cnt matching ${z}Masks" }
append say "Found ${tm}:" ; append wo "Found ${tm}:"
} else {
if {$cnt > 1} { set tm "$cnt ${z}Masks" } else { set tm "One ${z}Mask" }
append say "$tm in the ${z}List:" ; append wo "$tm in the ${z}List:"
}
} else { ;# else this is Not a New list/search #
if {$y eq "f"} { append say "Show more search results:"
append wo "Show more search results:"
} else { append say "List more ${z}Masks:"
append wo "List more ${z}Masks:"
}
}
####
#### Build the say Text: next add as many list items as possible... #
set end " \002and xx more...\002" ; set en2 " and xx more..."
set first [lindex $restls 0] ; set lcnt 0
foreach tm [lrange $fullls [expr {$first - 1}] end] {
lassign [split $tm] num m
set next " \002\[${num}\]\002 $m" ; set nex2 " \[${num}\] $m"
set with [string length "${say}$next"]
set wout [string length "${wo}$nex2"]
if {[llength $restls] > 1} {
incr with [string length $end] ; incr wout [string length $en2]
}
# if there is room for the next list item...
if {$with <= $cg(max_msg) && $wout <= $cg(max_chars)} {
append say $next ; append wo $nex2
set restls [lreplace $restls 0 0] ; incr lcnt
# End of List/results. close out the list foreach #
if {![llength $restls]} {
if {![info exists isnewls]} {
set end " \002End of list.\002" ; set en2 " End of list."
if {[string length "${say}$end"] >= ($cg(max_msg) + 5)} {
append say " \002EoL\002" ; append wo " EoL"
} else { append say $end ; append wo $en2 }
}
break
}
if {$lcnt == $cg(max_masks)} { set map [list "xx" [llength $restls]]
append say [string map $map $end] ; append wo [string map $map $en2]
break
}
# else there is No room for the next list item...
} else { set map [list "xx" [llength $restls]]
append say [string map $map $end] ; append wo [string map $map $en2]
break
}
} ;# end of: foreach tm [lrange $fullls....
####
puthelp "PRIVMSG $ch :$say"
set lists($idx) [list $_y $_x $_nk $_uh $_hn $_ch $_find $fullls $restls $new $ut]
return 0
} ;# end if is l or f #
######
######################################
} ;# end if info exists x #
return 0
}
##################################
###### Onjoin user checking ######
bind join - * [namespace current]::cg_onjoin
proc cg_onjoin {nk uh hn ch} { variable cg
if {[isbotnick $nk] || ![channel get $ch [string trim [namespace current] :]]} { return 0 }
if {$hn ne "*"} { return 0 } ;# exempt everyone with a handle #
if {![botisop $ch]} {
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :HELP! $nk ($uh) has joined $ch & I don't have ops there."
}
return 0
}
if {![llength $cg(_blist)]} {
if {$cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :The badMask list is empty! cloudGuard script is disabled."
puthelp "PRIVMSG $cg(owner) :To add a badMask now, use: \002!cg +bad <mask(s)>\002"
}
return 0
}
set isbad 0 ; set nkuh "$nk!$uh"
foreach m $cg(_blist) {
if {[matchaddr $m $nkuh]} { set isbad 1 ; break }
}
if {$isbad == 0} { return 0 }
foreach m $cg(_glist) {
if {[matchaddr $m $nkuh]} { return 0 }
}
if {$cg(doban) > 0} { set usr [lindex [split $uh "@"] 0]
pushmode $ch +b "*!${usr}@*"
if {$cg(owner) ne "" && $cg(dokick) == 0} {
puthelp "PRIVMSG $cg(owner) :Banned $nk ($uh) from $ch"
}
}
if {$cg(dokick) > 0} {
putkick $ch $nk
if {$cg(owner) ne "" && $cg(doban) == 0} {
puthelp "PRIVMSG $cg(owner) :Kicked $nk ($uh) from $ch"
}
}
if {$cg(doban) > 0 && $cg(dokick) > 0 && $cg(owner) ne ""} {
puthelp "PRIVMSG $cg(owner) :Kick/banned $nk ($uh) from $ch"
}
return 0
}
#########################
# cleanup some settings #
if {$cg(doban) != 0} { set cg(doban) 1 }
if {$cg(dokick) != 0} { set cg(dokick) 1 }
set cg(owner) [string trim $cg(owner)]
if {$cg(def_amask) ni {2 3}} { set cg(def_amask) 1 }
########################
###### file stuff ######
#badlist file name.
set cg(bfile) "scripts/cg_[string trim [namespace current] :]_badlist.txt"
#goodlist file name.
set cg(gfile) "scripts/cg_[string trim [namespace current] :]_goodlist.txt"
proc cg_onload {} { variable cg
foreach x {b g} {
set cg(${x}file) [string trim $cg(${x}file)]
if {![file exists $cg(${x}file)]} {
set openfile [open $cg(${x}file) a] ;## cg(bfile) || cg(gfile) ##
close $openfile
set cg(_${x}list) {} ;## sets var: cg(_blist) || cg(_glist) ##
}
if {![info exists cg(_${x}list)]} {
set openfile [open $cg(${x}file) r]
set cg(_${x}list) [split [read -nonewline $openfile] "\n"]
close $openfile
}
}
}
cg_onload
proc cg_savefile {x} { variable cg ;## $x can be: (b || g) ##
set openfile [open $cg(${x}file) w]
puts $openfile [join $cg(_${x}list) "\n"]
close $openfile
}
putlog "Loaded cloudGuard version 0.3 12Dec2022"
} ;## end of: namespace eval ##