diff --git a/composer.lock b/composer.lock index 5eceef78dd..45e20f16f6 100644 --- a/composer.lock +++ b/composer.lock @@ -529,12 +529,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "76e8d9f15c5ecc0d08d39968023380a2086f0d31" + "reference": "b049d56a3ef5c87e545882737f8e1a8e965fec1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/76e8d9f15c5ecc0d08d39968023380a2086f0d31", - "reference": "76e8d9f15c5ecc0d08d39968023380a2086f0d31", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/b049d56a3ef5c87e545882737f8e1a8e965fec1d", + "reference": "b049d56a3ef5c87e545882737f8e1a8e965fec1d", "shasum": "" }, "require": { @@ -563,7 +563,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-03-29T10:00:16+00:00" + "time": "2020-03-29T17:01:59+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 7618a953e2..fc3a6b1d91 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -35,7 +35,8 @@ use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\RakLib; -use raklib\server\RakLibServer; +use raklib\server\InterThreadChannelReader; +use raklib\server\InterThreadChannelWriter; use raklib\server\ServerHandler; use raklib\server\ServerInstance; use raklib\utils\InternetAddress; @@ -82,13 +83,16 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->rakLib = new RakLibServer( $this->server->getLogger(), - \pocketmine\COMPOSER_AUTOLOADER_PATH, new InternetAddress($this->server->getIp(), $this->server->getPort(), 4), (int) $this->server->getProperty("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, $this->sleeper ); - $this->interface = new ServerHandler($this->rakLib, $this); + $this->interface = new ServerHandler( + $this, + new InterThreadChannelReader($this->rakLib->getExternalQueue()), + new InterThreadChannelWriter($this->rakLib->getInternalQueue()) + ); } public function start() : void{ @@ -132,6 +136,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function shutdown() : void{ $this->server->getTickSleeper()->removeNotifier($this->sleeper); $this->interface->shutdown(); + $this->rakLib->quit(); } public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php new file mode 100644 index 0000000000..7c88693131 --- /dev/null +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -0,0 +1,193 @@ +address = $address; + + $this->serverId = mt_rand(0, PHP_INT_MAX); + $this->maxMtuSize = $maxMtuSize; + + $this->logger = $logger; + + $this->externalQueue = new \Threaded; + $this->internalQueue = new \Threaded; + + $this->mainPath = \pocketmine\PATH; + + $this->protocolVersion = $overrideProtocolVersion ?? RakLib::DEFAULT_PROTOCOL_VERSION; + + $this->mainThreadNotifier = $sleeper; + } + + /** + * Returns the RakNet server ID + * @return int + */ + public function getServerId() : int{ + return $this->serverId; + } + + /** + * @return \Threaded + */ + public function getExternalQueue() : \Threaded{ + return $this->externalQueue; + } + + /** + * @return \Threaded + */ + public function getInternalQueue() : \Threaded{ + return $this->internalQueue; + } + + /** + * @return void + */ + public function shutdownHandler(){ + if($this->cleanShutdown !== true){ + $error = error_get_last(); + + if($error !== null){ + $this->logger->emergency("Fatal error: " . $error["message"] . " in " . $error["file"] . " on line " . $error["line"]); + $this->setCrashInfo(new \ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])); + }else{ + $this->logger->emergency("RakLib shutdown unexpectedly"); + } + } + } + + public function getCrashInfo() : ?\Throwable{ + return $this->crashInfo; + } + + private function setCrashInfo(\Throwable $e) : void{ + $this->synchronized(function(\Throwable $e) : void{ + $this->crashInfo = $e; + $this->notify(); + }, $e); + } + + public function startAndWait(int $options = PTHREADS_INHERIT_NONE) : void{ + $this->start($options); + $this->synchronized(function() : void{ + while(!$this->ready and $this->crashInfo === null){ + $this->wait(); + } + if($this->crashInfo !== null){ + throw $this->crashInfo; + } + }); + } + + public function onRun() : void{ + try{ + gc_enable(); + ini_set("display_errors", '1'); + ini_set("display_startup_errors", '1'); + + register_shutdown_function([$this, "shutdownHandler"]); + + $socket = new Socket($this->address); + $manager = new SessionManager( + $this->serverId, + $this->logger, + $socket, + $this->maxMtuSize, + $this->protocolVersion, + new InterThreadChannelReader($this->internalQueue), + new InterThreadChannelWriter($this->externalQueue, $this->mainThreadNotifier), + new ExceptionTraceCleaner($this->mainPath) + ); + $this->synchronized(function() : void{ + $this->ready = true; + $this->notify(); + }); + $manager->run(); + $this->cleanShutdown = true; + }catch(\Throwable $e){ + $this->setCrashInfo($e); + $this->logger->logException($e); + } + } + +} diff --git a/src/utils/Process.php b/src/utils/Process.php index c76f9caf58..1d26bee642 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -114,7 +114,7 @@ final class Process{ //TODO: more OS - return count(ThreadManager::getInstance()->getAll()) + 3; //RakLib + MainLogger + Main Thread + return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread } /**