diff --git a/.travis.yml b/.travis.yml index 7590cb540..4196f2c2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,9 @@ php: before_script: # - pecl install channel://pecl.php.net/pthreads-3.1.6 - echo | pecl install channel://pecl.php.net/yaml-2.0.2 - - git clone https://github.com/krakjoe/pthreads.git + - git clone https://github.com/pmmp/pthreads.git - cd pthreads - - git checkout d32079fb4a88e6e008104d36dbbf0c2dd7deb403 + - git checkout c8cfacda84f21032d6014b53e72bf345ac901dac - phpize - ./configure - make diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e9372b2d4..4436ac534 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2168,7 +2168,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return false; } - $this->resetCraftingGridType(); + $this->doCloseInventory(); $message = TextFormat::clean($message, $this->removeFormat); foreach(explode("\n", $message) as $messagePart){ @@ -2243,7 +2243,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if(!$this->spawned or !$this->isAlive()){ return true; } - $this->resetCraftingGridType(); + $this->doCloseInventory(); switch($packet->event){ case EntityEventPacket::EATING_ITEM: @@ -2394,7 +2394,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; case InventoryTransactionPacket::USE_ITEM_ACTION_BREAK_BLOCK: - $this->resetCraftingGridType(); + $this->doCloseInventory(); $item = $this->inventory->getItemInHand(); $oldItem = clone $item; @@ -2635,7 +2635,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - $this->resetCraftingGridType(); + $this->doCloseInventory(); $target = $this->level->getEntity($packet->target); if($target === null){ @@ -2849,7 +2849,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - $this->resetCraftingGridType(); + $this->doCloseInventory(); if(isset($this->windowIndex[$packet->windowId])){ $this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$packet->windowId], $this)); @@ -2899,7 +2899,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if(!$this->spawned or !$this->isAlive()){ return true; } - $this->resetCraftingGridType(); + $this->doCloseInventory(); $pos = new Vector3($packet->x, $packet->y, $packet->z); if($pos->distanceSquared($this) > 10000 or $this->level->checkSpawnProtection($this, $pos)){ @@ -3617,7 +3617,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ //Crafting grid must always be evacuated even if keep-inventory is true. This dumps the contents into the //main inventory and drops the rest on the ground. - $this->resetCraftingGridType(); + $this->doCloseInventory(); $this->server->getPluginManager()->callEvent($ev = new PlayerDeathEvent($this, $this->getDrops(), new TranslationContainer($message, $params))); @@ -3800,15 +3800,19 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->craftingGrid = $grid; } - public function resetCraftingGridType() : void{ - $contents = $this->craftingGrid->getContents(); - if(count($contents) > 0){ - $drops = $this->inventory->addItem(...$contents); - foreach($drops as $drop){ - $this->dropItem($drop); - } + public function doCloseInventory() : void{ + /** @var Inventory[] $inventories */ + $inventories = [$this->craftingGrid, $this->cursorInventory]; + foreach($inventories as $inventory){ + $contents = $inventory->getContents(); + if(count($contents) > 0){ + $drops = $this->inventory->addItem(...$contents); + foreach($drops as $drop){ + $this->dropItem($drop); + } - $this->craftingGrid->clearAll(); + $inventory->clearAll(); + } } if($this->craftingGrid->getGridWidth() > CraftingGrid::SIZE_SMALL){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 94b4305f1..aa24df888 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2471,6 +2471,8 @@ class Server{ try{ if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){ $this->queryHandler->handle($interface, $address, $port, $payload); + }else{ + $this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload)); } }catch(\Throwable $e){ if(\pocketmine\DEBUG > 1){ diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 6101cde27..4774b4c58 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\Position; -use pocketmine\utils\MainLogger; /** * Manages block registration and instance creation @@ -436,19 +435,12 @@ class BlockFactory{ * @return int */ public static function toStaticRuntimeId(int $id, int $meta = 0) : int{ - if($id === Block::AIR){ - //TODO: HACK! (weird air blocks with non-zero damage values shouldn't turn into update! blocks) - $meta = 0; - } - - $index = ($id << 4) | $meta; - if(!isset(self::$staticRuntimeIdMap[$index])){ - self::registerMapping($rtId = ++self::$lastRuntimeId, $id, $meta); - MainLogger::getLogger()->error("ID $id meta $meta does not have a corresponding block static runtime ID, added a new unknown runtime ID ($rtId)"); - return $rtId; - } - - return self::$staticRuntimeIdMap[$index]; + /* + * try id+meta first + * if not found, try id+0 (strip meta) + * if still not found, return update! block + */ + return self::$staticRuntimeIdMap[($id << 4) | $meta] ?? self::$staticRuntimeIdMap[$id << 4] ?? self::$staticRuntimeIdMap[BlockIds::INFO_UPDATE << 4]; } /** diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 2f7a6370c..2ce84145d 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -66,7 +66,7 @@ class ConcretePowder extends Fallable{ private function checkAdjacentWater() : ?Block{ for($i = 1; $i < 6; ++$i){ //Do not check underneath if($this->getSide($i) instanceof Water){ - return Block::get(Block::CONCRETE, $this->meta); + return BlockFactory::get(Block::CONCRETE, $this->meta); } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 2489fd186..2fb7c1bf1 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -169,7 +169,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public const DATA_LIMITED_LIFE = 77; public const DATA_ARMOR_STAND_POSE_INDEX = 78; //int public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 79; //int - /* 80 (byte) something to do with nametag visibility? */ + public const DATA_ALWAYS_SHOW_NAMETAG = 80; //byte: -1 = default, 0 = only when looked at, 1 = always public const DATA_COLOR_2 = 81; //byte /* 82 (unknown) */ public const DATA_SCORE_TAG = 83; //string @@ -606,7 +606,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param bool $value */ public function setNameTagAlwaysVisible(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_ALWAYS_SHOW_NAMETAG, $value); + $this->propertyManager->setByte(self::DATA_ALWAYS_SHOW_NAMETAG, $value ? 1 : 0); } /** diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index b8a6fc9e2..d2aa56205 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1627,7 +1627,7 @@ class Level implements ChunkManager, Metadatable{ $spawnLocation = $this->getSpawnLocation(); $s = new Vector2($spawnLocation->x, $spawnLocation->z); - if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ + if($t->distance($s) <= $distance){ return true; } } @@ -2791,7 +2791,7 @@ class Level implements ChunkManager, Metadatable{ $chunk = $this->getChunk($v->x >> 4, $v->z >> 4, false); $x = (int) $v->x; $z = (int) $v->z; - if($chunk !== null){ + if($chunk !== null and $chunk->isGenerated()){ $y = (int) min($max - 2, $v->y); $wasAir = ($chunk->getBlockId($x & 0x0f, $y - 1, $z & 0x0f) === 0); for(; $y > 0; --$y){ diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 7c6770097..2a34cddb2 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -58,6 +58,11 @@ class QueryHandler{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); } + private function debug(string $message) : void{ + //TODO: replace this with a proper prefixed logger + $this->server->getLogger()->debug("[Query] $message"); + } + public function regenerateInfo(){ $ev = $this->server->getQueryInformation(); $this->longData = $ev->getLongQuery(); @@ -91,7 +96,8 @@ class QueryHandler{ break; case self::STATISTICS: //Stat $token = Binary::readInt(substr($payload, 0, 4)); - if($token !== self::getTokenString($this->token, $address) and $token !== self::getTokenString($this->lastToken, $address)){ + if($token !== ($t1 = self::getTokenString($this->token, $address)) and $token !== ($t2 = self::getTokenString($this->lastToken, $address))){ + $this->debug("Bad token $token from $address $port, expected $t1 or $t2"); break; } $reply = chr(self::STATISTICS); @@ -108,6 +114,9 @@ class QueryHandler{ } $interface->sendRawPacket($address, $port, $reply); break; + default: + $this->debug("Unhandled packet from $address $port: 0x" . bin2hex($packet)); + break; } } }