Merge branch 'minor-next' into major-next

This commit is contained in:
Dylan K. Taylor 2023-04-05 20:14:59 +01:00
commit 7e1467f3f7
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
9 changed files with 69 additions and 49 deletions

View File

@ -97,3 +97,15 @@ Released 29th March 2023.
## Fixes ## Fixes
- Fixed players being unable to join due to the appearance of a new `x5t` field in the JWT header of Xbox Live authentication tokens. - Fixed players being unable to join due to the appearance of a new `x5t` field in the JWT header of Xbox Live authentication tokens.
- Fixed items' durability appearing to reset when moving them around in the inventory. - Fixed items' durability appearing to reset when moving them around in the inventory.
# 4.18.3
Released 5th April 2023.
## Fixes
- Fixed Average Players not being shown on timings reports when custom player classes are used.
- Fixed incorrect tick violation calculation in timings reports.
- Fixed not being able to add or remove items from the offhand slot.
- Fixed creative inventory item count corruption when taking items (some players would see 64x items in the creative inventory after rejoining or changing gamemode).
- Fixed not being able to drop items directly from the creative inventory on mobile.
- Fixed `DataPacketReceiveEvent` not being called for packets sent by `EntityEventBroadcaster`.
- `CreativeInventory::getItem()` and `CreativeInventory::getAll()` now return cloned itemstacks, to prevent accidental modification of the creative inventory.

View File

@ -55,7 +55,7 @@
"symfony/filesystem": "^5.4" "symfony/filesystem": "^5.4"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "1.10.7", "phpstan/phpstan": "1.10.11",
"phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0", "phpstan/phpstan-strict-rules": "^1.2.0",
"phpunit/phpunit": "^9.2" "phpunit/phpunit": "^9.2"

37
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c7ae719a20240005f7c174bedbd67791", "content-hash": "438d391135646f845eed034c362dffe3",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -1775,16 +1775,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.10.7", "version": "1.10.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "b10ceb526d9607903c5b2673f1fc8775dbe48975" "reference": "8aa62e6ea8b58ffb650e02940e55a788cbc3fe21"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/b10ceb526d9607903c5b2673f1fc8775dbe48975", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8aa62e6ea8b58ffb650e02940e55a788cbc3fe21",
"reference": "b10ceb526d9607903c5b2673f1fc8775dbe48975", "reference": "8aa62e6ea8b58ffb650e02940e55a788cbc3fe21",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1833,7 +1833,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-03-16T15:24:20+00:00" "time": "2023-04-04T19:17:42+00:00"
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",
@ -1889,16 +1889,16 @@
}, },
{ {
"name": "phpstan/phpstan-strict-rules", "name": "phpstan/phpstan-strict-rules",
"version": "1.5.0", "version": "1.5.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git", "url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "b7dd96a5503919a43b3cd06a2dced9d4252492f2" "reference": "b21c03d4f6f3a446e4311155f4be9d65048218e6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/b7dd96a5503919a43b3cd06a2dced9d4252492f2", "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/b21c03d4f6f3a446e4311155f4be9d65048218e6",
"reference": "b7dd96a5503919a43b3cd06a2dced9d4252492f2", "reference": "b21c03d4f6f3a446e4311155f4be9d65048218e6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1932,9 +1932,9 @@
"description": "Extra strict and opinionated rules for PHPStan", "description": "Extra strict and opinionated rules for PHPStan",
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues", "issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.0" "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.1"
}, },
"time": "2023-02-21T10:17:10+00:00" "time": "2023-03-29T14:47:40+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@ -2256,16 +2256,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "9.6.5", "version": "9.6.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5" "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86e761949019ae83f49240b2f2123fb5ab3b2fc5", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115",
"reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5", "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2338,7 +2338,8 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.5" "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6"
}, },
"funding": [ "funding": [
{ {
@ -2354,7 +2355,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-03-09T06:34:10+00:00" "time": "2023-03-27T11:43:46+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",

View File

@ -28,6 +28,7 @@ use pocketmine\crafting\json\ItemStackData;
use pocketmine\data\bedrock\BedrockDataFiles; use pocketmine\data\bedrock\BedrockDataFiles;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\utils\SingletonTrait; use pocketmine\utils\SingletonTrait;
use pocketmine\utils\Utils;
final class CreativeInventory{ final class CreativeInventory{
use SingletonTrait; use SingletonTrait;
@ -62,11 +63,11 @@ final class CreativeInventory{
* @return Item[] * @return Item[]
*/ */
public function getAll() : array{ public function getAll() : array{
return $this->creative; return Utils::cloneObjectArray($this->creative);
} }
public function getItem(int $index) : ?Item{ public function getItem(int $index) : ?Item{
return $this->creative[$index] ?? null; return isset($this->creative[$index]) ? clone $this->creative[$index] : null;
} }
public function getItemIndex(Item $item) : int{ public function getItemIndex(Item $item) : int{

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe; namespace pocketmine\network\mcpe;
use pocketmine\event\server\DataPacketSendEvent;
use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\timings\Timings; use pocketmine\timings\Timings;
@ -57,14 +56,6 @@ final class NetworkBroadcastUtils{
return false; return false;
} }
$ev = new DataPacketSendEvent($sessions, $packets);
$ev->call();
if($ev->isCancelled()){
return false;
}
$sessions = $ev->getTargets();
$packets = $ev->getPackets();
/** @var PacketBroadcaster[] $uniqueBroadcasters */ /** @var PacketBroadcaster[] $uniqueBroadcasters */
$uniqueBroadcasters = []; $uniqueBroadcasters = [];
/** @var NetworkSession[][] $broadcasterTargets */ /** @var NetworkSession[][] $broadcasterTargets */

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe; namespace pocketmine\network\mcpe;
use pocketmine\event\server\DataPacketSendEvent;
use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
@ -41,6 +42,15 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{
){} ){}
public function broadcastPackets(array $recipients, array $packets) : void{ public function broadcastPackets(array $recipients, array $packets) : void{
//TODO: this shouldn't really be called here, since the broadcaster might be replaced by an alternative
//implementation that doesn't fire events
$ev = new DataPacketSendEvent($recipients, $packets);
$ev->call();
if($ev->isCancelled()){
return;
}
$packets = $ev->getPackets();
$compressors = []; $compressors = [];
/** @var NetworkSession[][] $targetsByCompressor */ /** @var NetworkSession[][] $targetsByCompressor */

View File

@ -147,6 +147,11 @@ class ItemStackRequestExecutor{
* @throws ItemStackRequestProcessException * @throws ItemStackRequestProcessException
*/ */
protected function removeItemFromSlot(ItemStackRequestSlotInfo $slotInfo, int $count) : Item{ protected function removeItemFromSlot(ItemStackRequestSlotInfo $slotInfo, int $count) : Item{
if($slotInfo->getContainerId() === ContainerUIIds::CREATED_OUTPUT && $slotInfo->getSlotId() === UIInventorySlotOffset::CREATED_ITEM_OUTPUT){
//special case for the "created item" output slot
//TODO: do we need to send a response for this slot info?
return $this->takeCreatedItem($count);
}
$this->requestSlotInfos[] = $slotInfo; $this->requestSlotInfos[] = $slotInfo;
[$inventory, $slot] = $this->getBuilderInventoryAndSlot($slotInfo); [$inventory, $slot] = $this->getBuilderInventoryAndSlot($slotInfo);
if($count < 1){ if($count < 1){
@ -188,6 +193,13 @@ class ItemStackRequestExecutor{
$inventory->setItem($slot, $newItem); $inventory->setItem($slot, $newItem);
} }
protected function dropItem(Item $item, int $count) : void{
if($count < 1){
throw new ItemStackRequestProcessException("Cannot drop less than 1 of an item");
}
$this->builder->addAction(new DropItemAction((clone $item)->setCount($count)));
}
/** /**
* @throws ItemStackRequestProcessException * @throws ItemStackRequestProcessException
*/ */
@ -254,7 +266,7 @@ class ItemStackRequestExecutor{
/** /**
* @throws ItemStackRequestProcessException * @throws ItemStackRequestProcessException
*/ */
protected function takeCreatedItem(ItemStackRequestSlotInfo $destination, int $count) : void{ protected function takeCreatedItem(int $count) : Item{
if($count < 1){ if($count < 1){
//this should be impossible at the protocol level, but in case of buggy core code this will prevent exploits //this should be impossible at the protocol level, but in case of buggy core code this will prevent exploits
throw new ItemStackRequestProcessException("Cannot take less than 1 created item"); throw new ItemStackRequestProcessException("Cannot take less than 1 created item");
@ -272,10 +284,12 @@ class ItemStackRequestExecutor{
} }
$this->createdItemsTakenCount += $count; $this->createdItemsTakenCount += $count;
$this->addItemToSlot($destination, $createdItem, $count); $createdItem = clone $createdItem;
$createdItem->setCount($count);
if(!$this->createdItemFromCreativeInventory && $this->createdItemsTakenCount >= $createdItem->getCount()){ if(!$this->createdItemFromCreativeInventory && $this->createdItemsTakenCount >= $createdItem->getCount()){
$this->setNextCreatedItem(null); $this->setNextCreatedItem(null);
} }
return $createdItem;
} }
/** /**
@ -299,14 +313,7 @@ class ItemStackRequestExecutor{
$action instanceof TakeStackRequestAction || $action instanceof TakeStackRequestAction ||
$action instanceof PlaceStackRequestAction $action instanceof PlaceStackRequestAction
){ ){
$source = $action->getSource(); $this->transferItems($action->getSource(), $action->getDestination(), $action->getCount());
$destination = $action->getDestination();
if($source->getContainerId() === ContainerUIIds::CREATED_OUTPUT && $source->getSlotId() === UIInventorySlotOffset::CREATED_ITEM_OUTPUT){
$this->takeCreatedItem($destination, $action->getCount());
}else{
$this->transferItems($source, $destination, $action->getCount());
}
}elseif($action instanceof SwapStackRequestAction){ }elseif($action instanceof SwapStackRequestAction){
$this->requestSlotInfos[] = $action->getSlot1(); $this->requestSlotInfos[] = $action->getSlot1();
$this->requestSlotInfos[] = $action->getSlot2(); $this->requestSlotInfos[] = $action->getSlot2();

View File

@ -63,10 +63,7 @@ use function realpath;
use function shuffle; use function shuffle;
use function sprintf; use function sprintf;
use function str_contains; use function str_contains;
use function str_starts_with;
use function strlen;
use function strtolower; use function strtolower;
use function substr;
/** /**
* Manages all the plugins * Manages all the plugins
@ -654,11 +651,6 @@ class PluginManager{
throw new PluginException("Plugin attempted to register event handler " . $handlerName . "() to event " . $event . " while not enabled"); throw new PluginException("Plugin attempted to register event handler " . $handlerName . "() to event " . $event . " while not enabled");
} }
$prefix = $plugin->getDescription()->getSrcNamespacePrefix();
if(str_starts_with($handlerName, $prefix) && $prefix !== ""){
$handlerName = substr($handlerName, strlen($prefix) + 1);
}
$timings = new TimingsHandler($handlerName . "(" . (new \ReflectionClass($event))->getShortName() . ")", group: $plugin->getDescription()->getFullName()); $timings = new TimingsHandler($handlerName . "(" . (new \ReflectionClass($event))->getShortName() . ")", group: $plugin->getDescription()->getFullName());
$registeredListener = new RegisteredListener($handler, $priority, $plugin, $handleCancelled, $timings); $registeredListener = new RegisteredListener($handler, $priority, $plugin, $handleCancelled, $timings);

View File

@ -31,6 +31,7 @@ use pocketmine\network\mcpe\protocol\ServerboundPacket;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\scheduler\TaskHandler; use pocketmine\scheduler\TaskHandler;
use function get_class; use function get_class;
use function str_starts_with;
abstract class Timings{ abstract class Timings{
public const INCLUDED_BY_OTHER_TIMINGS_PREFIX = "** "; public const INCLUDED_BY_OTHER_TIMINGS_PREFIX = "** ";
@ -279,7 +280,12 @@ abstract class Timings{
public static function getEventTimings(Event $event) : TimingsHandler{ public static function getEventTimings(Event $event) : TimingsHandler{
$eventClass = get_class($event); $eventClass = get_class($event);
if(!isset(self::$events[$eventClass])){ if(!isset(self::$events[$eventClass])){
self::$events[$eventClass] = new TimingsHandler($eventClass, group: "Events"); if(str_starts_with($eventClass, "pocketmine\\event\\")){
$name = (new \ReflectionClass($event))->getShortName();
}else{
$name = $eventClass;
}
self::$events[$eventClass] = new TimingsHandler($name, group: "Events");
} }
return self::$events[$eventClass]; return self::$events[$eventClass];