Compare commits

...

22 Commits

Author SHA1 Message Date
442049d564 Prepare 5.32.1 release (#6766) 2025-08-14 11:37:24 +01:00
e375437439 ResourcePacksPacketHandler: harden checks for client responses 2025-08-12 20:11:35 +01:00
c417ecd30d NetworkSession: Abort packet processing if handling triggered a disconnection
this shows up when requesting invalid data during resource pack handling, for example
2025-08-12 18:38:24 +01:00
11612ed0e2 Fixed content log warning about recipe with missing ID 2025-08-11 00:49:37 +01:00
0b9e680753 Fix GitHub release trigger actions borked
https://github.com/actions/runner/issues/2788
2025-08-06 17:15:21 +01:00
275fdc4280 5.32.1 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/16781699267
2025-08-06 15:42:50 +00:00
173b685b02 Bedrock 1.21.100 (#6760)
---------

Co-authored-by: Dylan T. <dktapps@pmmp.io>
2025-08-06 16:41:44 +01:00
89d18f929f RakLibServer: fixed deadlock on thread crash
synchronized block -> getCrashInfo -> join -> synchronized on the same
context on the child thread -> deadlock

instead we check for isTerminated and then get the crash info outside
of the synchronized block.
2025-08-06 15:49:52 +01:00
a83c62a4a2 readme: Stop showing random PR statuses on CI badge 2025-07-30 19:08:29 +01:00
40ea6dd30d Bump phpstan/phpstan-strict-rules in the development-patch-updates group (#6758) 2025-07-29 09:26:25 +00:00
866df55edf Bump ramsey/uuid from 4.8.1 to 4.9.0 (#6748) 2025-07-29 09:25:19 +00:00
4047cbaafe Bump phpstan/phpstan-strict-rules in the development-patch-updates group (#6756) 2025-07-23 12:07:07 +00:00
a1d74b5710 5.31.1 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/16143550499
2025-07-08 12:43:11 +00:00
50e15db9ac Prepare 5.31.0 release (#6752) 2025-07-08 13:41:59 +01:00
f1f6e796a4 Bump the github-actions group with 2 updates (#6749) 2025-07-01 10:28:28 +00:00
7ea0f2ff43 copilot-setup-steps: also add extension stubs 2025-06-26 00:14:34 +01:00
6dbd4282cb fix cache key 2025-06-26 00:12:12 +01:00
3176e7549e woops 2025-06-26 00:11:26 +01:00
92c3ce7f02 Create copilot-setup-steps.yml 2025-06-26 00:10:46 +01:00
3a5432b316 Bump build/php from 1549433 to ce1b095 (#6741) 2025-06-25 00:16:12 +00:00
40a3ee68dd fix typo in changelog (#6745) 2025-06-24 13:35:32 +01:00
e415518435 5.30.2 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/15834488047
2025-06-23 20:31:58 +00:00
26 changed files with 269 additions and 75 deletions

View File

@ -4,6 +4,11 @@ on:
release:
types:
- published
workflow_dispatch:
inputs:
release:
description: 'Tag name to build'
required: true
jobs:
build:
@ -33,11 +38,23 @@ jobs:
repository: pmmp/PocketMine-Docker
fetch-depth: 1
- name: Get tag names
- name: Get tag name
id: tag-name
run: |
VERSION=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{')
echo TAG_NAME=$VERSION >> $GITHUB_OUTPUT
if [[ "${{ github.event_name }}" == "release" ]]; then
echo TAG_NAME="${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo TAG_NAME="${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
echo "Unsupported event type: ${{ github.event_name }}"
exit 1
fi
- name: Parse version
id: version
run: |
VERSION="${{ steps.tag-name.outputs.TAG_NAME }}"
echo MAJOR=$(echo $VERSION | cut -d. -f1) >> $GITHUB_OUTPUT
echo MINOR=$(echo $VERSION | cut -d. -f1-2) >> $GITHUB_OUTPUT
@ -71,8 +88,8 @@ jobs:
push: true
context: ./pocketmine-mp
tags: |
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MAJOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MAJOR }}
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MAJOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MAJOR }}
build-args: |
PMMP_TAG=${{ steps.tag-name.outputs.TAG_NAME }}
PMMP_REPO=${{ github.repository }}
@ -84,8 +101,8 @@ jobs:
push: true
context: ./pocketmine-mp
tags: |
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MINOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MINOR }}
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MINOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MINOR }}
build-args: |
PMMP_TAG=${{ steps.tag-name.outputs.TAG_NAME }}
PMMP_REPO=${{ github.repository }}

View File

@ -0,0 +1,47 @@
name: "Copilot Agent environment setup"
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: pmmp/setup-php-action@3.2.0
with:
php-version: 8.3
install-path: "./bin"
pm-version-major: 5
- name: Restore Composer package cache
uses: actions/cache@v4
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-8.3-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: composer install --prefer-dist --no-interaction
- name: Clone extension stubs
uses: actions/checkout@v4
with:
repository: pmmp/phpstorm-stubs
path: extension-stubs

View File

@ -4,6 +4,11 @@ on:
release:
types:
- published
workflow_dispatch:
inputs:
release:
description: 'Release to make notification for'
required: true
jobs:
build:
@ -13,7 +18,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.33.0
uses: shivammathur/setup-php@2.34.1
with:
php-version: 8.2
@ -30,9 +35,17 @@ jobs:
- name: Install Composer dependencies
run: composer install --no-dev --prefer-dist --no-interaction --ignore-platform-reqs
- name: Get actual tag name
- name: Get tag name
id: tag-name
run: echo TAG_NAME=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{') >> $GITHUB_OUTPUT
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
echo TAG_NAME="${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo TAG_NAME="${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
echo "Unsupported event type: ${{ github.event_name }}"
exit 1
fi
- name: Run webhook post script
run: php .github/workflows/discord-release-embed.php ${{ github.repository }} ${{ steps.tag-name.outputs.TAG_NAME }} ${{ github.token }} ${{ secrets.DISCORD_RELEASE_WEBHOOK }} ${{ secrets.DISCORD_NEWS_PING_ROLE_ID }}

View File

@ -49,7 +49,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@2.33.0
uses: shivammathur/setup-php@2.34.1
with:
php-version: 8.2

View File

@ -87,7 +87,7 @@ jobs:
submodules: true
- name: Setup PHP
uses: shivammathur/setup-php@2.33.0
uses: shivammathur/setup-php@2.34.1
with:
php-version: ${{ env.PHP_VERSION }}
@ -165,7 +165,7 @@ jobs:
${{ github.workspace }}/core-permissions.rst
- name: Create draft release
uses: ncipollo/release-action@v1.16.0
uses: ncipollo/release-action@v1.18.0
id: create-draft
with:
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json,${{ github.workspace }}/core-permissions.rst

View File

@ -28,7 +28,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.33.0
uses: shivammathur/setup-php@2.34.1
with:
php-version: 8.3
tools: php-cs-fixer:3.75

View File

@ -4,6 +4,11 @@ on:
release:
types:
- published
workflow_dispatch:
inputs:
release:
description: 'Release to publish info for'
required: true
jobs:
build:
@ -19,9 +24,17 @@ jobs:
repository: ${{ github.repository_owner }}/update.pmmp.io
ssh-key: ${{ secrets.UPDATE_PMMP_IO_DEPLOY_KEY }}
- name: Get actual tag name
- name: Get tag name
id: tag-name
run: echo TAG_NAME=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{') >> $GITHUB_OUTPUT
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
echo TAG_NAME="${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo TAG_NAME="${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
echo "Unsupported event type: ${{ github.event_name }}"
exit 1
fi
- name: Download new release information
run: curl -f -L ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ steps.tag-name.outputs.TAG_NAME }}/build_info.json -o new_build_info.json

View File

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/pmmp/PocketMine-MP/actions/workflows/main.yml"><img src="https://github.com/pmmp/PocketMine-MP/workflows/CI/badge.svg" alt="CI" /></a>
<a href="https://github.com/pmmp/PocketMine-MP/actions/workflows/main.yml"><img src="https://github.com/pmmp/PocketMine-MP/actions/workflows/main.yml/badge.svg" alt="CI" /></a>
<a href="https://github.com/pmmp/PocketMine-MP/releases/latest"><img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/pmmp/PocketMine-MP?label=release&sort=semver"></a>
<a href="https://discord.gg/bmSAZBG"><img src="https://img.shields.io/discord/373199722573201408?label=discord&color=7289DA&logo=discord" alt="Discord" /></a>
<br>

View File

@ -67,7 +67,7 @@ Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if
Released 23rd June 2025.
## Fixes
- Fixed accidental break of backwards compatability in `EntityExplodeEvent` introduced in the previous release.
- Fixed accidental break of backwards compatibility in `EntityExplodeEvent` introduced in the previous release.
- Fixed placement of player holding block when exploding respawn anchor.
- Updated BedrockProtocol to fix incorrect encoding of `ServerScriptDebugDrawerPacket`.
- Disabled client-side locator bar, allowing plugins to write their own implementations.

14
changelogs/5.31.md Normal file
View File

@ -0,0 +1,14 @@
# 5.31.0
Released 8th July 2025.
This is a support release for Minecraft: Bedrock Edition 1.21.93.
**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.93.
- Removed support for earlier versions.

25
changelogs/5.32.md Normal file
View File

@ -0,0 +1,25 @@
# 5.32.0
Released 6th August 2025.
This is a support release for Minecraft: Bedrock Edition 1.21.100.
**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.100.
- Removed support for earlier versions.
## Fixes
- Fixed deadlock on RakLib thread crash (e.g. due to port binding failure).
# 5.32.1
Released 14th August 2025.
## Fixes
- Hardened checks when processing resource pack sending during player logins.
- Fixed content log warning about crafting recipe with missing ID.
- Fixed packets in a batch still being processed after one of them caused the session to be terminated.

View File

@ -34,9 +34,9 @@
"adhocore/json-comment": "~1.2.0",
"netresearch/jsonmapper": "~v5.0.0",
"pocketmine/bedrock-block-upgrade-schema": "~5.1.0+bedrock-1.21.60",
"pocketmine/bedrock-data": "~5.1.0+bedrock-1.21.90",
"pocketmine/bedrock-item-upgrade-schema": "~1.14.0+bedrock-1.21.50",
"pocketmine/bedrock-protocol": "~39.0.0+bedrock-1.21.90",
"pocketmine/bedrock-data": "~5.3.0+bedrock-1.21.100",
"pocketmine/bedrock-item-upgrade-schema": "~1.15.0+bedrock-1.21.100",
"pocketmine/bedrock-protocol": "~40.0.0+bedrock-1.21.100",
"pocketmine/binaryutils": "^0.2.1",
"pocketmine/callback-validator": "^1.0.2",
"pocketmine/color": "^0.3.0",
@ -48,7 +48,7 @@
"pocketmine/raklib": "~1.2.0",
"pocketmine/raklib-ipc": "~1.0.0",
"pocketmine/snooze": "^0.5.0",
"ramsey/uuid": "~4.8.0",
"ramsey/uuid": "~4.9.0",
"symfony/filesystem": "~6.4.0"
},
"require-dev": {

63
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": "9bf4984c23f688264d3ce6a729a6ec17",
"content-hash": "402ad5667b1e636a8ec6acf2f1b5f055",
"packages": [
{
"name": "adhocore/json-comment",
@ -204,16 +204,16 @@
},
{
"name": "pocketmine/bedrock-data",
"version": "5.1.0+bedrock-1.21.90",
"version": "5.3.0+bedrock-1.21.100",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockData.git",
"reference": "89ed34957aeccc63e517aa849af593adae958e98"
"reference": "5279e76261df158d5af187cfaafc1618c1da9e3f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/89ed34957aeccc63e517aa849af593adae958e98",
"reference": "89ed34957aeccc63e517aa849af593adae958e98",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/5279e76261df158d5af187cfaafc1618c1da9e3f",
"reference": "5279e76261df158d5af187cfaafc1618c1da9e3f",
"shasum": ""
},
"type": "library",
@ -224,22 +224,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/bedrock-1.21.90"
"source": "https://github.com/pmmp/BedrockData/tree/5.3.0+bedrock-1.21.100"
},
"time": "2025-06-17T23:44:21+00:00"
"time": "2025-07-30T22:07:56+00:00"
},
{
"name": "pocketmine/bedrock-item-upgrade-schema",
"version": "1.14.0",
"version": "1.15.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git",
"reference": "9fc7c9bbb558a017395c1cb7dd819c033ee971bb"
"reference": "09e0dbe9743f21a76b1fe04b2b4136785775f52b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/9fc7c9bbb558a017395c1cb7dd819c033ee971bb",
"reference": "9fc7c9bbb558a017395c1cb7dd819c033ee971bb",
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/09e0dbe9743f21a76b1fe04b2b4136785775f52b",
"reference": "09e0dbe9743f21a76b1fe04b2b4136785775f52b",
"shasum": ""
},
"type": "library",
@ -250,22 +250,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.14.0"
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.15.0"
},
"time": "2024-12-04T12:22:49+00:00"
"time": "2025-08-06T15:08:48+00:00"
},
{
"name": "pocketmine/bedrock-protocol",
"version": "39.0.1+bedrock-1.21.90",
"version": "40.0.0+bedrock-1.21.100",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "fd231bad0d94024ff50169dc06e8c4fca5aa2eb3"
"reference": "5e95cab3a6e6c24920e0c25ca4aaf887ed4b70ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/fd231bad0d94024ff50169dc06e8c4fca5aa2eb3",
"reference": "fd231bad0d94024ff50169dc06e8c4fca5aa2eb3",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5e95cab3a6e6c24920e0c25ca4aaf887ed4b70ca",
"reference": "5e95cab3a6e6c24920e0c25ca4aaf887ed4b70ca",
"shasum": ""
},
"require": {
@ -296,9 +296,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/39.0.1+bedrock-1.21.90"
"source": "https://github.com/pmmp/BedrockProtocol/tree/40.0.0+bedrock-1.21.100"
},
"time": "2025-06-23T13:22:50+00:00"
"time": "2025-08-06T15:13:45+00:00"
},
{
"name": "pocketmine/binaryutils",
@ -818,21 +818,20 @@
},
{
"name": "ramsey/uuid",
"version": "4.8.1",
"version": "4.9.0",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28"
"reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/4e0e23cc785f0724a0e838279a9eb03f28b092a0",
"reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0",
"shasum": ""
},
"require": {
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13",
"ext-json": "*",
"php": "^8.0",
"ramsey/collection": "^1.2 || ^2.0"
},
@ -891,9 +890,9 @@
],
"support": {
"issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.8.1"
"source": "https://github.com/ramsey/uuid/tree/4.9.0"
},
"time": "2025-06-01T06:28:46+00:00"
"time": "2025-06-25T14:20:11+00:00"
},
{
"name": "symfony/filesystem",
@ -1312,16 +1311,16 @@
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "2.0.4",
"version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a"
"reference": "f9f77efa9de31992a832ff77ea52eb42d675b094"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/3e139cbe67fafa3588e1dbe27ca50f31fdb6236a",
"reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/f9f77efa9de31992a832ff77ea52eb42d675b094",
"reference": "f9f77efa9de31992a832ff77ea52eb42d675b094",
"shasum": ""
},
"require": {
@ -1354,9 +1353,9 @@
"description": "Extra strict and opinionated rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.4"
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.6"
},
"time": "2025-03-18T11:42:40+00:00"
"time": "2025-07-21T12:19:29+00:00"
},
{
"name": "phpunit/php-code-coverage",

View File

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

View File

@ -54,13 +54,13 @@ final class WorldDataVersions{
* 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.
*/
public const NETWORK = 818;
public const NETWORK = 827;
public const LAST_OPENED_IN = [
1, //major
21, //minor
90, //patch
3, //revision
100, //patch
23, //revision
0 //is beta
];
}

View File

@ -255,6 +255,7 @@ final class BlockTypeNames{
public const CONDUIT = "minecraft:conduit";
public const COPPER_BLOCK = "minecraft:copper_block";
public const COPPER_BULB = "minecraft:copper_bulb";
public const COPPER_CHEST = "minecraft:copper_chest";
public const COPPER_DOOR = "minecraft:copper_door";
public const COPPER_GRATE = "minecraft:copper_grate";
public const COPPER_ORE = "minecraft:copper_ore";
@ -533,6 +534,7 @@ final class BlockTypeNames{
public const EXPOSED_CHISELED_COPPER = "minecraft:exposed_chiseled_copper";
public const EXPOSED_COPPER = "minecraft:exposed_copper";
public const EXPOSED_COPPER_BULB = "minecraft:exposed_copper_bulb";
public const EXPOSED_COPPER_CHEST = "minecraft:exposed_copper_chest";
public const EXPOSED_COPPER_DOOR = "minecraft:exposed_copper_door";
public const EXPOSED_COPPER_GRATE = "minecraft:exposed_copper_grate";
public const EXPOSED_COPPER_TRAPDOOR = "minecraft:exposed_copper_trapdoor";
@ -857,6 +859,7 @@ final class BlockTypeNames{
public const OXIDIZED_CHISELED_COPPER = "minecraft:oxidized_chiseled_copper";
public const OXIDIZED_COPPER = "minecraft:oxidized_copper";
public const OXIDIZED_COPPER_BULB = "minecraft:oxidized_copper_bulb";
public const OXIDIZED_COPPER_CHEST = "minecraft:oxidized_copper_chest";
public const OXIDIZED_COPPER_DOOR = "minecraft:oxidized_copper_door";
public const OXIDIZED_COPPER_GRATE = "minecraft:oxidized_copper_grate";
public const OXIDIZED_COPPER_TRAPDOOR = "minecraft:oxidized_copper_trapdoor";
@ -1211,6 +1214,7 @@ final class BlockTypeNames{
public const WAXED_CHISELED_COPPER = "minecraft:waxed_chiseled_copper";
public const WAXED_COPPER = "minecraft:waxed_copper";
public const WAXED_COPPER_BULB = "minecraft:waxed_copper_bulb";
public const WAXED_COPPER_CHEST = "minecraft:waxed_copper_chest";
public const WAXED_COPPER_DOOR = "minecraft:waxed_copper_door";
public const WAXED_COPPER_GRATE = "minecraft:waxed_copper_grate";
public const WAXED_COPPER_TRAPDOOR = "minecraft:waxed_copper_trapdoor";
@ -1221,6 +1225,7 @@ final class BlockTypeNames{
public const WAXED_EXPOSED_CHISELED_COPPER = "minecraft:waxed_exposed_chiseled_copper";
public const WAXED_EXPOSED_COPPER = "minecraft:waxed_exposed_copper";
public const WAXED_EXPOSED_COPPER_BULB = "minecraft:waxed_exposed_copper_bulb";
public const WAXED_EXPOSED_COPPER_CHEST = "minecraft:waxed_exposed_copper_chest";
public const WAXED_EXPOSED_COPPER_DOOR = "minecraft:waxed_exposed_copper_door";
public const WAXED_EXPOSED_COPPER_GRATE = "minecraft:waxed_exposed_copper_grate";
public const WAXED_EXPOSED_COPPER_TRAPDOOR = "minecraft:waxed_exposed_copper_trapdoor";
@ -1231,6 +1236,7 @@ final class BlockTypeNames{
public const WAXED_OXIDIZED_CHISELED_COPPER = "minecraft:waxed_oxidized_chiseled_copper";
public const WAXED_OXIDIZED_COPPER = "minecraft:waxed_oxidized_copper";
public const WAXED_OXIDIZED_COPPER_BULB = "minecraft:waxed_oxidized_copper_bulb";
public const WAXED_OXIDIZED_COPPER_CHEST = "minecraft:waxed_oxidized_copper_chest";
public const WAXED_OXIDIZED_COPPER_DOOR = "minecraft:waxed_oxidized_copper_door";
public const WAXED_OXIDIZED_COPPER_GRATE = "minecraft:waxed_oxidized_copper_grate";
public const WAXED_OXIDIZED_COPPER_TRAPDOOR = "minecraft:waxed_oxidized_copper_trapdoor";
@ -1241,6 +1247,7 @@ final class BlockTypeNames{
public const WAXED_WEATHERED_CHISELED_COPPER = "minecraft:waxed_weathered_chiseled_copper";
public const WAXED_WEATHERED_COPPER = "minecraft:waxed_weathered_copper";
public const WAXED_WEATHERED_COPPER_BULB = "minecraft:waxed_weathered_copper_bulb";
public const WAXED_WEATHERED_COPPER_CHEST = "minecraft:waxed_weathered_copper_chest";
public const WAXED_WEATHERED_COPPER_DOOR = "minecraft:waxed_weathered_copper_door";
public const WAXED_WEATHERED_COPPER_GRATE = "minecraft:waxed_weathered_copper_grate";
public const WAXED_WEATHERED_COPPER_TRAPDOOR = "minecraft:waxed_weathered_copper_trapdoor";
@ -1251,6 +1258,7 @@ final class BlockTypeNames{
public const WEATHERED_CHISELED_COPPER = "minecraft:weathered_chiseled_copper";
public const WEATHERED_COPPER = "minecraft:weathered_copper";
public const WEATHERED_COPPER_BULB = "minecraft:weathered_copper_bulb";
public const WEATHERED_COPPER_CHEST = "minecraft:weathered_copper_chest";
public const WEATHERED_COPPER_DOOR = "minecraft:weathered_copper_door";
public const WEATHERED_COPPER_GRATE = "minecraft:weathered_copper_grate";
public const WEATHERED_COPPER_TRAPDOOR = "minecraft:weathered_copper_trapdoor";

View File

@ -153,8 +153,19 @@ final class ItemTypeNames{
public const COOKED_RABBIT = "minecraft:cooked_rabbit";
public const COOKED_SALMON = "minecraft:cooked_salmon";
public const COOKIE = "minecraft:cookie";
public const COPPER_AXE = "minecraft:copper_axe";
public const COPPER_BOOTS = "minecraft:copper_boots";
public const COPPER_CHESTPLATE = "minecraft:copper_chestplate";
public const COPPER_DOOR = "minecraft:copper_door";
public const COPPER_GOLEM_SPAWN_EGG = "minecraft:copper_golem_spawn_egg";
public const COPPER_HELMET = "minecraft:copper_helmet";
public const COPPER_HOE = "minecraft:copper_hoe";
public const COPPER_INGOT = "minecraft:copper_ingot";
public const COPPER_LEGGINGS = "minecraft:copper_leggings";
public const COPPER_NUGGET = "minecraft:copper_nugget";
public const COPPER_PICKAXE = "minecraft:copper_pickaxe";
public const COPPER_SHOVEL = "minecraft:copper_shovel";
public const COPPER_SWORD = "minecraft:copper_sword";
public const CORAL = "minecraft:coral";
public const CORAL_BLOCK = "minecraft:coral_block";
public const CORAL_FAN = "minecraft:coral_fan";
@ -372,6 +383,7 @@ final class ItemTypeNames{
public const MUSIC_DISC_CREATOR = "minecraft:music_disc_creator";
public const MUSIC_DISC_CREATOR_MUSIC_BOX = "minecraft:music_disc_creator_music_box";
public const MUSIC_DISC_FAR = "minecraft:music_disc_far";
public const MUSIC_DISC_LAVA_CHICKEN = "minecraft:music_disc_lava_chicken";
public const MUSIC_DISC_MALL = "minecraft:music_disc_mall";
public const MUSIC_DISC_MELLOHI = "minecraft:music_disc_mellohi";
public const MUSIC_DISC_OTHERSIDE = "minecraft:music_disc_otherside";

View File

@ -415,6 +415,11 @@ class NetworkSession{
$this->logger->debug($packet->getName() . ": " . base64_encode($buffer));
throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName());
}
if(!$this->isConnected()){
//handling this packet may have caused a disconnection
$this->logger->debug("Aborting batch processing due to server-side disconnection");
break;
}
}
}catch(PacketDecodeException|BinaryDataException $e){
$this->logger->logException($e);

View File

@ -56,6 +56,12 @@ final class CraftingDataCache{
*/
private array $caches = [];
/**
* The client doesn't like recipes with ID 0 (as of 1.21.100) and complains about them in the content log
* This doesn't actually affect the function of the recipe, but it is annoying, so this offset fixes it
*/
public const RECIPE_ID_OFFSET = 1;
public function getCache(CraftingManager $manager) : CraftingDataPacket{
$id = spl_object_id($manager);
if(!isset($this->caches[$id])){
@ -82,6 +88,8 @@ final class CraftingDataCache{
$noUnlockingRequirement = new RecipeUnlockingRequirement(null);
foreach($manager->getCraftingRecipeIndex() as $index => $recipe){
//the client doesn't like recipes with an ID of 0, so we need to offset them
$recipeNetId = $index + self::RECIPE_ID_OFFSET;
if($recipe instanceof ShapelessRecipe){
$typeTag = match($recipe->getType()){
ShapelessRecipeType::CRAFTING => CraftingRecipeBlockName::CRAFTING_TABLE,
@ -91,14 +99,14 @@ final class CraftingDataCache{
};
$recipesWithTypeIds[] = new ProtocolShapelessRecipe(
CraftingDataPacket::ENTRY_SHAPELESS,
Binary::writeInt($index),
Binary::writeInt($recipeNetId),
array_map($converter->coreRecipeIngredientToNet(...), $recipe->getIngredientList()),
array_map($converter->coreItemStackToNet(...), $recipe->getResults()),
$nullUUID,
$typeTag,
50,
$noUnlockingRequirement,
$index
$recipeNetId
);
}elseif($recipe instanceof ShapedRecipe){
$inputs = [];
@ -110,7 +118,7 @@ final class CraftingDataCache{
}
$recipesWithTypeIds[] = $r = new ProtocolShapedRecipe(
CraftingDataPacket::ENTRY_SHAPED,
Binary::writeInt($index),
Binary::writeInt($recipeNetId),
$inputs,
array_map($converter->coreItemStackToNet(...), $recipe->getResults()),
$nullUUID,
@ -118,7 +126,7 @@ final class CraftingDataCache{
50,
true,
$noUnlockingRequirement,
$index,
$recipeNetId,
);
}else{
//TODO: probably special recipe types

View File

@ -35,6 +35,7 @@ use pocketmine\inventory\transaction\TransactionBuilder;
use pocketmine\inventory\transaction\TransactionBuilderInventory;
use pocketmine\item\Durable;
use pocketmine\item\Item;
use pocketmine\network\mcpe\cache\CraftingDataCache;
use pocketmine\network\mcpe\InventoryManager;
use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds;
use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName;
@ -238,9 +239,10 @@ class ItemStackRequestExecutor{
throw new ItemStackRequestProcessException("Cannot craft a recipe more than 256 times");
}
$craftingManager = $this->player->getServer()->getCraftingManager();
$recipe = $craftingManager->getCraftingRecipeFromIndex($recipeId);
$recipeIndex = $recipeId - CraftingDataCache::RECIPE_ID_OFFSET;
$recipe = $craftingManager->getCraftingRecipeFromIndex($recipeIndex);
if($recipe === null){
throw new ItemStackRequestProcessException("No such crafting recipe index: $recipeId");
throw new ItemStackRequestProcessException("No such crafting recipe index: $recipeIndex");
}
$this->specialTransaction = new CraftingTransaction($this->player, $craftingManager, [], $recipe, $repetitions);

View File

@ -108,6 +108,7 @@ class PreSpawnPacketHandler extends PacketHandler{
Uuid::fromString(Uuid::NIL),
false,
false,
false,
new NetworkPermissions(disableClientSounds: true),
[],
0,

View File

@ -36,6 +36,7 @@ use pocketmine\network\mcpe\protocol\types\Experiments;
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry;
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry;
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType;
use pocketmine\network\PacketHandlingException;
use pocketmine\resourcepacks\ResourcePack;
use Ramsey\Uuid\Uuid;
use function array_keys;
@ -43,6 +44,7 @@ use function array_map;
use function ceil;
use function count;
use function implode;
use function sprintf;
use function strpos;
use function strtolower;
use function substr;
@ -66,6 +68,9 @@ class ResourcePacksPacketHandler extends PacketHandler{
*/
private array $resourcePacksById = [];
private bool $requestedMetadata = false;
private bool $requestedStack = false;
/** @var bool[][] uuid => [chunk index => hasSent] */
private array $downloadedChunks = [];
@ -140,6 +145,21 @@ class ResourcePacksPacketHandler extends PacketHandler{
$this->session->disconnect("Refused resource packs", "You must accept resource packs to join this server.", true);
break;
case ResourcePackClientResponsePacket::STATUS_SEND_PACKS:
if($this->requestedMetadata){
throw new PacketHandlingException("Cannot request resource pack metadata multiple times");
}
$this->requestedMetadata = true;
if($this->requestedStack){
//client already told us that they have all the packs, they shouldn't be asking for more
throw new PacketHandlingException("Cannot request resource pack metadata after resource pack stack");
}
if(count($packet->packIds) > count($this->resourcePacksById)){
throw new PacketHandlingException(sprintf("Requested metadata for more resource packs (%d) than available on the server (%d)", count($packet->packIds), count($this->resourcePacksById)));
}
$seen = [];
foreach($packet->packIds as $uuid){
//dirty hack for mojang's dirty hack for versions
$splitPos = strpos($uuid, "_");
@ -153,6 +173,9 @@ class ResourcePacksPacketHandler extends PacketHandler{
$this->disconnectWithError("Unknown pack $uuid requested, available packs: " . implode(", ", array_keys($this->resourcePacksById)));
return false;
}
if(isset($seen[$pack->getPackId()])){
throw new PacketHandlingException("Repeated metadata request for pack $uuid");
}
$this->session->sendDataPacket(ResourcePackDataInfoPacket::create(
$pack->getPackId(),
@ -163,11 +186,16 @@ class ResourcePacksPacketHandler extends PacketHandler{
false,
ResourcePackType::RESOURCES //TODO: this might be an addon (not behaviour pack), needed to properly support client-side custom items
));
$seen[$pack->getPackId()] = true;
}
$this->session->getLogger()->debug("Player requested download of " . count($packet->packIds) . " resource packs");
break;
case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS:
if($this->requestedStack){
throw new PacketHandlingException("Cannot request resource pack stack multiple times");
}
$this->requestedStack = true;
$stack = array_map(static function(ResourcePack $pack) : ResourcePackStackEntry{
return new ResourcePackStackEntry($pack->getPackId(), $pack->getPackVersion(), ""); //TODO: subpacks
}, $this->resourcePackStack);

View File

@ -68,17 +68,17 @@ class RakLibServer extends Thread{
public function startAndWait(int $options = NativeThread::INHERIT_NONE) : void{
$this->start($options);
$this->synchronized(function() : void{
while(!$this->ready && $this->getCrashInfo() === null){
while(!$this->ready && !$this->isTerminated()){
$this->wait();
}
$crashInfo = $this->getCrashInfo();
if($crashInfo !== null){
if($crashInfo->getType() === SocketException::class){
throw new SocketException($crashInfo->getMessage());
}
throw new ThreadCrashException("RakLib failed to start", $crashInfo);
}
});
$crashInfo = $this->getCrashInfo();
if($crashInfo !== null){
if($crashInfo->getType() === SocketException::class){
throw new SocketException($crashInfo->getMessage());
}
throw new ThreadCrashException("RakLib failed to start", $crashInfo);
}
}
protected function onRun() : void{

View File

@ -100,6 +100,8 @@ trait CommonThreadPartsTrait{
//*before* the shutdown handler is invoked, so we might land here before the crash info has been set.
//In the future this should probably be fixed by running the shutdown handlers before setting isTerminated,
//but this workaround should be good enough for now.
//WARNING: Do not call this inside a synchronized block on this thread's context. Because the shutdown handler
//runs in a synchronized block, this will result in a deadlock.
if($this->isTerminated() && !$this->isJoined()){
$this->join();
}

View File

@ -28,7 +28,7 @@ namespace pocketmine\world\biome\model;
*/
final class BiomeDefinitionEntryData{
/** @required */
public ?int $id;
public int $id;
/** @required */
public float $temperature;