Compare commits

...

36 Commits

Author SHA1 Message Date
f7279b6672 Release 4.23.5 2023-08-09 13:56:19 +01:00
2711ab4f00 Update composer dependencies 2023-08-09 13:49:19 +01:00
b4c5f5d58d PluginBase: fixed resource leak
all this time we've been harping at plugin devs to fix their own leaks, and here's one right under our noses that no one spotted for 10 years ...

this leak is rather common, since it will occur whenever a plugin attempts to save a resource which already exists in the data folder.

This bug was introduced in 2014 by commit 6328834681.
2023-08-09 13:28:05 +01:00
d88c3d8ced Fixed coral block killing itself when calling getDropsForCompatibleTool()
this might be called by plugins without actually breaking the block, in which case the block will glitch.
2023-08-02 13:43:36 +01:00
bb0e648276 Fixed BlockDeathEvent usages showing an oldState which is already dead 2023-08-02 13:36:54 +01:00
e9e5923639 4.23.5 is next 2023-08-01 11:12:52 +01:00
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
28 changed files with 286 additions and 113 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).

62
changelogs/4.23.md Normal file
View File

@ -0,0 +1,62 @@
# 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.
# 4.23.5
Released 9th August 2023.
## General
- Updated translation data to [pmmp/Language 2.19.6](https://github.com/pmmp/Language/releases/tag/2.19.6).
## Fixes
- Fixed `PluginBase->saveResource()` leaking file resources when the data file already exists in the plugin's data folder. This bug existed since 2014 and was only discovered recently.
- Fixed coral blocks becoming dead after calling `getDropsForCompatibleTool()` on them.
- Fixed `BlockDeathEvent->getOldState()` returning a block which is already dead.

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",

119
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.3+bedrock-1.20.10",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "ceff28a0bd5d248f37fb97be3e836d536e37526e"
"reference": "e4157c7af3f91e1b08fe21be171eb73dad7029e9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/ceff28a0bd5d248f37fb97be3e836d536e37526e",
"reference": "ceff28a0bd5d248f37fb97be3e836d536e37526e",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/e4157c7af3f91e1b08fe21be171eb73dad7029e9",
"reference": "e4157c7af3f91e1b08fe21be171eb73dad7029e9",
"shasum": ""
},
"require": {
@ -294,8 +294,8 @@
"php": "^8.0",
"pocketmine/binaryutils": "^0.2.0",
"pocketmine/color": "^0.2.0 || ^0.3.0",
"pocketmine/math": "^0.3.0 || ^0.4.0",
"pocketmine/nbt": "^0.3.0",
"pocketmine/math": "^0.3.0 || ^0.4.0 || ^1.0.0",
"pocketmine/nbt": "^0.3.0 || ^1.0.0",
"ramsey/uuid": "^4.1"
},
"require-dev": {
@ -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.3+bedrock-1.20.10"
},
"time": "2023-06-07T19:22:05+00:00"
"time": "2023-08-03T15:30:52+00:00"
},
{
"name": "pocketmine/binaryutils",
@ -538,16 +538,16 @@
},
{
"name": "pocketmine/locale-data",
"version": "2.19.5",
"version": "2.19.6",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Language.git",
"reference": "71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d"
"reference": "93e473e20e7f4515ecf45c5ef0f9155b9247a86e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Language/zipball/71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d",
"reference": "71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d",
"url": "https://api.github.com/repos/pmmp/Language/zipball/93e473e20e7f4515ecf45c5ef0f9155b9247a86e",
"reference": "93e473e20e7f4515ecf45c5ef0f9155b9247a86e",
"shasum": ""
},
"type": "library",
@ -555,9 +555,9 @@
"description": "Language resources used by PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/Language/issues",
"source": "https://github.com/pmmp/Language/tree/2.19.5"
"source": "https://github.com/pmmp/Language/tree/2.19.6"
},
"time": "2023-03-19T16:45:15+00:00"
"time": "2023-08-08T16:53:23+00:00"
},
{
"name": "pocketmine/log",
@ -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",
@ -1901,16 +1901,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "10.1.2",
"version": "10.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e"
"reference": "be1fe461fdc917de2a29a452ccf2657d325b443d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/db1497ec8dd382e82c962f7abbe0320e4882ee4e",
"reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/be1fe461fdc917de2a29a452ccf2657d325b443d",
"reference": "be1fe461fdc917de2a29a452ccf2657d325b443d",
"shasum": ""
},
"require": {
@ -1967,7 +1967,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.2"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.3"
},
"funding": [
{
@ -1975,7 +1975,7 @@
"type": "github"
}
],
"time": "2023-05-22T09:04:27+00:00"
"time": "2023-07-26T13:45:28+00:00"
},
{
"name": "phpunit/php-file-iterator",
@ -2221,16 +2221,16 @@
},
{
"name": "phpunit/phpunit",
"version": "10.2.3",
"version": "10.3.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "35c8cac1734ede2ae354a6644f7088356ff5b08e"
"reference": "d442ce7c4104d5683c12e67e4dcb5058159e9804"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/35c8cac1734ede2ae354a6644f7088356ff5b08e",
"reference": "35c8cac1734ede2ae354a6644f7088356ff5b08e",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d442ce7c4104d5683c12e67e4dcb5058159e9804",
"reference": "d442ce7c4104d5683c12e67e4dcb5058159e9804",
"shasum": ""
},
"require": {
@ -2255,7 +2255,7 @@
"sebastian/diff": "^5.0",
"sebastian/environment": "^6.0",
"sebastian/exporter": "^5.0",
"sebastian/global-state": "^6.0",
"sebastian/global-state": "^6.0.1",
"sebastian/object-enumerator": "^5.0",
"sebastian/recursion-context": "^5.0",
"sebastian/type": "^4.0",
@ -2270,7 +2270,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "10.2-dev"
"dev-main": "10.3-dev"
}
},
"autoload": {
@ -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.3.1"
},
"funding": [
{
@ -2318,7 +2318,7 @@
"type": "tidelift"
}
],
"time": "2023-06-30T06:17:38+00:00"
"time": "2023-08-04T06:48:08+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.5";
public const IS_DEVELOPMENT_BUILD = false;
public const BUILD_CHANNEL = "stable";
private function __construct(){

View File

@ -51,7 +51,7 @@ abstract class BaseCoral extends Transparent{
//TODO: check water inside the block itself (not supported on the API yet)
if(!$hasWater){
$ev = new BlockDeathEvent($this, $this->setDead(true));
$ev = new BlockDeathEvent($this, (clone $this)->setDead(true));
$ev->call();
if(!$ev->isCancelled()){
$world->setBlock($this->position, $ev->getNewState());

View File

@ -78,7 +78,7 @@ final class CoralBlock extends Opaque{
}
}
if(!$hasWater){
$ev = new BlockDeathEvent($this, $this->setDead(true));
$ev = new BlockDeathEvent($this, (clone $this)->setDead(true));
$ev->call();
if(!$ev->isCancelled()){
$world->setBlock($this->position, $ev->getNewState());
@ -88,7 +88,7 @@ final class CoralBlock extends Opaque{
}
public function getDropsForCompatibleTool(Item $item) : array{
return [$this->setDead(true)->asItem()];
return [(clone $this)->setDead(true)->asItem()];
}
public function isAffectedBySilkTouch() : bool{

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

@ -226,19 +226,19 @@ abstract class PluginBase implements Plugin, CommandExecutor{
return false;
}
$out = Path::join($this->dataFolder, $filename);
if(file_exists($out) && !$replace){
return false;
}
if(($resource = $this->getResource($filename)) === null){
return false;
}
$out = Path::join($this->dataFolder, $filename);
if(!file_exists(dirname($out))){
mkdir(dirname($out), 0755, true);
}
if(file_exists($out) && !$replace){
return false;
}
$fp = fopen($out, "wb");
if($fp === false) throw new AssumptionFailedError("fopen() should not fail with wb flags");

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);
}
}
}