Bearbeiten · Veränderungen zeigen · Druckansicht ·

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.

Inhaltsverzeichnis

Vorraussetzung

TCL-Kenntnisse?

TCL-Scripte laden

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

Ereignisse (events) des sBNC

Der sBNC stellt uns verschiedene Events zur Verfügung, auf die unser TCL-Script reagieren kann

TypeprocBeschreibung
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>
}

Reaktion auf ein Command

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"
    }
}

Reaktion auf einen Verbindungsaufbau vom User zum sBNC

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"
        }
    }
}

Reaktion auf eine Server Nachricht

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]
        }
    }
}

sBNC Commands

Ein paar sBNC spezifische Commandos, mit der ihr eure Scripte schreiben könnt:

setctx

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"
}

bncnotc

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

"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"
    }
}

Webinterface erweitern

Um das Webinterface zu erweitern, müssen wir zwei Sachen machen:

  • Ein TCL-Script schreiben
  • PHP Dateien editieren

TCL-Script schreiben

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.

PHP Dateien editieren

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.

Bearbeiten · Veränderungen zeigen · Druckansicht ·
Page last modified on January 21, 2009, at 07:32 PM