diff --git a/changelogs/4.2.md b/changelogs/4.2.md index 1aecd14a6..6451bfe88 100644 --- a/changelogs/4.2.md +++ b/changelogs/4.2.md @@ -79,3 +79,9 @@ Released 28th March 2022. ### Gameplay - Reduced the appearance of ghost items in unsupported gameplay scenarios using client prediction information. This fixes, for example, the appearance of ghost items when right-clicking on a filled flower pot. + +# 4.2.6 +Released 1st April 2022. + +## Fixes +- Fixed buffer length underflow crash in `LoginPacket` handling. diff --git a/composer.json b/composer.json index d1f46e049..8d28a7972 100644 --- a/composer.json +++ b/composer.json @@ -35,13 +35,13 @@ "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", "pocketmine/bedrock-data": "~1.6.0+bedrock-1.18.10", - "pocketmine/bedrock-protocol": "~8.0.0+bedrock-1.18.10", + "pocketmine/bedrock-protocol": "~8.0.2+bedrock-1.18.10", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.6.0", - "pocketmine/locale-data": "~2.4.2", + "pocketmine/locale-data": "~2.5.0", "pocketmine/log": "^0.4.0", "pocketmine/log-pthreads": "^0.4.0", "pocketmine/math": "^0.4.0", @@ -53,7 +53,7 @@ "webmozart/path-util": "^2.3" }, "require-dev": { - "phpstan/phpstan": "1.5.1", + "phpstan/phpstan": "1.5.4", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index 4a89b9421..3f87cee4f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fca583271e9a38b30ef924da651f7a20", + "content-hash": "afc47e972ac67ed1e1ab564a63171fa6", "packages": [ { "name": "adhocore/json-comment", @@ -275,16 +275,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "8.0.1+bedrock-1.18.10", + "version": "8.0.2+bedrock-1.18.10", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "a740f6095b35278c0e0dac6db84a5e4d2456b113" + "reference": "d1f1afdbb4ea61ea52eb511a79ee1ca561da349c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/a740f6095b35278c0e0dac6db84a5e4d2456b113", - "reference": "a740f6095b35278c0e0dac6db84a5e4d2456b113", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/d1f1afdbb4ea61ea52eb511a79ee1ca561da349c", + "reference": "d1f1afdbb4ea61ea52eb511a79ee1ca561da349c", "shasum": "" }, "require": { @@ -298,7 +298,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.4.5", + "phpstan/phpstan": "1.5.3", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5" @@ -316,9 +316,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/8.0.1+bedrock-1.18.10" + "source": "https://github.com/pmmp/BedrockProtocol/tree/8.0.2+bedrock-1.18.10" }, - "time": "2022-02-21T03:31:48+00:00" + "time": "2022-04-01T21:55:10+00:00" }, { "name": "pocketmine/binaryutils", @@ -536,16 +536,16 @@ }, { "name": "pocketmine/locale-data", - "version": "2.4.3", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "4d0b081f1a79407e087968ea76aaf330db6ea2b5" + "reference": "df6fc7f2b48850b306c60466a11f7a27bb8fe1de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/4d0b081f1a79407e087968ea76aaf330db6ea2b5", - "reference": "4d0b081f1a79407e087968ea76aaf330db6ea2b5", + "url": "https://api.github.com/repos/pmmp/Language/zipball/df6fc7f2b48850b306c60466a11f7a27bb8fe1de", + "reference": "df6fc7f2b48850b306c60466a11f7a27bb8fe1de", "shasum": "" }, "type": "library", @@ -553,9 +553,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/2.4.3" + "source": "https://github.com/pmmp/Language/tree/2.5.0" }, - "time": "2022-01-25T23:18:24+00:00" + "time": "2022-04-01T22:36:58+00:00" }, { "name": "pocketmine/log", @@ -930,25 +930,24 @@ }, { "name": "ramsey/uuid", - "version": "4.2.3", + "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8505afd4fea63b81a85d3b7b53ac3cb8dc347c28", + "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28", "shasum": "" }, "require": { "brick/math": "^0.8 || ^0.9", + "ext-ctype": "*", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -985,9 +984,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -1012,7 +1008,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.3.1" }, "funding": [ { @@ -1024,7 +1020,7 @@ "type": "tidelift" } ], - "time": "2021-09-25T23:10:38+00:00" + "time": "2022-03-27T21:42:02+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1108,89 +1104,6 @@ ], "time": "2021-10-20T20:35:02+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-03-04T08:16:47+00:00" - }, { "name": "symfony/polyfill-php81", "version": "v1.25.0", @@ -1789,16 +1702,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" + "reference": "77a32518733312af16a44300404e945338981de3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", "shasum": "" }, "require": { @@ -1833,9 +1746,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" }, - "time": "2022-01-04T19:58:01+00:00" + "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpspec/prophecy", @@ -1906,16 +1819,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.5.1", + "version": "1.5.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "cc67578d9afd0f5f2545067285613d7a529aefac" + "reference": "bbf68cae24f6dc023c607ea0f87da55dd9d55c2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cc67578d9afd0f5f2545067285613d7a529aefac", - "reference": "cc67578d9afd0f5f2545067285613d7a529aefac", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bbf68cae24f6dc023c607ea0f87da55dd9d55c2b", + "reference": "bbf68cae24f6dc023c607ea0f87da55dd9d55c2b", "shasum": "" }, "require": { @@ -1941,7 +1854,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.5.1" + "source": "https://github.com/phpstan/phpstan/tree/1.5.4" }, "funding": [ { @@ -1961,7 +1874,7 @@ "type": "tidelift" } ], - "time": "2022-03-28T15:34:48+00:00" + "time": "2022-04-03T12:39:00+00:00" }, { "name": "phpstan/phpstan-phpunit", @@ -2386,16 +2299,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.19", + "version": "9.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "35ea4b7f3acabb26f4bb640f8c30866c401da807" + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/35ea4b7f3acabb26f4bb640f8c30866c401da807", - "reference": "35ea4b7f3acabb26f4bb640f8c30866c401da807", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", "shasum": "" }, "require": { @@ -2473,7 +2386,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" }, "funding": [ { @@ -2485,7 +2398,7 @@ "type": "github" } ], - "time": "2022-03-15T09:57:31+00:00" + "time": "2022-04-01T12:37:26+00:00" }, { "name": "sebastian/cli-parser", diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index 7d0a337a7..1b22c9e80 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -173,10 +173,31 @@ console: title-tick: true aliases: - #Examples: - #showtheversion: version + ##This section allows you to add, remove or remap command aliases. + ##A single alias can call one or more other commands (or aliases). + ##Aliases defined here will override any command aliases declared by plugins or PocketMine-MP itself. + + ##To remove an alias, set it to [], like so (note that prefixed aliases like "pocketmine:stop" will remain and can't + ##be removed): + #stop: [] + + ##Commands are not removed, only their aliases. You can still refer to a command using its full (prefixed) + ##name, even if all its aliases are overwritten. The full name is usually something like "pocketmine:commandname" or + ##"pluginname:commandname". + #abort: [pocketmine:stop] + + ##To add an alias, list the command(s) that it calls: + #showtheversion: [version] #savestop: [save-all, stop] + ##To invoke another command with arguments, use $1 to pass the first argument, $2 for the second etc: + #giveadmin: [op $1] ## `giveadmin alex` -> `op alex` + #kill: [suicide, say "I tried to kill $1"] ## `kill alex` -> `suicide` + `say "I tried to kill alex"` + #giverandom: [give $1 $2, say "Someone has just received a $2!"] ## `giverandom alex diamond` -> `give alex diamond` + `say "Someone has just received a diamond!"` + + ##To change an existing command alias and make it do something else: + #tp: [suicide] + worlds: #These settings will override the generator set in server.properties and allows loading multiple worlds #Example: diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 5ab1d6a45..1ca59df1d 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -768,17 +768,29 @@ abstract class Entity{ } protected function broadcastMovement(bool $teleport = false) : void{ - $this->server->broadcastPackets($this->hasSpawned, [MoveActorAbsolutePacket::create( - $this->id, - $this->getOffsetPosition($this->location), - $this->location->pitch, - $this->location->yaw, - $this->location->yaw, - ( - ($teleport ? MoveActorAbsolutePacket::FLAG_TELEPORT : 0) | - ($this->onGround ? MoveActorAbsolutePacket::FLAG_GROUND : 0) - ) - )]); + if($teleport){ + //TODO: HACK! workaround for https://github.com/pmmp/PocketMine-MP/issues/4394 + //this happens because MoveActor*Packet doesn't clear interpolation targets on the client, so the entity + //snaps to the teleport position, but then lerps back to the original position if a normal movement for the + //entity was recently broadcasted. This can be seen with players throwing ender pearls. + //TODO: remove this if the bug ever gets fixed (lol) + foreach($this->hasSpawned as $player){ + $this->despawnFrom($player); + $this->spawnTo($player); + } + }else{ + $this->server->broadcastPackets($this->hasSpawned, [MoveActorAbsolutePacket::create( + $this->id, + $this->getOffsetPosition($this->location), + $this->location->pitch, + $this->location->yaw, + $this->location->yaw, + ( + //TODO: if the above hack for #4394 gets removed, we should be setting FLAG_TELEPORT here + ($this->onGround ? MoveActorAbsolutePacket::FLAG_GROUND : 0) + ) + )]); + } } protected function broadcastMotion() : void{ diff --git a/src/event/player/PlayerPreLoginEvent.php b/src/event/player/PlayerPreLoginEvent.php index 66cf550d2..78be4746e 100644 --- a/src/event/player/PlayerPreLoginEvent.php +++ b/src/event/player/PlayerPreLoginEvent.php @@ -31,7 +31,7 @@ use function count; /** * Called when a player connects to the server, prior to authentication taking place. - * Cancelling this event will cause the player to be disconnected with the kick message set. + * Set a kick reason to cancel the event and disconnect the player with the kick message set. * * This event should be used to decide if the player may continue to login to the server. Do things like checking * bans, whitelisting, server-full etc here. diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index d3b262d79..f006f937b 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1829,6 +1829,10 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_mainClassAbstract() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_MAINCLASSABSTRACT, []); + } + public static function pocketmine_plugin_mainClassNotFound() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_MAINCLASSNOTFOUND, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 1e488e2b8..038049d0a 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -379,6 +379,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_PLUGIN_INVALIDMANIFEST = "pocketmine.plugin.invalidManifest"; public const POCKETMINE_PLUGIN_LOAD = "pocketmine.plugin.load"; public const POCKETMINE_PLUGIN_LOADERROR = "pocketmine.plugin.loadError"; + public const POCKETMINE_PLUGIN_MAINCLASSABSTRACT = "pocketmine.plugin.mainClassAbstract"; public const POCKETMINE_PLUGIN_MAINCLASSNOTFOUND = "pocketmine.plugin.mainClassNotFound"; public const POCKETMINE_PLUGIN_MAINCLASSWRONGTYPE = "pocketmine.plugin.mainClassWrongType"; public const POCKETMINE_PLUGIN_RESTRICTEDNAME = "pocketmine.plugin.restrictedName"; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 896ed7d00..fe40ab6e8 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -228,8 +228,10 @@ class InGamePacketHandler extends PacketHandler{ $this->player->jump(); } - //TODO: this packet has WAYYYYY more useful information that we're not using - $this->player->handleMovement($newPos); + if(!$this->forceMoveSync){ + //TODO: this packet has WAYYYYY more useful information that we're not using + $this->player->handleMovement($newPos); + } $packetHandled = true; @@ -457,13 +459,10 @@ class InGamePacketHandler extends PacketHandler{ if(!$this->player->consumeHeldItem()){ $hungerAttr = $this->player->getAttributeMap()->get(Attribute::HUNGER) ?? throw new AssumptionFailedError(); $hungerAttr->markSynchronized(false); - $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } - if(!$this->player->useHeldItem()){ - $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); - } + $this->player->useHeldItem(); return true; } @@ -483,7 +482,6 @@ class InGamePacketHandler extends PacketHandler{ * Internal function used to execute rollbacks when an action fails on a block. */ private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ - $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); if($blockPos->distanceSquared($this->player->getLocation()) < 10000){ $blocks = $blockPos->sidesArray(); if($face !== null){ @@ -512,14 +510,10 @@ class InGamePacketHandler extends PacketHandler{ //TODO: use transactiondata for rollbacks here switch($data->getActionType()){ case UseItemOnEntityTransactionData::ACTION_INTERACT: - if(!$this->player->interactEntity($target, $data->getClickPosition())){ - $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); - } + $this->player->interactEntity($target, $data->getClickPosition()); return true; case UseItemOnEntityTransactionData::ACTION_ATTACK: - if(!$this->player->attackEntity($target)){ - $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); - } + $this->player->attackEntity($target); return true; } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index c6db43a85..5cb4e4637 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -166,6 +166,14 @@ class PluginManager{ ))); return null; } + $reflect = new \ReflectionClass($mainClass); //this shouldn't throw; we already checked that it exists + if(!$reflect->isInstantiable()){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassAbstract() + ))); + return null; + } $permManager = PermissionManager::getInstance(); foreach($description->getPermissions() as $permsGroup){ @@ -463,8 +471,12 @@ class PluginManager{ } public function tickSchedulers(int $currentTick) : void{ - foreach($this->enabledPlugins as $p){ - $p->getScheduler()->mainThreadHeartbeat($currentTick); + foreach($this->enabledPlugins as $pluginName => $p){ + if(isset($this->enabledPlugins[$pluginName])){ + //the plugin may have been disabled as a result of updating other plugins' schedulers, and therefore + //removed from enabledPlugins; however, foreach will still see it due to copy-on-write + $p->getScheduler()->mainThreadHeartbeat($currentTick); + } } } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 5233cf18d..4ade6cecd 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -85,3 +85,8 @@ parameters: count: 2 path: ../../../src/world/format/io/region/RegionLoader.php + - + message: "#^Negated boolean expression is always true\\.$#" + count: 1 + path: ../../../src/network/mcpe/handler/InGamePacketHandler.php +