This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

set topic on join channel

Help for those learning Tcl or writing their own scripts.
Post Reply
n
na85
Voice
Posts: 5
Joined: Thu Jan 29, 2009 11:46 pm

set topic on join channel

Post by na85 »

I'm trying to make a script that will have my bot automatically set the topic when he a) gets chanop or b) creates the channel.

Here's what I've got so far

Code: Select all

set topicchan #na85

set chantopic "omg a topic"

bind mode - "* +o" changetopic
bind join - "#na85 *" onjoin

proc onjoin {nick uhost handle channel} {
        global topicchan chantopic
        if {[isbotnick $nick] && [isop superbot $topicchan]} {
                putserv "TOPIC $channel :$chantopic"
        }
}

proc changetopic {nick uhost hand chan mc targ} {
 global topicchan chantopic
    if {[isbotnick $targ] && [string equal -nocase $topicchan $chan]} {
  putserv "TOPIC $chan :$chantopic"
    }
}
Unfortunately it doesn't work right. When he gets +o on the channel he sets the topic just fine.

However when he creates the channel (i.e. he's the first user) then nothing happens and the topic never gets set.

Obviously there's something wrong but I can't figure out what. Any help would be appreciated.
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

When your bot joins the channel it is not an op, therefore cannot set a topic. There is always a slight delay before chanserv ops a user if they are on a channel access list or if they are the first in a newly created channel. Hence your JOIN proc can never work.

I would have suggested using a utimer inside the JOIN proc to call another proc after a few seconds (giving chanserv opportunity to op) which then sets the topic. However, it would seem superfluous. You already have a proc that sets the topic when the bot is the target of a +o mode change.
n
na85
Voice
Posts: 5
Joined: Thu Jan 29, 2009 11:46 pm

Post by na85 »

Yeah I do, but interestingly enough the +o mode change doesn't seem to fire when you create a channel (I'm on efnet, so chanserv doesn't really concern me).

I was able to get this to work by removing the

Code: Select all

&& [isop superbot $topicchan]
from the first proc, obviously.

However part of my rationale for adding that check was so that my bot didn't try to change the topic if it joined a channel where users were already present. Is there a way to check if a channel is empty?
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

If the bot is not in the channel then the answer to your question would depend on whether there was a command you could send to the ircd or channel services to return that information. You would then need to programmatically send the command and capture/interpret the response. Even if such a command exists, this would be rather more difficult to script than your existing simplistic JOIN and MODE binds.

On DALnet the /who command exists but generally users are not visible if you are not in the channel and so returns nothing useful.

If the bot is in the channel, then the Eggdrop Tcl command [chanlist #channelname] would return a list of the channel users. However, I suspect that there may be flaws in this approach depending on exactly when the command is used. If the bot needs to wait for the next raw /who response from the network to be aware of the channel users, then the command may not return an accurate list immediately after it joins the channel. Warrants experimentation, unless anybody else is aware of the facts. If the command returns an accurate list immediately on joining a channel then it would be a list of length at least 1 because the bot is there.

If you do play around with the command, please publish your results here. I would be interested to know.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Using isop, chanlist, or any channel-status command on the join-binding will produce "non-authorative" results (it will considder itself the only member of the channel, and not being op'd).

At the same time, if sticking with "classic" ircd behaviour, if you are the creator of a channel you will actually join the channel with operator status. IE, there will be no servermode (hence the mode-binding will not trigger), instead the 353 numeric response will already show the client as an operator. Unfortunately, as arfer mentioned, channel members list will not be updated until the response of a /who-request is recieved (which is performed after the join-binding triggers).

One more reliable workaround would be to listen for the 315 (End of WHO) numeric, indicating your eggdrop has already recieved (and parsed) all the channel-data it needs.
Keep in mind that when working with raw-bindings, eggdrop will only extract the source (servername in this case) and command (315 in this case), leaving the rest of the line unparsed as the third argument. As such, you'll need to extract the channelname from here to see that we've joined the right channel... Also, having a returncode other than 0 may result in unpredictable behaviour, as this prevents further processing of this message (possibly blocking eggdrop from "seeing" important "stuff").

Something like this should convert the line to a proper list, and make a decent skeleton for dealing with raw bindings:

Code: Select all

proc myraw {source command text} {
 set i [string first " :" $text]
 set list [split [string range $text 0 [expr $i-1]]]
 lappend list [string range $text [expr $i+2] end]

 #your code here

 #Make sure we return 0, so we won't block eggdrop's own raw bindings.
 return 0
}
Reading rfc1459 reveals the rest being nickname, channel and "End of WHO list.", so [lindex $list 1] should yield the channelname for the 315 numeric reply.
NML_375
Post Reply