I've seen many questions about changing the banmask used in eggdrop scripts. There is a pretty simple (and obvious) solution: Replace the internal maskhost-command with a proc that returns the type of mask you'd like. Then make sure all your scripts use this proc.
Adding the bans to your internal banlist is done via newban (global ban) or newchanban (channel ban) and the rest (placing the ban on channels, enforcing etc) is controlled via channel settings. If you, for some reason, don't want to use the internal banlist, use pushmode to place a ban directly on some channel. (look the commands up in tcl-commands.doc if you don't know their syntax)
As for the bans created by the built in flood/autokick/revenge-mechanisms, you'll need to make a script that takes care of the banning via your own maskhost proc if you want custom ban types. The flood kicks are easy; just 'bind flud' and add a tiny proc. Revenge and +k require alot more in terms of code as you'll need to implement the entire feature in tcl (unless you know C and feel like messing with the eggdrop code)
This is sort of off-topic, but I've also seen a couple of requests regarding placing a different type of ban than the one matching a joining/nick changing user. E.g.: someone joins matching your ban for "guest*!*@*" and you want to ban *!*@their.host.tld to keep them out for a while. Again; this requires a tcl script as the bans added via the built in ban mechanism are used for both the internal matching AND placing the actual ban on irc.
I won't address the last two paragraphs any further in this post, but here's a proc to replace the internal maskhost command...
usage: maskhost <nick!ident@host.tld> [type]
The type is optional, meaning you can leave it out and call the proc just like the built in command. The default type (see below) is used if you do that. This proc is a bit stricter than the built in command when it comes to accepting input...the "name" to be masked must contain a "!" and a "@" and there has to be at least one char on each side and between these two (which makes perfect sense if you expect the proc to produce output resembling the desired type's description)
Types supported by my proc (stolen from mirc):
NOTE: if the host is an ip, the last octet will be an asterisk (*) for the types that have one of those after the "@" in the type list above. If the host is a name, but there is no subdomain and/or second level domain, the entire hostname will be returned. Any tilde(s) in the start of the ident/username will be trimmed off for the types that contain "!*user@"0: *!user@full.host.tld
1: *!*user@full.host.tld
2: *!*@full.host.tld
3: *!*user@*.host.tld
4: *!*@*.host.tld
5: nick!user@full.host.tld
6: nick!*user@full.host.tld
7: nick!*@full.host.tld
8: nick!*user@*.host.tld
9: nick!*@*.host.tld
E.g.:
"maskhost nick!~id@127.0.0.1 3" returns *!*id@127.0.0.*
"maskhost nick!~id@pretty.lame.tld 3" returns *!*id@*.lame.tld
"maskhost nick!~id@lame.tld 3" returns *!*id@lame.tld
Code: Select all
# Setting:
set maskhostDefaultType 3
# The proc:
proc maskhost [list name [list type $maskhostDefaultType]] {
if {[scan $name {%[^!]!%[^@]@%s} nick user host]!=3} {
error "Usage: maskhost <nick!user@host> \[type\]"
}
if [string match {[3489]} $type] {
if [string match {*[0-9]} $host] {
set host [join [lrange [split $host .] 0 2] .].*
} elseif {[string match *.*.* $host]} {
set host *.[join [lrange [split $host .] end-1 end] .]
}
}
if [string match {[1368]} $type] {
set user *[string trimleft $user ~]
} elseif {[string match {[2479]} $type]} {
set user *
}
if [string match {[01234]} $type] {
set nick *
}
set name $nick!$user@$host
}
Different irc networks have different ways of dealing with case sensitivity. rfc-compliant ircds consider {, } and | the lowercase versions of [, ] and \, others see them as entirely different characters. This means there's no single way to match bans that will work on all networks. Your matching code must be tailored to the particular ircd you're running the script on. (The detection of what type of matching is used on your network can be done using a raw bind (005))
I've seen many people use string match to do ban matching without thinking about the special meaning square brackets ([]) and backslash (\) have in a glob pattern. The glob pattern used by string match is NOT the same as a ban on irc. To have the brackets and backslashes treated like normal characters by string match, you must escape them ...or, for rfc-compliant networks, replace them with their "lowercase" counterparts.
If you have a hard time understanding what kind of problems failing to deal with these special chars might lead to, here's an example for you: Let's say you have the ban [die]!*@* in one of your scripts, then someone by that nick joins (or whatever triggering a match check), but nothing happens...why? The unescaped brackets are interpreted as "match any one of these 3 letters" (d, i OR e) and the brackets themselves are discarded in the actual matching, so you end up with a mismatch for the nick [die], but your mask is matching 3 other single letter nicks.
I'm tired of writing...please let me know if you spot any errors/i left something out/you need examples/more info on some of this. (post below)