Merge branch 'minor-next' into major-next

This commit is contained in:
Dylan K. Taylor 2025-06-18 19:56:54 +01:00
commit 6340d12881
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
10 changed files with 115 additions and 26 deletions

View File

@ -188,4 +188,4 @@ jobs:
if: github.event_name == 'pull_request_target' if: github.event_name == 'pull_request_target'
uses: thollander/actions-comment-pull-request@v3 uses: thollander/actions-comment-pull-request@v3
with: with:
message: "[Draft release ${{ steps.get-pm-version.outputs.PM_VERSION }}](${{ steps.create-draft.outputs.html_url }}) has been created for commit ${{ github.sha }}. Please review and publish it." message: "${{ vars.DRAFT_RELEASE_NOTIFICATION_MENTION }} [Draft release ${{ steps.get-pm-version.outputs.PM_VERSION }}](${{ steps.create-draft.outputs.html_url }}) has been created for commit ${{ github.sha }}. Please review and publish it."

25
changelogs/5.29.md Normal file
View File

@ -0,0 +1,25 @@
# 5.29.0
Released 18th June 2025.
This is a support release for Minecraft: Bedrock Edition 1.21.90.
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` 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.21.90.
- Removed support for earlier versions.
## Fixes
- Fixed thread crashes sometimes not reporting proper cause information in crashdumps.
- Fixed crash when a plugin replaced a player's held tool with a different tool with a damage exceeding the old tool's max damage during an action.
- Fixed performance issue of `PlayerAuthInputPacket` input flags handling (broken change detection).
- Fixed `BaseInventory->addItem()` triggering updates on empty slots when no items were added.
- Fixed slow check in `SubChunk` block layer garbage collection.
## Internals
- `LoginPacketHandler->processLogin()` signature has changed. This will break any plugins overriding `LoginPacketHandler`. As noted above, this is _not_ covered by the API version guarantee.
- Automated branch sync for `minor-next` and `major-next` is now triggered by `repository_dispatch` from a cron job in this repository instead of `RestrictedActions`. The `RestrictedActions` cron job was getting automatically disabled by GitHub due to repo inactivity.

View File

@ -34,9 +34,9 @@
"adhocore/json-comment": "~1.2.0", "adhocore/json-comment": "~1.2.0",
"netresearch/jsonmapper": "~v5.0.0", "netresearch/jsonmapper": "~v5.0.0",
"pocketmine/bedrock-block-upgrade-schema": "~5.1.0+bedrock-1.21.60", "pocketmine/bedrock-block-upgrade-schema": "~5.1.0+bedrock-1.21.60",
"pocketmine/bedrock-data": "~5.0.0+bedrock-1.21.80", "pocketmine/bedrock-data": "~5.1.0+bedrock-1.21.90",
"pocketmine/bedrock-item-upgrade-schema": "~1.14.0+bedrock-1.21.50", "pocketmine/bedrock-item-upgrade-schema": "~1.14.0+bedrock-1.21.50",
"pocketmine/bedrock-protocol": "~38.1.0+bedrock-1.21.80", "pocketmine/bedrock-protocol": "~39.0.0+bedrock-1.21.90",
"pocketmine/binaryutils": "^0.2.1", "pocketmine/binaryutils": "^0.2.1",
"pocketmine/callback-validator": "^1.0.2", "pocketmine/callback-validator": "^1.0.2",
"pocketmine/color": "^0.3.0", "pocketmine/color": "^0.3.0",

26
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": "d9a2346fa3dbb8503ac686e78349e7f0", "content-hash": "762dc69261168a2418157e427cd9fc22",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -204,16 +204,16 @@
}, },
{ {
"name": "pocketmine/bedrock-data", "name": "pocketmine/bedrock-data",
"version": "5.0.0+bedrock-1.21.80", "version": "5.1.0+bedrock-1.21.90",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/BedrockData.git", "url": "https://github.com/pmmp/BedrockData.git",
"reference": "e38d5ea19f794ec5216e5f96742237e8c4e7f080" "reference": "89ed34957aeccc63e517aa849af593adae958e98"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/e38d5ea19f794ec5216e5f96742237e8c4e7f080", "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/89ed34957aeccc63e517aa849af593adae958e98",
"reference": "e38d5ea19f794ec5216e5f96742237e8c4e7f080", "reference": "89ed34957aeccc63e517aa849af593adae958e98",
"shasum": "" "shasum": ""
}, },
"type": "library", "type": "library",
@ -224,9 +224,9 @@
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP", "description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
"support": { "support": {
"issues": "https://github.com/pmmp/BedrockData/issues", "issues": "https://github.com/pmmp/BedrockData/issues",
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.80" "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.90"
}, },
"time": "2025-05-09T14:15:18+00:00" "time": "2025-06-17T23:44:21+00:00"
}, },
{ {
"name": "pocketmine/bedrock-item-upgrade-schema", "name": "pocketmine/bedrock-item-upgrade-schema",
@ -256,16 +256,16 @@
}, },
{ {
"name": "pocketmine/bedrock-protocol", "name": "pocketmine/bedrock-protocol",
"version": "38.1.0+bedrock-1.21.80", "version": "39.0.0+bedrock-1.21.90",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git", "url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "a1fa215563517050045309bb779a67f75843b867" "reference": "2b088183d12fc003523400867ee398e3893899ed"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/a1fa215563517050045309bb779a67f75843b867", "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/2b088183d12fc003523400867ee398e3893899ed",
"reference": "a1fa215563517050045309bb779a67f75843b867", "reference": "2b088183d12fc003523400867ee398e3893899ed",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -296,9 +296,9 @@
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
"support": { "support": {
"issues": "https://github.com/pmmp/BedrockProtocol/issues", "issues": "https://github.com/pmmp/BedrockProtocol/issues",
"source": "https://github.com/pmmp/BedrockProtocol/tree/38.1.0+bedrock-1.21.80" "source": "https://github.com/pmmp/BedrockProtocol/tree/39.0.0+bedrock-1.21.90"
}, },
"time": "2025-05-28T22:19:59+00:00" "time": "2025-06-17T23:46:38+00:00"
}, },
{ {
"name": "pocketmine/binaryutils", "name": "pocketmine/binaryutils",

View File

@ -31,7 +31,7 @@ use function str_repeat;
final class VersionInfo{ final class VersionInfo{
public const NAME = "PocketMine-MP"; public const NAME = "PocketMine-MP";
public const BASE_VERSION = "5.28.3"; public const BASE_VERSION = "5.29.1";
public const IS_DEVELOPMENT_BUILD = true; public const IS_DEVELOPMENT_BUILD = true;
public const BUILD_CHANNEL = "stable"; public const BUILD_CHANNEL = "stable";

View File

@ -54,12 +54,12 @@ final class WorldDataVersions{
* This may be lower than the current protocol version if PocketMine-MP does not yet support features of the newer * This may be lower than the current protocol version if PocketMine-MP does not yet support features of the newer
* version. This allows the protocol to be updated independently of world format support. * version. This allows the protocol to be updated independently of world format support.
*/ */
public const NETWORK = 800; public const NETWORK = 818;
public const LAST_OPENED_IN = [ public const LAST_OPENED_IN = [
1, //major 1, //major
21, //minor 21, //minor
80, //patch 90, //patch
3, //revision 3, //revision
0 //is beta 0 //is beta
]; ];

View File

@ -380,6 +380,7 @@ final class ItemTypeNames{
public const MUSIC_DISC_RELIC = "minecraft:music_disc_relic"; public const MUSIC_DISC_RELIC = "minecraft:music_disc_relic";
public const MUSIC_DISC_STAL = "minecraft:music_disc_stal"; public const MUSIC_DISC_STAL = "minecraft:music_disc_stal";
public const MUSIC_DISC_STRAD = "minecraft:music_disc_strad"; public const MUSIC_DISC_STRAD = "minecraft:music_disc_strad";
public const MUSIC_DISC_TEARS = "minecraft:music_disc_tears";
public const MUSIC_DISC_WAIT = "minecraft:music_disc_wait"; public const MUSIC_DISC_WAIT = "minecraft:music_disc_wait";
public const MUSIC_DISC_WARD = "minecraft:music_disc_ward"; public const MUSIC_DISC_WARD = "minecraft:music_disc_ward";
public const MUTTON = "minecraft:mutton"; public const MUTTON = "minecraft:mutton";

View File

@ -33,6 +33,8 @@ use pocketmine\network\mcpe\JwtUtils;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\LoginPacket;
use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData;
use pocketmine\network\mcpe\protocol\types\login\AuthenticationInfo;
use pocketmine\network\mcpe\protocol\types\login\AuthenticationType;
use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\ClientData;
use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper; use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper;
use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\network\mcpe\protocol\types\login\JwtChain;
@ -42,7 +44,11 @@ use pocketmine\player\PlayerInfo;
use pocketmine\player\XboxLivePlayerInfo; use pocketmine\player\XboxLivePlayerInfo;
use pocketmine\Server; use pocketmine\Server;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use function gettype;
use function is_array; use function is_array;
use function is_object;
use function json_decode;
use const JSON_THROW_ON_ERROR;
/** /**
* Handles the initial login phase of the session. This handler is used as the initial state. * Handles the initial login phase of the session. This handler is used as the initial state.
@ -60,7 +66,9 @@ class LoginPacketHandler extends PacketHandler{
){} ){}
public function handleLogin(LoginPacket $packet) : bool{ public function handleLogin(LoginPacket $packet) : bool{
$extraData = $this->fetchAuthData($packet->chainDataJwt); $authInfo = $this->parseAuthInfo($packet->authInfoJson);
$jwtChain = $this->parseJwtChain($authInfo->Certificate);
$extraData = $this->fetchAuthData($jwtChain);
if(!Player::isValidUserName($extraData->displayName)){ if(!Player::isValidUserName($extraData->displayName)){
$this->session->disconnectWithError(KnownTranslationFactory::disconnectionScreen_invalidName()); $this->session->disconnectWithError(KnownTranslationFactory::disconnectionScreen_invalidName());
@ -139,11 +147,61 @@ class LoginPacketHandler extends PacketHandler{
return true; return true;
} }
$this->processLogin($packet, $ev->isAuthRequired()); $this->processLogin($authInfo->Token, AuthenticationType::from($authInfo->AuthenticationType), $jwtChain->chain, $packet->clientDataJwt, $ev->isAuthRequired());
return true; return true;
} }
/**
* @throws PacketHandlingException
*/
protected function parseAuthInfo(string $authInfo) : AuthenticationInfo{
try{
$authInfoJson = json_decode($authInfo, associative: false, flags: JSON_THROW_ON_ERROR);
}catch(\JsonException $e){
throw PacketHandlingException::wrap($e);
}
if(!is_object($authInfoJson)){
throw new \RuntimeException("Unexpected type for auth info data: " . gettype($authInfoJson) . ", expected object");
}
$mapper = new \JsonMapper();
$mapper->bExceptionOnMissingData = true;
$mapper->bExceptionOnUndefinedProperty = true;
$mapper->bStrictObjectTypeChecking = true;
try{
$clientData = $mapper->map($authInfoJson, new AuthenticationInfo());
}catch(\JsonMapper_Exception $e){
throw PacketHandlingException::wrap($e);
}
return $clientData;
}
/**
* @throws PacketHandlingException
*/
protected function parseJwtChain(string $chainDataJwt) : JwtChain{
try{
$jwtChainJson = json_decode($chainDataJwt, associative: false, flags: JSON_THROW_ON_ERROR);
}catch(\JsonException $e){
throw PacketHandlingException::wrap($e);
}
if(!is_object($jwtChainJson)){
throw new \RuntimeException("Unexpected type for JWT chain data: " . gettype($jwtChainJson) . ", expected object");
}
$mapper = new \JsonMapper();
$mapper->bExceptionOnMissingData = true;
$mapper->bExceptionOnUndefinedProperty = true;
$mapper->bStrictObjectTypeChecking = true;
try{
$clientData = $mapper->map($jwtChainJson, new JwtChain());
}catch(\JsonMapper_Exception $e){
throw PacketHandlingException::wrap($e);
}
return $clientData;
}
/** /**
* @throws PacketHandlingException * @throws PacketHandlingException
*/ */
@ -211,10 +269,15 @@ class LoginPacketHandler extends PacketHandler{
* TODO: This is separated for the purposes of allowing plugins (like Specter) to hack it and bypass authentication. * TODO: This is separated for the purposes of allowing plugins (like Specter) to hack it and bypass authentication.
* In the future this won't be necessary. * In the future this won't be necessary.
* *
* @param null|string[] $legacyCertificate
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ protected function processLogin(string $token, AuthenticationType $authType, ?array $legacyCertificate, string $clientData, bool $authRequired) : void{
$this->server->getAsyncPool()->submitTask(new ProcessLoginTask($packet->chainDataJwt->chain, $packet->clientDataJwt, $authRequired, $this->authCallback)); if($legacyCertificate === null){
throw new PacketHandlingException("Legacy certificate cannot be null");
}
$this->server->getAsyncPool()->submitTask(new ProcessLoginTask($legacyCertificate, $clientData, $authRequired, $this->authCallback));
$this->session->setHandler(null); //drop packets received during login verification $this->session->setHandler(null); //drop packets received during login verification
} }
} }

View File

@ -40,7 +40,6 @@ use pocketmine\network\mcpe\protocol\types\Experiments;
use pocketmine\network\mcpe\protocol\types\LevelSettings; use pocketmine\network\mcpe\protocol\types\LevelSettings;
use pocketmine\network\mcpe\protocol\types\NetworkPermissions; use pocketmine\network\mcpe\protocol\types\NetworkPermissions;
use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings; use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings;
use pocketmine\network\mcpe\protocol\types\ServerAuthMovementMode;
use pocketmine\network\mcpe\protocol\types\SpawnSettings; use pocketmine\network\mcpe\protocol\types\SpawnSettings;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\Server; use pocketmine\Server;
@ -99,7 +98,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$this->server->getMotd(), $this->server->getMotd(),
"", "",
false, false,
new PlayerMovementSettings(ServerAuthMovementMode::SERVER_AUTHORITATIVE_V3, 0, true), new PlayerMovementSettings(0, true),
0, 0,
0, 0,
"", "",

View File

@ -120,7 +120,8 @@ class ResourcePacksPacketHandler extends PacketHandler{
hasAddons: false, hasAddons: false,
hasScripts: false, hasScripts: false,
worldTemplateId: Uuid::fromString(Uuid::NIL), worldTemplateId: Uuid::fromString(Uuid::NIL),
worldTemplateVersion: "" worldTemplateVersion: "",
forceDisableVibrantVisuals: true,
)); ));
$this->session->getLogger()->debug("Waiting for client to accept resource packs"); $this->session->getLogger()->debug("Waiting for client to accept resource packs");
} }