server = $server; $this->server->getLogger()->info("Starting remote control listener"); if($password === ""){ throw new \RuntimeException("Empty password"); } $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if($this->socket === false or !@socket_bind($this->socket, $interface, $port) or !@socket_listen($this->socket)){ throw new \RuntimeException(trim(socket_strerror(socket_last_error()))); } socket_set_block($this->socket); $ret = @socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $ipc); if(!$ret){ $err = socket_last_error(); if(($err !== SOCKET_EPROTONOSUPPORT and $err !== SOCKET_ENOPROTOOPT) or !@socket_create_pair(AF_INET, SOCK_STREAM, 0, $ipc)){ throw new \RuntimeException(trim(socket_strerror(socket_last_error()))); } } [$this->ipcMainSocket, $this->ipcThreadSocket] = $ipc; $notifier = new SleeperNotifier(); $this->server->getTickSleeper()->addNotifier($notifier, function() : void{ $response = new RemoteConsoleCommandSender(); $this->server->dispatchCommand($response, $this->instance->cmd); $this->instance->response = TextFormat::clean($response->getMessage()); $this->instance->synchronized(function(RCONInstance $thread){ $thread->notify(); }, $this->instance); }); $this->instance = new RCONInstance($this->socket, $password, (int) max(1, $maxClients), $this->server->getLogger(), $this->ipcThreadSocket, $notifier); socket_getsockname($this->socket, $addr, $port); $this->server->getLogger()->info("RCON running on $addr:$port"); } public function stop() : void{ $this->instance->close(); socket_write($this->ipcMainSocket, "\x00"); //make select() return $this->instance->quit(); @socket_close($this->socket); @socket_close($this->ipcMainSocket); @socket_close($this->ipcThreadSocket); } }