CTCP y Usuarios Remotos
Escrito por TeMpEsT

Publicado:14/02/1999
  Actualizado:14/02/1999
 

 

Introducción 
 
Las siglas CTCP significan “Client to Client Protocol” o “Protocolo de cliente a cliente” en castellano, y básicamente se trata de un tipo escpecial de comunicación entre los usuarios de un server de IRC que será usada para provocar que los usuarios de el 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 enventos 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, despues 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 y consiste en enviar un ping al otro usuario: 
  /ctcp <nick> ping   
El programa del otro usuario responderá automaticamente 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 existendes 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 haran 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, 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 despues de esa palabra hubiera alguna palabra más, se ejcutaría de todas formas en comando. En este ejemplo en concreto eso no es de mucha utlilidad, 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 diciendole que está ocupado. Por ejemplo un usuario le podría hacer un /ctcp <sunick> dime la hora o quizas /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 Nada de Pings, gracias! | halt 

} 
 
Este evento hará que cuando usted reciba un /ctcp ping de algún usuario, le enviará un /notice diciéndole: “Nada de Pings, 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 mIRCs, 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 mIRCs
   ctcp 1:habla*:#:{ /say $1- }  
Cuando desde uno de los mIRCs escribamos 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 1:entra:*:{ /join $1 }  
Este hará que el clon entre en el canal que especifiquemos en /ctcp <nickclon> entra #canal ctcp 1:comosoy:#:{ /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 despues del /ctcp <nickclon> comosoy , por ejemplo si ponemos /ctcp <nickbot> comosoy Pepe 20 alto , el bot pondrá en el canal “Me llamo Pepe, tengo 20 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, tambien 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: 
 
[TeMpEsT PING reply]: 0 secs 
 
Pero quizás para hacer más bonito el script le gustaría que pusiera: 
 
Lag con TeMpEsT: 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 lineas de texto en pantalla. Vamos a ver como conseguiriamos 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 a 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 recibio el PING, por lo tanto si restamos a la hora actual en el formato $ctime (que nos devolvera la hora actual como numero de segundos desde el 1 de enero de 1970) de la fecha en la que el nick recibio 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 continuacion, 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 pruebelo de nuevo suprimiendo el /halt para que vea usted mismo a que me refiero. 
 
 
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 usaurio 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 algun 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:TeMpEsT!*@*  20:Scytale!*@theilax.arrakis.es   
Hemos creado dos usuarios remotos, el primero TeMpEsT 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 tendra aquel que su nick sea “Scytale” y su host sea “theilax.arrakis.es”, de esa forma nos aseguramos que los provilegios que especifiquemos para el nivel 20 solo los Scytale 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, Scytale tendria acceso a los eventos de nivel 20, pero tb a los de nivel 10. Si quisieramos que Scytale tuviera acceso únicamente a los eventos de nivel 20, tendríamos que escribirlo de la siguiente forma: 
  =20:Scytale!*@theilax.arrakis.es   
el ‘=’ delante del nivel indica que la persona especificada solo podra 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 Scytale. 
 
Pues bien así se asignan los niveles de una forma “estática” es decir, vamos al editor del mIRC y los intriducimos a mano, pero tambien 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 TeMpEsT   
Añade a TeMpEsT a la lista de usuarios remotos con nivel 10, si TeMpEsT ya estaba en esa lista, será borrado y sustituido por la nueva entrada 
 
 
/auser –a 12,13 TeMpEsT 
 
Añade los niveles 12 y 13 a los que ya tenía el usuario TeMpEsT, por lo tanto la sección users quedará asi: 
  10,12,13:TeMpEsT   
En lugar de un nick podriamos haber especificado una máscara con el modelo [email protected] 
 
 
/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 a 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 tambien 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 Ytreme 4   
El mIRC buscará la información de Ytreme 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:TeMpEsT  12,20:Ytreme   
El comando: /rlevel 12 borrará al usuario Ytreme puesto que su primer nivel el 12 
  /rlevel –r 12   
Borrará tanto a Ytreme como a TeMpEsT 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 especificos (con un nivel especifico), para ello simplemente cambiaremos ese “1” que soliamos 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 accederan 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 usario 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 accceso 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 automaticamente 
 
Resumiendo un poco esta última parte en la siguiente tabla de ejmplos: 
 
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 tano analicemos un poco en que se basará nuestro medidor para que despues nos sea más fácil construirlo: 
 
Primero necesitaremos un TIMER , es decir que cada ‘X’ segundos el mIRC nos haga automaticamente un PING para hallar nuestro lag.
 
Despues 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 linea 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 (automaticamente 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 elaborándo 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 ejcutará 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 ultimo se usa un “halt” para que la respuesta predeterminada del mIRC al PING quede escondida. Y obviamente si cualquiero 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.