Underc0de

Programación Web => Back-end => Mensaje iniciado por: Aex12 en Julio 30, 2013, 04:46:19 PM

Título: Clase para conectar a un IRC mediante PHP.
Publicado por: Aex12 en Julio 30, 2013, 04:46:19 PM
Hoy leyendo el post de WHK sobre el Bot que creo para el irc, me dí cuenta de lo mal organizado que estaba todo el código, y que apenas hay clases para PHP que se encarguen de esto, por no decir que solo existe una, y esta hecha en pear, por lo cual en muchos servidores gratuitos no se puede instalar.

En vista de todo esto decidí crear mi propia clase para realizar conexiones a un IRC, y bueno, aun no esta terminada del todo pero se le puede sacar mucho jugo tal y como está. Primero definimos la clase irc:
Código (php) [Seleccionar]
<?php
class irc{
var 
$nick;
var 
$channel;
var 
$host;
var 
$port;

var 
$logged "false";
var 
$fp;

function 
nick($nick){
$this->nick $nick;
}

function 
channel($channel){
$this->channel $channel;
}

function 
sendmessage($message){
fwrite($this->fp'PRIVMSG '.$this->channel.' :'.$message."\n");
}

function 
buffer(){
return 
trim((string)fgets($this->fp2048));
}

function 
connect($host$port){
$this->host=$host$this->port=$port;
$this->fp fsockopen($this->host$this->port);
}

function 
open(){
$buffer $this->buffer();
if((
$this->logged == "false") and (substr($buffer01) === ':')){
fwrite($this->fp'USER '.$this->nick.' '.$this->nick.' '.$this->nick.' '.$this->nick."\n");
fwrite($this->fp'NICK '.$this->nick."\n");
fwrite($this->fp'JOIN '.$this->channel."\n");
$this->sendmessage("IRC Class TESTING");
$this->logged "true";
}

if(
strtolower(substr($buffer06)) === 'PING :'){
$host explode(':'$buffer);
$host trim($host[1]);
fwrite($this->fp'PONG :'.$host."\n");
unset(
$host);
}
        
if(
$this->logged == "true"){
return 
$buffer;
}
}

function 
getmessage($message){
$f explode(' PRIVMSG '.$this->channel.' :'$message);
if(
count($f) === 2){
$return = array();
$return['message'] = $f['1'];
$return['name'] = explode("!"$f['0']);
$return['name']=substr($return['name'],1);
return 
$return;
} else {
return 
false;
}
}

function 
disconnect(){
fclose($this->fp);
}

}
?>


Agregamos una función opcional (Fuera de la clase) para saber cuando la cadena X empieza por la cadena Y. (Muy util para cuando queremos enviar "comandos" al bot):
Código (php) [Seleccionar]

<?php
function empiezapor($value$search){
$value strtolower($value);
$search strtolower($search);
$chars strlen($search);
if(
substr($value0$chars) === $search){
return 
true;
} else {
return 
false;
}
}
?>


Ahora ya la estructura para hacer funcionar la clase correctamente:
Código (php) [Seleccionar]

<?php
$aex 
= new irc;
$aex->nick("AexBot_PHP");
$aex->channel("#CanalTestingBots");
$aex->connect("irc.freenode.net"8000);

while(
$buffer $aex->open()){

}

$aex->disconnect();
?>



Y ahora para capturar los mensajes recibidos por el irc agregamos esto al while:
Código (php) [Seleccionar]

<?php
while($buffer $aex->open()){
if(
$buffer == "!:error:"){
$aex->sendmessage("ERRORAZO!");
}

if(
$message $aex->getmessage($buffer)){
$mensaje $message['message'];
$nombre $message['name'];

if(
empiezapor($mensaje"adios")){
$aex->sendmessage("Adiós ".$nombre."!");
$aex->disconnect();
}
if(
empiezapor($mensaje"hola")){
$aex->sendmessage("Hola ".$nombre);
$aex->sendmessage("El buffer ha arrojado lo siguiente:");
$aex->sendmessage($buffer);
}
}
}
?>



De momento por una razon que se me escapa no soy capaz de capturar el nombre del emisor de un mensaje, aunque ya lo tengo declarado en la funcion getmessage(); pero parece no funcionarme. Espero que se entienda todo, un saludo!

Bugs encontrados:
- No reconoce el nombre del emisor de un mensaje
- Cuando pasa X tiempo se autodesconecta (Al no recibir paquetes por el buffer el while acaba y se autodesconecta)