mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-10 03:34:06 +00:00
Compare commits
26 Commits
4.18.0-ALP
...
4.18.1
Author | SHA1 | Date | |
---|---|---|---|
cd603e8266 | |||
af385668c2 | |||
3ee62d8440 | |||
811639f2cd | |||
58974765a6 | |||
eca9fe50b6 | |||
006cdaf6ea | |||
acc8ae87fb | |||
0e8b28716a | |||
7c77233d12 | |||
6f02b83a26 | |||
fbfdf749f2 | |||
289c0b08f4 | |||
dd37b531ad | |||
58d5126ada | |||
f978c1e9a0 | |||
0b8193aeb3 | |||
00286e761c | |||
db59f71130 | |||
b11457d605 | |||
ea386c42d3 | |||
043e81e737 | |||
52ea4feac0 | |||
01d557062a | |||
a619fd2be6 | |||
05d9298958 |
7
.github/workflows/build-docker-image.yml
vendored
7
.github/workflows/build-docker-image.yml
vendored
@ -20,6 +20,13 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Clone pmmp/PocketMine-Docker repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
|
@ -21,21 +21,22 @@ Larger contributions like feature additions should be preceded by a [Change Prop
|
||||
## Choosing a target branch
|
||||
PocketMine-MP has three primary branches of development.
|
||||
|
||||
| Type of change | `stable` | `minor-next` | `major-next` |
|
||||
|:---------------|:--------:|:------------:|:------------:|
|
||||
| Bug fixes | ✔️ | ✔️ | ✔️ |
|
||||
| Improvements to API docs | ✔️ | ✔️ | ✔️ |
|
||||
| Cleaning up code | ❌ | ✔️ | ✔️ |
|
||||
| Changing code formatting or style | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new core features | ❌ | 🟡 Only if non-disruptive | ✔️ |
|
||||
| Changing core behaviour (e.g. making something use threads) | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new configuration options | ❌ | 🟡 Only if optional | ✔️ |
|
||||
| Addition of new API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Deprecating API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Adding optional parameters to an API method | ❌ | ✔️ | ✔️ |
|
||||
| Changing API behaviour | ❌ | 🟡 Only if backwards-compatible | ✔️ |
|
||||
| Removal of API | ❌ | ❌ | ✔️ |
|
||||
| Backwards-incompatible API change (e.g. renaming a method) | ❌ | ❌ | ✔️ |
|
||||
| Type of change | `stable` | `minor-next` | `major-next` |
|
||||
|:--------------------------------------------------------------------------------------------|:--------:|:-------------------------------:|:------------:|
|
||||
| Bug fixes | ✔️ | ✔️ | ✔️ |
|
||||
| Improvements to API docs | ✔️ | ✔️ | ✔️ |
|
||||
| Cleaning up code | ❌ | ✔️ | ✔️ |
|
||||
| Changing code formatting or style | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new core features | ❌ | 🟡 Only if non-disruptive | ✔️ |
|
||||
| Changing core behaviour (e.g. making something use threads) | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new configuration options | ❌ | 🟡 Only if optional | ✔️ |
|
||||
| Addition of new API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Deprecating API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Adding optional parameters to an API method | ❌ | ✔️ | ✔️ |
|
||||
| Changing API behaviour | ❌ | 🟡 Only if backwards-compatible | ✔️ |
|
||||
| Removal of API | ❌ | ❌ | ✔️ |
|
||||
| Backwards-incompatible API change (e.g. renaming a method) | ❌ | ❌ | ✔️ |
|
||||
| Backwards-incompatible internals change (e.g. changing things in `pocketmine\network\mcpe`) | ❌ | ✔️ | ✔️ |
|
||||
|
||||
### Notes
|
||||
- **Non-disruptive** means that usage should not be significantly altered by the change.
|
||||
@ -43,6 +44,10 @@ PocketMine-MP has three primary branches of development.
|
||||
- Examples of **disruptive** changes include changing the way the server is run, world format changes (since those require downtime for the user to convert their world).
|
||||
- **API** includes all public and protected classes, functions and constants (unless marked as `@internal`).
|
||||
- Private members are not part of the API, **unless in a trait**.
|
||||
- The `pocketmine\network\mcpe` package is considered implicitly `@internal` in its entirety (see its [README](src/network/mcpe/README.md) for more details).
|
||||
- Minecraft's protocol changes are considered necessary internal changes, and are **not** subject to the same rules.
|
||||
- Protocol changes must always be released in a new minor version, since they disrupt user experience by requiring a client update.
|
||||
- BC-breaking changes to the internal network API are allowed, but only in new minor versions. This ensures that plugins which use the internal network API will not break (though they shouldn't use such API anyway).
|
||||
|
||||
## Making a pull request
|
||||
The basic procedure to create a pull request is:
|
||||
|
Submodule build/php updated: a464454d1e...9d8807be82
@ -11,4 +11,23 @@ Released 14th March 2023.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.70.
|
||||
- Removed support for older versions.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.17.1
|
||||
Released 22nd March 2023.
|
||||
|
||||
## General
|
||||
- Docker images for PocketMine-MP are now published on [GitHub Container Registry](https://github.com/pmmp/PocketMine-MP/pkgs/container/pocketmine-mp). The Docker Hub images will stop being maintained in the future.
|
||||
- Updated translations.
|
||||
|
||||
## Fixes
|
||||
- Fixed server crash on empty packets in certain cases.
|
||||
- Fixed mushroom blocks dropping the wrong items when broken with a silk-touch tool.
|
||||
- Fixed mushroom blocks giving the wrong items when block-picked.
|
||||
- Fixed missing ability flag `PRIVILEGED_BUILDER`.
|
||||
|
||||
## Internals
|
||||
- `update-updater-api.yml` workflow now uses `github.repository_owner` to make it easier to test the workflow on forks.
|
||||
- Added version-specific channels to `update.pmmp.io`, such as `4`, `4.18-beta`, `4.17`, etc.
|
||||
- Replaced deprecated `::set-output` commands in GitHub Actions workflows.
|
||||
- `build/make-release.php` no longer automatically pushes changes, to avoid accidents when testing release workflows on forks.
|
||||
|
92
changelogs/4.18.md
Normal file
92
changelogs/4.18.md
Normal file
@ -0,0 +1,92 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.70**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the `pocketmine\network\mcpe` namespace are compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**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.
|
||||
|
||||
### Highlights
|
||||
This version significantly improves server performance with many players and/or entities by making changes to the internal network system.
|
||||
|
||||
It also introduces support for the newer `ItemStackRequest` protocol, which fixes many bugs and improves server security.
|
||||
|
||||
While these changes don't affect non-internal API, they are still significant enough to warrant a new minor version, as they may break plugins which use the internal network API (not recommended).
|
||||
|
||||
# 4.18.0
|
||||
Released 25th March 2023.
|
||||
|
||||
## General
|
||||
- Significantly improved server performance in congested areas of the world (lots of players and/or entities in the same area).
|
||||
- Included more sections of the network system in `Player Network Send` performance timings.
|
||||
- Changed the names of some performance timings to make them more user-friendly.
|
||||
- Removed packet IDs from `receivePacket` and `sendPacket` performance timings, as they were not very useful.
|
||||
- Added new specialized performance timings for the following:
|
||||
- Item entity base ticking (merging)
|
||||
- Player movement processing
|
||||
- Entity movement processing (collision checking section)
|
||||
- Projectile movement (all)
|
||||
- Projectile movement processing (ray tracing section)
|
||||
|
||||
## API
|
||||
### `pocketmine\crafting`
|
||||
- The following new API methods have been added:
|
||||
- `CraftingManager->getCraftingRecipeIndex() : array<int, CraftingRecipe>` - returns a list of all crafting recipes
|
||||
- `CraftingManager->getCraftingRecipeFromIndex(int $index) : ?CraftingRecipe` - returns the crafting recipe at the given index, or null if it doesn't exist
|
||||
|
||||
### `pocketmine\event\server`
|
||||
- The following new classes have been added:
|
||||
- `DataPacketDecodeEvent` - called before a packet is decoded by a `NetworkSession`; useful to mitigate DoS attacks if PocketMine-MP hasn't been patched against new bugs yet
|
||||
|
||||
### `pocketmine\inventory\transaction`
|
||||
- The following API methods have changed signatures:
|
||||
- `CraftingTransaction->__construct()` now accepts additional arguments `?CraftingRecipe $recipe = null, ?int $repetitions = null`
|
||||
- The following new API methods have been added:
|
||||
- `TransactionBuilderInventory->getActualInventory() : Inventory` - returns the actual inventory that this inventory is a proxy for
|
||||
|
||||
## Internals
|
||||
### Network
|
||||
- Introduced new system for broadcasting entity events to network sessions.
|
||||
- This change improves performance when lots of players and/or entities are in the same area.
|
||||
- New interface `EntityEventBroadcaster` and class `StandardEntityEventBroadcaster` have been added to implement this.
|
||||
- All entity-specific `on*()` and `sync*()` methods have been removed from `NetworkSession` (internals backwards compatibility break, not covered by API version guarantee).
|
||||
- `NetworkSession` now accepts an `EntityEventBroadcaster` instance in its constructor.
|
||||
- `NetworkBroadcastUtils::broadcastEntityEvent()` can be used to efficiently broadcast events to unique broadcasters shared by several network sessions.
|
||||
- All network sessions now share the same `PacketSerializerContext` and `PacketBroadcaster` by default.
|
||||
- Previously, every session had its own context, meaning that broadcast optimisations were not used, causing significant performance losses compared to 3.x.
|
||||
- This change improves performance in congested areas by allowing reuse of previously encoded packet buffers for all sessions sharing the same context.
|
||||
- Packet broadcasts are automatically encoded separately per unique `PacketSerializerContext` instance. This allows, for example, a multi-version fork to have a separate context for each protocol version, to ensure maximum broadcast efficiency while encoding different packets for different versions.
|
||||
- `PacketSerializerContext` is now passed in `NetworkSession::__construct()`, instead of being created by the session.
|
||||
- `StandardPacketBroadcaster` is now locked to a single `PacketSerializer` context, reducing complexity.
|
||||
- Introduced `NetworkBroadcastUtils::broadcastPackets()`, replacing `Server->broadcastPackets()`.
|
||||
- `Server->broadcastPackets()` has been deprecated. It will be removed in a future version.
|
||||
- Introduced support for the `ItemStackRequest` Minecraft: Bedrock network protocol.
|
||||
- This fixes a large number of inventory- and crafting-related bugs.
|
||||
- This also improves server security by closing off many code pathways that might have been used for exploits. `TypeConverter->netItemStackToCore()` is no longer used in server code, and remains for tool usage only.
|
||||
- This system is also significantly more bandwidth-efficient and has lower overhead than the legacy system.
|
||||
- This now opens the gateway to easily implement lots of gameplay features which have been missing for a long time, such as enchanting, anvils, looms, and more.
|
||||
- Significant changes have been made to `pocketmine\network\mcpe\InventoryManager` internals. These shouldn't affect plugins, but may affect plugins which use internal network API.
|
||||
- **No changes have been made to the plugin `InventoryTransaction` API**.
|
||||
- This system has been implemented as a shim for the existing PocketMine-MP transaction system to preserve plugin compatibility. Plugins using `InventoryTransactionEvent` should continue to work seamlessly.
|
||||
- The `InventoryTransaction` API will be redesigned in a future major version to make use of the new information provided by the `ItemStackRequest` system.
|
||||
- `InventoryTransactionPacket` is no longer sent by the client for "regular" inventory actions. However, it is still sent when dropping items, interacting with blocks, and using items.
|
||||
- Inventory slot and content syncing is now buffered until the end of the tick. This reduces outbound network usage when the client performs multiple transactions in a single tick (e.g. crafting a stack of items).
|
||||
- Renamed some `InventoryManager` internal properties to make them easier to understand.
|
||||
- `TypeConverter->createInventoryAction()` has been removed.
|
||||
- Packet batch limit has been lowered to `100` packets. With the introduction of `ItemStackRequest`, this is more than sufficient for normal gameplay.
|
||||
|
||||
### Other
|
||||
- Use `Vector3::zero()` instead of `new Vector3()` in some places.
|
||||
|
||||
# 4.18.1
|
||||
Released 27th March 2023.
|
||||
|
||||
## General
|
||||
- `RakLibInterface` now logs the name of the currently active session if a crash occurs when processing a packet. This makes it easier to reproduce bugs, which is important to be able to fix them.
|
||||
- Added more detailed debugging information to `InventoryManager->syncSelectedHotbarSlot()`.
|
||||
|
||||
## Fixes
|
||||
- Fixed server crash when attempting to drop more of an item from a stack than available in the inventory.
|
||||
- Fixed packet processing errors when editing writable books.
|
||||
- Fixed packet processing errors when shift-clicking on the recipe book to craft recipes which draw from a large number of inventory slots.
|
@ -43,7 +43,7 @@
|
||||
"pocketmine/classloader": "^0.2.0",
|
||||
"pocketmine/color": "^0.3.0",
|
||||
"pocketmine/errorhandler": "^0.6.0",
|
||||
"pocketmine/locale-data": "~2.18.0",
|
||||
"pocketmine/locale-data": "~2.19.0",
|
||||
"pocketmine/log": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.4.0",
|
||||
"pocketmine/math": "^0.4.0",
|
||||
@ -56,7 +56,7 @@
|
||||
"webmozart/path-util": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.10.6",
|
||||
"phpstan/phpstan": "1.10.7",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
|
41
composer.lock
generated
41
composer.lock
generated
@ -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": "01afa65b40f95ad9378c8cd999e6098d",
|
||||
"content-hash": "956553d402f9c522cfcfe19260af2d2b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -589,16 +589,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/locale-data",
|
||||
"version": "2.18.3",
|
||||
"version": "2.19.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Language.git",
|
||||
"reference": "da25bfe9ee4822a84feb9b7e620c56ad4000aed0"
|
||||
"reference": "71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/da25bfe9ee4822a84feb9b7e620c56ad4000aed0",
|
||||
"reference": "da25bfe9ee4822a84feb9b7e620c56ad4000aed0",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d",
|
||||
"reference": "71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -606,9 +606,9 @@
|
||||
"description": "Language resources used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Language/issues",
|
||||
"source": "https://github.com/pmmp/Language/tree/2.18.3"
|
||||
"source": "https://github.com/pmmp/Language/tree/2.19.5"
|
||||
},
|
||||
"time": "2023-01-17T21:43:36+00:00"
|
||||
"time": "2023-03-19T16:45:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log",
|
||||
@ -1884,16 +1884,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.10.6",
|
||||
"version": "1.10.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "50d089a3e0904b0fe7e2cf2d4fd37d427d64235a"
|
||||
"reference": "b10ceb526d9607903c5b2673f1fc8775dbe48975"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/50d089a3e0904b0fe7e2cf2d4fd37d427d64235a",
|
||||
"reference": "50d089a3e0904b0fe7e2cf2d4fd37d427d64235a",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/b10ceb526d9607903c5b2673f1fc8775dbe48975",
|
||||
"reference": "b10ceb526d9607903c5b2673f1fc8775dbe48975",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1922,8 +1922,11 @@
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://phpstan.org/user-guide/getting-started",
|
||||
"forum": "https://github.com/phpstan/phpstan/discussions",
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.10.6"
|
||||
"security": "https://github.com/phpstan/phpstan/security/policy",
|
||||
"source": "https://github.com/phpstan/phpstan-src"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1939,20 +1942,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-09T16:55:12+00:00"
|
||||
"time": "2023-03-16T15:24:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
"version": "1.3.10",
|
||||
"version": "1.3.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
||||
"reference": "4cc5c6cc38e56bce7ea47c4091814e516d172dc3"
|
||||
"reference": "9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/4cc5c6cc38e56bce7ea47c4091814e516d172dc3",
|
||||
"reference": "4cc5c6cc38e56bce7ea47c4091814e516d172dc3",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c",
|
||||
"reference": "9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1989,9 +1992,9 @@
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.10"
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.11"
|
||||
},
|
||||
"time": "2023-03-02T10:25:13+00:00"
|
||||
"time": "2023-03-25T19:42:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-strict-rules",
|
||||
|
@ -5,7 +5,6 @@ includes:
|
||||
- tests/phpstan/configs/impossible-generics.neon
|
||||
- tests/phpstan/configs/php-bugs.neon
|
||||
- tests/phpstan/configs/phpstan-bugs.neon
|
||||
- tests/phpstan/configs/runtime-type-checks.neon
|
||||
- tests/phpstan/configs/spl-fixed-array-sucks.neon
|
||||
- vendor/phpstan/phpstan-phpunit/extension.neon
|
||||
- vendor/phpstan/phpstan-phpunit/rules.neon
|
||||
|
@ -31,9 +31,9 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "4.18.0-ALPHA2";
|
||||
public const BASE_VERSION = "4.18.1";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "alpha";
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
|
@ -1606,6 +1606,14 @@ final class KnownTranslationFactory{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_BAN_NOREASON, []);
|
||||
}
|
||||
|
||||
public static function pocketmine_disconnect_clientDisconnect() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_CLIENTDISCONNECT, []);
|
||||
}
|
||||
|
||||
public static function pocketmine_disconnect_clientReconnect() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_CLIENTRECONNECT, []);
|
||||
}
|
||||
|
||||
public static function pocketmine_disconnect_error(Translatable|string $error, Translatable|string $errorId) : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR, [
|
||||
"error" => $error,
|
||||
@ -1633,6 +1641,10 @@ final class KnownTranslationFactory{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR_RESPAWN, []);
|
||||
}
|
||||
|
||||
public static function pocketmine_disconnect_error_timeout() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR_TIMEOUT, []);
|
||||
}
|
||||
|
||||
public static function pocketmine_disconnect_incompatibleProtocol(Translatable|string $param0) : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [
|
||||
0 => $param0,
|
||||
|
@ -349,12 +349,15 @@ final class KnownTranslationKeys{
|
||||
public const POCKETMINE_DISCONNECT_BAN_HARDCORE = "pocketmine.disconnect.ban.hardcore";
|
||||
public const POCKETMINE_DISCONNECT_BAN_IP = "pocketmine.disconnect.ban.ip";
|
||||
public const POCKETMINE_DISCONNECT_BAN_NOREASON = "pocketmine.disconnect.ban.noReason";
|
||||
public const POCKETMINE_DISCONNECT_CLIENTDISCONNECT = "pocketmine.disconnect.clientDisconnect";
|
||||
public const POCKETMINE_DISCONNECT_CLIENTRECONNECT = "pocketmine.disconnect.clientReconnect";
|
||||
public const POCKETMINE_DISCONNECT_ERROR = "pocketmine.disconnect.error";
|
||||
public const POCKETMINE_DISCONNECT_ERROR_AUTHENTICATION = "pocketmine.disconnect.error.authentication";
|
||||
public const POCKETMINE_DISCONNECT_ERROR_BADPACKET = "pocketmine.disconnect.error.badPacket";
|
||||
public const POCKETMINE_DISCONNECT_ERROR_INTERNAL = "pocketmine.disconnect.error.internal";
|
||||
public const POCKETMINE_DISCONNECT_ERROR_LOGINTIMEOUT = "pocketmine.disconnect.error.loginTimeout";
|
||||
public const POCKETMINE_DISCONNECT_ERROR_RESPAWN = "pocketmine.disconnect.error.respawn";
|
||||
public const POCKETMINE_DISCONNECT_ERROR_TIMEOUT = "pocketmine.disconnect.error.timeout";
|
||||
public const POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL = "pocketmine.disconnect.incompatibleProtocol";
|
||||
public const POCKETMINE_DISCONNECT_INVALIDSESSION = "pocketmine.disconnect.invalidSession";
|
||||
public const POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE = "pocketmine.disconnect.invalidSession.badSignature";
|
||||
|
@ -407,8 +407,13 @@ class InventoryManager{
|
||||
}
|
||||
|
||||
public function onSlotChange(Inventory $inventory, int $slot) : void{
|
||||
$inventoryEntry = $this->inventories[spl_object_id($inventory)] ?? null;
|
||||
if($inventoryEntry === null){
|
||||
//this can happen when an inventory changed during InventoryCloseEvent, or when a temporary inventory
|
||||
//is cleared before removal.
|
||||
return;
|
||||
}
|
||||
$currentItem = TypeConverter::getInstance()->coreItemStackToNet($inventory->getItem($slot));
|
||||
$inventoryEntry = $this->inventories[spl_object_id($inventory)];
|
||||
$clientSideItem = $inventoryEntry->predictions[$slot] ?? null;
|
||||
if($clientSideItem === null || !$clientSideItem->equals($currentItem)){
|
||||
//no prediction or incorrect - do not associate this with the currently active itemstack request
|
||||
@ -469,7 +474,12 @@ class InventoryManager{
|
||||
}
|
||||
|
||||
public function syncContents(Inventory $inventory) : void{
|
||||
$entry = $this->inventories[spl_object_id($inventory)];
|
||||
$entry = $this->inventories[spl_object_id($inventory)] ?? null;
|
||||
if($entry === null){
|
||||
//this can happen when an inventory changed during InventoryCloseEvent, or when a temporary inventory
|
||||
//is cleared before removal.
|
||||
return;
|
||||
}
|
||||
if($entry->complexSlotMap !== null){
|
||||
$windowId = ContainerIds::UI;
|
||||
}else{
|
||||
@ -566,9 +576,13 @@ class InventoryManager{
|
||||
$playerInventory = $this->player->getInventory();
|
||||
$selected = $playerInventory->getHeldItemIndex();
|
||||
if($selected !== $this->clientSelectedHotbarSlot){
|
||||
$itemStackInfo = $this->getItemStackInfo($playerInventory, $selected);
|
||||
$inventoryEntry = $this->inventories[spl_object_id($playerInventory)] ?? null;
|
||||
if($inventoryEntry === null){
|
||||
throw new AssumptionFailedError("Player inventory should always be tracked");
|
||||
}
|
||||
$itemStackInfo = $inventoryEntry->itemStackInfos[$selected] ?? null;
|
||||
if($itemStackInfo === null){
|
||||
throw new AssumptionFailedError("Player inventory slots should always be tracked");
|
||||
throw new AssumptionFailedError("Untracked player inventory slot $selected");
|
||||
}
|
||||
|
||||
$this->session->sendDataPacket(MobEquipmentPacket::create(
|
||||
|
@ -102,6 +102,7 @@ use pocketmine\player\XboxLivePlayerInfo;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\BinaryDataException;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\utils\ObjectSet;
|
||||
use pocketmine\utils\TextFormat;
|
||||
@ -391,7 +392,7 @@ class NetworkSession{
|
||||
throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName());
|
||||
}
|
||||
}
|
||||
}catch(PacketDecodeException $e){
|
||||
}catch(PacketDecodeException|BinaryDataException $e){
|
||||
$this->logger->logException($e);
|
||||
throw PacketHandlingException::wrap($e, "Packet batch decode error");
|
||||
}
|
||||
|
@ -377,48 +377,73 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
private function handleNormalTransaction(NormalTransactionData $data, int $itemStackRequestId) : bool{
|
||||
//When the ItemStackRequest system is used, this transaction type is only used for dropping items by pressing Q.
|
||||
//When the ItemStackRequest system is used, this transaction type is used for dropping items by pressing Q.
|
||||
//I don't know why they don't just use ItemStackRequest for that too, which already supports dropping items by
|
||||
//clicking them outside an open inventory menu, but for now it is what it is.
|
||||
//Fortunately, this means we can be extremely strict about the validation criteria.
|
||||
//Fortunately, this means we can be much stricter about the validation criteria.
|
||||
|
||||
if(count($data->getActions()) > 2){
|
||||
throw new PacketHandlingException("Expected exactly 2 actions for dropping an item");
|
||||
$actionCount = count($data->getActions());
|
||||
if($actionCount > 2){
|
||||
if($actionCount > 5){
|
||||
throw new PacketHandlingException("Too many actions ($actionCount) in normal inventory transaction");
|
||||
}
|
||||
|
||||
//Due to a bug in the game, this transaction type is still sent when a player edits a book. We don't need
|
||||
//these transactions for editing books, since we have BookEditPacket, so we can just ignore them.
|
||||
$this->session->getLogger()->debug("Ignoring normal inventory transaction with $actionCount actions (drop-item should have exactly 2 actions)");
|
||||
return false;
|
||||
}
|
||||
|
||||
$sourceSlot = null;
|
||||
$clientItemStack = null;
|
||||
$droppedCount = null;
|
||||
|
||||
foreach($data->getActions() as $networkInventoryAction){
|
||||
if($networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_WORLD && $networkInventoryAction->inventorySlot == NetworkInventoryAction::ACTION_MAGIC_SLOT_DROP_ITEM){
|
||||
//drop item - we don't need to validate this, we only care about the count
|
||||
//if the resulting actions don't match the client for some reason, it will trigger an automatic
|
||||
//prediction rollback anyway.
|
||||
//it's technically possible to see this more than once, but a normal client should never do that.
|
||||
$droppedItemStack = $networkInventoryAction->newItem->getItemStack();
|
||||
if($droppedItemStack->getCount() <= 0){
|
||||
$droppedCount = $networkInventoryAction->newItem->getItemStack()->getCount();
|
||||
if($droppedCount <= 0){
|
||||
throw new PacketHandlingException("Expected positive count for dropped item");
|
||||
}
|
||||
$inventory = $this->player->getInventory();
|
||||
|
||||
$heldItem = $inventory->getItemInHand();
|
||||
$heldItemStack = TypeConverter::getInstance()->coreItemStackToNet($heldItem);
|
||||
//because the client doesn't tell us the expected itemstack ID, we have to deep-compare our known
|
||||
//itemstack info with the one the client sent. This is costly, but we don't have any other option :(
|
||||
if($heldItemStack->getCount() < $droppedItemStack->getCount() || !$heldItemStack->equalsWithoutCount($droppedItemStack)){
|
||||
return false;
|
||||
}
|
||||
|
||||
//this modifies $heldItem
|
||||
$droppedItem = $heldItem->pop($droppedItemStack->getCount());
|
||||
|
||||
$builder = new TransactionBuilder();
|
||||
$builder->getInventory($inventory)->setItem($inventory->getHeldItemIndex(), $heldItem);
|
||||
$builder->addAction(new DropItemAction($droppedItem));
|
||||
|
||||
$transaction = new InventoryTransaction($this->player, $builder->generateActions());
|
||||
return $this->executeInventoryTransaction($transaction, $itemStackRequestId);
|
||||
}elseif($networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER && $networkInventoryAction->windowId === ContainerIds::INVENTORY){
|
||||
//mobile players can drop an item from a non-selected hotbar slot
|
||||
$sourceSlot = $networkInventoryAction->inventorySlot;
|
||||
$clientItemStack = $networkInventoryAction->oldItem->getItemStack();
|
||||
}else{
|
||||
$this->session->getLogger()->debug("Unexpected inventory action type $networkInventoryAction->sourceType in drop item transaction");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if($sourceSlot === null || $clientItemStack === null || $droppedCount === null){
|
||||
$this->session->getLogger()->debug("Missing information in drop item transaction, need source slot, client item stack and dropped count");
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new PacketHandlingException("Legacy 'normal' transactions should only be used for dropping items");
|
||||
$inventory = $this->player->getInventory();
|
||||
|
||||
if(!$inventory->slotExists($sourceSlot)){
|
||||
return false; //TODO: size desync??
|
||||
}
|
||||
|
||||
$sourceSlotItem = $inventory->getItem($sourceSlot);
|
||||
if($sourceSlotItem->getCount() < $droppedCount){
|
||||
return false;
|
||||
}
|
||||
$serverItemStack = TypeConverter::getInstance()->coreItemStackToNet($sourceSlotItem);
|
||||
//because the client doesn't tell us the expected itemstack ID, we have to deep-compare our known
|
||||
//itemstack info with the one the client sent. This is costly, but we don't have any other option :(
|
||||
if(!$serverItemStack->equals($clientItemStack)){
|
||||
return false;
|
||||
}
|
||||
|
||||
//this modifies $sourceSlotItem
|
||||
$droppedItem = $sourceSlotItem->pop($droppedCount);
|
||||
|
||||
$builder = new TransactionBuilder();
|
||||
$builder->getInventory($inventory)->setItem($sourceSlot, $sourceSlotItem);
|
||||
$builder->addAction(new DropItemAction($droppedItem));
|
||||
|
||||
$transaction = new InventoryTransaction($this->player, $builder->generateActions());
|
||||
return $this->executeInventoryTransaction($transaction, $itemStackRequestId);
|
||||
}
|
||||
|
||||
private function handleUseItemTransaction(UseItemTransactionData $data) : bool{
|
||||
@ -533,8 +558,17 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
private function handleSingleItemStackRequest(ItemStackRequest $request) : ItemStackResponse{
|
||||
if(count($request->getActions()) > 20){
|
||||
//TODO: we can probably lower this limit, but this will do for now
|
||||
if(count($request->getActions()) > 60){
|
||||
//recipe book auto crafting can affect all slots of the inventory when consuming inputs or producing outputs
|
||||
//this means there could be as many as 50 CraftingConsumeInput actions or Place (taking the result) actions
|
||||
//in a single request (there are certain ways items can be arranged which will result in the same stack
|
||||
//being taken from multiple times, but this is behaviour with a calculable limit)
|
||||
//this means there SHOULD be AT MOST 53 actions in a single request, but 60 is a nice round number.
|
||||
//n64Stacks = ?
|
||||
//n1Stacks = 45 - n64Stacks
|
||||
//nItemsRequiredFor1Craft = 9
|
||||
//nResults = floor((n1Stacks + (n64Stacks * 64)) / nItemsRequiredFor1Craft)
|
||||
//nTakeActionsTotal = floor(64 / nResults) + max(1, 64 % nResults) + ((nResults * nItemsRequiredFor1Craft) - (n64Stacks * 64))
|
||||
throw new PacketHandlingException("Too many actions in ItemStackRequest");
|
||||
}
|
||||
$executor = new ItemStackRequestExecutor($this->player, $this->inventoryManager, $request);
|
||||
|
@ -192,6 +192,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||
$session = $this->sessions[$sessionId];
|
||||
$address = $session->getIp();
|
||||
$buf = substr($packet, 1);
|
||||
$name = $session->getDisplayName();
|
||||
try{
|
||||
$session->handleEncoded($buf);
|
||||
}catch(PacketHandlingException $e){
|
||||
@ -204,6 +205,10 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||
$logger->debug(implode("\n", Utils::printableExceptionInfo($e)));
|
||||
$session->disconnect("Packet processing error (Error ID: $errorId)");
|
||||
$this->interface->blockAddress($address, 5);
|
||||
}catch(\Throwable $e){
|
||||
//record the name of the player who caused the crash, to make it easier to find the reproducing steps
|
||||
$this->server->getLogger()->emergency("Crash occurred while handling a packet from session: $name");
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/block/BaseBanner.php
|
||||
|
||||
-
|
||||
message: "#^Comparison operation \"\\<\" between int\\<1, max\\> and 1 is always false\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/console/ConsoleCommandSender.php
|
||||
|
||||
-
|
||||
message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#"
|
||||
count: 1
|
||||
@ -35,21 +30,11 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/raklib/SnoozeAwarePthreadsChannelWriter.php
|
||||
|
||||
-
|
||||
message: "#^Comparison operation \"\\<\" between int\\<1, max\\> and 1 is always false\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/player/Player.php
|
||||
|
||||
-
|
||||
message: "#^Dead catch \\- RuntimeException is never thrown in the try block\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/plugin/PluginManager.php
|
||||
|
||||
-
|
||||
message: "#^Offset \\(int\\|string\\) on array\\<pocketmine\\\\plugin\\\\Plugin\\> in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/plugin/PluginManager.php
|
||||
|
||||
-
|
||||
message: "#^Static property pocketmine\\\\scheduler\\\\AsyncTask\\:\\:\\$threadLocalStorage \\(ArrayObject\\<int, array\\<string, mixed\\>\\>\\|null\\) does not accept non\\-empty\\-array\\<int, non\\-empty\\-array\\<string, mixed\\>\\>\\|ArrayObject\\<int, array\\<string, mixed\\>\\>\\.$#"
|
||||
count: 1
|
||||
@ -65,11 +50,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/thread/Worker.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#"
|
||||
count: 2
|
||||
path: ../../../src/world/format/io/region/RegionLoader.php
|
||||
|
||||
-
|
||||
message: "#^Casting to int something that's already int\\.$#"
|
||||
count: 1
|
||||
|
@ -1,12 +0,0 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Casting to int something that's already int\\.$#"
|
||||
count: 2
|
||||
path: ../../../src/item/Item.php
|
||||
|
||||
-
|
||||
message: "#^Instanceof between pocketmine\\\\nbt\\\\tag\\\\CompoundTag and pocketmine\\\\nbt\\\\tag\\\\CompoundTag will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/handler/InGamePacketHandler.php
|
||||
|
Reference in New Issue
Block a user