From 16c253d7a9baa0f32065875f56337f9c3ef6e976 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Jul 2018 12:46:16 +0100 Subject: [PATCH 1/4] Item: allow negative IDs this will be needed in the future for extended blocks support. --- src/pocketmine/item/Item.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 6f33ba580..6769ddf77 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -196,7 +196,10 @@ class Item implements ItemIds, \JsonSerializable{ * @param string $name */ public function __construct(int $id, int $meta = 0, string $name = "Unknown"){ - $this->id = $id & 0xffff; + if($id < -0x8000 or $id > 0x7fff){ //signed short range + throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); + } + $this->id = $id; $this->setDamage($meta); $this->name = $name; } @@ -916,7 +919,7 @@ class Item implements ItemIds, \JsonSerializable{ */ public function nbtSerialize(int $slot = -1, string $tagName = "") : CompoundTag{ $result = new CompoundTag($tagName, [ - new ShortTag("id", Binary::signShort($this->id)), + new ShortTag("id", $this->id), new ByteTag("Count", Binary::signByte($this->count)), new ShortTag("Damage", $this->meta) ]); @@ -951,7 +954,7 @@ class Item implements ItemIds, \JsonSerializable{ $idTag = $tag->getTag("id"); if($idTag instanceof ShortTag){ - $item = ItemFactory::get(Binary::unsignShort($idTag->getValue()), $meta, $count); + $item = ItemFactory::get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format $item = ItemFactory::fromString($idTag->getValue()); $item->setDamage($meta); From 71c3c349766e348bf53a1beeefaf9a897bc0a954 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Jul 2018 13:24:12 +0100 Subject: [PATCH 2/4] ItemFactory: prepare for handling items with negative IDs --- src/pocketmine/item/ItemFactory.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index a1922b94b..e87dde253 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -281,7 +281,7 @@ class ItemFactory{ throw new \RuntimeException("Trying to overwrite an already registered item"); } - self::$list[$id] = clone $item; + self::$list[self::getListOffset($id)] = clone $item; } /** @@ -302,10 +302,10 @@ class ItemFactory{ try{ /** @var Item|null $listed */ - $listed = self::$list[$id]; + $listed = self::$list[self::getListOffset($id)]; if($listed !== null){ $item = clone $listed; - }elseif($id < 256){ + }elseif($id < 256){ //intentionally includes negatives, for extended block IDs /* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are * crafting ingredients with any-damage. */ $item = new ItemBlock($id, $meta); @@ -353,13 +353,13 @@ class ItemFactory{ if(!isset($b[1])){ $meta = 0; }elseif(is_numeric($b[1])){ - $meta = $b[1] & 0xFFFF; + $meta = $b[1]; }else{ throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $str . "\" as a valid meta value"); } if(is_numeric($b[0])){ - $item = self::get(((int) $b[0]) & 0xFFFF, $meta); + $item = self::get((int) $b[0], $meta); }elseif(defined(ItemIds::class . "::" . strtoupper($b[0]))){ $item = self::get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); }else{ @@ -380,6 +380,13 @@ class ItemFactory{ if($id < 256){ return BlockFactory::isRegistered($id); } - return self::$list[$id] !== null; + return self::$list[self::getListOffset($id)] !== null; + } + + private static function getListOffset(int $id) : int{ + if($id < -0x8000 or $id > 0x7fff){ + throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); + } + return $id & 0xffff; } } From 921f7e8f6a78a1ef1b7659372841505160c8bb67 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Jul 2018 17:36:36 +0100 Subject: [PATCH 3/4] Level: remove useless check from populateChunk() this is already checked at the top of the function. --- src/pocketmine/level/Level.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d2aa56205..f7f9c2a0e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2947,16 +2947,14 @@ class Level implements ChunkManager, Metadatable{ } if($populate){ - if(!isset($this->chunkPopulationQueue[$index])){ - $this->chunkPopulationQueue[$index] = true; - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - $this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true; - } + $this->chunkPopulationQueue[$index] = true; + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + $this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true; } - $task = new PopulationTask($this, $chunk); - $this->server->getAsyncPool()->submitTask($task); } + $task = new PopulationTask($this, $chunk); + $this->server->getAsyncPool()->submitTask($task); } Timings::$populationTimer->stopTiming(); From b4bf6901e363308f41d0b7d6e1e4b621b04d0a38 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 17 Jul 2018 10:10:28 +0100 Subject: [PATCH 4/4] Server: remove useless try/catch around Query event firing this doesn't raise any exceptions, and if it causes Errors to be thrown, those are defects that should be fixed. A catch-all is a bad thing. --- src/pocketmine/Server.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d56cdcf7c..5bb50e38e 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2528,13 +2528,9 @@ class Server{ } if(($this->tickCounter & 0b111111111) === 0){ - try{ - $this->getPluginManager()->callEvent($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5)); - if($this->queryHandler !== null){ - $this->queryHandler->regenerateInfo(); - } - }catch(\Throwable $e){ - $this->logger->logException($e); + $this->getPluginManager()->callEvent($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5)); + if($this->queryHandler !== null){ + $this->queryHandler->regenerateInfo(); } }