From 08f9873c320d70da996cff276bf1a2cc9ba36aae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Nov 2023 18:30:03 +0000 Subject: [PATCH 01/11] Update build/php submodule to pmmp/PHP-Binaries@3c3c483baac5cb90dff057dfff4388b1dc3f217c --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index a34e48e7d..3c3c483ba 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit a34e48e7da753b633ffaa4a4f9516eae4bb97baa +Subproject commit 3c3c483baac5cb90dff057dfff4388b1dc3f217c From c3c81b09e828ccb143dbeb26cd650b7daaa29afa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Nov 2023 18:51:17 +0000 Subject: [PATCH 02/11] Release 5.8.2 --- changelogs/5.8.md | 19 +++++++++++++++++++ src/VersionInfo.php | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/changelogs/5.8.md b/changelogs/5.8.md index 0e712a092..7ae64742c 100644 --- a/changelogs/5.8.md +++ b/changelogs/5.8.md @@ -117,3 +117,22 @@ Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if - Removed code generation step for `RuntimeDataDescriber` enum serialization. All described enums now use PHP 8.1 native enums, which can be described without codegen using `RuntimeDataDescriber->enum()`. - Added `DeprecatedLegacyEnumAccessRule` custom PHPStan rule to flag legacy `EnumTrait` case accessors. - Cleaned up remaining hardcoded `Config` keys in `SetupWizard`. These usages now use auto-generated constants like the rest of the codebase. + +# 5.8.2 +Released 9th November 2023. + +## Performance +- Improved performance of small packet zero-compression (unintended use of slow zlib compressor instead of fast libdeflate one). + - This affected the majority of outbound packets, as most packets are below the 256-byte threshold for compression. + - This faster method is over 20x faster than the old method, producing noticeable performance gains for large servers. + +## Fixes +- Fixed melons and pumpkins not growing. +- Fixed melon and pumpkin stems not attaching to the grown melon/pumpkin. +- Fixed iron and gold ores not being affected by the Fortune enchantment. +- Fixed ancient debris burning in lava. +- Fixed sign (front) text loading from vanilla world saves (back text is not yet supported). + +## Internals +- Removed bogus optimization from `tools/generate-blockstate-upgrade-schema.php` that could cause incorrect `remappedStates` generation when some of the states stayed under the old ID. +- Fixed possible crash in `BlockStateUpgrader` name flattening rule handling with invalid blockstate NBT data. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index e24d43494..8c18ab6a6 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -32,7 +32,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "5.8.2"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; /** From 93699024da47e55b8e2cbe93aa67c2ce792de348 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Nov 2023 18:51:20 +0000 Subject: [PATCH 03/11] 5.8.3 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 8c18ab6a6..e0f4ca4f3 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.8.2"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "5.8.3"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; /** From 269b3d89a29628443091d0ffe2a71e73b8e6f6a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Nov 2023 19:03:12 +0000 Subject: [PATCH 04/11] Update build/php submodule to pmmp/PHP-Binaries@39885cf24826773bc3a0e8134e04a2032e97f477 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 3c3c483ba..39885cf24 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 3c3c483baac5cb90dff057dfff4388b1dc3f217c +Subproject commit 39885cf24826773bc3a0e8134e04a2032e97f477 From 7a4cf8ef688eef9d342b47cc7e5e4bc7320dbce3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Nov 2023 19:04:53 +0000 Subject: [PATCH 05/11] Prepare for PHP 8.2 as primary version --- .github/workflows/discord-release-notify.yml | 2 +- .github/workflows/draft-release.yml | 2 +- .github/workflows/main.yml | 4 ++-- BUILDING.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/discord-release-notify.yml b/.github/workflows/discord-release-notify.yml index f73113098..ad30aa4f2 100644 --- a/.github/workflows/discord-release-notify.yml +++ b/.github/workflows/discord-release-notify.yml @@ -15,7 +15,7 @@ jobs: - name: Setup PHP and tools uses: shivammathur/setup-php@2.27.1 with: - php-version: 8.1 + php-version: 8.2 - name: Restore Composer package cache uses: actions/cache@v3 diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 03bfedc89..d4f68ee0b 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: [8.1] + php-version: [8.2] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c57cecb84..8bf6fd7d6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -175,8 +175,8 @@ jobs: - name: Setup PHP and tools uses: shivammathur/setup-php@2.27.1 with: - php-version: 8.1 - tools: php-cs-fixer:3.17 + php-version: 8.2 + tools: php-cs-fixer:3.38 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/BUILDING.md b/BUILDING.md index 95197de6b..986f098e2 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -2,7 +2,7 @@ ## Pre-requisites - A bash shell (git bash is sufficient for Windows) - [`git`](https://git-scm.com) available in your shell -- PHP 8.1 or newer available in your shell +- PHP 8.2 or newer available in your shell - [`composer`](https://getcomposer.org) available in your shell ## Custom PHP binaries From c44758f36cad5ce33d6bbbcea6e43d97aeff6371 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Nov 2023 15:26:02 +0000 Subject: [PATCH 06/11] StringToItemParser: added pitcher_plant and pitcher_pod it seems a bit weird to map pitcher_pod to PITCHER_CROP(). Perhaps this wasn't implemented correctly. --- src/item/StringToItemParser.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index d4f242621..14c93cb5e 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -868,6 +868,8 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("pink_petals", fn() => Blocks::PINK_PETALS()); $result->registerBlock("pink_tulip", fn() => Blocks::PINK_TULIP()); $result->registerBlock("piglin_head", fn() => Blocks::MOB_HEAD()->setMobHeadType(MobHeadType::PIGLIN)); + $result->registerBlock("pitcher_plant", fn() => Blocks::PITCHER_PLANT()); + $result->registerBlock("pitcher_pod", fn() => Blocks::PITCHER_CROP()); $result->registerBlock("plank", fn() => Blocks::OAK_PLANKS()); $result->registerBlock("planks", fn() => Blocks::OAK_PLANKS()); $result->registerBlock("player_head", fn() => Blocks::MOB_HEAD()->setMobHeadType(MobHeadType::PLAYER)); From 22b10e4cb0d47ef39588066e61ec144a6c23c42e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Nov 2023 15:36:35 +0000 Subject: [PATCH 07/11] Timings: Stop using BREAKDOWN group with tree timings, the breakdown is actually pretty annoying, since it makes it hard to find a timer in the aggregate lists. --- src/timings/Timings.php | 85 ++++++++++++++++------------------ src/timings/TimingsHandler.php | 2 +- src/world/WorldTimings.php | 2 +- 3 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/timings/Timings.php b/src/timings/Timings.php index 0d8a256de..61a8bbc92 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -35,6 +35,7 @@ use function get_class; use function str_starts_with; abstract class Timings{ + public const GROUP_MINECRAFT = "Minecraft"; public const GROUP_BREAKDOWN = "Minecraft - Breakdown"; private static bool $initialized = false; @@ -134,8 +135,8 @@ abstract class Timings{ self::$initialized = true; self::$fullTick = new TimingsHandler("Full Server Tick"); - self::$serverTick = new TimingsHandler("Server Tick Update Cycle", self::$fullTick, group: self::GROUP_BREAKDOWN); - self::$serverInterrupts = new TimingsHandler("Server Mid-Tick Processing", self::$fullTick, group: self::GROUP_BREAKDOWN); + self::$serverTick = new TimingsHandler("Server Tick Update Cycle", self::$fullTick); + self::$serverInterrupts = new TimingsHandler("Server Mid-Tick Processing", self::$fullTick); self::$memoryManager = new TimingsHandler("Memory Manager"); self::$garbageCollector = new TimingsHandler("Garbage Collector", self::$memoryManager); self::$titleTick = new TimingsHandler("Console Title Tick"); @@ -143,51 +144,51 @@ abstract class Timings{ self::$connection = new TimingsHandler("Connection Handler"); self::$playerNetworkSend = new TimingsHandler("Player Network Send", self::$connection); - self::$playerNetworkSendCompress = new TimingsHandler("Player Network Send - Compression", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); - self::$playerNetworkSendCompressBroadcast = new TimingsHandler("Player Network Send - Compression (Broadcast)", self::$playerNetworkSendCompress, group: self::GROUP_BREAKDOWN); - self::$playerNetworkSendCompressSessionBuffer = new TimingsHandler("Player Network Send - Compression (Session Buffer)", self::$playerNetworkSendCompress, group: self::GROUP_BREAKDOWN); - self::$playerNetworkSendEncrypt = new TimingsHandler("Player Network Send - Encryption", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); - self::$playerNetworkSendInventorySync = new TimingsHandler("Player Network Send - Inventory Sync", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); - self::$playerNetworkSendPreSpawnGameData = new TimingsHandler("Player Network Send - Pre-Spawn Game Data", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); + self::$playerNetworkSendCompress = new TimingsHandler("Player Network Send - Compression", self::$playerNetworkSend); + self::$playerNetworkSendCompressBroadcast = new TimingsHandler("Player Network Send - Compression (Broadcast)", self::$playerNetworkSendCompress); + self::$playerNetworkSendCompressSessionBuffer = new TimingsHandler("Player Network Send - Compression (Session Buffer)", self::$playerNetworkSendCompress); + self::$playerNetworkSendEncrypt = new TimingsHandler("Player Network Send - Encryption", self::$playerNetworkSend); + self::$playerNetworkSendInventorySync = new TimingsHandler("Player Network Send - Inventory Sync", self::$playerNetworkSend); + self::$playerNetworkSendPreSpawnGameData = new TimingsHandler("Player Network Send - Pre-Spawn Game Data", self::$playerNetworkSend); self::$playerNetworkReceive = new TimingsHandler("Player Network Receive", self::$connection); - self::$playerNetworkReceiveDecompress = new TimingsHandler("Player Network Receive - Decompression", self::$playerNetworkReceive, group: self::GROUP_BREAKDOWN); - self::$playerNetworkReceiveDecrypt = new TimingsHandler("Player Network Receive - Decryption", self::$playerNetworkReceive, group: self::GROUP_BREAKDOWN); + self::$playerNetworkReceiveDecompress = new TimingsHandler("Player Network Receive - Decompression", self::$playerNetworkReceive); + self::$playerNetworkReceiveDecrypt = new TimingsHandler("Player Network Receive - Decryption", self::$playerNetworkReceive); - self::$broadcastPackets = new TimingsHandler("Broadcast Packets", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); + self::$broadcastPackets = new TimingsHandler("Broadcast Packets", self::$playerNetworkSend); self::$playerMove = new TimingsHandler("Player Movement"); self::$playerChunkOrder = new TimingsHandler("Player Order Chunks"); - self::$playerChunkSend = new TimingsHandler("Player Network Send - Chunks", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); + self::$playerChunkSend = new TimingsHandler("Player Network Send - Chunks", self::$playerNetworkSend); self::$scheduler = new TimingsHandler("Scheduler"); self::$serverCommand = new TimingsHandler("Server Command"); self::$permissibleCalculation = new TimingsHandler("Permissible Calculation"); - self::$permissibleCalculationDiff = new TimingsHandler("Permissible Calculation - Diff", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN); - self::$permissibleCalculationCallback = new TimingsHandler("Permissible Calculation - Callbacks", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN); + self::$permissibleCalculationDiff = new TimingsHandler("Permissible Calculation - Diff", self::$permissibleCalculation); + self::$permissibleCalculationCallback = new TimingsHandler("Permissible Calculation - Callbacks", self::$permissibleCalculation); self::$syncPlayerDataLoad = new TimingsHandler("Player Data Load"); self::$syncPlayerDataSave = new TimingsHandler("Player Data Save"); - self::$entityMove = new TimingsHandler("Entity Movement", group: self::GROUP_BREAKDOWN); - self::$entityMoveCollision = new TimingsHandler("Entity Movement - Collision Checks", self::$entityMove, group: self::GROUP_BREAKDOWN); + self::$entityMove = new TimingsHandler("Entity Movement"); + self::$entityMoveCollision = new TimingsHandler("Entity Movement - Collision Checks", self::$entityMove); - self::$projectileMove = new TimingsHandler("Projectile Movement", self::$entityMove, group: self::GROUP_BREAKDOWN); - self::$projectileMoveRayTrace = new TimingsHandler("Projectile Movement - Ray Tracing", self::$projectileMove, group: self::GROUP_BREAKDOWN); + self::$projectileMove = new TimingsHandler("Projectile Movement", self::$entityMove); + self::$projectileMoveRayTrace = new TimingsHandler("Projectile Movement - Ray Tracing", self::$projectileMove); - self::$playerCheckNearEntities = new TimingsHandler("checkNearEntities", group: self::GROUP_BREAKDOWN); - self::$entityBaseTick = new TimingsHandler("Entity Base Tick", group: self::GROUP_BREAKDOWN); - self::$livingEntityBaseTick = new TimingsHandler("Entity Base Tick - Living", group: self::GROUP_BREAKDOWN); - self::$itemEntityBaseTick = new TimingsHandler("Entity Base Tick - ItemEntity", group: self::GROUP_BREAKDOWN); + self::$playerCheckNearEntities = new TimingsHandler("checkNearEntities"); + self::$entityBaseTick = new TimingsHandler("Entity Base Tick"); + self::$livingEntityBaseTick = new TimingsHandler("Entity Base Tick - Living"); + self::$itemEntityBaseTick = new TimingsHandler("Entity Base Tick - ItemEntity"); - self::$schedulerSync = new TimingsHandler("Scheduler - Sync Tasks", group: self::GROUP_BREAKDOWN); + self::$schedulerSync = new TimingsHandler("Scheduler - Sync Tasks"); - self::$schedulerAsync = new TimingsHandler("Scheduler - Async Tasks", group: self::GROUP_BREAKDOWN); - self::$asyncTaskProgressUpdateParent = new TimingsHandler("Async Tasks - Progress Updates", self::$schedulerAsync, group: self::GROUP_BREAKDOWN); - self::$asyncTaskCompletionParent = new TimingsHandler("Async Tasks - Completion Handlers", self::$schedulerAsync, group: self::GROUP_BREAKDOWN); - self::$asyncTaskErrorParent = new TimingsHandler("Async Tasks - Error Handlers", self::$schedulerAsync, group: self::GROUP_BREAKDOWN); + self::$schedulerAsync = new TimingsHandler("Scheduler - Async Tasks"); + self::$asyncTaskProgressUpdateParent = new TimingsHandler("Async Tasks - Progress Updates", self::$schedulerAsync); + self::$asyncTaskCompletionParent = new TimingsHandler("Async Tasks - Completion Handlers", self::$schedulerAsync); + self::$asyncTaskErrorParent = new TimingsHandler("Async Tasks - Error Handlers", self::$schedulerAsync); - self::$playerCommand = new TimingsHandler("Player Command", group: self::GROUP_BREAKDOWN); - self::$craftingDataCacheRebuild = new TimingsHandler("Build CraftingDataPacket Cache", group: self::GROUP_BREAKDOWN); + self::$playerCommand = new TimingsHandler("Player Command"); + self::$craftingDataCacheRebuild = new TimingsHandler("Build CraftingDataPacket Cache"); } @@ -229,7 +230,7 @@ abstract class Timings{ }else{ $displayName = self::shortenCoreClassName($entity::class, "pocketmine\\entity\\"); } - self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName, group: self::GROUP_BREAKDOWN); + self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName); } return self::$entityTypeTimingMap[$entity::class]; @@ -239,8 +240,7 @@ abstract class Timings{ self::init(); if(!isset(self::$tileEntityTypeTimingMap[$tile::class])){ self::$tileEntityTypeTimingMap[$tile::class] = new TimingsHandler( - "Block Entity Tick - " . self::shortenCoreClassName($tile::class, "pocketmine\\block\\tile\\"), - group: self::GROUP_BREAKDOWN + "Block Entity Tick - " . self::shortenCoreClassName($tile::class, "pocketmine\\block\\tile\\") ); } @@ -250,7 +250,7 @@ abstract class Timings{ public static function getReceiveDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{ self::init(); if(!isset(self::$packetReceiveTimingMap[$pk::class])){ - self::$packetReceiveTimingMap[$pk::class] = new TimingsHandler("Receive - " . $pk->getName(), self::$playerNetworkReceive, group: self::GROUP_BREAKDOWN); + self::$packetReceiveTimingMap[$pk::class] = new TimingsHandler("Receive - " . $pk->getName(), self::$playerNetworkReceive); } return self::$packetReceiveTimingMap[$pk::class]; @@ -259,31 +259,28 @@ abstract class Timings{ public static function getDecodeDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{ return self::$packetDecodeTimingMap[$pk::class] ??= new TimingsHandler( "Decode - " . $pk->getName(), - self::getReceiveDataPacketTimings($pk), - group: self::GROUP_BREAKDOWN + self::getReceiveDataPacketTimings($pk) ); } public static function getHandleDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{ return self::$packetHandleTimingMap[$pk::class] ??= new TimingsHandler( "Handler - " . $pk->getName(), - self::getReceiveDataPacketTimings($pk), - group: self::GROUP_BREAKDOWN + self::getReceiveDataPacketTimings($pk) ); } public static function getEncodeDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{ return self::$packetEncodeTimingMap[$pk::class] ??= new TimingsHandler( "Encode - " . $pk->getName(), - self::getSendDataPacketTimings($pk), - group: self::GROUP_BREAKDOWN + self::getSendDataPacketTimings($pk) ); } public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{ self::init(); if(!isset(self::$packetSendTimingMap[$pk::class])){ - self::$packetSendTimingMap[$pk::class] = new TimingsHandler("Send - " . $pk->getName(), self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); + self::$packetSendTimingMap[$pk::class] = new TimingsHandler("Send - " . $pk->getName(), self::$playerNetworkSend); } return self::$packetSendTimingMap[$pk::class]; @@ -292,7 +289,7 @@ abstract class Timings{ public static function getCommandDispatchTimings(string $commandName) : TimingsHandler{ self::init(); - return self::$commandTimingMap[$commandName] ??= new TimingsHandler("Command - " . $commandName, group: self::GROUP_BREAKDOWN); + return self::$commandTimingMap[$commandName] ??= new TimingsHandler("Command - " . $commandName); } public static function getEventTimings(Event $event) : TimingsHandler{ @@ -316,7 +313,7 @@ abstract class Timings{ return self::$eventHandlers[$event][$handlerName]; } - public static function getAsyncTaskProgressUpdateTimings(AsyncTask $task, string $group = self::GROUP_BREAKDOWN) : TimingsHandler{ + public static function getAsyncTaskProgressUpdateTimings(AsyncTask $task, string $group = self::GROUP_MINECRAFT) : TimingsHandler{ $taskClass = $task::class; if(!isset(self::$asyncTaskProgressUpdate[$taskClass])){ self::init(); @@ -330,7 +327,7 @@ abstract class Timings{ return self::$asyncTaskProgressUpdate[$taskClass]; } - public static function getAsyncTaskCompletionTimings(AsyncTask $task, string $group = self::GROUP_BREAKDOWN) : TimingsHandler{ + public static function getAsyncTaskCompletionTimings(AsyncTask $task, string $group = self::GROUP_MINECRAFT) : TimingsHandler{ $taskClass = $task::class; if(!isset(self::$asyncTaskCompletion[$taskClass])){ self::init(); @@ -344,7 +341,7 @@ abstract class Timings{ return self::$asyncTaskCompletion[$taskClass]; } - public static function getAsyncTaskErrorTimings(AsyncTask $task, string $group = self::GROUP_BREAKDOWN) : TimingsHandler{ + public static function getAsyncTaskErrorTimings(AsyncTask $task, string $group = self::GROUP_MINECRAFT) : TimingsHandler{ $taskClass = $task::class; if(!isset(self::$asyncTaskError[$taskClass])){ self::init(); diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index ba6c3cfea..574dd6d2b 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -120,7 +120,7 @@ class TimingsHandler{ public function __construct( private string $name, private ?TimingsHandler $parent = null, - private string $group = "Minecraft" + private string $group = Timings::GROUP_MINECRAFT ){} public function getName() : string{ return $this->name; } diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index 2d3a2090c..191dee778 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -66,7 +66,7 @@ class WorldTimings{ private static function newTimer(string $worldName, string $timerName) : TimingsHandler{ $aggregator = self::$aggregators[$timerName] ??= new TimingsHandler("Worlds - $timerName"); //displayed in Minecraft primary table - return new TimingsHandler("$worldName - $timerName", $aggregator, Timings::GROUP_BREAKDOWN); + return new TimingsHandler("$worldName - $timerName", $aggregator); } public function __construct(World $world){ From 58ea94bab8b2644cf60d5804075b976e1fd9f65a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Nov 2023 15:41:17 +0000 Subject: [PATCH 08/11] ... --- src/world/WorldTimings.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index 191dee778..9a43828c2 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world; -use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; class WorldTimings{ From c2189bc2df5fd6e2477b63698e341db4adf03ce5 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 10 Nov 2023 16:16:49 +0000 Subject: [PATCH 09/11] Update README.md [ci skip] --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 9f8c6a326..bbecbe72b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,25 @@ GitHub release (latest by SemVer)

+## What is this? +PocketMine-MP is a highly customisable server software for Minecraft: Bedrock Edition, built from scratch in PHP, with over 10 years of history. + +If you're looking to create a Minecraft: Bedrock server with **custom functionality**, look no further. + +- 🧩 **Powerful plugin API** - extend and customise gameplay as you see fit +- 🗺️ **Rich ecosystem** and **large developer community** - find plugins easily and learn to develop your own +- 🌐 **Multi-world support** - offer a more varied game experience to players without transferring them to other server nodes +- 🏎️ **Performance** - get 100+ players onto one server (depending on hardware and plugins) +- ⤴️ **Continuously updated** - new Minecraft versions are usually supported within days + +## :x: PocketMine-MP is NOT a vanilla Minecraft server software. +**It is poorly suited to hosting vanilla survival servers.** +It doesn't have many features from the vanilla game, such as vanilla world generation, redstone, mob AI, and various other things. + +If you just want to play **vanilla survival multiplayer**, consider using the [official Minecraft: Bedrock server software](https://minecraft.net/download/server/bedrock) instead of PocketMine-MP. + +If that's not an option for you, you may be able to add some of PocketMine-MP's missing features using plugins from [Poggit](https://poggit.pmmp.io/plugins), or write plugins to implement them yourself. + ## Getting started - [Documentation](http://pmmp.readthedocs.org/) - [Installation instructions](https://pmmp.readthedocs.io/en/rtfd/installation.html) From bd43ff657952349859aaf24d576791ce69ae0fc4 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 10 Nov 2023 16:27:57 +0000 Subject: [PATCH 10/11] Update README.md [ci skip] --- README.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bbecbe72b..b9e2e1888 100644 --- a/README.md +++ b/README.md @@ -39,31 +39,42 @@ If you just want to play **vanilla survival multiplayer**, consider using the [o If that's not an option for you, you may be able to add some of PocketMine-MP's missing features using plugins from [Poggit](https://poggit.pmmp.io/plugins), or write plugins to implement them yourself. -## Getting started +## Getting Started - [Documentation](http://pmmp.readthedocs.org/) - [Installation instructions](https://pmmp.readthedocs.io/en/rtfd/installation.html) - [Docker image](https://github.com/pmmp/PocketMine-MP/pkgs/container/pocketmine-mp) - [Plugin repository](https://poggit.pmmp.io/plugins) ## Community & Support -- [Forums](https://forums.pmmp.io/) -- [Discord](https://discord.gg/bmSAZBG) -- [StackOverflow](https://stackoverflow.com/tags/pocketmine) +Join our [Discord](https://discord.gg/bmSAZBG) server to chat with other users and developers. + +You can also post questions on [StackOverflow](https://stackoverflow.com/tags/pocketmine) under the tag `pocketmine`. + +## Developing Plugins +If you want to write your own plugins, the following resources may be useful. +Don't forget you can always ask our community if you need help. -## For developers - * [Building and running from source](BUILDING.md) * [Developer documentation](https://devdoc.pmmp.io) - General documentation for PocketMine-MP plugin developers * [Latest release API documentation](https://apidoc.pmmp.io) - Doxygen API documentation generated for each release * [Latest bleeding-edge API documentation](https://apidoc-dev.pmmp.io) - Doxygen API documentation generated weekly from `major-next` branch * [DevTools](https://github.com/pmmp/DevTools/) - Development tools plugin for creating plugins * [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features + +## Contributing to PocketMine-MP +PocketMine-MP accepts community contributions! The following resources will be useful if you want to contribute to PocketMine-MP. + * [Building and running PocketMine-MP from source](BUILDING.md) * [Contributing Guidelines](CONTRIBUTING.md) ## Donate -- Bitcoin Cash (BCH): `qq3r46hn6ljnhnqnfwxt5pg3g447eq9jhvw5ddfear` +PocketMine-MP is free, but it requires a lot of time and effort from unpaid volunteers to develop. Donations enable us to keep delivering support for new versions and adding features your players love. + +You can support development using the following methods: + +- [Patreon](https://www.patreon.com/pocketminemp) - Bitcoin (BTC): `171u8K9e4FtU6j3e5sqNoxKUgEw9qWQdRV` - Stellar Lumens (XLM): `GAAC5WZ33HCTE3BFJFZJXONMEIBNHFLBXM2HJVAZHXXPYA3HP5XPPS7T` -- [Patreon](https://www.patreon.com/pocketminemp) + +Thanks for your support! ## Licensing information This project is licensed under LGPL-3.0. Please see the [LICENSE](/LICENSE) file for details. From 77590fb63a2ba159af49d491a1cae3b803b261f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Nov 2023 11:12:00 +0000 Subject: [PATCH 11/11] Server: fixed prepareBatch() not being marked as internal --- src/Server.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Server.php b/src/Server.php index 6b3a91543..f4d4a0958 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1356,6 +1356,7 @@ class Server{ } /** + * @internal * Broadcasts a list of packets in a batch to a list of players * * @param bool|null $sync Compression on the main thread (true) or workers (false). Default is automatic (null).