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