#--------------------------------------------------------------------- # topiclock.tcl # TCL script for IRC bot eggdrop # # If a channel is being set to +topiclock, the bot will maintain the # topic previously set by checking the topic every minute. # # Usage: !topiclock (locks the topic on the channel) # Usage: !topicunlock (unlocks the topic on the channel) # # v0: 10-Oct-2002 # v1: 15-Oct-2002 #--------------------------------------------------------------------- #--------------------------------------------------------------------- # package needs, bindings, setudef #--------------------------------------------------------------------- package require eggdrop 1.6 package require Tcl 8.0 bind PUB m|m !topiclock topiclock:lock bind PUB m|m !topicunlock topiclock:unlock bind TIME - * topiclock:time bind TOPC - * topiclock:topc setudef flag topiclock #--------------------------------------------------------------------- # Public locking of channel topic. #--------------------------------------------------------------------- proc topiclock:lock { nick uhost hand chan text } { global topiclocktopic # retrieve channel information. set chaninfo [channel info $chan] # topic already locked? need unlock first. if {[lsearch -exact $chaninfo +topiclock] != -1} { puthelp "PRIVMSG $chan :Topic on $chan is already locked.\ Use !topicunlock to unlock first." return 1 } # a proper topic must exist. set chan [string tolower $chan] if {![info exists topiclocktopic($chan)]} { puthelp "PRIVMSG $chan :Cannot find a channel topic.\ Set a channel topic first and then use !topiclock." return 1 } # The channel is -topiclock and a proper topic exists: # now switch to +topiclock ... channel set $chan +topiclock # ... and notify the channel. set topic $topiclocktopic($chan) if {[string length $topic] > 30} { set topic "[string range $topic 0 30] ..." } puthelp "PRIVMSG $chan :Topic on $chan locked by $nick ($topic)" return 1 } #--------------------------------------------------------------------- # Public unlocking of channel topic. #--------------------------------------------------------------------- proc topiclock:unlock { nick uhost hand chan text } { channel set $chan -topiclock puthelp "PRIVMSG $chan :Topic on $chan unlocked by $nick." return 1 } #--------------------------------------------------------------------- # Every minute check all channels and check the topic settings. # Channel must be valid, -inactive, +topiclock and bot must have ops. #--------------------------------------------------------------------- proc topiclock:time { min hour day mon year } { global topiclocktopic foreach chan [array names topiclocktopic] { if {![validchan $chan]} { continue } set chaninfo [channel info $chan] if {[lsearch -exact $chaninfo +inactive] != -1} { continue } if {[lsearch -exact $chaninfo +topiclock] == -1} { continue } if {![botisop $chan]} { continue } if {[topic $chan] == $topiclocktopic($chan)} { continue } puthelp "TOPIC $chan :$topiclocktopic($chan)" } } #--------------------------------------------------------------------- # Upon a topic change keep the new topic in memory and save it # to file #--------------------------------------------------------------------- proc topiclock:topc { nick uhost hand chan topic } { global topiclocktopic set chaninfo [channel info $chan] # do not log if topiclock is set. set chan [string tolower $chan] if {[lsearch -exact $chaninfo +topiclock] != -1} { if {![info exists topiclocktopic($chan)]} { # Weird situation: topic is locked but no topic to lock! # Note that in this situation any topic changes will not # be logged until the channel is -topiclock. putlog "Topiclock: (WARNING) $chan is +topiclock, but no\ topic to lock found!" } return } # topiclock is off. set topiclocktopic($chan) $topic # append topic to data file. topiclock:append $chan return } #--------------------------------------------------------------------- # Append topic to file #--------------------------------------------------------------------- proc topiclock:append { chan } { global topiclocktopic set filename topic.dat # check file status. if {[file exists $filename]} { if {![file writable $filename]} { putlog "Topiclock: (ERROR) $filename is NOT writeable!" return } } else { putlog "Topiclock: created file $filename." } # Append topic to file. set fileid [open $filename a+] puts $fileid "$chan $topiclocktopic($chan)" close $fileid } #--------------------------------------------------------------------- # Load topic from file and save back to file (removing multiple # topics for a channel) #--------------------------------------------------------------------- proc topiclock:loadsave { } { global topiclocktopic set filename topic.dat # check file status. if {![file exists $filename]} { return } if {![file readable $filename]} { putlog "Topiclock: (ERROR) file $filename is not readable!" } # clear existing array. if { [array exists topiclocktopic] } { unset topiclocktopic } # read all topics from file set fileid [open $filename r] set contents [read $fileid] close $fileid # split the file contents into a list. set lines [split $contents "\n"] # iterate on the list, scanning out the channel name and topic. foreach line $lines { set scancount [scan $line "%s %\[^\n\]" chan topic] # something wrong or an end of file. if { $scancount <= 0 } { continue } # in case the file was edited by hand. set chan [string tolower $chan] # if topic is empty, it was saved correctly, # but scan ommits the space if { $scancount == 1 } { set topic "" } set topiclocktopic($chan) $topic } # Write the topics back to file, thus removing multiple # topic definitions for a channel. if {![file writable $filename]} { putlog "Topiclock: (ERROR) file $filename is not writeable!" } set fileid [open $filename w] foreach chan [array names topiclocktopic] { puts $fileid "$chan $topiclocktopic($chan)" } close $fileid } #--------------------------------------------------------------------- # On startup #--------------------------------------------------------------------- topiclock:loadsave putlog "Loaded (version 0): Topiclock."