This is the second part of my "Adventures in Eggdrop TCL Scripting" posts. In the
first post I wrote down the solutions to some simple TCL specific issues I had. In this post I will explain how I solved some eggdrop related issues I faced.
Eggdrop IRC interaction
To make you eggdrop bot useful you want to be able to give commands that eggdrop will catch and process. This is done by using eggdrop binds like this:
bind msg - "start" start;
This will bind run the start method every time someone messaged the Eggdrop bot directly typing: start
Sometimes you want the bot to listen for commands in the channel where the Eggdrop bot is active. This is done with the following bind command:
bind pub - "!start" start;
The above example is a bit dumb but notice how it says "bind pub" instead of "bind msg". This bind will listen in all channels where the bot is active and run the start method whenever someone writes !start in the channel.
When you've issued a command to your Eggdrop bot, you would most likely like it to give you some sort of response. If you just want to respond to a specific channel where it resides you could do the following:
channel "#somechannel"
putserv "PRIVMSG $channel : Response String";
But sometimes you don't want it to respond to a channel but to you in a private message. To do so you would do something very similar like this:
nick ""
putserv "PRIVMSG $nick : Response String";
Notice how it's almost identical to the above, but instead of a channel name it uses an IRC nick.
Eggdrop Timers
After building simple request/response kind of functionality it was time to try a new thing. We wanted some functionality to announce once new things happened in our guild. That required Eggdrop to periodically check for news and then announce those news.
For that purpose I utilized Eggdrop's timer functionality.
proc run_periodically {} {
#DO SOME CODE HERE
timer 10 run_periodically;
return 1;
}
The above code will run some code (checking for news and output to channel) and the call the timer functionality. The above example will then wait 10 minutes and execute the same function again.
There are a few caveats to this though. You have to be careful how you call the run_periodically method the first time. If you just do it on load time of the script it will get called if you rehash eggdrop WITHOUT cancelling the previous timers. For this purpose I created some start and stop methods to control the execution of the periodically needed code.
proc hasTimers {} {
set timerList [timers];
return [llength $timerList];
}
proc start {nick uhost handle text} {
if {[hasTimers] == 0} {
#No current timer is active, meaning its safe to start running periodically
run_periodically
} else {
#Do nothing as a timer is already active, meaning it is already running periodically
}
}
proc stop {nick uhost handle text} {
set timerList [timers];
foreach timer $timerList {
killtimer [lindex $timer 2];
}
}
In the above code there is a few things to note. First is the hasTimers method which is a utility method for checking if we have any currently running timers. Notice the nick, uhost, handle and text parameters in the start and stop methods. Those parameters are needed by eggdrop as the start and stop methods are called using Eggdrop bind commands explained above. Also notice the killtimer command to kill a currently running timer. Having these methods allows the user to control whether or not the timed methods should be run or not.