From 5a98b08ee8dc8ff14862cd83d2e4af9d212fefc2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Apr 2022 16:48:18 +0100 Subject: [PATCH 01/11] Fixed several crashes on bad data due to inadequate TAG_List type checks --- src/block/tile/ContainerTrait.php | 2 +- src/item/Banner.php | 3 ++- src/item/Item.php | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 2abe134f2..ba8ab084a 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -44,7 +44,7 @@ trait ContainerTrait{ abstract public function getRealInventory(); protected function loadItems(CompoundTag $tag) : void{ - if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag){ + if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){ $inventory = $this->getRealInventory(); $listeners = $inventory->getListeners()->toArray(); $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization diff --git a/src/item/Banner.php b/src/item/Banner.php index 18d0f1081..ea7320b79 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -29,6 +29,7 @@ use pocketmine\block\utils\BannerPatternLayer; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\BannerPatternTypeIdMap; use pocketmine\data\bedrock\DyeColorIdMap; +use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use function count; @@ -98,7 +99,7 @@ class Banner extends ItemBlockWallOrFloor{ $colorIdMap = DyeColorIdMap::getInstance(); $patternIdMap = BannerPatternTypeIdMap::getInstance(); $patterns = $tag->getListTag(self::TAG_PATTERNS); - if($patterns !== null){ + if($patterns !== null && $patterns->getTagType() === NBT::TAG_Compound){ /** @var CompoundTag $t */ foreach($patterns as $t){ $patternColor = $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR)) ?? DyeColor::BLACK(); //TODO: missing pattern colour should be an error diff --git a/src/item/Item.php b/src/item/Item.php index b490ac6b1..9c1119db3 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -306,7 +306,7 @@ class Item implements \JsonSerializable{ $this->canPlaceOn = []; $canPlaceOn = $tag->getListTag("CanPlaceOn"); - if($canPlaceOn !== null){ + if($canPlaceOn !== null && $canPlaceOn->getTagType() === NBT::TAG_String){ /** @var StringTag $entry */ foreach($canPlaceOn as $entry){ $this->canPlaceOn[$entry->getValue()] = $entry->getValue(); @@ -314,7 +314,7 @@ class Item implements \JsonSerializable{ } $this->canDestroy = []; $canDestroy = $tag->getListTag("CanDestroy"); - if($canDestroy !== null){ + if($canDestroy !== null && $canDestroy->getTagType() === NBT::TAG_String){ /** @var StringTag $entry */ foreach($canDestroy as $entry){ $this->canDestroy[$entry->getValue()] = $entry->getValue(); From 1d314ad4cef2a0f505a22f86ca29e26463b606da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Apr 2022 16:53:11 +0100 Subject: [PATCH 02/11] Release 4.2.9 --- changelogs/4.2.md | 6 ++++++ src/VersionInfo.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelogs/4.2.md b/changelogs/4.2.md index 96f849148..840b94498 100644 --- a/changelogs/4.2.md +++ b/changelogs/4.2.md @@ -107,3 +107,9 @@ Released 17th April 2022. - Fixed a memory leak in RakLib which could result in a server crash when players stay online for a long time. - Fixed server crash when attempting to load a corrupted empty resource pack. - Fixed users with the same name with differerently cased letters being able to duplicate items (userdata is matched by case-insensitive name). + +# 4.2.9 +Released 19th April 2022. + +## Fixes +- Fixed several potential crashes when deserializing item NBT (due to insufficient validation of input data). diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 36b0c4893..6228b9c63 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 = "4.2.9"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; private function __construct(){ From 624a7dff16589734d017fd76f590da24796e88db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Apr 2022 16:53:12 +0100 Subject: [PATCH 03/11] 4.2.10 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 6228b9c63..1bb0cdc2d 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 = "4.2.9"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.2.10"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; private function __construct(){ From df33e179e5d3ff13b56a2d7060bf592b0f797258 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 13:01:05 +0100 Subject: [PATCH 04/11] Player: fixed chat newlines denial-of-service vulnerability irresponsibly reported in #4974 closes #4974 --- src/player/Player.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index e27b72500..cb9ef0a5b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1377,8 +1377,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function chat(string $message) : bool{ $this->removeCurrentWindow(); + //Fast length check, to make sure we don't get hung trying to explode MBs of string ... + $maxTotalLength = $this->messageCounter * (self::MAX_CHAT_BYTE_LENGTH + 1); + if(strlen($message) > $maxTotalLength){ + return false; + } + $message = TextFormat::clean($message, false); - foreach(explode("\n", $message) as $messagePart){ + foreach(explode("\n", $message, $this->messageCounter + 1) as $messagePart){ if(trim($messagePart) !== "" && strlen($messagePart) <= self::MAX_CHAT_BYTE_LENGTH && mb_strlen($messagePart, 'UTF-8') <= self::MAX_CHAT_CHAR_LENGTH && $this->messageCounter-- > 0){ if(strpos($messagePart, './') === 0){ $messagePart = substr($messagePart, 1); From 3339225fe82a5440bba0b6d2c109555ba8659f5f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 13:03:25 +0100 Subject: [PATCH 05/11] Release 4.2.10 --- changelogs/4.2.md | 6 ++++++ src/VersionInfo.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelogs/4.2.md b/changelogs/4.2.md index 840b94498..1e10b6041 100644 --- a/changelogs/4.2.md +++ b/changelogs/4.2.md @@ -113,3 +113,9 @@ Released 19th April 2022. ## Fixes - Fixed several potential crashes when deserializing item NBT (due to insufficient validation of input data). + +# 4.2.10 +Released 20th April 2022. + +## Fixes +- Fixed performance issue when chat messages received from the client contain many newlines. This security vulnerability was disclosed publicly necessitating a priority fix. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 1bb0cdc2d..9f2e46a79 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 = "4.2.10"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; private function __construct(){ From e0d4bd985ef659b01769a0c77abf495d11fb87e3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 13:03:25 +0100 Subject: [PATCH 06/11] 4.2.11 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 9f2e46a79..a76bc2cf7 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 = "4.2.10"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.2.11"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; private function __construct(){ From c085bf0db4c7df5ac8ae2575d880f44a82ffef82 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 13:59:50 +0100 Subject: [PATCH 07/11] Changes for 1.18.30 --- composer.json | 4 +-- composer.lock | 30 +++++++++---------- src/entity/Human.php | 2 ++ .../mcpe/serializer/ChunkSerializer.php | 2 +- src/world/particle/FloatingTextParticle.php | 2 ++ 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index eec8fa3c8..085d3d536 100644 --- a/composer.json +++ b/composer.json @@ -34,8 +34,8 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-data": "~1.6.0+bedrock-1.18.10", - "pocketmine/bedrock-protocol": "~8.0.2+bedrock-1.18.10", + "pocketmine/bedrock-data": "~1.7.0+bedrock-1.18.30", + "pocketmine/bedrock-protocol": "~9.0.0+bedrock-1.18.30", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "^0.2.0", diff --git a/composer.lock b/composer.lock index 52285f2d5..b38a0c0cb 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "b20ae069f5f467084bcbaae90c893bc9", + "content-hash": "bc9cfcfe04209226c67d903f77cb1620", "packages": [ { "name": "adhocore/json-comment", @@ -249,42 +249,42 @@ }, { "name": "pocketmine/bedrock-data", - "version": "1.6.0+bedrock-1.18.10", + "version": "1.7.0+bedrock-1.18.30", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "e98c511584a7bd58a95986374d2df4b04c6a2ba0" + "reference": "c8f323ff0cbdb36a5d95e7e4a23969f562445be0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/e98c511584a7bd58a95986374d2df4b04c6a2ba0", - "reference": "e98c511584a7bd58a95986374d2df4b04c6a2ba0", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/c8f323ff0cbdb36a5d95e7e4a23969f562445be0", + "reference": "c8f323ff0cbdb36a5d95e7e4a23969f562445be0", "shasum": "" }, "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0" + "CC0-1.0" ], "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.18.10" + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.18.30" }, - "time": "2022-02-08T19:13:47+00:00" + "time": "2022-04-20T12:40:59+00:00" }, { "name": "pocketmine/bedrock-protocol", - "version": "8.0.2+bedrock-1.18.10", + "version": "9.0.0+bedrock-1.18.30", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "d1f1afdbb4ea61ea52eb511a79ee1ca561da349c" + "reference": "76cf00af0070dbb3f63a3e7fe74039d011a5475e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/d1f1afdbb4ea61ea52eb511a79ee1ca561da349c", - "reference": "d1f1afdbb4ea61ea52eb511a79ee1ca561da349c", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/76cf00af0070dbb3f63a3e7fe74039d011a5475e", + "reference": "76cf00af0070dbb3f63a3e7fe74039d011a5475e", "shasum": "" }, "require": { @@ -298,7 +298,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.5.3", + "phpstan/phpstan": "1.5.4", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5" @@ -316,9 +316,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/8.0.2+bedrock-1.18.10" + "source": "https://github.com/pmmp/BedrockProtocol/tree/9.0.0+bedrock-1.18.30" }, - "time": "2022-04-01T21:55:10+00:00" + "time": "2022-04-20T12:44:11+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/entity/Human.php b/src/entity/Human.php index 56da6570e..a5673eae6 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -55,6 +55,7 @@ use pocketmine\network\mcpe\protocol\types\DeviceOS; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; +use pocketmine\network\mcpe\protocol\types\GameMode; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\player\Player; @@ -473,6 +474,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->location->yaw, $this->location->yaw, //TODO: head yaw ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand())), + GameMode::SURVIVAL, $this->getAllNetworkData(), AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->getId()), //TODO [], //TODO: entity links diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 0fe5d891a..06e60cb40 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -78,7 +78,7 @@ final class ChunkSerializer{ //TODO: right now we don't support 3D natively, so we just 3Dify our 2D biomes so they fill the column $encodedBiomePalette = self::serializeBiomesAsPalette($chunk); - $stream->put(str_repeat($encodedBiomePalette, 25)); + $stream->put(str_repeat($encodedBiomePalette, 24)); $stream->putByte(0); //border block array count //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 1fe3ee008..a8358ce81 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -36,6 +36,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; +use pocketmine\network\mcpe\protocol\types\GameMode; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; @@ -117,6 +118,7 @@ class FloatingTextParticle implements Particle{ 0, 0, ItemStackWrapper::legacy(ItemStack::null()), + GameMode::SURVIVAL, $actorMetadata, AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->entityId), [], From 6b4687a36b5acda9985d1b2751e350c057f41dd0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 14:00:20 +0100 Subject: [PATCH 08/11] RuntimeBlockMapping: unseal constructor to facilitate easier testing of new versions --- .../mcpe/convert/RuntimeBlockMapping.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 75835be0f..a6344eb79 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -48,9 +48,16 @@ final class RuntimeBlockMapping{ /** @var CompoundTag[] */ private $bedrockKnownStates; - private function __construct(){ + private static function make() : self{ + return new self( + Path::join(\pocketmine\BEDROCK_DATA_PATH, "canonical_block_states.nbt"), + Path::join(\pocketmine\BEDROCK_DATA_PATH, "r12_to_current_block_map.bin") + ); + } + + public function __construct(string $canonicalBlockStatesFile, string $r12ToCurrentBlockMapFile){ $stream = PacketSerializer::decoder( - Utils::assumeNotFalse(file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, "canonical_block_states.nbt")), "Missing required resource file"), + Utils::assumeNotFalse(file_get_contents($canonicalBlockStatesFile), "Missing required resource file"), 0, new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()) ); @@ -60,15 +67,15 @@ final class RuntimeBlockMapping{ } $this->bedrockKnownStates = $list; - $this->setupLegacyMappings(); + $this->setupLegacyMappings($r12ToCurrentBlockMapFile); } - private function setupLegacyMappings() : void{ + private function setupLegacyMappings(string $r12ToCurrentBlockMapFile) : void{ $legacyIdMap = LegacyBlockIdToStringIdMap::getInstance(); /** @var R12ToCurrentBlockMapEntry[] $legacyStateMap */ $legacyStateMap = []; $legacyStateMapReader = PacketSerializer::decoder( - Utils::assumeNotFalse(file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, "r12_to_current_block_map.bin")), "Missing required resource file"), + Utils::assumeNotFalse(file_get_contents($r12ToCurrentBlockMapFile), "Missing required resource file"), 0, new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()) ); From e4ce467c0ba22e8e9f0300bd5d375a0728369813 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 14:15:06 +0100 Subject: [PATCH 09/11] Release 4.3.0 --- changelogs/4.3.md | 14 ++++++++++++++ src/VersionInfo.php | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 changelogs/4.3.md diff --git a/changelogs/4.3.md b/changelogs/4.3.md new file mode 100644 index 000000000..6faf3a229 --- /dev/null +++ b/changelogs/4.3.md @@ -0,0 +1,14 @@ +**For Minecraft: Bedrock Edition 1.18.30** + +### Note about API versions +Plugins which don't touch the protocol and 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 protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do. + +# 4.3.0 +Released 20th April 2022. + +## General +- Added support for Minecraft: Bedrock Edition 1.18.30. +- Removed support for older versions. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index a76bc2cf7..6973e67b7 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 = "4.2.11"; - public const IS_DEVELOPMENT_BUILD = true; + public const BASE_VERSION = "4.3.0"; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; private function __construct(){ From cd021f49cdd2cd0fd1dfbad58c24fae6c3a4e5b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 14:15:12 +0100 Subject: [PATCH 10/11] 4.3.1 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 6973e67b7..c9db21a7e 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 = "4.3.0"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.3.1"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; private function __construct(){ From cfea0dac76e7f942c688808b8a7f70d292f36c58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Apr 2022 14:22:31 +0100 Subject: [PATCH 11/11] Push back to 4.4.0 --- src/VersionInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index c2b9b3974..3da89892c 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,7 +31,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.3.0"; + public const BASE_VERSION = "4.4.0"; public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "beta";