BuDuS
15-08-2007, 23:38
Proverò a spiegare nel modo più semplice e conciso possibile cosa sono e come si creano le Sentinelle.
Le sentinelle sono un sistema con il quale lo script consente all'utente di eseguire determinate operazioni al verificarsi di un determinato evento.
Ad esempio un evento può essere quando qualcuno entra in un canale, viene cambiata una modalità, qualcuno scrive una frase, si riceve un kick e così via, in sintesi: un evento rappresenta ciò che può succedere su IRC, in una chat.
Ogni evento porta con se quelli che potremmo definire come "dati caratteristici", ad esempio immaginiamo un OP che esegue un KICK su un utente. Supponiamo che l'OP abbia nickname Budus e la "vittima" si chiami paperino. Budus digita un comando IRC come questo:
/KICK paperino togliti dai piedi !Con i privilegi adeguati, un comando come questo provoca il KICK di paperino dal canale con un il messaggio "togliti dai piedi !".
Ecco quindi che, come "dati caratteristici", abbiamo almeno questi:
Il nickname dell'utente che ha eseguito il KICK
Il nickname dell'utente che ha subito il KICK
l'Hostname dell'utente che ha subito il KICK (è importante se di mezzo c'è un KICKBAN piuttosto che un semplice KICK)
Il nome del canale
il nome del server IRC
il messaggio (eventuale) che spiega la ragione del KICKAd ognuno di questi dati potremmo, per comodità, dare un nome, un po' come si fa nei programmi con le variabili, cioè si da un nome ad un "contenitore di dati" che può assumere un valore.
Per "chiarezza", giusto per non confondere queste "variabili", stabiliamo anche che il loro nome dovrà sempre iniziare con il carattere $ , così sappiamo distinguere quando sono variabili o quando invece effettivamente semplici parole.
Ad esempio:
$lu sarà il nickname di chi esegue il KICK
$ru sarà il nickname di chi lo subisce
$rhost l'Hostname dell'utente KICKATO
$channel potrebbe essere il nome del canale
$server lo associamo al nome del server IRC
$data conterrà il testo con il motivo del KICKIl KICK è di per se un evento, cioè un'azione che si può compiere in chat.
Supponiamo di voler creare una Sentinella che, quando ad essere "KICKATO" è l'utente locale, cioè noi stessi, lo script reagisca in un certo modo, non so, un re-join automatico del canale dal quale si è stati espulsi, tanto per iniziare.
Potremmo quindi dire che vogliamo una sentinella come questa:
ogni volta che viene eseguito un KICK e $nick è uguale a $lu esegui un re-join
La variabile $nick non l'ho elencata sopra, ma rappresenta sempre il nickname dell'utente locale.
Ecco, noi sappiamo che questa "sentinella" dovrà agire in suddette condizioni; per comodità, proviamo a scomporla in quelli che sono i suoi componenti principali:
"ogni volta" rappresenta QUANTE volte la nostra sentinella dovrà intervenire; in questo caso abbiamo sostanzialmente "sempre", ma potrebbero verificarsi situazioni dove ci torna comodo che agisca solo 2 o 3 volte o 1 sola. Sostanzialmente abbiamo definito il numero di ripetizioni.
"KICK" rappresenta il nostro evento . La sentinella sarà presa in considerazione solo quando da qualche parte c'è almeno un KICK, qualsiasi altra operazione sarà ignorata.
"$nick è uguale a $lu" è la nostra condizione, ovvero, ok che controlliamo tutti i KICK che vengono eseguiti, ma interveniamo esclusivamente solo quando questa condizione è soddisfatta. $nick abbiamo detto che è una variabile e rappresenta il "nickname dell'utente locale" mentre $ru è colui che lo subisce. Se coincidono, significa proprio che è l'utente localde ad aver subito l'azione !
"re-join" è l'azione che vogliamo compiere quando la condizione viene soddisfatta.BuDuScRiPt fornisce il comando /event add per creare sentinelle e quest'ultimo accetta i parametri citati qui sopra nel seguente modo:
RIPETIZIONE EVENTO CONDIZIONE AZIONE
La RIPETIZIONE possiamo definirla mettendo il numero 0 (zero) per identificare quando vogliamo che sia sempre valutata la condizione (ciò avviene solo se l'evento corrisponde a quello che si è effettivamente verificato), un numero superiore a 0 (da 1 in sù) per definire quante volte dovrà essere valutata (quindi mettendo 3 otteniamo che al massimo l'azione verrà eseguita al verificarsi di 3 evento+condizione soddisfatti) mentre inserendo il carattere '?' otterremo che nel momento in cui la sentinella verrà soddisfatta, dopo che l'azione sarà eseguita, si auto-eliminerà.
L'EVENTO è una parola chiave associato ad una operazione IRC, e in BuDuScRiPt abbiamo:
jserver quando si entra in un server
jchannel quando si entra in un canale o lo fanno altri
pchannel quando si esce da un canale o lo fanno altri
pserver quando si esce da un server o lo fanno altri
kick quando viene eseguito un kick
who quando viene eseguito un who
chgnick quando si cambia nickname o lo fanno altri
text quando altri scrivono qualcosa nel canale
badword quando si scrive una parolaccia o lo fanno altri
query quando altri ci scrivono in query
ctcp quando si riceve un CTCP
mode quando viene eseguito un mode
flood quando altri superano l'anti-flood
notify quando si riceve una NOTIFICA
all qualsiasi evento gestito (tutti quelli precedenti)
La CONDIZIONE va scomposta in "costante=variabile" oppure "costante!variabile" ('!' rappresenta il "non uguale").
L'AZIONE è sempre un comando IRC o BuDuScRiPt; nel nostro caso un "/join #nomecanale".Ora, la RIPETIZIONE noi sappiamo che deve essere "sempre", quindi useremo 0 come parametro.
L'EVENTO che fa al caso nostro è certamente il kick, quindi anche qui sappiamo cosa usare.
La CONDIZIONE è un po' più ostica, perché dobbiamo prima di tutto sapere come questa viene VALUTATA. Abbiamo detto che è formata da una costante, poi viene l'operatore (= o !) e quindi la variabile.
Non è tassativo che la costante sia sempre tale, anzi, spesso è necessario che anch'essa contenga variabili.
Lo script, quando valuta una condizione, procede in questo modo:
Controlla se la costante è contenuta nella variabile (chiaramente qui si intende il VALORE che assumerà la variabile)
Controlla se la variabile è contenuta nella costante
Verifica se la variabile può essere soddisfatta dall'Espressione Regolare ( http://it.wikipedia.org/wiki/Espressione_regolare ). Più avanti vedremo di cosa si tratta, per chi già non conosce l'argomento.Ciò significa che non è una vera UGUAGLIANZA, ovvero scrivere:
p=paperinopotrebbe, a rigor di logica, sembrare FALSA come soluzione, ma se leggiamo bene come lo script ragiona, ci accorgeremo che proprio al punto [1] la condizione sarà soddisfatta perché "p" è contenuta in "paperino".
Allo stesso modo se avessimo avuto:
paperino=pla condizione era soddisfatta al controllo del punto [2].
Ciò significa che questa valutazione è molto "permissiva", nel senso che lascia facilmente spazio a molteplici soluzioni positive, non sempre facilmente individuabili nel momento in cui usiamo una cosa come questa:
paperino=$ru$ru è la variabile che identifica "l'utente remoto"; ebbene, che valori può assumere ?
Sostanzialmente illimitati, qualsiasi nickname; ecco quindi che se $ru assume valore "|-paperino-|" otteniamo:
paperino=|-paperino-|e sempre la valutazione del punto [2] viene soddisfatta, anche se probabilmente non è ciò che ci aspettiamo !
Come risolvere ?
Beh, se ad esempio usassimo degli apici per delimitare costante e variabile otterremmo:
'paperino'='$ru'che risolto diventa:
'paperino'='|-paperino-|'ora la stringa "'paperino'" non può essere contenuta in "'|-paperino-|'" e neanche viceversa (e, per ora fidarsi, nemmeno l'espressione regolare lo è).
Ecco quindi che l'uso degli apici ci è venuto in aiuto per ottenere un comportamento "ragionevole", più simile a quello che il simbolo = rappresenta.
Avremmo potuto usare altri caratteri al posto dell'apice ' tuttavia quest'ultimo ha un'ulteriore scopo: se la costante inizia con il carattere apice ' , la valutazione per espressione regolare non sarà fatta.
Quindi, non solo la condizione sopra non poteva essere soddisfatta da una espressione regolare (da ora regexp), ma nemmeno sarebbe stata presa in considerazione perché era presente il carattere ' .
A volte però può capitare la necessità di NON usare gli apici (almeno nella costante) ma si vuole tuttavia evitare il controllo delle regexp; in questi casi è possibile usare il solo apice iniziale nella costante, in questo modo:
'paperino='|-paperino-|'se non lo si vuole anche nella variabile, il discorso non cambia (chiaramente la valutazione sarà diversa, ma comunque la regexp non sarà valutata):
'paperino=|-paperino-|L'apice ' sarà automaticamente rimosso, in modo che non "infastidisca" la valutazione; se invece si desidera non venga rimosso, bisogna anteporre un backslash \ , in questo modo:
\'paperino=|-paperino-|Tornando al nostro caso del KICK, la condizione che a noi probabilmente torna comoda è qualcosa come la seguente:
'mionickname'='$ru'ora, "mionickname" dovrebbe rappresentare il nickname che effettivamente si utilizza in chat (ad esempio "paperino") mentre $ru abbiamo già detto che sarà sostituito con il nickname della vittima del KICK. Per evitare di dover creare tante sentinelle quanti sono i possibili nickname che si vuole poter utilizzare, possiamo usare una variabile che non abbiamo citato precedentemente $nick, che assume sempre come valore il nickname corrente dell'utente locale; quindi otteniamo:
'$nick'='$ru'Infine l'AZIONE sarà un semplice comando IRC:
/JOIN #nomecanalemmm, però a pensarci bene, anche qua ci tocca creare tante sentinelle per ogni possibile canale !
Ma siamo matti ?! :-?
Certo che no ! :proud:
E' sufficiente usare una variabile ! :D
/JOIN $channelGià perchè, come detto sopra, $channel assumerà il nome del canale nel quale è stato eseguito il KICK.
Abbiamo quindi trovato i 4 parametri, RIPETIZIONE, EVENTO, CONDIZIONE e AZIONE, assembliamoli:
/event add 0 kick '$nick'='$ru' /JOIN $channelche appunto significa: ogni volta che mi kickano, rientra nel canale.
Dato che l'appetito vien mangiando, a qualcuno potrebbe interessare anche una "soluzione più pesante", ovvero non limitarsi solo a rientrare ma kickare a sua volta chi ci ha kickato ! :rotfl:
Ebbene, le sentinelle consentono di eseguire comandi multipli semplicemente separandoli dalla sequenza \; . Quindi:
/event add 0 kick '$nick'='$ru' /JOIN $channel\;/KICK $lu beccati questo !Nella maggior parte degli eventi, la variabile $lu assume come valore proprio il nickname dell'utente locale (tant'è che "lu" sta per LocalUser) ma, nel caso del KICK, assume invece il nickname di chi ha eseguito il KICK.
Un'altra variabile che assume valore a seconda della circostanza è $data; ad esempio nel KICK abbiamo visto che rappresenta il "motivo del KICK", ma ad esempio in un pchannel (cioè un PART da un canale) assume il motivo di uscita dell'utente (se viene specificato, solitamente ce ne sta almeno uno di default del client IRC), mentre per un evento come badword la variabile assumerà il numero di parolacce che il relativo utente ha scritto.
Per quanto riguarda le regexp, potremmo pensare di creare una sentinella che vada a sgridare quegli utenti che, maleducatamente, scrivono solo in MAIUSCOLO (andando palesemente contro la netiquette IRC).
Ora, spiegare come funziona una regexp è abbondantemente fuori dallo scopo di questo post, quindi invito a farsi una sana lettura almeno di questa guida: http://it.wikipedia.org/wiki/Espressione_regolare
tuttavia qui darò qualche consiglio su come procedere.
Come prima cosa dovete sapere che nella cartella .xchat2/buduscript è presente il programma udaregexp, usabile da terminale, che aiuta l'utente a creare/controllare le proprie espressioni regolari.
Un'Espressione Regolare, sinteticamente, è una sequenza di caratteri (simboli, numeri e lettere) che rappresentano un insieme di stringhe (dove per stringa s'intende sempre una sequenza di lettere, numeri e anche simboli).
Contorto :sospiro:
Ad esempio, supponiamo di voler creare una CONDIZIONE come la seguente: LETTERE_MAIUSCOLE='$data'
Ovvero, vogliamo che la nostra costante sia rappresentata da qualsiasi combinazione possibile di lettere maiuscole, in modo che se l'utente del nostro canale scrive solo in maiuscolo (e ciò che scrive finirà dentro a $data) la condizione sia vera.
Sembra chiaramente una cosa impossibile da fare, come faccio a definire "solo le lettere maiuscole in qualsiasi combinazione e lunghezza" ? :-?
Ebbene, consideriamo alcuni dei "caratteri speciali" utilizzati nelle regexp:
^ : sta ad indicare che la stringa deve iniziare da lì
[ ] : tutti i caratteri tra parentesi quadre sono un'espressione che definisce un insieme di caratteri che dovrà essere presente.
* : significa che l'espressione precedente può essere ripetuta infinite volte
$ : sta ad indicare che la stringa deve finire lìSe ad esempio scrivessimo:
^[ABCDEFG]*$otterremmo una regexp che si traduce così: una stringa contenente una qualsiasi ripetizione dei seguenti caratteri (in qualsiasi ordine): A, B, C, D, E, F, G
Le regexp ci vengono incontro anche per definire da quale a quale carattere prendere l'insieme, quindi scrivendo:
^[A-Z]*$di fatto intendiamo tutti i caratteri MAIUSCOLI dalla A alla Z.
Ora, per fare qualche prova di questa regexp, potremmo usare il programma udaregexp; apriamo un terminale e digitiamo i seguenti comandi:
cd .xchat2/buduscript
./udaregexp '^[A-Z]*$' 'prova'
otterremo come risultato:
regexp '^[A-Z]*$' on: 'prova' = 0"prova" dobbiamo immaginare che sia ciò che può scrivere un utente; il risultato della valutazione è 0 (zero), ciò significa che se un utente scrive "prova" la condizione non sarà soddisfatta, data una costante contenente l'espressione regolare ^[A-Z]*$ (nel terminale abbiamo usato gli apici ' affinché la BASH Linux non interpreti "a suo modo" determinati caratteri, come il $, ma in una condizione ricordarsi che non si può usare ' come carattere iniziale se si vuole la valutazione di tipo regexp).
Proviamo invece a scrivere "PROVA" in maiuscolo per vedere cosa succede:
./udaregexp '^[A-Z]*$' 'PROVA'otteniamo:
regexp '^[A-Z]*$' on: 'PROVA' = 1mmm, molto interessante ! :D
Proviamo con una frase !
./udaregexp '^[A-Z]*$' 'PROVA DI UNA FRASE'risultato:
regexp '^[A-Z]*$' on: 'PROVA DI UNA FRASE' = 0mmm, ma come, perché ora mi da 0 quando è tutto in maiuscolo ? :-?
Semplice: la frase contiene anche il carattere spazio, non SOLO caratteri dalla A alla Z.NB: Nella CONDIZIONE non si può utilizzare lo SPAZIO così com'è, al suo posto bisogna utilizzare la variabile $_ ; ad esempio:
'una frase con molti spazi'='$data'dovremo scrivere:
'una$_frase$_con$_molti$_spazi'='$data'Proviamo ad aggiungere, tra i caratteri dell'insieme, anche lo spazio (usando la variabile $_):
./udaregexp '^[A-Z$_]*$' 'PROVA DI UNA FRASE'otteniamo:
regexp '^[A-Z ]*$' on: 'PROVA DI UNA FRASE' = 1(notare che $_ è stato sostituito da uno spazio)
Ahh, funziona ! :proud:
Bene, ora non ci resta che tradurre il tutto in una sentinella:
RIPETIZIONE: direi sempre, quindi 0
EVENTO: quando scrivono gli altri nel canale, quindi text
CONDIZIONE: direi che ^[A-Z$_]*$='$data' fa al caso nostro
AZIONE: bah, qua potremmo usare un semplice /SAY $ru non scrivere in maiuscolo !che assemblata diventa:
/event add 0 text ^[A-Z$_]*$='$data' /SAY $ru non scrivere in maiuscolo !La fame vien mangiando, ora magari vi piacerebbe anche KICKARE chi per troppe volte scrive in maiuscolo, ma io sono stanco di scrivere
e magari, se proprio non riuscite da soli, proverò a buttare giù qualcosa alla prossima puntata, ok ? :okay:
Le sentinelle sono un sistema con il quale lo script consente all'utente di eseguire determinate operazioni al verificarsi di un determinato evento.
Ad esempio un evento può essere quando qualcuno entra in un canale, viene cambiata una modalità, qualcuno scrive una frase, si riceve un kick e così via, in sintesi: un evento rappresenta ciò che può succedere su IRC, in una chat.
Ogni evento porta con se quelli che potremmo definire come "dati caratteristici", ad esempio immaginiamo un OP che esegue un KICK su un utente. Supponiamo che l'OP abbia nickname Budus e la "vittima" si chiami paperino. Budus digita un comando IRC come questo:
/KICK paperino togliti dai piedi !Con i privilegi adeguati, un comando come questo provoca il KICK di paperino dal canale con un il messaggio "togliti dai piedi !".
Ecco quindi che, come "dati caratteristici", abbiamo almeno questi:
Il nickname dell'utente che ha eseguito il KICK
Il nickname dell'utente che ha subito il KICK
l'Hostname dell'utente che ha subito il KICK (è importante se di mezzo c'è un KICKBAN piuttosto che un semplice KICK)
Il nome del canale
il nome del server IRC
il messaggio (eventuale) che spiega la ragione del KICKAd ognuno di questi dati potremmo, per comodità, dare un nome, un po' come si fa nei programmi con le variabili, cioè si da un nome ad un "contenitore di dati" che può assumere un valore.
Per "chiarezza", giusto per non confondere queste "variabili", stabiliamo anche che il loro nome dovrà sempre iniziare con il carattere $ , così sappiamo distinguere quando sono variabili o quando invece effettivamente semplici parole.
Ad esempio:
$lu sarà il nickname di chi esegue il KICK
$ru sarà il nickname di chi lo subisce
$rhost l'Hostname dell'utente KICKATO
$channel potrebbe essere il nome del canale
$server lo associamo al nome del server IRC
$data conterrà il testo con il motivo del KICKIl KICK è di per se un evento, cioè un'azione che si può compiere in chat.
Supponiamo di voler creare una Sentinella che, quando ad essere "KICKATO" è l'utente locale, cioè noi stessi, lo script reagisca in un certo modo, non so, un re-join automatico del canale dal quale si è stati espulsi, tanto per iniziare.
Potremmo quindi dire che vogliamo una sentinella come questa:
ogni volta che viene eseguito un KICK e $nick è uguale a $lu esegui un re-join
La variabile $nick non l'ho elencata sopra, ma rappresenta sempre il nickname dell'utente locale.
Ecco, noi sappiamo che questa "sentinella" dovrà agire in suddette condizioni; per comodità, proviamo a scomporla in quelli che sono i suoi componenti principali:
"ogni volta" rappresenta QUANTE volte la nostra sentinella dovrà intervenire; in questo caso abbiamo sostanzialmente "sempre", ma potrebbero verificarsi situazioni dove ci torna comodo che agisca solo 2 o 3 volte o 1 sola. Sostanzialmente abbiamo definito il numero di ripetizioni.
"KICK" rappresenta il nostro evento . La sentinella sarà presa in considerazione solo quando da qualche parte c'è almeno un KICK, qualsiasi altra operazione sarà ignorata.
"$nick è uguale a $lu" è la nostra condizione, ovvero, ok che controlliamo tutti i KICK che vengono eseguiti, ma interveniamo esclusivamente solo quando questa condizione è soddisfatta. $nick abbiamo detto che è una variabile e rappresenta il "nickname dell'utente locale" mentre $ru è colui che lo subisce. Se coincidono, significa proprio che è l'utente localde ad aver subito l'azione !
"re-join" è l'azione che vogliamo compiere quando la condizione viene soddisfatta.BuDuScRiPt fornisce il comando /event add per creare sentinelle e quest'ultimo accetta i parametri citati qui sopra nel seguente modo:
RIPETIZIONE EVENTO CONDIZIONE AZIONE
La RIPETIZIONE possiamo definirla mettendo il numero 0 (zero) per identificare quando vogliamo che sia sempre valutata la condizione (ciò avviene solo se l'evento corrisponde a quello che si è effettivamente verificato), un numero superiore a 0 (da 1 in sù) per definire quante volte dovrà essere valutata (quindi mettendo 3 otteniamo che al massimo l'azione verrà eseguita al verificarsi di 3 evento+condizione soddisfatti) mentre inserendo il carattere '?' otterremo che nel momento in cui la sentinella verrà soddisfatta, dopo che l'azione sarà eseguita, si auto-eliminerà.
L'EVENTO è una parola chiave associato ad una operazione IRC, e in BuDuScRiPt abbiamo:
jserver quando si entra in un server
jchannel quando si entra in un canale o lo fanno altri
pchannel quando si esce da un canale o lo fanno altri
pserver quando si esce da un server o lo fanno altri
kick quando viene eseguito un kick
who quando viene eseguito un who
chgnick quando si cambia nickname o lo fanno altri
text quando altri scrivono qualcosa nel canale
badword quando si scrive una parolaccia o lo fanno altri
query quando altri ci scrivono in query
ctcp quando si riceve un CTCP
mode quando viene eseguito un mode
flood quando altri superano l'anti-flood
notify quando si riceve una NOTIFICA
all qualsiasi evento gestito (tutti quelli precedenti)
La CONDIZIONE va scomposta in "costante=variabile" oppure "costante!variabile" ('!' rappresenta il "non uguale").
L'AZIONE è sempre un comando IRC o BuDuScRiPt; nel nostro caso un "/join #nomecanale".Ora, la RIPETIZIONE noi sappiamo che deve essere "sempre", quindi useremo 0 come parametro.
L'EVENTO che fa al caso nostro è certamente il kick, quindi anche qui sappiamo cosa usare.
La CONDIZIONE è un po' più ostica, perché dobbiamo prima di tutto sapere come questa viene VALUTATA. Abbiamo detto che è formata da una costante, poi viene l'operatore (= o !) e quindi la variabile.
Non è tassativo che la costante sia sempre tale, anzi, spesso è necessario che anch'essa contenga variabili.
Lo script, quando valuta una condizione, procede in questo modo:
Controlla se la costante è contenuta nella variabile (chiaramente qui si intende il VALORE che assumerà la variabile)
Controlla se la variabile è contenuta nella costante
Verifica se la variabile può essere soddisfatta dall'Espressione Regolare ( http://it.wikipedia.org/wiki/Espressione_regolare ). Più avanti vedremo di cosa si tratta, per chi già non conosce l'argomento.Ciò significa che non è una vera UGUAGLIANZA, ovvero scrivere:
p=paperinopotrebbe, a rigor di logica, sembrare FALSA come soluzione, ma se leggiamo bene come lo script ragiona, ci accorgeremo che proprio al punto [1] la condizione sarà soddisfatta perché "p" è contenuta in "paperino".
Allo stesso modo se avessimo avuto:
paperino=pla condizione era soddisfatta al controllo del punto [2].
Ciò significa che questa valutazione è molto "permissiva", nel senso che lascia facilmente spazio a molteplici soluzioni positive, non sempre facilmente individuabili nel momento in cui usiamo una cosa come questa:
paperino=$ru$ru è la variabile che identifica "l'utente remoto"; ebbene, che valori può assumere ?
Sostanzialmente illimitati, qualsiasi nickname; ecco quindi che se $ru assume valore "|-paperino-|" otteniamo:
paperino=|-paperino-|e sempre la valutazione del punto [2] viene soddisfatta, anche se probabilmente non è ciò che ci aspettiamo !
Come risolvere ?
Beh, se ad esempio usassimo degli apici per delimitare costante e variabile otterremmo:
'paperino'='$ru'che risolto diventa:
'paperino'='|-paperino-|'ora la stringa "'paperino'" non può essere contenuta in "'|-paperino-|'" e neanche viceversa (e, per ora fidarsi, nemmeno l'espressione regolare lo è).
Ecco quindi che l'uso degli apici ci è venuto in aiuto per ottenere un comportamento "ragionevole", più simile a quello che il simbolo = rappresenta.
Avremmo potuto usare altri caratteri al posto dell'apice ' tuttavia quest'ultimo ha un'ulteriore scopo: se la costante inizia con il carattere apice ' , la valutazione per espressione regolare non sarà fatta.
Quindi, non solo la condizione sopra non poteva essere soddisfatta da una espressione regolare (da ora regexp), ma nemmeno sarebbe stata presa in considerazione perché era presente il carattere ' .
A volte però può capitare la necessità di NON usare gli apici (almeno nella costante) ma si vuole tuttavia evitare il controllo delle regexp; in questi casi è possibile usare il solo apice iniziale nella costante, in questo modo:
'paperino='|-paperino-|'se non lo si vuole anche nella variabile, il discorso non cambia (chiaramente la valutazione sarà diversa, ma comunque la regexp non sarà valutata):
'paperino=|-paperino-|L'apice ' sarà automaticamente rimosso, in modo che non "infastidisca" la valutazione; se invece si desidera non venga rimosso, bisogna anteporre un backslash \ , in questo modo:
\'paperino=|-paperino-|Tornando al nostro caso del KICK, la condizione che a noi probabilmente torna comoda è qualcosa come la seguente:
'mionickname'='$ru'ora, "mionickname" dovrebbe rappresentare il nickname che effettivamente si utilizza in chat (ad esempio "paperino") mentre $ru abbiamo già detto che sarà sostituito con il nickname della vittima del KICK. Per evitare di dover creare tante sentinelle quanti sono i possibili nickname che si vuole poter utilizzare, possiamo usare una variabile che non abbiamo citato precedentemente $nick, che assume sempre come valore il nickname corrente dell'utente locale; quindi otteniamo:
'$nick'='$ru'Infine l'AZIONE sarà un semplice comando IRC:
/JOIN #nomecanalemmm, però a pensarci bene, anche qua ci tocca creare tante sentinelle per ogni possibile canale !
Ma siamo matti ?! :-?
Certo che no ! :proud:
E' sufficiente usare una variabile ! :D
/JOIN $channelGià perchè, come detto sopra, $channel assumerà il nome del canale nel quale è stato eseguito il KICK.
Abbiamo quindi trovato i 4 parametri, RIPETIZIONE, EVENTO, CONDIZIONE e AZIONE, assembliamoli:
/event add 0 kick '$nick'='$ru' /JOIN $channelche appunto significa: ogni volta che mi kickano, rientra nel canale.
Dato che l'appetito vien mangiando, a qualcuno potrebbe interessare anche una "soluzione più pesante", ovvero non limitarsi solo a rientrare ma kickare a sua volta chi ci ha kickato ! :rotfl:
Ebbene, le sentinelle consentono di eseguire comandi multipli semplicemente separandoli dalla sequenza \; . Quindi:
/event add 0 kick '$nick'='$ru' /JOIN $channel\;/KICK $lu beccati questo !Nella maggior parte degli eventi, la variabile $lu assume come valore proprio il nickname dell'utente locale (tant'è che "lu" sta per LocalUser) ma, nel caso del KICK, assume invece il nickname di chi ha eseguito il KICK.
Un'altra variabile che assume valore a seconda della circostanza è $data; ad esempio nel KICK abbiamo visto che rappresenta il "motivo del KICK", ma ad esempio in un pchannel (cioè un PART da un canale) assume il motivo di uscita dell'utente (se viene specificato, solitamente ce ne sta almeno uno di default del client IRC), mentre per un evento come badword la variabile assumerà il numero di parolacce che il relativo utente ha scritto.
Per quanto riguarda le regexp, potremmo pensare di creare una sentinella che vada a sgridare quegli utenti che, maleducatamente, scrivono solo in MAIUSCOLO (andando palesemente contro la netiquette IRC).
Ora, spiegare come funziona una regexp è abbondantemente fuori dallo scopo di questo post, quindi invito a farsi una sana lettura almeno di questa guida: http://it.wikipedia.org/wiki/Espressione_regolare
tuttavia qui darò qualche consiglio su come procedere.
Come prima cosa dovete sapere che nella cartella .xchat2/buduscript è presente il programma udaregexp, usabile da terminale, che aiuta l'utente a creare/controllare le proprie espressioni regolari.
Un'Espressione Regolare, sinteticamente, è una sequenza di caratteri (simboli, numeri e lettere) che rappresentano un insieme di stringhe (dove per stringa s'intende sempre una sequenza di lettere, numeri e anche simboli).
Contorto :sospiro:
Ad esempio, supponiamo di voler creare una CONDIZIONE come la seguente: LETTERE_MAIUSCOLE='$data'
Ovvero, vogliamo che la nostra costante sia rappresentata da qualsiasi combinazione possibile di lettere maiuscole, in modo che se l'utente del nostro canale scrive solo in maiuscolo (e ciò che scrive finirà dentro a $data) la condizione sia vera.
Sembra chiaramente una cosa impossibile da fare, come faccio a definire "solo le lettere maiuscole in qualsiasi combinazione e lunghezza" ? :-?
Ebbene, consideriamo alcuni dei "caratteri speciali" utilizzati nelle regexp:
^ : sta ad indicare che la stringa deve iniziare da lì
[ ] : tutti i caratteri tra parentesi quadre sono un'espressione che definisce un insieme di caratteri che dovrà essere presente.
* : significa che l'espressione precedente può essere ripetuta infinite volte
$ : sta ad indicare che la stringa deve finire lìSe ad esempio scrivessimo:
^[ABCDEFG]*$otterremmo una regexp che si traduce così: una stringa contenente una qualsiasi ripetizione dei seguenti caratteri (in qualsiasi ordine): A, B, C, D, E, F, G
Le regexp ci vengono incontro anche per definire da quale a quale carattere prendere l'insieme, quindi scrivendo:
^[A-Z]*$di fatto intendiamo tutti i caratteri MAIUSCOLI dalla A alla Z.
Ora, per fare qualche prova di questa regexp, potremmo usare il programma udaregexp; apriamo un terminale e digitiamo i seguenti comandi:
cd .xchat2/buduscript
./udaregexp '^[A-Z]*$' 'prova'
otterremo come risultato:
regexp '^[A-Z]*$' on: 'prova' = 0"prova" dobbiamo immaginare che sia ciò che può scrivere un utente; il risultato della valutazione è 0 (zero), ciò significa che se un utente scrive "prova" la condizione non sarà soddisfatta, data una costante contenente l'espressione regolare ^[A-Z]*$ (nel terminale abbiamo usato gli apici ' affinché la BASH Linux non interpreti "a suo modo" determinati caratteri, come il $, ma in una condizione ricordarsi che non si può usare ' come carattere iniziale se si vuole la valutazione di tipo regexp).
Proviamo invece a scrivere "PROVA" in maiuscolo per vedere cosa succede:
./udaregexp '^[A-Z]*$' 'PROVA'otteniamo:
regexp '^[A-Z]*$' on: 'PROVA' = 1mmm, molto interessante ! :D
Proviamo con una frase !
./udaregexp '^[A-Z]*$' 'PROVA DI UNA FRASE'risultato:
regexp '^[A-Z]*$' on: 'PROVA DI UNA FRASE' = 0mmm, ma come, perché ora mi da 0 quando è tutto in maiuscolo ? :-?
Semplice: la frase contiene anche il carattere spazio, non SOLO caratteri dalla A alla Z.NB: Nella CONDIZIONE non si può utilizzare lo SPAZIO così com'è, al suo posto bisogna utilizzare la variabile $_ ; ad esempio:
'una frase con molti spazi'='$data'dovremo scrivere:
'una$_frase$_con$_molti$_spazi'='$data'Proviamo ad aggiungere, tra i caratteri dell'insieme, anche lo spazio (usando la variabile $_):
./udaregexp '^[A-Z$_]*$' 'PROVA DI UNA FRASE'otteniamo:
regexp '^[A-Z ]*$' on: 'PROVA DI UNA FRASE' = 1(notare che $_ è stato sostituito da uno spazio)
Ahh, funziona ! :proud:
Bene, ora non ci resta che tradurre il tutto in una sentinella:
RIPETIZIONE: direi sempre, quindi 0
EVENTO: quando scrivono gli altri nel canale, quindi text
CONDIZIONE: direi che ^[A-Z$_]*$='$data' fa al caso nostro
AZIONE: bah, qua potremmo usare un semplice /SAY $ru non scrivere in maiuscolo !che assemblata diventa:
/event add 0 text ^[A-Z$_]*$='$data' /SAY $ru non scrivere in maiuscolo !La fame vien mangiando, ora magari vi piacerebbe anche KICKARE chi per troppe volte scrive in maiuscolo, ma io sono stanco di scrivere
e magari, se proprio non riuscite da soli, proverò a buttare giù qualcosa alla prossima puntata, ok ? :okay: