2013-09-05 11:55:43 +02:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* The ProtocolHandler for the IRC Protocol.
|
|
|
|
* @author JPT
|
|
|
|
* @package Protocol
|
|
|
|
*/
|
|
|
|
class Protocol_IrcProtocolHandler extends Protocol_AbstractProtocolHandler {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $linebreak;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is called by the constructor.
|
|
|
|
* Shall create the two buffers and set them up.
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function createBuffers() {
|
|
|
|
$this->linebreak = "\n";
|
|
|
|
$this->bufferIncoming = new Misc_Buffer($this->linebreak);
|
|
|
|
$this->bufferOutgoing = new Misc_Buffer($this->linebreak);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main worker function. It will be called in a loop.
|
|
|
|
* It does all the protocol-dependent parsing.
|
|
|
|
* The returned ContentObject will be passed to the client.
|
|
|
|
* @return Protocol_IrcProtocolContentObject
|
|
|
|
* @throws Exception_ProtocolHandlerException
|
|
|
|
* @throws Exception_GeneralException
|
|
|
|
*/
|
|
|
|
public function work() {
|
|
|
|
$data = $this->bufferIncoming->getNextLine();
|
|
|
|
//create contentObject and set the raw data.
|
|
|
|
$contentObject = new Protocol_IrcProtocolContentObject($data);
|
|
|
|
|
|
|
|
//trim whitespace
|
|
|
|
$data = trim($data);
|
|
|
|
|
|
|
|
//no data? complain!
|
|
|
|
if($data === "") throw new Exception_ProtocolHandlerException("No data to process! Where did it go?!", 1292082006);
|
|
|
|
|
|
|
|
//get the guy who sent the message
|
|
|
|
$sender = "";
|
|
|
|
if($data[0] === ":") {
|
|
|
|
list($sender, $data) = explode(" ", $data, 2);
|
|
|
|
//cut the colon
|
|
|
|
$sender = substr($sender, 1);
|
|
|
|
$contentObject->setSender($sender);
|
|
|
|
}
|
|
|
|
|
|
|
|
//determine what command was sent
|
|
|
|
$command = "";
|
|
|
|
if(strpos($data, " ") !== FALSE) {
|
|
|
|
list($command, $data) = explode(" ", $data, 2);
|
|
|
|
} else {
|
|
|
|
$command = $data;
|
|
|
|
}
|
|
|
|
$contentObject->setCommand($command);
|
|
|
|
|
|
|
|
//we'll write these values into the contentObject later!
|
|
|
|
//contains a user or the channel a command is addressed to.
|
|
|
|
$target = NULL;
|
|
|
|
//parameters of the command
|
|
|
|
$params = NULL;
|
|
|
|
//content or message
|
|
|
|
$message = NULL;
|
|
|
|
//affected nickname(s) (e.g. by a KICK or MODE +b)
|
|
|
|
$subject = NULL;
|
|
|
|
|
|
|
|
//command-dependent parsing
|
|
|
|
switch($command) {
|
|
|
|
|
|
|
|
case "PRIVMSG":
|
|
|
|
case "NOTICE":
|
|
|
|
list($target, $params) = explode(" ", $data, 2);
|
|
|
|
//cut the colon
|
|
|
|
$message = substr($params, 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "INVITE":
|
|
|
|
list($target, $params) = explode(" ", $data, 2);
|
|
|
|
//cut the colon
|
|
|
|
$params = substr($params, 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "ERROR":
|
|
|
|
case "QUIT":
|
|
|
|
if(strpos($data, " :") !== FALSE) {
|
|
|
|
list($params, $message) = explode(" :", $data);
|
|
|
|
$message = substr($message, 1);
|
|
|
|
} else {
|
|
|
|
$params = $data;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "PING":
|
|
|
|
case "JOIN":
|
|
|
|
//cut the colon
|
|
|
|
$params = substr($data, 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
//channel, <comment>
|
|
|
|
case "PART":
|
|
|
|
if(strpos($data, " :") !== FALSE) {
|
|
|
|
list($params, $message) = explode(" :", $data);
|
|
|
|
$message = substr($message, 1);
|
|
|
|
} else {
|
|
|
|
$params = $data;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "NICK":
|
|
|
|
//cut the colon
|
|
|
|
$params = substr($data, 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
//channel, user, <comment>
|
|
|
|
case "KICK":
|
|
|
|
$pieces = explode(" ", $data, 3);
|
|
|
|
list($target, $subject, $data) = explode(" ", $data, 3);
|
|
|
|
//get comment for kick and cut the colon
|
|
|
|
if(count($pieces === 3)) $message = substr($data, 1);
|
|
|
|
unset($pieces);
|
|
|
|
break;
|
|
|
|
|
|
|
|
//MOTD content
|
|
|
|
case "372":
|
|
|
|
list($target, $message) = explode(" :", $data);
|
|
|
|
break;
|
|
|
|
|
|
|
|
//user, comment
|
|
|
|
case "KILL":
|
|
|
|
case "MODE":
|
|
|
|
|
|
|
|
|
|
|
|
case "AWAY":
|
|
|
|
|
|
|
|
case "001":
|
|
|
|
case "002":
|
|
|
|
case "003":
|
|
|
|
case "004":
|
|
|
|
case "005":
|
|
|
|
|
|
|
|
case "250":
|
|
|
|
case "251":
|
|
|
|
case "252":
|
|
|
|
case "253":
|
|
|
|
case "254":
|
|
|
|
case "255":
|
|
|
|
case "265":
|
|
|
|
case "266":
|
|
|
|
|
|
|
|
case "332":
|
|
|
|
case "333":
|
|
|
|
case "353":
|
|
|
|
//NAMES end
|
|
|
|
case "366":
|
|
|
|
|
|
|
|
//MOTD start
|
|
|
|
case "375":
|
|
|
|
//MOTD end
|
|
|
|
case "376":
|
|
|
|
|
|
|
|
//break;
|
|
|
|
//tell when stuff is not implemented
|
|
|
|
default:
|
|
|
|
//echo "N.i.y.: " . $command . " [".$data."]\r\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//we're done parsing, now write the stuff into the contentObject.
|
|
|
|
$contentObject->setTarget($target);
|
|
|
|
$contentObject->setParams($params);
|
|
|
|
$contentObject->setMessage($message);
|
|
|
|
|
|
|
|
return $contentObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether there is work to be done.
|
|
|
|
* Important in order to assure that a ContentObject is created and passed to the Client.
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function canWork() {
|
|
|
|
return $this->bufferIncoming->hasLines();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Will put raw data into the outgoing buffer.
|
|
|
|
* This function will be removed soon.
|
|
|
|
* The ProtocolHandler shall take care of this directly.
|
|
|
|
* @param string $data
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function sendRaw($data) {
|
|
|
|
$this->bufferOutgoing->addData($data . $this->linebreak);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sends a pong.
|
|
|
|
* @param string $param
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function pong($param) {
|
|
|
|
$this->sendRaw("PONG :" . $param);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2010-11-28 01:04:35 +01:00
|
|
|
?>
|