public function run() { while ($this->stop !== true) { $this->synchronized(function () { $this->wait(2000); }); $r = [$socket = $this->socket]; $w = null; $e = null; if (socket_select($r, $w, $e, 0) === 1) { if (($client = socket_accept($this->socket)) !== false) { socket_set_block($client); socket_set_option($client, SOL_SOCKET, SO_KEEPALIVE, 1); $done = false; for ($n = 0; $n < $this->maxClients; ++$n) { if ($this->{"client" . $n} === null) { $this->{"client" . $n} = $client; $this->{"status" . $n} = 0; $this->{"timeout" . $n} = microtime(true) + 5; $done = true; break; } } if ($done === false) { @socket_close($client); } } } for ($n = 0; $n < $this->maxClients; ++$n) { $client =& $this->{"client" . $n}; if ($client !== null) { if ($this->{"status" . $n} !== -1 and $this->stop !== true) { if ($this->{"status" . $n} === 0 and $this->{"timeout" . $n} < microtime(true)) { //Timeout $this->{"status" . $n} = -1; continue; } $p = $this->readPacket($client, $size, $requestID, $packetType, $payload); if ($p === false) { $this->{"status" . $n} = -1; continue; } elseif ($p === null) { continue; } switch ($packetType) { case 9: //Protocol check if ($this->{"status" . $n} !== 1) { $this->{"status" . $n} = -1; continue; } $this->writePacket($client, $requestID, 0, RCON::PROTOCOL_VERSION); $this->response = ""; if ($payload == RCON::PROTOCOL_VERSION) { $this->logger->setSendMsg(true); } //GeniRCON output break; case 4: //Logger if ($this->{"status" . $n} !== 1) { $this->{"status" . $n} = -1; continue; } $this->writePacket($client, $requestID, 0, str_replace("\n", "\r\n", trim($this->logger->getMessages()))); $this->response = ""; break; case 3: //Login if ($this->{"status" . $n} !== 0) { $this->{"status" . $n} = -1; continue; } if ($payload === $this->password) { socket_getpeername($client, $addr, $port); $this->response = "[INFO] Successful Rcon connection from: /{$addr}:{$port}"; $this->response = ""; $this->writePacket($client, $requestID, 2, ""); $this->{"status" . $n} = 1; } else { $this->{"status" . $n} = -1; $this->writePacket($client, -1, 2, ""); continue; } break; case 2: //Command if ($this->{"status" . $n} !== 1) { $this->{"status" . $n} = -1; continue; } if (strlen($payload) > 0) { $this->cmd = ltrim($payload); $this->synchronized(function () { $this->waiting = true; $this->wait(); }); $this->waiting = false; $this->writePacket($client, $requestID, 0, str_replace("\n", "\r\n", trim($this->response))); $this->response = ""; $this->cmd = ""; } break; } } else { @socket_set_option($client, SOL_SOCKET, SO_LINGER, ["l_onoff" => 1, "l_linger" => 1]); @socket_shutdown($client, 2); @socket_set_block($client); @socket_read($client, 1); @socket_close($client); $this->{"status" . $n} = 0; $this->{"client" . $n} = null; } } } } unset($this->socket, $this->cmd, $this->response, $this->stop); exit(0); }