Compare commits

...

30 Commits

Author SHA1 Message Date
49a9da147b Release 4.23.4 2023-08-01 11:12:41 +01:00
eb53b795d5 ItemEntity: fixed O(n^2) performance issue when many of the same unstackable item are in the same place
this produced a 40% performance improvement in a simulation with 800 item entities.

If the items were all different, then this would still be a problem. However, many of the same unstackable items occupying the same space is a problem for SkyBlock farms, so this should improve performance for SkyBlock quite a bit.
2023-07-31 11:29:12 +01:00
1c611a03e6 4.23.4 is next 2023-07-24 16:59:48 +01:00
948875b025 Release 4.23.3 2023-07-24 16:59:45 +01:00
2a4909d328 Fixed missing handling for some ContainerUIIds
SMITHING_TABLE_TEMPLATE is new in 1.20
HORSE_EQUIP was always present, but somehow got overlooked when building up that big ugly switch table
2023-07-24 16:44:01 +01:00
70dd8732e2 Update build/php to pmmp/PHP-Binaries@46604f2f6a 2023-07-24 11:59:11 +01:00
cdf72563f4 Update composer dependencies 2023-07-24 11:58:50 +01:00
d65d8c3356 Fix typo in documentation of ChunkSelector:selectChunks() (#5924) 2023-07-21 10:34:34 +01:00
9b43ddecbd Drop usages of Process:kill() with subprocesses parameter
we don't need this any more with console reader improvements, and this was not working correctly anyway.

closes #5234
2023-07-20 17:10:39 +01:00
4bdd6410db Fire: fixed support requirements
closes #5599
2023-07-20 17:00:32 +01:00
6ea7fd7d6b ShulkerBox: do not offer support for other blocks 2023-07-20 16:36:25 +01:00
5e7f18cbcf StandardEntityEventBroadcaster: suppress client-side emote messages
if users want these, they can broadcast them themselves using Server::broadcastMessage(), which will also record the message in the server log like chat

closes #5669
2023-07-20 16:20:34 +01:00
cff4a8d2bc 4.23.3 is next 2023-07-18 22:14:24 +01:00
20b7e8d702 Release 4.23.2 2023-07-18 22:14:23 +01:00
c6110be051 Update BedrockProtocol dependency 2023-07-18 22:12:33 +01:00
86bd6777a3 4.23.2 is next 2023-07-14 13:06:26 +01:00
935df62006 Release 4.23.1 2023-07-14 13:06:26 +01:00
2709dd359c ProcessLoginTask: fixed backport errors 2023-07-14 12:37:50 +01:00
4e646d19a4 Harden login EC key validation 2023-07-14 11:55:47 +01:00
2a11762e61 Update JsonMapper dependency 2023-07-14 11:54:05 +01:00
7e0b5cf73d 4.23.1 is next 2023-07-12 13:44:16 +01:00
e903da8998 Release 4.23.0 2023-07-12 13:44:16 +01:00
f2193d1ba7 1.20.10 2023-07-12 13:23:47 +01:00
f7977c9668 Update build/php submodule to pmmp/PHP-Binaries@16378ffcc3 2023-07-12 12:10:09 +01:00
cfd9950b02 4.22.4 is next 2023-07-11 16:01:42 +01:00
8ebcdb452d Release 4.22.3 2023-07-11 16:01:38 +01:00
aacc00a911 update-updater-api: do not allow multiple jobs to run simultaneously
this would result in git conflicts if multiple releases are made at the same time

closes #5814
2023-07-11 15:10:35 +01:00
0c250a2ef0 InGamePacketHandler: fixed inconsistent handling of invalid data in BlockActorDataPacket 2023-07-11 12:53:29 +01:00
70dd9c7371 AsyncTask: fixed reentrancy bug tested by f8e6f036af 2023-07-01 13:27:32 +01:00
f8e6f036af AsyncPoolTest: added failing test case for AsyncTask::__destruct() reentrancy bug 2023-07-01 13:24:50 +01:00
25 changed files with 251 additions and 89 deletions

View File

@ -8,6 +8,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
concurrency: update-updater-api # only one job can run at a time, to avoid git conflicts when updating the repository
steps:
- name: Install jq

View File

@ -46,3 +46,13 @@ Released 1st July 2023.
- Due to the lack of a hard date for the key changeover, we guessed that July 1st would be a safe bet, but this appears to have backfired.
- This version will accept both old and new keys indefinitely.
- A security release will be published to remove the old key after the transition occurs.
# 4.22.3
Released 11th July 2023.
## Fixes
- Fixed mishandling of NBT leading to a server crash when editing signs.
- Fixed an edge case crash that could occur in `AsyncTask->__destruct()` when thread-local storage referenced other `AsyncTask` objects.
## Internals
- Added a concurrency lock to prevent the `update-updater-api` GitHub Action from running for multiple releases at the same time (which would have caused one of them to fail due to git conflicts).

51
changelogs/4.23.md Normal file
View File

@ -0,0 +1,51 @@
# 4.23.0
Released 12th July 2023.
**For Minecraft: Bedrock Edition 1.20.10**
This is a support release for Minecraft: Bedrock Edition 1.20.10.
**Plugin compatibility:** Plugins for previous 4.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` namespace.
Do not update plugin minimum API versions unless you need new features added in this release.
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
## General
- Added support for Minecraft: Bedrock Edition 1.20.10.
- Removed support for older versions.
## Fixes
- Fixed Docker image build failure due to outdated `build/php` submodule.
# 4.23.1
Released 14th July 2023.
## Fixes
- Hardened validation of JWT signing keys in `LoginPacket`.
- Fixed server crash due to a bug in upstream dependency [`netresearch/jsonmapper`](https://github.com/cweiske/JsonMapper).
# 4.23.2
Released 18th July 2023.
## Fixes
- Fixed login errors due to a new `sandboxId` field appearing in the Xbox Live authentication data in `LoginPacket`. All clients, regardless of version, are affected by this change.
# 4.23.3
Released 24th July 2023.
## Documentation
- Fixed typo in `ChunkSelector::selectChunks()` documentation.
## Fixes
- Fixed the server not stopping properly during crash conditions on *nix platforms.
- Fixed `HORSE_EQUIP` and `SMITHING_TABLE_TEMPLATE` container UI types not being handled by `ItemStackContainerIdTranslator`. This bug prevented plugins from implementing missing inventory types.
- Player emotes no longer broadcast messages to other players. This was unintended behaviour caused by a client-side behavioural change.
- Shulker boxes no longer support the placement of torches or other similar blocks.
- Fire can now be placed on upper slabs and the top of upside-down stairs.
# 4.23.4
Released 1st August 2023.
## Fixes
- Fixed exponentially increasing lag when many hundreds of non-mergeable dropped items occupied the same space. This disproportionately affected SkyBlock servers due to large cactus farms using water to collect items together.

View File

@ -33,11 +33,11 @@
"composer-runtime-api": "^2.0",
"adhocore/json-comment": "~1.2.0",
"fgrosse/phpasn1": "~2.5.0",
"pocketmine/netresearch-jsonmapper": "~v4.2.999",
"pocketmine/bedrock-block-upgrade-schema": "~2.2.0+bedrock-1.20.0",
"pocketmine/bedrock-data": "~2.3.0+bedrock-1.20.0",
"pocketmine/bedrock-item-upgrade-schema": "~1.3.0+bedrock-1.20.0",
"pocketmine/bedrock-protocol": "~22.0.0+bedrock-1.20.0",
"pocketmine/netresearch-jsonmapper": "~v4.2.1000",
"pocketmine/bedrock-block-upgrade-schema": "~3.1.0+bedrock-1.20.10",
"pocketmine/bedrock-data": "~2.4.0+bedrock-1.20.10",
"pocketmine/bedrock-item-upgrade-schema": "~1.4.0+bedrock-1.20.10",
"pocketmine/bedrock-protocol": "~23.0.2+bedrock-1.20.10",
"pocketmine/binaryutils": "^0.2.1",
"pocketmine/callback-validator": "^1.0.2",
"pocketmine/classloader": "^0.2.0",

87
composer.lock generated
View File

@ -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": "01dabd17488f8f5a5ac5c65b9eb8eea4",
"content-hash": "2acf1299aa8b354c44495ae048aa8893",
"packages": [
{
"name": "adhocore/json-comment",
@ -198,16 +198,16 @@
},
{
"name": "pocketmine/bedrock-block-upgrade-schema",
"version": "2.2.0",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git",
"reference": "79bb3ad542ef19e828fdf1fa6adc54f1fa4b3bb5"
"reference": "6d4ae416043337946a22fc31e8065ca2c21f472d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/79bb3ad542ef19e828fdf1fa6adc54f1fa4b3bb5",
"reference": "79bb3ad542ef19e828fdf1fa6adc54f1fa4b3bb5",
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/6d4ae416043337946a22fc31e8065ca2c21f472d",
"reference": "6d4ae416043337946a22fc31e8065ca2c21f472d",
"shasum": ""
},
"type": "library",
@ -218,22 +218,22 @@
"description": "Schemas describing how to upgrade saved block data in older Minecraft: Bedrock Edition world saves",
"support": {
"issues": "https://github.com/pmmp/BedrockBlockUpgradeSchema/issues",
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/2.2.0"
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/3.1.0"
},
"time": "2023-05-04T21:49:36+00:00"
"time": "2023-07-12T12:05:36+00:00"
},
{
"name": "pocketmine/bedrock-data",
"version": "2.3.1+bedrock-1.20.0",
"version": "2.4.0+bedrock-1.20.10",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockData.git",
"reference": "fb89ccdc039252462d8d068a769635e24151b7e2"
"reference": "f98bd1cae46d2920058acf3b23c0bedeac79f4ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/fb89ccdc039252462d8d068a769635e24151b7e2",
"reference": "fb89ccdc039252462d8d068a769635e24151b7e2",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/f98bd1cae46d2920058acf3b23c0bedeac79f4ab",
"reference": "f98bd1cae46d2920058acf3b23c0bedeac79f4ab",
"shasum": ""
},
"type": "library",
@ -244,22 +244,22 @@
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/BedrockData/issues",
"source": "https://github.com/pmmp/BedrockData/tree/2.3.1+bedrock-1.20.0"
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.20.10"
},
"time": "2023-06-13T16:42:09+00:00"
"time": "2023-07-12T11:51:54+00:00"
},
{
"name": "pocketmine/bedrock-item-upgrade-schema",
"version": "1.3.0",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git",
"reference": "b16c59cfae08833f180dd82f88de7c1f43bc67c9"
"reference": "60d199afe5e371fd189b21d685ec1fed6ba54230"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/b16c59cfae08833f180dd82f88de7c1f43bc67c9",
"reference": "b16c59cfae08833f180dd82f88de7c1f43bc67c9",
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/60d199afe5e371fd189b21d685ec1fed6ba54230",
"reference": "60d199afe5e371fd189b21d685ec1fed6ba54230",
"shasum": ""
},
"type": "library",
@ -270,22 +270,22 @@
"description": "JSON schemas for upgrading items found in older Minecraft: Bedrock world saves",
"support": {
"issues": "https://github.com/pmmp/BedrockItemUpgradeSchema/issues",
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.3.0"
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.4.0"
},
"time": "2023-05-18T15:34:32+00:00"
"time": "2023-07-12T12:08:37+00:00"
},
{
"name": "pocketmine/bedrock-protocol",
"version": "22.0.0+bedrock-1.20.0",
"version": "23.0.2+bedrock-1.20.10",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "ceff28a0bd5d248f37fb97be3e836d536e37526e"
"reference": "69a309a2dd7dcf3ec8c316385b866397e8c2cbfd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/ceff28a0bd5d248f37fb97be3e836d536e37526e",
"reference": "ceff28a0bd5d248f37fb97be3e836d536e37526e",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/69a309a2dd7dcf3ec8c316385b866397e8c2cbfd",
"reference": "69a309a2dd7dcf3ec8c316385b866397e8c2cbfd",
"shasum": ""
},
"require": {
@ -317,9 +317,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/22.0.0+bedrock-1.20.0"
"source": "https://github.com/pmmp/BedrockProtocol/tree/23.0.2+bedrock-1.20.10"
},
"time": "2023-06-07T19:22:05+00:00"
"time": "2023-07-24T15:35:36+00:00"
},
{
"name": "pocketmine/binaryutils",
@ -730,16 +730,16 @@
},
{
"name": "pocketmine/netresearch-jsonmapper",
"version": "v4.2.999",
"version": "v4.2.1000",
"source": {
"type": "git",
"url": "https://github.com/pmmp/netresearch-jsonmapper.git",
"reference": "f700806dec756ed825a8200dc2950ead98265956"
"reference": "078764e869e9b732f97206ec9363480a77c35532"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/netresearch-jsonmapper/zipball/f700806dec756ed825a8200dc2950ead98265956",
"reference": "f700806dec756ed825a8200dc2950ead98265956",
"url": "https://api.github.com/repos/pmmp/netresearch-jsonmapper/zipball/078764e869e9b732f97206ec9363480a77c35532",
"reference": "078764e869e9b732f97206ec9363480a77c35532",
"shasum": ""
},
"require": {
@ -778,9 +778,9 @@
"support": {
"email": "cweiske@cweiske.de",
"issues": "https://github.com/cweiske/jsonmapper/issues",
"source": "https://github.com/pmmp/netresearch-jsonmapper/tree/v4.2.999"
"source": "https://github.com/pmmp/netresearch-jsonmapper/tree/v4.2.1000"
},
"time": "2023-06-01T13:43:01+00:00"
"time": "2023-07-14T10:44:14+00:00"
},
{
"name": "pocketmine/raklib",
@ -2221,16 +2221,16 @@
},
{
"name": "phpunit/phpunit",
"version": "10.2.3",
"version": "10.2.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "35c8cac1734ede2ae354a6644f7088356ff5b08e"
"reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/35c8cac1734ede2ae354a6644f7088356ff5b08e",
"reference": "35c8cac1734ede2ae354a6644f7088356ff5b08e",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c17815c129f133f3019cc18e8d0c8622e6d9bcd",
"reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd",
"shasum": ""
},
"require": {
@ -2302,7 +2302,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.3"
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.6"
},
"funding": [
{
@ -2318,7 +2318,7 @@
"type": "tidelift"
}
],
"time": "2023-06-30T06:17:38+00:00"
"time": "2023-07-17T12:08:28+00:00"
},
{
"name": "sebastian/cli-parser",
@ -2830,16 +2830,16 @@
},
{
"name": "sebastian/global-state",
"version": "6.0.0",
"version": "6.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "aab257c712de87b90194febd52e4d184551c2d44"
"reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/aab257c712de87b90194febd52e4d184551c2d44",
"reference": "aab257c712de87b90194febd52e4d184551c2d44",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
"reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
"shasum": ""
},
"require": {
@ -2879,7 +2879,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/6.0.0"
"security": "https://github.com/sebastianbergmann/global-state/security/policy",
"source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
},
"funding": [
{
@ -2887,7 +2888,7 @@
"type": "github"
}
],
"time": "2023-02-03T07:07:38+00:00"
"time": "2023-07-19T07:19:23+00:00"
},
{
"name": "sebastian/lines-of-code",

View File

@ -343,7 +343,7 @@ JIT_WARNING
if(ThreadManager::getInstance()->stopAll() > 0){
$logger->debug("Some threads could not be stopped, performing a force-kill");
Process::kill(Process::pid(), true);
Process::kill(Process::pid());
}
}while(false);

View File

@ -1446,7 +1446,7 @@ class Server{
private function forceShutdownExit() : void{
$this->forceShutdown();
Process::kill(Process::pid(), true);
Process::kill(Process::pid());
}
public function forceShutdown() : void{
@ -1514,7 +1514,7 @@ class Server{
}catch(\Throwable $e){
$this->logger->logException($e);
$this->logger->emergency("Crashed while crashing, killing process");
@Process::kill(Process::pid(), true);
@Process::kill(Process::pid());
}
}
@ -1668,7 +1668,7 @@ class Server{
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
sleep($spacing);
}
@Process::kill(Process::pid(), true);
@Process::kill(Process::pid());
exit(1);
}

View File

@ -31,8 +31,8 @@ use function str_repeat;
final class VersionInfo{
public const NAME = "PocketMine-MP";
public const BASE_VERSION = "4.22.3";
public const IS_DEVELOPMENT_BUILD = true;
public const BASE_VERSION = "4.23.4";
public const IS_DEVELOPMENT_BUILD = false;
public const BUILD_CHANNEL = "stable";
private function __construct(){

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\BlockDataSerializer;
use pocketmine\block\utils\SupportType;
use pocketmine\entity\Entity;
use pocketmine\entity\projectile\Arrow;
use pocketmine\event\block\BlockBurnEvent;
@ -99,9 +100,13 @@ class Fire extends Flowable{
return [];
}
private function canBeSupportedBy(Block $block) : bool{
return $block->getSupportType(Facing::UP)->equals(SupportType::FULL());
}
public function onNearbyBlockChange() : void{
$world = $this->position->getWorld();
if($this->getSide(Facing::DOWN)->isTransparent() && !$this->hasAdjacentFlammableBlocks()){
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->hasAdjacentFlammableBlocks()){
$world->setBlock($this->position, VanillaBlocks::AIR());
}else{
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\block\tile\ShulkerBox as TileShulkerBox;
use pocketmine\block\utils\AnyFacingTrait;
use pocketmine\block\utils\SupportType;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
@ -103,4 +104,8 @@ class ShulkerBox extends Opaque{
return true;
}
public function getSupportType(int $facing) : SupportType{
return SupportType::NONE();
}
}

View File

@ -90,4 +90,4 @@ while(!feof($socket)){
//For simplicity's sake, we don't bother with a graceful shutdown here.
//The parent process would normally forcibly terminate the child process anyway, so we only reach this point if the
//parent process was terminated forcibly and didn't clean up after itself.
Process::kill(Process::pid(), false);
Process::kill(Process::pid());

View File

@ -131,7 +131,7 @@ class ItemEntity extends Entity{
}
}
if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){
if($this->hasMovementUpdate() && $this->isMergeCandidate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){
$mergeable = [$this]; //in case the merge target ends up not being this
$mergeTarget = $this;
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){
@ -173,12 +173,19 @@ class ItemEntity extends Entity{
}
}
private function isMergeCandidate() : bool{
return $this->pickupDelay !== self::NEVER_DESPAWN && $this->item->getCount() < $this->item->getMaxStackSize();
}
/**
* Returns whether this item entity can merge with the given one.
*/
public function isMergeable(ItemEntity $entity) : bool{
if(!$this->isMergeCandidate() || !$entity->isMergeCandidate()){
return false;
}
$item = $entity->item;
return $entity !== $this && $entity->pickupDelay !== self::NEVER_DESPAWN && $item->canStackWith($this->item) && $item->getCount() + $this->item->getCount() <= $item->getMaxStackSize();
return $entity !== $this && $item->canStackWith($this->item) && $item->getCount() + $this->item->getCount() <= $item->getMaxStackSize();
}
/**

View File

@ -61,6 +61,7 @@ use const OPENSSL_ALGO_SHA384;
use const STR_PAD_LEFT;
final class JwtUtils{
public const BEDROCK_SIGNING_KEY_CURVE_NAME = "secp384r1";
/**
* @return string[]
@ -203,6 +204,17 @@ final class JwtUtils{
if($signingKeyOpenSSL === false){
throw new JwtException("OpenSSL failed to parse key: " . openssl_error_string());
}
$details = openssl_pkey_get_details($signingKeyOpenSSL);
if($details === false){
throw new JwtException("OpenSSL failed to get details from key: " . openssl_error_string());
}
if(!isset($details['ec']['curve_name'])){
throw new JwtException("Expected an EC key");
}
$curve = $details['ec']['curve_name'];
if($curve !== self::BEDROCK_SIGNING_KEY_CURVE_NAME){
throw new JwtException("Key must belong to curve " . self::BEDROCK_SIGNING_KEY_CURVE_NAME . ", got $curve");
}
return $signingKeyOpenSSL;
}
}

View File

@ -84,6 +84,7 @@ use pocketmine\network\mcpe\protocol\types\AbilitiesLayer;
use pocketmine\network\mcpe\protocol\types\BlockPosition;
use pocketmine\network\mcpe\protocol\types\command\CommandData;
use pocketmine\network\mcpe\protocol\types\command\CommandEnum;
use pocketmine\network\mcpe\protocol\types\command\CommandOverload;
use pocketmine\network\mcpe\protocol\types\command\CommandParameter;
use pocketmine\network\mcpe\protocol\types\command\CommandPermissions;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
@ -949,8 +950,9 @@ class NetworkSession{
0,
$aliasObj,
[
[CommandParameter::standard("args", AvailableCommandsPacket::ARG_TYPE_RAWTEXT, 0, true)]
]
new CommandOverload(chaining: false, parameters: [CommandParameter::standard("args", AvailableCommandsPacket::ARG_TYPE_RAWTEXT, 0, true)])
],
chainedSubCommandData: []
);
$commandData[$command->getLabel()] = $data;

View File

@ -138,6 +138,6 @@ final class StandardEntityEventBroadcaster implements EntityEventBroadcaster{
}
public function onEmote(array $recipients, Human $from, string $emoteId) : void{
$this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER));
$this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER | EmotePacket::FLAG_MUTE_ANNOUNCEMENT));
}
}

View File

@ -32,7 +32,6 @@ use pocketmine\scheduler\AsyncTask;
use function base64_decode;
use function igbinary_serialize;
use function igbinary_unserialize;
use function openssl_error_string;
use function time;
class ProcessLoginTask extends AsyncTask{
@ -156,7 +155,8 @@ class ProcessLoginTask extends AsyncTask{
try{
$signingKeyOpenSSL = JwtUtils::parseDerPublicKey($headerDerKey);
}catch(JwtException $e){
throw new VerifyLoginException("Invalid JWT public key: " . openssl_error_string());
//TODO: we shouldn't be showing this internal information to the client
throw new VerifyLoginException("Invalid JWT public key: " . $e->getMessage(), 0, $e);
}
try{
if(!JwtUtils::verify($jwt, $signingKeyOpenSSL)){
@ -196,6 +196,12 @@ class ProcessLoginTask extends AsyncTask{
if($identityPublicKey === false){
throw new VerifyLoginException("Invalid identityPublicKey: base64 error decoding");
}
try{
//verify key format and parameters
JwtUtils::parseDerPublicKey($identityPublicKey);
}catch(JwtException $e){
throw new VerifyLoginException("Invalid identityPublicKey: " . $e->getMessage(), 0, $e);
}
$currentPublicKey = $identityPublicKey; //if there are further links, the next link should be signed with this
}
}

View File

@ -33,6 +33,7 @@ use function hex2bin;
use function openssl_digest;
use function openssl_error_string;
use function openssl_pkey_derive;
use function openssl_pkey_get_details;
use function str_pad;
use const STR_PAD_LEFT;
@ -42,7 +43,20 @@ final class EncryptionUtils{
//NOOP
}
private static function validateKey(\OpenSSLAsymmetricKey $key) : void{
$keyDetails = Utils::assumeNotFalse(openssl_pkey_get_details($key));
if(!isset($keyDetails["ec"]["curve_name"])){
throw new \InvalidArgumentException("Key must be an EC key");
}
$curveName = $keyDetails["ec"]["curve_name"];
if($curveName !== JwtUtils::BEDROCK_SIGNING_KEY_CURVE_NAME){
throw new \InvalidArgumentException("Key must belong to the " . JwtUtils::BEDROCK_SIGNING_KEY_CURVE_NAME . " elliptic curve, got $curveName");
}
}
public static function generateSharedSecret(\OpenSSLAsymmetricKey $localPriv, \OpenSSLAsymmetricKey $remotePub) : \GMP{
self::validateKey($localPriv);
self::validateKey($remotePub);
$hexSecret = openssl_pkey_derive($remotePub, $localPriv, 48);
if($hexSecret === false){
throw new \InvalidArgumentException("Failed to derive shared secret: " . openssl_error_string());

View File

@ -113,9 +113,9 @@ use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use pocketmine\world\format\Chunk;
use function array_push;
use function base64_encode;
use function count;
use function fmod;
use function get_debug_type;
use function implode;
use function in_array;
use function is_bool;
@ -748,27 +748,32 @@ class InGamePacketHandler extends PacketHandler{
if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit
if($block instanceof BaseSign){
if(($textBlobTag = $nbt->getCompoundTag(Sign::TAG_FRONT_TEXT)?->getTag(Sign::TAG_TEXT_BLOB)) instanceof StringTag){
try{
$text = SignText::fromBlob($textBlobTag->getValue());
}catch(\InvalidArgumentException $e){
throw PacketHandlingException::wrap($e, "Invalid sign text update");
}
try{
if(!$block->updateText($this->player, $text)){
foreach($this->player->getWorld()->createBlockUpdatePackets([$pos]) as $updatePacket){
$this->session->sendDataPacket($updatePacket);
}
}
}catch(\UnexpectedValueException $e){
throw PacketHandlingException::wrap($e);
}
return true;
$frontTextTag = $nbt->getTag(Sign::TAG_FRONT_TEXT);
if(!$frontTextTag instanceof CompoundTag){
throw new PacketHandlingException("Invalid tag type " . get_debug_type($frontTextTag) . " for tag \"" . Sign::TAG_FRONT_TEXT . "\" in sign update data");
}
$textBlobTag = $frontTextTag->getTag(Sign::TAG_TEXT_BLOB);
if(!$textBlobTag instanceof StringTag){
throw new PacketHandlingException("Invalid tag type " . get_debug_type($textBlobTag) . " for tag \"" . Sign::TAG_TEXT_BLOB . "\" in sign update data");
}
$this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->nbt->getEncodedNbt()));
try{
$text = SignText::fromBlob($textBlobTag->getValue());
}catch(\InvalidArgumentException $e){
throw PacketHandlingException::wrap($e, "Invalid sign text update");
}
try{
if(!$block->updateText($this->player, $text)){
foreach($this->player->getWorld()->createBlockUpdatePackets([$pos]) as $updatePacket){
$this->session->sendDataPacket($updatePacket);
}
}
}catch(\UnexpectedValueException $e){
throw PacketHandlingException::wrap($e);
}
return true;
}
return false;

View File

@ -70,6 +70,7 @@ final class ItemStackContainerIdTranslator{
ContainerUIIds::MATERIAL_REDUCER_OUTPUT,
ContainerUIIds::SMITHING_TABLE_INPUT,
ContainerUIIds::SMITHING_TABLE_MATERIAL,
ContainerUIIds::SMITHING_TABLE_TEMPLATE,
ContainerUIIds::STONECUTTER_INPUT,
ContainerUIIds::TRADE2_INGREDIENT1,
ContainerUIIds::TRADE2_INGREDIENT2,
@ -84,6 +85,7 @@ final class ItemStackContainerIdTranslator{
ContainerUIIds::FURNACE_FUEL,
ContainerUIIds::FURNACE_INGREDIENT,
ContainerUIIds::FURNACE_RESULT,
ContainerUIIds::HORSE_EQUIP,
ContainerUIIds::LEVEL_ENTITY, //chest
ContainerUIIds::SHULKER_BOX,
ContainerUIIds::SMOKER_INGREDIENT => [$currentWindowId, $slotId],

View File

@ -30,7 +30,7 @@ use const M_SQRT2;
final class ChunkSelector{
/**
* @preturn \Generator|int[]
* @return \Generator|int[]
* @phpstan-return \Generator<int, int, void, void>
*/
public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{

View File

@ -252,9 +252,15 @@ abstract class AsyncTask extends \Threaded{
final public function __destruct(){
$this->reallyDestruct();
if(self::$threadLocalStorage !== null && isset(self::$threadLocalStorage[$h = spl_object_id($this)])){
unset(self::$threadLocalStorage[$h]);
if(self::$threadLocalStorage->count() === 0){
//Beware changing this code!
//This code may cause the GC to be triggered, causing destruction of other AsyncTasks (which may or may not
//have been indirectly referenced by the TLS).
//This may cause the code to be re-entered from a different context unexpectedly, causing a crash if handled
//incorrectly.
if(self::$threadLocalStorage->count() === 1){
self::$threadLocalStorage = null;
}else{
unset(self::$threadLocalStorage[$h]);
}
}
}

View File

@ -125,7 +125,10 @@ final class Process{
return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread
}
public static function kill(int $pid, bool $subprocesses) : void{
/**
* @param bool $subprocesses @deprecated
*/
public static function kill(int $pid, bool $subprocesses = false) : void{
$logger = \GlobalLogger::get();
if($logger instanceof MainLogger){
$logger->syncFlushBuffer();

View File

@ -49,7 +49,7 @@ class ServerKiller extends Thread{
});
if(time() - $start >= $this->time){
echo "\nTook too long to stop, server was killed forcefully!\n";
@Process::kill(Process::pid(), true);
@Process::kill(Process::pid());
}
}

View File

@ -69,4 +69,36 @@ class AsyncPoolTest extends TestCase{
}
self::assertTrue(PublishProgressRaceAsyncTask::$success, "Progress was not reported before task completion");
}
/**
* This test ensures that the fix for an exotic AsyncTask::__destruct() reentrancy bug has not regressed.
*
* Due to an unset() in the function body, other AsyncTask::__destruct() calls could be triggered during
* an AsyncTask's destruction. If done in the wrong way, this could lead to a crash.
*
* @doesNotPerformAssertions This test is checking for a crash condition, not a specific output.
*/
public function testTaskDestructorReentrancy() : void{
$this->pool->submitTask(new class extends AsyncTask{
public function __construct(){
$this->storeLocal("task", new class extends AsyncTask{
public function __construct(){
$this->storeLocal("dummy", 1);
}
public function onRun() : void{
//dummy
}
});
}
public function onRun() : void{
//dummy
}
});
while($this->pool->collectTasks()){
usleep(50 * 1000);
}
}
}