¿Qué es un CTCP?
Las siglas CTCP significan “Client to Client Protocol” o “Protocolo de cliente a cliente”, y básicamente se trata de un tipo especial de comunicación entre los usuarios de un servidor de IRC que será usada para provocar que los usuarios del script que estemos haciendo ejecuten ciertas acciones automáticamente al recibir cierta información por CTCP.
Por otra parte los usuarios remotos se refiere a algo que usted seguro que ya ha visto anteriormente en el tutorial de eventos remotos, se trata de ese numerito que siempre ponemos en el evento por ejemplo “on 1:OPEN:”, ¿qué es ese ‘1’? Pues sencillamente es el nivel que necesita un usuario para hacer que salte ese evento con los comandos que se hayan especificado, después entraré en más detalle en esto, ahora volviendo al principio vamos a ver todo lo referente a los eventos CTCP:
Comandos CTCP
Para mandar información a otro usuario mediante CTCP lo haremos de la siguiente forma: /ctcp <nick> <mensaje> donde <nick> es el nick de la otra persona y <mensaje> es cualquier mensaje que queramos enviar por ese protocolo. Lógicamente no nos pondremos a hablar con un usuario mediante CTCP's ya que seria absurdo estando los dos conectados al IRC. Los CTCP's tienen otra utilidad... que es la de que el otro usuario reaccione automáticamente de una cierta manera al usted enviarle ese CTCP. Por ejemplo, existe uno que tiene el mIRC ya implementado: el famoso CTCP PING y consiste en enviar un ping al otro usuario:
/ctcp <nick> ping
El programa del otro usuario responderá automáticamente al CTCP PING y lo hará devolviendo una información, que al llegarnos de nuevo el mIRC nos muestra en pantalla. En este caso en pantalla se muestra el “Lag” o retardo de la línea que hay entre usted y la persona a la que envió el ping. Puede probar con los otros CTCP implementados ya en mIRC, el funcionamiento de todos es similar; solo varia la respuesta que proporcionan.
A continuación aprenderá a crear sus propias respuestas a ciertos CTCP's, ya que el mIRC solo trae unas cuantas ya definidas (como son PING, VERSION, TIME...) pero usted quizás quiera hacer otras con otros nombres, o tal vez cambiar las respuestas que a los ya existentes dará su programa.
Eventos CTCP
Vamos a ver ya como usamos este tipo de eventos para que la explicación sea más fácil de entender. En la sección “Remotes” del editor del mIRC es donde definiremos estos eventos y se hacen de una forma parecida al resto de eventos remotos. La sintaxis es: ctcp <nivel>:<texto>:<#,?,*>:{ comandos }
Este tipo de eventos harán que nuestro programa se comporte de cierta manera (es decir, que ejecute los comandos que le especifiquemos) cuando recibamos un CTCP <texto> de otro usuario. El <nivel> de momento lo dejaremos siempre en ‘1’ , y el otro parámetro ha de ser o bien un ‘#’ si nos referimos a un canal, un ‘?’ para un privado(query) o un ‘*’ para “en cualquier lado”. Con un pequeño ejemplo lo veremos más claro, copie lo siguiente en el editor del mIRC, pestaña “Remotes”:
ctcp 1:*hora*:*:{
msg $nick Son las $time
}
Ese evento hará como ya habrá imaginado que cuando un usuario le haga un /ctcp <nick> hora, usted automáticamente le responda enviándole un query en el que diga por ejemplo “Son las 19:45:23”. Como ve se pueden usar ‘*’ en el parámetro <texto> para indicar que si la palabra “hola” del mensaje CTCP viniera precedida de cualquier otra, o después de esa palabra hubiera alguna palabra más, se ejecutaría de todas formas en comando. En este ejemplo en concreto eso no es de mucha utilidad, pero en el siguiente si que lo será:
ctcp 1:dime*:*:{
msg $nick Lo siento estoy ocupado
}
Este evento hará que cuando un usuario le envíe un /ctcp DIME, usted le responda diciéndole que está ocupado. Por ejemplo un usuario le podría hacer un /ctcp <sunick> dime la hora o quizás /ctcp <sunick> dime tu nombre. En cualquier caso la respuesta será la misma.
Lo que hemos visto hasta ahora se refiere a crear eventos CTCP propios, que no existían antes en el mIRC y a los que el script responderá de la forma que le hemos especificado, pero también si quisiera, podría cambiar su respuesta a algunos de los eventos CTCP ya definidos, como es el caso del PING, para ello tendremos que especificar al final de los comandos, el comando /halt.
Por ejemplo:
ctcp 1:PING:*:{
notice $nick NO me toques, gracias! | halt
}
Este evento hará que cuando usted reciba un /ctcp ping de algún usuario, le enviará un /notice diciéndole: “NO me toques, gracias!”, y mediante el comando /halt haremos que el script deje de procesar ese evento, y de esa forma que no procese la parte que ya estaba hecha en el mIRC (la que nos devuelve el lag). También podríamos usar este procedimiento para otros CTCPs ya definidos como son TIME, USERINFO... etc.
Otra utilidad de estos eventos puede ser la de controlar nuestro mIRC “a distancia”, y me explico, si abrimos dos miRC, podremos controlar a uno de ellos mediante CTCPs mientras que el otro lo controlaremos normalmente, se pueden usar por lo tanto para controlar a nuestros clones, por ejemplo si copiamos el siguiente código en la sección Remotes y abrimos dos miRC:
ctcp 1:habla*:#:{ /say $1- }
Cuando desde uno de los mIRC escribamos /ctcp <nick_clon> HABLA <mensaje> el otro mIRC que hemos abierto enviará el mensaje que pongamos después del “HABLA” al canal, por ejemplo si ponemos /ctcp <nickclon> habla soy un bot, me manejan con ctcps! hará que nuestro clon diga ese mensaje al canal.
ctcp 1:quit:*:{ /quit $1- }
Este nuevo ejemplo hará que al recibirlo el CTCP, el clon cierre el mIRC con el mensaje especificado en /ctcp <nickclon> quit <mensaje_de_quit>
ctcp 1:entra:*:{ /join $1 }
Este hará que el clon entre en el canal que especifiquemos en /ctcp <nickclon> entra #canal
ctcp 1:cometin:#:{ /say Me llamo $1 , tengo $2 años y soy $3 }
Este último hará que el clon diga en el canal ese mensaje usando las tres siguientes palabras que pongamos después del /ctcp <nickclon> cometin, por ejemplo si ponemos /ctcp <nickbot> cometin Raúl 29 alto, el bot o clon pondrá en el canal"Me llamo Raúl, tengo 29 años y soy alto".
Con esto hemos matado dos pájaros de un tiro, no sólo ya sabemos manejar los eventos CTCP y como evitar las respuestas predeterminadas de algunos de ellos, sino que hemos aprendido sobre su principal utilidad que es la creación de Clones que obedezcan nuestras órdenes, también conocidos como “bots”.
Antes de pasar a la siguiente sección hay que comentar también que hay un tipo especial de eventos CTCP que sirven exclusivamente para cambiar la apariencia de las respuestas estándar de los CTCPs predefinidos en el mIRC... es decir que por ejemplo cuando usted hace un ping a alguien, ese alguien le devuelve la información del ping, y usted ve en pantalla algo como: [Bj0rn PING reply]: 0 secs
Pero quizás para hacer más bonito el script le gustaría que pusiera:
Lag con Bj0rn: 0 segundos
Para ello usamos el evento ON CTCPREPLY que tiene la siguiente sintaxis:
on 1:CTCPREPLY:<ctcp>:{ comandos }
Donde <ctcp> pondremos el CTCP predefinido al que nos referimos, y en comandos la secuencia de comandos que queremos ejecutar. Generalmente para este tipo de acciones usaremos /echo para poner líneas de texto en pantalla. Vamos a ver como conseguiríamos hacer que la respuesta del PING nos fuera mostrada como hemos visto antes, debemos escribir en los “remotes”:
on 1:CTCPREPLY:*PING*:{
%lag = $ctime - $2
echo –s Lag con $nick : %lag
halt
}
Lo que hemos hecho es primero calcular el lag basándonos en la información que nos devuelve el nick al que le hemos hecho el PING. En este caso nos devuelve: “PING 919197981” . ¿Y que es ese numero tan largo? . Ese numero corresponde a una referencia de tiempo, indicada como el numero de segundos transcurridos desde el 1 de enero de 1970 . El instante al que se refiere ese número es el momento en que la persona recibió el PING, por lo tanto si restamos a la hora actual en el formato $ctime (que nos devolverá la hora actual como numero de segundos desde el 1 de enero de 1970) de la fecha en la que el nick recibió el ctcp, nos quedará un numero más pequeño y corresponderá al LAG en segundos. Guardamos ese dato en la variable %lag y a continuación, mediante un /echo, ponemos la información en Status, y el comando /halt. Se debe estar preguntando ¿ese halt no parará el proceso del PING y nos dejará sin ver la información? La respuesta es no, puesto que cuando este evento “salta” la información del PING ya nos ha sido devuelta por la otra persona, así que en este tipo de eventos el /halt al final lo único que hará será evitar que veamos, además del mensaje que hemos especificado, el que ya había por defecto. Pruebe ese ejemplo, y después pruébelo de nuevo suprimiendo el /halt para que vea usted mismo a lo que nos referimos.
Usuarios Remotos
Ya le he dado una pista antes de que son los usuarios remotos... nos referimos a un usuario remoto cada vez que especificamos un evento remoto , por ejemplo en el evento “on 1:JOIN” le estamos diciendo al mIRC “cuando un usuario de nivel 1 entre a un canal...” . Ésta es una sección completamente opcional y no necesariamente todos los scripts harán uso de ella, puesto que sólo es realmente útil para ciertas tareas muy específicas. Antes que nada debe saber, que por defecto, nivel 1 quiere decir “todos los usuarios”, es por eso que hasta ahora todos los eventos remotos se han declarado con “on 1:...” para que tengan efecto sobre todos los usuarios, pero podría darse la ocasión en que usted quiera que algún o algunos usuarios en concreto tengan acceso a unos eventos y no lo tenga el resto, para ello les tendremos que asignar un nivel.
· Asignación de niveles a usuarios
Para asignar un nivel determinado a un usuario iremos al editor del mIRC, pero esta vez a una pestaña que seguramente tendremos en blanco, la pestaña “USERS”. La sintaxis para declarar que un usuario tiene un cierto nivel es:
<nivel>:<nick>!<user>@<host>/<ip>
Por ejemplo:
10:Bj0rn!*@*
20:Sammy!*@conmutado.ctcreuna.cl
Hemos creado dos usuarios remotos, el primero Bj0rn le hemos dado el nivel ‘10’ y cualquier persona con ese nick tendrá acceso a los privilegios de ese nivel 10, que los especificaremos más adelante. El segundo nivel que hemos es asignado es más especifico porque se lo asignamos a un nick y a una máscara, es decir que el nivel 20 solo lo tendrá aquel que su nick sea “Sammy” y su host sea “conmutado.ctcreuna.cl”, de esa forma nos aseguramos que los privilegios que especifiquemos para el nivel 20 solo los Sammy y no alguna persona que se ponga ese nick. Una cosa importante a recordar es que una persona con nivel 20 tendrá acceso no solo a los privilegios del nivel 20, sino también a los de nivel 19,18,17....etc, es decir que en el ejemplo anterior, Sammy tendría acceso a los eventos de nivel 20, pero también a los de nivel 10. Si quisiéramos que Sammy tuviera acceso únicamente a los eventos de nivel 20, tendríamos que escribirlo de la siguiente forma:
=20: Sammy!*@conmutado.ctcreuna.cl
El ‘=’ delante del nivel indica que la persona especificada solo podrá acceder a los eventos que marquemos con un nivel 20, es decir que los de nivel 1, o 2, o 10 no los podrá acceder el usuario Sammy.
Pues bien así se asignan los niveles de una forma “estática” es decir, vamos al editor del mIRC y los introducimos a mano, pero también podríamos hacerlo de una forma “dinámica” mediante comandos del mIRC, digo dinámica porque nos pueden servir estos comandos para más adelante permitir al usuario cambiar el nivel de cierta persona o añadir mas gente con un determinado nivel. Los comandos son: /auser [-a] <niveles> <nick/host>
Añade un usuario con el nivel o niveles que especifiquemos a la lista de usuarios remotos, si especificamos el parámetro [-a] hará que si el usuario ya existía, se le añada el nuevo nivel al que ya tenía. Por ejemplo:
/auser 10 Bj0rn
Añade a Bj0rn a la lista de usuarios remotos con nivel 10, si Bj0rn ya estaba en esa lista, será borrado y sustituido por la nueva entrada.
/auser –a 12,13 Bj0rn Añade los niveles 12 y 13 a los que ya tenía el usuario Bj0rn, por lo tanto la sección users quedará así:
10,12,13: Bj0rn
En lugar de un nick podríamos haber especificado una máscara con el modelo nick!user@host
/flush [niveles] - Este comando borrará a todos los nicks de niveles especificados que no estén actualmente en ninguno de nuestros canales.
Por ejemplo:
/flush 1,2,3. Borrará de la lista de usuarios remotos a todas las personas que tengan nivel 1, 2 o 3 y no estén en ninguno de nuestros canales.
/flush - Cuando se especifique este comando sin argumentos borrará todas las entradas (en la pestaña “Users” del mIRC) de gente que no esté actualmente en ninguno de nuestros canales
/guser [-a] <niveles> <nick> [tipo] - Este comando trabaja de la misma forma que /auser con la única diferencia de que solo le podemos especificar el nick de la persona y el mIRC mirará su máscara actual y la añadirá al nick, para ello tenemos que especificarle también el [tipo] de máscara que será un número de 0 a 9
/guser 10 TipoX 4 - Añade al nick TipoX con nivel 10 y una máscara del tipo 4 (*!*@*.dominio)
/ruser [niveles] <nick / host> [tipo] - Borrará los niveles que especifiquemos del nick o host que especifiquemos, podemos también darle solo el nick y especificar el [tipo] de máscara para que el mIRC la mire y borre los niveles de los usuarios que tengan esa máscara.
/ruser 10 Ytreme - Borrará el nivel 10 que le hayamos dado al nick Ytreme
/ruser Ytreme - Borrará a Ytreme de la lista de usuarios remotos (o lo que es lo mismo le quitará todos los niveles)
/ruser 25 Somatic 4 - El mIRC buscará la información de Somatic y borrará el nivel 25 de todas las entradas en la lista de usuarios remotos que tengan esa máscara.
/rlevel [-r] <niveles> - Borra a todos los usuarios de la lista de usuarios remotos cuyo primer nivel sea el que especifiquemos en <niveles>. Si usamos el parámetro [-r] borrará a todos los usuarios que tengan el nivel <niveles> en cualquier lugar. Partiendo de:
10,12,15: TireX
12,20: Yan
El comando: /rlevel 12 - borrará al usuario TireX puesto que su primer nivel el 12
/rlevel –r - Borrará tanto a TireX como a Yan puesto que tienen el nivel 12, no importa en que posición.
/ulist [ < / > ] <nivel> - Lista a los usuarios de nivel <nivel>, o bien podemos especificar el parámetro [ < / > ] como">4" o “<10”.
Por ejemplo:
/ulist <10 - Lista todos los usuarios cuyo nivel sea menor o igual a 10
/ulist >20 - Lista a todos los usuarios remotos cuyo nivel sea mayor o igual a 20
Restricciones en el acceso a eventos
Vista ya la forma en la que asignamos niveles a usuarios, ahora veremos como puede hacer que ciertos eventos solo sean accesibles por usuarios específicos (con un nivel específico), para ello simplemente cambiaremos ese “1” que solíamos poner en todos los eventos remotos/ctcps por el nivel mínimo que necesitará el usuario para acceder al evento:
on 10:JOIN:#:{ echo –s Ha entrado un usuario de nivel 10 o superior}
Este evento hará que cuando un usuario de nivel 10 o superior entre en un canal en el que usted esté, le salga un mensaje en en Status avisándole. Pero recuerde que este evento no sólo lo accederán los usuarios de nivel 10, sino los de 20, 30, etc...
Pero también podemos hacer que un evento solo sea accesible por los usuarios de un nivel determinado, y no por aquellos usuarios que tengan más nivel, lo haremos mediante el prefijo ‘+’ :
on +5:JOIN:#:{ echo –s Ha entrado un usuario de nivel 5 }
De esta forma si entra un usuario con nivel 10 por ejemplo, este evento no se ejecutará puesto que esta restringido a los usuarios de nivel 5.
Otra forma de restringir el acceso a eventos es mediante el sufijo ‘!’ al nivel, que hará que el evento no se ejecute si fue accionado por usted mismo, por ejemplo:
on 1!:OP:#:{ /echo $nick le dio op a $opnick }
Este evento hará que cuando un usuario le de op a otro nos sea notificado en la ventana activa, a excepción de cuando sea usted el usuario que da op.
Y al igual que restringimos el acceso a ciertos eventos también podemos tener eventos de “libre acceso” por todos los usuarios, independientemente del nivel que tengan usando un ‘*’ en lugar del nivel:
on *:JOIN:#:{ echo $chan Ha entrado $nick }
Ese evento mostrará un mensaje en pantalla cada vez que entre un usuario a un canal, sin tener en cuenta su nivel.
También podemos usar el prefijo ‘@’ para indicarle al script que ese evento solo salte cuando tengamos OP en ese canal, por ejemplo:
on @10:JOIN:#:{ op $nick }
Este evento hará que cuando un usuario de nivel 10 entre a un canal en el que estemos, y en el que seamos op, le demos op automáticamente .
Resumiendo un poco esta última parte en la siguiente tabla de ejemplos:
Evento Accesible por usuarios de nivel:
on 100:PART 100 o superior
on +30:DEOP Únicamente 30
on 5!:QUIT 5 o superior (excepto usted!)
on *:JOIN Todos
on @30:NICK 30 o superior (solo si usted es OP en el canal)
Visto esto, y para finalizar, se va a realizar un ejemplo que mezcle los Usuarios Remotos con lo que vimos al principio de este documento sobre eventos CTCP, el objetivo será crear un medidor de LAG, algo que es fundamental en cualquier script.
Ejemplo 1: Creación de un medidor de LAG
Para medir el lag que se tiene con una cierta persona, lo que se hace, como ya sabe, es hacerle a esa persona un CTCP PING, pues bien si usted quiere hallar el lag con usted mismo, es decir su propio lag con el server, lo que tendrá que hacer es como ya habrá adivinado, hacerse un CTCP PING a usted mismo, por lo tanto analicemos un poco en que se basará nuestro medidor para que después nos sea más fácil construirlo:
Primero necesitaremos un TIMER, es decir que cada ‘X’ segundos el mIRC nos haga automáticamente un PING para hallar nuestro lag.
Después necesitaremos que la respuesta a ese ping se nos muestre en un formato diferente al habitual y que la respuesta habitual se omita, pero habrá que tener en cuenta que cuando hagamos un ping a nosotros mismos, la respuesta que recibiremos será del tipo “Tu lag es de X segundos”, para ello usaremos el evento “ctcp 1:ping”. El problema es que si en ese evento ponemos una línea que diga “Tu lag es de X segundos” ese ctcp saltará cada vez que alguien nos haga un ping, sea quien sea, y lo que haremos en este ejemplo es que ese evento solo se ejecute cuando la persona que le haga el ping sea usted misma, de esa forma conseguiremos que cada vez que usted se haga un ping (automáticamente mediante el timer) se active el evento ctcp del ping que usted habrá diseñado y que cuando sea otra persona la que le haga un ping, ésta reciba el mensaje estándar. Pasemos ya a ver el código para este ejemplo, y posteriormente l acabaremos de comentar:
Copie lo siguiente en “Aliases”:
/medidor {
timer 0 30 ctcp $me PING
auser 55 $me
}
Copie lo siguiente en “Remotes”:
ctcp 55:PING:{
%lag = $ctime - $2
titlebar Lag: %lag
halt
}
on 1:CONNECT:{ medidor }
Y ya está, lógicamente este es un medidor de lag bastante primitivo en el sentido de que se le pueden añadir muchas más cosas, pero esta es la base y a partir de ella usted podrá ir elaborando su propio medidor de lag con sus conocimientos.
La explicación es bastante simple, cuando usted conecte a un servidor de IRC (salta el evento on 1:connect) se ejecutará el alias “medidor” que iniciará un timer infinito (de ahí el ‘0’ como primer parámetro) que consistirá en hacerse a usted ($me) un CTCP PING cada 30 segundos. Además cuando conecte usted será añadido a la lista de usuarios remotos con nivel 55. Al cabo de 30 segundos se producirá por primera vez ese CTCP PING que pusimos en el timer, y puesto que el ping lo manda usted que es un usuario de nivel 55, saltará el evento “CTCP 55” que calculará el lag y lo mostrará en la barra de título del mIRC mediante el comando “titlebar”, por último se usa un “halt” para que la respuesta predeterminada del mIRC al PING quede escondida. Y obviamente si cualquier otro usuario le hiciera un ping, como usted será el único con nivel 55, este evento no saltará y por tanto el otro usuario recibirá la respuesta estándar del PING.