PocketMine-MP/changelogs/4.0-snapshot.md

44 KiB

4.0.0-SNAPSHOT-1907XX (2019-07-XX)

This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp.

Core

General

  • A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading.
  • The /reload command has been removed.
  • The /effect command no longer supports numeric IDs - it's now required to use names.
  • Remote console (RCON) has been removed. The RconServer plugin is provided as a substitute.
  • Spawn protection has been removed. The BasicSpawnProtection plugin is provided as a substitute.
  • CTRL+C signal handling has been removed. The PcntlSignalHandler plugin is provided as a substitute.
  • Player movement anti-cheat has been removed. Its corresponding pocketmine.yml setting player.anti-cheat.allow-movement-cheats has been removed.
  • The pocketmine_chunkutils PHP extension has been dropped.
  • New PHP extensions are required by this version:

World handling

Functional

  • Modern Minecraft Bedrock world formats are now supported.
  • Automatic conversion of deprecated world formats is now implemented.
  • All formats except leveldb have been deprecated. The following world formats will be automatically converted on load to a new format:
    • mcregion
    • anvil
    • pmanvil
  • 256 build-height is now supported in all worlds (facilitated by automatic conversion).
  • Extended blocks are now supported (facilitated by automatic conversion).
  • Unsupported world formats no longer causes a crash, but a graceful shutdown instead.
  • World corruption no longer causes a crash, but a graceful shutdown instead.

Performance

  • leveldb is now the primary supported world format. It is inherently faster than region-based formats thanks to better design.
  • Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn drastically reduces the time to complete world saves. This is possible thanks to the modular design of the leveldb world format - this enhancement is not possible with region-based formats.

Logger revamp

  • Many components now have a dedicated logger which automatically adds [prefixes] to their messages.
  • Main logger now includes milliseconds in timestamps.

Network

This version features substantial changes to the network system, improving coherency, reliability and modularity.

Minecraft Bedrock packet encryption

  • This fixes replay attacks where hackers steal and replay player logins.
  • A new setting has been added to pocketmine.yml: network.enable-encryption which is true by default.

Packet receive error handling has been overhauled

  • Only BadPacketException is now caught during packet decode and handling. This requires that all decoding MUST perform proper data error checking.
    • Throwing a BadPacketException from decoding will now cause players to be kicked with the message Packet processing error.
    • The disconnect message includes a random hex ID to help server owners identify the problems reported by their players.
  • Throwing any other exception will now cause a server crash. Internal server error has been removed.
  • It is now illegal to send a clientbound packet to the server. Doing so will result in the client being kicked with the message Unexpected non-serverbound packet.

New packet handler system

  • Packet handlers have been separated from NetworkSession into a dedicated packet handler structure.
  • A network session may have exactly 1 handler at a time, which is mutable and may be replaced at any time. This allows packet handling logic to be broken up into multiple stages:
    • preventing undefined behaviour when sending wrong packets at the wrong time (they'll now be silently dropped)
    • allowing the existence of ephemeral state-specific logic (for example stricter resource packs download checks)
  • Packet handlers are now almost entirely absent from Player and instead appear in their own dedicated units.
  • Almost all game logic that was previously locked up inside packet handlers in Player has been extracted into new API methods. See Player API changes for details.

API

General

  • Most places which previously allowed callable now only allow \Closure. This is because closures have more consistent behaviour and are more performant.
  • void and ?nullable parameter and return types have been applied in many places.
  • Everything in the pocketmine\metadata namespace and related implementations have been removed.

Block

  • A new VanillaBlocks class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of BlockFactory::get() where constants were used.
  • Blocks now contain their positions instead of extending Position. Block->getPos() has been added.
  • Blocks with IDs >= 256 are now supported.
  • Block state and variant metadata have been separated.
    • Variant is considered an extension of ID and is immutable.
    • Block->setDamage() has been removed. Block->readStateFromData() is now used for state deserialization.
  • Tile entities are now created and deleted automatically when World->setBlock() is used with a block that requires a tile entity.
  • Some tile entities' API has been exposed on their corresponding Block classes, with the tile entity classes being deprecated.
  • The pocketmine\tile namespace has been relocated to pocketmine\block\tile.
  • Block->recalculateBoundingBox() and Block->recalculateCollisionBoxes() are now expected to return AABBs relative to 0,0,0 instead of their own position.
  • Block break-info has been extracted into a new dynamic BlockBreakInfo unit. The following methods have been moved:
    • Block->getBlastResistance() -> BlockBreakInfo->getBlastResistance()
    • Block->getBreakTime() -> BlockBreakInfo->getBreakTime()
    • Block->getHardness() -> BlockBreakInfo->getHardness()
    • Block->getToolHarvestLevel() -> BlockBreakInfo->getToolHarvestLevel()
    • Block->getToolType() -> BlockBreakInfo->getToolType()
    • Block->isBreakable() -> BlockBreakInfo->isBreakable()
    • Block->isCompatibleWithTool() -> BlockBreakInfo->isToolCompatible()
  • The following API methods have been added:
    • Block->asItem(): returns an itemstack corresponding to the block
    • Block->isSameState(): returns whether the block is the same as the parameter, including state information
    • Block->isSameType(): returns whether the block is the same as the parameter, without state information
    • Block->isFullCube()
  • The following hooks have been added:
    • Block->onAttack(): called when a player in survival left-clicks the block to try to start breaking it
    • Block->onPostPlace(): called directly after placement in the world, handles things like rail connections and chest pairing
  • The following API methods have been renamed:
    • Block->getDamage() -> Block->getMeta()
    • Block->onActivate() -> Block->onInteract()
    • Block->onEntityCollide() -> Block->onEntityInside()
  • The following API methods have changed signatures:
    • Block->onInteract() now has the signature onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool
    • Block->getCollisionBoxes() is now final. Classes should override recalculateCollisionBoxes().
  • The following API methods have been removed:
    • Block->canPassThrough()
    • Block->setDamage()
    • Block::get(): this was superseded by BlockFactory::get() a long time ago
    • Block->getBoundingBox()
  • The following classes have been renamed:
    • BlockIds -> BlockLegacyIds
    • CobblestoneWall -> Wall
    • NoteBlock -> Note
    • SignPost -> Sign
    • StandingBanner -> Banner
  • The following classes have been removed:
    • Bricks
    • BurningFurnace
    • CobblestoneStairs
    • Dandelion
    • DoubleSlab
    • DoubleStoneSlab
    • EndStone
    • GlowingRedstoneOre
    • GoldOre
    • Gold
    • IronDoor
    • IronOre
    • IronTrapdoor
    • Iron
    • Lapis
    • NetherBrickFence
    • NetherBrickStairs
    • Obsidian
    • PurpurStairs
    • Purpur
    • QuartzStairs
    • Quartz
    • RedSandstoneStairs
    • RedSandstone
    • SandstoneStairs
    • Sandstone
    • StainedClay
    • StainedGlassPane
    • StainedGlass
    • StoneBrickStairs
    • StoneBricks
    • StoneSlab2
    • StoneSlab
    • Stone
    • WallBanner
    • WallSign
    • Wood2
  • BlockToolType constants have been renamed to remove the TYPE_ prefix.

Command

  • The following classes have been removed:
    • RemoteConsoleCommandSender
  • The following API methods have signature changes:
    • Command->setPermission() argument is now mandatory (but still nullable).
    • CommandSender->setScreenLineHeight() argument is now mandatory (but still nullable).

Entity

General

  • Entity no longer extends from Location. Entity->getLocation() and Entity->getPosition() should be used instead.
  • The following API methods have been added:
    • ItemEntity->getDespawnDelay()
    • ItemEntity->setDespawnDelay()
    • Human->getHungerManager()
    • Human->getXpManager()
  • The following methods have signature changes:
    • Entity->entityBaseTick() is now protected.
    • Entity->move() is now protected.
    • Living->knockBack() now accepts float, float, float (the first two parameters have been removed).
    • Living->getEffects() now returns EffectManager instead of Effect[].
  • The following classes have been added:
    • effect\EffectManager: contains effect-management functionality extracted from Living
    • HungerManager: contains hunger-management functionality extracted from Human
    • ExperienceManager: contains XP-management functionality extracted from Human
  • The following API methods have been moved / renamed:
    • Living->removeAllEffects() -> EffectManager->clear()
    • Living->removeEffect() -> EffectManager->remove()
    • Living->addEffect() -> EffectManager->add()
    • Living->getEffect() -> EffectManager->get()
    • Living->hasEffect() -> EffectManager->has()
    • Living->hasEffects() -> EffectManager->hasEffects()
    • Living->getEffects() -> EffectManager->all()
    • Human->getFood() -> HungerManager->getFood()
    • Human->setFood() -> HungerManager->setFood()
    • Human->getMaxFood() -> HungerManager->getMaxFood()
    • Human->addFood() -> HungerManager->addFood()
    • Human->isHungry() -> HungerManager->isHungry()
    • Human->getSaturation() -> HungerManager->getSaturation()
    • Human->setSaturation() -> HungerManager->setSaturation()
    • Human->addSaturation() -> HungerManager->addSaturation()
    • Human->getExhaustion() -> HungerManager->getExhaustion()
    • Human->setExhaustion() -> HungerManager->setExhaustion()
    • Human->exhaust() -> HungerManager->exhaust()
    • Human->getXpLevel() -> ExperienceManager->getXpLevel()
    • Human->setXpLevel() -> ExperienceManager->setXpLevel()
    • Human->addXpLevels() -> ExperienceManager->addXpLevels()
    • Human->subtractXpLevels() -> ExperienceManager->subtractXpLevels()
    • Human->getXpProgress() -> ExperienceManager->getXpProgress()
    • Human->setXpProgress() -> ExperienceManager->setXpProgress()
    • Human->getRemainderXp() -> ExperienceManager->getRemainderXp()
    • Human->getCurrentTotalXp() -> ExperienceManager->getCurrentTotalXp()
    • Human->setCurrentTotalXp() -> ExperienceManager->setCurrentTotalXp()
    • Human->addXp() -> ExperienceManager->addXp()
    • Human->subtractXp() -> ExperienceManager->subtractXp()
    • Human->getLifetimeTotalXp() -> ExperienceManager->getLifetimeTotalXp()
    • Human->setLifetimeTotalXp() -> ExperienceManager->setLifetimeTotalXp()
    • Human->canPickupXp() -> ExperienceManager->canPickupXp()
    • Human->onPickupXp() -> ExperienceManager->onPickupXp()
    • Human->resetXpCooldown() -> ExperienceManager->resetXpCooldown()
  • The following API methods have been removed:
    • Human->getRawUniqueId(): use Human->getUniqueId()->toBinary() instead
  • The following classes have been removed:
    • Creature
    • Damageable
    • Monster
    • NPC
    • Rideable
    • Vehicle
  • Skin now throws exceptions on creation if given invalid data.

Effect

  • All Effect related classes have been moved to the pocketmine\entity\effect namespace.
  • Effect functionality embedded in the Effect class has been separated out into several classes. The following classes have been added:
    • AbsorptionEffect
    • HealthBoostEffect
    • HungerEffect
    • InstantDamageEffect
    • InstantEffect
    • InstantHealthEffect
    • InvisibilityEffect
    • LevitationEffect
    • PoisonEffect
    • RegenerationEffect
    • SaturationEffect
    • SlownessEffect
    • SpeedEffect
    • WitherEffect
  • Negative effect amplifiers are now explicitly disallowed due to undefined behaviour they created.
  • The following API methods have been renamed:
    • Effect::registerEffect() -> Effect::register()
    • Effect::getEffect() -> Effect::get()
    • Effect::getEffectByName() -> Effect::fromString()
  • Static getter methods for all registered enchantment types have been added. Effect::getEffect(Effect::WHATEVER) should be replaced by VanillaEffects::WHATEVER().
  • All effect registry functionality has been removed from the Effect base class and migrated to the VanillaEffects class.

Removal of runtime entity NBT

  • Entities no longer keep their NBT alive at runtime.
    • Entity->namedtag has been removed.
    • Entity->saveNBT() now returns a newly created CompoundTag instead of modifying the previous one in-place.
    • Entity->initEntity() now accepts a CompoundTag parameter.

Entity creation

  • Entity class overriding is now explicitly supported, without needing to touch save IDs.
    • Entity classes can be overridden using EntityFactory::override(). The provided replacement class must be a subclass of the existing class. If the existing class isn't there, an exception will be thrown.
    • Attempting to register an entity to a save ID that is already registered will now cause an exception to be thrown.
  • Registering entities will now throw exceptions on error cases instead of returning false.
  • Entity creation has now been split into two paths:
    • EntityFactory::create(): Creates an entity by the given class. This accepts arguments to be passed to the entity constructor. This function is guaranteed to return an entity which is an instanceof the given class.
    • EntityFactory::createFromData(): Creates an entity from save data. This may return any Entity class or NULL. This function is internal and shouldn't be used by plugins.
  • It is no longer possible to directly create an entity by save ID. This is discouraged because save IDs are internal and format-dependent.
  • The following API methods have been moved:
    • Entity::registerEntity() -> EntityFactory::register()
    • Entity::createEntity() -> EntityFactory::create()
    • Entity::getKnownEntityTypes() -> EntityFactory::getKnownTypes()
    • Entity::createBaseNBT() -> EntityFactory::createBaseNBT()
  • The following API methods have been removed:
    • Entity->getSaveId()

WIP removal of entity network metadata

  • All network metadata related constants have been removed from the Entity class and moved to the protocol layer. It is intended to remove network metadata from the API entirely, but this has not yet been completed.
    • Entity::DATA_FLAG_* constants have been moved to pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags.
    • Entity::DATA_TYPE_* constants have been moved to pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes.
    • Entity::DATA_* constants have been moved to pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties.
  • DataPropertyManager has been moved to the pocketmine\network\mcpe\protocol\types\entity namespace, and as such isn't considered part of the API anymore.
  • Introduced internal Entity hook syncNetworkData(). This function is expected to synchronize entity properties with the entity's network data set.
  • Internal usage of network metadata sets to store internal entity properties has been removed. Entities are now expected to use regular class properties and synchronize with the network data set as-asked.
  • Entity->propertyManager has been renamed to Entity->networkProperties.
  • Entity->getDataPropertyManager() has been renamed to Entity->getNetworkProperties().

Event

Internal event system no longer depends on Listeners

  • The internal event processing system no longer depends on Listener objects. Arbitrary closures can now be used, provided that they satisfy the standard requirements to be a handler.
    • This change improves performance of event handler calling by approximately 15%. This does not include anything plugins are doing.
    • The following classes have been removed:
      • pocketmine\plugin\EventExecutor
      • pocketmine\plugin\MethodEventExecutor
    • RegisteredListener->__construct() now requires Closure instead of Listener, EventExecutor as the leading parameters.
    • RegisteredListener->getListener() has been removed.

Default cancelled handling behaviour has changed

  • Handler functions will now not receive cancelled events by default. This is a silent BC break, i.e. it won't raise errors, but it might cause bugs.
  • @ignoreCancelled is now no longer respected.
  • @handleCancelled has been added. This allows opting into receiving cancelled events (it's the opposite of @ignoreCancelled).

PlayerPreLoginEvent changes

  • The Player object no longer exists at this phase of the login. Instead, a PlayerInfo object is provided, along with connection information.
  • Ban, server-full and whitelist checks are now centralized to PlayerPreLoginEvent. It's no longer necessary (or possible) to intercept PlayerKickEvent to handle these types of disconnects.
    • Multiple kick reasons may be set to ensure that the player is still removed if there are other reasons for them to be disconnected and one of them is cleared. For example, if a player is banned and the server is full, clearing the ban flag will still cause the player to be disconnected because the server is full.
    • Plugins may set custom kick reasons. Any custom reason has absolute priority.
    • If multiple flags are set, the kick message corresponding to the highest priority reason will be shown. The priority (as of this snapshot) is as follows:
      • Custom (highest priority)
      • Server full
      • Whitelisted
      • Banned
    • The PlayerPreLoginEvent::KICK_REASON_PRIORITY constant contains a list of kick reason priorities, highest first.
  • The following constants have been added:
    • PlayerPreLoginEvent::KICK_REASON_PLUGIN
    • PlayerPreLoginEvent::KICK_REASON_SERVER_FULL
    • PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED
    • PlayerPreLoginEvent::KICK_REASON_BANNED
    • PlayerPreLoginEvent::KICK_REASON_PRIORITY: ordered list of kick reason priorities, highest first
  • The following API methods have been added:
    • PlayerPreLoginEvent->clearAllKickReasons()
    • PlayerPreLoginEvent->clearKickReason()
    • PlayerPreLoginEvent->getFinalKickMessage(): the message to be shown to the player with the current reason list in place
    • PlayerPreLoginEvent->getIp()
    • PlayerPreLoginEvent->getKickReasons(): returns an array of flags indicating kick reasons, must be empty to allow joining
    • PlayerPreLoginEvent->getPlayerInfo()
    • PlayerPreLoginEvent->getPort()
    • PlayerPreLoginEvent->isAllowed()
    • PlayerPreLoginEvent->isAuthRequired(): whether XBL authentication will be enforced
    • PlayerPreLoginEvent->isKickReasonSet()
    • PlayerPreLoginEvent->setAuthRequired()
    • PlayerPreLoginEvent->setKickReason()
  • The following API methods have been changed:
    • PlayerPreLoginEvent->getKickMessage() now has the signature getKickMessage(int $flag) : ?string
  • The following API methods have been removed:
    • PlayerPreLoginEvent->setKickMessage()
    • PlayerPreLoginEvent->getPlayer()

Other changes

  • Disconnecting players during events no longer crashes the server (although it might cause other side effects).
  • PlayerKickEvent is no longer fired for disconnects that occur before the player completes the initial login sequence (i.e. completing downloading resource packs).
  • Cancellable events must now implement CancellableTrait to get the cancellable components needed to satisfy interface requirements.
  • PlayerInteractEvent is no longer fired when a player activates an item. This fixes the age-old complaint of PlayerInteractEvent firing multiple times when interacting once. The following constants have been removed:
    • PlayerInteractEvent::LEFT_CLICK_AIR
    • PlayerInteractEvent::RIGHT_CLICK_AIR
    • PlayerInteractEvent::PHYSICAL
  • The following events have been added:
    • PlayerItemUseEvent: player activating their held item, for example to throw it.
    • BlockTeleportEvent: block teleporting, for example dragon egg when attacked.
  • The following events have been removed:
    • EntityArmorChangeEvent
    • EntityInventoryChangeEvent
    • EntityLevelChangeEvent - EntityTeleportEvent with world checks should be used instead.
    • NetworkInterfaceCrashEvent
    • PlayerCheatEvent
    • PlayerIllegalMoveEvent
  • The following API methods have been added:
    • EntityDeathEvent->getXpDropAmount()
    • EntityDeathEvent->setXpDropAmount()
    • PlayerDeathEvent->getXpDropAmount()
    • PlayerDeathEvent->setXpDropAmount()
  • The following API methods have been removed:
    • PlayerPreLoginEvent->getPlayer()
  • The following API methods have been moved:
    • Event->isCancelled() -> CancellableTrait->isCancelled(): this was a stub which threw BadMethodCallException if the class didn't implement Cancellable; now this is simply not available on non-cancellable events
    • Event->setCancelled() -> CancellableTrait->setCancelled()
    • HandlerList::unregisterAll() -> HandlerListManager->unregisterAll()
    • HandlerList::getHandlerListFor() -> HandlerListManager->getListFor()
    • HandlerList::getHandlerLists() -> HandlerListManager->getAll()
  • The following classes have been moved:
    • pocketmine\plugin\RegisteredListener -> pocketmine\event\RegisteredListener

Inventory

  • All crafting and recipe related classes have been moved to the pocketmine\crafting namespace.
  • The following classes have been added:
    • CallbackInventoryChangeListener
    • CreativeInventory: contains the creative functionality previously embedded in pocketmine\item\Item, see Item changes for details
    • InventoryChangeListener: allows listening (but not interfering with) events in an inventory.
    • transaction\CreateItemAction
    • transaction\DestroyItemAction
  • The following classes have been renamed:
    • ContainerInventory -> BlockInventory
  • The following classes have been removed:
    • CustomInventory
    • InventoryEventProcessor
    • Recipe
    • transaction\CreativeInventoryAction
  • The following API methods have been added:
    • Inventory->addChangeListeners()
    • Inventory->getChangeListeners()
    • Inventory->removeChangeListeners()
    • Inventory->swap(): swaps the contents of two slots
  • The following API methods have been removed:
    • BaseInventory->getDefaultSize()
    • BaseInventory->setSize()
    • Inventory->close()
    • Inventory->dropContents()
    • Inventory->getName()
    • Inventory->getTitle()
    • Inventory->onSlotChange()
    • Inventory->open()
    • Inventory->sendContents()
    • Inventory->sendSlot()
    • InventoryAction->onExecuteFail()
    • InventoryAction->onExecuteSuccess()
    • PlayerInventory->sendCreativeContents()
  • The following API methods have signature changes:
    • Inventory->clear() now returns void instead of bool.
    • Inventory->setItem() now returns void instead of bool.
    • InventoryAction->execute() now returns void instead of bool.
    • BaseInventory->construct() no longer accepts a list of items to initialize with.
  • PlayerInventory->setItemInHand() now sends the update to viewers of the player.

Item

General

  • A new VanillaItems class has been added, which contains static methods for creating any currently-known item type. This should be preferred instead of use of ItemFactory::get() where constants were used.
  • Item->count is no longer public.
  • The hierarchy of writable books has been changed: WritableBook and WrittenBook now extend WritableBookBase.
  • The following API methods have signature changes:
    • WritableBookBase->setPages() now accepts WritableBookPage[] instead of CompoundTag[].
    • ItemFactory::get() no longer accepts string for the tags parameter.
    • ItemFactory::fromString() no longer accepts a $multiple parameter and now only returns Item, not Item|Item[].
  • The following methods are now fluent:
    • WritableBookBase->setPages()
    • Item->addEnchantment()
    • Item->removeEnchantment()
    • Item->removeEnchantments()
    • Armor->setCustomColor()
    • WrittenBook->setTitle()
    • WrittenBook->setAuthor()
    • WrittenBook->setGeneration()
  • The following API methods have been removed:
    • Item->getNamedTagEntry()
    • Item->removeNamedTagEntry()
    • Item->setDamage(): "Damage" is now immutable for all items except Durable descendents.
    • Item->setNamedTagEntry()
    • Item::get(): this was superseded by ItemFactory::get() a long time ago
    • Item::fromString(): this was superseded by ItemFactory::fromString() a long time ago
    • Item->setCompoundTag()
    • Item->getCompoundTag()
    • Item->hasCompoundTag()
    • ProjectileItem->getProjectileEntityType()
  • The following methods have been renamed:
    • Item->getDamage() -> Item->getMeta()
  • The following methods have been moved to pocketmine\inventory\CreativeInventory:
    • Item::addCreativeItem() -> CreativeInventory::add()
    • Item::clearCreativeItems() -> CreativeInventory::clear()
    • Item::getCreativeItemIndex() -> CreativeInventory::getItemIndex()
    • Item::getCreativeItems() -> CreativeInventory::getAll()
    • Item::initCreativeItems() -> CreativeInventory::init()
    • Item::isCreativeItem() -> CreativeInventory::contains()
    • Item::removeCreativeItem() -> CreativeInventory::remove()
  • The following classes have been added:
    • ArmorTypeInfo
    • Fertilizer
    • LiquidBucket
    • MilkBucket
    • WritableBookBase
    • WritableBookPage
  • The following API methods have been added:
    • Armor->getArmorSlot()
    • ProjectileItem->getProjectileEntityClass(): returns the class of projectile to be created when thrown
  • The following classes have been removed:
    • ChainBoots
    • ChainChestplate
    • ChainHelmet
    • ChainLeggings
    • DiamondBoots
    • DiamondChestplate
    • DiamondHelmet
    • DiamondLeggings
    • GoldBoots
    • GoldChestplate
    • GoldHelmet
    • GoldLeggings
    • IronBoots
    • IronChesplate
    • IronHelmet
    • IronLeggings
    • LeatherBoots
    • LeatherCap
    • LeatherPants
    • LeatherTunic

NBT handling

  • Serialized NBT byte array caches are no longer stored on itemstacks. These caches were a premature optimization used for network layer serialization and as such were dependent on the network NBT format.
  • Internal NBT usage has been marginalized. It's no longer necessary to immediately write changes to NBT. The following hooks have been added:
    • Item->serializeCompoundTag()
    • Item->deserializeCompoundTag()
  • It's planned to remove runtime NBT from items completely, but this currently presents unresolved backwards-compatibility problems.

Enchantment

  • The following API methods have been renamed:
    • Enchantment::registerEnchantment() -> Enchantment::register()
    • Enchantment::getEnchantment() -> Enchantment::get()
    • Enchantment::getEnchantmentByName() -> Enchantment::fromString()
  • Static getter methods for all registered enchantment types have been added. Enchantment::getEnchantment(Enchantment::WHATEVER) should be replaced by Enchantment::WHATEVER().

Lang

  • The following classes have been renamed:
    • BaseLang -> Language
  • LanguageNotFoundException has been added. This is thrown when trying to construct a Language which doesn't exist in the server files.

Network

  • The following fields have been removed:
    • Network::$BATCH_THRESHOLD
  • The following classes have been renamed:
    • SourceInterface -> NetworkInterface
    • AdvancedSourceInterface -> AdvancedNetworkInterface
  • The following classes have been moved:
    • CompressBatchedTask -> mcpe\CompressBatchTask
    • level\format\io\ChunkRequestTask -> mcpe\ChunkRequestTask
    • mcpe\RakLibInterface -> mcpe\raklib\RakLibInterface
  • The following classes have been removed:
    • mcpe\PlayerNetworkSessionAdapter
  • The following methods have been removed:
    • NetworkInterface->putPacket()
    • NetworkInterface->close()
    • NetworkInterface->emergencyShutdown()
  • NetworkInterface now represents a more generic interface to be implemented by any network component, as opposed to specifically a player network interface.
  • Everything under the rcon subnamespace has been removed.
  • upnp\UPnP has significant changes. It's now a network component instead of a pair of static methods.

Permission

  • Added PermissibleDelegateTrait to reduce boilerplate for users of PermissibleBase. This trait is used by ConsoleCommandSender and Player.
  • The following API methods have been moved:
    • Permission::getByName() -> PermissionParser::defaultFromString()
    • Permission::loadPermissions() -> PermissionParser::loadPermissions()
    • Permission::loadPermission() -> PermissionParser::loadPermission()
  • The following API methods have been added:
    • PermissionParser::emitPermissions()
  • The following API methods have changes:
    • PermissionParser::defaultFromString() now throws InvalidArgumentException on unknown values.

Player

  • The following classes have moved to the new pocketmine\player namespace:
    • Achievement
    • GameMode
    • IPlayer
    • OfflinePlayer
    • PlayerInfo
    • Player
  • The following constants have been removed:
    • Player::SURVIVAL - use GameMode::SURVIVAL()
    • Player::CREATIVE - use GameMode::CREATIVE()
    • Player::ADVENTURE - use GameMode::ADVENTURE()
    • Player::SPECTATOR - use GameMode::SPECTATOR()
    • Player::VIEW - use GameMode::SPECTATOR()
  • (almost) all packet handlers have been removed from Player. They are now encapsulated within the network layer.
  • The following API methods have been added:
    • Player->attackBlock(): attack (left click) the target block, e.g. to start destroying it (survival)
    • Player->attackEntity(): melee-attack (left click) the target entity (if within range)
    • Player->breakBlock(): destroy the target block in the current world (immediately)
    • Player->consumeHeldItem(): consume the previously activated item, e.g. eating food
    • Player->continueBreakBlock(): punch the target block during destruction in survival, advancing break animation and creating particles
    • Player->hasFiniteResources()
    • Player->interactBlock(): interact (right click) the target block in the current world
    • Player->interactEntity(): interact (right click) the target entity, e.g. to apply a nametag (not implemented yet)
    • Player->pickBlock(): picks (mousewheel click) the target block in the current world
    • Player->releaseHeldItem(): release the previously activated item, e.g. shooting a bow
    • Player->selectHotbarSlot(): select the specified hotbar slot
    • Player->stopBreakBlock(): cease attacking a previously attacked block
    • Player->toggleFlight(): tries to start / stop flying (fires events, may be cancelled)
    • Player->updateNextPosition(): sets the player's next attempted move location (fires events, may be cancelled)
    • Player->useHeldItem(): activate the held item, e.g. throwing a snowball
  • The following API methods have been removed:
    • Player->addActionBarMessage(): replaced by sendActionBarMessage()
    • Player->addSubTitle(): replaced by sendSubTitle()
    • Player->addTitle(): replaced by sendTitle()
    • Player->getAddress(): replaced by NetworkSession->getIp()
    • Player->getPing(): moved to NetworkSession
    • Player->getPort(): moved to NetworkSession
    • Player->updatePing(): moved to NetworkSession
    • Player->dataPacket(): replaced by NetworkSession->sendDataPacket()
    • Player->sendDataPacket(): replaced by NetworkSession->sendDataPacket()

Plugin

  • API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message Multiple minimum API versions found for some major versions.
  • plugin.yml YAML commands loading is now internalized inside PluginBase.
  • PluginManager->registerEvent() now has a simpler signature: registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false). The provided closure must accept the specified event class as its only parameter. See Event API changes for more details.
  • The following classes have been removed:
    • PluginLogger
  • The following interface requirements have been removed:
    • Plugin->onEnable(): this is now internalized inside PluginBase
    • Plugin->onDisable(): same as above
    • Plugin->onLoad(): same as above
    • Plugin no longer extends CommandExecutor. This means that Plugin implementations don't need to implement onCommand() anymore.
  • The following hook methods have changed visibility:
    • PluginBase->onEnable() changed from public to protected
    • PluginBase->onDisable() changed from public to protected
    • PluginBase->onLoad() changed from public to protected
  • The following hook methods have been renamed:
    • Plugin->setEnabled() -> Plugin->onEnableStateChange(). This change was made to force plugin developers misusing this hook to stop, and to give it a name that better describes what it does.
  • The following (deprecated) API methods have been removed:
    • PluginManager->callEvent(): use Event->call() instead
    • PluginManager->addPermission(): use PermissionManager instead
    • PluginManager->getDefaultPermSubscriptions(): use PermissionManager instead
    • PluginManager->getDefaultPermissions(): use PermissionManager instead
    • PluginManager->getPermission(): use PermissionManager instead
    • PluginManager->getPermissionSubscriptions(): use PermissionManager instead
    • PluginManager->getPermissions(): use PermissionManager instead
    • PluginManager->recalculatePermissionDefaults(): use PermissionManager instead
    • PluginManager->removePermission(): use PermissionManager instead
    • PluginManager->subscribeToDefaultPerms(): use PermissionManager instead
    • PluginManager->subscribeToPermission(): use PermissionManager instead
    • PluginManager->unsubscribeFromDefaultPerms(): use PermissionManager instead
    • PluginManager->unsubscribeFromPermission(): use PermissionManager instead
  • It is no longer permitted to throw exceptions from PluginBase->onEnable() or PluginBase->onLoad(). Doing so will now cause the server to crash.

Scheduler

Thread-local storage for AsyncTasks

  • TLS has been completely rewritten in this release to be self contained, more robust and easier to use.
  • Now behaves more like simple properties. storeLocal() writes, fetchLocal() reads.
  • Self-contained and doesn't depend on the async pool to clean up after it.
  • Values are automatically removed from storage when the AsyncTask is garbage-collected, just like a regular property.
  • Supports storing multiple values, differentiated by string names.
  • fetchLocal() can now be used multiple times. It no longer deletes the stored value.
  • The following classes have been removed:
    • FileWriteTask
  • The following methods have been removed:
    • AsyncTask->peekLocal(): use fetchLocal() instead
  • The following methods have signature changes:
    • AsyncTask->storeLocal() now has the signature storeLocal(string $key, mixed $complexData) : void
    • AsyncTask->fetchLocal() now has the signature fetchLocal(string $key) : mixed

Other changes

  • AsyncPool uses a new, significantly more performant algorithm for task collection.
  • BulkCurlTask has had the $complexData constructor parameter removed.
  • pocketmine\Collectable has been removed, and is no longer extended by AsyncTask.
  • The following hooks have been added:
    • AsyncTask->onError(): called on the main thread when an uncontrolled error was detected in the async task, such as a memory failure
  • The following hooks have signature changes:
    • AsyncTask->onCompletion() no longer accepts a Server parameter, and has a void return type.
    • AsyncTask->onProgressUpdate() no longer accepts a Server parameter, and has a void return type.
  • The following API methods have been removed:
    • AsyncTask->getFromThreadStore(): use AsyncTask->worker->getFromThreadStore()
    • AsyncTask->removeFromThreadStore(): use AsyncTask->worker->removeFromThreadStore()
    • AsyncTask->saveToThreadStore(): use AsyncTask->worker->saveToThreadStore()

Server

  • The following API methods have been removed:
    • reloadWhitelist()
    • getLevelMetadata()
    • getPlayerMetadata()
    • getEntityMetadata()
    • getDefaultGamemode()
    • getLoggedInPlayers()
    • onPlayerLogout()
    • addPlayer()
    • removePlayer()
    • reload()
    • getSpawnRadius()
    • enablePlugin()
    • disablePlugin()
    • getGamemodeString() - replaced by pocketmine\player\GameMode->getTranslationKey()
    • getGamemodeName() - replaced by pocketmine\player\GameMode->name()
    • getGamemodeFromString() - replaced by GameMode::fromString()
  • The following API methods have changed:
    • getOfflinePlayerData() no longer creates data when it doesn't exist.

Level / World

General

  • All references to Level in the context of "world" have been changed to World.
    • The pocketmine\level namespace has been renamed to pocketmine\world
    • All classes containing the world Level in the name in the "world" context have been changed to World.
    • Position->getLevel() has been renamed to Position->getWorld(), and Position->level has been renamed to Position->world.
  • Extracted a WorldManager unit from Server
    • Server->findEntity() -> WorldManager->findEntity()
    • Server->generateLevel() -> WorldManager->generateWorld()
    • Server->getAutoSave() -> WorldManager->getAutoSave()
    • Server->getDefaultLevel() -> WorldManager->getDefaultWorld()
    • Server->getLevel() -> WorldManager->getWorld()
    • Server->getLevelByName() -> WorldManager->getWorldByName()
    • Server->getLevels() -> WorldManager->getWorlds()
    • Server->isLevelGenerated() -> WorldManager->isWorldGenerated()
    • Server->isLevelLoaded() -> WorldManager->isWorldLoaded()
    • Server->loadLevel() -> WorldManager->loadWorld()
    • Server->setAutoSave() -> WorldManager->setAutoSave()
    • Server->setDefaultLevel() -> WorldManager->setDefaultWorld()
    • Server->unloadLevel() -> WorldManager->unloadWorld()
  • Added WorldManager->getAutoSaveTicks() and WorldManager->setAutoSaveTicks() to allow controlling the autosave interval.
  • The following classes have been added:
    • BlockTransaction: allows creating batch commits of block changes with validation conditions - if any block can't be applied, the whole transaction fails to apply.
    • ChunkListenerNoOpTrait: contains default no-op stubs for chunk listener implementations
    • ChunkListener: interface allowing subscribing to events happening on a given chunk
  • The following API methods have been added:
    • World->registerChunkListener()
    • World->unregisterChunkListener()
  • The following API methods have been removed:
    • ChunkLoader->getLoaderId() (now object ID is used)
    • World->isFullBlock()
  • The following API methods have changed signatures:
    • World->addParticle() now has the signature addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void
    • World->addSound() now has the signature addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void
    • World->getRandomTickedBlocks() now returns bool[] instead of SplFixedArray.
    • World->addRandomTickedBlock() now accepts Block instead of int, int.
    • World->removeRandomTickedBlock() now accepts Block instead of int, int.
    • World->setBlock() has had the $direct parameter removed.
  • The following API methods have been renamed / moved:
    • Level->getCollisionCubes() -> World->getCollisionBoxes()
  • Extracted a unit pocketmine\world\format\io\FastChunkSerializer from Chunk:
    • Chunk->fastDeserialize() -> FastChunkSerializer::deserialize()
    • Chunk->fastSerialize() -> FastChunkSerializer::serialize()
  • A ChunkListener interface has been extracted from ChunkLoader. The following methods have been moved:
    • ChunkLoader->onBlockChanged() -> ChunkListener->onBlockChanged()
    • ChunkLoader->onChunkChanged() -> ChunkListener->onChunkChanged()
    • ChunkLoader->onChunkLoaded() -> ChunkListener->onChunkLoaded()
    • ChunkLoader->onChunkPopulated() -> ChunkListener->onChunkPopulated()
    • ChunkLoader->onChunkUnloaded() -> ChunkListener->onChunkUnloaded()
  • Location has been moved to pocketmine\entity\Location.

Particles

  • DustParticle->__construct() now accepts a pocketmine\utils\Color object instead of r, g, b, a.
  • pocketmine\world\particle\Particle no longer extends pocketmine\math\Vector3, and has been converted to an interface.
  • Added the following Particle classes:
    • DragonEggTeleportParticle
    • PunchBlockParticle

Sounds

  • pocketmine\world\sound\Sound no longer extends pocketmine\math\Vector3, and has been converted to an interface.
  • Sound->encode() now accepts ?\pocketmine\math\Vector3. NULL may be passed for sounds which are global.
  • Added the following classes:
    • ArrowHitSound
    • BlockBreakSound
    • BlockPlaceSound
    • BowShootSound
    • BucketEmptyLavaSound
    • BucketEmptyWaterSound
    • BucketFillLavaSound
    • BucketFillWaterSound
    • ChestCloseSound
    • ChestOpenSound
    • EnderChestCloseSound
    • EnderChestOpenSound
    • ExplodeSound
    • FlintSteelSound
    • ItemBreakSound
    • NoteInstrument
    • NoteSound
    • PaintingPlaceSound
    • PotionSplashSound
    • RedstonePowerOffSound
    • RedstonePowerOnSound
    • ThrowSound
    • XpCollectSound
    • XpLevelUpSound

Utils

  • Terminal::hasFormattingCodes() no longer auto-detects the availability of formatting codes. Instead it's necessary to use Terminal::init() with no parameters to initialize, or true or false to override.
  • Config->save() no longer catches exceptions thrown during emitting to disk.
  • The following new classes have been added:
    • InternetException
    • Internet
    • Process
  • The following API methods have been added:
    • Color::fromRGBA()
    • Config->getPath(): returns the path to the config on disk
    • Terminal::write(): emits a Minecraft-formatted text line without newline
    • Terminal::writeLine(): emits a Minecraft-formatted text line with newline
    • Utils::recursiveUnlink(): recursively deletes a directory and its contents
  • The following deprecated API redirects have been removed:
    • Utils::execute(): moved to Process
    • Utils::getIP(): moved to Internet
    • Utils::getMemoryUsage(): moved to Process
    • Utils::getRealMemoryUsage(): moved to Process
    • Utils::getThreadCount(): moved to Process
    • Utils::getURL(): moved to Internet
    • Utils::kill(): moved to Process
    • Utils::postURL(): moved to Internet
    • Utils::simpleCurl(): moved to Internet
  • The following API fields have been removed / hidden:
    • Utils::$ip
    • Utils::$online
    • Utils::$os
  • The following API methods have signature changes:
    • Color::mix() now requires the first parameter. Previously, it was possible to pass zero arguments, which would raise an ArgumentCountError (not static analysis friendly).
    • Internet::simpleCurl() now requires a Closure for its onSuccess parameter instead of callable.
  • The following API methods have been removed:
    • Color->setA()
    • Color->setR()
    • Color->setG()
    • Color->setB()
    • Color->toABGR()
    • Color->toBGRA()
    • Color::fromABGR()
    • Utils::getCallableIdentifier()