From 4637aae6210d0a2bb3be6679ef0f649dcf4616f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 11:43:09 +0100 Subject: [PATCH 01/24] Living: do not apply noDamageTicks to suicide damage suicide damage is a voluntary damage source, which noDamageTicks is intended to prevent getting damaged while the player gets their bearings after (re)spawning. --- src/entity/Living.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index de433cd12..e615e4148 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -504,7 +504,7 @@ abstract class Living extends Entity{ } public function attack(EntityDamageEvent $source) : void{ - if($this->noDamageTicks > 0){ + if($this->noDamageTicks > 0 && $source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE){ $source->cancel(); } From 8414c78969ff76a25f0f86b360b62097be89c5c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 11:49:52 +0100 Subject: [PATCH 02/24] Fixed netherite items burning in lava --- src/entity/Entity.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index cc7647912..092fcc0fc 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -519,7 +519,12 @@ abstract class Entity{ } public function attack(EntityDamageEvent $source) : void{ - if($this->isFireProof() && ($source->getCause() === EntityDamageEvent::CAUSE_FIRE || $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK)){ + if($this->isFireProof() && ( + $source->getCause() === EntityDamageEvent::CAUSE_FIRE || + $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK || + $source->getCause() === EntityDamageEvent::CAUSE_LAVA + ) + ){ $source->cancel(); } $source->call(); From 763241b11ff74de0b29c9adfcbcd5263accb4277 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 12:32:00 +0100 Subject: [PATCH 03/24] Fixed burning animations for fireproof entities creative players are not technically fireproof; they just don't take any damage from fire --- src/entity/Entity.php | 15 +++++++++------ src/player/Player.php | 8 ++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 092fcc0fc..8a406924e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -691,8 +691,10 @@ abstract class Entity{ if($fireTicks < 0 || $fireTicks > 0x7fff){ throw new \InvalidArgumentException("Fire ticks must be in range 0 ... " . 0x7fff . ", got $fireTicks"); } - $this->fireTicks = $fireTicks; - $this->networkPropertiesDirty = true; + if(!$this->isFireProof()){ + $this->fireTicks = $fireTicks; + $this->networkPropertiesDirty = true; + } } public function extinguish() : void{ @@ -705,12 +707,13 @@ abstract class Entity{ } protected function doOnFireTick(int $tickDiff = 1) : bool{ - if($this->isFireProof() && $this->fireTicks > 1){ - $this->fireTicks = 1; - }else{ - $this->fireTicks -= $tickDiff; + if($this->isFireProof() && $this->isOnFire()){ + $this->extinguish(); + return false; } + $this->fireTicks -= $tickDiff; + if(($this->fireTicks % 20 === 0) || $tickDiff > 20){ $this->dealFireDamage(); } diff --git a/src/player/Player.php b/src/player/Player.php index 11dabf7db..ccce2d45e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1195,10 +1195,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return !$this->gamemode->equals(GameMode::CREATIVE()); } - public function isFireProof() : bool{ - return $this->isCreative(); - } - public function getDrops() : array{ if($this->hasFiniteResources()){ return parent::getDrops(); @@ -1436,6 +1432,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->entityBaseTick($tickDiff); Timings::$entityBaseTick->stopTiming(); + if($this->isCreative() && $this->fireTicks > 1){ + $this->fireTicks = 1; + } + if(!$this->isSpectator() && $this->isAlive()){ Timings::$playerCheckNearEntities->startTiming(); $this->checkNearEntities(); From 537721fe7d845bd369fe456ae0f28fc40e8ff4ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 13:34:42 +0100 Subject: [PATCH 04/24] Replace Closure::fromCallable() usages with first-class callables PHP 8.1 <3 --- src/block/Liquid.php | 2 +- src/crafting/CraftingManagerFromDataHelper.php | 11 ++++------- src/network/mcpe/InventoryManager.php | 2 +- src/network/mcpe/NetworkSession.php | 4 ++-- src/world/World.php | 6 +++--- src/world/format/io/WorldProviderManager.php | 8 ++++---- .../phpstan/rules/UnsafeForeachArrayOfStringRule.php | 2 +- 7 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 98f1d5627..a56f666a2 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -312,7 +312,7 @@ abstract class Liquid extends Transparent{ } if($adjacentDecay <= self::MAX_DECAY){ - $calculator = new MinimumCostFlowCalculator($world, $this->getFlowDecayPerBlock(), \Closure::fromCallable([$this, 'canFlowInto'])); + $calculator = new MinimumCostFlowCalculator($world, $this->getFlowDecayPerBlock(), $this->canFlowInto(...)); foreach($calculator->getOptimalFlowDirections($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) as $facing){ $this->flowIntoBlock($world->getBlock($this->position->getSide($facing)), $adjacentDecay, false); } diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 0a28ca328..812ff83e0 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -209,9 +209,6 @@ final class CraftingManagerFromDataHelper{ public static function make(string $directoryPath) : CraftingManager{ $result = new CraftingManager(); - $ingredientDeserializerFunc = \Closure::fromCallable([self::class, "deserializeIngredient"]); - $itemDeserializerFunc = \Closure::fromCallable([self::class, 'deserializeItemStack']); - foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'shapeless_crafting.json'), ShapelessRecipeData::class) as $recipe){ $recipeType = match($recipe->block){ "crafting_table" => ShapelessRecipeType::CRAFTING(), @@ -225,7 +222,7 @@ final class CraftingManagerFromDataHelper{ } $inputs = []; foreach($recipe->input as $inputData){ - $input = $ingredientDeserializerFunc($inputData); + $input = self::deserializeIngredient($inputData); if($input === null){ //unknown input item continue 2; } @@ -233,7 +230,7 @@ final class CraftingManagerFromDataHelper{ } $outputs = []; foreach($recipe->output as $outputData){ - $output = $itemDeserializerFunc($outputData); + $output = self::deserializeItemStack($outputData); if($output === null){ //unknown output item continue 2; } @@ -251,7 +248,7 @@ final class CraftingManagerFromDataHelper{ } $inputs = []; foreach(Utils::stringifyKeys($recipe->input) as $symbol => $inputData){ - $input = $ingredientDeserializerFunc($inputData); + $input = self::deserializeIngredient($inputData); if($input === null){ //unknown input item continue 2; } @@ -259,7 +256,7 @@ final class CraftingManagerFromDataHelper{ } $outputs = []; foreach($recipe->output as $outputData){ - $output = $itemDeserializerFunc($outputData); + $output = self::deserializeItemStack($outputData); if($output === null){ //unknown output item continue 2; } diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index a94dbe946..316abfd3e 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -108,7 +108,7 @@ class InventoryManager{ private NetworkSession $session ){ $this->containerOpenCallbacks = new ObjectSet(); - $this->containerOpenCallbacks->add(\Closure::fromCallable([self::class, 'createContainerOpen'])); + $this->containerOpenCallbacks->add(self::createContainerOpen(...)); $this->add(ContainerIds::INVENTORY, $this->player->getInventory()); $this->add(ContainerIds::OFFHAND, $this->player->getOffHandInventory()); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b10e7f25a..252db34cf 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -225,13 +225,13 @@ class NetworkSession{ $this->logger->setPrefix($this->getLogPrefix()); $this->manager->markLoginReceived($this); }, - \Closure::fromCallable([$this, "setAuthenticationStatus"]) + $this->setAuthenticationStatus(...) )); } protected function createPlayer() : void{ $this->server->createPlayer($this, $this->info, $this->authenticated, $this->cachedOfflinePlayerData)->onCompletion( - \Closure::fromCallable([$this, 'onPlayerCreated']), + $this->onPlayerCreated(...), function() : void{ //TODO: this should never actually occur... right? $this->logger->error("Failed to create player"); diff --git a/src/world/World.php b/src/world/World.php index deb03ef6d..f556d2e1f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1610,7 +1610,7 @@ class World implements ChunkManager{ * the current weather and time of day. */ public function getHighestAdjacentFullLightAt(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getFullLightAt'])); + return $this->getHighestAdjacentLight($x, $y, $z, $this->getFullLightAt(...)); } /** @@ -1706,7 +1706,7 @@ class World implements ChunkManager{ * Returns the highest potential level of sky light in the positions adjacent to the specified block coordinates. */ public function getHighestAdjacentPotentialBlockSkyLight(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getPotentialBlockSkyLightAt'])); + return $this->getHighestAdjacentLight($x, $y, $z, $this->getPotentialBlockSkyLightAt(...)); } /** @@ -1721,7 +1721,7 @@ class World implements ChunkManager{ * Returns the highest block light level available in the positions adjacent to the specified block coordinates. */ public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getBlockLightAt'])); + return $this->getHighestAdjacentLight($x, $y, $z, $this->getBlockLightAt(...)); } private function executeQueuedLightUpdates() : void{ diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index 8a30bcb57..1767c539a 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -41,13 +41,13 @@ final class WorldProviderManager{ private WritableWorldProviderManagerEntry $default; public function __construct(){ - $leveldb = new WritableWorldProviderManagerEntry(\Closure::fromCallable([LevelDB::class, 'isValid']), fn(string $path, \Logger $logger) => new LevelDB($path, $logger), \Closure::fromCallable([LevelDB::class, 'generate'])); + $leveldb = new WritableWorldProviderManagerEntry(LevelDB::isValid(...), fn(string $path, \Logger $logger) => new LevelDB($path, $logger), LevelDB::generate(...)); $this->default = $leveldb; $this->addProvider($leveldb, "leveldb"); - $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([Anvil::class, 'isValid']), fn(string $path, \Logger $logger) => new Anvil($path, $logger)), "anvil"); - $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([McRegion::class, 'isValid']), fn(string $path, \Logger $logger) => new McRegion($path, $logger)), "mcregion"); - $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([PMAnvil::class, 'isValid']), fn(string $path, \Logger $logger) => new PMAnvil($path, $logger)), "pmanvil"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(Anvil::isValid(...), fn(string $path, \Logger $logger) => new Anvil($path, $logger)), "anvil"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(McRegion::isValid(...), fn(string $path, \Logger $logger) => new McRegion($path, $logger)), "mcregion"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(PMAnvil::isValid(...), fn(string $path, \Logger $logger) => new PMAnvil($path, $logger)), "pmanvil"); } /** diff --git a/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php b/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php index d53baa365..e42d32927 100644 --- a/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php +++ b/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php @@ -78,7 +78,7 @@ final class UnsafeForeachArrayOfStringRule implements Rule{ return $type; }); if($hasCastableKeyTypes && !$expectsIntKeyTypes){ - $func = \Closure::fromCallable([Utils::class, 'stringifyKeys']); + $func = Utils::stringifyKeys(...); return [ RuleErrorBuilder::message(sprintf( "Unsafe foreach on array with key type %s (they might be casted to int).", From 914dd90b3d2fb60b87cbd5f8b0fdeb1264c1173f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 13:56:48 +0100 Subject: [PATCH 05/24] Use first-class closures in more places --- src/Server.php | 2 +- src/network/mcpe/InventoryManager.php | 4 +--- src/network/mcpe/NetworkSession.php | 10 +++------- src/network/mcpe/cache/CraftingDataCache.php | 12 +++--------- src/utils/RegistryTrait.php | 4 +--- 5 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/Server.php b/src/Server.php index f604c93d7..530b8d469 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1009,7 +1009,7 @@ class Server{ $this->playerDataProvider = new DatFilePlayerDataProvider(Path::join($this->dataPath, "players")); - register_shutdown_function([$this, "crashDump"]); + register_shutdown_function($this->crashDump(...)); $loadErrorCount = 0; $this->pluginManager->loadPlugins($this->pluginPath, $loadErrorCount); diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 316abfd3e..254eff910 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -116,9 +116,7 @@ class InventoryManager{ $this->addComplex(UIInventorySlotOffset::CURSOR, $this->player->getCursorInventory()); $this->addComplex(UIInventorySlotOffset::CRAFTING2X2_INPUT, $this->player->getCraftingGrid()); - $this->player->getInventory()->getHeldItemIndexChangeListeners()->add(function() : void{ - $this->syncSelectedHotbarSlot(); - }); + $this->player->getInventory()->getHeldItemIndexChangeListeners()->add($this->syncSelectedHotbarSlot(...)); } private function associateIdWithInventory(int $id, Inventory $inventory) : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 252db34cf..dbd857b0f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -197,7 +197,7 @@ class NetworkSession{ $this->setHandler(new SessionStartPacketHandler( $this, - fn() => $this->onSessionStartSuccess() + $this->onSessionStartSuccess(...) )); $this->manager->add($this); @@ -787,9 +787,7 @@ class NetworkSession{ $this->cipher = EncryptionContext::fakeGCM($encryptionKey); - $this->setHandler(new HandshakePacketHandler(function() : void{ - $this->onServerLoginSuccess(); - })); + $this->setHandler(new HandshakePacketHandler($this->onServerLoginSuccess(...))); $this->logger->debug("Enabled encryption"); })); }else{ @@ -818,9 +816,7 @@ class NetworkSession{ public function notifyTerrainReady() : void{ $this->logger->debug("Sending spawn notification, waiting for spawn response"); $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); - $this->setHandler(new SpawnResponsePacketHandler(function() : void{ - $this->onClientSpawnResponse(); - })); + $this->setHandler(new SpawnResponsePacketHandler($this->onClientSpawnResponse(...))); } private function onClientSpawnResponse() : void{ diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index e6ac6167b..58aa94a88 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -95,12 +95,8 @@ final class CraftingDataCache{ $recipesWithTypeIds[] = new ProtocolShapelessRecipe( CraftingDataPacket::ENTRY_SHAPELESS, Binary::writeInt($index), - array_map(function(RecipeIngredient $item) use ($converter) : ProtocolRecipeIngredient{ - return $converter->coreRecipeIngredientToNet($item); - }, $recipe->getIngredientList()), - array_map(function(Item $item) use ($converter) : ItemStack{ - return $converter->coreItemStackToNet($item); - }, $recipe->getResults()), + array_map($converter->coreRecipeIngredientToNet(...), $recipe->getIngredientList()), + array_map($converter->coreItemStackToNet(...), $recipe->getResults()), $nullUUID, $typeTag, 50, @@ -118,9 +114,7 @@ final class CraftingDataCache{ CraftingDataPacket::ENTRY_SHAPED, Binary::writeInt($index), $inputs, - array_map(function(Item $item) use ($converter) : ItemStack{ - return $converter->coreItemStackToNet($item); - }, $recipe->getResults()), + array_map($converter->coreItemStackToNet(...), $recipe->getResults()), $nullUUID, CraftingRecipeBlockName::CRAFTING_TABLE, 50, diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index f8ffc1143..573f4737f 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -121,8 +121,6 @@ trait RegistryTrait{ */ private static function _registryGetAll() : array{ self::checkInit(); - return array_map(function(object $o) : object{ - return self::preprocessMember($o); - }, self::$members); + return array_map(self::preprocessMember(...), self::$members); } } From 3c34841dfc351f9ce795c71866538c7e26964f62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 14:00:35 +0100 Subject: [PATCH 06/24] CS --- src/network/mcpe/cache/CraftingDataCache.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 58aa94a88..aa70c7d35 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -25,21 +25,17 @@ namespace pocketmine\network\mcpe\cache; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\FurnaceType; -use pocketmine\crafting\RecipeIngredient; use pocketmine\crafting\ShapedRecipe; use pocketmine\crafting\ShapelessRecipe; use pocketmine\crafting\ShapelessRecipeType; -use pocketmine\item\Item; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\recipe\CraftingRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\IntIdMetaItemDescriptor; use pocketmine\network\mcpe\protocol\types\recipe\PotionContainerChangeRecipe as ProtocolPotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\PotionTypeRecipe as ProtocolPotionTypeRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient as ProtocolRecipeIngredient; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; use pocketmine\timings\Timings; From 6c59912ed59fb5ef22d7bd2d19d8e8447140da88 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 15:19:33 +0100 Subject: [PATCH 07/24] LevelDB: workaround 0 bpb palettes with a length prefix this was caused by a plugin overriding the world provider. related: - https://github.com/pmmp/PocketMine-MP/issues/5911 - https://github.com/Refaltor77/CustomItemAPI/issues/68 fixes #5911 --- src/world/format/io/leveldb/LevelDB.php | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index a42d8d53e..6f6c99d80 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\data\bedrock\BiomeIds; use pocketmine\data\bedrock\block\BlockStateDeserializeException; use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; @@ -155,7 +156,35 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $nbt = new LittleEndianNbtSerializer(); $palette = []; - $paletteSize = $bitsPerBlock === 0 ? 1 : $stream->getLInt(); + if($bitsPerBlock === 0){ + $paletteSize = 1; + /* + * Due to code copy-paste in a public plugin, some PM4 worlds have 0 bpb palettes with a length prefix. + * This is invalid and does not happen in vanilla. + * These palettes were accepted by PM4 despite being invalid, but PM5 considered them corrupt, causing loss + * of data. Since many users were affected by this, a workaround is therefore necessary to allow PM5 to read + * these worlds without data loss. + * + * References: + * - https://github.com/Refaltor77/CustomItemAPI/issues/68 + * - https://github.com/pmmp/PocketMine-MP/issues/5911 + */ + $offset = $stream->getOffset(); + $byte1 = $stream->getByte(); + $stream->setOffset($offset); //reset offset + + if($byte1 !== NBT::TAG_Compound){ //normally the first byte would be the NBT of the blockstate + $susLength = $stream->getLInt(); + if($susLength !== 1){ //make sure the data isn't complete garbage + throw new CorruptedChunkException("CustomItemAPI borked 0 bpb palette should always have a length of 1"); + } + $logger->error("Unexpected palette size for 0 bpb palette"); + }else{ + $logger->debug("Normal 0 bpb palette found :)"); + } + }else{ + $paletteSize = $stream->getLInt(); + } for($i = 0; $i < $paletteSize; ++$i){ try{ From 82b75e0ccbb87837c0f571050ffd4e806b631afa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 15:21:47 +0100 Subject: [PATCH 08/24] LevelDB: Remove happy debug message --- src/world/format/io/leveldb/LevelDB.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 6f6c99d80..40a93ba9e 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -179,8 +179,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ throw new CorruptedChunkException("CustomItemAPI borked 0 bpb palette should always have a length of 1"); } $logger->error("Unexpected palette size for 0 bpb palette"); - }else{ - $logger->debug("Normal 0 bpb palette found :)"); } }else{ $paletteSize = $stream->getLInt(); From 1b9c2821948d724b0a00ee7364056ef9a35dc84c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 16:29:14 +0100 Subject: [PATCH 09/24] LevelDB: tolerate incorrect number of biome palettes, as long as there are enough for each real subchunk modern versions save 24 exactly, but previous versions saved more. We don't use the excess, so it's not a problem if they are missing, but this is nonetheless non-compliant with vanilla. --- src/world/format/io/leveldb/LevelDB.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 40a93ba9e..5fb104feb 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -304,6 +304,11 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ if($nextIndex <= Chunk::MAX_SUBCHUNK_INDEX){ //older versions wrote additional superfluous biome palettes $result[$nextIndex++] = $decoded; } + if($stream->feof() && $nextIndex >= Chunk::MAX_SUBCHUNK_INDEX){ + //not enough padding biome arrays for the given version - this is non-critical since we discard the excess anyway, but this should be logged + $logger->error("Wrong number of 3D biome palettes: expected $expectedCount, but got " . ($i + 1) . " - this is not a problem, but may indicate a corrupted chunk"); + break; + } }catch(BinaryDataException $e){ throw new CorruptedChunkException("Failed to deserialize biome palette $i: " . $e->getMessage(), 0, $e); } From b33a9690e975df0e50a9615619e638106785c778 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 16:30:13 +0100 Subject: [PATCH 10/24] LevelDB: simplify condition --- src/world/format/io/leveldb/LevelDB.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 5fb104feb..2cb5fc42c 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -303,8 +303,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $previous = $decoded; if($nextIndex <= Chunk::MAX_SUBCHUNK_INDEX){ //older versions wrote additional superfluous biome palettes $result[$nextIndex++] = $decoded; - } - if($stream->feof() && $nextIndex >= Chunk::MAX_SUBCHUNK_INDEX){ + }elseif($stream->feof()){ //not enough padding biome arrays for the given version - this is non-critical since we discard the excess anyway, but this should be logged $logger->error("Wrong number of 3D biome palettes: expected $expectedCount, but got " . ($i + 1) . " - this is not a problem, but may indicate a corrupted chunk"); break; From 86810c5e1c11ccc60e7bdc0565c5d943f30465a1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 16:31:10 +0100 Subject: [PATCH 11/24] LevelDB: clearer error message --- src/world/format/io/leveldb/LevelDB.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 2cb5fc42c..3d4f577a1 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -305,7 +305,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $result[$nextIndex++] = $decoded; }elseif($stream->feof()){ //not enough padding biome arrays for the given version - this is non-critical since we discard the excess anyway, but this should be logged - $logger->error("Wrong number of 3D biome palettes: expected $expectedCount, but got " . ($i + 1) . " - this is not a problem, but may indicate a corrupted chunk"); + $logger->error("Wrong number of 3D biome palettes for this chunk version: expected $expectedCount, but got " . ($i + 1) . " - this is not a problem, but may indicate a corrupted chunk"); break; } }catch(BinaryDataException $e){ From 24d979bd08e15202a05e3c2ae9420142d1a285f5 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 19 Jul 2023 16:33:16 +0100 Subject: [PATCH 12/24] Fixed /kill not properly killing the player under certain conditions, closes #4680 (#5919) This occurs if the player had very high levels of Health Boost or other weird modifications. It doesn't really make sense to apply damage modifiers to suicide anyway. Really I'm doubtful that suicide should even be considered a damage type (perhaps we should add an EntitySuicideEvent), but that's a discussion for another time. --- src/command/defaults/KillCommand.php | 2 +- src/entity/Living.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index e58234ead..fbc743690 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -53,7 +53,7 @@ class KillCommand extends VanillaCommand{ return true; } - $player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000)); + $player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, $player->getHealth())); if($player === $sender){ $sender->sendMessage(KnownTranslationFactory::commands_kill_successful($sender->getName())); }else{ diff --git a/src/entity/Living.php b/src/entity/Living.php index e615e4148..c6fdf34a7 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -517,7 +517,9 @@ abstract class Living extends Entity{ $source->cancel(); } - $this->applyDamageModifiers($source); + if($source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE){ + $this->applyDamageModifiers($source); + } if($source instanceof EntityDamageByEntityEvent && ( $source->getCause() === EntityDamageEvent::CAUSE_BLOCK_EXPLOSION || From 777a90193268bc28d05fba81100db272997a0904 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 16:37:33 +0100 Subject: [PATCH 13/24] Bump shivammathur/setup-php from 2.25.2 to 2.25.4 (#5829) Bumps [shivammathur/setup-php](https://github.com/shivammathur/setup-php) from 2.25.2 to 2.25.4. - [Release notes](https://github.com/shivammathur/setup-php/releases) - [Commits](https://github.com/shivammathur/setup-php/compare/2.25.2...2.25.4) --- updated-dependencies: - dependency-name: shivammathur/setup-php dependency-type: direct:production update-type: version-update:semver-patch ... 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 5f4e944a8..5275c445b 100644 --- a/.github/workflows/discord-release-notify.yml +++ b/.github/workflows/discord-release-notify.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.25.2 + uses: shivammathur/setup-php@2.25.4 with: php-version: 8.1 diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index ac2e65b2f..b5376f3ba 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -18,7 +18,7 @@ jobs: submodules: true - name: Setup PHP - uses: shivammathur/setup-php@2.25.2 + uses: shivammathur/setup-php@2.25.4 with: php-version: 8.1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f83a2e597..60e513d80 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -173,7 +173,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.25.2 + uses: shivammathur/setup-php@2.25.4 with: php-version: 8.1 tools: php-cs-fixer:3.17 From 4517948297f1edcf5d4a3db95b841c002d944aec Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:12:05 -0500 Subject: [PATCH 14/24] FrostedIce: Remove non-Bedrock melting behaviour (#5486) --- src/block/FrostedIce.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index ba8c7b536..38c552a95 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -48,12 +48,7 @@ class FrostedIce extends Ice{ } public function onNearbyBlockChange() : void{ - $world = $this->position->getWorld(); - if(!$this->checkAdjacentBlocks(2)){ - $world->useBreakOn($this->position); - }else{ - $world->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40)); - } + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40)); } public function onRandomTick() : void{ From 5e7f18cbcf2240c3dac6c6dccd91c9bbda5a380a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Jul 2023 16:20:34 +0100 Subject: [PATCH 15/24] StandardEntityEventBroadcaster: suppress client-side emote messages if users want these, they can broadcast them themselves using Server::broadcastMessage(), which will also record the message in the server log like chat closes #5669 --- src/network/mcpe/StandardEntityEventBroadcaster.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/StandardEntityEventBroadcaster.php b/src/network/mcpe/StandardEntityEventBroadcaster.php index 9996b354b..160022722 100644 --- a/src/network/mcpe/StandardEntityEventBroadcaster.php +++ b/src/network/mcpe/StandardEntityEventBroadcaster.php @@ -138,6 +138,6 @@ final class StandardEntityEventBroadcaster implements EntityEventBroadcaster{ } public function onEmote(array $recipients, Human $from, string $emoteId) : void{ - $this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER)); + $this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER | EmotePacket::FLAG_MUTE_ANNOUNCEMENT)); } } From 6ea7fd7d6b7cb8219f7ffb54d15c8ddf2632d6e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Jul 2023 16:36:25 +0100 Subject: [PATCH 16/24] ShulkerBox: do not offer support for other blocks --- src/block/ShulkerBox.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/block/ShulkerBox.php b/src/block/ShulkerBox.php index de8cefeb8..49de988cd 100644 --- a/src/block/ShulkerBox.php +++ b/src/block/ShulkerBox.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\ShulkerBox as TileShulkerBox; use pocketmine\block\utils\AnyFacingTrait; +use pocketmine\block\utils\SupportType; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -103,4 +104,8 @@ class ShulkerBox extends Opaque{ return true; } + + public function getSupportType(int $facing) : SupportType{ + return SupportType::NONE(); + } } From 4bdd6410db2636fb521c155eced5c385014e2ead Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Jul 2023 17:00:32 +0100 Subject: [PATCH 17/24] Fire: fixed support requirements closes #5599 --- src/block/Fire.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/block/Fire.php b/src/block/Fire.php index 648724529..0f2f7c876 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\SupportType; use pocketmine\entity\Entity; use pocketmine\entity\projectile\Arrow; use pocketmine\event\block\BlockBurnEvent; @@ -99,9 +100,13 @@ class Fire extends Flowable{ return []; } + private function canBeSupportedBy(Block $block) : bool{ + return $block->getSupportType(Facing::UP)->equals(SupportType::FULL()); + } + public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if($this->getSide(Facing::DOWN)->isTransparent() && !$this->hasAdjacentFlammableBlocks()){ + if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->hasAdjacentFlammableBlocks()){ $world->setBlock($this->position, VanillaBlocks::AIR()); }else{ $world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40)); From 9b43ddecbd77e5ff750ed305eb7d0433a3bca6cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Jul 2023 17:10:39 +0100 Subject: [PATCH 18/24] Drop usages of Process:kill() with subprocesses parameter we don't need this any more with console reader improvements, and this was not working correctly anyway. closes #5234 --- src/PocketMine.php | 2 +- src/Server.php | 6 +++--- src/console/ConsoleReaderChildProcess.php | 2 +- src/utils/Process.php | 5 ++++- src/utils/ServerKiller.php | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index c653d33ea..cbab95c85 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -343,7 +343,7 @@ JIT_WARNING if(ThreadManager::getInstance()->stopAll() > 0){ $logger->debug("Some threads could not be stopped, performing a force-kill"); - Process::kill(Process::pid(), true); + Process::kill(Process::pid()); } }while(false); diff --git a/src/Server.php b/src/Server.php index d4aba8282..d1f7ea4b9 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1446,7 +1446,7 @@ class Server{ private function forceShutdownExit() : void{ $this->forceShutdown(); - Process::kill(Process::pid(), true); + Process::kill(Process::pid()); } public function forceShutdown() : void{ @@ -1514,7 +1514,7 @@ class Server{ }catch(\Throwable $e){ $this->logger->logException($e); $this->logger->emergency("Crashed while crashing, killing process"); - @Process::kill(Process::pid(), true); + @Process::kill(Process::pid()); } } @@ -1668,7 +1668,7 @@ class Server{ echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; sleep($spacing); } - @Process::kill(Process::pid(), true); + @Process::kill(Process::pid()); exit(1); } diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php index 2d4e3fc56..20a3e5bf1 100644 --- a/src/console/ConsoleReaderChildProcess.php +++ b/src/console/ConsoleReaderChildProcess.php @@ -90,4 +90,4 @@ while(!feof($socket)){ //For simplicity's sake, we don't bother with a graceful shutdown here. //The parent process would normally forcibly terminate the child process anyway, so we only reach this point if the //parent process was terminated forcibly and didn't clean up after itself. -Process::kill(Process::pid(), false); +Process::kill(Process::pid()); diff --git a/src/utils/Process.php b/src/utils/Process.php index 96169b34f..c4dd848d5 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -125,7 +125,10 @@ final class Process{ return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread } - public static function kill(int $pid, bool $subprocesses) : void{ + /** + * @param bool $subprocesses @deprecated + */ + public static function kill(int $pid, bool $subprocesses = false) : void{ $logger = \GlobalLogger::get(); if($logger instanceof MainLogger){ $logger->syncFlushBuffer(); diff --git a/src/utils/ServerKiller.php b/src/utils/ServerKiller.php index 1739643d0..b7f415528 100644 --- a/src/utils/ServerKiller.php +++ b/src/utils/ServerKiller.php @@ -49,7 +49,7 @@ class ServerKiller extends Thread{ }); if(time() - $start >= $this->time){ echo "\nTook too long to stop, server was killed forcefully!\n"; - @Process::kill(Process::pid(), true); + @Process::kill(Process::pid()); } } From d65d8c33566bc8e77413c68005b6135926c47df4 Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Fri, 21 Jul 2023 04:34:34 -0500 Subject: [PATCH 19/24] Fix typo in documentation of `ChunkSelector:selectChunks()` (#5924) --- src/player/ChunkSelector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/ChunkSelector.php b/src/player/ChunkSelector.php index feb1b25e2..14d6b2888 100644 --- a/src/player/ChunkSelector.php +++ b/src/player/ChunkSelector.php @@ -30,7 +30,7 @@ use const M_SQRT2; final class ChunkSelector{ /** - * @preturn \Generator|int[] + * @return \Generator|int[] * @phpstan-return \Generator */ public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{ From 5899f2fc1d39175ce7bf0672cc6c09514779b5f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Jul 2023 15:02:25 +0100 Subject: [PATCH 20/24] Block: introduce new methods to reduce support type boilerplate checks this switches from a 'can be supported by' concept to a 'can stay at this position' paradigm, which requires way less boilerplate code. there may be further improvements we can make from here, such as adding traits, but this is a good first step. --- src/block/BaseRail.php | 4 ++-- src/block/Bed.php | 8 ++++---- src/block/Bell.php | 20 ++++++++++---------- src/block/Block.php | 5 +++++ src/block/Button.php | 8 ++++---- src/block/Candle.php | 3 +-- src/block/CaveVines.php | 8 ++++---- src/block/Coral.php | 8 ++++---- src/block/Door.php | 9 ++++----- src/block/FloorCoralFan.php | 8 ++++---- src/block/FlowerPot.php | 8 ++++---- src/block/GlowLichen.php | 4 ++-- src/block/ItemFrame.php | 8 ++++---- src/block/Ladder.php | 8 ++++---- src/block/Lantern.php | 11 ++++++----- src/block/Lever.php | 9 ++++----- src/block/NetherVines.php | 13 +++++-------- src/block/PressurePlate.php | 8 ++++---- src/block/RedstoneComparator.php | 8 ++++---- src/block/RedstoneRepeater.php | 8 ++++---- src/block/RedstoneWire.php | 8 ++++---- src/block/SnowLayer.php | 6 +++--- src/block/SporeBlossom.php | 8 ++++---- src/block/Torch.php | 17 +++++++---------- src/block/WallCoralFan.php | 8 ++++---- 25 files changed, 105 insertions(+), 108 deletions(-) diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 971beffac..0bcb2f340 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -38,7 +38,7 @@ use function in_array; abstract class BaseRail extends Flowable{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockReplace->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){ + if($blockReplace->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -222,7 +222,7 @@ abstract class BaseRail extends Flowable{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){ + if(!$this->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){ $world->useBreakOn($this->position); }else{ foreach($this->getCurrentShapeConnections() as $connection){ diff --git a/src/block/Bed.php b/src/block/Bed.php index 13b466026..312b21cd1 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -177,11 +177,11 @@ class Bed extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH; $next = $this->getSide($this->getOtherHalfSide()); - if($next->canBeReplaced() && $this->canBeSupportedBy($next->getSide(Facing::DOWN))){ + if($next->canBeReplaced() && $this->canBeSupportedAt($next)){ $nextState = clone $this; $nextState->head = true; $tx->addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState); @@ -208,8 +208,8 @@ class Bed extends Transparent{ return parent::getAffectedBlocks(); } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } public function getMaxStackSize() : int{ return 1; } diff --git a/src/block/Bell.php b/src/block/Bell.php index 753d6453d..0e2941d8e 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -87,13 +87,13 @@ final class Bell extends Transparent{ return $this; } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return !$block->getSupportType($face)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return !$block->getAdjacentSupportType($face)->equals(SupportType::NONE()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->down()), Facing::UP)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::DOWN)){ return false; } if($player !== null){ @@ -101,18 +101,18 @@ final class Bell extends Transparent{ } $this->setAttachmentType(BellAttachmentType::FLOOR()); }elseif($face === Facing::DOWN){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->up()), Facing::DOWN)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::UP)){ return false; } $this->setAttachmentType(BellAttachmentType::CEILING()); }else{ $this->setFacing($face); - if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide(Facing::opposite($face))), $face)){ + if($this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ $this->setAttachmentType(BellAttachmentType::ONE_WALL()); }else{ return false; } - if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide($face)), Facing::opposite($face))){ + if($this->canBeSupportedAt($blockReplace, $face)){ $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); } } @@ -121,10 +121,10 @@ final class Bell extends Transparent{ public function onNearbyBlockChange() : void{ if( - ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedBy($this->getSide(Facing::UP), Facing::DOWN)) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedBy($this->getSide(Facing::DOWN), Facing::UP)) || - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)) || - ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing), Facing::opposite($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing))) + ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedAt($this, Facing::UP)) || + ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedAt($this, Facing::DOWN)) || + ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedAt($this, Facing::opposite($this->facing))) || + ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedAt($this, $this->facing) || !$this->canBeSupportedAt($this, Facing::opposite($this->facing)))) ){ $this->position->getWorld()->useBreakOn($this->position); } diff --git a/src/block/Block.php b/src/block/Block.php index b4203e6b6..0e045792f 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -41,6 +41,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemBlock; use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -863,6 +864,10 @@ class Block{ return SupportType::FULL(); } + protected function getAdjacentSupportType(int $facing) : SupportType{ + return $this->getSide($facing)->getSupportType(Facing::opposite($facing)); + } + public function isFullCube() : bool{ $bb = $this->getCollisionBoxes(); diff --git a/src/block/Button.php b/src/block/Button.php index 85d1d3e09..73bd1d556 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -52,7 +52,7 @@ abstract class Button extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if($this->canBeSupportedAt($blockReplace, $face)){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -83,12 +83,12 @@ abstract class Button extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ + if(!$this->canBeSupportedAt($this, $this->facing)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $support, int $face) : bool{ - return $support->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType(Facing::opposite($face))->hasCenterSupport(); } } diff --git a/src/block/Candle.php b/src/block/Candle.php index 5936a0812..7009acef6 100644 --- a/src/block/Candle.php +++ b/src/block/Candle.php @@ -104,8 +104,7 @@ class Candle extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $down = $blockReplace->getSide(Facing::DOWN); - if(!$down->getSupportType(Facing::UP)->hasCenterSupport()){ + if(!$blockReplace->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport()){ return false; } $existing = $this->getCandleIfCompatibleType($blockReplace); diff --git a/src/block/CaveVines.php b/src/block/CaveVines.php index 55f73fb65..e56b8b720 100644 --- a/src/block/CaveVines.php +++ b/src/block/CaveVines.php @@ -87,18 +87,18 @@ class CaveVines extends Flowable{ return $this->berries ? 14 : 0; } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::DOWN)->equals(SupportType::FULL()) || $block->hasSameTypeId($this); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::UP)->equals(SupportType::FULL()) || $block->hasSameTypeId($this); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } $this->age = mt_rand(0, self::MAX_AGE); diff --git a/src/block/Coral.php b/src/block/Coral.php index b621a3ab0..837a81857 100644 --- a/src/block/Coral.php +++ b/src/block/Coral.php @@ -32,7 +32,7 @@ use pocketmine\world\BlockTransaction; final class Coral extends BaseCoral{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -40,14 +40,14 @@ final class Coral extends BaseCoral{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){ + if(!$this->canBeSupportedAt($this)){ $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } } diff --git a/src/block/Door.php b/src/block/Door.php index 06da8e68b..a03427d5a 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -106,7 +106,7 @@ class Door extends Transparent{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->getSide(Facing::DOWN) instanceof Door){ //Replace with common break method + if(!$this->canBeSupportedAt($this) && !$this->getSide(Facing::DOWN) instanceof Door){ //Replace with common break method $this->position->getWorld()->useBreakOn($this->position); //this will delete both halves if they exist } } @@ -114,8 +114,7 @@ class Door extends Transparent{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ $blockUp = $this->getSide(Facing::UP); - $blockDown = $this->getSide(Facing::DOWN); - if(!$blockUp->canBeReplaced() || !$this->canBeSupportedBy($blockDown)){ + if(!$blockUp->canBeReplaced() || !$this->canBeSupportedAt($blockReplace)){ return false; } @@ -172,7 +171,7 @@ class Door extends Transparent{ return parent::getAffectedBlocks(); } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasEdgeSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport(); } } diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index efa560467..a267a0385 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -53,7 +53,7 @@ final class FloorCoralFan extends BaseCoral{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } if($player !== null){ @@ -75,15 +75,15 @@ final class FloorCoralFan extends BaseCoral{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){ + if(!$this->canBeSupportedAt($this)){ $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } public function asItem() : Item{ diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index 1c85ea0d8..4e4dbfa6e 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -90,7 +90,7 @@ class FlowerPot extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } @@ -98,13 +98,13 @@ class FlowerPot extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ diff --git a/src/block/GlowLichen.php b/src/block/GlowLichen.php index d1baaa7d2..39ce512a6 100644 --- a/src/block/GlowLichen.php +++ b/src/block/GlowLichen.php @@ -121,7 +121,7 @@ class GlowLichen extends Transparent{ $changed = false; foreach($this->faces as $face){ - if(!$this->getSide($face)->getSupportType(Facing::opposite($face))->equals(SupportType::FULL())){ + if(!$this->getAdjacentSupportType($face)->equals(SupportType::FULL())){ unset($this->faces[$face]); $changed = true; } @@ -275,7 +275,7 @@ class GlowLichen extends Transparent{ private function getAvailableFaces() : array{ $faces = []; foreach(Facing::ALL as $face){ - if(!$this->hasFace($face) && $this->getSide($face)->getSupportType(Facing::opposite($face))->equals(SupportType::FULL())){ + if(!$this->hasFace($face) && $this->getAdjacentSupportType($face)->equals(SupportType::FULL())){ $faces[$face] = $face; } } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index f14720fe4..21bc5c20a 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -163,18 +163,18 @@ class ItemFrame extends Flowable{ return true; } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return !$block->getSupportType($face)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return !$block->getAdjacentSupportType($face)->equals(SupportType::NONE()); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ $this->position->getWorld()->useBreakOn($this->position); } } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ return false; } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 66e5f28cd..83adada82 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -70,7 +70,7 @@ class Ladder extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face) && Facing::axis($face) !== Axis::Y){ + if($this->canBeSupportedAt($blockReplace, Facing::opposite($face)) && Facing::axis($face) !== Axis::Y){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -79,12 +79,12 @@ class Ladder extends Transparent{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ //Replace with common break method + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ //Replace with common break method $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->equals(SupportType::FULL()); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->equals(SupportType::FULL()); } } diff --git a/src/block/Lantern.php b/src/block/Lantern.php index bc50c3cb6..8ebc8ba2c 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -77,22 +77,23 @@ class Lantern extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP), Facing::DOWN) && !$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN), Facing::UP)){ + $downSupport = $this->canBeSupportedAt($blockReplace, Facing::DOWN); + if(!$downSupport && !$this->canBeSupportedAt($blockReplace, Facing::UP)){ return false; } - $this->hanging = ($face === Facing::DOWN || !$this->canBeSupportedBy($this->position->getWorld()->getBlock($blockReplace->getPosition()->down()), Facing::UP)); + $this->hanging = $face === Facing::DOWN || !$downSupport; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ $face = $this->hanging ? Facing::UP : Facing::DOWN; - if(!$this->canBeSupportedBy($this->getSide($face), Facing::opposite($face))){ + if(!$this->canBeSupportedAt($this, $face)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->hasCenterSupport(); } } diff --git a/src/block/Lever.php b/src/block/Lever.php index 5d86ac7d2..e4b8c0811 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -66,7 +66,7 @@ class Lever extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ return false; } @@ -90,8 +90,7 @@ class Lever extends Flowable{ } public function onNearbyBlockChange() : void{ - $facing = $this->facing->getFacing(); - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($facing)), $facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing->getFacing()))){ $this->position->getWorld()->useBreakOn($this->position); } } @@ -107,8 +106,8 @@ class Lever extends Flowable{ return true; } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->hasCenterSupport(); } //TODO diff --git a/src/block/NetherVines.php b/src/block/NetherVines.php index ac075f667..c78000fa1 100644 --- a/src/block/NetherVines.php +++ b/src/block/NetherVines.php @@ -83,16 +83,13 @@ class NetherVines extends Flowable{ return true; } - private function getSupportFace() : int{ - return Facing::opposite($this->growthFace); - } - - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType($this->getSupportFace())->hasCenterSupport() || $block->hasSameTypeId($this); + private function canBeSupportedAt(Block $block) : bool{ + $supportBlock = $block->getSide(Facing::opposite($this->growthFace)); + return $supportBlock->getSupportType($this->growthFace)->hasCenterSupport() || $supportBlock->hasSameTypeId($this); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide($this->getSupportFace()))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } @@ -109,7 +106,7 @@ class NetherVines extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportFace()))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } $this->age = mt_rand(0, self::MAX_AGE - 1); diff --git a/src/block/PressurePlate.php b/src/block/PressurePlate.php index 7f9403b74..4df0bf927 100644 --- a/src/block/PressurePlate.php +++ b/src/block/PressurePlate.php @@ -45,18 +45,18 @@ abstract class PressurePlate extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 2158f1a84..8b436020b 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -85,7 +85,7 @@ class RedstoneComparator extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } @@ -102,13 +102,13 @@ class RedstoneComparator extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } //TODO: redstone functionality diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index d4f145238..518eeb9e5 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -68,7 +68,7 @@ class RedstoneRepeater extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } @@ -88,13 +88,13 @@ class RedstoneRepeater extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } //TODO: redstone functionality diff --git a/src/block/RedstoneWire.php b/src/block/RedstoneWire.php index 022672b5d..167365f56 100644 --- a/src/block/RedstoneWire.php +++ b/src/block/RedstoneWire.php @@ -35,7 +35,7 @@ class RedstoneWire extends Flowable{ use AnalogRedstoneSignalEmitterTrait; public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; @@ -49,13 +49,13 @@ class RedstoneWire extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } public function asItem() : Item{ diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index f2425455c..f561c8ff5 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -80,8 +80,8 @@ class SnowLayer extends Flowable implements Fallable{ return SupportType::NONE(); } - private function canBeSupportedBy(Block $b) : bool{ - return $b->getSupportType(Facing::UP)->equals(SupportType::FULL()); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::FULL()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ @@ -91,7 +91,7 @@ class SnowLayer extends Flowable implements Fallable{ } $this->layers = $blockReplace->layers + 1; } - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/SporeBlossom.php b/src/block/SporeBlossom.php index 73e31edf2..909932178 100644 --- a/src/block/SporeBlossom.php +++ b/src/block/SporeBlossom.php @@ -32,12 +32,12 @@ use pocketmine\world\BlockTransaction; final class SporeBlossom extends Flowable{ - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::DOWN)->equals(SupportType::FULL()); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::UP)->equals(SupportType::FULL()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } @@ -45,7 +45,7 @@ final class SporeBlossom extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Torch.php b/src/block/Torch.php index 163c0d115..66b62bc19 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; -use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -56,15 +55,13 @@ class Torch extends Flowable{ } public function onNearbyBlockChange() : void{ - $face = Facing::opposite($this->facing); - - if(!$this->canBeSupportedBy($this->getSide($face), $this->facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ $this->position->getWorld()->useBreakOn($this->position); } } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($face !== Facing::DOWN && $this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if($face !== Facing::DOWN && $this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ @@ -75,8 +72,7 @@ class Torch extends Flowable{ Facing::EAST, Facing::DOWN ] as $side){ - $block = $this->getSide($side); - if($this->canBeSupportedBy($block, Facing::opposite($side))){ + if($this->canBeSupportedAt($blockReplace, $side)){ $this->facing = Facing::opposite($side); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -85,8 +81,9 @@ class Torch extends Flowable{ return false; } - private function canBeSupportedBy(Block $support, int $face) : bool{ - return ($face === Facing::UP && $support->getSupportType($face)->hasCenterSupport()) || - (Facing::axis($face) !== Axis::Y && $support->getSupportType($face)->equals(SupportType::FULL())); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $face === Facing::DOWN ? + $block->getAdjacentSupportType($face)->hasCenterSupport() : + $block->getAdjacentSupportType($face)->equals(SupportType::FULL()); } } diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index 432dd5ddb..f9dece1cd 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -42,7 +42,7 @@ final class WallCoralFan extends BaseCoral{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $axis = Facing::axis($face); - if(($axis !== Axis::X && $axis !== Axis::Z) || !$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if(($axis !== Axis::X && $axis !== Axis::Z) || !$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ return false; } $this->facing = $face; @@ -54,15 +54,15 @@ final class WallCoralFan extends BaseCoral{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->canBeSupportedBy($world->getBlock($this->position->getSide(Facing::opposite($this->facing))), $this->facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->hasCenterSupport(); } public function asItem() : Item{ From 2779f92828de5214f73d4df151effa1d97466deb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Jul 2023 15:29:33 +0100 Subject: [PATCH 21/24] Bell: clean up code --- src/block/Bell.php | 55 ++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/block/Bell.php b/src/block/Bell.php index 0e2941d8e..3f15d6909 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -35,6 +35,7 @@ use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\BellRingSound; @@ -92,41 +93,39 @@ final class Bell extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ + return false; + } if($face === Facing::UP){ - if(!$this->canBeSupportedAt($blockReplace, Facing::DOWN)){ - return false; - } if($player !== null){ $this->setFacing(Facing::opposite($player->getHorizontalFacing())); } $this->setAttachmentType(BellAttachmentType::FLOOR()); }elseif($face === Facing::DOWN){ - if(!$this->canBeSupportedAt($blockReplace, Facing::UP)){ - return false; - } $this->setAttachmentType(BellAttachmentType::CEILING()); }else{ $this->setFacing($face); - if($this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ - $this->setAttachmentType(BellAttachmentType::ONE_WALL()); - }else{ - return false; - } - if($this->canBeSupportedAt($blockReplace, $face)){ - $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); - } + $this->setAttachmentType( + $this->canBeSupportedAt($blockReplace, $face) ? + BellAttachmentType::TWO_WALLS() : + BellAttachmentType::ONE_WALL() + ); } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if( - ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedAt($this, Facing::UP)) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedAt($this, Facing::DOWN)) || - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedAt($this, Facing::opposite($this->facing))) || - ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedAt($this, $this->facing) || !$this->canBeSupportedAt($this, Facing::opposite($this->facing)))) - ){ - $this->position->getWorld()->useBreakOn($this->position); + foreach(match($this->attachmentType){ + BellAttachmentType::CEILING() => [Facing::UP], + BellAttachmentType::FLOOR() => [Facing::DOWN], + BellAttachmentType::ONE_WALL() => [Facing::opposite($this->facing)], + BellAttachmentType::TWO_WALLS() => [$this->facing, Facing::opposite($this->facing)], + default => throw new AssumptionFailedError("All cases of BellAttachmentType must be handled") + } as $supportBlockDirection){ + if(!$this->canBeSupportedAt($this, $supportBlockDirection)){ + $this->position->getWorld()->useBreakOn($this->position); + break; + } } } @@ -159,13 +158,11 @@ final class Bell extends Transparent{ } private function isValidFaceToRing(int $faceHit) : bool{ - return ( - $this->attachmentType->equals(BellAttachmentType::CEILING()) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) || - ( - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) && - ($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true)) - ) - ); + return match($this->attachmentType){ + BellAttachmentType::CEILING() => true, + BellAttachmentType::FLOOR() => Facing::axis($faceHit) === Facing::axis($this->facing), + BellAttachmentType::ONE_WALL(), BellAttachmentType::TWO_WALLS() => $faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true), + default => throw new AssumptionFailedError("All cases of BellAttachmentType must be handled") + }; } } From cdf72563f4b483ef657bdb29aa107d38d1883b7e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jul 2023 11:58:50 +0100 Subject: [PATCH 22/24] Update composer dependencies --- composer.lock | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index 81c81e27c..cae00386d 100644 --- a/composer.lock +++ b/composer.lock @@ -2221,16 +2221,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.2.3", + "version": "10.2.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "35c8cac1734ede2ae354a6644f7088356ff5b08e" + "reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/35c8cac1734ede2ae354a6644f7088356ff5b08e", - "reference": "35c8cac1734ede2ae354a6644f7088356ff5b08e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c17815c129f133f3019cc18e8d0c8622e6d9bcd", + "reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd", "shasum": "" }, "require": { @@ -2302,7 +2302,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.3" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.6" }, "funding": [ { @@ -2318,7 +2318,7 @@ "type": "tidelift" } ], - "time": "2023-06-30T06:17:38+00:00" + "time": "2023-07-17T12:08:28+00:00" }, { "name": "sebastian/cli-parser", @@ -2830,16 +2830,16 @@ }, { "name": "sebastian/global-state", - "version": "6.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "aab257c712de87b90194febd52e4d184551c2d44" + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/aab257c712de87b90194febd52e4d184551c2d44", - "reference": "aab257c712de87b90194febd52e4d184551c2d44", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", "shasum": "" }, "require": { @@ -2879,7 +2879,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" }, "funding": [ { @@ -2887,7 +2888,7 @@ "type": "github" } ], - "time": "2023-02-03T07:07:38+00:00" + "time": "2023-07-19T07:19:23+00:00" }, { "name": "sebastian/lines-of-code", From 70dd8732e2955245f3c1a2a47befcaebf93f0bc9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jul 2023 11:59:11 +0100 Subject: [PATCH 23/24] Update build/php to pmmp/PHP-Binaries@46604f2f6a07e3f68a82e4f4d7efdd45629b101e --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 16378ffcc..46604f2f6 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 16378ffcc39036cf4905d32ce845b2c831db4331 +Subproject commit 46604f2f6a07e3f68a82e4f4d7efdd45629b101e From 43770313ba08a7fb021536a2bc892c2228724c5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jul 2023 12:07:32 +0100 Subject: [PATCH 24/24] Update symfony/filesystem to 6.3.x --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 4589d73a1..ea312ac14 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "pocketmine/raklib-ipc": "^0.2.0", "pocketmine/snooze": "^0.5.0", "ramsey/uuid": "~4.7.0", - "symfony/filesystem": "~6.2.0" + "symfony/filesystem": "~6.3.0" }, "require-dev": { "phpstan/phpstan": "1.10.16", diff --git a/composer.lock b/composer.lock index a82393a89..53807f312 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": "ee46ec27f8dfc8c767527b7776fe9992", + "content-hash": "74166e6c2f09b356c83a951efef349f2", "packages": [ { "name": "adhocore/json-comment", @@ -998,16 +998,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.2.12", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b0818e7203e53540f2a5c9a5017d97897df1e9bb" + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b0818e7203e53540f2a5c9a5017d97897df1e9bb", - "reference": "b0818e7203e53540f2a5c9a5017d97897df1e9bb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", "shasum": "" }, "require": { @@ -1041,7 +1041,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.12" + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" }, "funding": [ { @@ -1057,7 +1057,7 @@ "type": "tidelift" } ], - "time": "2023-06-01T08:29:37+00:00" + "time": "2023-06-01T08:30:39+00:00" }, { "name": "symfony/polyfill-ctype",