Skip to content
This repository was archived by the owner on Jul 9, 2026. It is now read-only.

Commit 9c71f4f

Browse files
authored
Assemble 1.21.90 (#6736)
1 parent 95b4db5 commit 9c71f4f

9 files changed

Lines changed: 115 additions & 26 deletions

File tree

changelogs/5.29.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# 5.29.0
2+
Released 18th June 2025.
3+
4+
This is a support release for Minecraft: Bedrock Edition 1.21.90.
5+
6+
**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.
7+
Do not update plugin minimum API versions unless you need new features added in this release.
8+
9+
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
10+
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
11+
12+
## General
13+
- Added support for Minecraft: Bedrock Edition 1.21.90.
14+
- Removed support for earlier versions.
15+
16+
## Fixes
17+
- Fixed thread crashes sometimes not reporting proper cause information in crashdumps.
18+
- 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.
19+
- Fixed performance issue of `PlayerAuthInputPacket` input flags handling (broken change detection).
20+
- Fixed `BaseInventory->addItem()` triggering updates on empty slots when no items were added.
21+
- Fixed slow check in `SubChunk` block layer garbage collection.
22+
23+
## Internals
24+
- `LoginPacketHandler->processLogin()` signature has changed. This will break any plugins overriding `LoginPacketHandler`. As noted above, this is _not_ covered by the API version guarantee.
25+
- 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.

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
"adhocore/json-comment": "~1.2.0",
3535
"netresearch/jsonmapper": "~v5.0.0",
3636
"pocketmine/bedrock-block-upgrade-schema": "~5.1.0+bedrock-1.21.60",
37-
"pocketmine/bedrock-data": "~5.0.0+bedrock-1.21.80",
37+
"pocketmine/bedrock-data": "~5.1.0+bedrock-1.21.90",
3838
"pocketmine/bedrock-item-upgrade-schema": "~1.14.0+bedrock-1.21.50",
39-
"pocketmine/bedrock-protocol": "~38.1.0+bedrock-1.21.80",
39+
"pocketmine/bedrock-protocol": "~39.0.0+bedrock-1.21.90",
4040
"pocketmine/binaryutils": "^0.2.1",
4141
"pocketmine/callback-validator": "^1.0.2",
4242
"pocketmine/color": "^0.3.0",

composer.lock

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VersionInfo.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131

3232
final class VersionInfo{
3333
public const NAME = "PocketMine-MP";
34-
public const BASE_VERSION = "5.28.3";
35-
public const IS_DEVELOPMENT_BUILD = true;
34+
public const BASE_VERSION = "5.29.0";
35+
public const IS_DEVELOPMENT_BUILD = false;
3636
public const BUILD_CHANNEL = "stable";
3737

3838
/**

src/data/bedrock/item/ItemTypeNames.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ final class ItemTypeNames{
380380
public const MUSIC_DISC_RELIC = "minecraft:music_disc_relic";
381381
public const MUSIC_DISC_STAL = "minecraft:music_disc_stal";
382382
public const MUSIC_DISC_STRAD = "minecraft:music_disc_strad";
383+
public const MUSIC_DISC_TEARS = "minecraft:music_disc_tears";
383384
public const MUSIC_DISC_WAIT = "minecraft:music_disc_wait";
384385
public const MUSIC_DISC_WARD = "minecraft:music_disc_ward";
385386
public const MUTTON = "minecraft:mutton";

src/network/mcpe/handler/LoginPacketHandler.php

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
use pocketmine\network\mcpe\NetworkSession;
3434
use pocketmine\network\mcpe\protocol\LoginPacket;
3535
use pocketmine\network\mcpe\protocol\types\login\AuthenticationData;
36+
use pocketmine\network\mcpe\protocol\types\login\AuthenticationInfo;
37+
use pocketmine\network\mcpe\protocol\types\login\AuthenticationType;
3638
use pocketmine\network\mcpe\protocol\types\login\ClientData;
3739
use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper;
3840
use pocketmine\network\mcpe\protocol\types\login\JwtChain;
@@ -42,7 +44,11 @@
4244
use pocketmine\player\XboxLivePlayerInfo;
4345
use pocketmine\Server;
4446
use Ramsey\Uuid\Uuid;
47+
use function gettype;
4548
use function is_array;
49+
use function is_object;
50+
use function json_decode;
51+
use const JSON_THROW_ON_ERROR;
4652

4753
/**
4854
* Handles the initial login phase of the session. This handler is used as the initial state.
@@ -60,7 +66,9 @@ public function __construct(
6066
){}
6167

6268
public function handleLogin(LoginPacket $packet) : bool{
63-
$extraData = $this->fetchAuthData($packet->chainDataJwt);
69+
$authInfo = $this->parseAuthInfo($packet->authInfoJson);
70+
$jwtChain = $this->parseJwtChain($authInfo->Certificate);
71+
$extraData = $this->fetchAuthData($jwtChain);
6472

6573
if(!Player::isValidUserName($extraData->displayName)){
6674
$this->session->disconnectWithError(KnownTranslationFactory::disconnectionScreen_invalidName());
@@ -139,11 +147,61 @@ public function handleLogin(LoginPacket $packet) : bool{
139147
return true;
140148
}
141149

142-
$this->processLogin($packet, $ev->isAuthRequired());
150+
$this->processLogin($authInfo->Token, AuthenticationType::from($authInfo->AuthenticationType), $jwtChain->chain, $packet->clientDataJwt, $ev->isAuthRequired());
143151

144152
return true;
145153
}
146154

155+
/**
156+
* @throws PacketHandlingException
157+
*/
158+
protected function parseAuthInfo(string $authInfo) : AuthenticationInfo{
159+
try{
160+
$authInfoJson = json_decode($authInfo, associative: false, flags: JSON_THROW_ON_ERROR);
161+
}catch(\JsonException $e){
162+
throw PacketHandlingException::wrap($e);
163+
}
164+
if(!is_object($authInfoJson)){
165+
throw new \RuntimeException("Unexpected type for auth info data: " . gettype($authInfoJson) . ", expected object");
166+
}
167+
168+
$mapper = new \JsonMapper();
169+
$mapper->bExceptionOnMissingData = true;
170+
$mapper->bExceptionOnUndefinedProperty = true;
171+
$mapper->bStrictObjectTypeChecking = true;
172+
try{
173+
$clientData = $mapper->map($authInfoJson, new AuthenticationInfo());
174+
}catch(\JsonMapper_Exception $e){
175+
throw PacketHandlingException::wrap($e);
176+
}
177+
return $clientData;
178+
}
179+
180+
/**
181+
* @throws PacketHandlingException
182+
*/
183+
protected function parseJwtChain(string $chainDataJwt) : JwtChain{
184+
try{
185+
$jwtChainJson = json_decode($chainDataJwt, associative: false, flags: JSON_THROW_ON_ERROR);
186+
}catch(\JsonException $e){
187+
throw PacketHandlingException::wrap($e);
188+
}
189+
if(!is_object($jwtChainJson)){
190+
throw new \RuntimeException("Unexpected type for JWT chain data: " . gettype($jwtChainJson) . ", expected object");
191+
}
192+
193+
$mapper = new \JsonMapper();
194+
$mapper->bExceptionOnMissingData = true;
195+
$mapper->bExceptionOnUndefinedProperty = true;
196+
$mapper->bStrictObjectTypeChecking = true;
197+
try{
198+
$clientData = $mapper->map($jwtChainJson, new JwtChain());
199+
}catch(\JsonMapper_Exception $e){
200+
throw PacketHandlingException::wrap($e);
201+
}
202+
return $clientData;
203+
}
204+
147205
/**
148206
* @throws PacketHandlingException
149207
*/
@@ -211,10 +269,15 @@ protected function parseClientData(string $clientDataJwt) : ClientData{
211269
* TODO: This is separated for the purposes of allowing plugins (like Specter) to hack it and bypass authentication.
212270
* In the future this won't be necessary.
213271
*
272+
* @param null|string[] $legacyCertificate
273+
*
214274
* @throws \InvalidArgumentException
215275
*/
216-
protected function processLogin(LoginPacket $packet, bool $authRequired) : void{
217-
$this->server->getAsyncPool()->submitTask(new ProcessLoginTask($packet->chainDataJwt->chain, $packet->clientDataJwt, $authRequired, $this->authCallback));
276+
protected function processLogin(string $token, AuthenticationType $authType, ?array $legacyCertificate, string $clientData, bool $authRequired) : void{
277+
if($legacyCertificate === null){
278+
throw new PacketHandlingException("Legacy certificate cannot be null");
279+
}
280+
$this->server->getAsyncPool()->submitTask(new ProcessLoginTask($legacyCertificate, $clientData, $authRequired, $this->authCallback));
218281
$this->session->setHandler(null); //drop packets received during login verification
219282
}
220283
}

src/network/mcpe/handler/PreSpawnPacketHandler.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
use pocketmine\network\mcpe\protocol\types\LevelSettings;
4141
use pocketmine\network\mcpe\protocol\types\NetworkPermissions;
4242
use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings;
43-
use pocketmine\network\mcpe\protocol\types\ServerAuthMovementMode;
4443
use pocketmine\network\mcpe\protocol\types\SpawnSettings;
4544
use pocketmine\player\Player;
4645
use pocketmine\Server;
@@ -99,7 +98,7 @@ public function setUp() : void{
9998
$this->server->getMotd(),
10099
"",
101100
false,
102-
new PlayerMovementSettings(ServerAuthMovementMode::SERVER_AUTHORITATIVE_V2, 0, false),
101+
new PlayerMovementSettings(0, false),
103102
0,
104103
0,
105104
"",

src/network/mcpe/handler/ResourcePacksPacketHandler.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ public function setUp() : void{
120120
hasAddons: false,
121121
hasScripts: false,
122122
worldTemplateId: Uuid::fromString(Uuid::NIL),
123-
worldTemplateVersion: ""
123+
worldTemplateVersion: "",
124+
forceDisableVibrantVisuals: true,
124125
));
125126
$this->session->getLogger()->debug("Waiting for client to accept resource packs");
126127
}

src/world/format/io/data/BedrockWorldData.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@
5151
class BedrockWorldData extends BaseNbtWorldData{
5252

5353
public const CURRENT_STORAGE_VERSION = 10;
54-
public const CURRENT_STORAGE_NETWORK_VERSION = 800;
54+
public const CURRENT_STORAGE_NETWORK_VERSION = 818;
5555
public const CURRENT_CLIENT_VERSION_TARGET = [
5656
1, //major
5757
21, //minor
58-
80, //patch
58+
90, //patch
5959
3, //revision
6060
0 //is beta
6161
];

0 commit comments

Comments
 (0)