From e137ac4c56b161b6e48a715f3176a084681b29b5 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Thu, 10 Sep 2015 21:29:29 +0200 Subject: [PATCH] Base PHP7 work to make it "run" - READ NEXT LINES! All plugins will need to bump the API if they want to use this. NOTE THAT THIS IS NOT THE FINAL API 2.0.0 AND THAT THERE WILL BE MORE CHANGES. To start updating, you might also want to read https://secure.php.net/manual/en/migration70.php and specifically https://secure.php.net/manual/en/migration70.incompatible.php To compile PHP7 with some of the required dependencies, use https://gist.github.com/shoghicp/166ab26ce5cc7a390f45 ONLY LINUX IS TESTED, DO NOT ASK FOR OTHER PLATFORMS! ----- THIS VERSION IS NOT SUPPORTED ----- This version WILL crash randomly in unexpected places due to PHP7, pthreads, PocketMine or cosmic rays. Handle with care, and store under direct sunlight for the best performance. --- src/pocketmine/PocketMine.php | 21 ++--- src/pocketmine/Server.php | 45 ++++++----- src/pocketmine/Thread.php | 6 +- src/pocketmine/Worker.php | 6 +- src/pocketmine/command/CommandReader.php | 4 +- .../command/FormattedCommandAlias.php | 2 +- src/pocketmine/command/SimpleCommandMap.php | 2 +- .../command/defaults/GiveCommand.php | 2 +- src/pocketmine/item/Item.php | 76 +++++++++---------- src/pocketmine/item/ItemBlock.php | 4 +- src/pocketmine/level/Level.php | 2 +- src/pocketmine/level/format/anvil/Chunk.php | 6 +- src/pocketmine/level/format/leveldb/Chunk.php | 4 +- .../level/format/mcregion/Chunk.php | 6 +- .../level/format/mcregion/RegionLoader.php | 2 +- .../network/CompressBatchedTask.php | 4 +- src/pocketmine/network/Network.php | 4 +- src/pocketmine/network/RakLibInterface.php | 2 +- src/pocketmine/network/rcon/RCON.php | 2 +- src/pocketmine/network/rcon/RCONInstance.php | 6 +- src/pocketmine/network/upnp/UPnP.php | 4 +- src/pocketmine/plugin/PluginManager.php | 8 +- src/pocketmine/scheduler/AsyncPool.php | 5 +- src/pocketmine/scheduler/AsyncTask.php | 4 +- src/pocketmine/scheduler/AsyncWorker.php | 2 +- src/pocketmine/scheduler/FileWriteTask.php | 2 +- src/pocketmine/scheduler/SendUsageTask.php | 2 +- src/pocketmine/scheduler/ServerScheduler.php | 6 +- src/pocketmine/utils/Config.php | 2 +- src/pocketmine/utils/MainLogger.php | 2 +- src/raklib | 2 +- src/spl | 2 +- start.sh | 8 +- 33 files changed, 131 insertions(+), 124 deletions(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 7c2857091..6925b1efa 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -143,9 +143,8 @@ namespace pocketmine { //Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone. date_default_timezone_set("UTC"); - var_dump("LOAD LOGGER"); + $logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI); - var_dump("LOGGER LOADED"); if(!ini_get("date.timezone")){ if(($timezone = detect_system_timezone()) and date_default_timezone_set($timezone)){ @@ -320,7 +319,11 @@ namespace pocketmine { case "mac": case "linux": default: - exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); + if(function_exists("posix_kill")){ + posix_kill($pid, SIGKILL); + }else{ + exec("kill -9 " . ((int)$pid) . " > /dev/null 2>&1"); + } } } @@ -394,8 +397,8 @@ namespace pocketmine { if(substr_count($pthreads_version, ".") < 2){ $pthreads_version = "0.$pthreads_version"; } - if(version_compare($pthreads_version, "2.0.9") < 0){ - $logger->critical("pthreads >= 2.0.9 is required, while you have $pthreads_version."); + if(version_compare($pthreads_version, "3.0.0") < 0){ + $logger->critical("pthreads >= 3.0.0 is required, while you have $pthreads_version."); ++$errors; } @@ -418,13 +421,13 @@ namespace pocketmine { ++$errors; } - if(!extension_loaded("sqlite3")){ - $logger->critical("Unable to find the SQLite3 extension."); + if(!extension_loaded("yaml")){ + $logger->critical("Unable to find the YAML extension."); ++$errors; } - if(!extension_loaded("yaml")){ - $logger->critical("Unable to find the YAML extension."); + if(!extension_loaded("sqlite3")){ + $logger->critical("Unable to find the SQLite3 extension."); ++$errors; } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 13d58a62b..3f1cf0c34 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -132,6 +132,9 @@ class Server{ /** @var Server */ private static $instance = null; + /** @var \Threaded */ + private static $sleeper = null; + /** @var BanList */ private $banByName = null; @@ -754,7 +757,7 @@ class Server{ $nbt->readCompressed(file_get_contents($path . "$name.dat")); return $nbt->getData(); - }catch(\Exception $e){ //zlib decode error / corrupt data + }catch(\Throwable $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); } @@ -871,7 +874,7 @@ class Server{ }else{ file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed()); } - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); if(\pocketmine\DEBUG > 1 and $this->logger instanceof MainLogger){ $this->logger->logException($e); @@ -1080,7 +1083,7 @@ class Server{ try{ $level = new Level($this, $name, $path, $provider); - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->logger->error($this->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); if($this->logger instanceof MainLogger){ @@ -1140,7 +1143,7 @@ class Server{ $level->initLevel(); $level->setTickRate($this->baseTickRate); - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->logger->error($this->getLanguage()->translateString("pocketmine.level.generateError", [$name, $e->getMessage()])); if($this->logger instanceof MainLogger){ $this->logger->logException($e); @@ -1436,10 +1439,18 @@ class Server{ /** * @return Server */ - public static function getInstance(){ + public static function getInstance() : Server{ return self::$instance; } + public static function microSleep(int $microseconds){ + Server::$sleeper->synchronized(function(int $ms){ + var_dump("Sleeping $ms"); + Server::$sleeper->wait($ms); + var_dump("Finished sleep $ms"); + }, $microseconds); + } + /** * @param \ClassLoader $autoloader * @param \ThreadedLogger $logger @@ -1449,6 +1460,7 @@ class Server{ */ public function __construct(\ClassLoader $autoloader, \ThreadedLogger $logger, $filePath, $dataPath, $pluginPath){ self::$instance = $this; + self::$sleeper = \ThreadedFactory::create(); $this->autoloader = $autoloader; $this->logger = $logger; @@ -1627,7 +1639,6 @@ class Server{ register_shutdown_function([$this, "crashDump"]); $this->queryRegenerateTask = new QueryRegenerateEvent($this, 5); - $this->network->registerInterface(new RakLibInterface($this)); $this->pluginManager->loadPlugins($this->pluginPath); @@ -1986,11 +1997,6 @@ class Server{ * Shutdowns the server correctly */ public function shutdown(){ - if($this->isRunning){ - $killer = new ServerKiller(90); - $killer->start(); - $killer->detach(); - } $this->isRunning = false; } @@ -2040,7 +2046,7 @@ class Server{ $this->getLogger()->debug("Closing console"); $this->console->shutdown(); - $this->console->detach(); + $this->console->kill(); $this->getLogger()->debug("Stopping network interfaces"); foreach($this->network->getInterfaces() as $interface){ @@ -2051,8 +2057,9 @@ class Server{ $this->memoryManager->doObjectCleanup(); gc_collect_cycles(); - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->logger->emergency("Crashed while crashing, killing process"); + $this->logger->emergency(get_class($e) . ": ". $e->getMessage()); @kill(getmypid()); } @@ -2110,7 +2117,7 @@ class Server{ } } - public function exceptionHandler(\Exception $e, $trace = null){ + public function exceptionHandler(\Throwable $e, $trace = null){ if($e === null){ return; } @@ -2165,7 +2172,7 @@ class Server{ $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create")); try{ $dump = new CrashDump($this); - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.crash.error", $e->getMessage())); return; } @@ -2225,7 +2232,7 @@ class Server{ if($next > microtime(true)){ try{ time_sleep_until($next); - }catch(\Exception $e){ + }catch(\Throwable $e){ //Sometimes $next is less than the current time. High load? } } @@ -2344,7 +2351,7 @@ class Server{ $level->tickRateCounter = $level->getTickRate(); } } - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.level.tickError", [$level->getName(), $e->getMessage()])); if(\pocketmine\DEBUG > 1 and $this->logger instanceof MainLogger){ $this->logger->logException($e); @@ -2439,7 +2446,7 @@ class Server{ if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){ $this->queryHandler->handle($address, $port, $payload); } - }catch(\Exception $e){ + }catch(\Throwable $e){ if(\pocketmine\DEBUG > 1){ if($this->logger instanceof MainLogger){ $this->logger->logException($e); @@ -2497,7 +2504,7 @@ class Server{ if($this->queryHandler !== null){ $this->queryHandler->regenerateInfo(); } - }catch(\Exception $e){ + }catch(\Throwable $e){ if($this->logger instanceof MainLogger){ $this->logger->logException($e); } diff --git a/src/pocketmine/Thread.php b/src/pocketmine/Thread.php index ce05d37b2..d7a33f757 100644 --- a/src/pocketmine/Thread.php +++ b/src/pocketmine/Thread.php @@ -51,7 +51,7 @@ abstract class Thread extends \Thread{ } } - public function start($options = PTHREADS_INHERIT_ALL){ + public function start(int $options = PTHREADS_INHERIT_ALL){ ThreadManager::getInstance()->add($this); if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){ @@ -70,16 +70,14 @@ abstract class Thread extends \Thread{ public function quit(){ if($this->isRunning()){ $this->kill(); - $this->detach(); }elseif(!$this->isJoined()){ if(!$this->isTerminated()){ $this->join(); }else{ $this->kill(); - $this->detach(); } }else{ - $this->detach(); + $this->kill(); } ThreadManager::getInstance()->remove($this); diff --git a/src/pocketmine/Worker.php b/src/pocketmine/Worker.php index 2b54171ec..547e50963 100644 --- a/src/pocketmine/Worker.php +++ b/src/pocketmine/Worker.php @@ -51,7 +51,7 @@ abstract class Worker extends \Worker{ } } - public function start($options = PTHREADS_INHERIT_ALL){ + public function start(int $options = PTHREADS_INHERIT_ALL){ ThreadManager::getInstance()->add($this); if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){ @@ -71,16 +71,14 @@ abstract class Worker extends \Worker{ if($this->isRunning()){ $this->unstack(); $this->kill(); - $this->detach(); }elseif(!$this->isJoined()){ if(!$this->isTerminated()){ $this->join(); }else{ $this->kill(); - $this->detach(); } }else{ - $this->detach(); + $this->kill(); } ThreadManager::getInstance()->remove($this); diff --git a/src/pocketmine/command/CommandReader.php b/src/pocketmine/command/CommandReader.php index 54f25cc23..c44b89c73 100644 --- a/src/pocketmine/command/CommandReader.php +++ b/src/pocketmine/command/CommandReader.php @@ -86,7 +86,9 @@ class CommandReader extends Thread{ if(($line = $this->readLine()) !== ""){ $this->buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line); }elseif(!$this->shutdown and (microtime(true) - $lastLine) <= 0.1){ //Non blocking! Sleep to save CPU - usleep(10000); + $this->synchronized(function(){ + $this->wait(10000); + }); } $lastLine = microtime(true); diff --git a/src/pocketmine/command/FormattedCommandAlias.php b/src/pocketmine/command/FormattedCommandAlias.php index 842ab59f6..dbbe23d77 100644 --- a/src/pocketmine/command/FormattedCommandAlias.php +++ b/src/pocketmine/command/FormattedCommandAlias.php @@ -46,7 +46,7 @@ class FormattedCommandAlias extends Command{ foreach($this->formatStrings as $formatString){ try{ $commands[] = $this->buildCommand($formatString, $args); - }catch(\Exception $e){ + }catch(\Throwable $e){ if($e instanceof \InvalidArgumentException){ $sender->sendMessage(TextFormat::RED . $e->getMessage()); }else{ diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index 243354131..0e17b80fc 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -193,7 +193,7 @@ class SimpleCommandMap implements CommandMap{ $target->timings->startTiming(); try{ $target->execute($sender, $sentCommandLabel, $args); - }catch(\Exception $e){ + }catch(\Throwable $e){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.exception")); $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.command.exception", [$commandLine, (string) $target, $e->getMessage()])); $logger = $sender->getServer()->getLogger(); diff --git a/src/pocketmine/command/defaults/GiveCommand.php b/src/pocketmine/command/defaults/GiveCommand.php index 3c7578d5e..b01d7edc5 100644 --- a/src/pocketmine/command/defaults/GiveCommand.php +++ b/src/pocketmine/command/defaults/GiveCommand.php @@ -66,7 +66,7 @@ class GiveCommand extends VanillaCommand{ $data = implode(" ", array_slice($args, 3)); try{ $tags = NBT::parseJSON($data); - }catch (\Exception $ex){ + }catch (\Throwable $ex){ $exception = $ex; } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index cb73fb81f..9defb5af3 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -42,13 +42,10 @@ use pocketmine\nbt\NBT; class Item{ + /** @var NBT */ private static $cachedParser = null; - /** - * @param $tag - * @return CompoundTag - */ - private static function parseCompoundTag($tag){ + private static function parseCompoundTag(string $tag) : CompoundTag{ if(self::$cachedParser === null){ self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN); } @@ -57,11 +54,7 @@ class Item{ return self::$cachedParser->getData(); } - /** - * @param CompoundTag $tag - * @return string - */ - private static function writeCompoundTag(CompoundTag $tag){ + private static function writeCompoundTag(CompoundTag $tag) : string{ if(self::$cachedParser === null){ self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN); } @@ -850,7 +843,7 @@ class Item{ Item::$creative = []; } - public static function getCreativeItems(){ + public static function getCreativeItems() : array{ return Item::$creative; } @@ -865,7 +858,7 @@ class Item{ } } - public static function isCreativeItem(Item $item){ + public static function isCreativeItem(Item $item) : bool{ foreach(Item::$creative as $i => $d){ if($item->equals($d, !$item->isTool())){ return true; @@ -879,15 +872,11 @@ class Item{ * @param $index * @return Item */ - public static function getCreativeItem($index){ + public static function getCreativeItem(int $index){ return isset(Item::$creative[$index]) ? Item::$creative[$index] : null; } - /** - * @param Item $item - * @return int - */ - public static function getCreativeItemIndex(Item $item){ + public static function getCreativeItemIndex(Item $item) : int{ foreach(Item::$creative as $i => $d){ if($item->equals($d, !$item->isTool())){ return $i; @@ -897,7 +886,7 @@ class Item{ return -1; } - public static function get($id, $meta = 0, $count = 1, $tags = ""){ + public static function get(int $id, $meta = 0, int $count = 1, $tags = "") : Item{ try{ $class = self::$list[$id]; if($class === null){ @@ -912,7 +901,12 @@ class Item{ } } - public static function fromString($str, $multiple = false){ + /** + * @param string $str + * @param bool $multiple + * @return Item[]|Item + */ + public static function fromString(string $str, bool $multiple = false){ if($multiple === true){ $blocks = []; foreach(explode(",", $str) as $b){ @@ -941,10 +935,10 @@ class Item{ } } - public function __construct($id, $meta = 0, $count = 1, $name = "Unknown"){ + public function __construct(int $id, $meta = 0, int $count = 1, string $name = "Unknown"){ $this->id = $id & 0xffff; $this->meta = $meta !== null ? $meta & 0xffff : null; - $this->count = (int) $count; + $this->count = $count; $this->name = $name; if(!isset($this->block) and $this->id <= 0xff and isset(Block::$list[$this->id])){ $this->block = Block::get($this->id, $this->meta); @@ -970,11 +964,11 @@ class Item{ return $this->tags; } - public function hasCompoundTag(){ + public function hasCompoundTag() : bool{ return $this->tags !== "" and $this->tags !== null; } - public function hasCustomBlockData(){ + public function hasCustomBlockData() : bool{ if(!$this->hasCompoundTag()){ return false; } @@ -1030,7 +1024,7 @@ class Item{ return null; } - public function hasEnchantments(){ + public function hasEnchantments() : bool{ if(!$this->hasCompoundTag()){ return false; } @@ -1050,7 +1044,7 @@ class Item{ * @param $id * @return Enchantment|null */ - public function getEnchantment($id){ + public function getEnchantment(int $id){ if(!$this->hasEnchantments()){ return null; } @@ -1107,7 +1101,7 @@ class Item{ /** * @return Enchantment[] */ - public function getEnchantments(){ + public function getEnchantments() : array{ if(!$this->hasEnchantments()){ return []; } @@ -1123,7 +1117,7 @@ class Item{ return $enchantments; } - public function hasCustomName(){ + public function hasCustomName() : bool{ if(!$this->hasCompoundTag()){ return false; } @@ -1139,7 +1133,7 @@ class Item{ return false; } - public function getCustomName(){ + public function getCustomName() : string{ if(!$this->hasCompoundTag()){ return ""; } @@ -1155,8 +1149,8 @@ class Item{ return ""; } - public function setCustomName($name){ - if((string) $name === ""){ + public function setCustomName(string $name){ + if($name === ""){ $this->clearCustomName(); } @@ -1228,23 +1222,23 @@ class Item{ return $this->setCompoundTag(""); } - public function getCount(){ + public function getCount() : int{ return $this->count; } - public function setCount($count){ - $this->count = (int) $count; + public function setCount(int $count){ + $this->count = $count; } - final public function getName(){ + final public function getName() : string{ return $this->hasCustomName() ? $this->getCustomName() : $this->name; } - final public function canBePlaced(){ + final public function canBePlaced() : bool{ return $this->block !== null and $this->block->canBePlaced(); } - public function getBlock(){ + public function getBlock() : Block{ if($this->block instanceof Block){ return clone $this->block; }else{ @@ -1252,7 +1246,7 @@ class Item{ } } - final public function getId(){ + final public function getId() : int{ return $this->id; } @@ -1326,7 +1320,7 @@ class Item{ return false; } - final public function __toString(){ + final public function __toString() : string{ return "Item " . $this->name . " (" . $this->id . ":" . ($this->meta === null ? "?" : $this->meta) . ")x" . $this->count . ($this->hasCompoundTag() ? " tags:0x".bin2hex($this->getCompoundTag()) : ""); } @@ -1338,11 +1332,11 @@ class Item{ return false; } - public final function equals(Item $item, $checkDamage = true, $checkCompound = true){ + public final function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ return $this->id === $item->getId() and ($checkDamage === false or $this->getDamage() === $item->getDamage()) and ($checkCompound === false or $this->getCompoundTag() === $item->getCompoundTag()); } - public final function deepEquals(Item $item, $checkDamage = true, $checkCompound = true){ + public final function deepEquals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ if($item->equals($item, $checkDamage, $checkCompound)){ return true; }elseif($item->hasCompoundTag() or $this->hasCompoundTag()){ diff --git a/src/pocketmine/item/ItemBlock.php b/src/pocketmine/item/ItemBlock.php index fcbc18ea5..e7e827512 100644 --- a/src/pocketmine/item/ItemBlock.php +++ b/src/pocketmine/item/ItemBlock.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; * Class used for Items that can be Blocks */ class ItemBlock extends Item{ - public function __construct(Block $block, $meta = 0, $count = 1){ + public function __construct(Block $block, $meta = 0, int $count = 1){ $this->block = $block; parent::__construct($block->getId(), $block->getDamage(), $count, $block->getName()); } @@ -41,7 +41,7 @@ class ItemBlock extends Item{ $this->block = clone $this->block; } - public function getBlock(){ + public function getBlock() : Block{ return $this->block; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f6afcdfd0..465e8a313 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2607,7 +2607,7 @@ class Level implements ChunkManager, Metadatable{ } } $this->provider->unloadChunk($x, $z, $safe); - }catch(\Exception $e){ + }catch(\Throwable $e){ $logger = $this->server->getLogger(); $logger->error($this->server->getLanguage()->translateString("pocketmine.level.chunkUnloadError", [$e->getMessage()])); if($logger instanceof MainLogger){ diff --git a/src/pocketmine/level/format/anvil/Chunk.php b/src/pocketmine/level/format/anvil/Chunk.php index d4ebd564a..f7db19a17 100644 --- a/src/pocketmine/level/format/anvil/Chunk.php +++ b/src/pocketmine/level/format/anvil/Chunk.php @@ -180,7 +180,7 @@ class Chunk extends BaseChunk{ } return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level); - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } @@ -203,7 +203,7 @@ class Chunk extends BaseChunk{ } return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level); - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } @@ -361,7 +361,7 @@ class Chunk extends BaseChunk{ $chunk->nbt->LightPopulated = new ByteTag("LightPopulated", 0); return $chunk; - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } diff --git a/src/pocketmine/level/format/leveldb/Chunk.php b/src/pocketmine/level/format/leveldb/Chunk.php index d4f64d3fe..9716605d0 100644 --- a/src/pocketmine/level/format/leveldb/Chunk.php +++ b/src/pocketmine/level/format/leveldb/Chunk.php @@ -305,7 +305,7 @@ class Chunk extends BaseFullChunk{ $chunk->setLightPopulated(); } return $chunk; - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } @@ -393,7 +393,7 @@ class Chunk extends BaseFullChunk{ $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, str_repeat("\x00", self::DATA_LENGTH)); $chunk->skyLight = str_repeat("\xff", 16384); return $chunk; - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } diff --git a/src/pocketmine/level/format/mcregion/Chunk.php b/src/pocketmine/level/format/mcregion/Chunk.php index 0d4909f31..af8273adc 100644 --- a/src/pocketmine/level/format/mcregion/Chunk.php +++ b/src/pocketmine/level/format/mcregion/Chunk.php @@ -315,7 +315,7 @@ class Chunk extends BaseFullChunk{ } return new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, $chunk->Level); - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } @@ -353,7 +353,7 @@ class Chunk extends BaseFullChunk{ $chunk->nbt->LightPopulated = new ByteTag("LightPopulated", ($flags >> 2) & 0b1); return $chunk; - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } @@ -461,7 +461,7 @@ class Chunk extends BaseFullChunk{ $chunk->nbt->LightPopulated = new ByteTag("LightPopulated", 0); return $chunk; - }catch(\Exception $e){ + }catch(\Throwable $e){ return null; } } diff --git a/src/pocketmine/level/format/mcregion/RegionLoader.php b/src/pocketmine/level/format/mcregion/RegionLoader.php index c7a528874..c410f7ac5 100644 --- a/src/pocketmine/level/format/mcregion/RegionLoader.php +++ b/src/pocketmine/level/format/mcregion/RegionLoader.php @@ -195,7 +195,7 @@ class RegionLoader{ try{ $chunk = zlib_decode(substr($chunk, 5)); - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->locationTable[$i] = [0, 0, 0]; //Corrupted chunk, remove it continue; } diff --git a/src/pocketmine/network/CompressBatchedTask.php b/src/pocketmine/network/CompressBatchedTask.php index 22a4aaa90..66f546295 100644 --- a/src/pocketmine/network/CompressBatchedTask.php +++ b/src/pocketmine/network/CompressBatchedTask.php @@ -43,12 +43,12 @@ class CompressBatchedTask extends AsyncTask{ try{ $this->final = zlib_encode($this->data, ZLIB_ENCODING_DEFLATE, $this->level); $this->data = null; - }catch(\Exception $e){ + }catch(\Throwable $e){ } } public function onCompletion(Server $server){ - $server->broadcastPacketsCallback($this->final, $this->targets, $this->channel); + $server->broadcastPacketsCallback($this->final, $this->targets); } } \ No newline at end of file diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 8540d56b7..05da01ed3 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -157,7 +157,7 @@ class Network{ foreach($this->interfaces as $interface){ try { $interface->process(); - }catch(\Exception $e){ + }catch(\Throwable $e){ $logger = $this->server->getLogger(); if(\pocketmine\DEBUG > 1){ if($logger instanceof MainLogger){ @@ -253,7 +253,7 @@ class Network{ } } } - }catch(\Exception $e){ + }catch(\Throwable $e){ if(\pocketmine\DEBUG > 1){ $logger = $this->server->getLogger(); if($logger instanceof MainLogger){ diff --git a/src/pocketmine/network/RakLibInterface.php b/src/pocketmine/network/RakLibInterface.php index 0a7a55216..ae98c7f12 100644 --- a/src/pocketmine/network/RakLibInterface.php +++ b/src/pocketmine/network/RakLibInterface.php @@ -140,7 +140,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ $this->players[$identifier]->handleDataPacket($pk); } } - }catch(\Exception $e){ + }catch(\Throwable $e){ if(\pocketmine\DEBUG > 1 and isset($pk)){ $logger = $this->server->getLogger(); if($logger instanceof MainLogger){ diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index 455d018d0..50347b093 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -70,7 +70,7 @@ class RCON{ public function stop(){ for($n = 0; $n < $this->threads; ++$n){ $this->workers[$n]->close(); - usleep(50000); + Server::microSleep(50000); $this->workers[$n]->kill(); } @socket_close($this->socket); diff --git a/src/pocketmine/network/rcon/RCONInstance.php b/src/pocketmine/network/rcon/RCONInstance.php index 92d289647..b7d9990fb 100644 --- a/src/pocketmine/network/rcon/RCONInstance.php +++ b/src/pocketmine/network/rcon/RCONInstance.php @@ -85,7 +85,9 @@ class RCONInstance extends Thread{ public function run(){ while($this->stop !== true){ - usleep(2000); + $this->synchronized(function(){ + $this->wait(2000); + }); $r = [$socket = $this->socket]; $w = null; $e = null; @@ -162,7 +164,7 @@ class RCONInstance extends Thread{ } break; } - usleep(1); + }else{ @socket_set_option($client, SOL_SOCKET, SO_LINGER, ["l_onoff" => 1, "l_linger" => 1]); @socket_shutdown($client, 2); diff --git a/src/pocketmine/network/upnp/UPnP.php b/src/pocketmine/network/upnp/UPnP.php index e9b116dc2..e4ea65792 100644 --- a/src/pocketmine/network/upnp/UPnP.php +++ b/src/pocketmine/network/upnp/UPnP.php @@ -42,7 +42,7 @@ abstract class UPnP{ return false; } $com->StaticPortMappingCollection->Add($port, "UDP", $port, $myLocalIP, true, "PocketMine-MP"); - }catch(\Exception $e){ + }catch(\Throwable $e){ return false; } @@ -63,7 +63,7 @@ abstract class UPnP{ return false; } $com->StaticPortMappingCollection->Remove($port, "UDP"); - }catch(\Exception $e){ + }catch(\Throwable $e){ return false; } diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 4110bb73d..e52844782 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -249,7 +249,7 @@ class PluginManager{ } } } - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.fileError", [$file, $directory, $e->getMessage()])); $logger = $this->server->getLogger(); if($logger instanceof MainLogger){ @@ -563,7 +563,7 @@ class PluginManager{ $this->addPermission($perm); } $plugin->getPluginLoader()->enablePlugin($plugin); - }catch(\Exception $e){ + }catch(\Throwable $e){ $logger = Server::getInstance()->getLogger(); if($logger instanceof MainLogger){ $logger->logException($e); @@ -637,7 +637,7 @@ class PluginManager{ if($plugin->isEnabled()){ try{ $plugin->getPluginLoader()->disablePlugin($plugin); - }catch(\Exception $e){ + }catch(\Throwable $e){ $logger = Server::getInstance()->getLogger(); if($logger instanceof MainLogger){ $logger->logException($e); @@ -674,7 +674,7 @@ class PluginManager{ try{ $registration->callEvent($event); - }catch(\Exception $e){ + }catch(\Throwable $e){ $this->server->getLogger()->critical( $this->server->getLanguage()->translateString("pocketmine.plugin.eventError", [ $event->getEventName(), diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index 65b68a690..bb0914a61 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -109,8 +109,7 @@ class AsyncPool{ if(!$force and ($task->isRunning() or !$task->isGarbage())){ return; } - $this->workers[$w = $this->taskWorkers[$task->getTaskId()]]->unstack($task); - $this->workerUsage[$w]--; + $this->workerUsage[$this->taskWorkers[$task->getTaskId()]]--; } unset($this->tasks[$task->getTaskId()]); @@ -127,7 +126,7 @@ class AsyncPool{ } if(count($this->tasks) > 0){ - usleep(25000); + Server::microSleep(25000); } }while(count($this->tasks) > 0); diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 48bcb3bc4..17b9320cd 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -144,7 +144,9 @@ abstract class AsyncTask extends \Collectable{ public function cleanObject(){ foreach($this as $p => $v){ - $this->{$p} = null; + if(!($v instanceof \Threaded)){ + $this->{$p} = null; + } } } diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 3d1825c56..d9d38d6f2 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -35,7 +35,7 @@ class AsyncWorker extends Worker{ } - public function start($options = PTHREADS_INHERIT_NONE){ + public function start(int $options = PTHREADS_INHERIT_NONE){ parent::start(PTHREADS_INHERIT_CONSTANTS | PTHREADS_INHERIT_FUNCTIONS); } diff --git a/src/pocketmine/scheduler/FileWriteTask.php b/src/pocketmine/scheduler/FileWriteTask.php index f952e91e8..d76174d1a 100644 --- a/src/pocketmine/scheduler/FileWriteTask.php +++ b/src/pocketmine/scheduler/FileWriteTask.php @@ -36,7 +36,7 @@ class FileWriteTask extends AsyncTask{ public function onRun(){ try{ file_put_contents($this->path, $this->contents, (int) $this->flags); - }catch (\Exception $e){ + }catch (\Throwable $e){ } } diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php index 632d0563a..911f9717a 100644 --- a/src/pocketmine/scheduler/SendUsageTask.php +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -143,7 +143,7 @@ class SendUsageTask extends AsyncTask{ "Content-Type: application/json", "Content-Length: ". strlen($this->data) ]); - }catch(\Exception $e){ + }catch(\Throwable $e){ } } diff --git a/src/pocketmine/scheduler/ServerScheduler.php b/src/pocketmine/scheduler/ServerScheduler.php index 4271f0f72..4c5503306 100644 --- a/src/pocketmine/scheduler/ServerScheduler.php +++ b/src/pocketmine/scheduler/ServerScheduler.php @@ -160,7 +160,9 @@ class ServerScheduler{ } $this->tasks = []; $this->asyncPool->removeTasks(); - $this->queue = new ReversePriorityQueue(); + while(!$this->queue->isEmpty()){ + $this->queue->extract(); + } $this->ids = 1; } @@ -245,7 +247,7 @@ class ServerScheduler{ $task->timings->startTiming(); try{ $task->run($this->currentTick); - }catch(\Exception $e){ + }catch(\Throwable $e){ Server::getInstance()->getLogger()->critical("Could not execute task " . $task->getTaskName() . ": " . $e->getMessage()); $logger = Server::getInstance()->getLogger(); if($logger instanceof MainLogger){ diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index 5de2ed481..dbcfb40c1 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -207,7 +207,7 @@ class Config{ }else{ file_put_contents($this->file, $content); } - }catch(\Exception $e){ + }catch(\Throwable $e){ $logger = Server::getInstance()->getLogger(); $logger->critical("Could not save Config " . $this->file . ": " . $e->getMessage()); if(\pocketmine\DEBUG > 1 and $logger instanceof MainLogger){ diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 94929f941..f40349544 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -101,7 +101,7 @@ class MainLogger extends \AttachableThreadedLogger{ $this->logDebug = (bool) $logDebug; } - public function logException(\Exception $e, $trace = null){ + public function logException(\Throwable $e, $trace = null){ if($trace === null){ $trace = $e->getTrace(); } diff --git a/src/raklib b/src/raklib index d7da0c554..11fc08675 160000 --- a/src/raklib +++ b/src/raklib @@ -1 +1 @@ -Subproject commit d7da0c5549215c7616a6fc103299afb0aeac88e7 +Subproject commit 11fc08675d301e73f1dbdec24029663a576de2c4 diff --git a/src/spl b/src/spl index d59c0f673..9c79e91a0 160000 --- a/src/spl +++ b/src/spl @@ -1 +1 @@ -Subproject commit d59c0f673455f02b2620853f3fa6290d63ffd960 +Subproject commit 9c79e91a03dffe64101660e959da2593264f1462 diff --git a/start.sh b/start.sh index b84f60d73..d4dcd8080 100755 --- a/start.sh +++ b/start.sh @@ -22,13 +22,13 @@ while getopts "p:f:l" OPTION 2> /dev/null; do done if [ "$PHP_BINARY" == "" ]; then - if [ -f ./bin/php5/bin/php ]; then + if [ -f ./bin/php7/bin/php ]; then export PHPRC="" - PHP_BINARY="./bin/php5/bin/php" + PHP_BINARY="./bin/php7/bin/php" elif [ type php 2>/dev/null ]; then PHP_BINARY=$(type -p php) else - echo "Couldn't find a working PHP binary, please use the installer." + echo "Couldn't find a working PHP 7 binary, please use the installer." exit 1 fi fi @@ -58,4 +58,4 @@ done if [ ${LOOPS} -gt 1 ]; then echo "Restarted $LOOPS times" -fi \ No newline at end of file +fi