diff --git a/README.md b/README.md index 4d376751cc..0f91b11423 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,8 @@ ## For developers * [Building and running from source](BUILDING.md) * [Developer documentation](https://devdoc.pmmp.io) - General documentation for PocketMine-MP plugin developers - * [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development + * [Latest release API documentation](https://apidoc.pmmp.io) - Doxygen API documentation generated for each release + * [Latest bleeding-edge API documentation](https://apidoc-dev.pmmp.io) - Doxygen API documentation generated weekly from `next-major` branch * [DevTools](https://github.com/pmmp/DevTools/) - Development tools plugin for creating plugins * [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features * [Contributing Guidelines](CONTRIBUTING.md) diff --git a/build/php b/build/php index 30eed13faa..d110b60bef 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 30eed13faaa8995814b1ada426b7e947f891ee3c +Subproject commit d110b60bef0cc98529909fda2f6aaa77963aad6a diff --git a/changelogs/4.2.md b/changelogs/4.2.md index 67008e792e..337a17943b 100644 --- a/changelogs/4.2.md +++ b/changelogs/4.2.md @@ -8,3 +8,14 @@ Plugin developers should **only** update their required API to this version if y # 4.2.0 - Added support for Minecraft: Bedrock Edition 1.18.10. + +# 4.2.1 +Released 19th February 2022. + +## General +- Improved performance of `Item::nbtSerialize()` - this will improve performance during world saves. +- Added more missing changes to the 4.0.0 changelog. + +## Fixes +- Fixed multiple players being able to sleep in the same bed. +- Fixed hitbox not resetting properly after swimming or gliding. diff --git a/composer.lock b/composer.lock index d2688559c5..9fd4c5cac9 100644 --- a/composer.lock +++ b/composer.lock @@ -1474,12 +1474,12 @@ }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1623,16 +1623,16 @@ }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { @@ -1668,9 +1668,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -2071,16 +2071,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.10", + "version": "9.2.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" + "reference": "deac8540cb7bd40b2b8cfa679b76202834fd04e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/deac8540cb7bd40b2b8cfa679b76202834fd04e8", + "reference": "deac8540cb7bd40b2b8cfa679b76202834fd04e8", "shasum": "" }, "require": { @@ -2136,7 +2136,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.13" }, "funding": [ { @@ -2144,7 +2144,7 @@ "type": "github" } ], - "time": "2021-12-05T09:12:13+00:00" + "time": "2022-02-23T17:02:38+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2389,16 +2389,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.13", + "version": "9.5.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "597cb647654ede35e43b137926dfdfef0fb11743" + "reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", - "reference": "597cb647654ede35e43b137926dfdfef0fb11743", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5ff8c545a50226c569310a35f4fa89d79f1ddfdc", + "reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc", "shasum": "" }, "require": { @@ -2414,7 +2414,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -2449,11 +2449,11 @@ } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2476,7 +2476,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.16" }, "funding": [ { @@ -2488,7 +2488,7 @@ "type": "github" } ], - "time": "2022-01-24T07:33:35+00:00" + "time": "2022-02-23T17:10:58+00:00" }, { "name": "sebastian/cli-parser", @@ -2996,16 +2996,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { @@ -3048,7 +3048,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" }, "funding": [ { @@ -3056,7 +3056,7 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2022-02-14T08:28:10+00:00" }, { "name": "sebastian/lines-of-code", diff --git a/doxygen/doxygen.conf b/doxygen/doxygen.conf index c65220fb31..9899588833 100644 --- a/doxygen/doxygen.conf +++ b/doxygen/doxygen.conf @@ -1239,7 +1239,7 @@ HTML_COLORSTYLE_GAMMA = 80 # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that diff --git a/src/MemoryManager.php b/src/MemoryManager.php index b248533176..3a1ab365ac 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -508,8 +508,13 @@ class MemoryManager{ return "(error) ARRAY RECURSION LIMIT REACHED"; } $data = []; + $numeric = 0; foreach($from as $key => $value){ - $data[$key] = self::continueDump($value, $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); + $data[$numeric] = [ + "k" => self::continueDump($key, $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize), + "v" => self::continueDump($value, $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize), + ]; + $numeric++; } }elseif(is_string($from)){ $data = "(string) len(" . strlen($from) . ") " . substr(Utils::printable($from), 0, $maxStringSize); diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index e008c7fdab..a75b4d9f1b 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -148,18 +148,20 @@ class BrewingStand extends Spawnable implements Container, Nameable{ * @phpstan-return array */ private function getBrewableRecipes() : array{ - if($this->inventory->getItem(BrewingStandInventory::SLOT_INGREDIENT)->isNull()){ + $ingredient = $this->inventory->getItem(BrewingStandInventory::SLOT_INGREDIENT); + if($ingredient->isNull()){ return []; } $recipes = []; + $craftingManager = $this->position->getWorld()->getServer()->getCraftingManager(); foreach([BrewingStandInventory::SLOT_BOTTLE_LEFT, BrewingStandInventory::SLOT_BOTTLE_MIDDLE, BrewingStandInventory::SLOT_BOTTLE_RIGHT] as $slot){ $input = $this->inventory->getItem($slot); if($input->isNull()){ continue; } - if(($recipe = $this->position->getWorld()->getServer()->getCraftingManager()->matchBrewingRecipe($input, $this->inventory->getItem(BrewingStandInventory::SLOT_INGREDIENT))) !== null){ + if(($recipe = $craftingManager->matchBrewingRecipe($input, $ingredient)) !== null){ $recipes[$slot] = $recipe; } } diff --git a/src/command/defaults/DumpMemoryCommand.php b/src/command/defaults/DumpMemoryCommand.php index 0f57103046..6ce3d29670 100644 --- a/src/command/defaults/DumpMemoryCommand.php +++ b/src/command/defaults/DumpMemoryCommand.php @@ -44,7 +44,7 @@ class DumpMemoryCommand extends VanillaCommand{ return true; } - $sender->getServer()->getMemoryManager()->dumpServerMemory($args[0] ?? (Path::join($sender->getServer()->getDataPath(), "memory_dumps" . date("D_M_j-H.i.s-T_Y"))), 48, 80); + $sender->getServer()->getMemoryManager()->dumpServerMemory($args[0] ?? (Path::join($sender->getServer()->getDataPath(), "memory_dumps", date("D_M_j-H.i.s-T_Y"))), 48, 80); return true; } } diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index 1da30d2e98..baeecb5af5 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -49,7 +49,7 @@ class PlayerInventory extends SimpleInventory{ } public function isHotbarSlot(int $slot) : bool{ - return $slot >= 0 && $slot <= $this->getHotbarSize(); + return $slot >= 0 && $slot < $this->getHotbarSize(); } /** diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index e7e53b4d36..6cd8e50198 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -37,6 +37,7 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; +use pocketmine\network\mcpe\convert\TypeConversionException; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; @@ -50,7 +51,9 @@ use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; +use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; +use pocketmine\network\PacketHandlingException; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\ObjectSet; @@ -145,6 +148,24 @@ class InventoryManager{ } } + /** + * @param NetworkInventoryAction[] $networkInventoryActions + * @throws PacketHandlingException + */ + public function addPredictedSlotChanges(array $networkInventoryActions) : void{ + foreach($networkInventoryActions as $action){ + if($action->sourceType === NetworkInventoryAction::SOURCE_CONTAINER && isset($this->windowMap[$action->windowId])){ + //this won't cover stuff like crafting grid due to too much magic + try{ + $item = TypeConverter::getInstance()->netItemStackToCore($action->newItem->getItemStack()); + }catch(TypeConversionException $e){ + throw new PacketHandlingException($e->getMessage(), 0, $e); + } + $this->initiatedSlotChanges[$action->windowId][$action->inventorySlot] = $item; + } + } + } + public function onCurrentWindowChange(Inventory $inventory) : void{ $this->onCurrentWindowRemove(); $this->add($this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % self::RESERVED_WINDOW_ID_RANGE_START), $inventory); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index dc2a5e4683..f2e0eafb48 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -411,6 +411,7 @@ class InGamePacketHandler extends PacketHandler{ private function handleUseItemTransaction(UseItemTransactionData $data) : bool{ $this->player->selectHotbarSlot($data->getHotbarSlot()); + $this->inventoryManager->addPredictedSlotChanges($data->getActions()); switch($data->getActionType()){ case UseItemTransactionData::ACTION_CLICK_BLOCK: @@ -500,6 +501,7 @@ class InGamePacketHandler extends PacketHandler{ } $this->player->selectHotbarSlot($data->getHotbarSlot()); + $this->inventoryManager->addPredictedSlotChanges($data->getActions()); //TODO: use transactiondata for rollbacks here switch($data->getActionType()){ @@ -520,6 +522,7 @@ class InGamePacketHandler extends PacketHandler{ private function handleReleaseItemTransaction(ReleaseItemTransactionData $data) : bool{ $this->player->selectHotbarSlot($data->getHotbarSlot()); + $this->inventoryManager->addPredictedSlotChanges($data->getActions()); //TODO: use transactiondata for rollbacks here (resending entire inventory is very wasteful) switch($data->getActionType()){ diff --git a/src/utils/Internet.php b/src/utils/Internet.php index ff0c3ca219..42745b59a1 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -160,7 +160,7 @@ class Internet{ * * @param string[]|string $args * @param string[] $extraHeaders - * @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. + * @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occurred during the operation. * @phpstan-param string|array $args * @phpstan-param list $extraHeaders */ diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 32fde0439e..80184b9ec1 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -29,14 +29,12 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; use pocketmine\utils\Filesystem; use pocketmine\utils\Limits; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\generator\Flat; -use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; @@ -50,6 +48,12 @@ use function time; class BedrockWorldData extends BaseNbtWorldData{ public const CURRENT_STORAGE_VERSION = 8; + /** + * WARNING: In the future, this should be only as high as the newest world format currently supported. We don't + * actually support worlds from 1.18.10 yet, but due to an old stupid bug, all worlds created by PM will report this + * version. + */ + public const CURRENT_STORAGE_NETWORK_VERSION = 486; // 1.18.10 public const GENERATOR_LIMITED = 0; public const GENERATOR_INFINITE = 1; @@ -74,7 +78,7 @@ class BedrockWorldData extends BaseNbtWorldData{ ->setInt("Generator", $generatorType) ->setLong("LastPlayed", time()) ->setString("LevelName", $name) - ->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL) + ->setInt("NetworkVersion", self::CURRENT_STORAGE_NETWORK_VERSION) //->setInt("Platform", 2) //TODO: find out what the possible values are for ->setLong("RandomSeed", $options->getSeed()) ->setInt("SpawnX", $options->getSpawnPosition()->getFloorX()) @@ -161,7 +165,7 @@ class BedrockWorldData extends BaseNbtWorldData{ } public function save() : void{ - $this->compoundTag->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL); + $this->compoundTag->setInt("NetworkVersion", self::CURRENT_STORAGE_NETWORK_VERSION); $this->compoundTag->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); $nbt = new LittleEndianNbtSerializer();