public function run()
 {
     while ($this->running) {
         while ($this->buffer->hasMoreWrite()) {
             $line = IRCLine::parseInternalLine($this->buffer->nextWrite(), $signal, $client);
             if ($signal === IRCLine::SIGNAL_STD_LINE) {
                 if (isset($this->sockets[$client])) {
                     socket_write($this->sockets[$client], $line . "\r\n");
                 }
             } elseif ($signal === IRCLine::SIGNAL_CLOSE_SESSION) {
                 if (isset($this->sockets[$line])) {
                     socket_close($this->sockets[$line]);
                     unset($this->sockets[$line]);
                 }
             }
         }
         while (($newSock = socket_accept($this->serverSocket)) !== false) {
             socket_getpeername($newSock, $address, $port);
             $identifier = "{$address}:{$port}";
             $this->buffer->addRead(chr(IRCLine::SIGNAL_OPEN_SESSION) . $identifier);
             $this->sockets[$identifier] = $newSock;
         }
         while (($line = $this->readLine($identifier)) !== false) {
             $this->buffer->addRead(chr(IRCLine::SIGNAL_STD_LINE) . "{$identifier} {$line}");
         }
     }
     foreach ($this->sockets as $socket) {
         socket_write($socket, "ERROR :Server shutting down\r\n");
         socket_close($socket);
     }
     socket_close($this->serverSocket);
 }
 public function handleLine(IRCLine $line)
 {
     try {
         $cmd = $line->getCommand();
     } catch (\Exception $e) {
         if (stripos(get_class($e), "outofboundsexception") !== false) {
             $this->send("461 {$line->getCmdName()} :Not enough parameters");
         }
         return;
     }
     switch ($cmd->getName()) {
         case PassCommand::$name:
             return;
             // ignored
         // ignored
         case NickCommand::$name:
             /** @var NickCommand $cmd */
             $this->send("432 {$cmd->nick} :Erroneous nickname");
             return;
         case UserCommand::$name:
             /** @var UserCommand $cmd */
             $this->username = $cmd->user;
             $this->realname = $cmd->realname;
             return;
         case ModeCommand::$name:
             // TODO
             return;
         case "SERVICE":
             return;
         case "OPER":
             return;
         case QuitCommand::$name:
             $this->main->getManager()->getBuffer()->addWrite(chr(IRCLine::SIGNAL_CLOSE_SESSION) . $this->identifier);
             return;
     }
 }
 public function tick()
 {
     while ($this->buffer->hasMoreRead()) {
         $line = IRCLine::parseInternalLine($this->buffer->nextRead(), $signal, $client);
         switch ($signal) {
             case IRCLine::SIGNAL_OPEN_SESSION:
                 $this->sessions[$line] = new IRCSession($line, $this->main);
                 break;
             case IRCLine::SIGNAL_CLOSE_SESSION:
                 if (isset($this->sessions[$line])) {
                     $this->sessions[$line]->finalize();
                     unset($this->sessions[$line]);
                 }
                 break;
             case IRCLine::SIGNAL_STD_LINE:
                 if (isset($this->sessions[$client])) {
                     $this->sessions[$client]->handleLine(new IRCLine($line));
                 }
         }
     }
 }