set_details($server, $port, $user, $real, $nick, $pass); } function set_details($server = "", $port = 0, $user = "", $real = "", $nick = "", $pass = "") { $this->server = $server; $this->port = $port; $this->user = $user; $this->real = $real; $this->nick = $nick; $this->serv_pass = $pass; } function connect($server = "", $port = "", $user = "", $real = "", $nick = "", $pass = "") { if(!$this->server || !$this->port || !$this->user || !$this->real || !$this->nick) { $this->set_details($server, $port, $user, $real, $nick, $pass); } $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die(socket_strerror(socket_last_error($this->socket))); if(!socket_bind($socket, "0.0.0.0")) { echo socket_strerror(socket_last_error($socket)); } if(!socket_connect($socket, $this->server, $this->port)) { echo socket_strerror(socket_last_error($socket)); } $this->socket = $socket; if($this->serv_pass) { $this->raw($socket, "PASS $server->serv_pass\n"); } $this->raw("NICK $this->nick"); $this->raw("USER $this->user arloria.net $this->server $this->real"); } function raw($string) { if(!$string || !$this->socket) { return false; } socket_write($this->socket, $string . "\n") or $this->socket_error(); } function privmsg($target, $message) { $this->raw("PRIVMSG " . $target . " :" . $message); } function notice($target, $message) { $this->raw("NOTICE " . $target . " :" . $message); } function join($target, $key = "") { if($key) { $this->raw("JOIN :" . $target); } else { $this->raw("JOIN :" . $target . " " . $key); } } function ctcp($target, $type, $message, $reply = 0) { if(!$reply) { $this->privmsg($target, chr(01) . $type . chr(32) . $message . chr(01)); } else { $this->notice($target, chr(01) . $type . chr(32) . $message . chr(01)); } } function handle($event, $function, $overwrite = false) { if(!$event || (!empty($this->events[$event]) && $overwrite === false)) { return false; } $this->events[$event] = array($function); } function alarm($delay, $function, $args = array(), $persist = false) { if(!$delay || !$function) { return false; } if(!is_int($delay)) { return false; } $this->alarms[] = array(gmdate('U') + $delay, $function, $args, $delay, $persist); } function unhandle($event) { if(!$event || empty($this->events[$event])) { return false; } unset($this->events[$event]); } function socket_error() { die(socket_strerror(socket_last_error($this->socket))); } function ismask($mask) { if(preg_match("/.{1,30}![a-zA-Z0-9]{1,10}@.+/", $mask)) { return true; } return false; } function event($event_name) { $args = func_get_args(); array_shift($args); $event_name = strtolower($event_name); if(!empty($this->events[$event_name])) { if(function_exists($this->events[$event_name][0])) { call_user_func($this->events[$event_name][0], &$this, $args); } } } function alarms() { if(empty($this->alarms)) { return false; } $date = gmdate('U'); foreach($this->alarms as $alarm) { $element = key($this->alarms); if ($alarm[0] <= $date) { if(function_exists($alarm[1])) { call_user_func($alarm[1], &$this, $alarm[2]); if($alarm[4] === false) { unset($this->alarms[$element]); } elseif($alarm[4] != 0) { $this->alarms[$element][4]--; if($this->alarms[$element][4] == 0) { unset($this->alarms[$element]); } else { $this->alarms[$element][0] = $date + $alarm[3]; } } } } } } function parse($data) { if(empty($data)) { return true; } $pieces = explode(" ", $data); if($pieces[0] == "PING") { $this->raw("PONG $pieces[1]"); $pong = strstr($pieces[1], ":"); $this->event('ping', $pong); } elseif(!empty($pieces[1]) && (is_numeric($pieces[1]) || $pieces[1] == "NOTICE")) { $sender = array_shift($pieces); $sender = substr($sender, 1); $event = array_shift($pieces); $target = array_shift($pieces); $message = explode(":", $data, 3); if(!empty($message[2])) { $this->event($event, $target, $message[2], $sender); } else { $this->event($event, $target, "", $sender); } } elseif($pieces[0] == "ERROR") { $event = 'error'; $type = substr($pieces[1], 1); $message = substr($pieces[2], 1); $this->event('error', $type, $message); } elseif (!empty($pieces[1])) { switch($pieces[1]) { case "PRIVMSG": case "NOTICE": case "INVITE": $sender = array_shift($pieces); $sender = substr($sender, 1); $event = array_shift($pieces); if($event == 353) { array_shift($pieces); } $target = array_shift($pieces); $message = explode(":", $data, 3); if(!empty($message[2])) { if(strpos($message[2], chr(01)) === 0 && strrpos($message[2], chr(01)) == strlen($message[2])) { $ctcp = substr($message[2], 1, -1); if(strpos($ctcp, " ")) { list($ctcp_type, $ctcp_message) = explode(' ', $ctcp, 2); } else { $ctcp_type = $ctcp; } if($event == "PRIVMSG") { $this->event('ctcp', $target, $sender, $ctcp_type, $ctcp_message); $this->event('ctcp_' . $ctcp_type, $sender, $target, $ctcp_message); } elseif($event == "NOTICE") { $this->event('ctcpreply', $target, $sender, $ctcp_type, $ctcp_message); $this->event('ctcpreply_' . $ctcp_type, $sender, $target, $ctcp_message); } } else { $this->event($event, $target, $message[2], $sender); } } else { $this->event($event, $target, "", $sender); } break; case "MODE": $sender = array_shift($pieces); $sender = substr($sender, 1); $event = array_shift($pieces); $target = array_shift($pieces); $modes = array_shift($pieces); if(strpos($modes, ":") === 0) { $modes = substr($modes, 1); } $option = ""; if (!empty($pieces[0])) { $option = implode(" ", $pieces); } $this->event($event, $target, $sender, $modes, $option); break; case "JOIN": case "PART": $sender = array_shift($pieces); $sender = substr($sender, 1); $event = array_shift($pieces); $channel = array_shift($pieces); if(strpos($channel, ":") === 0) { $channel = substr($channel, 1); } $message = ""; if(!empty($pieces)) { $message = implode(" ", $pieces); if(strpos($message, ":") === 0) { $message = substr($message, 1); } } $this->event($event, $channel, $sender, $message); break; // :Sheepeep!sheepeep@network-admin.arloria.net KICK #fingal Sheepeep :Test kick case "KICK": $sender = array_shift($pieces); $sender = substr($sender, 1); $event = array_shift($pieces); $channel = array_shift($pieces); $user = array_shift($pieces); $reason = implode(" ", $pieces); $reason = substr($reason, 1); $this->event($event, $channel, $user, $reason); break; case "QUIT": case "NICK": $sender = array_shift($pieces); $sender = substr($sender, 1); $event = array_shift($pieces); $arg2 = implode(" ", $pieces); $arg2 = substr($arg2, 1); $this->event($event, $sender, $args); break; } } return true; } function loop() { if(!$this->socket) { return false; } while(1) { $read = array($this->socket); $null = NULL; $count = socket_select($read, $null, $null, 0, 1); if($count > 0) { $data = socket_read($this->socket, 512, PHP_NORMAL_READ) or $this->socket_error(); $data = trim($data); if(!empty($data)) { $part = explode(" ", $data); $this->parse($data); } } $this->alarms(); ob_flush(); usleep(10000); } } } ?>