Code: Select all
# autoReinvite by Artix <loyauflorian@gmail.com>
# Version: 1.1 - 30/10/2010
#
# Compatibility: Requires eggdrop 1.6 (1.8 should work too), Tcl8.5/8.6
# and the channels, server and irc modules.
#
# Since the script uses the watch list, you'll need to be on an unrealIRCd server
# that supports it. I haven't heard of other server type that support it so far.
#
# Note that using other scripts that count on the watchlist at same time is a bad idea.
#
# Contact me by mail at loyauflorian@gmail.com
# or on IRC, irc.epiknet.org, channel #eggdrop
#
#
#
# Script description:
#
# Auto-reinvites (yeah, seriously!) people on a chan under
# specific events.
#
# Features:
# - Auto-reinvite on part or kick
# - Add to watch list when quitting (or netsplit loss)
# - Auto-invite when reconnecting while in watch list
# - The watch list is saved in a database file
# - Automatic trimming of the database
# - Hourly saving of the database
# - Invites done only if the guy is not banned on channel
# - Fully (but lightly) commented code
#
# Version 1.1:
# - Bindings uninstalling now properly working, thanks to MenzAgitat
# - Same for bindings that would trigger on EVERY channel. Thanks once more.
# - When the watchlist is full, oldest entries are now removed - instead of
# removing a random entry from the list.
#
#
# Note that the database isn't supposed to be modified or
# read. Let the script do the stuff, and delete the file
# if you want to erase the database.
#
# The database is saved at hourly-updates time set in
# the config file, once every hour.
# You can change this at the end of the file if needed.
#
# YOU HAVE TO set the chan below in the configuration
# for the script to work.
#
# Thanks to thommey of eggheads for fixing
# my poor database writing code ._.'
# If the file was sourced already, better get rid of everything
# before reloading it.
if {[info procs ::autoReinvite::uninstall] ne ""} { ::autoReinvite::uninstall }
namespace eval ::autoReinvite {
#===================
## CONFIG START ##
#===================
# UNIQUE chan the script will work on
variable bindedchan "#RuP_HF"
# Toggles invites
variable enabled 1
# Path to the watch nick database
variable watchdb "autoReinvite.db"
# Maximum entries in the database
# Technical notes: previous entries will be replaced,
# the script won't delete any entry while running.
# The watch list is only trimmmed when saving.
variable maxwatch 500
## CONFIG END ##
# Watch List initialisation
variable watchlist {}
# Either add or remove the whole watchlist at once
# + to add, - to remove all
proc modwatch {symbol} {
variable watchlist
# Add every nick to watch one by one
foreach entry $watchlist {
lappend output "$symbol[lindex $entry 0]"
}
# Send 'em to the server.
if {![info exists output]} return
putquick "WATCH [join $output]"
}
# Loads the watch DB. Done automatically on startup.
proc loadWatchDB {} {
variable watchdb
variable watchlist
# Get rid of ALL previous watches!
modwatch -
set watchlist {}
# Open the new file and load it
if {![file exists $watchdb]} return
set channelID [open $watchdb r]
set watchlist [gets $channelID]
close $channelID
# Add the new watches
modwatch +
}
# Since we're loading the script, better load the DB too.
loadWatchDB
# Save the watch db
proc saveWatchDB {args} {
variable watchdb
variable watchlist
variable maxwatch
# Eventually trim the database if it's too big
if {[llength $watchlist] > $maxwatch} {
set watchlist [lrange $watchlist 0 $maxwatch-1]
}
# Open the file and write the watchlist into it
set channelID [open $watchdb w+]
puts -nonewline $channelID $watchlist
close $channelID
}
# Clear watches and bindings, save DB, delete the namespace
proc uninstall {args} {
saveWatchDB
modwatch -
foreach bind [binds ::autoReinvite::*] {
catch { unbind [lindex $bind 0] [lindex $bind 1] [lindex $bind 2] [lindex $bind 4] }
}
namespace delete ::autoReinvite
return }
# If a watch get detected, invite the guy.
proc watchDetection {from keyword data} {
set data [split $data]
::autoReinvite::invite [lindex $data 1] [lindex $data 2]@[lindex $data 3] }
# In case of a part, we reinvite the guy!
proc partDetection {nick uhost hand chan reason} { ::autoReinvite::invite $nick $uhost 1 }
# In case of a kick, we reinvite the guy!
proc kickDetection {nick uhost hand chan victim reason} { ::autoReinvite::invite $victim [getchanhost $victim $chan] 1 }
# Invite someone.. if he's not banned!
proc invite {nick uhost {override_onchan_check 0}} {
# NOTE: We need an argument to override the onchan check
# because the bot will say someone that triggered a part
# or kick bind is still on channel.
variable enabled
variable bindedchan
# If the guy's already here, or the script disabled, don't bother
if {([onchan $nick $bindedchan] && !$override_onchan_check) || !$enabled} return
# Check every chan ban for a match
foreach line [chanbans $bindedchan] {
if {[string match -nocase [string map "\[ \\\[ \] \\\]" [lindex $line 0]] $nick!$uhost]} return
}
# In case everything's ok, we just invite him.
putquick "INVITE $nick $bindedchan"
}
# Add someone to the watchlist and start
# watching him.
proc addWatch {nick uhost hand chan reason} {
variable bindedchan
variable watchlist
variable maxwatch
# Cancel if it's the wrong chan
if {$chan ne $bindedchan} return
# Clear previous matching watches
if {[clearWatch $nick $uhost $hand 1]} {
# Start watching the guy on IRC
putquick "WATCH +$nick"
}
# Add a fresh watch in the list
lappend watchlist [list $nick $uhost $hand]
# If the watchlist grows too big, we delete the first entry in the list
if {([llength $watchlist] - 1) < $maxwatch} {
clearWatch {*}[lindex $watchlist 0]
}
}
# Deletes a current watch (on channel join)
proc delWatch {nick uhost hand chan args} {
variable bindedchan
# Just laugh loud if it's the bot joining or wrong chan
if {$nick eq $::nick || $chan ne $bindedchan} return
# Else remove the watch
clearWatch $nick $uhost $hand
# Pretty simple eh?
return
}
# Clears a watch from the watchlist
# Based on nick/uhost/handle
# Stuff matching either one will get removed
# Corresponding IRC watchs get removed as well
proc clearWatch {nick uhost hand {nowatch 0}} {
variable watchlist
# If the list is empty, just gtfo! Might cause errors otherwise.
if {![llength $watchlist]} { return 0 }
# If the nick matchs an existing watch, remove it
if {[set nickIndex [lsearch -exact -index 0 $watchlist $nick]] != -1} { removeEntry $nickIndex
# Same for userhost...
} elseif {[set uhostIndex [lsearch -exact -index 1 $watchlist $uhost]] != -1} { removeEntry $uhostIndex
# ...and handle.
} elseif {$hand ne "*" && [set handIndex [lsearch -exact -index 2 $watchlist $hand]] != -1} { removeEntry $handIndex
# If a match was found, we remove the watch on IRC too
} else { return 0 }
if {!$nowatch} { putquick "WATCH -$nick" }
return 1
}
# Deletes an entry from the watchlist in a conveninent way
proc removeEntry {index} {
variable watchlist
set watchlist [lreplace $watchlist $index $index]
}
# Bind on 'logged in' watch message
bind raw - 600 ::autoReinvite::watchDetection
# Bind on someone parting to reinvite him asap
bind part - "$::autoReinvite::bindedchan *" ::autoReinvite::partDetection
bind kick - "$::autoReinvite::bindedchan *" ::autoReinvite::kickDetection
# Bind on someone quitting to add the watch
bind sign - "$::autoReinvite::bindedchan *" ::autoReinvite::addWatch
# Bind on someone rejoining to remove the watch
bind join - "$::autoReinvite::bindedchan *" ::autoReinvite::delWatch
# rehash script uninstall binding
bind evnt - prerehash ::autoReinvite::uninstall
putlog "autoReinvite by Artix <loyauflorian@gmail.com> loaded succesfully."
}