All pastes #778345 Raw Edit

Something

public text v1 · immutable
·published 2007-11-17 14:31 UTC
rendered paste body
############################
#### Checkaccess script ####
############################
## Info
# This script is made to work with the Undernet +D channelmode.
#   The +D mode makes joiners to a channel invisible, untill they speak.
#   This protects the channel more against join/part flooders, but also allows users to stay invisible.
#   This Tcl detects invisible users, and makes the bot execute all bind join scripts.
#   The detection happens 1 minute apart.  This is the lowest timespan, without using timers, and should
#   be enough.
#
# What can you use this Tcl for?
#   Making autovoice and greet scripts work with +D
#    (or any other script that does something when a user joins the channel)
#
# Things to watch out for when using this Tcl
#   All the users that are found, are added all at once to the bot's internal channel list.
#   This can cause some problems with anti-flood scripts.  Make sure to test out different
#   settings before using this tcl on very busy channels.
#
#   - Voice scripts :
#           It's advised to use a voice script that waits a few seconds before voicing.
#           This is especially important when using defensive scripts like clonecheckers
#           or versioncheckers (that way, the offenders are weeded out, before they get voiced)
#   - Protective scripts :
#           Load protection scripts immediatly after this script, and before general scripts
#           like autovoice or greet scripts.  This will make sure that protection is done before serving.
#
# This script adds a channel setting called 'checkhidden'.  This script will only work on
# a channel that's +D or +d, AND has the checkhidden-setting set to '+'.
# You can do this by entering '.chanset #channel +checkhidden' in the partyline.
#
#
## Custom Commands
# - none
#
## Todo
# - none at the moment.
#
## How to install
# You can install this tcl by editing your eggdrop.conf.
# First copy this tcl to your prefered directory, then add a line to your eggdrop.conf
#   source path/to/script.tcl
# Save the config and rehash your bot.
# After this, the script is installed.
#
## I want to contact you!
# If you want to contact me, you can find me on:
# - #tcl and #eggies @Undernet (irc.undernet.org)
# Call "wanderer" in one of those channels, and if I'm there I will respond.
# If you can't find me on irc, you're welcome to drop me an email on wanderer@powersource.cx
#
# Please check http://tcl.powersource.cx if you have problems with this tcl.  If you can't find an update
# or your problem isn't fixed by it, contact me.
# I can't promise this tcl being without bugs, I do know that I've already put a lot of effort in them
# and want to make them as good as possible.  So please, let me know if you find a bug, or the script
# isn't working for you.
#
#################
### Variables ###
#################
# Should feedback be sent to a "monitoring" channel?
# set di(logchan) "#channel"
set di(logchan) ""

# Should feedback be sent to the partyline?
# set di(pl) 0
set di(pl) 1

#############
### Binds ###
#############
bind time - "* * * * *" checkinvisible:check

bind raw - 354 checkinvisible:raw:354
bind raw - 315 checkinvisible:raw:315

#############
### Procs ###
#############
###
## Proc that handles the logging to logchan & partyline
#
proc checkinvisible:feedback {text} {
  if {[string index $::di(logchan) 0]=="#"} {puthelp "privmsg $::di(logchan) :$text"}
  if {$::di(pl)} {putlog "$text"}
}
###
## Forking proc for *raw:irc:join
#
proc new:irc:join {nuh cmd channel} {
  set nuh [split $nuh "!"]
  set nick [lindex $nuh 0]
  set uhost [lindex $nuh 1]
  if {[string index $channel 0]==":"} {set channel [string range $channel 1 end]}
  if {![info exists ::di(hiddenusers,$channel)]} { set ::di(hiddenusers,$channel) {} }
  if {![string match *D* [getchanmode $channel]]||([lsearch -exact $::di(hiddenusers,$channel) $nick]>"-1"&&[lsearch -exact [chanlist $channel] $nick]=="-1")} {
    *raw:irc:joinreal "$nick!$uhost" "JOIN" ":$channel"
  }
}
###
## Forking proc for *raw:irc:part
#
proc new:irc:part {nuh cmd text} {
  set nuh [split $nuh "@"]
  set nick [lindex $nuh 0]
  set uhost [lindex $nuh 1]
  if {[string index $text 0]==":"} {
    set channel [string range $text 1 end]
  } else {
    set channel [lindex [split $text " "] 0]
  }
  if {![info exists ::di(hiddenusers,$channel)]} { set ::di(hiddenusers,$channel) {} }
  # if in di(hiddenusers,$channel) -> remove from list
  if {[set i [lsearch -exact $::di(hiddenusers,$channel)]]>"-1"} {set ::di(hiddenusers,$channel) [lreplace $::di(hiddenusers,$channel) $i $i]}
  *raw:irc:partreal "$nick!uhost" "PART" "$text"
}
###
## Proc that start the checking
#
proc checkinvisible:check {args} {
  set counter 1
  foreach c [channels] {
    if {[channel get $c checkhidden]} {
      if {[string match -nocase *D* [getchanmode $c]]} {
        # This channel wants to check for hidden users AND has the D or d flag
        int:unset ::di(list,$c)
        set ::di(list,$c) {}
        set ::di(counter,$counter) $c
        set ::di(channel,$c) $counter
        puthelp "WHO $c d%tnuh,$counter"
        #checkinvisible:feedback "\002\[CheckInvisible\]\002 Checked for users in $c (WHO)"
        incr counter
      }
    }
  }
}
###
## Raw 354 = reply from the WHO-command
#
proc checkinvisible:raw:354 {from cmd text} {
  if {[llength $text]==5} {
    set text [split $text " "]
    set counter [lindex $text 1]
    set nick [lindex $text 4]
    set uname [lindex $text 2]
    set host [lindex $text 3]
    set channel $::di(counter,$counter)
    lappend ::di(list,$channel) $nick $uname $host
  }
}
###
## Raw 315 = End of WHO-command
#
proc checkinvisible:raw:315 {from cmd text} {
  set channel [lindex [split $text " "] 1]
  if {[info exists ::di(channel,$channel)]&&[info exists ::di(list,$channel)]} {
    set foundusers {}
    set goneusers {}
    set counter $::di(channel,$channel)
    set detected [chanlist $channel]
    set undetected $::di(list,$channel)
    int:unset ::di($channel)
    int:unset ::di($counter)
    int:unset ::di(list,$channel)
    foreach {user uname host} $undetected {
      # is this user known?
      if {[lsearch -exact $detected $user]=="-1"} {
        lappend foundusers $user
        lappend ::di(hiddenusers,$channel) $user
        *raw:irc:join $user!$uname@$host JOIN $channel
      }
    }
    set ::di(hiddenusers,$channel) [lsort -unique $::di(hiddenusers,$channel)]
    # are there users in hiddenusers, that aren't found (left/quit)?
    foreach user $detected {
      if {[lsearch -exact $undetected $user]=="-1"} {
        lappend goneusers $user
        *raw:irc:part $user![getchanhost $user] PART :$channel
      }
    }
    if {[llength $foundusers]>0} {
      checkinvisible:feedback "\002\[CheckInvisible\]\002 The following new hidden user(s) were detected on $channel: [join $foundusers ", "]"
    }
    if {[llength $goneusers]>0} {
      checkinvisible:feedback "\002\[CheckInvisible\]\002 The following hidden user(s) left $channel: [join $goneusers ", "]"
    }
  }
}


############
### Init ###
############
# check if the *raw:irc:join proc exists
# check if the *raw:irc:joinreal proc exists
if {[string eq [info command "*raw:irc:join"] "*raw:irc:join"]} {
  if {[string eq [info command "*raw:irc:joinreal"] "*raw:irc:joinreal"]} {
    # the joinreal exists, clear the *raw:irc:join proc & rename new:irc:join
    rename *raw:irc:join ""
    rename new:irc:join *raw:irc:join
  } {
    # rename *raw:irc:join to *raw:irc:joinreal
    rename *raw:irc:join *raw:irc:joinreal
    rename new:irc:join *raw:irc:join
  }
  # o ooh... no *raw:irc:join proc...  Something must be wrong... restarting.
} {restart}
# check if the *raw:irc:part proc exists
# check if the *raw:irc:partreal proc exists
if {[string eq [info command "*raw:irc:part"] "*raw:irc:part"]} {
  if {[string eq [info command "*raw:irc:partreal"] "*raw:irc:partreal"]} {
    # the partreal exists, clear the *raw:irc:part proc & rename new:irc:part
    rename *raw:irc:part ""
    rename new:irc:part *raw:irc:part

  } {
    # rename *raw:irc:part to *raw:irc:partreal
    rename *raw:irc:part *raw:irc:partreal
    rename new:irc:part *raw:irc:part
  }
  # o ooh... no *raw:irc:join proc...  Something must be wrong... restarting.
} {restart}

proc int:unset {var} {if {[info exists $var]} {unset $var}}

setudef flag checkhidden

set psversion(checkinvisible) "1.11"
putlog "\002\[CheckInvisible\]\002 $psversion(checkinvisible) -=\002LOADED\002=- (c)wanderer - http://tcl.powersource.cx"

################
### Versions ###
################
# - 1.0  : Original version
#          Thanks to DammiT (#defence @ Undernet) to allow me to use his channel for testing purposes.
# - 1.1  : Small bugfix concerning the parsing of RAW PART.
# - 1.11 : Another bugfix in the part proc. The bug caused an error to display, when the script is newly loaded
#          and the first action on a channel is a part, not a join.
#          Thanks to n-iCe for reporting this.


#################
### Statement ###
#################
# I was asked by some people from the "tcl committee" to not release this script to the public.  I believe these people
# to be the same ones that made the EAFS-tcl (#Ayuda @ Undernet - http://www.canal-ayuda.org/bulletin/forumdisplay.php?f=40)
# The reason they asked me this, is because they firmly believe that only big channels who "deserve" it should have this tcl.
# As you can see, I don't agree with that statement.  Undernet doesn't place a requirement on +D mode itself either, does it?
#
# To all channel owners out there... If you have a good idea for a channel protection script, but can't write it... Come and find me.
#
# Regards,
#  Wanderer.