Hier werden wir uns dem TCL-Scripting? widmen. Euch werden hier die Eigenheiten der TCL-Schnittstelle für die Bouncer? ShroudBNC vorgestellt.
Ich verwende hier als Referenz die englische Anleitung von Doomie (Doomie's Script Archive).
Diese Anleitung werde ich nicht am Stück schreiben, sondern peu a peu, bis sie kompett ist.
Im Internet gibt es bestimmt viele TCL-Scripte für den sbnc, hab mich selber noch nie nach Scripten umgeschaut, aber um ein Script im sbnc hinzuzufügen musst du dieses in den Ordner scripts/ kopieren und in die sbnc.tcl eintragen:
source scripts/euer_script.tcl
Der sBNC stellt uns verschiedene Events zur Verfügung, auf die unser TCL-Script reagieren kann
Type | proc | Beschreibung |
---|---|---|
client | {client parameters} | Wird ausgeführt, wenn der Client irgendwas sendet |
server | {client parameters} | Wird ausgeführt, wenn der Server irgendwas sendet |
pre | {} | Wird vor einem Vorgang (Ereigniss) ausgeführt |
post | {} | Wird nach einem Vorgang (Ereigniss) ausgeführt |
attach | {client} | Wird ausgeführt, wenn sich ein User einloggt |
detach | {client} | Wird ausgeführt, wenn sich ein User ausloggt |
modec | {client params} | Wird ausgeführt, wenn ein Channel Mode gesetzt/zurückgesetzt wird |
unload | {} | Wird ausgeführt, wenn TCL "ausgeschalten" wird |
svrconnect | {client} | Wird ausgeführt, wenn eine neue Verbindung zu einem IRC-Server aufgebaut wird |
svrlogon | {client} | Wird ausgeführt, wenn das MOTD (Message of the Day) gesendet wurde |
usrcreate | {client} | Wird ausgeführt, wenn ein User hinzugefügt wurde |
usrload | {client} | Wird ausgeführt, wenn eine User.conf geladen wurde |
usrdelete | {client} | Wird ausgeführt, wenn ein User gelöscht wurde |
command | {client parameters} | Wird ausgeführt, wenn ein Command (über /sbnc oder /msg -sBNC) gesendet wurde |
Ein einfaches Script könnte so aussehen:
internalbind <type> <proc> <proc> <parameters> { <TCL-Commands> }
Benutzt das command event, wenn ihr auf einenen Befehl, der vom User mit /sbnc oder /msg -sBNC gesendet wird, reagieren wollt:
# wir binden alle befehle auf unsere proc own:time internalbind command own:time # hier ist unsere proc own:time mit den parametern client und parameters proc own:time {client parameters} { # prüfen wir ob der erste parameter/befehl "time" ist if{[string equal -nocase [lindex $parameters 0] "time"]} { # bncreplay antworetet auf das command mit einer notice oder privmsg # je nachdem ob man /sbnc oder /msg -sBNC benutzt hat bncreply "[ctime [unixtime]]" # haltoutput sorgt dafür, das der sBNC nicht die default ausgabe (z.B. "Unknown command. Try /msg -sBNC help") sendet. haltoutput } }
Dieses einfach Beispiel liefert uns die aktuelle Zeit zurück, wenn wir "/sbnc time" oder "/msg -sBNC time" an den sBNC senden.
Mit dem nächsten Beispiel modifizieren wir die Hilfe, die wir mit "/sbnc help" oder "/msg -sBNC help" aufrufen können. Zwei Befehle benötigen wir dazu:
bncaddcommand <Name> <Kategorie> <Beschreibung> [<HilfeText>] # als Kategorie steht uns "User" und "Admin" zur verfügung bncdeletecommand <Name>
Der erste Befehl fügt den Hilfe Text hinzu, und der zweite löscht ihn wieder. Wir können dies nur in einem "internalbin command" das auf den command "help" reagiert ausführen.
# Wir binden alle Befehle auf unsere proc own:help internalbind command own:help proc own:help {client parameters} { # prüfen wir ob help als befehl übergeben wurde if {[string equal -nocase [lindex $parameters 0] "help"]} { # jetzt können wir den Befehl in die Hilfe mit aufnehmen bncaddcommand time user "Zeit die aktuelle Uhrzeit" "/sbnc time\n /msg -sBNC time" } }
Das "attach" event wird ausgelöst, wenn sich ein User zum sBNC verbindet, Du kannst damit sehr nützliche Sachen machen, z.B. ein eigenes MOTD
# binden wir das attach event auf unsere proc own:motd internalbind attach own:motd proc own:motd {client} { # senden wir irgendwas an den clienten z.B. unser MOTD bncnotc "#######################################" bncnotc "# Mein MOTD #" bncnotc "# Wir können schreiben was wir wollen #" bncnotc "#######################################" }
Anmerkung: bncnotc sendet nur zum aktuellen User wenn du einem anderen User was senden willst schau dir setctx an.
Das Event "detach" wird ausgelöst, wenn sich ein User vom sBNC trennt. Nützlich ist es, wenn man sich automatisch von einem Bot trennen will, oder einen awaymsg in jeden channel posten will. Das folgende Script ist vom offiziellem Release vom sBNC:
# binden wir das event "detach" auf unsere proc awaymsg:detach internalbind detach awaymsg:detach proc awaymsg:detach {client} { # hier holen wir uns die awaymessage vom User mit getbncuser set result [getbncuser $client tag awaymessage] # wenn eine awaymessage gestzt wurde if {$result != ""} { # gehen wir alle channels nacheinander durch foreach chan [internalchannels] { # uns senden unseren awaygrund mit einem Action in alle Channels putquick "PRIVMSG $chan :\001ACTION $result \001" } } }
Dies ist eine der wichtigsten events. Das "server" event wird ausgelöst, wenn der Server eine Nachricht zum Client schickt. Damit kannst du sehr vieles machen, z.B. Bestimmte User automatisch OP beim joinen eines channels geben (Eggdrop ersatz). Das folgende Script loggt jede Zeile, wenn wir nicht mit dem sBNC verbunden sind und jemand unseren Nick in eine Nachricht schreibt.
# binden wir das server event auf unsere proc own:log internalbind server own:log proc own:log {client parameters} { # wenn der Client offline ist if {![getbncuser $client hasclient]} { # vergleichen wir jede Zeile mit unserem aktuellen nick # Anmerkung: In $parameters steht Beispielsweise: PRIVMSG #channel :<message> if {[string match -nocase *${::botnick}* [lindex $parameters 3]]} { # schreiben wir ins logfile putlog [lrange $parameters 2 end] } } }
Ein paar sBNC spezifische Commandos, mit der ihr eure Scripte schreiben könnt:
Mit setctx wird der aktuelle User festgelegt. Mit diesem User wird das Script ausgeführt:
setctx USER # schreiben wir was in das Log des Users "USER" putlog "Hallo" # senden wir dem IRC-Server des Users ein Command putserv "QUIT"
wenn ein Script als ein anderer User ausgeführt werden soll, dann ist es besser den alten zu speichern:
set cuser [getctx] setctx USER [commands] setctx $cuser
Ganz nach dem Eggdrop Style:
# setzen wir den aktuellen (aktiven) User setctx USER # binden wir "!hallo" auf die proc egg:hallo bind pub - !hallo egg:hallo proc egg:hallo {nick uhost handle chan text} { # senden wir Hallo in den Channel, indem auch !hallo geschrieben wurde puthelp "PRIVMSG $chan Hallo Hallo" }
Mit "bncnotc" könnt ihr eine PRIVMSG an den aktuellen User schicken
bncnotc "Nachricht"
ist das selbe wie:
putclient ":-sBNC!sBNC@shroudbnc.org PRIVMSG $::botnick :message"
Anmerkung, den "aktiven" User an dem die nachricht geht legst du mit fest
"bncreply" sendet nach dem command eine Notice oder Privmsg zum User je nachdem ob der User seinen command mit /sbnc oder /msg -sBNC gesendet hat.
internalbind command own:test proc own:test {client parameters} { if {[string equal -nocase [lindex $parameters 1] "test"]} { bncreply "muh" } }
Um das Webinterface zu erweitern, müssen wir zwei Sachen machen:
Bevor wir jetzt die offiziellen TCL-Scripte bearbeiten, um unser Webinterface zu erweitern, schreiben wir lieber unser eigenes TCL-Script wir nennen das einfach mal "owniface.tcl". Wir schreiben hier ein Script, dass es uns ermöglicht das MOTD des sBNC über das Webinterface zu ändern.
# zuerst definieren wir unsere proc mit der wir alle commandos vom webinterface entgegennehmen. proc motd:ifacecmd {command params account} { # wir prüfen das command mit switch. switch -- $command { # wenn das command "getmotd" ist "getmotd" { # wir geben das aktuelle MOTD aus return [bncgetmotd] } # command ist setmotd "setmotd" { # prüfen wir ob es sich um einen Admin Account handelt if {[getbncuser $account admin]} { # und aktualsieren es bncsetmotd [join $params] # und geben "1" zurück return 1 } } } } # registerifacehandler ist eine bequeme Möglichkeit um neue Features im Webinterface einzufügen # die iface.tcl schaut automatsich auf alle registriereten proc's und prüft ob das # command registriert ist # prüfen wir ob "registerifacehandler" verfügbar ist: # (sprich ob die iface.tcl geladen ist oder nicht) if {[lsearch -exact [info commands] "registerifacehandler"] != -1} { # wenn "registerifacehandler" verfügbar ist registrieren wir unser Feature registerifacehandler motd motd:ifacecmd }
Anmerkung: User TCL-Script muss nach der iface.tcl geladen werden, weil sonst "registerifacehandler" nicht arbeitet.
Dieser Teil hat jetzt nichts mehr mit TCL zu tun, sondern dreht sich um PHP. Wenn wir ein Feature in unser Webinterface intigrieren wollen, müssen wir zwangsweise auch die php Dateien des Webinterfaces editieren. Wollen wir jetzt das MOTD des sbnc's am anfang unsers Webinterfaces anzeigen lassen oder ändern, müssen wir die info.php bearbeiten:
// Das hier steht schon in eurer info.php include_once('sec.php'); sbnc_guard(); // hasplugin prüft, ob ein plugin geladen ist oder nicht (ifacehandler registriert das plugin) // wenn die funktion 1 zurückgibt, ist sie geladen, bei 0 nicht if (sbnc_command('hasplugin motd')) { // geben wir das aktuelle motd aus $motd = sbnc_command('getmotd'); if ($motd == "") { $motd = "none"; } // nun geben wir das MOTD aus echo '<fieldset><legend>MOTD</legend>'.$motd.'</fieldset><br />'; } // ab hier geht der original code weiter ....
Anmerkung: Das Webinterface benutzt Sprach-Dateien. Wenn wir die auch nutzen wollen, dann müssen wir mit printf() und $lang_info[...] arbeiten. Ein gutes Beispiel dafür findet ihr in allen PHP-Dateien des Webinterfaces.
So das wars jetzt von mir fürs erste :) Ich werd jetzt erstmal selber ein paar Scripte schreiben, und auch das motd Script fürs Webinterface etwas besser umsetzen. Werd euch natürlich dann auch mein Script hier zur verfügung stellen.