From c51b1b28125a12f5c874ed9aeee4ac9f331cc43a Mon Sep 17 00:00:00 2001 From: Hugo_ <55756021+Dhaiven@users.noreply.github.com> Date: Wed, 20 Dec 2023 16:21:11 +0100 Subject: [PATCH 01/38] Create LightableTrait and remove repetitive code (#6111) --- src/block/Furnace.php | 16 ++--------- src/block/RedstoneOre.php | 20 ++----------- src/block/RedstoneTorch.php | 20 +++++-------- src/block/utils/CandleTrait.php | 15 +--------- src/block/utils/LightableTrait.php | 46 ++++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 59 deletions(-) create mode 100644 src/block/utils/LightableTrait.php diff --git a/src/block/Furnace.php b/src/block/Furnace.php index fbff73c939..7a64e3cd3e 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; +use pocketmine\block\utils\LightableTrait; use pocketmine\crafting\FurnaceType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; @@ -34,11 +35,10 @@ use function mt_rand; class Furnace extends Opaque{ use FacesOppositePlacingPlayerTrait; + use LightableTrait; protected FurnaceType $furnaceType; - protected bool $lit = false; - public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, FurnaceType $furnaceType){ $this->furnaceType = $furnaceType; parent::__construct($idInfo, $name, $typeInfo); @@ -57,18 +57,6 @@ class Furnace extends Opaque{ return $this->lit ? 13 : 0; } - public function isLit() : bool{ - return $this->lit; - } - - /** - * @return $this - */ - public function setLit(bool $lit = true) : self{ - $this->lit = $lit; - return $this; - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ if($player instanceof Player){ $furnace = $this->position->getWorld()->getTile($this->position); diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 9e537bd279..10e701a6f4 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\FortuneDropHelper; -use pocketmine\data\runtime\RuntimeDataDescriber; +use pocketmine\block\utils\LightableTrait; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; @@ -32,23 +32,7 @@ use pocketmine\player\Player; use function mt_rand; class RedstoneOre extends Opaque{ - protected bool $lit = false; - - protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ - $w->bool($this->lit); - } - - public function isLit() : bool{ - return $this->lit; - } - - /** - * @return $this - */ - public function setLit(bool $lit = true) : self{ - $this->lit = $lit; - return $this; - } + use LightableTrait; public function getLightLevel() : int{ return $this->lit ? 9 : 0; diff --git a/src/block/RedstoneTorch.php b/src/block/RedstoneTorch.php index b30c011d4d..26c86038b9 100644 --- a/src/block/RedstoneTorch.php +++ b/src/block/RedstoneTorch.php @@ -23,28 +23,22 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\LightableTrait; use pocketmine\data\runtime\RuntimeDataDescriber; class RedstoneTorch extends Torch{ - protected bool $lit = true; + use LightableTrait; + + public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){ + $this->lit = true; + parent::__construct($idInfo, $name, $typeInfo); + } protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ parent::describeBlockOnlyState($w); $w->bool($this->lit); } - public function isLit() : bool{ - return $this->lit; - } - - /** - * @return $this - */ - public function setLit(bool $lit = true) : self{ - $this->lit = $lit; - return $this; - } - public function getLightLevel() : int{ return $this->lit ? 7 : 0; } diff --git a/src/block/utils/CandleTrait.php b/src/block/utils/CandleTrait.php index 58a7443a3c..c9da97ee0c 100644 --- a/src/block/utils/CandleTrait.php +++ b/src/block/utils/CandleTrait.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block\utils; use pocketmine\block\Block; -use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\entity\projectile\Projectile; use pocketmine\item\Durable; use pocketmine\item\enchantment\VanillaEnchantments; @@ -38,24 +37,12 @@ use pocketmine\world\sound\FireExtinguishSound; use pocketmine\world\sound\FlintSteelSound; trait CandleTrait{ - private bool $lit = false; - - protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ - $w->bool($this->lit); - } + use LightableTrait; public function getLightLevel() : int{ return $this->lit ? 3 : 0; } - public function isLit() : bool{ return $this->lit; } - - /** @return $this */ - public function setLit(bool $lit) : self{ - $this->lit = $lit; - return $this; - } - /** @see Block::onInteract() */ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ if($item->getTypeId() === ItemTypeIds::FIRE_CHARGE || $item->getTypeId() === ItemTypeIds::FLINT_AND_STEEL || $item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())){ diff --git a/src/block/utils/LightableTrait.php b/src/block/utils/LightableTrait.php new file mode 100644 index 0000000000..51ce54f42c --- /dev/null +++ b/src/block/utils/LightableTrait.php @@ -0,0 +1,46 @@ +bool($this->lit); + } + + public function isLit() : bool{ + return $this->lit; + } + + /** + * @return $this + */ + public function setLit(bool $lit = true) : self{ + $this->lit = $lit; + return $this; + } +} From 57f3a04bc50700c3e0727277b59ce436604e429a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Dec 2023 16:06:54 +0000 Subject: [PATCH 02/38] data: Use statically analyzable ways of ensuring all cases are registered PHPStan will verify that these matches cover all cases, which guarantees that all cases will be covered. In addition, if PHPStan is not used, the constructors will immediately bail out when they hit a case that isn't covered. The only downside is the extra indentation :( --- src/data/bedrock/BannerPatternTypeIdMap.php | 80 +++++++++-------- src/data/bedrock/DyeColorIdMap.php | 38 ++++---- src/data/bedrock/MedicineTypeIdMap.php | 12 ++- src/data/bedrock/MobHeadTypeIdMap.php | 18 ++-- src/data/bedrock/MushroomBlockTypeIdMap.php | 26 +++--- src/data/bedrock/NoteInstrumentIdMap.php | 36 ++++---- src/data/bedrock/PotionTypeIdMap.php | 90 ++++++++++--------- src/data/bedrock/SuspiciousStewTypeIdMap.php | 25 +++--- src/data/java/GameModeIdMap.php | 12 ++- .../data/bedrock/DyeColorIdMapTest.php | 38 -------- 10 files changed, 188 insertions(+), 187 deletions(-) delete mode 100644 tests/phpunit/data/bedrock/DyeColorIdMapTest.php diff --git a/src/data/bedrock/BannerPatternTypeIdMap.php b/src/data/bedrock/BannerPatternTypeIdMap.php index 064844e199..87f9b8f571 100644 --- a/src/data/bedrock/BannerPatternTypeIdMap.php +++ b/src/data/bedrock/BannerPatternTypeIdMap.php @@ -43,44 +43,48 @@ final class BannerPatternTypeIdMap{ private array $enumToId = []; public function __construct(){ - $this->register("bo", BannerPatternType::BORDER); - $this->register("bri", BannerPatternType::BRICKS); - $this->register("mc", BannerPatternType::CIRCLE); - $this->register("cre", BannerPatternType::CREEPER); - $this->register("cr", BannerPatternType::CROSS); - $this->register("cbo", BannerPatternType::CURLY_BORDER); - $this->register("lud", BannerPatternType::DIAGONAL_LEFT); - $this->register("rd", BannerPatternType::DIAGONAL_RIGHT); - $this->register("ld", BannerPatternType::DIAGONAL_UP_LEFT); - $this->register("rud", BannerPatternType::DIAGONAL_UP_RIGHT); - $this->register("flo", BannerPatternType::FLOWER); - $this->register("gra", BannerPatternType::GRADIENT); - $this->register("gru", BannerPatternType::GRADIENT_UP); - $this->register("hh", BannerPatternType::HALF_HORIZONTAL); - $this->register("hhb", BannerPatternType::HALF_HORIZONTAL_BOTTOM); - $this->register("vh", BannerPatternType::HALF_VERTICAL); - $this->register("vhr", BannerPatternType::HALF_VERTICAL_RIGHT); - $this->register("moj", BannerPatternType::MOJANG); - $this->register("mr", BannerPatternType::RHOMBUS); - $this->register("sku", BannerPatternType::SKULL); - $this->register("ss", BannerPatternType::SMALL_STRIPES); - $this->register("bl", BannerPatternType::SQUARE_BOTTOM_LEFT); - $this->register("br", BannerPatternType::SQUARE_BOTTOM_RIGHT); - $this->register("tl", BannerPatternType::SQUARE_TOP_LEFT); - $this->register("tr", BannerPatternType::SQUARE_TOP_RIGHT); - $this->register("sc", BannerPatternType::STRAIGHT_CROSS); - $this->register("bs", BannerPatternType::STRIPE_BOTTOM); - $this->register("cs", BannerPatternType::STRIPE_CENTER); - $this->register("dls", BannerPatternType::STRIPE_DOWNLEFT); - $this->register("drs", BannerPatternType::STRIPE_DOWNRIGHT); - $this->register("ls", BannerPatternType::STRIPE_LEFT); - $this->register("ms", BannerPatternType::STRIPE_MIDDLE); - $this->register("rs", BannerPatternType::STRIPE_RIGHT); - $this->register("ts", BannerPatternType::STRIPE_TOP); - $this->register("bt", BannerPatternType::TRIANGLE_BOTTOM); - $this->register("tt", BannerPatternType::TRIANGLE_TOP); - $this->register("bts", BannerPatternType::TRIANGLES_BOTTOM); - $this->register("tts", BannerPatternType::TRIANGLES_TOP); + foreach(BannerPatternType::cases() as $case){ + $this->register(match($case){ + BannerPatternType::BORDER => "bo", + BannerPatternType::BRICKS => "bri", + BannerPatternType::CIRCLE => "mc", + BannerPatternType::CREEPER => "cre", + BannerPatternType::CROSS => "cr", + BannerPatternType::CURLY_BORDER => "cbo", + BannerPatternType::DIAGONAL_LEFT => "lud", + BannerPatternType::DIAGONAL_RIGHT => "rd", + BannerPatternType::DIAGONAL_UP_LEFT => "ld", + BannerPatternType::DIAGONAL_UP_RIGHT => "rud", + BannerPatternType::FLOWER => "flo", + BannerPatternType::GRADIENT => "gra", + BannerPatternType::GRADIENT_UP => "gru", + BannerPatternType::HALF_HORIZONTAL => "hh", + BannerPatternType::HALF_HORIZONTAL_BOTTOM => "hhb", + BannerPatternType::HALF_VERTICAL => "vh", + BannerPatternType::HALF_VERTICAL_RIGHT => "vhr", + BannerPatternType::MOJANG => "moj", + BannerPatternType::RHOMBUS => "mr", + BannerPatternType::SKULL => "sku", + BannerPatternType::SMALL_STRIPES => "ss", + BannerPatternType::SQUARE_BOTTOM_LEFT => "bl", + BannerPatternType::SQUARE_BOTTOM_RIGHT => "br", + BannerPatternType::SQUARE_TOP_LEFT => "tl", + BannerPatternType::SQUARE_TOP_RIGHT => "tr", + BannerPatternType::STRAIGHT_CROSS => "sc", + BannerPatternType::STRIPE_BOTTOM => "bs", + BannerPatternType::STRIPE_CENTER => "cs", + BannerPatternType::STRIPE_DOWNLEFT => "dls", + BannerPatternType::STRIPE_DOWNRIGHT => "drs", + BannerPatternType::STRIPE_LEFT => "ls", + BannerPatternType::STRIPE_MIDDLE => "ms", + BannerPatternType::STRIPE_RIGHT => "rs", + BannerPatternType::STRIPE_TOP => "ts", + BannerPatternType::TRIANGLE_BOTTOM => "bt", + BannerPatternType::TRIANGLE_TOP => "tt", + BannerPatternType::TRIANGLES_BOTTOM => "bts", + BannerPatternType::TRIANGLES_TOP => "tts", + }, $case); + } } public function register(string $stringId, BannerPatternType $type) : void{ diff --git a/src/data/bedrock/DyeColorIdMap.php b/src/data/bedrock/DyeColorIdMap.php index a360e4f910..60c5097059 100644 --- a/src/data/bedrock/DyeColorIdMap.php +++ b/src/data/bedrock/DyeColorIdMap.php @@ -48,22 +48,28 @@ final class DyeColorIdMap{ private array $enumToItemId = []; private function __construct(){ - $this->register(0, ItemTypeNames::WHITE_DYE, DyeColor::WHITE); - $this->register(1, ItemTypeNames::ORANGE_DYE, DyeColor::ORANGE); - $this->register(2, ItemTypeNames::MAGENTA_DYE, DyeColor::MAGENTA); - $this->register(3, ItemTypeNames::LIGHT_BLUE_DYE, DyeColor::LIGHT_BLUE); - $this->register(4, ItemTypeNames::YELLOW_DYE, DyeColor::YELLOW); - $this->register(5, ItemTypeNames::LIME_DYE, DyeColor::LIME); - $this->register(6, ItemTypeNames::PINK_DYE, DyeColor::PINK); - $this->register(7, ItemTypeNames::GRAY_DYE, DyeColor::GRAY); - $this->register(8, ItemTypeNames::LIGHT_GRAY_DYE, DyeColor::LIGHT_GRAY); - $this->register(9, ItemTypeNames::CYAN_DYE, DyeColor::CYAN); - $this->register(10, ItemTypeNames::PURPLE_DYE, DyeColor::PURPLE); - $this->register(11, ItemTypeNames::BLUE_DYE, DyeColor::BLUE); - $this->register(12, ItemTypeNames::BROWN_DYE, DyeColor::BROWN); - $this->register(13, ItemTypeNames::GREEN_DYE, DyeColor::GREEN); - $this->register(14, ItemTypeNames::RED_DYE, DyeColor::RED); - $this->register(15, ItemTypeNames::BLACK_DYE, DyeColor::BLACK); + foreach(DyeColor::cases() as $case){ + [$colorId, $dyeItemId] = match($case){ + DyeColor::WHITE => [0, ItemTypeNames::WHITE_DYE], + DyeColor::ORANGE => [1, ItemTypeNames::ORANGE_DYE], + DyeColor::MAGENTA => [2, ItemTypeNames::MAGENTA_DYE], + DyeColor::LIGHT_BLUE => [3, ItemTypeNames::LIGHT_BLUE_DYE], + DyeColor::YELLOW => [4, ItemTypeNames::YELLOW_DYE], + DyeColor::LIME => [5, ItemTypeNames::LIME_DYE], + DyeColor::PINK => [6, ItemTypeNames::PINK_DYE], + DyeColor::GRAY => [7, ItemTypeNames::GRAY_DYE], + DyeColor::LIGHT_GRAY => [8, ItemTypeNames::LIGHT_GRAY_DYE], + DyeColor::CYAN => [9, ItemTypeNames::CYAN_DYE], + DyeColor::PURPLE => [10, ItemTypeNames::PURPLE_DYE], + DyeColor::BLUE => [11, ItemTypeNames::BLUE_DYE], + DyeColor::BROWN => [12, ItemTypeNames::BROWN_DYE], + DyeColor::GREEN => [13, ItemTypeNames::GREEN_DYE], + DyeColor::RED => [14, ItemTypeNames::RED_DYE], + DyeColor::BLACK => [15, ItemTypeNames::BLACK_DYE], + }; + + $this->register($colorId, $dyeItemId, $case); + } } private function register(int $id, string $itemId, DyeColor $color) : void{ diff --git a/src/data/bedrock/MedicineTypeIdMap.php b/src/data/bedrock/MedicineTypeIdMap.php index 00d1f27a86..90fd835509 100644 --- a/src/data/bedrock/MedicineTypeIdMap.php +++ b/src/data/bedrock/MedicineTypeIdMap.php @@ -32,9 +32,13 @@ final class MedicineTypeIdMap{ use IntSaveIdMapTrait; private function __construct(){ - $this->register(MedicineTypeIds::ANTIDOTE, MedicineType::ANTIDOTE); - $this->register(MedicineTypeIds::ELIXIR, MedicineType::ELIXIR); - $this->register(MedicineTypeIds::EYE_DROPS, MedicineType::EYE_DROPS); - $this->register(MedicineTypeIds::TONIC, MedicineType::TONIC); + foreach(MedicineType::cases() as $case){ + $this->register(match($case){ + MedicineType::ANTIDOTE => MedicineTypeIds::ANTIDOTE, + MedicineType::ELIXIR => MedicineTypeIds::ELIXIR, + MedicineType::EYE_DROPS => MedicineTypeIds::EYE_DROPS, + MedicineType::TONIC => MedicineTypeIds::TONIC, + }, $case); + } } } diff --git a/src/data/bedrock/MobHeadTypeIdMap.php b/src/data/bedrock/MobHeadTypeIdMap.php index ec678b1924..bf16e6eba0 100644 --- a/src/data/bedrock/MobHeadTypeIdMap.php +++ b/src/data/bedrock/MobHeadTypeIdMap.php @@ -32,12 +32,16 @@ final class MobHeadTypeIdMap{ use IntSaveIdMapTrait; private function __construct(){ - $this->register(0, MobHeadType::SKELETON); - $this->register(1, MobHeadType::WITHER_SKELETON); - $this->register(2, MobHeadType::ZOMBIE); - $this->register(3, MobHeadType::PLAYER); - $this->register(4, MobHeadType::CREEPER); - $this->register(5, MobHeadType::DRAGON); - $this->register(6, MobHeadType::PIGLIN); + foreach(MobHeadType::cases() as $case){ + $this->register(match($case){ + MobHeadType::SKELETON => 0, + MobHeadType::WITHER_SKELETON => 1, + MobHeadType::ZOMBIE => 2, + MobHeadType::PLAYER => 3, + MobHeadType::CREEPER => 4, + MobHeadType::DRAGON => 5, + MobHeadType::PIGLIN => 6, + }, $case); + } } } diff --git a/src/data/bedrock/MushroomBlockTypeIdMap.php b/src/data/bedrock/MushroomBlockTypeIdMap.php index 92edef4b23..a25336d897 100644 --- a/src/data/bedrock/MushroomBlockTypeIdMap.php +++ b/src/data/bedrock/MushroomBlockTypeIdMap.php @@ -33,16 +33,20 @@ final class MushroomBlockTypeIdMap{ use IntSaveIdMapTrait; public function __construct(){ - $this->register(LegacyMeta::MUSHROOM_BLOCK_ALL_PORES, MushroomBlockType::PORES); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER, MushroomBlockType::CAP_NORTHWEST); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_NORTH_SIDE, MushroomBlockType::CAP_NORTH); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER, MushroomBlockType::CAP_NORTHEAST); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_WEST_SIDE, MushroomBlockType::CAP_WEST); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_TOP_ONLY, MushroomBlockType::CAP_MIDDLE); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_EAST_SIDE, MushroomBlockType::CAP_EAST); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER, MushroomBlockType::CAP_SOUTHWEST); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTH_SIDE, MushroomBlockType::CAP_SOUTH); - $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER, MushroomBlockType::CAP_SOUTHEAST); - $this->register(LegacyMeta::MUSHROOM_BLOCK_ALL_CAP, MushroomBlockType::ALL_CAP); + foreach(MushroomBlockType::cases() as $case){ + $this->register(match($case){ + MushroomBlockType::PORES => LegacyMeta::MUSHROOM_BLOCK_ALL_PORES, + MushroomBlockType::CAP_NORTHWEST => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER, + MushroomBlockType::CAP_NORTH => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTH_SIDE, + MushroomBlockType::CAP_NORTHEAST => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER, + MushroomBlockType::CAP_WEST => LegacyMeta::MUSHROOM_BLOCK_CAP_WEST_SIDE, + MushroomBlockType::CAP_MIDDLE => LegacyMeta::MUSHROOM_BLOCK_CAP_TOP_ONLY, + MushroomBlockType::CAP_EAST => LegacyMeta::MUSHROOM_BLOCK_CAP_EAST_SIDE, + MushroomBlockType::CAP_SOUTHWEST => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER, + MushroomBlockType::CAP_SOUTH => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTH_SIDE, + MushroomBlockType::CAP_SOUTHEAST => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER, + MushroomBlockType::ALL_CAP => LegacyMeta::MUSHROOM_BLOCK_ALL_CAP, + }, $case); + } } } diff --git a/src/data/bedrock/NoteInstrumentIdMap.php b/src/data/bedrock/NoteInstrumentIdMap.php index e721b881d2..c847ecd98c 100644 --- a/src/data/bedrock/NoteInstrumentIdMap.php +++ b/src/data/bedrock/NoteInstrumentIdMap.php @@ -32,21 +32,25 @@ final class NoteInstrumentIdMap{ use IntSaveIdMapTrait; private function __construct(){ - $this->register(0, NoteInstrument::PIANO); - $this->register(1, NoteInstrument::BASS_DRUM); - $this->register(2, NoteInstrument::SNARE); - $this->register(3, NoteInstrument::CLICKS_AND_STICKS); - $this->register(4, NoteInstrument::DOUBLE_BASS); - $this->register(5, NoteInstrument::BELL); - $this->register(6, NoteInstrument::FLUTE); - $this->register(7, NoteInstrument::CHIME); - $this->register(8, NoteInstrument::GUITAR); - $this->register(9, NoteInstrument::XYLOPHONE); - $this->register(10, NoteInstrument::IRON_XYLOPHONE); - $this->register(11, NoteInstrument::COW_BELL); - $this->register(12, NoteInstrument::DIDGERIDOO); - $this->register(13, NoteInstrument::BIT); - $this->register(14, NoteInstrument::BANJO); - $this->register(15, NoteInstrument::PLING); + foreach(NoteInstrument::cases() as $case){ + $this->register(match($case){ + NoteInstrument::PIANO => 0, + NoteInstrument::BASS_DRUM => 1, + NoteInstrument::SNARE => 2, + NoteInstrument::CLICKS_AND_STICKS => 3, + NoteInstrument::DOUBLE_BASS => 4, + NoteInstrument::BELL => 5, + NoteInstrument::FLUTE => 6, + NoteInstrument::CHIME => 7, + NoteInstrument::GUITAR => 8, + NoteInstrument::XYLOPHONE => 9, + NoteInstrument::IRON_XYLOPHONE => 10, + NoteInstrument::COW_BELL => 11, + NoteInstrument::DIDGERIDOO => 12, + NoteInstrument::BIT => 13, + NoteInstrument::BANJO => 14, + NoteInstrument::PLING => 15, + }, $case); + } } } diff --git a/src/data/bedrock/PotionTypeIdMap.php b/src/data/bedrock/PotionTypeIdMap.php index 3fef20f68c..4e7d8d4c79 100644 --- a/src/data/bedrock/PotionTypeIdMap.php +++ b/src/data/bedrock/PotionTypeIdMap.php @@ -32,48 +32,52 @@ final class PotionTypeIdMap{ use IntSaveIdMapTrait; private function __construct(){ - $this->register(PotionTypeIds::WATER, PotionType::WATER); - $this->register(PotionTypeIds::MUNDANE, PotionType::MUNDANE); - $this->register(PotionTypeIds::LONG_MUNDANE, PotionType::LONG_MUNDANE); - $this->register(PotionTypeIds::THICK, PotionType::THICK); - $this->register(PotionTypeIds::AWKWARD, PotionType::AWKWARD); - $this->register(PotionTypeIds::NIGHT_VISION, PotionType::NIGHT_VISION); - $this->register(PotionTypeIds::LONG_NIGHT_VISION, PotionType::LONG_NIGHT_VISION); - $this->register(PotionTypeIds::INVISIBILITY, PotionType::INVISIBILITY); - $this->register(PotionTypeIds::LONG_INVISIBILITY, PotionType::LONG_INVISIBILITY); - $this->register(PotionTypeIds::LEAPING, PotionType::LEAPING); - $this->register(PotionTypeIds::LONG_LEAPING, PotionType::LONG_LEAPING); - $this->register(PotionTypeIds::STRONG_LEAPING, PotionType::STRONG_LEAPING); - $this->register(PotionTypeIds::FIRE_RESISTANCE, PotionType::FIRE_RESISTANCE); - $this->register(PotionTypeIds::LONG_FIRE_RESISTANCE, PotionType::LONG_FIRE_RESISTANCE); - $this->register(PotionTypeIds::SWIFTNESS, PotionType::SWIFTNESS); - $this->register(PotionTypeIds::LONG_SWIFTNESS, PotionType::LONG_SWIFTNESS); - $this->register(PotionTypeIds::STRONG_SWIFTNESS, PotionType::STRONG_SWIFTNESS); - $this->register(PotionTypeIds::SLOWNESS, PotionType::SLOWNESS); - $this->register(PotionTypeIds::LONG_SLOWNESS, PotionType::LONG_SLOWNESS); - $this->register(PotionTypeIds::WATER_BREATHING, PotionType::WATER_BREATHING); - $this->register(PotionTypeIds::LONG_WATER_BREATHING, PotionType::LONG_WATER_BREATHING); - $this->register(PotionTypeIds::HEALING, PotionType::HEALING); - $this->register(PotionTypeIds::STRONG_HEALING, PotionType::STRONG_HEALING); - $this->register(PotionTypeIds::HARMING, PotionType::HARMING); - $this->register(PotionTypeIds::STRONG_HARMING, PotionType::STRONG_HARMING); - $this->register(PotionTypeIds::POISON, PotionType::POISON); - $this->register(PotionTypeIds::LONG_POISON, PotionType::LONG_POISON); - $this->register(PotionTypeIds::STRONG_POISON, PotionType::STRONG_POISON); - $this->register(PotionTypeIds::REGENERATION, PotionType::REGENERATION); - $this->register(PotionTypeIds::LONG_REGENERATION, PotionType::LONG_REGENERATION); - $this->register(PotionTypeIds::STRONG_REGENERATION, PotionType::STRONG_REGENERATION); - $this->register(PotionTypeIds::STRENGTH, PotionType::STRENGTH); - $this->register(PotionTypeIds::LONG_STRENGTH, PotionType::LONG_STRENGTH); - $this->register(PotionTypeIds::STRONG_STRENGTH, PotionType::STRONG_STRENGTH); - $this->register(PotionTypeIds::WEAKNESS, PotionType::WEAKNESS); - $this->register(PotionTypeIds::LONG_WEAKNESS, PotionType::LONG_WEAKNESS); - $this->register(PotionTypeIds::WITHER, PotionType::WITHER); - $this->register(PotionTypeIds::TURTLE_MASTER, PotionType::TURTLE_MASTER); - $this->register(PotionTypeIds::LONG_TURTLE_MASTER, PotionType::LONG_TURTLE_MASTER); - $this->register(PotionTypeIds::STRONG_TURTLE_MASTER, PotionType::STRONG_TURTLE_MASTER); - $this->register(PotionTypeIds::SLOW_FALLING, PotionType::SLOW_FALLING); - $this->register(PotionTypeIds::LONG_SLOW_FALLING, PotionType::LONG_SLOW_FALLING); - $this->register(PotionTypeIds::STRONG_SLOWNESS, PotionType::STRONG_SLOWNESS); + foreach(PotionType::cases() as $case){ + $this->register(match($case){ + PotionType::WATER => PotionTypeIds::WATER, + PotionType::MUNDANE => PotionTypeIds::MUNDANE, + PotionType::LONG_MUNDANE => PotionTypeIds::LONG_MUNDANE, + PotionType::THICK => PotionTypeIds::THICK, + PotionType::AWKWARD => PotionTypeIds::AWKWARD, + PotionType::NIGHT_VISION => PotionTypeIds::NIGHT_VISION, + PotionType::LONG_NIGHT_VISION => PotionTypeIds::LONG_NIGHT_VISION, + PotionType::INVISIBILITY => PotionTypeIds::INVISIBILITY, + PotionType::LONG_INVISIBILITY => PotionTypeIds::LONG_INVISIBILITY, + PotionType::LEAPING => PotionTypeIds::LEAPING, + PotionType::LONG_LEAPING => PotionTypeIds::LONG_LEAPING, + PotionType::STRONG_LEAPING => PotionTypeIds::STRONG_LEAPING, + PotionType::FIRE_RESISTANCE => PotionTypeIds::FIRE_RESISTANCE, + PotionType::LONG_FIRE_RESISTANCE => PotionTypeIds::LONG_FIRE_RESISTANCE, + PotionType::SWIFTNESS => PotionTypeIds::SWIFTNESS, + PotionType::LONG_SWIFTNESS => PotionTypeIds::LONG_SWIFTNESS, + PotionType::STRONG_SWIFTNESS => PotionTypeIds::STRONG_SWIFTNESS, + PotionType::SLOWNESS => PotionTypeIds::SLOWNESS, + PotionType::LONG_SLOWNESS => PotionTypeIds::LONG_SLOWNESS, + PotionType::WATER_BREATHING => PotionTypeIds::WATER_BREATHING, + PotionType::LONG_WATER_BREATHING => PotionTypeIds::LONG_WATER_BREATHING, + PotionType::HEALING => PotionTypeIds::HEALING, + PotionType::STRONG_HEALING => PotionTypeIds::STRONG_HEALING, + PotionType::HARMING => PotionTypeIds::HARMING, + PotionType::STRONG_HARMING => PotionTypeIds::STRONG_HARMING, + PotionType::POISON => PotionTypeIds::POISON, + PotionType::LONG_POISON => PotionTypeIds::LONG_POISON, + PotionType::STRONG_POISON => PotionTypeIds::STRONG_POISON, + PotionType::REGENERATION => PotionTypeIds::REGENERATION, + PotionType::LONG_REGENERATION => PotionTypeIds::LONG_REGENERATION, + PotionType::STRONG_REGENERATION => PotionTypeIds::STRONG_REGENERATION, + PotionType::STRENGTH => PotionTypeIds::STRENGTH, + PotionType::LONG_STRENGTH => PotionTypeIds::LONG_STRENGTH, + PotionType::STRONG_STRENGTH => PotionTypeIds::STRONG_STRENGTH, + PotionType::WEAKNESS => PotionTypeIds::WEAKNESS, + PotionType::LONG_WEAKNESS => PotionTypeIds::LONG_WEAKNESS, + PotionType::WITHER => PotionTypeIds::WITHER, + PotionType::TURTLE_MASTER => PotionTypeIds::TURTLE_MASTER, + PotionType::LONG_TURTLE_MASTER => PotionTypeIds::LONG_TURTLE_MASTER, + PotionType::STRONG_TURTLE_MASTER => PotionTypeIds::STRONG_TURTLE_MASTER, + PotionType::SLOW_FALLING => PotionTypeIds::SLOW_FALLING, + PotionType::LONG_SLOW_FALLING => PotionTypeIds::LONG_SLOW_FALLING, + PotionType::STRONG_SLOWNESS => PotionTypeIds::STRONG_SLOWNESS, + }, $case); + } } } diff --git a/src/data/bedrock/SuspiciousStewTypeIdMap.php b/src/data/bedrock/SuspiciousStewTypeIdMap.php index c4de4b742d..d6a31f0ea7 100644 --- a/src/data/bedrock/SuspiciousStewTypeIdMap.php +++ b/src/data/bedrock/SuspiciousStewTypeIdMap.php @@ -32,15 +32,20 @@ final class SuspiciousStewTypeIdMap{ use IntSaveIdMapTrait; private function __construct(){ - $this->register(SuspiciousStewTypeIds::POPPY, SuspiciousStewType::POPPY); - $this->register(SuspiciousStewTypeIds::CORNFLOWER, SuspiciousStewType::CORNFLOWER); - $this->register(SuspiciousStewTypeIds::TULIP, SuspiciousStewType::TULIP); - $this->register(SuspiciousStewTypeIds::AZURE_BLUET, SuspiciousStewType::AZURE_BLUET); - $this->register(SuspiciousStewTypeIds::LILY_OF_THE_VALLEY, SuspiciousStewType::LILY_OF_THE_VALLEY); - $this->register(SuspiciousStewTypeIds::DANDELION, SuspiciousStewType::DANDELION); - $this->register(SuspiciousStewTypeIds::BLUE_ORCHID, SuspiciousStewType::BLUE_ORCHID); - $this->register(SuspiciousStewTypeIds::ALLIUM, SuspiciousStewType::ALLIUM); - $this->register(SuspiciousStewTypeIds::OXEYE_DAISY, SuspiciousStewType::OXEYE_DAISY); - $this->register(SuspiciousStewTypeIds::WITHER_ROSE, SuspiciousStewType::WITHER_ROSE); + foreach(SuspiciousStewType::cases() as $case){ + $this->register(match($case){ + SuspiciousStewType::POPPY => SuspiciousStewTypeIds::POPPY, + SuspiciousStewType::CORNFLOWER => SuspiciousStewTypeIds::CORNFLOWER, + SuspiciousStewType::TULIP => SuspiciousStewTypeIds::TULIP, + SuspiciousStewType::AZURE_BLUET => SuspiciousStewTypeIds::AZURE_BLUET, + SuspiciousStewType::LILY_OF_THE_VALLEY => SuspiciousStewTypeIds::LILY_OF_THE_VALLEY, + SuspiciousStewType::DANDELION => SuspiciousStewTypeIds::DANDELION, + SuspiciousStewType::BLUE_ORCHID => SuspiciousStewTypeIds::BLUE_ORCHID, + SuspiciousStewType::ALLIUM => SuspiciousStewTypeIds::ALLIUM, + SuspiciousStewType::OXEYE_DAISY => SuspiciousStewTypeIds::OXEYE_DAISY, + SuspiciousStewType::WITHER_ROSE => SuspiciousStewTypeIds::WITHER_ROSE, + }, $case); + } + } } diff --git a/src/data/java/GameModeIdMap.php b/src/data/java/GameModeIdMap.php index 41258dd66e..9262723ed8 100644 --- a/src/data/java/GameModeIdMap.php +++ b/src/data/java/GameModeIdMap.php @@ -44,10 +44,14 @@ final class GameModeIdMap{ private array $enumToId = []; public function __construct(){ - $this->register(0, GameMode::SURVIVAL); - $this->register(1, GameMode::CREATIVE); - $this->register(2, GameMode::ADVENTURE); - $this->register(3, GameMode::SPECTATOR); + foreach(GameMode::cases() as $case){ + $this->register(match($case){ + GameMode::SURVIVAL => 0, + GameMode::CREATIVE => 1, + GameMode::ADVENTURE => 2, + GameMode::SPECTATOR => 3, + }, $case); + } } private function register(int $id, GameMode $type) : void{ diff --git a/tests/phpunit/data/bedrock/DyeColorIdMapTest.php b/tests/phpunit/data/bedrock/DyeColorIdMapTest.php deleted file mode 100644 index a3ca6db25c..0000000000 --- a/tests/phpunit/data/bedrock/DyeColorIdMapTest.php +++ /dev/null @@ -1,38 +0,0 @@ -toId($color); - $color2 = DyeColorIdMap::getInstance()->fromId($id); - self::assertTrue($color === $color2); - } - } -} From bf99917f2a6404ad5dff61874adbf283d9060936 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Dec 2023 17:01:20 +0000 Subject: [PATCH 03/38] ThreadSafeClassLoader: add native property types --- src/thread/ThreadSafeClassLoader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/thread/ThreadSafeClassLoader.php b/src/thread/ThreadSafeClassLoader.php index 95b983dc1b..fd9e6afed6 100644 --- a/src/thread/ThreadSafeClassLoader.php +++ b/src/thread/ThreadSafeClassLoader.php @@ -51,12 +51,12 @@ class ThreadSafeClassLoader extends ThreadSafe{ * @var ThreadSafeArray|string[] * @phpstan-var ThreadSafeArray */ - private $fallbackLookup; + private ThreadSafeArray $fallbackLookup; /** * @var ThreadSafeArray|string[][] * @phpstan-var ThreadSafeArray> */ - private $psr4Lookup; + private ThreadSafeArray $psr4Lookup; public function __construct(){ $this->fallbackLookup = new ThreadSafeArray(); From 7a55a6e6b6c10f5033491603443c16f434d0deed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Dec 2023 17:22:11 +0000 Subject: [PATCH 04/38] ServerKiller: harden against spurious wakeups If awakened by spurious wakeup, the thread would immediately exit without doing anything, rendering it useless. Not sure how it took so long for this to be found... --- src/utils/ServerKiller.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/utils/ServerKiller.php b/src/utils/ServerKiller.php index 98129f48f0..514a265ba6 100644 --- a/src/utils/ServerKiller.php +++ b/src/utils/ServerKiller.php @@ -24,7 +24,8 @@ declare(strict_types=1); namespace pocketmine\utils; use pocketmine\thread\Thread; -use function time; +use function hrtime; +use function intdiv; class ServerKiller extends Thread{ private bool $stopped = false; @@ -34,13 +35,15 @@ class ServerKiller extends Thread{ ){} protected function onRun() : void{ - $start = time(); - $this->synchronized(function() : void{ - if(!$this->stopped){ - $this->wait($this->time * 1000000); + $start = hrtime(true); + $remaining = $this->time * 1_000_000; + $this->synchronized(function() use (&$remaining, $start) : void{ + while(!$this->stopped && $remaining > 0){ + $this->wait($remaining); + $remaining -= intdiv(hrtime(true) - $start, 1000); } }); - if(time() - $start >= $this->time){ + if($remaining <= 0){ echo "\nTook too long to stop, server was killed forcefully!\n"; @Process::kill(Process::pid()); } From c05116849ad47d08bd2d1708a3b8d9e05df27368 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Dec 2023 12:38:51 +0000 Subject: [PATCH 05/38] AsyncWorker: clean up nonsensical sleeper notifier handling code --- src/scheduler/AsyncTask.php | 6 +----- src/scheduler/AsyncWorker.php | 13 ++++++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index b4c3ce20db..b0b64347ad 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -24,12 +24,10 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pmmp\thread\Runnable; -use pmmp\thread\Thread as NativeThread; use pmmp\thread\ThreadSafe; use pmmp\thread\ThreadSafeArray; use pocketmine\thread\NonThreadSafeValue; use function array_key_exists; -use function assert; use function igbinary_serialize; use function igbinary_unserialize; use function is_null; @@ -83,9 +81,7 @@ abstract class AsyncTask extends Runnable{ $this->onRun(); $this->finished = true; - $worker = NativeThread::getCurrentThread(); - assert($worker instanceof AsyncWorker); - $worker->getNotifier()->wakeupSleeper(); + AsyncWorker::getNotifier()->wakeupSleeper(); } /** diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index 919e3eedcf..0f05dd8969 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -36,7 +36,7 @@ class AsyncWorker extends Worker{ /** @var mixed[] */ private static array $store = []; - private const TLS_KEY_NOTIFIER = self::class . "::notifier"; + private static ?SleeperNotifier $notifier = null; public function __construct( private ThreadSafeLogger $logger, @@ -45,12 +45,11 @@ class AsyncWorker extends Worker{ private SleeperHandlerEntry $sleeperEntry ){} - public function getNotifier() : SleeperNotifier{ - $notifier = $this->getFromThreadStore(self::TLS_KEY_NOTIFIER); - if(!$notifier instanceof SleeperNotifier){ - throw new AssumptionFailedError("SleeperNotifier not found in thread-local storage"); + public static function getNotifier() : SleeperNotifier{ + if(self::$notifier !== null){ + return self::$notifier; } - return $notifier; + throw new AssumptionFailedError("SleeperNotifier not found in thread-local storage"); } protected function onRun() : void{ @@ -66,7 +65,7 @@ class AsyncWorker extends Worker{ $this->logger->debug("No memory limit set"); } - $this->saveToThreadStore(self::TLS_KEY_NOTIFIER, $this->sleeperEntry->createNotifier()); + self::$notifier = $this->sleeperEntry->createNotifier(); } public function getLogger() : ThreadSafeLogger{ From fd1bc1b8456907e8449087e5550ea08a1fd35e5c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Dec 2023 12:39:55 +0000 Subject: [PATCH 06/38] AsyncWorker: deprecate ThreadStore methods these are inconvenient and don't make any sense. It's far easier and more static-analysis-friendly to just use static properties. --- src/scheduler/AsyncWorker.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index 0f05dd8969..5fdfb1ebb7 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -83,6 +83,8 @@ class AsyncWorker extends Worker{ /** * Saves mixed data into the worker's thread-local object store. This can be used to store objects which you * want to use on this worker thread from multiple AsyncTasks. + * + * @deprecated Use static class properties instead. */ public function saveToThreadStore(string $identifier, mixed $value) : void{ if(NativeThread::getCurrentThread() !== $this){ @@ -98,6 +100,8 @@ class AsyncWorker extends Worker{ * account for the possibility that what you're trying to retrieve might not exist. * * Objects stored in this storage may ONLY be retrieved while the task is running. + * + * @deprecated Use static class properties instead. */ public function getFromThreadStore(string $identifier) : mixed{ if(NativeThread::getCurrentThread() !== $this){ @@ -108,6 +112,8 @@ class AsyncWorker extends Worker{ /** * Removes previously-stored mixed data from the worker's thread-local object store. + * + * @deprecated Use static class properties instead. */ public function removeFromThreadStore(string $identifier) : void{ if(NativeThread::getCurrentThread() !== $this){ From 03619ebca91387113e749555463c306b33754b0f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Dec 2023 12:44:03 +0000 Subject: [PATCH 07/38] Thread/Worker: Remove duplicated code Despite the comments, there doesn't seem to be an obvious reason for these to be copy-pasted. Perhaps there was some legacy reason for this with legacy pthreads. In fact, it looks likely that quit() will probably be able to be traitified too. --- src/thread/CommonThreadPartsTrait.php | 10 ++++++++++ src/thread/Thread.php | 10 ---------- src/thread/Worker.php | 11 ----------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index de2ecbde81..f01a979b09 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\thread; +use pmmp\thread\Thread as NativeThread; use pmmp\thread\ThreadSafeArray; use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\Server; @@ -96,6 +97,15 @@ trait CommonThreadPartsTrait{ public function getCrashInfo() : ?ThreadCrashInfo{ return $this->crashInfo; } + public function start(int $options = NativeThread::INHERIT_NONE) : bool{ + ThreadManager::getInstance()->add($this); + + if($this->getClassLoaders() === null){ + $this->setClassLoaders(); + } + return parent::start($options); + } + final public function run() : void{ error_reporting(-1); $this->registerClassLoaders(); diff --git a/src/thread/Thread.php b/src/thread/Thread.php index 706f964298..2f02040229 100644 --- a/src/thread/Thread.php +++ b/src/thread/Thread.php @@ -38,16 +38,6 @@ use pocketmine\scheduler\AsyncTask; abstract class Thread extends NativeThread{ use CommonThreadPartsTrait; - public function start(int $options = NativeThread::INHERIT_NONE) : bool{ - //this is intentionally not traitified - ThreadManager::getInstance()->add($this); - - if($this->getClassLoaders() === null){ - $this->setClassLoaders(); - } - return parent::start($options); - } - /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ diff --git a/src/thread/Worker.php b/src/thread/Worker.php index 3bc5cda97a..7d9ca72c3b 100644 --- a/src/thread/Worker.php +++ b/src/thread/Worker.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\thread; -use pmmp\thread\Thread as NativeThread; use pmmp\thread\Worker as NativeWorker; use pocketmine\scheduler\AsyncTask; @@ -40,16 +39,6 @@ use pocketmine\scheduler\AsyncTask; abstract class Worker extends NativeWorker{ use CommonThreadPartsTrait; - public function start(int $options = NativeThread::INHERIT_NONE) : bool{ - //this is intentionally not traitified - ThreadManager::getInstance()->add($this); - - if($this->getClassLoaders() === null){ - $this->setClassLoaders(); - } - return parent::start($options); - } - /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ From b69843a8bd2e72f16ee2f82a2842cfc1a0ca0b7a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Dec 2023 12:56:51 +0000 Subject: [PATCH 08/38] CommonThreadPartsTrait: add common implementation of quit() there's no need for the worker specialization here (isShutdown and shutdown are aliased to isJoined and join respectively), and the unstacking is not really desirable either as we previously learned with AsyncPool. --- src/thread/CommonThreadPartsTrait.php | 14 ++++++++++++++ src/thread/Thread.php | 14 -------------- src/thread/Worker.php | 17 ----------------- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index f01a979b09..9cd2b68f9a 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -120,6 +120,20 @@ trait CommonThreadPartsTrait{ $this->isKilled = true; } + /** + * Stops the thread using the best way possible. Try to stop it yourself before calling this. + */ + public function quit() : void{ + $this->isKilled = true; + + if(!$this->isJoined()){ + $this->notify(); + $this->join(); + } + + ThreadManager::getInstance()->remove($this); + } + /** * Called by set_exception_handler() when an uncaught exception is thrown. */ diff --git a/src/thread/Thread.php b/src/thread/Thread.php index 2f02040229..a6c36e14c7 100644 --- a/src/thread/Thread.php +++ b/src/thread/Thread.php @@ -37,18 +37,4 @@ use pocketmine\scheduler\AsyncTask; */ abstract class Thread extends NativeThread{ use CommonThreadPartsTrait; - - /** - * Stops the thread using the best way possible. Try to stop it yourself before calling this. - */ - public function quit() : void{ - $this->isKilled = true; - - if(!$this->isJoined()){ - $this->notify(); - $this->join(); - } - - ThreadManager::getInstance()->remove($this); - } } diff --git a/src/thread/Worker.php b/src/thread/Worker.php index 7d9ca72c3b..cc0b56046a 100644 --- a/src/thread/Worker.php +++ b/src/thread/Worker.php @@ -38,21 +38,4 @@ use pocketmine\scheduler\AsyncTask; */ abstract class Worker extends NativeWorker{ use CommonThreadPartsTrait; - - /** - * Stops the thread using the best way possible. Try to stop it yourself before calling this. - */ - public function quit() : void{ - $this->isKilled = true; - - if(!$this->isShutdown()){ - $this->synchronized(function() : void{ - while($this->unstack() !== null); - }); - $this->notify(); - $this->shutdown(); - } - - ThreadManager::getInstance()->remove($this); - } } From 1b0ef468f389832bf598b029548e199bd435776d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Dec 2023 13:09:05 +0000 Subject: [PATCH 09/38] CommonThreadPartsTrait: remove outdated documentation This is now automatically called by the final run(), and the user now only needs to implement onRun(), so they have no business calling this function. --- src/thread/CommonThreadPartsTrait.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index 9cd2b68f9a..9a14b23454 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -78,9 +78,7 @@ trait CommonThreadPartsTrait{ /** * Registers the class loaders for this thread. * - * WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable. - * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started - * (unless you are using a custom autoloader). + * @internal */ public function registerClassLoaders() : void{ if($this->composerAutoloaderPath !== null){ From 5386e8607977583767a62d8f4eba2011f9a050ea Mon Sep 17 00:00:00 2001 From: GameParrot <85067619+GameParrot@users.noreply.github.com> Date: Wed, 3 Jan 2024 07:50:05 -0500 Subject: [PATCH 10/38] ProcessLoginTask: remove old root key (#6211) --- src/network/mcpe/auth/ProcessLoginTask.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index c396338da9..3bd8d62b86 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -39,16 +39,6 @@ use function time; class ProcessLoginTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "completion"; - /** - * Old Mojang root auth key. This was used since the introduction of Xbox Live authentication in 0.15.0. - * This key is expected to be replaced by the key below in the future, but this has not yet happened as of - * 2023-07-01. - * Ideally we would place a time expiry on this key, but since Mojang have not given a hard date for the key change, - * and one bad guess has already caused a major outage, we can't do this. - * TODO: This needs to be removed as soon as the new key is deployed by Mojang's authentication servers. - */ - public const MOJANG_OLD_ROOT_PUBLIC_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V"; - /** * New Mojang root auth key. Mojang notified third-party developers of this change prior to the release of 1.20.0. * Expectations were that this would be used starting a "couple of weeks" after the release, but as of 2023-07-01, @@ -170,7 +160,7 @@ class ProcessLoginTask extends AsyncTask{ throw new VerifyLoginException($e->getMessage(), null, 0, $e); } - if($headers->x5u === self::MOJANG_ROOT_PUBLIC_KEY || $headers->x5u === self::MOJANG_OLD_ROOT_PUBLIC_KEY){ + if($headers->x5u === self::MOJANG_ROOT_PUBLIC_KEY){ $this->authenticated = true; //we're signed into xbox live } From 5718a1a20e03e375cc4798015db27ab5be1b84a5 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Mon, 8 Jan 2024 11:38:29 +0000 Subject: [PATCH 11/38] Reduce frequency of annoying Dependabot updates phpstan is releasing sometimes 4-5 times a week at this point, generating lots of noise. --- .github/dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 518a26c705..8acff71d66 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,7 @@ updates: - package-ecosystem: composer directory: "/" schedule: - interval: daily + interval: weekly time: "10:00" open-pull-requests-limit: 10 ignore: @@ -21,4 +21,4 @@ updates: - package-ecosystem: github-actions directory: "/" schedule: - interval: daily + interval: weekly From 19556634e34c1499e4dd89287dc852ccafbf4bd0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:08:54 +0000 Subject: [PATCH 12/38] Bump build/php from `73e5950` to `6f619bf` (#6220) Bumps [build/php](https://github.com/pmmp/php-build-scripts) from `73e5950` to `6f619bf`. - [Release notes](https://github.com/pmmp/php-build-scripts/releases) - [Commits](https://github.com/pmmp/php-build-scripts/compare/73e5950eb90033a8de589044b92aa5e95de9c494...6f619bf7a0b00e72a7c90915eec6e5a28866aa55) --- updated-dependencies: - dependency-name: build/php dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 73e5950eb9..6f619bf7a0 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 73e5950eb90033a8de589044b92aa5e95de9c494 +Subproject commit 6f619bf7a0b00e72a7c90915eec6e5a28866aa55 From f83280ece615aa9635b4513d6a20df4d4fdd87a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:11:18 +0000 Subject: [PATCH 13/38] Bump tests/plugins/DevTools from `411fd5b` to `c6dca35` (#6216) Bumps [tests/plugins/DevTools](https://github.com/pmmp/DevTools) from `411fd5b` to `c6dca35`. - [Release notes](https://github.com/pmmp/DevTools/releases) - [Commits](https://github.com/pmmp/DevTools/compare/411fd5bdc002edd82cf1ea658d170bb814d59483...c6dca357c7e8a37ce3479a1bedfe849451e072e3) --- updated-dependencies: - dependency-name: tests/plugins/DevTools dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 411fd5bdc0..c6dca357c7 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 411fd5bdc002edd82cf1ea658d170bb814d59483 +Subproject commit c6dca357c7e8a37ce3479a1bedfe849451e072e3 From 5b5c73f660eee54d72f73310c16b5dcdacbeff9c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jan 2024 16:12:03 +0000 Subject: [PATCH 14/38] Matrixify jobs that run on all PHP versions this allows us to specify PHP versions in just one place instead of 4, and also makes the display of jobs in the UI nicer. --- .github/workflows/main-php-matrix.yml | 165 ++++++++++++++++++++++++++ .github/workflows/main.yml | 157 +----------------------- 2 files changed, 171 insertions(+), 151 deletions(-) create mode 100644 .github/workflows/main-php-matrix.yml diff --git a/.github/workflows/main-php-matrix.yml b/.github/workflows/main-php-matrix.yml new file mode 100644 index 0000000000..3bc0bdebf5 --- /dev/null +++ b/.github/workflows/main-php-matrix.yml @@ -0,0 +1,165 @@ +name: CI (all supported PHP versions) + +on: + workflow_call: + inputs: + php: + description: 'PHP version in X.Y format' + required: true + type: string + + #these are parameterized to ease updating + pm-version-major: + description: 'PocketMine-MP major version' + default: 5 + type: number + image: + description: 'Runner image to use' + default: 'ubuntu-20.04' + type: string + +jobs: + phpstan: + name: PHPStan analysis + runs-on: ${{ inputs.image }} + + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: pmmp/setup-php-action@2.0.0 + with: + php-version: ${{ inputs.php }} + install-path: "./bin" + pm-version-major: ${{ inputs.pm-version-major }} + + - name: Restore Composer package cache + uses: actions/cache@v3 + with: + path: | + ~/.cache/composer/files + ~/.cache/composer/vcs + key: "composer-v2-cache-${{ inputs.php }}-${{ hashFiles('./composer.lock') }}" + restore-keys: | + composer-v2-cache- + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-interaction + + - name: Run PHPStan + run: ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G + + phpunit: + name: PHPUnit tests + runs-on: ${{ inputs.image }} + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: pmmp/setup-php-action@2.0.0 + with: + php-version: ${{ inputs.php }} + install-path: "./bin" + pm-version-major: ${{ inputs.pm-version-major }} + + - name: Restore Composer package cache + uses: actions/cache@v3 + with: + path: | + ~/.cache/composer/files + ~/.cache/composer/vcs + key: "composer-v2-cache-${{ inputs.php }}-${{ hashFiles('./composer.lock') }}" + restore-keys: | + composer-v2-cache- + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-interaction + + - name: Run PHPUnit tests + run: ./vendor/bin/phpunit --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit + + integration: + name: Integration tests + runs-on: ${{ inputs.image }} + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Setup PHP + uses: pmmp/setup-php-action@2.0.0 + with: + php-version: ${{ inputs.php }} + install-path: "./bin" + pm-version-major: ${{ inputs.pm-version-major }} + + - name: Restore Composer package cache + uses: actions/cache@v3 + with: + path: | + ~/.cache/composer/files + ~/.cache/composer/vcs + key: "composer-v2-cache-${{ inputs.php }}-${{ hashFiles('./composer.lock') }}" + restore-keys: | + composer-v2-cache- + + - name: Install Composer dependencies + run: composer install --no-dev --prefer-dist --no-interaction + + - name: Run integration tests + run: ./tests/travis.sh -t4 + + codegen: + name: Generated Code consistency checks + runs-on: ${{ inputs.image }} + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: pmmp/setup-php-action@2.0.0 + with: + php-version: ${{ inputs.php }} + install-path: "./bin" + pm-version-major: ${{ inputs.pm-version-major }} + + - name: Restore Composer package cache + uses: actions/cache@v3 + with: + path: | + ~/.cache/composer/files + ~/.cache/composer/vcs + key: "composer-v2-cache-${{ inputs.php }}-${{ hashFiles('./composer.lock') }}" + restore-keys: | + composer-v2-cache- + + - name: Install Composer dependencies + run: composer install --no-dev --prefer-dist --no-interaction + + - name: Regenerate registry annotations + run: php build/generate-registry-annotations.php src + + - name: Regenerate KnownTranslation APIs + run: php build/generate-known-translation-apis.php + + - name: Regenerate BedrockData available files constants + run: php build/generate-bedrockdata-path-consts.php + + - name: Regenerate YmlServerProperties constants + run: php build/generate-pocketmine-yml-property-consts.php + + - name: Verify code is unchanged + run: | + git diff + git diff --quiet diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 32f8be80e5..bcb8036d9b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,162 +6,17 @@ on: workflow_dispatch: jobs: - phpstan: - name: PHPStan analysis - runs-on: ${{ matrix.image }} - + all-php-versions: + name: PHP ${{ matrix.php }} strategy: fail-fast: false matrix: - image: [ubuntu-20.04] php: ["8.1", "8.2", "8.3"] - steps: - - uses: actions/checkout@v4 - - - name: Setup PHP - uses: pmmp/setup-php-action@2.0.0 - with: - php-version: ${{ matrix.php }} - install-path: "./bin" - pm-version-major: "5" - - - name: Restore Composer package cache - uses: actions/cache@v3 - with: - path: | - ~/.cache/composer/files - ~/.cache/composer/vcs - key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}" - restore-keys: | - composer-v2-cache- - - - name: Install Composer dependencies - run: composer install --prefer-dist --no-interaction - - - name: Run PHPStan - run: ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G - - phpunit: - name: PHPUnit tests - runs-on: ${{ matrix.image }} - strategy: - fail-fast: false - matrix: - image: [ubuntu-20.04] - php: ["8.1", "8.2", "8.3"] - - steps: - - uses: actions/checkout@v4 - - - name: Setup PHP - uses: pmmp/setup-php-action@2.0.0 - with: - php-version: ${{ matrix.php }} - install-path: "./bin" - pm-version-major: "5" - - - name: Restore Composer package cache - uses: actions/cache@v3 - with: - path: | - ~/.cache/composer/files - ~/.cache/composer/vcs - key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}" - restore-keys: | - composer-v2-cache- - - - name: Install Composer dependencies - run: composer install --prefer-dist --no-interaction - - - name: Run PHPUnit tests - run: ./vendor/bin/phpunit --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit - - integration: - name: Integration tests - runs-on: ${{ matrix.image }} - strategy: - fail-fast: false - matrix: - image: [ubuntu-20.04] - php: ["8.1", "8.2", "8.3"] - - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Setup PHP - uses: pmmp/setup-php-action@2.0.0 - with: - php-version: ${{ matrix.php }} - install-path: "./bin" - pm-version-major: "5" - - - name: Restore Composer package cache - uses: actions/cache@v3 - with: - path: | - ~/.cache/composer/files - ~/.cache/composer/vcs - key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}" - restore-keys: | - composer-v2-cache- - - - name: Install Composer dependencies - run: composer install --no-dev --prefer-dist --no-interaction - - - name: Run integration tests - run: ./tests/travis.sh -t4 - - codegen: - name: Generated Code consistency checks - runs-on: ${{ matrix.image }} - strategy: - fail-fast: false - matrix: - image: [ubuntu-20.04] - php: ["8.1", "8.2", "8.3"] - - steps: - - uses: actions/checkout@v4 - - - name: Setup PHP - uses: pmmp/setup-php-action@2.0.0 - with: - php-version: ${{ matrix.php }} - install-path: "./bin" - pm-version-major: "5" - - - name: Restore Composer package cache - uses: actions/cache@v3 - with: - path: | - ~/.cache/composer/files - ~/.cache/composer/vcs - key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}" - restore-keys: | - composer-v2-cache- - - - name: Install Composer dependencies - run: composer install --no-dev --prefer-dist --no-interaction - - - name: Regenerate registry annotations - run: php build/generate-registry-annotations.php src - - - name: Regenerate KnownTranslation APIs - run: php build/generate-known-translation-apis.php - - - name: Regenerate BedrockData available files constants - run: php build/generate-bedrockdata-path-consts.php - - - name: Regenerate YmlServerProperties constants - run: php build/generate-pocketmine-yml-property-consts.php - - - name: Verify code is unchanged - run: | - git diff - git diff --quiet + uses: ./.github/workflows/main-php-matrix.yml + with: + php: ${{ matrix.php }} + secrets: inherit codestyle: name: Code Style checks From ee977c80015433d2f9b48ea9dbbef666f6456f0d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jan 2024 16:18:13 +0000 Subject: [PATCH 15/38] Updated composer dependencies --- composer.lock | 78 ++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/composer.lock b/composer.lock index f8e0b31af6..24d36cd5fe 100644 --- a/composer.lock +++ b/composer.lock @@ -1211,25 +1211,27 @@ }, { "name": "nikic/php-parser", - "version": "v4.18.0", + "version": "v5.0.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -1237,7 +1239,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1261,9 +1263,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0" }, - "time": "2023-12-10T21:03:43+00:00" + "time": "2024-01-07T17:17:35+00:00" }, { "name": "phar-io/manifest", @@ -1541,23 +1543,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.10", + "version": "10.1.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "599109c8ca6bae97b23482d557d2874c25a65e59" + "reference": "78c3b7625965c2513ee96569a4dbb62601784145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/599109c8ca6bae97b23482d557d2874c25a65e59", - "reference": "599109c8ca6bae97b23482d557d2874c25a65e59", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145", + "reference": "78c3b7625965c2513ee96569a4dbb62601784145", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1", "phpunit/php-file-iterator": "^4.0", "phpunit/php-text-template": "^3.0", @@ -1607,7 +1609,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.10" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11" }, "funding": [ { @@ -1615,7 +1617,7 @@ "type": "github" } ], - "time": "2023-12-11T06:28:43+00:00" + "time": "2023-12-21T15:38:30+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2207,20 +2209,20 @@ }, { "name": "sebastian/complexity", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { - "nikic/php-parser": "^4.10", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1" }, "require-dev": { @@ -2229,7 +2231,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -2253,7 +2255,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -2261,20 +2263,20 @@ "type": "github" } ], - "time": "2023-09-28T11:50:59+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", - "version": "5.0.3", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f", "shasum": "" }, "require": { @@ -2287,7 +2289,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -2320,7 +2322,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0" }, "funding": [ { @@ -2328,7 +2330,7 @@ "type": "github" } ], - "time": "2023-05-01T07:48:21+00:00" + "time": "2023-12-22T10:55:06+00:00" }, { "name": "sebastian/environment", @@ -2536,20 +2538,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.10", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1" }, "require-dev": { @@ -2582,7 +2584,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -2590,7 +2592,7 @@ "type": "github" } ], - "time": "2023-08-31T09:25:50+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", From 4db38ee45201ed9fb9bf0eb1ecb5007e64b40ca9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jan 2024 16:20:42 +0000 Subject: [PATCH 16/38] Updated PHPStan --- build/server-phar.php | 12 +++++++++++- composer.json | 2 +- composer.lock | 12 ++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/build/server-phar.php b/build/server-phar.php index 0665c89d5d..8b4d410ce1 100644 --- a/build/server-phar.php +++ b/build/server-phar.php @@ -32,6 +32,7 @@ use function getcwd; use function getopt; use function implode; use function ini_get; +use function is_string; use function microtime; use function preg_quote; use function realpath; @@ -147,8 +148,17 @@ function main() : void{ }else{ $build = 0; } + if(isset($opts["out"])){ + if(!is_string($opts["out"])){ + echo "--out cannot be specified multiple times" . PHP_EOL; + exit(1); + } + $pharPath = $opts["out"]; + }else{ + $pharPath = getcwd() . DIRECTORY_SEPARATOR . "PocketMine-MP.phar"; + } foreach(buildPhar( - $opts["out"] ?? getcwd() . DIRECTORY_SEPARATOR . "PocketMine-MP.phar", + $pharPath, dirname(__DIR__) . DIRECTORY_SEPARATOR, [ 'resources', diff --git a/composer.json b/composer.json index bcec3a72b8..953f06931e 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.10.50", + "phpstan/phpstan": "1.10.55", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", "phpunit/phpunit": "~10.3.0 || ~10.2.0 || ~10.1.0" diff --git a/composer.lock b/composer.lock index 24d36cd5fe..0a2539521f 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": "894648a63ed7cd84303937208d1684af", + "content-hash": "d7a3fceea557add1b8cb461554db1ee7", "packages": [ { "name": "adhocore/json-comment", @@ -1380,16 +1380,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.50", + "version": "1.10.55", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4" + "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/06a98513ac72c03e8366b5a0cb00750b487032e4", - "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", + "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", "shasum": "" }, "require": { @@ -1438,7 +1438,7 @@ "type": "tidelift" } ], - "time": "2023-12-13T10:59:42+00:00" + "time": "2024-01-08T12:32:40+00:00" }, { "name": "phpstan/phpstan-phpunit", From db3bb55a2bf9daa658af6c119d2da9335d6a23bf Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Tue, 9 Jan 2024 12:28:20 +0000 Subject: [PATCH 17/38] Change `PHP_DEBUG` constant usage to `ZEND_DEBUG_BUILD` In PHP 8.4, the type of `PHP_DEBUG` changes from `int` to `bool`. See [PHP.Watch: PHP 8.4: `PHP_ZTS` and `PHP_DEBUG` constant value type changed from `int` to `bool`](https://php.watch/versions/8.4/PHP_ZTS-PHP_DEBUG-const-type-change). This changes the constants to `ZEND_DEBUG_BUILD`, which contains the same value but as a `bool` across all PHP versions. closes #6222 --- src/PocketMine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 72d72506d3..1209b28f02 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -166,7 +166,7 @@ namespace pocketmine { * @return void */ function emit_performance_warnings(\Logger $logger){ - if(PHP_DEBUG !== 0){ + if(ZEND_DEBUG_BUILD){ $logger->warning("This PHP binary was compiled in debug mode. This has a major impact on performance."); } if(extension_loaded("xdebug") && (!function_exists('xdebug_info') || count(xdebug_info('mode')) !== 0)){ From 9b03b082ab4b2b18a194419fb49066198d24ad1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jan 2024 13:04:14 +0000 Subject: [PATCH 18/38] Added --version option --- src/BootstrapOptions.php | 2 ++ src/PocketMine.php | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/BootstrapOptions.php b/src/BootstrapOptions.php index 879c502a69..c34dda94b9 100644 --- a/src/BootstrapOptions.php +++ b/src/BootstrapOptions.php @@ -45,4 +45,6 @@ final class BootstrapOptions{ public const PLUGINS = "plugins"; /** Path to store and load server data */ public const DATA = "data"; + /** Shows basic server version information and exits */ + public const VERSION = "version"; } diff --git a/src/PocketMine.php b/src/PocketMine.php index 1209b28f02..d13cf33a1a 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -25,6 +25,7 @@ namespace pocketmine { use Composer\InstalledVersions; use pocketmine\errorhandler\ErrorToExceptionHandler; + use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\thread\ThreadManager; use pocketmine\thread\ThreadSafeClassLoader; use pocketmine\utils\Filesystem; @@ -40,14 +41,17 @@ namespace pocketmine { use function extension_loaded; use function function_exists; use function getcwd; + use function getopt; use function is_dir; use function mkdir; use function phpversion; use function preg_match; use function preg_quote; + use function printf; use function realpath; use function version_compare; use const DIRECTORY_SEPARATOR; + use const PHP_EOL; require_once __DIR__ . '/VersionInfo.php'; @@ -273,6 +277,11 @@ JIT_WARNING ErrorToExceptionHandler::set(); + if(count(getopt("", [BootstrapOptions::VERSION])) > 0){ + printf("%s %s (git hash %s) for Minecraft: Bedrock Edition %s\n", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true), VersionInfo::GIT_HASH(), ProtocolInfo::MINECRAFT_VERSION); + exit(0); + } + $cwd = Utils::assumeNotFalse(realpath(Utils::assumeNotFalse(getcwd()))); $dataPath = getopt_string(BootstrapOptions::DATA) ?? $cwd; $pluginPath = getopt_string(BootstrapOptions::PLUGINS) ?? $cwd . DIRECTORY_SEPARATOR . "plugins"; From 288bd4018baf6c92ce7e3f2264fb8d4e7f6e1bc5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jan 2024 13:35:10 +0000 Subject: [PATCH 19/38] Block: deprecate isSolid() As discussed many years ago in #2551, no one actually knows what this property actually means. It definitely isn't the conventionally expected definition of 'solid' found in the real world, as signs are solid but flower pots are not. --- src/block/Block.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/block/Block.php b/src/block/Block.php index b2847bb358..d6158ea947 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -576,6 +576,15 @@ class Block{ return false; } + /** + * @deprecated TL;DR: Don't use this function. Its results are confusing and inconsistent. + * + * No one is sure what the meaning of this property actually is. It's borrowed from Minecraft Java Edition, and is + * used by various blocks for support checks. + * + * Things like signs and banners are considered "solid" despite having no collision box, and things like skulls and + * flower pots are considered non-solid despite obviously being "solid" in the conventional, real-world sense. + */ public function isSolid() : bool{ return true; } From a459e3c1a9c3f485c7073aa06a2c09b3ff884570 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jan 2024 13:35:36 +0000 Subject: [PATCH 20/38] Block: improve some documentation --- src/block/Block.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index d6158ea947..dbc269c630 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -402,7 +402,7 @@ class Block{ } /** - * AKA: Block->isPlaceable + * Returns whether this block can be placed when obtained as an item. */ public function canBePlaced() : bool{ return true; @@ -572,6 +572,9 @@ class Block{ return $this->getLightFilter() > 0; } + /** + * Returns whether this block allows any light to pass through it. + */ public function isTransparent() : bool{ return false; } @@ -590,7 +593,7 @@ class Block{ } /** - * AKA: Block->isFlowable + * Returns whether this block can be destroyed by liquid flowing into its cell. */ public function canBeFlowedInto() : bool{ return false; From e77cd39316999a382a2b197152ef23f6bdde03b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jan 2024 15:55:41 +0000 Subject: [PATCH 21/38] ItemBlock: add a workaround for air items with a stack size bigger than 0 In the future we should look into making empty slots be represented by null or a different, special item type, instead of breaking the air block for this purpose. closes #6185 closes #6016 --- src/item/ItemBlock.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index 11bcb58d37..015c784714 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; +use pocketmine\block\BlockTypeIds; use pocketmine\data\runtime\RuntimeDataDescriber; /** @@ -58,4 +59,12 @@ final class ItemBlock extends Item{ public function getMaxStackSize() : int{ return $this->block->getMaxStackSize(); } + + public function isNull() : bool{ + //TODO: we really shouldn't need to treat air as a special case here + //this is needed because the "null" empty slot item is represented by an air block, but there's no real reason + //why air should be needed at all. A separate special item type (or actual null) should be used instead, but + //this would cause a lot of BC breaks, so we can't do it yet. + return parent::isNull() || $this->block->getTypeId() === BlockTypeIds::AIR; + } } From c7c20d4d7906674cee099c191165935075af4f8f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jan 2024 16:43:11 +0000 Subject: [PATCH 22/38] tools/generate-block-palette-spec: fixed sorting --- tools/generate-block-palette-spec.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/generate-block-palette-spec.php b/tools/generate-block-palette-spec.php index 6217d54378..879ffd6b48 100644 --- a/tools/generate-block-palette-spec.php +++ b/tools/generate-block-palette-spec.php @@ -40,6 +40,7 @@ use function get_class; use function json_encode; use function ksort; use const JSON_PRETTY_PRINT; +use const SORT_NATURAL; use const SORT_STRING; use const STDERR; @@ -82,7 +83,7 @@ foreach($states as $state){ foreach(Utils::stringifyKeys($reportMap) as $blockName => $propertyList){ foreach(Utils::stringifyKeys($propertyList) as $propertyName => $propertyValues){ - ksort($reportMap[$blockName][$propertyName]); + ksort($propertyValues, SORT_NATURAL); $reportMap[$blockName][$propertyName] = array_values($propertyValues); } } From d97c8e2fd2b40cf778ae2f952e2520183fc4902f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jan 2024 18:48:32 +0000 Subject: [PATCH 23/38] tools/generate-item-upgrade-schema: filter old IDs that were already renamed by previous schemas this caused weird outputs if an item was renamed multiple times. --- tools/generate-item-upgrade-schema.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/generate-item-upgrade-schema.php b/tools/generate-item-upgrade-schema.php index c6096bafba..4eee925392 100644 --- a/tools/generate-item-upgrade-schema.php +++ b/tools/generate-item-upgrade-schema.php @@ -94,9 +94,14 @@ foreach($files as $file){ $newDiff = []; foreach($target["simple"] as $oldId => $newId){ - if(($merged["simple"][$oldId] ?? null) !== $newId){ - $newDiff["renamedIds"][$oldId] = $newId; + $previousNewId = $merged["simple"][$oldId] ?? null; + if( + $previousNewId === $newId || //if previous schemas already accounted for this + ($previousNewId !== null && isset($target["simple"][$previousNewId])) //or the item's ID has been changed for a second time + ){ + continue; } + $newDiff["renamedIds"][$oldId] = $newId; } if(isset($newDiff["renamedIds"])){ ksort($newDiff["renamedIds"], SORT_STRING); From 81d5b9ba0676ee520cb9a80a45965952055bc2dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jan 2024 18:49:06 +0000 Subject: [PATCH 24/38] tools/generate-bedrock-data-from-packets: add more exception detail for unexpected block runtimeIDs --- tools/generate-bedrock-data-from-packets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/generate-bedrock-data-from-packets.php b/tools/generate-bedrock-data-from-packets.php index 7316b3f867..77d2b9d93f 100644 --- a/tools/generate-bedrock-data-from-packets.php +++ b/tools/generate-bedrock-data-from-packets.php @@ -165,7 +165,7 @@ class ParserPacketHandler extends PacketHandler{ $data->block_states = self::blockStatePropertiesToString($blockState); } }elseif($itemStack->getBlockRuntimeId() !== ItemTranslator::NO_BLOCK_RUNTIME_ID){ - throw new PacketHandlingException("Non-blockitems should have a zero block runtime ID"); + throw new PacketHandlingException("Non-blockitems should have a zero block runtime ID (" . $itemStack->getBlockRuntimeId() . " on " . $itemStringId . ")"); }elseif($meta !== 0){ $data->meta = $meta; } From e28d20a68ed7afaf662df35deac6de76a1f07a67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:29:34 +0000 Subject: [PATCH 25/38] Bump shivammathur/setup-php from 2.28.0 to 2.29.0 (#6228) Bumps [shivammathur/setup-php](https://github.com/shivammathur/setup-php) from 2.28.0 to 2.29.0. - [Release notes](https://github.com/shivammathur/setup-php/releases) - [Commits](https://github.com/shivammathur/setup-php/compare/2.28.0...2.29.0) --- updated-dependencies: - dependency-name: shivammathur/setup-php dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/discord-release-notify.yml | 2 +- .github/workflows/draft-release.yml | 2 +- .github/workflows/main.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/discord-release-notify.yml b/.github/workflows/discord-release-notify.yml index 6081b8fd8c..77a231f4de 100644 --- a/.github/workflows/discord-release-notify.yml +++ b/.github/workflows/discord-release-notify.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.28.0 + uses: shivammathur/setup-php@2.29.0 with: php-version: 8.2 diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 62fa413328..bc72cfa201 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -20,7 +20,7 @@ jobs: submodules: true - name: Setup PHP - uses: shivammathur/setup-php@2.28.0 + uses: shivammathur/setup-php@2.29.0 with: php-version: ${{ matrix.php-version }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bcb8036d9b..ecadf8af3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.28.0 + uses: shivammathur/setup-php@2.29.0 with: php-version: 8.2 tools: php-cs-fixer:3.38 From 234199d241b99409b2726afe87f7605f626ba48d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:29:49 +0000 Subject: [PATCH 26/38] Bump actions/cache from 3 to 4 (#6229) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/discord-release-notify.yml | 2 +- .github/workflows/draft-release.yml | 2 +- .github/workflows/main-php-matrix.yml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/discord-release-notify.yml b/.github/workflows/discord-release-notify.yml index 77a231f4de..f02f047123 100644 --- a/.github/workflows/discord-release-notify.yml +++ b/.github/workflows/discord-release-notify.yml @@ -18,7 +18,7 @@ jobs: php-version: 8.2 - name: Restore Composer package cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/composer/files diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index bc72cfa201..77467fad21 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -25,7 +25,7 @@ jobs: php-version: ${{ matrix.php-version }} - name: Restore Composer package cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/composer/files diff --git a/.github/workflows/main-php-matrix.yml b/.github/workflows/main-php-matrix.yml index 3bc0bdebf5..110f8d0edd 100644 --- a/.github/workflows/main-php-matrix.yml +++ b/.github/workflows/main-php-matrix.yml @@ -37,7 +37,7 @@ jobs: pm-version-major: ${{ inputs.pm-version-major }} - name: Restore Composer package cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/composer/files @@ -69,7 +69,7 @@ jobs: pm-version-major: ${{ inputs.pm-version-major }} - name: Restore Composer package cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/composer/files @@ -103,7 +103,7 @@ jobs: pm-version-major: ${{ inputs.pm-version-major }} - name: Restore Composer package cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/composer/files @@ -135,7 +135,7 @@ jobs: pm-version-major: ${{ inputs.pm-version-major }} - name: Restore Composer package cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/composer/files From 5709d727a2fb24125be6da80c1cf15a99c0f3a83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:30:19 +0000 Subject: [PATCH 27/38] Bump phpstan/phpstan from 1.10.55 to 1.10.57 (#6235) Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.10.55 to 1.10.57. - [Release notes](https://github.com/phpstan/phpstan/releases) - [Changelog](https://github.com/phpstan/phpstan/blob/1.11.x/CHANGELOG.md) - [Commits](https://github.com/phpstan/phpstan/compare/1.10.55...1.10.57) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 953f06931e..728478e485 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.10.55", + "phpstan/phpstan": "1.10.57", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", "phpunit/phpunit": "~10.3.0 || ~10.2.0 || ~10.1.0" diff --git a/composer.lock b/composer.lock index 0a2539521f..a668d5aad5 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": "d7a3fceea557add1b8cb461554db1ee7", + "content-hash": "fecd5b7c364cb3a0f3a832004f594101", "packages": [ { "name": "adhocore/json-comment", @@ -1380,16 +1380,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.55", + "version": "1.10.57", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949" + "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", - "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1627b1d03446904aaa77593f370c5201d2ecc34e", + "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e", "shasum": "" }, "require": { @@ -1438,7 +1438,7 @@ "type": "tidelift" } ], - "time": "2024-01-08T12:32:40+00:00" + "time": "2024-01-24T11:51:34+00:00" }, { "name": "phpstan/phpstan-phpunit", From f207d1bbf244636de69a05d468926e530f60bec1 Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Mon, 5 Feb 2024 07:36:09 -0500 Subject: [PATCH 28/38] Make CocoaBlock Flowable (#6218) --- src/block/CocoaBlock.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 5cec4b933a..6d8ce1adc9 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\utils\AgeableTrait; use pocketmine\block\utils\BlockEventHelper; use pocketmine\block\utils\HorizontalFacingTrait; -use pocketmine\block\utils\SupportType; use pocketmine\block\utils\WoodType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Fertilizer; @@ -40,7 +39,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function mt_rand; -class CocoaBlock extends Transparent{ +class CocoaBlock extends Flowable{ use HorizontalFacingTrait; use AgeableTrait; @@ -65,10 +64,6 @@ class CocoaBlock extends Transparent{ ]; } - public function getSupportType(int $facing) : SupportType{ - return SupportType::NONE; - } - private function canAttachTo(Block $block) : bool{ return $block instanceof Wood && $block->getWoodType() === WoodType::JUNGLE; } From 6bb84bc46cbf8352824628c270b57bb037c591d2 Mon Sep 17 00:00:00 2001 From: ShockedPlot7560 Date: Tue, 6 Feb 2024 13:42:24 +0100 Subject: [PATCH 29/38] Add `Promise::all` (#6152) --- src/promise/Promise.php | 50 +++++++++++ tests/phpstan/configs/phpstan-bugs.neon | 15 ++++ tests/phpunit/promise/PromiseTest.php | 106 ++++++++++++++++++++++++ 3 files changed, 171 insertions(+) diff --git a/src/promise/Promise.php b/src/promise/Promise.php index bafec09797..0def7e6052 100644 --- a/src/promise/Promise.php +++ b/src/promise/Promise.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\promise; +use function count; use function spl_object_id; /** @@ -57,4 +58,53 @@ final class Promise{ //rejected or just hasn't been resolved yet return $this->shared->state === true; } + + /** + * Returns a promise that will resolve only once all the Promises in + * `$promises` have resolved. The resolution value of the returned promise + * will be an array containing the resolution values of each Promises in + * `$promises` indexed by the respective Promises' array keys. + * + * @param Promise[] $promises + * + * @phpstan-template TPromiseValue + * @phpstan-template TKey of array-key + * @phpstan-param non-empty-array> $promises + * + * @phpstan-return Promise> + */ + public static function all(array $promises) : Promise{ + if(count($promises) === 0){ + throw new \InvalidArgumentException("At least one promise must be provided"); + } + /** @phpstan-var PromiseResolver> $resolver */ + $resolver = new PromiseResolver(); + $values = []; + $toResolve = count($promises); + $continue = true; + + foreach($promises as $key => $promise){ + $promise->onCompletion( + function(mixed $value) use ($resolver, $key, $toResolve, &$values) : void{ + $values[$key] = $value; + + if(count($values) === $toResolve){ + $resolver->resolve($values); + } + }, + function() use ($resolver, &$continue) : void{ + if($continue){ + $continue = false; + $resolver->reject(); + } + } + ); + + if(!$continue){ + break; + } + } + + return $resolver->getPromise(); + } } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index af04866114..de38903bd3 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -35,3 +35,18 @@ parameters: count: 1 path: ../../../src/world/generator/normal/Normal.php + - + message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertFalse\\(\\) with false will always evaluate to true\\.$#" + count: 1 + path: ../../phpunit/promise/PromiseTest.php + + - + message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertTrue\\(\\) with false and 'All promise should…' will always evaluate to false\\.$#" + count: 1 + path: ../../phpunit/promise/PromiseTest.php + + - + message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertTrue\\(\\) with false will always evaluate to false\\.$#" + count: 2 + path: ../../phpunit/promise/PromiseTest.php + diff --git a/tests/phpunit/promise/PromiseTest.php b/tests/phpunit/promise/PromiseTest.php index 7198f4f619..682ee00703 100644 --- a/tests/phpunit/promise/PromiseTest.php +++ b/tests/phpunit/promise/PromiseTest.php @@ -39,4 +39,110 @@ final class PromiseTest extends TestCase{ } ); } + + public function testAllPreResolved() : void{ + $resolver = new PromiseResolver(); + $resolver->resolve(1); + + $allPromise = Promise::all([$resolver->getPromise()]); + $done = false; + $allPromise->onCompletion( + function($value) use (&$done) : void{ + $done = true; + self::assertEquals([1], $value); + }, + function() use (&$done) : void{ + $done = true; + self::fail("Promise was rejected"); + } + ); + self::assertTrue($done); + } + + public function testAllPostResolved() : void{ + $resolver = new PromiseResolver(); + + $allPromise = Promise::all([$resolver->getPromise()]); + $done = false; + $allPromise->onCompletion( + function($value) use (&$done) : void{ + $done = true; + self::assertEquals([1], $value); + }, + function() use (&$done) : void{ + $done = true; + self::fail("Promise was rejected"); + } + ); + self::assertFalse($done); + $resolver->resolve(1); + self::assertTrue($done); + } + + public function testAllResolve() : void{ + $resolver1 = new PromiseResolver(); + $resolver2 = new PromiseResolver(); + + $allPromise = Promise::all([$resolver1->getPromise(), $resolver2->getPromise()]); + $done = false; + $allPromise->onCompletion( + function($value) use (&$done) : void{ + $done = true; + self::assertEquals([1, 2], $value); + }, + function() use (&$done) : void{ + $done = true; + self::fail("Promise was rejected"); + } + ); + self::assertFalse($done); + $resolver1->resolve(1); + self::assertFalse($done); + $resolver2->resolve(2); + self::assertTrue($done); + } + + public function testAllPartialReject() : void{ + $resolver1 = new PromiseResolver(); + $resolver2 = new PromiseResolver(); + + $allPromise = Promise::all([$resolver1->getPromise(), $resolver2->getPromise()]); + $done = false; + $allPromise->onCompletion( + function($value) use (&$done) : void{ + $done = true; + self::fail("Promise was unexpectedly resolved"); + }, + function() use (&$done) : void{ + $done = true; + } + ); + self::assertFalse($done); + $resolver2->reject(); + self::assertTrue($done, "All promise should be rejected immediately after the first constituent rejection"); + $resolver1->resolve(1); + } + + /** + * Promise::all() should return a rejected promise if any of the input promises were rejected at the call time + */ + public function testAllPartialPreReject() : void{ + $resolver1 = new PromiseResolver(); + $resolver2 = new PromiseResolver(); + $resolver2->reject(); + + $allPromise = Promise::all([$resolver1->getPromise(), $resolver2->getPromise()]); + $done = false; + $allPromise->onCompletion( + function($value) use (&$done) : void{ + $done = true; + self::fail("Promise was unexpectedly resolved"); + }, + function() use (&$done) : void{ + $done = true; + } + ); + self::assertTrue($done, "All promise should be rejected immediately after the first constituent rejection"); + $resolver1->resolve(1); + } } From 6492e7f4a2b95465a9ec7d54f111fd3170d9f609 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 12:33:44 +0000 Subject: [PATCH 30/38] 1.20.60 support --- composer.json | 8 +-- composer.lock | 50 +++++++++---------- src/Server.php | 31 ++++++++---- src/data/bedrock/block/BlockStateData.php | 2 +- src/data/bedrock/block/BlockStateNames.php | 2 +- .../bedrock/block/BlockStateStringValues.php | 17 ------- src/data/bedrock/block/BlockTypeNames.php | 35 ++++++++++++- .../convert/BlockObjectToStateSerializer.php | 46 ++++++++++++++--- .../block/convert/BlockStateReader.php | 25 ---------- .../BlockStateToObjectDeserializer.php | 50 ++++++++++++++++--- .../block/convert/BlockStateWriter.php | 24 --------- .../ItemSerializerDeserializerRegistrar.php | 2 +- src/data/bedrock/item/ItemTypeNames.php | 9 +++- src/network/mcpe/ChunkRequestTask.php | 21 ++++++-- src/network/mcpe/NetworkSession.php | 28 ++++++++--- src/network/mcpe/cache/ChunkCache.php | 2 + .../mcpe/compression/CompressBatchTask.php | 3 +- src/network/mcpe/compression/Compressor.php | 10 ++++ .../mcpe/compression/ZlibCompressor.php | 5 ++ .../handler/SessionStartPacketHandler.php | 3 +- .../mcpe/serializer/ChunkSerializer.php | 40 ++++++++++++--- src/world/format/io/data/BedrockWorldData.php | 6 +-- 22 files changed, 267 insertions(+), 152 deletions(-) diff --git a/composer.json b/composer.json index 728478e485..47e798b164 100644 --- a/composer.json +++ b/composer.json @@ -33,10 +33,10 @@ "composer-runtime-api": "^2.0", "adhocore/json-comment": "~1.2.0", "pocketmine/netresearch-jsonmapper": "~v4.2.1000", - "pocketmine/bedrock-block-upgrade-schema": "~3.4.0+bedrock-1.20.50", - "pocketmine/bedrock-data": "~2.7.0+bedrock-1.20.50", - "pocketmine/bedrock-item-upgrade-schema": "~1.6.0+bedrock-1.20.50", - "pocketmine/bedrock-protocol": "~26.0.0+bedrock-1.20.50", + "pocketmine/bedrock-block-upgrade-schema": "~3.5.0+bedrock-1.20.60", + "pocketmine/bedrock-data": "~2.8.0+bedrock-1.20.60", + "pocketmine/bedrock-item-upgrade-schema": "~1.7.0+bedrock-1.20.60", + "pocketmine/bedrock-protocol": "~27.0.0+bedrock-1.20.60", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/color": "^0.3.0", diff --git a/composer.lock b/composer.lock index a668d5aad5..47aeeaecab 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": "fecd5b7c364cb3a0f3a832004f594101", + "content-hash": "d923f5fd75f0d33eb5198268a74a58b4", "packages": [ { "name": "adhocore/json-comment", @@ -122,16 +122,16 @@ }, { "name": "pocketmine/bedrock-block-upgrade-schema", - "version": "3.4.0", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git", - "reference": "9872eb37f15080b19c2b7861085e549c48dda92d" + "reference": "1ed4ba738333c4b4afe4fef8e9326a45c89f12e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/9872eb37f15080b19c2b7861085e549c48dda92d", - "reference": "9872eb37f15080b19c2b7861085e549c48dda92d", + "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/1ed4ba738333c4b4afe4fef8e9326a45c89f12e3", + "reference": "1ed4ba738333c4b4afe4fef8e9326a45c89f12e3", "shasum": "" }, "type": "library", @@ -142,22 +142,22 @@ "description": "Schemas describing how to upgrade saved block data in older Minecraft: Bedrock Edition world saves", "support": { "issues": "https://github.com/pmmp/BedrockBlockUpgradeSchema/issues", - "source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/3.4.0" + "source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/3.5.0" }, - "time": "2023-11-08T15:22:06+00:00" + "time": "2024-02-07T11:46:50+00:00" }, { "name": "pocketmine/bedrock-data", - "version": "2.7.0+bedrock-1.20.50", + "version": "2.8.0+bedrock-1.20.60", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "36f975dfca7520b7d36b0b39429f274464c9bc13" + "reference": "d8ea0355b7c835564af9fe6e273e650ac62c84a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/36f975dfca7520b7d36b0b39429f274464c9bc13", - "reference": "36f975dfca7520b7d36b0b39429f274464c9bc13", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/d8ea0355b7c835564af9fe6e273e650ac62c84a2", + "reference": "d8ea0355b7c835564af9fe6e273e650ac62c84a2", "shasum": "" }, "type": "library", @@ -168,22 +168,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.20.50" + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.20.60" }, - "time": "2023-12-06T13:59:08+00:00" + "time": "2024-02-07T11:23:46+00:00" }, { "name": "pocketmine/bedrock-item-upgrade-schema", - "version": "1.6.0", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git", - "reference": "d374e5fd8302977675dcd2a42733abd3ee476ca1" + "reference": "69772dd58e2b2c7b7513fa2bcdc46e782228641c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/d374e5fd8302977675dcd2a42733abd3ee476ca1", - "reference": "d374e5fd8302977675dcd2a42733abd3ee476ca1", + "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/69772dd58e2b2c7b7513fa2bcdc46e782228641c", + "reference": "69772dd58e2b2c7b7513fa2bcdc46e782228641c", "shasum": "" }, "type": "library", @@ -194,22 +194,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.6.0" + "source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.7.0" }, - "time": "2023-11-08T18:12:14+00:00" + "time": "2024-02-07T11:58:05+00:00" }, { "name": "pocketmine/bedrock-protocol", - "version": "26.0.0+bedrock-1.20.50", + "version": "27.0.1+bedrock-1.20.60", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "f278a0b6d4fa1e2e0408a125f323a3118b1968df" + "reference": "0cebb55f6e904f722b14d420f6b2c84c7fa69f10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/f278a0b6d4fa1e2e0408a125f323a3118b1968df", - "reference": "f278a0b6d4fa1e2e0408a125f323a3118b1968df", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/0cebb55f6e904f722b14d420f6b2c84c7fa69f10", + "reference": "0cebb55f6e904f722b14d420f6b2c84c7fa69f10", "shasum": "" }, "require": { @@ -241,9 +241,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/26.0.0+bedrock-1.20.50" + "source": "https://github.com/pmmp/BedrockProtocol/tree/27.0.1+bedrock-1.20.60" }, - "time": "2023-12-06T14:08:37+00:00" + "time": "2024-02-07T11:53:50+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/Server.php b/src/Server.php index 48f641947d..3f12f7669a 100644 --- a/src/Server.php +++ b/src/Server.php @@ -60,6 +60,7 @@ use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketBroadcaster; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; +use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\mcpe\StandardEntityEventBroadcaster; use pocketmine\network\mcpe\StandardPacketBroadcaster; @@ -125,6 +126,7 @@ use Symfony\Component\Filesystem\Path; use function array_fill; use function array_sum; use function base64_encode; +use function chr; use function cli_set_process_title; use function copy; use function count; @@ -1373,19 +1375,26 @@ class Server{ try{ $timings->startTiming(); - if($sync === null){ - $threshold = $compressor->getCompressionThreshold(); - $sync = !$this->networkCompressionAsync || $threshold === null || strlen($buffer) < $threshold; + $threshold = $compressor->getCompressionThreshold(); + if($threshold === null || strlen($buffer) < $compressor->getCompressionThreshold()){ + $compressionType = CompressionAlgorithm::NONE; + $compressed = $buffer; + + }else{ + $sync ??= !$this->networkCompressionAsync; + + if(!$sync && strlen($buffer) >= $this->networkCompressionAsyncThreshold){ + $promise = new CompressBatchPromise(); + $task = new CompressBatchTask($buffer, $promise, $compressor); + $this->asyncPool->submitTask($task); + return $promise; + } + + $compressionType = $compressor->getNetworkId(); + $compressed = $compressor->compress($buffer); } - if(!$sync && strlen($buffer) >= $this->networkCompressionAsyncThreshold){ - $promise = new CompressBatchPromise(); - $task = new CompressBatchTask($buffer, $promise, $compressor); - $this->asyncPool->submitTask($task); - return $promise; - } - - return $compressor->compress($buffer); + return chr($compressionType) . $compressed; }finally{ $timings->stopTiming(); } diff --git a/src/data/bedrock/block/BlockStateData.php b/src/data/bedrock/block/BlockStateData.php index 1417fa0144..b089eea5bd 100644 --- a/src/data/bedrock/block/BlockStateData.php +++ b/src/data/bedrock/block/BlockStateData.php @@ -42,7 +42,7 @@ final class BlockStateData{ public const CURRENT_VERSION = (1 << 24) | //major (20 << 16) | //minor - (50 << 8) | //patch + (60 << 8) | //patch (1); //revision public const TAG_NAME = "name"; diff --git a/src/data/bedrock/block/BlockStateNames.php b/src/data/bedrock/block/BlockStateNames.php index 9b28e936d8..75b45e88ec 100644 --- a/src/data/bedrock/block/BlockStateNames.php +++ b/src/data/bedrock/block/BlockStateNames.php @@ -56,7 +56,6 @@ final class BlockStateNames{ public const CHEMISTRY_TABLE_TYPE = "chemistry_table_type"; public const CHISEL_TYPE = "chisel_type"; public const CLUSTER_COUNT = "cluster_count"; - public const COLOR = "color"; public const COLOR_BIT = "color_bit"; public const COMPOSTER_FILL_LEVEL = "composter_fill_level"; public const CONDITIONAL_BIT = "conditional_bit"; @@ -145,6 +144,7 @@ final class BlockStateNames{ public const TALL_GRASS_TYPE = "tall_grass_type"; public const TOGGLE_BIT = "toggle_bit"; public const TORCH_FACING_DIRECTION = "torch_facing_direction"; + public const TRIAL_SPAWNER_STATE = "trial_spawner_state"; public const TRIGGERED_BIT = "triggered_bit"; public const TURTLE_EGG_COUNT = "turtle_egg_count"; public const TWISTING_VINES_AGE = "twisting_vines_age"; diff --git a/src/data/bedrock/block/BlockStateStringValues.php b/src/data/bedrock/block/BlockStateStringValues.php index 4a05fa33e9..d9d8a748d0 100644 --- a/src/data/bedrock/block/BlockStateStringValues.php +++ b/src/data/bedrock/block/BlockStateStringValues.php @@ -62,23 +62,6 @@ final class BlockStateStringValues{ public const CHISEL_TYPE_LINES = "lines"; public const CHISEL_TYPE_SMOOTH = "smooth"; - public const COLOR_BLACK = "black"; - public const COLOR_BLUE = "blue"; - public const COLOR_BROWN = "brown"; - public const COLOR_CYAN = "cyan"; - public const COLOR_GRAY = "gray"; - public const COLOR_GREEN = "green"; - public const COLOR_LIGHT_BLUE = "light_blue"; - public const COLOR_LIME = "lime"; - public const COLOR_MAGENTA = "magenta"; - public const COLOR_ORANGE = "orange"; - public const COLOR_PINK = "pink"; - public const COLOR_PURPLE = "purple"; - public const COLOR_RED = "red"; - public const COLOR_SILVER = "silver"; - public const COLOR_WHITE = "white"; - public const COLOR_YELLOW = "yellow"; - public const CORAL_COLOR_BLUE = "blue"; public const CORAL_COLOR_PINK = "pink"; public const CORAL_COLOR_PURPLE = "purple"; diff --git a/src/data/bedrock/block/BlockTypeNames.php b/src/data/bedrock/block/BlockTypeNames.php index fdca40a3a9..1d8bfadfa4 100644 --- a/src/data/bedrock/block/BlockTypeNames.php +++ b/src/data/bedrock/block/BlockTypeNames.php @@ -517,10 +517,40 @@ final class BlockTypeNames{ public const GREEN_WOOL = "minecraft:green_wool"; public const GRINDSTONE = "minecraft:grindstone"; public const HANGING_ROOTS = "minecraft:hanging_roots"; + public const HARD_BLACK_STAINED_GLASS = "minecraft:hard_black_stained_glass"; + public const HARD_BLACK_STAINED_GLASS_PANE = "minecraft:hard_black_stained_glass_pane"; + public const HARD_BLUE_STAINED_GLASS = "minecraft:hard_blue_stained_glass"; + public const HARD_BLUE_STAINED_GLASS_PANE = "minecraft:hard_blue_stained_glass_pane"; + public const HARD_BROWN_STAINED_GLASS = "minecraft:hard_brown_stained_glass"; + public const HARD_BROWN_STAINED_GLASS_PANE = "minecraft:hard_brown_stained_glass_pane"; + public const HARD_CYAN_STAINED_GLASS = "minecraft:hard_cyan_stained_glass"; + public const HARD_CYAN_STAINED_GLASS_PANE = "minecraft:hard_cyan_stained_glass_pane"; public const HARD_GLASS = "minecraft:hard_glass"; public const HARD_GLASS_PANE = "minecraft:hard_glass_pane"; - public const HARD_STAINED_GLASS = "minecraft:hard_stained_glass"; - public const HARD_STAINED_GLASS_PANE = "minecraft:hard_stained_glass_pane"; + public const HARD_GRAY_STAINED_GLASS = "minecraft:hard_gray_stained_glass"; + public const HARD_GRAY_STAINED_GLASS_PANE = "minecraft:hard_gray_stained_glass_pane"; + public const HARD_GREEN_STAINED_GLASS = "minecraft:hard_green_stained_glass"; + public const HARD_GREEN_STAINED_GLASS_PANE = "minecraft:hard_green_stained_glass_pane"; + public const HARD_LIGHT_BLUE_STAINED_GLASS = "minecraft:hard_light_blue_stained_glass"; + public const HARD_LIGHT_BLUE_STAINED_GLASS_PANE = "minecraft:hard_light_blue_stained_glass_pane"; + public const HARD_LIGHT_GRAY_STAINED_GLASS = "minecraft:hard_light_gray_stained_glass"; + public const HARD_LIGHT_GRAY_STAINED_GLASS_PANE = "minecraft:hard_light_gray_stained_glass_pane"; + public const HARD_LIME_STAINED_GLASS = "minecraft:hard_lime_stained_glass"; + public const HARD_LIME_STAINED_GLASS_PANE = "minecraft:hard_lime_stained_glass_pane"; + public const HARD_MAGENTA_STAINED_GLASS = "minecraft:hard_magenta_stained_glass"; + public const HARD_MAGENTA_STAINED_GLASS_PANE = "minecraft:hard_magenta_stained_glass_pane"; + public const HARD_ORANGE_STAINED_GLASS = "minecraft:hard_orange_stained_glass"; + public const HARD_ORANGE_STAINED_GLASS_PANE = "minecraft:hard_orange_stained_glass_pane"; + public const HARD_PINK_STAINED_GLASS = "minecraft:hard_pink_stained_glass"; + public const HARD_PINK_STAINED_GLASS_PANE = "minecraft:hard_pink_stained_glass_pane"; + public const HARD_PURPLE_STAINED_GLASS = "minecraft:hard_purple_stained_glass"; + public const HARD_PURPLE_STAINED_GLASS_PANE = "minecraft:hard_purple_stained_glass_pane"; + public const HARD_RED_STAINED_GLASS = "minecraft:hard_red_stained_glass"; + public const HARD_RED_STAINED_GLASS_PANE = "minecraft:hard_red_stained_glass_pane"; + public const HARD_WHITE_STAINED_GLASS = "minecraft:hard_white_stained_glass"; + public const HARD_WHITE_STAINED_GLASS_PANE = "minecraft:hard_white_stained_glass_pane"; + public const HARD_YELLOW_STAINED_GLASS = "minecraft:hard_yellow_stained_glass"; + public const HARD_YELLOW_STAINED_GLASS_PANE = "minecraft:hard_yellow_stained_glass_pane"; public const HARDENED_CLAY = "minecraft:hardened_clay"; public const HAY_BLOCK = "minecraft:hay_block"; public const HEAVY_WEIGHTED_PRESSURE_PLATE = "minecraft:heavy_weighted_pressure_plate"; @@ -900,6 +930,7 @@ final class BlockTypeNames{ public const TORCHFLOWER_CROP = "minecraft:torchflower_crop"; public const TRAPDOOR = "minecraft:trapdoor"; public const TRAPPED_CHEST = "minecraft:trapped_chest"; + public const TRIAL_SPAWNER = "minecraft:trial_spawner"; public const TRIP_WIRE = "minecraft:trip_wire"; public const TRIPWIRE_HOOK = "minecraft:tripwire_hook"; public const TUBE_CORAL = "minecraft:tube_coral"; diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index f70162ac5d..b0b06ac908 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -315,6 +315,44 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ } public function registerFlatColorBlockSerializers() : void{ + $this->map(Blocks::STAINED_HARDENED_GLASS(), fn(StainedHardenedGlass $block) => Writer::create(match($block->getColor()){ + DyeColor::BLACK => Ids::HARD_BLACK_STAINED_GLASS, + DyeColor::BLUE => Ids::HARD_BLUE_STAINED_GLASS, + DyeColor::BROWN => Ids::HARD_BROWN_STAINED_GLASS, + DyeColor::CYAN => Ids::HARD_CYAN_STAINED_GLASS, + DyeColor::GRAY => Ids::HARD_GRAY_STAINED_GLASS, + DyeColor::GREEN => Ids::HARD_GREEN_STAINED_GLASS, + DyeColor::LIGHT_BLUE => Ids::HARD_LIGHT_BLUE_STAINED_GLASS, + DyeColor::LIGHT_GRAY => Ids::HARD_LIGHT_GRAY_STAINED_GLASS, + DyeColor::LIME => Ids::HARD_LIME_STAINED_GLASS, + DyeColor::MAGENTA => Ids::HARD_MAGENTA_STAINED_GLASS, + DyeColor::ORANGE => Ids::HARD_ORANGE_STAINED_GLASS, + DyeColor::PINK => Ids::HARD_PINK_STAINED_GLASS, + DyeColor::PURPLE => Ids::HARD_PURPLE_STAINED_GLASS, + DyeColor::RED => Ids::HARD_RED_STAINED_GLASS, + DyeColor::WHITE => Ids::HARD_WHITE_STAINED_GLASS, + DyeColor::YELLOW => Ids::HARD_YELLOW_STAINED_GLASS, + })); + + $this->map(Blocks::STAINED_HARDENED_GLASS_PANE(), fn(StainedHardenedGlassPane $block) => Writer::create(match($block->getColor()){ + DyeColor::BLACK => Ids::HARD_BLACK_STAINED_GLASS_PANE, + DyeColor::BLUE => Ids::HARD_BLUE_STAINED_GLASS_PANE, + DyeColor::BROWN => Ids::HARD_BROWN_STAINED_GLASS_PANE, + DyeColor::CYAN => Ids::HARD_CYAN_STAINED_GLASS_PANE, + DyeColor::GRAY => Ids::HARD_GRAY_STAINED_GLASS_PANE, + DyeColor::GREEN => Ids::HARD_GREEN_STAINED_GLASS_PANE, + DyeColor::LIGHT_BLUE => Ids::HARD_LIGHT_BLUE_STAINED_GLASS_PANE, + DyeColor::LIGHT_GRAY => Ids::HARD_LIGHT_GRAY_STAINED_GLASS_PANE, + DyeColor::LIME => Ids::HARD_LIME_STAINED_GLASS_PANE, + DyeColor::MAGENTA => Ids::HARD_MAGENTA_STAINED_GLASS_PANE, + DyeColor::ORANGE => Ids::HARD_ORANGE_STAINED_GLASS_PANE, + DyeColor::PINK => Ids::HARD_PINK_STAINED_GLASS_PANE, + DyeColor::PURPLE => Ids::HARD_PURPLE_STAINED_GLASS_PANE, + DyeColor::RED => Ids::HARD_RED_STAINED_GLASS_PANE, + DyeColor::WHITE => Ids::HARD_WHITE_STAINED_GLASS_PANE, + DyeColor::YELLOW => Ids::HARD_YELLOW_STAINED_GLASS_PANE, + })); + $this->map(Blocks::GLAZED_TERRACOTTA(), function(GlazedTerracotta $block) : Writer{ return Writer::create(match($block->getColor()){ DyeColor::BLACK => Ids::BLACK_GLAZED_TERRACOTTA, @@ -1617,14 +1655,6 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeString(StateNames::SPONGE_TYPE, $block->isWet() ? StringValues::SPONGE_TYPE_WET : StringValues::SPONGE_TYPE_DRY); }); $this->map(Blocks::SPRUCE_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_SPRUCE)); - $this->map(Blocks::STAINED_HARDENED_GLASS(), function(StainedHardenedGlass $block) : Writer{ - return Writer::create(Ids::HARD_STAINED_GLASS) - ->writeColor($block->getColor()); - }); - $this->map(Blocks::STAINED_HARDENED_GLASS_PANE(), function(StainedHardenedGlassPane $block) : Writer{ - return Writer::create(Ids::HARD_STAINED_GLASS_PANE) - ->writeColor($block->getColor()); - }); $this->map(Blocks::STONECUTTER(), fn(Stonecutter $block) => Writer::create(Ids::STONECUTTER_BLOCK) ->writeCardinalHorizontalFacing($block->getFacing())); $this->map(Blocks::STONE_BRICKS(), fn() => Helper::encodeStoneBricks(StringValues::STONE_BRICK_TYPE_DEFAULT)); diff --git a/src/data/bedrock/block/convert/BlockStateReader.php b/src/data/bedrock/block/convert/BlockStateReader.php index 6bb0c8bf81..ea44e90b4c 100644 --- a/src/data/bedrock/block/convert/BlockStateReader.php +++ b/src/data/bedrock/block/convert/BlockStateReader.php @@ -25,7 +25,6 @@ namespace pocketmine\data\bedrock\block\convert; use pocketmine\block\utils\BellAttachmentType; use pocketmine\block\utils\CoralType; -use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SlabType; use pocketmine\block\utils\WallConnectionType; use pocketmine\data\bedrock\block\BlockLegacyMetadata; @@ -236,30 +235,6 @@ final class BlockStateReader{ }; } - /** @throws BlockStateDeserializeException */ - public function readColor() : DyeColor{ - // * color (StringTag) = black, blue, brown, cyan, gray, green, light_blue, lime, magenta, orange, pink, purple, red, silver, white, yellow - return match($color = $this->readString(BlockStateNames::COLOR)){ - StringValues::COLOR_BLACK => DyeColor::BLACK, - StringValues::COLOR_BLUE => DyeColor::BLUE, - StringValues::COLOR_BROWN => DyeColor::BROWN, - StringValues::COLOR_CYAN => DyeColor::CYAN, - StringValues::COLOR_GRAY => DyeColor::GRAY, - StringValues::COLOR_GREEN => DyeColor::GREEN, - StringValues::COLOR_LIGHT_BLUE => DyeColor::LIGHT_BLUE, - StringValues::COLOR_LIME => DyeColor::LIME, - StringValues::COLOR_MAGENTA => DyeColor::MAGENTA, - StringValues::COLOR_ORANGE => DyeColor::ORANGE, - StringValues::COLOR_PINK => DyeColor::PINK, - StringValues::COLOR_PURPLE => DyeColor::PURPLE, - StringValues::COLOR_RED => DyeColor::RED, - StringValues::COLOR_SILVER => DyeColor::LIGHT_GRAY, - StringValues::COLOR_WHITE => DyeColor::WHITE, - StringValues::COLOR_YELLOW => DyeColor::YELLOW, - default => throw $this->badValueException(BlockStateNames::COLOR, $color), - }; - } - /** @throws BlockStateDeserializeException */ public function readCoralFacing() : int{ return $this->parseFacingValue($this->readInt(BlockStateNames::CORAL_DIRECTION), [ diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 18e9b3e322..2941263675 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -185,6 +185,48 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ } private function registerFlatColorBlockDeserializers() : void{ + foreach([ + Ids::HARD_BLACK_STAINED_GLASS => DyeColor::BLACK, + Ids::HARD_BLUE_STAINED_GLASS => DyeColor::BLUE, + Ids::HARD_BROWN_STAINED_GLASS => DyeColor::BROWN, + Ids::HARD_CYAN_STAINED_GLASS => DyeColor::CYAN, + Ids::HARD_GRAY_STAINED_GLASS => DyeColor::GRAY, + Ids::HARD_GREEN_STAINED_GLASS => DyeColor::GREEN, + Ids::HARD_LIGHT_BLUE_STAINED_GLASS => DyeColor::LIGHT_BLUE, + Ids::HARD_LIGHT_GRAY_STAINED_GLASS => DyeColor::LIGHT_GRAY, + Ids::HARD_LIME_STAINED_GLASS => DyeColor::LIME, + Ids::HARD_MAGENTA_STAINED_GLASS => DyeColor::MAGENTA, + Ids::HARD_ORANGE_STAINED_GLASS => DyeColor::ORANGE, + Ids::HARD_PINK_STAINED_GLASS => DyeColor::PINK, + Ids::HARD_PURPLE_STAINED_GLASS => DyeColor::PURPLE, + Ids::HARD_RED_STAINED_GLASS => DyeColor::RED, + Ids::HARD_WHITE_STAINED_GLASS => DyeColor::WHITE, + Ids::HARD_YELLOW_STAINED_GLASS => DyeColor::YELLOW, + ] as $id => $color){ + $this->map($id, fn(Reader $in) => Blocks::STAINED_HARDENED_GLASS()->setColor($color)); + } + + foreach([ + Ids::HARD_BLACK_STAINED_GLASS_PANE => DyeColor::BLACK, + Ids::HARD_BLUE_STAINED_GLASS_PANE => DyeColor::BLUE, + Ids::HARD_BROWN_STAINED_GLASS_PANE => DyeColor::BROWN, + Ids::HARD_CYAN_STAINED_GLASS_PANE => DyeColor::CYAN, + Ids::HARD_GRAY_STAINED_GLASS_PANE => DyeColor::GRAY, + Ids::HARD_GREEN_STAINED_GLASS_PANE => DyeColor::GREEN, + Ids::HARD_LIGHT_BLUE_STAINED_GLASS_PANE => DyeColor::LIGHT_BLUE, + Ids::HARD_LIGHT_GRAY_STAINED_GLASS_PANE => DyeColor::LIGHT_GRAY, + Ids::HARD_LIME_STAINED_GLASS_PANE => DyeColor::LIME, + Ids::HARD_MAGENTA_STAINED_GLASS_PANE => DyeColor::MAGENTA, + Ids::HARD_ORANGE_STAINED_GLASS_PANE => DyeColor::ORANGE, + Ids::HARD_PINK_STAINED_GLASS_PANE => DyeColor::PINK, + Ids::HARD_PURPLE_STAINED_GLASS_PANE => DyeColor::PURPLE, + Ids::HARD_RED_STAINED_GLASS_PANE => DyeColor::RED, + Ids::HARD_WHITE_STAINED_GLASS_PANE => DyeColor::WHITE, + Ids::HARD_YELLOW_STAINED_GLASS_PANE => DyeColor::YELLOW, + ] as $id => $color){ + $this->map($id, fn(Reader $in) => Blocks::STAINED_HARDENED_GLASS_PANE()->setColor($color)); + } + foreach([ Ids::BLACK_GLAZED_TERRACOTTA => DyeColor::BLACK, Ids::BLUE_GLAZED_TERRACOTTA => DyeColor::BLUE, @@ -1159,14 +1201,6 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5)); }); $this->mapStairs(Ids::GRANITE_STAIRS, fn() => Blocks::GRANITE_STAIRS()); - $this->map(Ids::HARD_STAINED_GLASS, function(Reader $in) : Block{ - return Blocks::STAINED_HARDENED_GLASS() - ->setColor($in->readColor()); - }); - $this->map(Ids::HARD_STAINED_GLASS_PANE, function(Reader $in) : Block{ - return Blocks::STAINED_HARDENED_GLASS_PANE() - ->setColor($in->readColor()); - }); $this->map(Ids::HAY_BLOCK, function(Reader $in) : Block{ $in->ignored(StateNames::DEPRECATED); return Blocks::HAY_BALE()->setAxis($in->readPillarAxis()); diff --git a/src/data/bedrock/block/convert/BlockStateWriter.php b/src/data/bedrock/block/convert/BlockStateWriter.php index f5f34fff65..69efa4d0fd 100644 --- a/src/data/bedrock/block/convert/BlockStateWriter.php +++ b/src/data/bedrock/block/convert/BlockStateWriter.php @@ -25,7 +25,6 @@ namespace pocketmine\data\bedrock\block\convert; use pocketmine\block\utils\BellAttachmentType; use pocketmine\block\utils\CoralType; -use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SlabType; use pocketmine\block\utils\WallConnectionType; use pocketmine\block\utils\WoodType; @@ -193,29 +192,6 @@ final class BlockStateWriter{ }); } - /** @return $this */ - public function writeColor(DyeColor $color) : self{ - $this->writeString(BlockStateNames::COLOR, match($color){ - DyeColor::BLACK => StringValues::COLOR_BLACK, - DyeColor::BLUE => StringValues::COLOR_BLUE, - DyeColor::BROWN => StringValues::COLOR_BROWN, - DyeColor::CYAN => StringValues::COLOR_CYAN, - DyeColor::GRAY => StringValues::COLOR_GRAY, - DyeColor::GREEN => StringValues::COLOR_GREEN, - DyeColor::LIGHT_BLUE => StringValues::COLOR_LIGHT_BLUE, - DyeColor::LIGHT_GRAY => StringValues::COLOR_SILVER, - DyeColor::LIME => StringValues::COLOR_LIME, - DyeColor::MAGENTA => StringValues::COLOR_MAGENTA, - DyeColor::ORANGE => StringValues::COLOR_ORANGE, - DyeColor::PINK => StringValues::COLOR_PINK, - DyeColor::PURPLE => StringValues::COLOR_PURPLE, - DyeColor::RED => StringValues::COLOR_RED, - DyeColor::WHITE => StringValues::COLOR_WHITE, - DyeColor::YELLOW => StringValues::COLOR_YELLOW, - }); - return $this; - } - /** @return $this */ public function writeCoralFacing(int $value) : self{ $this->writeInt(BlockStateNames::CORAL_DIRECTION, match($value){ diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index 0c6dadc462..bbc295b725 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -348,7 +348,7 @@ final class ItemSerializerDeserializerRegistrar{ $this->map1to1Item(Ids::RIB_ARMOR_TRIM_SMITHING_TEMPLATE, Items::RIB_ARMOR_TRIM_SMITHING_TEMPLATE()); $this->map1to1Item(Ids::ROTTEN_FLESH, Items::ROTTEN_FLESH()); $this->map1to1Item(Ids::SALMON, Items::RAW_SALMON()); - $this->map1to1Item(Ids::SCUTE, Items::SCUTE()); + $this->map1to1Item(Ids::TURTLE_SCUTE, Items::SCUTE()); $this->map1to1Item(Ids::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, Items::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE()); $this->map1to1Item(Ids::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, Items::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE()); $this->map1to1Item(Ids::SHEARS, Items::SHEARS()); diff --git a/src/data/bedrock/item/ItemTypeNames.php b/src/data/bedrock/item/ItemTypeNames.php index c1534a0f0e..3f01ff1a88 100644 --- a/src/data/bedrock/item/ItemTypeNames.php +++ b/src/data/bedrock/item/ItemTypeNames.php @@ -38,6 +38,8 @@ final class ItemTypeNames{ public const ANGLER_POTTERY_SHERD = "minecraft:angler_pottery_sherd"; public const APPLE = "minecraft:apple"; public const ARCHER_POTTERY_SHERD = "minecraft:archer_pottery_sherd"; + public const ARMADILLO_SCUTE = "minecraft:armadillo_scute"; + public const ARMADILLO_SPAWN_EGG = "minecraft:armadillo_spawn_egg"; public const ARMOR_STAND = "minecraft:armor_stand"; public const ARMS_UP_POTTERY_SHERD = "minecraft:arms_up_pottery_sherd"; public const ARROW = "minecraft:arrow"; @@ -79,6 +81,7 @@ final class ItemTypeNames{ public const BOW = "minecraft:bow"; public const BOWL = "minecraft:bowl"; public const BREAD = "minecraft:bread"; + public const BREEZE_SPAWN_EGG = "minecraft:breeze_spawn_egg"; public const BREWER_POTTERY_SHERD = "minecraft:brewer_pottery_sherd"; public const BREWING_STAND = "minecraft:brewing_stand"; public const BRICK = "minecraft:brick"; @@ -238,6 +241,8 @@ final class ItemTypeNames{ public const GREEN_DYE = "minecraft:green_dye"; public const GUARDIAN_SPAWN_EGG = "minecraft:guardian_spawn_egg"; public const GUNPOWDER = "minecraft:gunpowder"; + public const HARD_STAINED_GLASS = "minecraft:hard_stained_glass"; + public const HARD_STAINED_GLASS_PANE = "minecraft:hard_stained_glass_pane"; public const HEART_OF_THE_SEA = "minecraft:heart_of_the_sea"; public const HEART_POTTERY_SHERD = "minecraft:heart_pottery_sherd"; public const HEARTBREAK_POTTERY_SHERD = "minecraft:heartbreak_pottery_sherd"; @@ -404,7 +409,6 @@ final class ItemTypeNames{ public const SALMON = "minecraft:salmon"; public const SALMON_BUCKET = "minecraft:salmon_bucket"; public const SALMON_SPAWN_EGG = "minecraft:salmon_spawn_egg"; - public const SCUTE = "minecraft:scute"; public const SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:sentry_armor_trim_smithing_template"; public const SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:shaper_armor_trim_smithing_template"; public const SHEAF_POTTERY_SHERD = "minecraft:sheaf_pottery_sherd"; @@ -466,11 +470,13 @@ final class ItemTypeNames{ public const TORCHFLOWER_SEEDS = "minecraft:torchflower_seeds"; public const TOTEM_OF_UNDYING = "minecraft:totem_of_undying"; public const TRADER_LLAMA_SPAWN_EGG = "minecraft:trader_llama_spawn_egg"; + public const TRIAL_KEY = "minecraft:trial_key"; public const TRIDENT = "minecraft:trident"; public const TROPICAL_FISH = "minecraft:tropical_fish"; public const TROPICAL_FISH_BUCKET = "minecraft:tropical_fish_bucket"; public const TROPICAL_FISH_SPAWN_EGG = "minecraft:tropical_fish_spawn_egg"; public const TURTLE_HELMET = "minecraft:turtle_helmet"; + public const TURTLE_SCUTE = "minecraft:turtle_scute"; public const TURTLE_SPAWN_EGG = "minecraft:turtle_spawn_egg"; public const VEX_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:vex_armor_trim_smithing_template"; public const VEX_SPAWN_EGG = "minecraft:vex_spawn_egg"; @@ -497,6 +503,7 @@ final class ItemTypeNames{ public const WITCH_SPAWN_EGG = "minecraft:witch_spawn_egg"; public const WITHER_SKELETON_SPAWN_EGG = "minecraft:wither_skeleton_spawn_egg"; public const WITHER_SPAWN_EGG = "minecraft:wither_spawn_egg"; + public const WOLF_ARMOR = "minecraft:wolf_armor"; public const WOLF_SPAWN_EGG = "minecraft:wolf_spawn_egg"; public const WOODEN_AXE = "minecraft:wooden_axe"; public const WOODEN_DOOR = "minecraft:wooden_door"; diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 87a4553c3e..ac07d5321a 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -30,6 +30,7 @@ use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\types\ChunkPosition; +use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\serializer\ChunkSerializer; use pocketmine\scheduler\AsyncTask; use pocketmine\thread\NonThreadSafeValue; @@ -43,16 +44,22 @@ class ChunkRequestTask extends AsyncTask{ protected string $chunk; protected int $chunkX; protected int $chunkZ; + /** @phpstan-var DimensionIds::* */ + private int $dimensionId; /** @phpstan-var NonThreadSafeValue */ protected NonThreadSafeValue $compressor; private string $tiles; - public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor){ + /** + * @phpstan-param DimensionIds::* $dimensionId + */ + public function __construct(int $chunkX, int $chunkZ, int $dimensionId, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor){ $this->compressor = new NonThreadSafeValue($compressor); $this->chunk = FastChunkSerializer::serializeTerrain($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; + $this->dimensionId = $dimensionId; $this->tiles = ChunkSerializer::serializeTiles($chunk); $this->storeLocal(self::TLS_KEY_PROMISE, $promise); @@ -60,14 +67,18 @@ class ChunkRequestTask extends AsyncTask{ public function onRun() : void{ $chunk = FastChunkSerializer::deserializeTerrain($this->chunk); - $subCount = ChunkSerializer::getSubChunkCount($chunk); + $dimensionId = $this->dimensionId; + + $subCount = ChunkSerializer::getSubChunkCount($chunk, $dimensionId); $converter = TypeConverter::getInstance(); $encoderContext = new PacketSerializerContext($converter->getItemTypeDictionary()); - $payload = ChunkSerializer::serializeFullChunk($chunk, $converter->getBlockTranslator(), $encoderContext, $this->tiles); + $payload = ChunkSerializer::serializeFullChunk($chunk, $dimensionId, $converter->getBlockTranslator(), $encoderContext, $this->tiles); $stream = new BinaryStream(); - PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $subCount, false, null, $payload)]); - $this->setResult($this->compressor->deserialize()->compress($stream->getBuffer())); + PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $dimensionId, $subCount, false, null, $payload)]); + + $compressor = $this->compressor->deserialize(); + $this->setResult(chr($compressor->getNetworkId()) . $compressor->compress($stream->getBuffer())); } public function onCompletion() : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 1a4c85255e..8ac4db98fc 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -86,6 +86,7 @@ use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandOverload; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; use pocketmine\network\mcpe\protocol\types\command\CommandPermissions; +use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; @@ -119,6 +120,7 @@ use function implode; use function in_array; use function is_string; use function json_encode; +use function ord; use function random_bytes; use function str_split; use function strcasecmp; @@ -355,15 +357,27 @@ class NetworkSession{ } } + if(strlen($payload) < 1){ + throw new PacketHandlingException("No bytes in payload"); + } + if($this->enableCompression){ Timings::$playerNetworkReceiveDecompress->startTiming(); - try{ - $decompressed = $this->compressor->decompress($payload); - }catch(DecompressionException $e){ - $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); - throw PacketHandlingException::wrap($e, "Compressed packet batch decode error"); - }finally{ - Timings::$playerNetworkReceiveDecompress->stopTiming(); + $compressionType = ord($payload[0]); + $compressed = substr($payload, 1); + if($compressionType === CompressionAlgorithm::NONE){ + $decompressed = $compressed; + }elseif($compressionType === $this->compressor->getNetworkId()){ + try{ + $decompressed = $this->compressor->decompress($compressed); + }catch(DecompressionException $e){ + $this->logger->debug("Failed to decompress packet: " . base64_encode($compressed)); + throw PacketHandlingException::wrap($e, "Compressed packet batch decode error"); + }finally{ + Timings::$playerNetworkReceiveDecompress->stopTiming(); + } + }else{ + throw new PacketHandlingException("Packet compressed with unexpected compression type $compressionType"); } }else{ $decompressed = $payload; diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index 71010a041c..6d80200857 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -27,6 +27,7 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; +use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\format\Chunk; @@ -116,6 +117,7 @@ class ChunkCache implements ChunkListener{ new ChunkRequestTask( $chunkX, $chunkZ, + DimensionIds::OVERWORLD, //TODO: not hardcode this $chunk, $this->caches[$chunkHash], $this->compressor diff --git a/src/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php index 96e9051b68..44ccef8b0e 100644 --- a/src/network/mcpe/compression/CompressBatchTask.php +++ b/src/network/mcpe/compression/CompressBatchTask.php @@ -43,7 +43,8 @@ class CompressBatchTask extends AsyncTask{ } public function onRun() : void{ - $this->setResult($this->compressor->deserialize()->compress($this->data)); + $compressor = $this->compressor->deserialize(); + $this->setResult(chr($compressor->getNetworkId()) . $compressor->compress($this->data)); } public function onCompletion() : void{ diff --git a/src/network/mcpe/compression/Compressor.php b/src/network/mcpe/compression/Compressor.php index a299f4eb08..fbb98e7890 100644 --- a/src/network/mcpe/compression/Compressor.php +++ b/src/network/mcpe/compression/Compressor.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\compression; +use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; + interface Compressor{ /** * @throws DecompressionException @@ -31,6 +33,14 @@ interface Compressor{ public function compress(string $payload) : string; + /** + * Returns the canonical ID of this compressor, used to tell the remote end how to decompress a packet compressed + * with this compressor. + * + * @return CompressionAlgorithm::* + */ + public function getNetworkId() : int; + /** * Returns the minimum size of packet batch that the compressor will attempt to compress. * diff --git a/src/network/mcpe/compression/ZlibCompressor.php b/src/network/mcpe/compression/ZlibCompressor.php index 066ba876a7..a6000e7813 100644 --- a/src/network/mcpe/compression/ZlibCompressor.php +++ b/src/network/mcpe/compression/ZlibCompressor.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\compression; +use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use function function_exists; @@ -75,4 +76,8 @@ final class ZlibCompressor implements Compressor{ libdeflate_deflate_compress($payload, $level) : Utils::assumeNotFalse(zlib_encode($payload, ZLIB_ENCODING_RAW, $level), "ZLIB compression failed"); } + + public function getNetworkId() : int{ + return CompressionAlgorithm::ZLIB; + } } diff --git a/src/network/mcpe/handler/SessionStartPacketHandler.php b/src/network/mcpe/handler/SessionStartPacketHandler.php index dd7ae47a85..8163574dbd 100644 --- a/src/network/mcpe/handler/SessionStartPacketHandler.php +++ b/src/network/mcpe/handler/SessionStartPacketHandler.php @@ -27,7 +27,6 @@ use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\NetworkSettingsPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\RequestNetworkSettingsPacket; -use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; final class SessionStartPacketHandler extends PacketHandler{ @@ -50,7 +49,7 @@ final class SessionStartPacketHandler extends PacketHandler{ //TODO: we're filling in the defaults to get pre-1.19.30 behaviour back for now, but we should explore the new options in the future $this->session->sendDataPacket(NetworkSettingsPacket::create( NetworkSettingsPacket::COMPRESS_EVERYTHING, - CompressionAlgorithm::ZLIB, + $this->session->getCompressor()->getNetworkId(), false, 0, 0 diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index afda6b7bbc..bd2b0736c1 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -31,6 +31,7 @@ use pocketmine\network\mcpe\convert\BlockTranslator; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; +use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; @@ -43,12 +44,34 @@ final class ChunkSerializer{ //NOOP } + /** + * Returns the min/max subchunk index expected in the protocol. + * This has no relation to the world height supported by PM. + * + * @phpstan-param DimensionIds::* $dimensionId + * @return int[] + * @phpstan-return array{int, int} + */ + public static function getDimensionChunkBounds(int $dimensionId) : array{ + return match($dimensionId){ + DimensionIds::OVERWORLD => [-4, 19], + DimensionIds::NETHER => [0, 7], + DimensionIds::THE_END => [0, 15], + default => throw new \InvalidArgumentException("Unknown dimension ID $dimensionId"), + }; + } + /** * Returns the number of subchunks that will be sent from the given chunk. * Chunks are sent in a stack, so every chunk below the top non-empty one must be sent. + * + * @phpstan-param DimensionIds::* $dimensionId */ - public static function getSubChunkCount(Chunk $chunk) : int{ - for($y = Chunk::MAX_SUBCHUNK_INDEX, $count = count($chunk->getSubChunks()); $y >= Chunk::MIN_SUBCHUNK_INDEX; --$y, --$count){ + public static function getSubChunkCount(Chunk $chunk, int $dimensionId) : int{ + //if the protocol world bounds ever exceed the PM supported bounds again in the future, we might need to + //polyfill some stuff here + [$minSubChunkIndex, $maxSubChunkIndex] = self::getDimensionChunkBounds($dimensionId); + for($y = $maxSubChunkIndex, $count = count($chunk->getSubChunks()); $y >= $minSubChunkIndex; --$y, --$count){ if($chunk->getSubChunk($y)->isEmptyFast()){ continue; } @@ -58,18 +81,23 @@ final class ChunkSerializer{ return 0; } - public static function serializeFullChunk(Chunk $chunk, BlockTranslator $blockTranslator, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ + /** + * @phpstan-param DimensionIds::* $dimensionId + */ + public static function serializeFullChunk(Chunk $chunk, int $dimensionId, BlockTranslator $blockTranslator, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ $stream = PacketSerializer::encoder($encoderContext); - $subChunkCount = self::getSubChunkCount($chunk); + $subChunkCount = self::getSubChunkCount($chunk, $dimensionId); $writtenCount = 0; - for($y = Chunk::MIN_SUBCHUNK_INDEX; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){ + + [$minSubChunkIndex, $maxSubChunkIndex] = self::getDimensionChunkBounds($dimensionId); + for($y = $minSubChunkIndex; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){ self::serializeSubChunk($chunk->getSubChunk($y), $blockTranslator, $stream, false); } $biomeIdMap = LegacyBiomeIdToStringIdMap::getInstance(); //all biomes must always be written :( - for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){ + for($y = $minSubChunkIndex; $y <= $maxSubChunkIndex; ++$y){ self::serializeBiomePalette($chunk->getSubChunk($y)->getBiomeArray(), $biomeIdMap, $stream); } diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index cb5468a525..bf86825477 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -51,12 +51,12 @@ use function time; class BedrockWorldData extends BaseNbtWorldData{ public const CURRENT_STORAGE_VERSION = 10; - public const CURRENT_STORAGE_NETWORK_VERSION = 630; + public const CURRENT_STORAGE_NETWORK_VERSION = 649; public const CURRENT_CLIENT_VERSION_TARGET = [ 1, //major 20, //minor - 50, //patch - 3, //revision + 60, //patch + 4, //revision 0 //is beta ]; From 8c7a4d720a8ef23d5e3d570d75476454cf51304e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 12:46:11 +0000 Subject: [PATCH 31/38] Fixed inconsistent global namespace reference --- src/utils/MainLogger.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 402a68edbb..ffd56b041a 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\utils; -use LogLevel; use pmmp\thread\Thread as NativeThread; use pocketmine\thread\log\AttachableThreadSafeLogger; use pocketmine\thread\log\ThreadSafeLoggerAttachment; @@ -132,28 +131,28 @@ class MainLogger extends AttachableThreadSafeLogger implements \BufferedLogger{ public function log($level, $message){ switch($level){ - case LogLevel::EMERGENCY: + case \LogLevel::EMERGENCY: $this->emergency($message); break; - case LogLevel::ALERT: + case \LogLevel::ALERT: $this->alert($message); break; - case LogLevel::CRITICAL: + case \LogLevel::CRITICAL: $this->critical($message); break; - case LogLevel::ERROR: + case \LogLevel::ERROR: $this->error($message); break; - case LogLevel::WARNING: + case \LogLevel::WARNING: $this->warning($message); break; - case LogLevel::NOTICE: + case \LogLevel::NOTICE: $this->notice($message); break; - case LogLevel::INFO: + case \LogLevel::INFO: $this->info($message); break; - case LogLevel::DEBUG: + case \LogLevel::DEBUG: $this->debug($message); break; } From f54ed8362dc93c015140a49dd0a54d14115df601 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 12:49:05 +0000 Subject: [PATCH 32/38] tools/convert-world: add a namespace not sure why this was left in the global namespace to its own devices --- tools/convert-world.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/convert-world.php b/tools/convert-world.php index 75483c6af3..d4d15ce57b 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -21,10 +21,29 @@ declare(strict_types=1); +namespace pocketmine\tools\convert_world; + use pocketmine\world\format\io\FormatConverter; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WorldProviderManagerEntry; use pocketmine\world\format\io\WritableWorldProviderManagerEntry; +use function array_filter; +use function array_key_exists; +use function array_keys; +use function array_map; +use function array_shift; +use function count; +use function dirname; +use function fwrite; +use function getopt; +use function implode; +use function is_dir; +use function is_string; +use function is_writable; +use function mkdir; +use function realpath; +use const PHP_EOL; +use const STDERR; require_once dirname(__DIR__) . '/vendor/autoload.php'; @@ -76,5 +95,5 @@ if(count($oldProviderClasses) > 1){ $oldProviderClass = array_shift($oldProviderClasses); $oldProvider = $oldProviderClass->fromPath($inputPath, new \PrefixedLogger(\GlobalLogger::get(), "Old World Provider")); -$converter = new FormatConverter($oldProvider, $writableFormats[$args["format"]], $backupPath, GlobalLogger::get()); +$converter = new FormatConverter($oldProvider, $writableFormats[$args["format"]], $backupPath, \GlobalLogger::get()); $converter->execute(); From fe06bfcda02702cf53411fdbe6f42dc6b4759095 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 12:50:37 +0000 Subject: [PATCH 33/38] Import alias cleanup courtesy of newest php-cs-fixer --- build/generate-build-info-json.php | 11 +- src/Server.php | 6 +- src/block/VanillaBlocks.php | 4 +- src/block/WoodLikeBlockIdHelper.php | 12 +- .../convert/BlockStateSerializerHelper.php | 104 +++++++++--------- .../block/regenerate_consistency_check.php | 4 +- 6 files changed, 72 insertions(+), 69 deletions(-) diff --git a/build/generate-build-info-json.php b/build/generate-build-info-json.php index b29d1c7285..a2e7489f3a 100644 --- a/build/generate-build-info-json.php +++ b/build/generate-build-info-json.php @@ -21,6 +21,9 @@ declare(strict_types=1); +use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\VersionInfo; + require dirname(__DIR__) . '/vendor/autoload.php'; if(count($argv) !== 7){ @@ -30,12 +33,12 @@ if(count($argv) !== 7){ echo json_encode([ "php_version" => sprintf("%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION), //deprecated - "base_version" => \pocketmine\VersionInfo::BASE_VERSION, + "base_version" => VersionInfo::BASE_VERSION, "build" => (int) $argv[4], - "is_dev" => \pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD, - "channel" => \pocketmine\VersionInfo::BUILD_CHANNEL, + "is_dev" => VersionInfo::IS_DEVELOPMENT_BUILD, + "channel" => VersionInfo::BUILD_CHANNEL, "git_commit" => $argv[1], - "mcpe_version" => \pocketmine\network\mcpe\protocol\ProtocolInfo::MINECRAFT_VERSION_NETWORK, + "mcpe_version" => ProtocolInfo::MINECRAFT_VERSION_NETWORK, "date" => time(), //TODO: maybe we should embed this in VersionInfo? "details_url" => "https://github.com/$argv[3]/releases/tag/$argv[2]", "download_url" => "https://github.com/$argv[3]/releases/download/$argv[2]/PocketMine-MP.phar", diff --git a/src/Server.php b/src/Server.php index 3f12f7669a..73bfdb85a2 100644 --- a/src/Server.php +++ b/src/Server.php @@ -739,7 +739,7 @@ class Server{ * @return string[][] */ public function getCommandAliases() : array{ - $section = $this->configGroup->getProperty(YmlServerProperties::ALIASES); + $section = $this->configGroup->getProperty(Yml::ALIASES); $result = []; if(is_array($section)){ foreach($section as $key => $value){ @@ -863,7 +863,7 @@ class Server{ $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error1(VersionInfo::NAME))); $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error2())); $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error3())); - $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error4(YmlServerProperties::SETTINGS_ENABLE_DEV_BUILDS))); + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error4(Yml::SETTINGS_ENABLE_DEV_BUILDS))); $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error5("https://github.com/pmmp/PocketMine-MP/releases"))); $this->forceShutdownExit(); @@ -1476,7 +1476,7 @@ class Server{ } if(isset($this->network)){ - $this->network->getSessionManager()->close($this->configGroup->getPropertyString(YmlServerProperties::SETTINGS_SHUTDOWN_MESSAGE, "Server closed")); + $this->network->getSessionManager()->close($this->configGroup->getPropertyString(Yml::SETTINGS_SHUTDOWN_MESSAGE, "Server closed")); } if(isset($this->worldManager)){ diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 67a77c183b..9c0e7d3b7c 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -788,7 +788,7 @@ final class VanillaBlocks{ } protected static function setup() : void{ - $railBreakInfo = new Info(new BlockBreakInfo(0.7)); + $railBreakInfo = new Info(new BreakInfo(0.7)); self::register("activator_rail", new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail", $railBreakInfo)); self::register("air", new Air(new BID(Ids::AIR), "Air", new Info(BreakInfo::indestructible(-1.0)))); self::register("anvil", new Anvil(new BID(Ids::ANVIL), "Anvil", new Info(BreakInfo::pickaxe(5.0, ToolTier::WOOD, 6000.0)))); @@ -1638,7 +1638,7 @@ final class VanillaBlocks{ self::register("cave_vines", new CaveVines(new BID(Ids::CAVE_VINES), "Cave Vines", new Info(BreakInfo::instant()))); - self::register("small_dripleaf", new SmallDripleaf(new BID(Ids::SMALL_DRIPLEAF), "Small Dripleaf", new Info(BreakInfo::instant(BlockToolType::SHEARS, toolHarvestLevel: 1)))); + self::register("small_dripleaf", new SmallDripleaf(new BID(Ids::SMALL_DRIPLEAF), "Small Dripleaf", new Info(BreakInfo::instant(ToolType::SHEARS, toolHarvestLevel: 1)))); self::register("big_dripleaf_head", new BigDripleafHead(new BID(Ids::BIG_DRIPLEAF_HEAD), "Big Dripleaf", new Info(BreakInfo::instant()))); self::register("big_dripleaf_stem", new BigDripleafStem(new BID(Ids::BIG_DRIPLEAF_STEM), "Big Dripleaf Stem", new Info(BreakInfo::instant()))); } diff --git a/src/block/WoodLikeBlockIdHelper.php b/src/block/WoodLikeBlockIdHelper.php index 5f668608a8..88fdff3a6e 100644 --- a/src/block/WoodLikeBlockIdHelper.php +++ b/src/block/WoodLikeBlockIdHelper.php @@ -171,7 +171,7 @@ final class WoodLikeBlockIdHelper{ }; } - public static function getTrapdoorIdentifier(WoodType $treeType) : BlockIdentifier{ + public static function getTrapdoorIdentifier(WoodType $treeType) : BID{ return new BID(match($treeType){ WoodType::OAK => Ids::OAK_TRAPDOOR, WoodType::SPRUCE => Ids::SPRUCE_TRAPDOOR, @@ -186,7 +186,7 @@ final class WoodLikeBlockIdHelper{ }); } - public static function getButtonIdentifier(WoodType $treeType) : BlockIdentifier{ + public static function getButtonIdentifier(WoodType $treeType) : BID{ return new BID(match($treeType){ WoodType::OAK => Ids::OAK_BUTTON, WoodType::SPRUCE => Ids::SPRUCE_BUTTON, @@ -201,7 +201,7 @@ final class WoodLikeBlockIdHelper{ }); } - public static function getPressurePlateIdentifier(WoodType $treeType) : BlockIdentifier{ + public static function getPressurePlateIdentifier(WoodType $treeType) : BID{ return new BID(match($treeType){ WoodType::OAK => Ids::OAK_PRESSURE_PLATE, WoodType::SPRUCE => Ids::SPRUCE_PRESSURE_PLATE, @@ -216,7 +216,7 @@ final class WoodLikeBlockIdHelper{ }); } - public static function getDoorIdentifier(WoodType $treeType) : BlockIdentifier{ + public static function getDoorIdentifier(WoodType $treeType) : BID{ return new BID(match($treeType){ WoodType::OAK => Ids::OAK_DOOR, WoodType::SPRUCE => Ids::SPRUCE_DOOR, @@ -231,7 +231,7 @@ final class WoodLikeBlockIdHelper{ }); } - public static function getFenceGateIdentifier(WoodType $treeType) : BlockIdentifier{ + public static function getFenceGateIdentifier(WoodType $treeType) : BID{ return new BID(match($treeType){ WoodType::OAK => Ids::OAK_FENCE_GATE, WoodType::SPRUCE => Ids::SPRUCE_FENCE_GATE, @@ -246,7 +246,7 @@ final class WoodLikeBlockIdHelper{ }); } - public static function getStairsIdentifier(WoodType $treeType) : BlockIdentifier{ + public static function getStairsIdentifier(WoodType $treeType) : BID{ return new BID(match($treeType){ WoodType::OAK => Ids::OAK_STAIRS, WoodType::SPRUCE => Ids::SPRUCE_STAIRS, diff --git a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php index 2b7e89b57e..2b91234381 100644 --- a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php @@ -57,42 +57,42 @@ use pocketmine\math\Facing; final class BlockStateSerializerHelper{ - public static function encodeAllSidedLog(Wood $block) : BlockStateWriter{ - return BlockStateWriter::create(Ids::WOOD) + public static function encodeAllSidedLog(Wood $block) : Writer{ + return Writer::create(Ids::WOOD) ->writeBool(BlockStateNames::STRIPPED_BIT, $block->isStripped()) ->writePillarAxis($block->getAxis()) ->writeLegacyWoodType($block->getWoodType()); } - public static function encodeButton(Button $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeButton(Button $block, Writer $out) : Writer{ return $out ->writeFacingDirection($block->getFacing()) ->writeBool(BlockStateNames::BUTTON_PRESSED_BIT, $block->isPressed()); } - public static function encodeCandle(Candle $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeCandle(Candle $block, Writer $out) : Writer{ return $out ->writeBool(StateNames::LIT, $block->isLit()) ->writeInt(StateNames::CANDLES, $block->getCount() - 1); } - public static function encodeChemistryTable(ChemistryTable $block, string $chemistryTableType, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeChemistryTable(ChemistryTable $block, string $chemistryTableType, Writer $out) : Writer{ return $out ->writeString(BlockStateNames::CHEMISTRY_TABLE_TYPE, $chemistryTableType) ->writeLegacyHorizontalFacing(Facing::opposite($block->getFacing())); } - public static function encodeCrops(Crops $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeCrops(Crops $block, Writer $out) : Writer{ return $out->writeInt(BlockStateNames::GROWTH, $block->getAge()); } - public static function encodeColoredTorch(Torch $block, bool $highBit, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeColoredTorch(Torch $block, bool $highBit, Writer $out) : Writer{ return $out ->writeBool(BlockStateNames::COLOR_BIT, $highBit) ->writeTorchFacing($block->getFacing()); } - public static function encodeCauldron(string $liquid, int $fillLevel) : BlockStateWriter{ + public static function encodeCauldron(string $liquid, int $fillLevel) : Writer{ return Writer::create(Ids::CAULDRON) ->writeString(BlockStateNames::CAULDRON_LIQUID, $liquid) ->writeInt(BlockStateNames::FILL_LEVEL, $fillLevel); @@ -107,7 +107,7 @@ final class BlockStateSerializerHelper{ }; } - public static function encodeDoor(Door $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeDoor(Door $block, Writer $out) : Writer{ return $out ->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop()) ->writeLegacyHorizontalFacing(Facing::rotateY($block->getFacing(), true)) @@ -115,111 +115,111 @@ final class BlockStateSerializerHelper{ ->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen()); } - public static function encodeDoublePlant(DoublePlant $block, string $doublePlantType, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeDoublePlant(DoublePlant $block, string $doublePlantType, Writer $out) : Writer{ return $out ->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop()) ->writeString(BlockStateNames::DOUBLE_PLANT_TYPE, $doublePlantType); } - public static function encodeFenceGate(FenceGate $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeFenceGate(FenceGate $block, Writer $out) : Writer{ return $out ->writeLegacyHorizontalFacing($block->getFacing()) ->writeBool(BlockStateNames::IN_WALL_BIT, $block->isInWall()) ->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen()); } - public static function encodeFloorSign(FloorSign $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeFloorSign(FloorSign $block, Writer $out) : Writer{ return $out ->writeInt(BlockStateNames::GROUND_SIGN_DIRECTION, $block->getRotation()); } - public static function encodeFurnace(Furnace $block, string $unlitId, string $litId) : BlockStateWriter{ - return BlockStateWriter::create($block->isLit() ? $litId : $unlitId) + public static function encodeFurnace(Furnace $block, string $unlitId, string $litId) : Writer{ + return Writer::create($block->isLit() ? $litId : $unlitId) ->writeCardinalHorizontalFacing($block->getFacing()); } - public static function encodeItemFrame(ItemFrame $block, string $id) : BlockStateWriter{ + public static function encodeItemFrame(ItemFrame $block, string $id) : Writer{ return Writer::create($id) ->writeBool(StateNames::ITEM_FRAME_MAP_BIT, $block->hasMap()) ->writeBool(StateNames::ITEM_FRAME_PHOTO_BIT, false) ->writeFacingDirection($block->getFacing()); } - public static function encodeLeaves(Leaves $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeLeaves(Leaves $block, Writer $out) : Writer{ return $out ->writeBool(BlockStateNames::PERSISTENT_BIT, $block->isNoDecay()) ->writeBool(BlockStateNames::UPDATE_BIT, $block->isCheckDecay()); } - public static function encodeLeaves1(Leaves $block, string $type) : BlockStateWriter{ - return self::encodeLeaves($block, BlockStateWriter::create(Ids::LEAVES) + public static function encodeLeaves1(Leaves $block, string $type) : Writer{ + return self::encodeLeaves($block, Writer::create(Ids::LEAVES) ->writeString(BlockStateNames::OLD_LEAF_TYPE, $type)); } - public static function encodeLeaves2(Leaves $block, string $type) : BlockStateWriter{ - return self::encodeLeaves($block, BlockStateWriter::create(Ids::LEAVES2) + public static function encodeLeaves2(Leaves $block, string $type) : Writer{ + return self::encodeLeaves($block, Writer::create(Ids::LEAVES2) ->writeString(BlockStateNames::NEW_LEAF_TYPE, $type)); } - public static function encodeLiquid(Liquid $block, string $stillId, string $flowingId) : BlockStateWriter{ - return BlockStateWriter::create($block->isStill() ? $stillId : $flowingId) + public static function encodeLiquid(Liquid $block, string $stillId, string $flowingId) : Writer{ + return Writer::create($block->isStill() ? $stillId : $flowingId) ->writeInt(BlockStateNames::LIQUID_DEPTH, $block->getDecay() | ($block->isFalling() ? 0x8 : 0)); } - public static function encodeLog(Wood $block, string $unstrippedId, string $strippedId) : BlockStateWriter{ + public static function encodeLog(Wood $block, string $unstrippedId, string $strippedId) : Writer{ $out = $block->isStripped() ? - BlockStateWriter::create($strippedId) : - BlockStateWriter::create($unstrippedId); + Writer::create($strippedId) : + Writer::create($unstrippedId); return $out ->writePillarAxis($block->getAxis()); } - public static function encodeMushroomBlock(RedMushroomBlock $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeMushroomBlock(RedMushroomBlock $block, Writer $out) : Writer{ return $out ->writeInt(BlockStateNames::HUGE_MUSHROOM_BITS, MushroomBlockTypeIdMap::getInstance()->toId($block->getMushroomBlockType())); } - public static function encodeQuartz(string $type, int $axis) : BlockStateWriter{ - return BlockStateWriter::create(Ids::QUARTZ_BLOCK) + public static function encodeQuartz(string $type, int $axis) : Writer{ + return Writer::create(Ids::QUARTZ_BLOCK) ->writeString(BlockStateNames::CHISEL_TYPE, $type) ->writePillarAxis($axis); //this isn't needed for all types, but we have to write it anyway } - public static function encodeRedFlower(string $type) : BlockStateWriter{ - return BlockStateWriter::create(Ids::RED_FLOWER)->writeString(BlockStateNames::FLOWER_TYPE, $type); + public static function encodeRedFlower(string $type) : Writer{ + return Writer::create(Ids::RED_FLOWER)->writeString(BlockStateNames::FLOWER_TYPE, $type); } - public static function encodeSandstone(string $id, string $type) : BlockStateWriter{ - return BlockStateWriter::create($id)->writeString(BlockStateNames::SAND_STONE_TYPE, $type); + public static function encodeSandstone(string $id, string $type) : Writer{ + return Writer::create($id)->writeString(BlockStateNames::SAND_STONE_TYPE, $type); } - public static function encodeSapling(Sapling $block, string $type) : BlockStateWriter{ - return BlockStateWriter::create(Ids::SAPLING) + public static function encodeSapling(Sapling $block, string $type) : Writer{ + return Writer::create(Ids::SAPLING) ->writeBool(BlockStateNames::AGE_BIT, $block->isReady()) ->writeString(BlockStateNames::SAPLING_TYPE, $type); } - public static function encodeSimplePressurePlate(SimplePressurePlate $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeSimplePressurePlate(SimplePressurePlate $block, Writer $out) : Writer{ //TODO: not sure what the deal is here ... seems like a mojang bug / artifact of bad implementation? //best to keep this separate from weighted plates anyway... return $out ->writeInt(BlockStateNames::REDSTONE_SIGNAL, $block->isPressed() ? 15 : 0); } - public static function encodeSlab(Slab $block, string $singleId, string $doubleId) : BlockStateWriter{ + public static function encodeSlab(Slab $block, string $singleId, string $doubleId) : Writer{ $slabType = $block->getSlabType(); - return BlockStateWriter::create($slabType === SlabType::DOUBLE ? $doubleId : $singleId) + return Writer::create($slabType === SlabType::DOUBLE ? $doubleId : $singleId) //this is (intentionally) also written for double slabs (as zero) to maintain bug parity with MCPE ->writeSlabPosition($slabType === SlabType::DOUBLE ? SlabType::BOTTOM : $slabType); } - public static function encodeStairs(Stair $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeStairs(Stair $block, Writer $out) : Writer{ return $out ->writeBool(BlockStateNames::UPSIDE_DOWN_BIT, $block->isUpsideDown()) ->writeWeirdoHorizontalFacing($block->getFacing()); } - public static function encodeStem(Stem $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeStem(Stem $block, Writer $out) : Writer{ //In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the //most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which //is absurd, and I refuse to make our API similarly absurd. @@ -228,40 +228,40 @@ final class BlockStateSerializerHelper{ ->writeFacingWithoutUp($facing === Facing::UP ? Facing::DOWN : $facing); } - public static function encodeStoneBricks(string $type) : BlockStateWriter{ - return BlockStateWriter::create(Ids::STONEBRICK) + public static function encodeStoneBricks(string $type) : Writer{ + return Writer::create(Ids::STONEBRICK) ->writeString(BlockStateNames::STONE_BRICK_TYPE, $type); } - private static function encodeStoneSlab(Slab $block, string $singleId, string $doubleId, string $typeKey, string $typeValue) : BlockStateWriter{ + private static function encodeStoneSlab(Slab $block, string $singleId, string $doubleId, string $typeKey, string $typeValue) : Writer{ return self::encodeSlab($block, $singleId, $doubleId) ->writeString($typeKey, $typeValue); } - public static function encodeStoneSlab1(Slab $block, string $typeValue) : BlockStateWriter{ + public static function encodeStoneSlab1(Slab $block, string $typeValue) : Writer{ return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB, Ids::DOUBLE_STONE_BLOCK_SLAB, BlockStateNames::STONE_SLAB_TYPE, $typeValue); } - public static function encodeStoneSlab2(Slab $block, string $typeValue) : BlockStateWriter{ + public static function encodeStoneSlab2(Slab $block, string $typeValue) : Writer{ return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB2, Ids::DOUBLE_STONE_BLOCK_SLAB2, BlockStateNames::STONE_SLAB_TYPE_2, $typeValue); } - public static function encodeStoneSlab3(Slab $block, string $typeValue) : BlockStateWriter{ + public static function encodeStoneSlab3(Slab $block, string $typeValue) : Writer{ return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB3, Ids::DOUBLE_STONE_BLOCK_SLAB3, BlockStateNames::STONE_SLAB_TYPE_3, $typeValue); } - public static function encodeStoneSlab4(Slab $block, string $typeValue) : BlockStateWriter{ + public static function encodeStoneSlab4(Slab $block, string $typeValue) : Writer{ return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB4, Ids::DOUBLE_STONE_BLOCK_SLAB4, BlockStateNames::STONE_SLAB_TYPE_4, $typeValue); } - public static function encodeTrapdoor(Trapdoor $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeTrapdoor(Trapdoor $block, Writer $out) : Writer{ return $out ->write5MinusHorizontalFacing($block->getFacing()) ->writeBool(BlockStateNames::UPSIDE_DOWN_BIT, $block->isTop()) ->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen()); } - public static function encodeWall(Wall $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeWall(Wall $block, Writer $out) : Writer{ return $out ->writeBool(BlockStateNames::WALL_POST_BIT, $block->isPost()) ->writeWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_EAST, $block->getConnection(Facing::EAST)) @@ -270,17 +270,17 @@ final class BlockStateSerializerHelper{ ->writeWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_WEST, $block->getConnection(Facing::WEST)); } - public static function encodeLegacyWall(Wall $block, string $type) : BlockStateWriter{ - return self::encodeWall($block, BlockStateWriter::create(Ids::COBBLESTONE_WALL)) + public static function encodeLegacyWall(Wall $block, string $type) : Writer{ + return self::encodeWall($block, Writer::create(Ids::COBBLESTONE_WALL)) ->writeString(BlockStateNames::WALL_BLOCK_TYPE, $type); } - public static function encodeWallSign(WallSign $block, BlockStateWriter $out) : BlockStateWriter{ + public static function encodeWallSign(WallSign $block, Writer $out) : Writer{ return $out ->writeHorizontalFacing($block->getFacing()); } - public static function encodeWoodenSlab(Slab $block, string $typeValue) : BlockStateWriter{ + public static function encodeWoodenSlab(Slab $block, string $typeValue) : Writer{ return self::encodeSlab($block, Ids::WOODEN_SLAB, Ids::DOUBLE_WOODEN_SLAB) ->writeString(BlockStateNames::WOOD_TYPE, $typeValue); } diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index ac8a1ad9de..b4b3875c68 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -30,7 +30,7 @@ require dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ -$factory = new \pocketmine\block\RuntimeBlockStateRegistry(); +$factory = new RuntimeBlockStateRegistry(); $remaps = []; $new = []; foreach(RuntimeBlockStateRegistry::getInstance()->getAllKnownStates() as $index => $block){ @@ -44,7 +44,7 @@ $oldTablePath = __DIR__ . '/block_factory_consistency_check.json'; if(file_exists($oldTablePath)){ $oldTable = json_decode(file_get_contents($oldTablePath), true); if(!is_array($oldTable)){ - throw new \pocketmine\utils\AssumptionFailedError("Old table should be array{knownStates: array, stateDataBits: int}"); + throw new AssumptionFailedError("Old table should be array{knownStates: array, stateDataBits: int}"); } $old = []; /** From 826cbea0bcf8b065c76b4fee246d108b5616237c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 12:51:27 +0000 Subject: [PATCH 34/38] Use newer php-cs-fixer on Actions --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ecadf8af3c..ebe5d9cb57 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,7 +31,7 @@ jobs: uses: shivammathur/setup-php@2.29.0 with: php-version: 8.2 - tools: php-cs-fixer:3.38 + tools: php-cs-fixer:3.49 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4fcb644c51528c70280aab95211ecd584ce36efe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 12:51:39 +0000 Subject: [PATCH 35/38] Added missing imports --- src/network/mcpe/ChunkRequestTask.php | 1 + src/network/mcpe/compression/CompressBatchTask.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index ac07d5321a..05a4f20c10 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -37,6 +37,7 @@ use pocketmine\thread\NonThreadSafeValue; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; +use function chr; class ChunkRequestTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; diff --git a/src/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php index 44ccef8b0e..a513cfa86c 100644 --- a/src/network/mcpe/compression/CompressBatchTask.php +++ b/src/network/mcpe/compression/CompressBatchTask.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\compression; use pocketmine\scheduler\AsyncTask; use pocketmine\thread\NonThreadSafeValue; +use function chr; class CompressBatchTask extends AsyncTask{ From ce8fecc6ecd62433d28090f4bae1b5cb3e6b9710 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 13:01:30 +0000 Subject: [PATCH 36/38] Release 5.11.0 --- changelogs/5.11.md | 26 ++++++++++++++++++++++++++ src/VersionInfo.php | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 changelogs/5.11.md diff --git a/changelogs/5.11.md b/changelogs/5.11.md new file mode 100644 index 0000000000..9ec0a3a6cc --- /dev/null +++ b/changelogs/5.11.md @@ -0,0 +1,26 @@ +# 5.11.0 +Released 7th February 2024. + +**For Minecraft: Bedrock Edition 1.20.60** + +This is a support release for Minecraft: Bedrock Edition 1.20.60. + +**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.20.60. +- Removed support for earlier versions. + +## Fixes +- Fixed `tools/generate-item-upgrade-schema.php` not correctly handling items whose IDs were changed multiple times. +- Fixed `ServerKiller` not working correctly in some cases (incorrectly handled wake-up conditions). +- `ItemBlock`s of `Air` blocks are now always considered as "null" items regardless of count, and don't occupy inventory slots. + +## Internals +- Restructured GitHub Actions CI workflows to make them easier to maintain (no need to update PHP versions in multiple places anymore). +- GitHub Actions CodeStyle workflow now uses php-cs-fixer 3.49.x. +- Dependabot updates are now processed weekly instead of daily. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 6c7963405e..b300ea5f16 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.10.1"; - public const IS_DEVELOPMENT_BUILD = true; + public const BASE_VERSION = "5.11.0"; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; /** From 169d3e0de8bb07f29057af0022b7d026da9830cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 13:01:30 +0000 Subject: [PATCH 37/38] 5.11.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 b300ea5f16..c87bc899b8 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.11.0"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "5.11.1"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; /** From eaab1a87847422c0fc83843de4db2bc6d2a773cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Feb 2024 18:58:41 +0000 Subject: [PATCH 38/38] ChunkSerializer: fixed count calculation for non-overworld chunks plugins that implement dimensions can't change the number of subchunks used by Chunk, they can only choose to use a subset of them. --- src/network/mcpe/serializer/ChunkSerializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index bd2b0736c1..e089daef56 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -71,7 +71,7 @@ final class ChunkSerializer{ //if the protocol world bounds ever exceed the PM supported bounds again in the future, we might need to //polyfill some stuff here [$minSubChunkIndex, $maxSubChunkIndex] = self::getDimensionChunkBounds($dimensionId); - for($y = $maxSubChunkIndex, $count = count($chunk->getSubChunks()); $y >= $minSubChunkIndex; --$y, --$count){ + for($y = $maxSubChunkIndex, $count = $maxSubChunkIndex - $minSubChunkIndex + 1; $y >= $minSubChunkIndex; --$y, --$count){ if($chunk->getSubChunk($y)->isEmptyFast()){ continue; }