211 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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);
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
?>
 |