Clase para conectar a un IRC mediante PHP.

Iniciado por Aex12, Julio 30, 2013, 04:46:19 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Julio 30, 2013, 04:46:19 PM Ultima modificación: Marzo 27, 2014, 05:29:24 PM por Expermicid
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
<?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->fp, 2048));
}

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($buffer, 0, 1) === ':')){
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($buffer, 0, 6)) === '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

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

Ahora ya la estructura para hacer funcionar la clase correctamente:
Código: php

<?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

<?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)