| View previous topic :: View next topic |
| Author |
Message |
CharlesZink Voice
Joined: 28 Feb 2010 Posts: 12 Location: The Interweb
|
Posted: Tue Mar 02, 2010 10:01 pm Post subject: My Channel Operations Script |
|
|
Hi guys,
I've posted a couple questions around here and the help has been great! I just started trying to learn TCL. I've mostly learned from reading other peoples scripts, and trial & error.
This is my first attempt at a script and it works.. Sorta. Some commands don't work at all, and other do only once. Not sure what is wrong, can you take a look and help out please?
(I've compiled this from some of my own stuff, and copying out of some other scripts.)
| Code: |
### BINDS ###
# All I can say is, change with caution.
bind pub o !op op_nick
bind pub o !deop deop_nick
bind pub o !voice voice_nick
bind pub o !devoice devoice_nick
bind pub o !kick kick_nick
bind pub o !topic set_topic
bind pub o !cycle cycle_bot
### CODE ###
# Don't edit my work, please.
#----- OP -----#
proc op_nick {nick host handle channel testes} {
putserv "MODE $channel +o $nick"
return 1
}
#----- DEOP -----#
proc deop_nick {nick host handle channel testes} {
putserv "MODE $channel -o $nick"
return 1
}
#----- VOICE -----#
proc voice_nick {nick host handle channel testes } {
putserv "MODE $channel +v $nick"
return 1
}
#----- DEVOICE -----#
proc devoice_nick {nick host handle channel testes} {
putserv "MODE $channel -v $nick"
return 1
}
#----- KICK -----#
proc kick_nick {nick uhost hand chan arg} {
global botnick
set who [lindex $arg 0]
set why [lrange $arg 1 end]
putserv "KICK $chan $who :$why 1 5,1•4•5•14,1.:X:. 14,1Gô15,1G14,1eR4,1.:X:. 5,1•4•5•"
return 1
}
#----- TOPIC -----#
proc set_topic {user host handle channel testes} {
set what [lrange $testes 0 end]
putserv "TOPIC $channel :$what"
return 1
}
#----- CYCLE -----#
proc cycle_bot {nick host handle channel testes} {
global botnick
set who [lindex $testes 0]
if {$who == ""} {
restart
return 1
}
}
|
|
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Wed Mar 03, 2010 4:42 am Post subject: |
|
|
Good effort.
Some of the things I've noticed :-
Although Tcl lists are in fact strings because Tcl can only have string data types, they are different in structure. You can't safely use string commands on lists or list commands on normal strings. The additional 'text' argument passed to a proc from a PUB bind, as well as other bind types, is a normal string. If you want to use list commands on it, you will need to split it into a list first. You may choose to join it back into a normal string before outputting, though this may not matter.
Your code :-
| Code: |
proc set_topic {user host handle channel testes} {
set what [lrange $testes 0 end]
putserv "TOPIC $channel :$what"
return 1
}
|
Correct code :-
| Code: |
proc set_topic {user host handle channel testes} {
set what [join [lrange [split $testes] 0 end]]
putserv "TOPIC $channel :$what"
return 0
}
|
In actual fact, in this particular case it is pointless.
[join [lrange [split $testes] 0 end]] == $testes
You may just as well do the following :-
| Code: |
proc set_topic {user host handle channel testes} {
putserv "TOPIC $channel :$testes"
return 0
}
|
Better still you might want to test if the command user actually included a topic with the command, as follows :-
| Code: |
proc set_topic {user host handle channel testes} {
if {[string length [string trim $testes]] != 0} {
putserv "TOPIC $channel :[string trim $testes]"
} else {
putserv "PRIVMSG $channel :correct syntax is !topic <topic>"
}
return 0
}
|
A good document to read on the subject of strings vs lists and how to avoid such issues choking scripts is :-
http://www.peterre.info/characters.html
Note also that I have returned 0 rather than 1. Some bind types (including PUB) behave differently if the proc returns 1. Simply a good habit, unless you deliberately want to return 1.
Take a look at tcl-commands.html in your bots doc/html subdirectory under the heading Binds b. Return values.
Your cycle command should probably be renamed to a restart command. There is no need to restart the bot if all you want to do is cycle an IRC channel.
To cycle the bot :-
| Code: |
putserv "PART #channelname"
|
The bot will immediately rejoin the channel because it still retains a record for the channel.
It is possible to control how long the bot stays out by, instead of the above, programmatically setting the channel +inactive then using a timer to reset the channel -inactive (normally the default value).
Generally, I would avoid overuse of the strange characters used to format text output (as in your kick command). Mainly because it makes the script difficult to read. There is an excellent text formatting document in the Scripting FAQ section of this forum. _________________ I must have had nothing to do |
|
| Back to top |
|
 |
CharlesZink Voice
Joined: 28 Feb 2010 Posts: 12 Location: The Interweb
|
Posted: Wed Mar 03, 2010 2:17 pm Post subject: RE |
|
|
Ok, thanks.
I partially understand what your saying, but how should I make this apply to the other commands like !voice and such?
Would this work:
| Code: |
proc voice_nick {nick host handle channel testes } {
putserv "MODE $channel :+v $testes"
return 0
}
|
For some reason I just don't think it's going to. I've done mIRC all my life, and TCL has thrown me for a total loop
Thanks for all your help, and I'll change the 'cycle' to 'restart' because when it leaves and comes back in, I want it to refresh all the scripts and such too, so it will see any changes, so I guess thats a restart not a cycle. |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Wed Mar 03, 2010 2:25 pm Post subject: |
|
|
Yes that would work fine, providing you used the command !voice <name> where <name> was the nick of the user you wished the bot to voice.
I would tend to trim the argument before using it because some IRC clients insert a space after the nick when using autocomplete.
| Code: |
proc voice_nick {nick host handle channel testes } {
putserv "MODE $channel :+v [string trim $testes]"
return 0
}
|
_________________ I must have had nothing to do |
|
| Back to top |
|
 |
CharlesZink Voice
Joined: 28 Feb 2010 Posts: 12 Location: The Interweb
|
Posted: Wed Mar 03, 2010 2:40 pm Post subject: Thanks |
|
|
Thanks for the help! I will re-code it all and see if it works. Much appreciated.
This page, http://www.egginfo.org/?page=tcl, has an amazing amount of info on some of the commands too. |
|
| Back to top |
|
 |
CharlesZink Voice
Joined: 28 Feb 2010 Posts: 12 Location: The Interweb
|
Posted: Wed Mar 03, 2010 6:09 pm Post subject: WHAT THE HELL? |
|
|
Woah! My bot is totally freaking out! I copied the voice code you edited and showed me and this is what I'm getting
| Quote: |
<~TheNerdTV> !voice advcomp2019
* Terminator sets mode: +p-s
|
And it does different stuff depending on each person?
| Quote: |
<~TheNerdTV> !voice SamsTechAnswers
* Terminator sets mode: +smcT
|
Any idea why? Once again, this is what I'm using...
| Code: |
proc voice_nick {nick host handle channel testes } {
putserv "MODE $channel :+v [string trim $testes]"
return 0
}
|
Crazy! |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Wed Mar 03, 2010 6:24 pm Post subject: |
|
|
The putserv statement has a superfluous colon. Sorry, I didn't notice that. This is the same used in a public command tcl shell.
[22:21] <@arfer> % putserv "MODE #eggtcl -v Hestia"
[22:21] * Baal sets mode: -v Hestia
Just remove the : _________________ I must have had nothing to do |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Wed Mar 03, 2010 7:19 pm Post subject: |
|
|
Out of interest, the following code for voicing users is what I would call more complete. It outputs pretty much every type of error that can occur in using the command and it lends much more scope in the possible syntax.
The bind requires that the user has global operator status in the bot's userfile (user flag o).
The other commands such as op, deop, devoice can be written in a similar way.
| Code: |
# !voice --> voice yourself in the command source channel
# !voice nick --> voice the specified nick in the command source channel
# !voice #channel --> voice yourself in the specified channel
# !voice nick #channel --> voice the specified nick in the specified channel
bind PUB o !voice pCommandsVoice
proc pCommandsVoice {nick uhost hand chan text} {
set arguments [regsub -all -- {[\s]{2,}} [string trim $text] { }]
switch -- [llength [split $arguments]] {
0 {
set tnick $nick
set tchan $chan
}
1 {
if {[regexp -- {^#} $arguments]} {
set tnick $nick
set tchan $arguments
} else {
set tnick $arguments
set tchan $chan
}
}
2 {
set tnick [lindex [split $arguments] 0]
set tchan [lindex [split $arguments] 1]
}
default {
putserv "PRIVMSG $chan :Incorrect syntax, use !voice ?nick? ?#channel?"
return 0
}
}
if {[string equal -nocase $nick $tnick]} {set nprefix "You are"} else {set nprefix "$tnick is"}
if {[string equal -nocase $chan $tchan]} {set cprefix "here"} else {set cprefix "on $tchan"}
if {[regexp -- {^#} $tchan]} {
if {[validchan $tchan]} {
if {[botonchan $tchan]} {
if {[botisop $tchan]} {
if {[regexp -- {^[\x41-\x7D][-\d\x41-\x7D]*$} $tnick]} {
if {[onchan $tnick $tchan]} {
if {![isvoice $tnick $tchan]} {
putserv "MODE $tchan +v $tnick"
} else {putserv "PRIVMSG $chan :$nprefix already voice'd $cprefix"}
} else {putserv "PRIVMSG $chan :$nprefix not $cprefix"}
} else {putserv "PRIVMSG $chan :$tnick is not a valid nick"}
} else {putserv "PRIVMSG $chan :I need to be op'd $cprefix to do that"}
} else {putserv "PRIVMSG $chan :I am not currently on $tchan"}
} else {putserv "PRIVMSG $chan :$tchan is not a valid bot channel"}
} else {putserv "PRIVMSG $chan :$tchan is not a valid channel name"}
return 0
}
|
_________________ I must have had nothing to do |
|
| Back to top |
|
 |
CharlesZink Voice
Joined: 28 Feb 2010 Posts: 12 Location: The Interweb
|
Posted: Wed Mar 03, 2010 11:58 pm Post subject: Thanks |
|
|
Thank you for taking the time to give me that voice code. Once I start putting the bot on multiple channels, I will use that. Off to remove the colon  |
|
| Back to top |
|
 |
|