Merge 1.16 support into PM4 (with changes)

This commit is contained in:
Dylan K. Taylor 2020-06-26 22:21:09 +01:00
commit 7e6adc41f0
82 changed files with 3044 additions and 154 deletions

@ -1 +1 @@
Subproject commit cc132c80dd9d76a44e4b0a360e85e8e28bba8956
Subproject commit 43edcfde6b9611b7c7d643be52332707cc10cd1b

View File

@ -85,11 +85,11 @@ class BlockFactory{
public $blastResistance;
public function __construct(){
$this->fullList = new \SplFixedArray(8192);
$this->fullList = new \SplFixedArray(16384);
$this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1));
$this->diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false));
$this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0.0));
$this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 16384, 1));
$this->diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false));
$this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0));
$this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail"));
$this->register(new Air(new BID(Ids::AIR), "Air"));

View File

@ -86,7 +86,8 @@ class CraftingManager{
}, $recipe->getResults()),
$nullUUID,
"crafting_table",
50
50,
$counter
);
}
}
@ -108,7 +109,8 @@ class CraftingManager{
}, $recipe->getResults()),
$nullUUID,
"crafting_table",
50
50,
$counter
);
}
}

View File

@ -69,6 +69,7 @@ class Enchantment{
public const MULTISHOT = 33;
public const PIERCING = 34;
public const QUICK_CHARGE = 35;
public const SOUL_SPEED = 36;
public const RARITY_COMMON = 10;
public const RARITY_UNCOMMON = 5;

View File

@ -38,11 +38,13 @@ use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
use pocketmine\network\mcpe\protocol\CreativeContentPacket;
use pocketmine\network\mcpe\protocol\InventoryContentPacket;
use pocketmine\network\mcpe\protocol\InventorySlotPacket;
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes;
use pocketmine\player\Player;
use function array_map;
@ -51,6 +53,14 @@ use function max;
class InventoryManager{
//TODO: HACK!
//these IDs are used for 1.16 to restore 1.14ish crafting & inventory behaviour; since they don't seem to have any
//effect on the behaviour of inventory transactions I don't currently plan to integrate these into the main system.
private const RESERVED_WINDOW_ID_RANGE_START = ContainerIds::LAST - 10;
private const RESERVED_WINDOW_ID_RANGE_END = ContainerIds::LAST;
public const HARDCODED_CRAFTING_GRID_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 1;
public const HARDCODED_INVENTORY_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 2;
/** @var Player */
private $player;
/** @var NetworkSession */
@ -107,7 +117,7 @@ class InventoryManager{
public function onCurrentWindowChange(Inventory $inventory) : void{
$this->onCurrentWindowRemove();
$this->add($this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST), $inventory);
$this->add($this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % self::RESERVED_WINDOW_ID_RANGE_START), $inventory);
$pk = $this->createContainerOpen($this->lastInventoryNetworkId, $inventory);
if($pk !== null){
@ -148,6 +158,10 @@ class InventoryManager{
}
public function onClientRemoveWindow(int $id) : void{
if($id >= self::RESERVED_WINDOW_ID_RANGE_START && $id <= self::RESERVED_WINDOW_ID_RANGE_END){
//TODO: HACK! crafting grid & main inventory currently use these fake IDs
return;
}
if($id === $this->lastInventoryNetworkId){
$this->remove($id);
$this->player->removeCurrentWindow();
@ -162,7 +176,7 @@ class InventoryManager{
$currentItem = $inventory->getItem($slot);
$clientSideItem = $this->initiatedSlotChanges[$windowId][$slot] ?? null;
if($clientSideItem === null or !$clientSideItem->equalsExact($currentItem)){
$this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, TypeConverter::getInstance()->coreItemStackToNet($currentItem)));
$this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($currentItem))));
}
unset($this->initiatedSlotChanges[$windowId][$slot]);
}
@ -173,8 +187,8 @@ class InventoryManager{
if($windowId !== null){
unset($this->initiatedSlotChanges[$windowId]);
$typeConverter = TypeConverter::getInstance();
$this->session->sendDataPacket(InventoryContentPacket::create($windowId, array_map(function(Item $itemStack) use ($typeConverter) : ItemStack{
return $typeConverter->coreItemStackToNet($itemStack);
$this->session->sendDataPacket(InventoryContentPacket::create($windowId, array_map(function(Item $itemStack) use ($typeConverter) : ItemStackWrapper{
return ItemStackWrapper::legacy($typeConverter->coreItemStackToNet($itemStack));
}, $inventory->getContents(true))));
}
}
@ -210,6 +224,9 @@ class InventoryManager{
}
}
$this->session->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items));
$nextEntryId = 1;
$this->session->sendDataPacket(CreativeContentPacket::create(array_map(function(Item $item) use($typeConverter, &$nextEntryId) : CreativeContentEntry{
return new CreativeContentEntry($nextEntryId++, $typeConverter->coreItemStackToNet($item));
}, $this->player->isSpectator() ? [] : CreativeInventory::getInstance()->getAll())));
}
}

View File

@ -85,6 +85,7 @@ use pocketmine\network\mcpe\protocol\TransferPacket;
use pocketmine\network\mcpe\protocol\types\command\CommandData;
use pocketmine\network\mcpe\protocol\types\command\CommandEnum;
use pocketmine\network\mcpe\protocol\types\command\CommandParameter;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute;
use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty;
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
@ -684,7 +685,8 @@ class NetworkSession{
}
public function syncPlayerSpawnPoint(Position $newSpawn) : void{
$this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), false)); //TODO: spawn forced
[$x, $y, $z] = [$newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ()];
$this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($x, $y, $z, DimensionIds::OVERWORLD, $x, $y, $z));
}
public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{

View File

@ -27,7 +27,7 @@ use pocketmine\utils\SingletonTrait;
use function strlen;
use function zlib_decode;
use function zlib_encode;
use const ZLIB_ENCODING_DEFLATE;
use const ZLIB_ENCODING_RAW;
final class ZlibCompressor implements Compressor{
use SingletonTrait;
@ -72,6 +72,6 @@ final class ZlibCompressor implements Compressor{
}
public function compress(string $payload) : string{
return zlib_encode($payload, ZLIB_ENCODING_DEFLATE, $this->willCompress($payload) ? $this->level : 0);
return zlib_encode($payload, ZLIB_ENCODING_RAW, $this->willCompress($payload) ? $this->level : 0);
}
}

View File

@ -0,0 +1,58 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\convert;
use pocketmine\nbt\tag\CompoundTag;
final class R12ToCurrentBlockMapEntry{
/** @var string */
private $id;
/** @var int */
private $meta;
/** @var CompoundTag */
private $blockState;
public function __construct(string $id, int $meta, CompoundTag $blockState){
$this->id = $id;
$this->meta = $meta;
$this->blockState = $blockState;
}
public function getId() : string{
return $this->id;
}
public function getMeta() : int{
return $this->meta;
}
public function getBlockState() : CompoundTag{
return $this->blockState;
}
public function __toString(){
return "id=$this->id, meta=$this->meta, nbt=$this->blockState";
}
}

View File

@ -29,6 +29,7 @@ use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\CacheableNbt;
use pocketmine\utils\SingletonTrait;
use function file_get_contents;
@ -70,9 +71,18 @@ final class RuntimeBlockMapping{
private function setupLegacyMappings() : void{
$legacyIdMap = LegacyBlockIdToStringIdMap::getInstance();
$legacyStateMap = (new NetworkNbtSerializer())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/r12_to_current_block_map.nbt"))->getTag();
if(!($legacyStateMap instanceof ListTag) or $legacyStateMap->getTagType() !== NBT::TAG_Compound){
throw new \RuntimeException("Invalid legacy states mapping table, expected TAG_List<TAG_Compound> root");
/** @var R12ToCurrentBlockMapEntry[] $legacyStateMap */
$legacyStateMap = [];
$legacyStateMapReader = new PacketSerializer(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/r12_to_current_block_map.bin"));
$nbtReader = new NetworkNbtSerializer();
while(!$legacyStateMapReader->feof()){
$id = $legacyStateMapReader->getString();
$meta = $legacyStateMapReader->getLShort();
$offset = $legacyStateMapReader->getOffset();
$state = $nbtReader->read($legacyStateMapReader->getBuffer(), $offset)->mustGetCompoundTag();
$legacyStateMapReader->setOffset($offset);
$legacyStateMap[] = new R12ToCurrentBlockMapEntry($id, $meta, $state);
}
/**
@ -82,19 +92,17 @@ final class RuntimeBlockMapping{
foreach($this->bedrockKnownStates as $k => $state){
$idToStatesMap[$state->getCompoundTag("block")->getString("name")][] = $k;
}
/** @var CompoundTag $pair */
foreach($legacyStateMap as $pair){
$oldState = $pair->getCompoundTag("old");
$id = $legacyIdMap->stringToLegacy($oldState->getString("name"));
$id = $legacyIdMap->stringToLegacy($pair->getId()) ?? null;
if($id === null){
throw new \RuntimeException("State does not have a legacy ID");
throw new \RuntimeException("No legacy ID matches " . $pair->getId());
}
$data = $oldState->getShort("val");
$data = $pair->getMeta();
if($data > 15){
//we can't handle metadata with more than 4 bits
continue;
}
$mappedState = $pair->getCompoundTag("new");
$mappedState = $pair->getBlockState();
$mappedName = $mappedState->getString("name");
if(!isset($idToStatesMap[$mappedName])){
throw new \RuntimeException("Mapped new state does not appear in network table");

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\handler;
use pocketmine\block\BlockLegacyIds;
use pocketmine\block\ItemFrame;
use pocketmine\block\Sign;
use pocketmine\block\utils\SignText;
@ -42,6 +43,7 @@ use pocketmine\nbt\tag\StringTag;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\network\mcpe\InventoryManager;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\ActorFallPacket;
@ -55,6 +57,7 @@ use pocketmine\network\mcpe\protocol\BossEventPacket;
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandRequestPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\InteractPacket;
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
@ -86,6 +89,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes;
use pocketmine\player\Player;
use pocketmine\utils\AssumptionFailedError;
use function array_push;
@ -205,25 +209,16 @@ class InGamePacketHandler extends PacketHandler{
$isFinalCraftingPart = false;
$converter = TypeConverter::getInstance();
foreach($data->getActions() as $networkInventoryAction){
$old = $converter->netItemStackToCore($networkInventoryAction->oldItem);
$new = $converter->netItemStackToCore($networkInventoryAction->newItem);
if(
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER and
$networkInventoryAction->windowId === ContainerIds::UI and
$networkInventoryAction->inventorySlot === 50 and
!$old->equalsExact($new)
){
$isCraftingPart = true;
if(!$old->isNull() and $new->isNull()){
$isFinalCraftingPart = true;
}
}elseif(
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_TODO and (
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT or
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT
)
){
$isCraftingPart = true;
if($networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT){
$isFinalCraftingPart = true;
}
}
try{
@ -262,7 +257,7 @@ class InGamePacketHandler extends PacketHandler{
* So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting
* transaction goes wrong.
*/
$this->session->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE));
$this->session->sendDataPacket(ContainerClosePacket::create(InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID));
return false;
}finally{
@ -318,6 +313,14 @@ class InGamePacketHandler extends PacketHandler{
$blockPos = $data->getBlockPos();
if(!$this->player->interactBlock($blockPos, $data->getFace(), $clickPos)){
$this->onFailedBlockAction($blockPos, $data->getFace());
}elseif($this->player->getWorld()->getBlock($blockPos)->getId() === BlockLegacyIds::CRAFTING_TABLE){
//TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack
//allows it to carry on working approximately the same way as it did in 1.14
$this->session->sendDataPacket(ContainerOpenPacket::blockInvVec3(
InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID,
WindowTypes::WORKBENCH,
$blockPos
));
}
return true;
case UseItemTransactionData::ACTION_BREAK_BLOCK:
@ -417,6 +420,21 @@ class InGamePacketHandler extends PacketHandler{
//TODO: implement handling for this where it matters
return true;
}
$target = $this->player->getWorld()->getEntity($packet->target);
if($target === null){
return false;
}
if($packet->action === InteractPacket::ACTION_OPEN_INVENTORY && $target === $this->player){
//TODO: HACK! this restores 1.14ish behaviour, but this should be able to be listened to and
//controlled by plugins. However, the player is always a subscriber to their own inventory so it
//doesn't integrate well with the regular container system right now.
$this->session->sendDataPacket(ContainerOpenPacket::entityInv(
InventoryManager::HARDCODED_INVENTORY_WINDOW_ID,
WindowTypes::INVENTORY,
$this->player->getId()
));
return true;
}
return false; //TODO
}
@ -506,13 +524,9 @@ class InGamePacketHandler extends PacketHandler{
public function handleContainerClose(ContainerClosePacket $packet) : bool{
$this->player->doCloseInventory();
if($packet->windowId === 255){
//Closed a fake window
return true;
}
$this->session->getInvManager()->onClientRemoveWindow($packet->windowId);
$this->session->sendDataPacket(ContainerClosePacket::create($packet->windowId));
return true;
}
@ -738,7 +752,8 @@ class InGamePacketHandler extends PacketHandler{
$inQuotes = true;
}else{
$backslashes = 0;
for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){}
for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){
}
if(($backslashes % 2) === 0){ //unescaped quote
$inQuotes = false;
}

View File

@ -52,6 +52,7 @@ use pocketmine\network\mcpe\protocol\ClientCacheBlobStatusPacket;
use pocketmine\network\mcpe\protocol\ClientCacheMissResponsePacket;
use pocketmine\network\mcpe\protocol\ClientCacheStatusPacket;
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
use pocketmine\network\mcpe\protocol\CodeBuilderPacket;
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandOutputPacket;
use pocketmine\network\mcpe\protocol\CommandRequestPacket;
@ -61,8 +62,11 @@ use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\CreativeContentPacket;
use pocketmine\network\mcpe\protocol\DebugInfoPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\EducationSettingsPacket;
use pocketmine\network\mcpe\protocol\EmoteListPacket;
use pocketmine\network\mcpe\protocol\EmotePacket;
use pocketmine\network\mcpe\protocol\EventPacket;
use pocketmine\network\mcpe\protocol\GameRulesChangedPacket;
@ -73,6 +77,8 @@ use pocketmine\network\mcpe\protocol\InventoryContentPacket;
use pocketmine\network\mcpe\protocol\InventorySlotPacket;
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
use pocketmine\network\mcpe\protocol\ItemStackRequestPacket;
use pocketmine\network\mcpe\protocol\ItemStackResponsePacket;
use pocketmine\network\mcpe\protocol\LabTablePacket;
use pocketmine\network\mcpe\protocol\LecternUpdatePacket;
use pocketmine\network\mcpe\protocol\LevelChunkPacket;
@ -99,15 +105,20 @@ use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket;
use pocketmine\network\mcpe\protocol\NpcRequestPacket;
use pocketmine\network\mcpe\protocol\OnScreenTextureAnimationPacket;
use pocketmine\network\mcpe\protocol\PacketHandlerInterface;
use pocketmine\network\mcpe\protocol\PacketViolationWarningPacket;
use pocketmine\network\mcpe\protocol\PhotoTransferPacket;
use pocketmine\network\mcpe\protocol\PlayerActionPacket;
use pocketmine\network\mcpe\protocol\PlayerArmorDamagePacket;
use pocketmine\network\mcpe\protocol\PlayerAuthInputPacket;
use pocketmine\network\mcpe\protocol\PlayerEnchantOptionsPacket;
use pocketmine\network\mcpe\protocol\PlayerHotbarPacket;
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
use pocketmine\network\mcpe\protocol\PositionTrackingDBClientRequestPacket;
use pocketmine\network\mcpe\protocol\PositionTrackingDBServerBroadcastPacket;
use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
@ -163,9 +174,9 @@ use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockPropertiesPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket;
use pocketmine\network\mcpe\protocol\UpdateEquipPacket;
use pocketmine\network\mcpe\protocol\UpdatePlayerGameTypePacket;
use pocketmine\network\mcpe\protocol\UpdateSoftEnumPacket;
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
use pocketmine\network\mcpe\protocol\VideoStreamConnectPacket;
/**
* Handlers are attached to sessions to handle packets received from their associated clients. A handler
@ -671,10 +682,6 @@ abstract class PacketHandler implements PacketHandlerInterface{
return false;
}
public function handleVideoStreamConnect(VideoStreamConnectPacket $packet) : bool{
return false;
}
public function handleAddEntity(AddEntityPacket $packet) : bool{
return false;
}
@ -746,4 +753,52 @@ abstract class PacketHandler implements PacketHandlerInterface{
public function handlePlayerAuthInput(PlayerAuthInputPacket $packet) : bool{
return false;
}
public function handleCreativeContent(CreativeContentPacket $packet) : bool{
return false;
}
public function handlePlayerEnchantOptions(PlayerEnchantOptionsPacket $packet) : bool{
return false;
}
public function handleItemStackRequest(ItemStackRequestPacket $packet) : bool{
return false;
}
public function handleItemStackResponse(ItemStackResponsePacket $packet) : bool{
return false;
}
public function handlePlayerArmorDamage(PlayerArmorDamagePacket $packet) : bool{
return false;
}
public function handleCodeBuilder(CodeBuilderPacket $packet) : bool{
return false;
}
public function handleUpdatePlayerGameType(UpdatePlayerGameTypePacket $packet) : bool{
return false;
}
public function handleEmoteList(EmoteListPacket $packet) : bool{
return false;
}
public function handlePositionTrackingDBServerBroadcast(PositionTrackingDBServerBroadcastPacket $packet) : bool{
return false;
}
public function handlePositionTrackingDBClientRequest(PositionTrackingDBClientRequestPacket $packet) : bool{
return false;
}
public function handleDebugInfo(DebugInfoPacket $packet) : bool{
return false;
}
public function handlePacketViolationWarning(PacketViolationWarningPacket $packet) : bool{
return false;
}
}

View File

@ -31,6 +31,7 @@ use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\types\BoolGameRule;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\network\mcpe\protocol\types\SpawnSettings;
use pocketmine\network\mcpe\StaticPacketCache;
use pocketmine\player\Player;
use pocketmine\Server;
@ -65,7 +66,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$pk->pitch = $location->pitch;
$pk->yaw = $location->yaw;
$pk->seed = -1;
$pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly
$pk->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly
$pk->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode());
$pk->difficulty = $location->getWorldNonNull()->getDifficulty();
$pk->spawnX = $spawnPosition->getFloorX();

View File

@ -87,6 +87,7 @@ class ActorEventPacket extends DataPacket implements ClientboundPacket, Serverbo
public const TREASURE_HUNT = 72;
public const AGENT_SUMMON = 73;
public const CHARGED_CROSSBOW = 74;
public const FALL = 75;
//TODO: add more events

View File

@ -0,0 +1,66 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class CodeBuilderPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::CODE_BUILDER_PACKET;
/** @var string */
private $url;
/** @var bool */
private $openCodeBuilder;
public static function create(string $url, bool $openCodeBuilder) : self{
$result = new self;
$result->url = $url;
$result->openCodeBuilder = $openCodeBuilder;
return $result;
}
public function getUrl() : string{
return $this->url;
}
public function openCodeBuilder() : bool{
return $this->openCodeBuilder;
}
protected function decodePayload(PacketSerializer $in) : void{
$this->url = $in->getString();
$this->openCodeBuilder = $in->getBool();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putString($this->url);
$out->putBool($this->openCodeBuilder);
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleCodeBuilder($this);
}
}

View File

@ -83,10 +83,13 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}
}
for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){
$input = $in->getVarInt();
$ingredient = $in->getVarInt();
$output = $in->getVarInt();
$this->potionTypeRecipes[] = new PotionTypeRecipe($input, $ingredient, $output);
$inputId = $in->getVarInt();
$inputMeta = $in->getVarInt();
$ingredientId = $in->getVarInt();
$ingredientMeta = $in->getVarInt();
$outputId = $in->getVarInt();
$outputMeta = $in->getVarInt();
$this->potionTypeRecipes[] = new PotionTypeRecipe($inputId, $inputMeta, $ingredientId, $ingredientMeta, $outputId, $outputMeta);
}
for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){
$input = $in->getVarInt();
@ -105,9 +108,12 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}
$out->putUnsignedVarInt(count($this->potionTypeRecipes));
foreach($this->potionTypeRecipes as $recipe){
$out->putVarInt($recipe->getInputPotionType());
$out->putVarInt($recipe->getInputItemId());
$out->putVarInt($recipe->getInputItemMeta());
$out->putVarInt($recipe->getIngredientItemId());
$out->putVarInt($recipe->getOutputPotionType());
$out->putVarInt($recipe->getIngredientItemMeta());
$out->putVarInt($recipe->getOutputItemId());
$out->putVarInt($recipe->getOutputItemMeta());
}
$out->putUnsignedVarInt(count($this->potionContainerRecipes));
foreach($this->potionContainerRecipes as $recipe){

View File

@ -0,0 +1,67 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry;
use function count;
class CreativeContentPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::CREATIVE_CONTENT_PACKET;
/** @var CreativeContentEntry[] */
private $entries;
/**
* @param CreativeContentEntry[] $entries
*/
public static function create(array $entries) : self{
$result = new self;
$result->entries = $entries;
return $result;
}
/** @return CreativeContentEntry[] */
public function getEntries() : array{ return $this->entries; }
protected function decodePayload(PacketSerializer $in) : void{
$this->entries = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$this->entries[] = CreativeContentEntry::read($in);
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putUnsignedVarInt(count($this->entries));
foreach($this->entries as $entry){
$entry->write($out);
}
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleCreativeContent($this);
}
}

View File

@ -0,0 +1,65 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class DebugInfoPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::DEBUG_INFO_PACKET;
/** @var int */
private $entityUniqueId;
/** @var string */
private $data;
public static function create(int $entityUniqueId, string $data) : self{
$result = new self;
$result->entityUniqueId = $entityUniqueId;
$result->data = $data;
return $result;
}
/**
* TODO: we can't call this getEntityRuntimeId() because of base class collision (crap architecture, thanks Shoghi)
*/
public function getEntityUniqueIdField() : int{ return $this->entityUniqueId; }
public function getData() : string{ return $this->data; }
protected function decodePayload(PacketSerializer $in) : void{
$this->entityUniqueId = $in->getEntityUniqueId();
$this->data = $in->getString();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putEntityUniqueId($this->entityUniqueId);
$out->putString($this->data);
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleDebugInfo($this);
}
}

View File

@ -32,12 +32,21 @@ class EducationSettingsPacket extends DataPacket implements ClientboundPacket{
/** @var string */
private $codeBuilderDefaultUri;
/** @var string */
private $codeBuilderTitle;
/** @var bool */
private $canResizeCodeBuilder;
/** @var string|null */
private $codeBuilderOverrideUri;
/** @var bool */
private $hasQuiz;
public static function create(string $codeBuilderDefaultUri, bool $hasQuiz) : self{
public static function create(string $codeBuilderDefaultUri, string $codeBuilderTitle, bool $canResizeCodeBuilder, ?string $codeBuilderOverrideUri, bool $hasQuiz) : self{
$result = new self;
$result->codeBuilderDefaultUri = $codeBuilderDefaultUri;
$result->codeBuilderTitle = $codeBuilderTitle;
$result->canResizeCodeBuilder = $canResizeCodeBuilder;
$result->codeBuilderOverrideUri = $codeBuilderOverrideUri;
$result->hasQuiz = $hasQuiz;
return $result;
}
@ -46,17 +55,42 @@ class EducationSettingsPacket extends DataPacket implements ClientboundPacket{
return $this->codeBuilderDefaultUri;
}
public function getCodeBuilderTitle() : string{
return $this->codeBuilderTitle;
}
public function canResizeCodeBuilder() : bool{
return $this->canResizeCodeBuilder;
}
public function getCodeBuilderOverrideUri() : ?string{
return $this->codeBuilderOverrideUri;
}
public function getHasQuiz() : bool{
return $this->hasQuiz;
}
protected function decodePayload(PacketSerializer $in) : void{
$this->codeBuilderDefaultUri = $in->getString();
$this->codeBuilderTitle = $in->getString();
$this->canResizeCodeBuilder = $in->getBool();
if($in->getBool()){
$this->codeBuilderOverrideUri = $in->getString();
}else{
$this->codeBuilderOverrideUri = null;
}
$this->hasQuiz = $in->getBool();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putString($this->codeBuilderDefaultUri);
$out->putString($this->codeBuilderTitle);
$out->putBool($this->canResizeCodeBuilder);
$out->putBool($this->codeBuilderOverrideUri !== null);
if($this->codeBuilderOverrideUri !== null){
$out->putString($this->codeBuilderOverrideUri);
}
$out->putBool($this->hasQuiz);
}

View File

@ -0,0 +1,74 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\uuid\UUID;
use function count;
class EmoteListPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::EMOTE_LIST_PACKET;
/** @var int */
private $playerEntityRuntimeId;
/** @var UUID[] */
private $emoteIds;
/**
* @param UUID[] $emoteIds
*/
public static function create(int $playerEntityRuntimeId, array $emoteIds) : self{
$result = new self;
$result->playerEntityRuntimeId = $playerEntityRuntimeId;
$result->emoteIds = $emoteIds;
return $result;
}
public function getPlayerEntityRuntimeId() : int{ return $this->playerEntityRuntimeId; }
/** @return UUID[] */
public function getEmoteIds() : array{ return $this->emoteIds; }
protected function decodePayload(PacketSerializer $in) : void{
$this->playerEntityRuntimeId = $in->getEntityRuntimeId();
$this->emoteIds = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$this->emoteIds[] = $in->getUUID();
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putEntityRuntimeId($this->playerEntityRuntimeId);
$out->putUnsignedVarInt(count($this->emoteIds));
foreach($this->emoteIds as $emoteId){
$out->putUUID($emoteId);
}
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleEmoteList($this);
}
}

View File

@ -30,14 +30,18 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class HurtArmorPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET;
/** @var int */
public $cause;
/** @var int */
public $health;
protected function decodePayload(PacketSerializer $in) : void{
$this->cause = $in->getVarInt();
$this->health = $in->getVarInt();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putVarInt($this->cause);
$out->putVarInt($this->health);
}

View File

@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use function count;
class InventoryContentPacket extends DataPacket implements ClientboundPacket{
@ -34,11 +34,11 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{
/** @var int */
public $windowId;
/** @var ItemStack[] */
/** @var ItemStackWrapper[] */
public $items = [];
/**
* @param ItemStack[] $items
* @param ItemStackWrapper[] $items
*
* @return InventoryContentPacket
*/
@ -53,7 +53,7 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{
$this->windowId = $in->getUnsignedVarInt();
$count = $in->getUnsignedVarInt();
for($i = 0; $i < $count; ++$i){
$this->items[] = $in->getSlot();
$this->items[] = ItemStackWrapper::read($in);
}
}
@ -61,7 +61,7 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{
$out->putUnsignedVarInt($this->windowId);
$out->putUnsignedVarInt(count($this->items));
foreach($this->items as $item){
$out->putSlot($item);
$item->write($out);
}
}

View File

@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
class InventorySlotPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::INVENTORY_SLOT_PACKET;
@ -35,10 +35,10 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{
public $windowId;
/** @var int */
public $inventorySlot;
/** @var ItemStack */
/** @var ItemStackWrapper */
public $item;
public static function create(int $windowId, int $slot, ItemStack $item) : self{
public static function create(int $windowId, int $slot, ItemStackWrapper $item) : self{
$result = new self;
$result->inventorySlot = $slot;
$result->item = $item;
@ -50,13 +50,13 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{
protected function decodePayload(PacketSerializer $in) : void{
$this->windowId = $in->getUnsignedVarInt();
$this->inventorySlot = $in->getUnsignedVarInt();
$this->item = $in->getSlot();
$this->item = ItemStackWrapper::read($in);
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putUnsignedVarInt($this->windowId);
$out->putUnsignedVarInt($this->inventorySlot);
$out->putSlot($this->item);
$this->item->write($out);
}
public function handle(PacketHandlerInterface $handler) : bool{

View File

@ -26,12 +26,14 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\InventoryTransactionChangedSlotsHack;
use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\TransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData;
use function count;
/**
* This packet effectively crams multiple packets into one.
@ -45,12 +47,28 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket
public const TYPE_USE_ITEM_ON_ENTITY = 3;
public const TYPE_RELEASE_ITEM = 4;
/** @var int */
public $requestId;
/** @var InventoryTransactionChangedSlotsHack[] */
public $requestChangedSlots;
/** @var bool */
public $hasItemStackIds;
/** @var TransactionData */
public $trData;
protected function decodePayload(PacketSerializer $in) : void{
$this->requestId = $in->readGenericTypeNetworkId();
$this->requestChangedSlots = [];
if($this->requestId !== 0){
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$this->requestChangedSlots[] = InventoryTransactionChangedSlotsHack::read($in);
}
}
$transactionType = $in->getUnsignedVarInt();
$this->hasItemStackIds = $in->getBool();
switch($transactionType){
case self::TYPE_NORMAL:
$this->trData = new NormalTransactionData();
@ -71,12 +89,23 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket
throw new PacketDecodeException("Unknown transaction type $transactionType");
}
$this->trData->decode($in);
$this->trData->decode($in, $this->hasItemStackIds);
}
protected function encodePayload(PacketSerializer $out) : void{
$out->writeGenericTypeNetworkId($this->requestId);
if($this->requestId !== 0){
$out->putUnsignedVarInt(count($this->requestChangedSlots));
foreach($this->requestChangedSlots as $changedSlots){
$changedSlots->write($out);
}
}
$out->putUnsignedVarInt($this->trData->getTypeId());
$this->trData->encode($out);
$out->putBool($this->hasItemStackIds);
$this->trData->encode($out, $this->hasItemStackIds);
}
public function handle(PacketHandlerInterface $handler) : bool{

View File

@ -0,0 +1,67 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\ItemStackRequest;
use function count;
class ItemStackRequestPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ITEM_STACK_REQUEST_PACKET;
/** @var ItemStackRequest[] */
private $requests;
/**
* @param ItemStackRequest[] $requests
*/
public static function create(array $requests) : self{
$result = new self;
$result->requests = $requests;
return $result;
}
/** @return ItemStackRequest[] */
public function getRequests() : array{ return $this->requests; }
protected function decodePayload(PacketSerializer $in) : void{
$this->requests = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$this->requests[] = ItemStackRequest::read($in);
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putUnsignedVarInt(count($this->requests));
foreach($this->requests as $request){
$request->write($out);
}
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleItemStackRequest($this);
}
}

View File

@ -0,0 +1,67 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse;
use function count;
class ItemStackResponsePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::ITEM_STACK_RESPONSE_PACKET;
/** @var ItemStackResponse[] */
private $responses;
/**
* @param ItemStackResponse[] $responses
*/
public static function create(array $responses) : self{
$result = new self;
$result->responses = $responses;
return $result;
}
/** @return ItemStackResponse[] */
public function getResponses() : array{ return $this->responses; }
protected function decodePayload(PacketSerializer $in) : void{
$this->responses = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$this->responses[] = ItemStackResponse::read($in);
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putUnsignedVarInt(count($this->responses));
foreach($this->responses as $response){
$response->write($out);
}
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleItemStackResponse($this);
}
}

View File

@ -273,8 +273,6 @@ interface PacketHandlerInterface{
public function handleLecternUpdate(LecternUpdatePacket $packet) : bool;
public function handleVideoStreamConnect(VideoStreamConnectPacket $packet) : bool;
public function handleAddEntity(AddEntityPacket $packet) : bool;
public function handleRemoveEntity(RemoveEntityPacket $packet) : bool;
@ -310,4 +308,28 @@ interface PacketHandlerInterface{
public function handleNetworkSettings(NetworkSettingsPacket $packet) : bool;
public function handlePlayerAuthInput(PlayerAuthInputPacket $packet) : bool;
}
public function handleCreativeContent(CreativeContentPacket $packet) : bool;
public function handlePlayerEnchantOptions(PlayerEnchantOptionsPacket $packet) : bool;
public function handleItemStackRequest(ItemStackRequestPacket $packet) : bool;
public function handleItemStackResponse(ItemStackResponsePacket $packet) : bool;
public function handlePlayerArmorDamage(PlayerArmorDamagePacket $packet) : bool;
public function handleCodeBuilder(CodeBuilderPacket $packet) : bool;
public function handleUpdatePlayerGameType(UpdatePlayerGameTypePacket $packet) : bool;
public function handleEmoteList(EmoteListPacket $packet) : bool;
public function handlePositionTrackingDBServerBroadcast(PositionTrackingDBServerBroadcastPacket $packet) : bool;
public function handlePositionTrackingDBClientRequest(PositionTrackingDBClientRequestPacket $packet) : bool;
public function handleDebugInfo(DebugInfoPacket $packet) : bool;
public function handlePacketViolationWarning(PacketViolationWarningPacket $packet) : bool;
}

View File

@ -166,7 +166,6 @@ class PacketPool{
$this->registerPacket(new LevelSoundEventPacket());
$this->registerPacket(new LevelEventGenericPacket());
$this->registerPacket(new LecternUpdatePacket());
$this->registerPacket(new VideoStreamConnectPacket());
$this->registerPacket(new AddEntityPacket());
$this->registerPacket(new RemoveEntityPacket());
$this->registerPacket(new ClientCacheStatusPacket());
@ -185,6 +184,18 @@ class PacketPool{
$this->registerPacket(new CompletedUsingItemPacket());
$this->registerPacket(new NetworkSettingsPacket());
$this->registerPacket(new PlayerAuthInputPacket());
$this->registerPacket(new CreativeContentPacket());
$this->registerPacket(new PlayerEnchantOptionsPacket());
$this->registerPacket(new ItemStackRequestPacket());
$this->registerPacket(new ItemStackResponsePacket());
$this->registerPacket(new PlayerArmorDamagePacket());
$this->registerPacket(new CodeBuilderPacket());
$this->registerPacket(new UpdatePlayerGameTypePacket());
$this->registerPacket(new EmoteListPacket());
$this->registerPacket(new PositionTrackingDBServerBroadcastPacket());
$this->registerPacket(new PositionTrackingDBClientRequestPacket());
$this->registerPacket(new DebugInfoPacket());
$this->registerPacket(new PacketViolationWarningPacket());
}
public function registerPacket(Packet $packet) : void{

View File

@ -0,0 +1,84 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class PacketViolationWarningPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::PACKET_VIOLATION_WARNING_PACKET;
public const TYPE_MALFORMED = 0;
public const SEVERITY_WARNING = 0;
public const SEVERITY_FINAL_WARNING = 1;
public const SEVERITY_TERMINATING_CONNECTION = 2;
/** @var int */
private $type;
/** @var int */
private $severity;
/** @var int */
private $packetId;
/** @var string */
private $message;
public static function create(int $type, int $severity, int $packetId, string $message) : self{
$result = new self;
$result->type = $type;
$result->severity = $severity;
$result->packetId = $packetId;
$result->message = $message;
return $result;
}
public function getType() : int{ return $this->type; }
public function getSeverity() : int{ return $this->severity; }
public function getPacketId() : int{ return $this->packetId; }
public function getMessage() : string{ return $this->message; }
protected function decodePayload(PacketSerializer $in) : void{
$this->type = $in->getVarInt();
$this->severity = $in->getVarInt();
$this->packetId = $in->getVarInt();
$this->message = $in->getString();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putVarInt($this->type);
$out->putVarInt($this->severity);
$out->putVarInt($this->packetId);
$out->putString($this->message);
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handlePacketViolationWarning($this);
}
}

View File

@ -50,7 +50,7 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{
public const ACTION_BUILD_DENIED = 17;
public const ACTION_CONTINUE_BREAK = 18;
public const ACTION_CHANGE_SKIN = 19;
public const ACTION_SET_ENCHANTMENT_SEED = 20;
public const ACTION_SET_ENCHANTMENT_SEED = 20; //no longer used
public const ACTION_START_SWIMMING = 21;
public const ACTION_STOP_SWIMMING = 22;
public const ACTION_START_SPIN_ATTACK = 23;

View File

@ -0,0 +1,108 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class PlayerArmorDamagePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::PLAYER_ARMOR_DAMAGE_PACKET;
private const FLAG_HEAD = 0;
private const FLAG_CHEST = 1;
private const FLAG_LEGS = 2;
private const FLAG_FEET = 3;
/** @var int|null */
private $headSlotDamage;
/** @var int|null */
private $chestSlotDamage;
/** @var int|null */
private $legsSlotDamage;
/** @var int|null */
private $feetSlotDamage;
public static function create(?int $headSlotDamage, ?int $chestSlotDamage, ?int $legsSlotDamage, ?int $feetSlotDamage) : self{
$result = new self;
$result->headSlotDamage = $headSlotDamage;
$result->chestSlotDamage = $chestSlotDamage;
$result->legsSlotDamage = $legsSlotDamage;
$result->feetSlotDamage = $feetSlotDamage;
return $result;
}
public function getHeadSlotDamage() : ?int{ return $this->headSlotDamage; }
public function getChestSlotDamage() : ?int{ return $this->chestSlotDamage; }
public function getLegsSlotDamage() : ?int{ return $this->legsSlotDamage; }
public function getFeetSlotDamage() : ?int{ return $this->feetSlotDamage; }
private function maybeReadDamage(int $flags, int $flag, PacketSerializer $in) : ?int{
if(($flags & (1 << $flag)) !== 0){
return $in->getVarInt();
}
return null;
}
protected function decodePayload(PacketSerializer $in) : void{
$flags = $in->getByte();
$this->headSlotDamage = $this->maybeReadDamage($flags, self::FLAG_HEAD, $in);
$this->chestSlotDamage = $this->maybeReadDamage($flags, self::FLAG_CHEST, $in);
$this->legsSlotDamage = $this->maybeReadDamage($flags, self::FLAG_LEGS, $in);
$this->feetSlotDamage = $this->maybeReadDamage($flags, self::FLAG_FEET, $in);
}
private function composeFlag(?int $field, int $flag) : int{
return $field !== null ? (1 << $flag) : 0;
}
private function maybeWriteDamage(?int $field, PacketSerializer $out) : void{
if($field !== null){
$out->putVarInt($field);
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putByte(
$this->composeFlag($this->headSlotDamage, self::FLAG_HEAD) |
$this->composeFlag($this->chestSlotDamage, self::FLAG_CHEST) |
$this->composeFlag($this->legsSlotDamage, self::FLAG_LEGS) |
$this->composeFlag($this->feetSlotDamage, self::FLAG_FEET)
);
$this->maybeWriteDamage($this->headSlotDamage, $out);
$this->maybeWriteDamage($this->chestSlotDamage, $out);
$this->maybeWriteDamage($this->legsSlotDamage, $out);
$this->maybeWriteDamage($this->feetSlotDamage, $out);
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handlePlayerArmorDamage($this);
}
}

View File

@ -0,0 +1,69 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\EnchantOption;
use function count;
class PlayerEnchantOptionsPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::PLAYER_ENCHANT_OPTIONS_PACKET;
/** @var EnchantOption[] */
private $options;
/**
* @param EnchantOption[] $options
*/
public static function create(array $options) : self{
$result = new self;
$result->options = $options;
return $result;
}
/**
* @return EnchantOption[]
*/
public function getOptions() : array{ return $this->options; }
protected function decodePayload(PacketSerializer $in) : void{
$this->options = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$this->options[] = EnchantOption::read($in);
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putUnsignedVarInt(count($this->options));
foreach($this->options as $option){
$option->write($out);
}
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handlePlayerEnchantOptions($this);
}
}

View File

@ -27,40 +27,38 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::VIDEO_STREAM_CONNECT_PACKET;
class PositionTrackingDBClientRequestPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::POSITION_TRACKING_D_B_CLIENT_REQUEST_PACKET;
public const ACTION_CONNECT = 0;
public const ACTION_DISCONNECT = 1;
public const ACTION_QUERY = 0;
/** @var string */
public $serverUri;
/** @var float */
public $frameSendFrequency;
/** @var int */
public $action;
private $action;
/** @var int */
public $resolutionX;
/** @var int */
public $resolutionY;
private $trackingId;
public static function create(int $action, int $trackingId) : self{
$result = new self;
$result->action = $action;
$result->trackingId = $trackingId;
return $result;
}
public function getAction() : int{ return $this->action; }
public function getTrackingId() : int{ return $this->trackingId; }
protected function decodePayload(PacketSerializer $in) : void{
$this->serverUri = $in->getString();
$this->frameSendFrequency = $in->getLFloat();
$this->action = $in->getByte();
$this->resolutionX = $in->getLInt();
$this->resolutionY = $in->getLInt();
$this->trackingId = $in->getVarInt();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putString($this->serverUri);
$out->putLFloat($this->frameSendFrequency);
$out->putByte($this->action);
$out->putLInt($this->resolutionX);
$out->putLInt($this->resolutionY);
$out->putVarInt($this->trackingId);
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleVideoStreamConnect($this);
return $handler->handlePositionTrackingDBClientRequest($this);
}
}

View File

@ -0,0 +1,81 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\CacheableNbt;
class PositionTrackingDBServerBroadcastPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::POSITION_TRACKING_D_B_SERVER_BROADCAST_PACKET;
public const ACTION_UPDATE = 0;
public const ACTION_DESTROY = 1;
public const ACTION_NOT_FOUND = 2;
/** @var int */
private $action;
/** @var int */
private $trackingId;
/**
* @var CacheableNbt
* @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag>
*/
private $nbt;
/**
* @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt
*/
public static function create(int $action, int $trackingId, CacheableNbt $nbt) : self{
$result = new self;
$result->action = $action;
$result->trackingId = $trackingId;
$result->nbt = $nbt;
return $result;
}
public function getAction() : int{ return $this->action; }
public function getTrackingId() : int{ return $this->trackingId; }
/** @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */
public function getNbt() : CacheableNbt{ return $this->nbt; }
protected function decodePayload(PacketSerializer $in) : void{
$this->action = $in->getByte();
$this->trackingId = $in->getVarInt();
$this->nbt = new CacheableNbt($in->getNbtCompoundRoot());
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putByte($this->action);
$out->putVarInt($this->trackingId);
$out->put($this->nbt->getEncodedNbt());
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handlePositionTrackingDBServerBroadcast($this);
}
}

View File

@ -41,11 +41,11 @@ final class ProtocolInfo{
*/
/** Actual Minecraft: PE protocol version */
public const CURRENT_PROTOCOL = 390;
public const CURRENT_PROTOCOL = 407;
/** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */
public const MINECRAFT_VERSION = 'v1.14.60';
public const MINECRAFT_VERSION = 'v1.16.0.67 beta';
/** Version number sent to clients in ping responses. */
public const MINECRAFT_VERSION_NETWORK = '1.14.60';
public const MINECRAFT_VERSION_NETWORK = '1.16.0.67';
public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02;
@ -172,7 +172,7 @@ final class ProtocolInfo{
public const LEVEL_SOUND_EVENT_PACKET = 0x7b;
public const LEVEL_EVENT_GENERIC_PACKET = 0x7c;
public const LECTERN_UPDATE_PACKET = 0x7d;
public const VIDEO_STREAM_CONNECT_PACKET = 0x7e;
public const ADD_ENTITY_PACKET = 0x7f;
public const REMOVE_ENTITY_PACKET = 0x80;
public const CLIENT_CACHE_STATUS_PACKET = 0x81;
@ -191,5 +191,17 @@ final class ProtocolInfo{
public const COMPLETED_USING_ITEM_PACKET = 0x8e;
public const NETWORK_SETTINGS_PACKET = 0x8f;
public const PLAYER_AUTH_INPUT_PACKET = 0x90;
public const CREATIVE_CONTENT_PACKET = 0x91;
public const PLAYER_ENCHANT_OPTIONS_PACKET = 0x92;
public const ITEM_STACK_REQUEST_PACKET = 0x93;
public const ITEM_STACK_RESPONSE_PACKET = 0x94;
public const PLAYER_ARMOR_DAMAGE_PACKET = 0x95;
public const CODE_BUILDER_PACKET = 0x96;
public const UPDATE_PLAYER_GAME_TYPE_PACKET = 0x97;
public const EMOTE_LIST_PACKET = 0x98;
public const POSITION_TRACKING_D_B_SERVER_BROADCAST_PACKET = 0x99;
public const POSITION_TRACKING_D_B_CLIENT_REQUEST_PACKET = 0x9a;
public const DEBUG_INFO_PACKET = 0x9b;
public const PACKET_VIOLATION_WARNING_PACKET = 0x9c;
}

View File

@ -41,34 +41,45 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{
public $y;
/** @var int */
public $z;
/** @var bool */
public $spawnForced;
/** @var int */
public $dimension;
/** @var int */
public $x2;
/** @var int */
public $y2;
/** @var int */
public $z2;
public static function playerSpawn(int $x, int $y, int $z, bool $forced) : self{
public static function playerSpawn(int $x, int $y, int $z, int $dimension, int $x2, int $y2, int $z2) : self{
$result = new self;
$result->spawnType = self::TYPE_PLAYER_SPAWN;
[$result->x, $result->y, $result->z] = [$x, $y, $z];
$result->spawnForced = $forced;
[$result->x2, $result->y2, $result->z2] = [$x2, $y2, $z2];
$result->dimension = $dimension;
return $result;
}
public static function worldSpawn(int $x, int $y, int $z) : self{
public static function worldSpawn(int $x, int $y, int $z, int $dimension) : self{
$result = new self;
$result->spawnType = self::TYPE_WORLD_SPAWN;
[$result->x, $result->y, $result->z] = [$x, $y, $z];
[$result->x2, $result->y2, $result->z2] = [$x, $y, $z];
$result->dimension = $dimension;
return $result;
}
protected function decodePayload(PacketSerializer $in) : void{
$this->spawnType = $in->getVarInt();
$in->getBlockPosition($this->x, $this->y, $this->z);
$this->spawnForced = $in->getBool();
$this->dimension = $in->getVarInt();
$in->getBlockPosition($this->x2, $this->y2, $this->z2);
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putVarInt($this->spawnType);
$out->putBlockPosition($this->x, $this->y, $this->z);
$out->putBool($this->spawnForced);
$out->putVarInt($this->dimension);
$out->putBlockPosition($this->x2, $this->y2, $this->z2);
}
public function handle(PacketHandlerInterface $handler) : bool{

View File

@ -34,6 +34,7 @@ use pocketmine\network\mcpe\protocol\types\GameRule;
use pocketmine\network\mcpe\protocol\types\GeneratorType;
use pocketmine\network\mcpe\protocol\types\MultiplayerGameVisibility;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\SpawnSettings;
use function count;
class StartGamePacket extends DataPacket implements ClientboundPacket{
@ -56,8 +57,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
/** @var int */
public $seed;
/** @var int */
public $dimension;
/** @var SpawnSettings */
public $spawnSettings;
/** @var int */
public $generator = GeneratorType::OVERWORLD;
/** @var int */
@ -78,6 +79,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public $eduEditionOffer = EducationEditionOffer::NONE;
/** @var bool */
public $hasEduFeaturesEnabled = false;
/** @var string */
public $eduProductUUID = "";
/** @var float */
public $rainLevel;
/** @var float */
@ -125,9 +128,17 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public $isWorldTemplateOptionLocked = false;
/** @var bool */
public $onlySpawnV1Villagers = false;
/** @var string */
public $vanillaVersion = ProtocolInfo::MINECRAFT_VERSION_NETWORK;
/** @var int */
public $limitedWorldWidth = 0;
/** @var int */
public $limitedWorldLength = 0;
/** @var bool */
public $isNewNether = true;
/** @var bool|null */
public $experimentalGameplayOverride = null;
/** @var string */
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
/** @var string */
@ -144,6 +155,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public $enchantmentSeed = 0;
/** @var string */
public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort
/** @var bool */
public $enableNewInventorySystem = false; //TODO
/**
* @var CacheableNbt
@ -168,7 +181,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
//Level settings
$this->seed = $in->getVarInt();
$this->dimension = $in->getVarInt();
$this->spawnSettings = SpawnSettings::read($in);
$this->generator = $in->getVarInt();
$this->worldGamemode = $in->getVarInt();
$this->difficulty = $in->getVarInt();
@ -177,6 +190,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->time = $in->getVarInt();
$this->eduEditionOffer = $in->getVarInt();
$this->hasEduFeaturesEnabled = $in->getBool();
$this->eduProductUUID = $in->getString();
$this->rainLevel = $in->getLFloat();
$this->lightningLevel = $in->getLFloat();
$this->hasConfirmedPlatformLockedContent = $in->getBool();
@ -198,8 +212,16 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->isFromWorldTemplate = $in->getBool();
$this->isWorldTemplateOptionLocked = $in->getBool();
$this->onlySpawnV1Villagers = $in->getBool();
$this->vanillaVersion = $in->getString();
$this->limitedWorldWidth = $in->getLInt();
$this->limitedWorldLength = $in->getLInt();
$this->isNewNether = $in->getBool();
if($in->getBool()){
$this->experimentalGameplayOverride = $in->getBool();
}else{
$this->experimentalGameplayOverride = null;
}
$this->levelId = $in->getString();
$this->worldName = $in->getString();
$this->premiumWorldTemplateId = $in->getString();
@ -224,6 +246,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
}
$this->multiplayerCorrelationId = $in->getString();
$this->enableNewInventorySystem = $in->getBool();
}
protected function encodePayload(PacketSerializer $out) : void{
@ -238,7 +261,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
//Level settings
$out->putVarInt($this->seed);
$out->putVarInt($this->dimension);
$this->spawnSettings->write($out);
$out->putVarInt($this->generator);
$out->putVarInt($this->worldGamemode);
$out->putVarInt($this->difficulty);
@ -247,6 +270,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$out->putVarInt($this->time);
$out->putVarInt($this->eduEditionOffer);
$out->putBool($this->hasEduFeaturesEnabled);
$out->putString($this->eduProductUUID);
$out->putLFloat($this->rainLevel);
$out->putLFloat($this->lightningLevel);
$out->putBool($this->hasConfirmedPlatformLockedContent);
@ -268,8 +292,15 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$out->putBool($this->isFromWorldTemplate);
$out->putBool($this->isWorldTemplateOptionLocked);
$out->putBool($this->onlySpawnV1Villagers);
$out->putString($this->vanillaVersion);
$out->putLInt($this->limitedWorldWidth);
$out->putLInt($this->limitedWorldLength);
$out->putBool($this->isNewNether);
$out->putBool($this->experimentalGameplayOverride !== null);
if($this->experimentalGameplayOverride !== null){
$out->putBool($this->experimentalGameplayOverride);
}
$out->putString($this->levelId);
$out->putString($this->worldName);
$out->putString($this->premiumWorldTemplateId);
@ -284,6 +315,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$out->put(self::serializeItemTable($this->itemTable));
$out->putString($this->multiplayerCorrelationId);
$out->putBool($this->enableNewInventorySystem);
}
/**

View File

@ -40,7 +40,8 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac
public const TYPE_SYSTEM = 6;
public const TYPE_WHISPER = 7;
public const TYPE_ANNOUNCEMENT = 8;
public const TYPE_JSON = 9;
public const TYPE_JSON_WHISPER = 9;
public const TYPE_JSON = 10;
/** @var int */
public $type;
@ -127,6 +128,7 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac
case self::TYPE_RAW:
case self::TYPE_TIP:
case self::TYPE_SYSTEM:
case self::TYPE_JSON_WHISPER:
case self::TYPE_JSON:
$this->message = $in->getString();
break;
@ -158,6 +160,7 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac
case self::TYPE_RAW:
case self::TYPE_TIP:
case self::TYPE_SYSTEM:
case self::TYPE_JSON_WHISPER:
case self::TYPE_JSON:
$out->putString($this->message);
break;

View File

@ -0,0 +1,67 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\GameMode;
class UpdatePlayerGameTypePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::UPDATE_PLAYER_GAME_TYPE_PACKET;
/**
* @var int
* @see GameMode
*/
private $gameMode;
/** @var int */
private $playerEntityUniqueId;
public static function create(int $gameMode, int $playerEntityUniqueId) : self{
$result = new self;
$result->gameMode = $gameMode;
$result->playerEntityUniqueId = $playerEntityUniqueId;
return $result;
}
public function getGameMode() : int{ return $this->gameMode; }
public function getPlayerEntityUniqueId() : int{ return $this->playerEntityUniqueId; }
protected function decodePayload(PacketSerializer $in) : void{
$this->gameMode = $in->getVarInt();
$this->playerEntityUniqueId = $in->getEntityUniqueId();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putVarInt($this->gameMode);
$out->putEntityUniqueId($this->playerEntityUniqueId);
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleUpdatePlayerGameType($this);
}
}

View File

@ -412,7 +412,7 @@ class PacketSerializer extends BinaryStream{
*
* @throws BinaryDataException
*/
public function getEntityUniqueId() : int{
final public function getEntityUniqueId() : int{
return $this->getVarLong();
}
@ -428,7 +428,7 @@ class PacketSerializer extends BinaryStream{
*
* @throws BinaryDataException
*/
public function getEntityRuntimeId() : int{
final public function getEntityRuntimeId() : int{
return $this->getUnsignedVarLong();
}
@ -591,7 +591,8 @@ class PacketSerializer extends BinaryStream{
$toEntityUniqueId = $this->getEntityUniqueId();
$type = $this->getByte();
$immediate = $this->getBool();
return new EntityLink($fromEntityUniqueId, $toEntityUniqueId, $type, $immediate);
$causedByRider = $this->getBool();
return new EntityLink($fromEntityUniqueId, $toEntityUniqueId, $type, $immediate, $causedByRider);
}
public function putEntityLink(EntityLink $link) : void{
@ -599,6 +600,7 @@ class PacketSerializer extends BinaryStream{
$this->putEntityUniqueId($link->toEntityUniqueId);
$this->putByte($link->type);
$this->putBool($link->immediate);
$this->putBool($link->causedByRider);
}
/**
@ -712,4 +714,12 @@ class PacketSerializer extends BinaryStream{
throw PacketDecodeException::wrap($e, "Expected TAG_Compound NBT root");
}
}
public function readGenericTypeNetworkId() : int{
return $this->getVarInt();
}
public function writeGenericTypeNetworkId(int $id) : void{
$this->putVarInt($id);
}
}

View File

@ -0,0 +1,53 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class Enchant{
/** @var int */
private $id;
/** @var int */
private $level;
public function __construct(int $id, int $level){
$this->id = $id;
$this->level = $level;
}
public function getId() : int{ return $this->id; }
public function getLevel() : int{ return $this->level; }
public static function read(PacketSerializer $in) : self{
$id = $in->getByte();
$level = $in->getByte();
return new self($id, $level);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->id);
$out->putByte($this->level);
}
}

View File

@ -0,0 +1,126 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use function count;
final class EnchantOption{
/** @var int */
private $cost;
/** @var int */
private $slotFlags;
/** @var Enchant[] */
private $equipActivatedEnchantments;
/** @var Enchant[] */
private $heldActivatedEnchantments;
/** @var Enchant[] */
private $selfActivatedEnchantments;
/** @var string */
private $name;
/** @var int */
private $optionId;
/**
* @param Enchant[] $equipActivatedEnchantments
* @param Enchant[] $heldActivatedEnchantments
* @param Enchant[] $selfActivatedEnchantments
*/
public function __construct(int $cost, int $slotFlags, array $equipActivatedEnchantments, array $heldActivatedEnchantments, array $selfActivatedEnchantments, string $name, int $optionId){
$this->cost = $cost;
$this->slotFlags = $slotFlags;
$this->equipActivatedEnchantments = $equipActivatedEnchantments;
$this->heldActivatedEnchantments = $heldActivatedEnchantments;
$this->selfActivatedEnchantments = $selfActivatedEnchantments;
$this->name = $name;
$this->optionId = $optionId;
}
public function getCost() : int{ return $this->cost; }
public function getSlotFlags() : int{ return $this->slotFlags; }
/** @return Enchant[] */
public function getEquipActivatedEnchantments() : array{ return $this->equipActivatedEnchantments; }
/** @return Enchant[] */
public function getHeldActivatedEnchantments() : array{ return $this->heldActivatedEnchantments; }
/** @return Enchant[] */
public function getSelfActivatedEnchantments() : array{ return $this->selfActivatedEnchantments; }
public function getName() : string{ return $this->name; }
public function getOptionId() : int{ return $this->optionId; }
/**
* @return Enchant[]
*/
private static function readEnchantList(PacketSerializer $in) : array{
$result = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$result[] = Enchant::read($in);
}
return $result;
}
/**
* @param Enchant[] $list
*/
private static function writeEnchantList(PacketSerializer $out, array $list) : void{
$out->putUnsignedVarInt(count($list));
foreach($list as $item){
$item->write($out);
}
}
public static function read(PacketSerializer $in) : self{
$cost = $in->getUnsignedVarInt();
$slotFlags = $in->getLInt();
$equipActivatedEnchants = self::readEnchantList($in);
$heldActivatedEnchants = self::readEnchantList($in);
$selfActivatedEnchants = self::readEnchantList($in);
$name = $in->getString();
$optionId = $in->readGenericTypeNetworkId();
return new self($cost, $slotFlags, $equipActivatedEnchants, $heldActivatedEnchants, $selfActivatedEnchants, $name, $optionId);
}
public function write(PacketSerializer $out) : void{
$out->putUnsignedVarInt($this->cost);
$out->putLInt($this->slotFlags);
self::writeEnchantList($out, $this->equipActivatedEnchantments);
self::writeEnchantList($out, $this->heldActivatedEnchantments);
self::writeEnchantList($out, $this->selfActivatedEnchantments);
$out->putString($this->name);
$out->writeGenericTypeNetworkId($this->optionId);
}
}

View File

@ -0,0 +1,73 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class SpawnSettings{
public const BIOME_TYPE_DEFAULT = 0;
public const BIOME_TYPE_USER_DEFINED = 1;
/** @var int */
private $biomeType;
/** @var string */
private $biomeName;
/** @var int */
private $dimension;
public function __construct(int $biomeType, string $biomeName, int $dimension){
$this->biomeType = $biomeType;
$this->biomeName = $biomeName;
$this->dimension = $dimension;
}
public function getBiomeType() : int{
return $this->biomeType;
}
public function getBiomeName() : string{
return $this->biomeName;
}
/**
* @see DimensionIds
*/
public function getDimension() : int{
return $this->dimension;
}
public static function read(PacketSerializer $in) : self{
$biomeType = $in->getLShort();
$biomeName = $in->getString();
$dimension = $in->getVarInt();
return new self($biomeType, $biomeName, $dimension);
}
public function write(PacketSerializer $out) : void{
$out->putLShort($this->biomeType);
$out->putString($this->biomeName);
$out->putVarInt($this->dimension);
}
}

View File

@ -37,11 +37,14 @@ class EntityLink{
public $type;
/** @var bool */
public $immediate; //for dismounting on mount death
/** @var bool */
public $causedByRider;
public function __construct(int $fromEntityUniqueId, int $toEntityUniqueId, int $type, bool $immediate){
public function __construct(int $fromEntityUniqueId, int $toEntityUniqueId, int $type, bool $immediate, bool $causedByRider){
$this->fromEntityUniqueId = $fromEntityUniqueId;
$this->toEntityUniqueId = $toEntityUniqueId;
$this->type = $type;
$this->immediate = $immediate;
$this->causedByRider = $causedByRider;
}
}

View File

@ -114,10 +114,13 @@ final class EntityMetadataFlags{
public const ROARING = 83;
public const DELAYED_ATTACKING = 84;
public const AVOIDING_MOBS = 85;
public const FACING_TARGET_TO_RANGE_ATTACK = 86;
public const HIDDEN_WHEN_INVISIBLE = 87; //??????????????????
public const IS_IN_UI = 88;
public const STALKING = 89;
public const EMOTING = 90;
public const CELEBRATING = 91;
public const AVOIDING_BLOCK = 86;
public const FACING_TARGET_TO_RANGE_ATTACK = 87;
public const HIDDEN_WHEN_INVISIBLE = 88; //??????????????????
public const IS_IN_UI = 89;
public const STALKING = 90;
public const EMOTING = 91;
public const CELEBRATING = 92;
public const ADMIRING = 93;
public const CELEBRATING_SPECIAL = 94;
}

View File

@ -35,7 +35,7 @@ final class ContainerIds{
public const LAST = 100;
public const OFFHAND = 119;
public const ARMOR = 120;
public const CREATIVE = 121;
public const HOTBAR = 122;
public const FIXED_INVENTORY = 123;
public const UI = 124;

View File

@ -0,0 +1,54 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class CreativeContentEntry{
/** @var int */
private $entryId;
/** @var ItemStack */
private $item;
public function __construct(int $entryId, ItemStack $item){
$this->entryId = $entryId;
$this->item = $item;
}
public function getEntryId() : int{ return $this->entryId; }
public function getItem() : ItemStack{ return $this->item; }
public static function read(PacketSerializer $in) : self{
$entryId = $in->readGenericTypeNetworkId();
$item = $in->getSlot();
return new self($entryId, $item);
}
public function write(PacketSerializer $out) : void{
$out->writeGenericTypeNetworkId($this->entryId);
$out->putSlot($this->item);
}
}

View File

@ -0,0 +1,65 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use function count;
final class InventoryTransactionChangedSlotsHack{
/** @var int */
private $containerId;
/** @var int[] */
private $changedSlotIndexes;
/**
* @param int[] $changedSlotIndexes
*/
public function __construct(int $containerId, array $changedSlotIndexes){
$this->containerId = $containerId;
$this->changedSlotIndexes = $changedSlotIndexes;
}
public function getContainerId() : int{ return $this->containerId; }
/** @return int[] */
public function getChangedSlotIndexes() : array{ return $this->changedSlotIndexes; }
public static function read(PacketSerializer $in) : self{
$containerId = $in->getByte();
$changedSlots = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$changedSlots[] = $in->getByte();
}
return new self($containerId, $changedSlots);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->containerId);
$out->putUnsignedVarInt(count($this->changedSlotIndexes));
foreach($this->changedSlotIndexes as $index){
$out->putByte($index);
}
}
}

View File

@ -0,0 +1,59 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory;
use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class ItemStackWrapper{
/** @var int */
private $stackId;
/** @var ItemStack */
private $itemStack;
public function __construct(int $stackId, ItemStack $itemStack){
$this->stackId = $stackId;
$this->itemStack = $itemStack;
}
public static function legacy(ItemStack $itemStack) : self{
return new self($itemStack->getId() === 0 ? 0 : 1, $itemStack);
}
public function getStackId() : int{ return $this->stackId; }
public function getItemStack() : ItemStack{ return $this->itemStack; }
public static function read(PacketSerializer $in) : self{
$stackId = $in->readGenericTypeNetworkId();
$stack = $in->getSlot();
return new self($stackId, $stack);
}
public function write(PacketSerializer $out) : void{
$out->writeGenericTypeNetworkId($this->stackId);
$out->putSlot($this->itemStack);
}
}

View File

@ -76,6 +76,8 @@ class NetworkInventoryAction{
public $oldItem;
/** @var ItemStack */
public $newItem;
/** @var int|null */
public $newItemStackId = null;
/**
* @return $this
@ -83,7 +85,7 @@ class NetworkInventoryAction{
* @throws BinaryDataException
* @throws PacketDecodeException
*/
public function read(PacketSerializer $packet) : NetworkInventoryAction{
public function read(PacketSerializer $packet, bool $hasItemStackIds) : NetworkInventoryAction{
$this->sourceType = $packet->getUnsignedVarInt();
switch($this->sourceType){
@ -105,6 +107,9 @@ class NetworkInventoryAction{
$this->inventorySlot = $packet->getUnsignedVarInt();
$this->oldItem = $packet->getSlot();
$this->newItem = $packet->getSlot();
if($hasItemStackIds){
$this->newItemStackId = $packet->readGenericTypeNetworkId();
}
return $this;
}
@ -112,7 +117,7 @@ class NetworkInventoryAction{
/**
* @throws \InvalidArgumentException
*/
public function write(PacketSerializer $packet) : void{
public function write(PacketSerializer $packet, bool $hasItemStackIds) : void{
$packet->putUnsignedVarInt($this->sourceType);
switch($this->sourceType){
@ -134,5 +139,11 @@ class NetworkInventoryAction{
$packet->putUnsignedVarInt($this->inventorySlot);
$packet->putSlot($this->oldItem);
$packet->putSlot($this->newItem);
if($hasItemStackIds){
if($this->newItemStackId === null){
throw new \InvalidStateException("Item stack ID for newItem must be provided");
}
$packet->writeGenericTypeNetworkId($this->newItemStackId);
}
}
}

View File

@ -45,10 +45,10 @@ abstract class TransactionData{
* @throws BinaryDataException
* @throws PacketDecodeException
*/
final public function decode(PacketSerializer $stream) : void{
final public function decode(PacketSerializer $stream, bool $hasItemStackIds) : void{
$actionCount = $stream->getUnsignedVarInt();
for($i = 0; $i < $actionCount; ++$i){
$this->actions[] = (new NetworkInventoryAction())->read($stream);
$this->actions[] = (new NetworkInventoryAction())->read($stream, $hasItemStackIds);
}
$this->decodeData($stream);
}
@ -59,10 +59,10 @@ abstract class TransactionData{
*/
abstract protected function decodeData(PacketSerializer $stream) : void;
final public function encode(PacketSerializer $stream) : void{
final public function encode(PacketSerializer $stream, bool $hasItemStackIds) : void{
$stream->putUnsignedVarInt(count($this->actions));
foreach($this->actions as $action){
$action->write($stream);
$action->write($stream, $hasItemStackIds);
}
$this->encodeData($stream);
}

View File

@ -63,5 +63,8 @@ final class WindowTypes{
public const SMOKER = 28;
public const STONECUTTER = 29;
public const CARTOGRAPHY = 30;
public const HUD = 31;
public const JIGSAW_EDITOR = 32;
public const SMITHING_TABLE = 33;
}

View File

@ -0,0 +1,59 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* Completes a transaction involving a beacon consuming input to produce effects.
*/
final class BeaconPaymentStackRequestAction extends ItemStackRequestAction{
/** @var int */
private $primaryEffectId;
/** @var int */
private $secondaryEffectId;
public function __construct(int $primaryEffectId, int $secondaryEffectId){
$this->primaryEffectId = $primaryEffectId;
$this->secondaryEffectId = $secondaryEffectId;
}
public function getPrimaryEffectId() : int{ return $this->primaryEffectId; }
public function getSecondaryEffectId() : int{ return $this->secondaryEffectId; }
public static function getTypeId() : int{ return ItemStackRequestActionType::BEACON_PAYMENT; }
public static function read(PacketSerializer $in) : self{
$primary = $in->getVarInt();
$secondary = $in->getVarInt();
return new self($primary, $secondary);
}
public function write(PacketSerializer $out) : void{
$out->putVarInt($this->primaryEffectId);
$out->putVarInt($this->secondaryEffectId);
}
}

View File

@ -0,0 +1,34 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
/**
* Tells that the current transaction crafted the specified recipe, using the recipe book. This is effectively the same
* as the regular crafting result action.
*/
final class CraftRecipeAutoStackRequestAction extends ItemStackRequestAction{
use CraftRecipeStackRequestActionTrait;
public static function getTypeId() : int{ return ItemStackRequestActionType::CRAFTING_RECIPE_AUTO; }
}

View File

@ -0,0 +1,33 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
/**
* Tells that the current transaction crafted the specified recipe.
*/
final class CraftRecipeStackRequestAction extends ItemStackRequestAction{
use CraftRecipeStackRequestActionTrait;
public static function getTypeId() : int{ return ItemStackRequestActionType::CRAFTING_RECIPE; }
}

View File

@ -0,0 +1,47 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
trait CraftRecipeStackRequestActionTrait{
/** @var int */
private $recipeId;
final public function __construct(int $recipeId){
$this->recipeId = $recipeId;
}
public function getRecipeId() : int{ return $this->recipeId; }
public static function read(PacketSerializer $in) : self{
$recipeId = $in->readGenericTypeNetworkId();
return new self($recipeId);
}
public function write(PacketSerializer $out) : void{
$out->writeGenericTypeNetworkId($this->recipeId);
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
/**
* Sends some (or all) items from the source slot to the magic place where crafting ingredients turn into result items.
*/
final class CraftingConsumeInputStackRequestAction extends ItemStackRequestAction{
use DisappearStackRequestActionTrait;
public static function getTypeId() : int{ return ItemStackRequestActionType::CRAFTING_CONSUME_INPUT; }
}

View File

@ -0,0 +1,53 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* I have no clear idea what this does. It seems to be the client hinting to the server "hey, put a secondary output in
* X crafting grid slot". This is used for things like buckets.
*/
final class CraftingMarkSecondaryResultStackRequestAction extends ItemStackRequestAction{
/** @var int */
private $craftingGridSlot;
public function __construct(int $craftingGridSlot){
$this->craftingGridSlot = $craftingGridSlot;
}
public function getCraftingGridSlot() : int{ return $this->craftingGridSlot; }
public static function getTypeId() : int{ return ItemStackRequestActionType::CRAFTING_MARK_SECONDARY_RESULT_SLOT; }
public static function read(PacketSerializer $in) : self{
$slot = $in->getByte();
return new self($slot);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->craftingGridSlot);
}
}

View File

@ -0,0 +1,52 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* Creates an item by copying it from the creative inventory. This is treated as a crafting action by vanilla.
*/
final class CreativeCreateStackRequestAction extends ItemStackRequestAction{
/** @var int */
private $creativeItemId;
public function __construct(int $creativeItemId){
$this->creativeItemId = $creativeItemId;
}
public function getCreativeItemId() : int{ return $this->creativeItemId; }
public static function getTypeId() : int{ return ItemStackRequestActionType::CREATIVE_CREATE; }
public static function read(PacketSerializer $in) : self{
$creativeItemId = $in->readGenericTypeNetworkId();
return new self($creativeItemId);
}
public function write(PacketSerializer $out) : void{
$out->writeGenericTypeNetworkId($this->creativeItemId);
}
}

View File

@ -0,0 +1,45 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* Tells that the current transaction involves crafting an item in a way that isn't supported by the current system.
* At the time of writing, this includes using anvils.
*/
final class DeprecatedCraftingNonImplementedStackRequestAction extends ItemStackRequestAction{
public static function getTypeId() : int{
return ItemStackRequestActionType::CRAFTING_NON_IMPLEMENTED_DEPRECATED_ASK_TY_LAING;
}
public static function read(PacketSerializer $in) : self{
return new self;
}
public function write(PacketSerializer $out) : void{
//NOOP
}
}

View File

@ -0,0 +1,74 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
use function count;
/**
* Not clear what this is needed for, but it is very clearly marked as deprecated, so hopefully it'll go away before I
* have to write a proper description for it.
*/
final class DeprecatedCraftingResultsStackRequestAction extends ItemStackRequestAction{
/** @var ItemStack[] */
private $results;
/** @var int */
private $iterations;
/**
* @param ItemStack[] $results
*/
public function __construct(array $results, int $iterations){
$this->results = $results;
$this->iterations = $iterations;
}
/** @return ItemStack[] */
public function getResults() : array{ return $this->results; }
public function getIterations() : int{ return $this->iterations; }
public static function getTypeId() : int{
return ItemStackRequestActionType::CRAFTING_RESULTS_DEPRECATED_ASK_TY_LAING;
}
public static function read(PacketSerializer $in) : self{
$results = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$results[] = $in->getSlot();
}
$iterations = $in->getByte();
return new self($results, $iterations);
}
public function write(PacketSerializer $out) : void{
$out->putUnsignedVarInt(count($this->results));
foreach($this->results as $result){
$out->putSlot($result);
}
$out->putByte($this->iterations);
}
}

View File

@ -0,0 +1,34 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
/**
* Sends some (or all) items from the source slot to /dev/null. This happens when the player clicks items into the
* creative inventory menu in creative mode.
*/
final class DestroyStackRequestAction extends ItemStackRequestAction{
use DisappearStackRequestActionTrait;
public static function getTypeId() : int{ return ItemStackRequestActionType::DESTROY; }
}

View File

@ -0,0 +1,53 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
trait DisappearStackRequestActionTrait{
/** @var int */
private $count;
/** @var ItemStackRequestSlotInfo */
private $source;
final public function __construct(int $count, ItemStackRequestSlotInfo $source){
$this->count = $count;
$this->source = $source;
}
final public function getCount() : int{ return $this->count; }
final public function getSource() : ItemStackRequestSlotInfo{ return $this->source; }
public static function read(PacketSerializer $in) : self{
$count = $in->getByte();
$source = ItemStackRequestSlotInfo::read($in);
return new self($count, $source);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->count);
$this->source->write($out);
}
}

View File

@ -0,0 +1,66 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* Drops some (or all) items from the source slot into the world as an item entity.
*/
final class DropStackRequestAction extends ItemStackRequestAction{
/** @var int */
private $count;
/** @var ItemStackRequestSlotInfo */
private $source;
/** @var bool */
private $randomly;
public function __construct(int $count, ItemStackRequestSlotInfo $source, bool $randomly){
$this->count = $count;
$this->source = $source;
$this->randomly = $randomly;
}
public function getCount() : int{ return $this->count; }
public function getSource() : ItemStackRequestSlotInfo{ return $this->source; }
public function isRandomly() : bool{ return $this->randomly; }
public static function getTypeId() : int{ return ItemStackRequestActionType::DROP; }
public static function read(PacketSerializer $in) : self{
$count = $in->getByte();
$source = ItemStackRequestSlotInfo::read($in);
$random = $in->getBool();
return new self($count, $source, $random);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->count);
$this->source->write($out);
$out->putBool($this->randomly);
}
}

View File

@ -0,0 +1,87 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use function count;
final class ItemStackRequest{
/** @var int */
private $requestId;
/** @var ItemStackRequestAction[] */
private $actions;
/**
* @param ItemStackRequestAction[] $actions
*/
public function __construct(int $requestId, array $actions){
$this->requestId = $requestId;
$this->actions = $actions;
}
public function getRequestId() : int{ return $this->requestId; }
/** @return ItemStackRequestAction[] */
public function getActions() : array{ return $this->actions; }
private static function readAction(PacketSerializer $in, int $typeId) : ItemStackRequestAction{
switch($typeId){
case TakeStackRequestAction::getTypeId(): return TakeStackRequestAction::read($in);
case PlaceStackRequestAction::getTypeId(): return PlaceStackRequestAction::read($in);
case SwapStackRequestAction::getTypeId(): return SwapStackRequestAction::read($in);
case DropStackRequestAction::getTypeId(): return DropStackRequestAction::read($in);
case DestroyStackRequestAction::getTypeId(): return DestroyStackRequestAction::read($in);
case CraftingConsumeInputStackRequestAction::getTypeId(): return CraftingConsumeInputStackRequestAction::read($in);
case CraftingMarkSecondaryResultStackRequestAction::getTypeId(): return CraftingMarkSecondaryResultStackRequestAction::read($in);
case LabTableCombineStackRequestAction::getTypeId(): return LabTableCombineStackRequestAction::read($in);
case BeaconPaymentStackRequestAction::getTypeId(): return BeaconPaymentStackRequestAction::read($in);
case CraftRecipeStackRequestAction::getTypeId(): return CraftRecipeStackRequestAction::read($in);
case CraftRecipeAutoStackRequestAction::getTypeId(): return CraftRecipeAutoStackRequestAction::read($in);
case CreativeCreateStackRequestAction::getTypeId(): return CreativeCreateStackRequestAction::read($in);
case DeprecatedCraftingNonImplementedStackRequestAction::getTypeId(): return DeprecatedCraftingNonImplementedStackRequestAction::read($in);
case DeprecatedCraftingResultsStackRequestAction::getTypeId(): return DeprecatedCraftingResultsStackRequestAction::read($in);
}
throw new \UnexpectedValueException("Unhandled item stack request action type $typeId");
}
public static function read(PacketSerializer $in) : self{
$requestId = $in->readGenericTypeNetworkId();
$actions = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$typeId = $in->getByte();
$actions[] = self::readAction($in, $typeId);
}
return new self($requestId, $actions);
}
public function write(PacketSerializer $out) : void{
$out->writeGenericTypeNetworkId($this->requestId);
$out->putUnsignedVarInt(count($this->actions));
foreach($this->actions as $action){
$out->putByte($action::getTypeId());
$action->write($out);
}
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
abstract class ItemStackRequestAction{
abstract public static function getTypeId() : int;
abstract public function write(PacketSerializer $out) : void;
}

View File

@ -0,0 +1,46 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
final class ItemStackRequestActionType{
private function __construct(){
//NOOP
}
public const TAKE = 0;
public const PLACE = 1;
public const SWAP = 2;
public const DROP = 3;
public const DESTROY = 4;
public const CRAFTING_CONSUME_INPUT = 5;
public const CRAFTING_MARK_SECONDARY_RESULT_SLOT = 6;
public const LAB_TABLE_COMBINE = 7;
public const BEACON_PAYMENT = 8;
public const CRAFTING_RECIPE = 9;
public const CRAFTING_RECIPE_AUTO = 10; //recipe book?
public const CREATIVE_CREATE = 11;
public const CRAFTING_NON_IMPLEMENTED_DEPRECATED_ASK_TY_LAING = 12; //anvils aren't fully implemented yet
public const CRAFTING_RESULTS_DEPRECATED_ASK_TY_LAING = 13; //no idea what this is for
}

View File

@ -0,0 +1,61 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class ItemStackRequestSlotInfo{
/** @var int */
private $containerId;
/** @var int */
private $slotId;
/** @var int */
private $stackId;
public function __construct(int $containerId, int $slotId, int $stackId){
$this->containerId = $containerId;
$this->slotId = $slotId;
$this->stackId = $stackId;
}
public function getContainerId() : int{ return $this->containerId; }
public function getSlotId() : int{ return $this->slotId; }
public function getStackId() : int{ return $this->stackId; }
public static function read(PacketSerializer $in) : self{
$containerId = $in->getByte();
$slotId = $in->getByte();
$stackId = $in->readGenericTypeNetworkId();
return new self($containerId, $slotId, $stackId);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->containerId);
$out->putByte($this->slotId);
$out->writeGenericTypeNetworkId($this->stackId);
}
}

View File

@ -0,0 +1,43 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* Not clear what the point of this is. It's sent when the player uses a lab table, but it's not clear why this action
* is needed.
*/
final class LabTableCombineStackRequestAction extends ItemStackRequestAction{
public static function getTypeId() : int{ return ItemStackRequestActionType::LAB_TABLE_COMBINE; }
public static function read(PacketSerializer $in) : self{
return new self;
}
public function write(PacketSerializer $out) : void{
//NOOP
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
/**
* Puts some (or all) of the items from the source slot into the destination slot.
*/
final class PlaceStackRequestAction extends ItemStackRequestAction{
use TakeOrPlaceStackRequestActionTrait;
public static function getTypeId() : int{ return ItemStackRequestActionType::PLACE; }
}

View File

@ -0,0 +1,59 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
/**
* Swaps two stacks. These don't have to be in the same inventory. This action does not modify the stacks themselves.
*/
final class SwapStackRequestAction extends ItemStackRequestAction{
/** @var ItemStackRequestSlotInfo */
private $slot1;
/** @var ItemStackRequestSlotInfo */
private $slot2;
public function __construct(ItemStackRequestSlotInfo $slot1, ItemStackRequestSlotInfo $slot2){
$this->slot1 = $slot1;
$this->slot2 = $slot2;
}
public function getSlot1() : ItemStackRequestSlotInfo{ return $this->slot1; }
public function getSlot2() : ItemStackRequestSlotInfo{ return $this->slot2; }
public static function getTypeId() : int{ return ItemStackRequestActionType::SWAP; }
public static function read(PacketSerializer $in) : self{
$slot1 = ItemStackRequestSlotInfo::read($in);
$slot2 = ItemStackRequestSlotInfo::read($in);
return new self($slot1, $slot2);
}
public function write(PacketSerializer $out) : void{
$this->slot1->write($out);
$this->slot2->write($out);
}
}

View File

@ -0,0 +1,61 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
trait TakeOrPlaceStackRequestActionTrait{
/** @var int */
private $count;
/** @var ItemStackRequestSlotInfo */
private $source;
/** @var ItemStackRequestSlotInfo */
private $destination;
final public function __construct(int $count, ItemStackRequestSlotInfo $source, ItemStackRequestSlotInfo $destination){
$this->count = $count;
$this->source = $source;
$this->destination = $destination;
}
final public function getCount() : int{ return $this->count; }
final public function getSource() : ItemStackRequestSlotInfo{ return $this->source; }
final public function getDestination() : ItemStackRequestSlotInfo{ return $this->destination; }
public static function read(PacketSerializer $in) : self{
$count = $in->getByte();
$src = ItemStackRequestSlotInfo::read($in);
$dst = ItemStackRequestSlotInfo::read($in);
return new self($count, $src, $dst);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->count);
$this->source->write($out);
$this->destination->write($out);
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest;
/**
* Takes some (or all) of the items from the source slot into the destination slot (usually the cursor?).
*/
final class TakeStackRequestAction extends ItemStackRequestAction{
use TakeOrPlaceStackRequestActionTrait;
public static function getTypeId() : int{ return ItemStackRequestActionType::TAKE; }
}

View File

@ -0,0 +1,72 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackresponse;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use function count;
final class ItemStackResponse{
/** @var bool */
private $ok;
/** @var int */
private $requestId;
/** @var ItemStackResponseContainerInfo[] */
private $containerInfos;
/**
* @param ItemStackResponseContainerInfo[] $containerInfos
*/
public function __construct(bool $ok, int $requestId, array $containerInfos){
$this->ok = $ok;
$this->requestId = $requestId;
$this->containerInfos = $containerInfos;
}
public function isOk() : bool{ return $this->ok; }
public function getRequestId() : int{ return $this->requestId; }
/** @return ItemStackResponseContainerInfo[] */
public function getContainerInfos() : array{ return $this->containerInfos; }
public static function read(PacketSerializer $in) : self{
$ok = $in->getBool();
$requestId = $in->readGenericTypeNetworkId();
$containerInfos = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$containerInfos[] = ItemStackResponseContainerInfo::read($in);
}
return new self($ok, $requestId, $containerInfos);
}
public function write(PacketSerializer $out) : void{
$out->putBool($this->ok);
$out->writeGenericTypeNetworkId($this->requestId);
$out->putUnsignedVarInt(count($this->containerInfos));
foreach($this->containerInfos as $containerInfo){
$containerInfo->write($out);
}
}
}

View File

@ -0,0 +1,65 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackresponse;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
use function count;
final class ItemStackResponseContainerInfo{
/** @var int */
private $containerId;
/** @var ItemStackResponseSlotInfo[] */
private $slots;
/**
* @param ItemStackResponseSlotInfo[] $slots
*/
public function __construct(int $containerId, array $slots){
$this->containerId = $containerId;
$this->slots = $slots;
}
public function getContainerId() : int{ return $this->containerId; }
/** @return ItemStackResponseSlotInfo[] */
public function getSlots() : array{ return $this->slots; }
public static function read(PacketSerializer $in) : self{
$containerId = $in->getByte();
$slots = [];
for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){
$slots[] = ItemStackResponseSlotInfo::read($in);
}
return new self($containerId, $slots);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->containerId);
$out->putUnsignedVarInt(count($this->slots));
foreach($this->slots as $slot){
$slot->write($out);
}
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types\inventory\stackresponse;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class ItemStackResponseSlotInfo{
/** @var int */
private $slot;
/** @var int */
private $hotbarSlot;
/** @var int */
private $count;
/** @var int */
private $itemStackId;
public function __construct(int $slot, int $hotbarSlot, int $count, int $itemStackId){
$this->slot = $slot;
$this->hotbarSlot = $hotbarSlot;
$this->count = $count;
$this->itemStackId = $itemStackId;
}
public function getSlot() : int{ return $this->slot; }
public function getHotbarSlot() : int{ return $this->hotbarSlot; }
public function getCount() : int{ return $this->count; }
public function getItemStackId() : int{ return $this->itemStackId; }
public static function read(PacketSerializer $in) : self{
$slot = $in->getByte();
$hotbarSlot = $in->getByte();
$count = $in->getByte();
$itemStackId = $in->readGenericTypeNetworkId();
return new self($slot, $hotbarSlot, $count, $itemStackId);
}
public function write(PacketSerializer $out) : void{
$out->putByte($this->slot);
$out->putByte($this->hotbarSlot);
$out->putByte($this->count);
$out->writeGenericTypeNetworkId($this->itemStackId);
}
}

View File

@ -43,21 +43,31 @@ final class MultiRecipe extends RecipeWithTypeId{
/** @var UUID */
private $recipeId;
/** @var int */
private $recipeNetId;
public function __construct(int $typeId, UUID $recipeId){
public function __construct(int $typeId, UUID $recipeId, int $recipeNetId){
parent::__construct($typeId);
$this->recipeId = $recipeId;
$this->recipeNetId = $recipeNetId;
}
public function getRecipeId() : UUID{
return $this->recipeId;
}
public function getRecipeNetId() : int{
return $this->recipeNetId;
}
public static function decode(int $typeId, PacketSerializer $in) : self{
return new self($typeId, $in->getUUID());
$uuid = $in->getUUID();
$recipeNetId = $in->readGenericTypeNetworkId();
return new self($typeId, $uuid, $recipeNetId);
}
public function encode(PacketSerializer $out) : void{
$out->putUUID($this->recipeId);
$out->writeGenericTypeNetworkId($this->recipeNetId);
}
}

View File

@ -25,27 +25,48 @@ namespace pocketmine\network\mcpe\protocol\types\recipe;
class PotionTypeRecipe{
/** @var int */
private $inputPotionType;
private $inputItemId;
/** @var int */
private $inputItemMeta;
/** @var int */
private $ingredientItemId;
/** @var int */
private $outputPotionType;
private $ingredientItemMeta;
/** @var int */
private $outputItemId;
/** @var int */
private $outputItemMeta;
public function __construct(int $inputPotionType, int $ingredientItemId, int $outputPotionType){
$this->inputPotionType = $inputPotionType;
public function __construct(int $inputItemId, int $inputItemMeta, int $ingredientItemId, int $ingredientItemMeta, int $outputItemId, int $outputItemMeta){
$this->inputItemId = $inputItemId;
$this->inputItemMeta = $inputItemMeta;
$this->ingredientItemId = $ingredientItemId;
$this->outputPotionType = $outputPotionType;
$this->ingredientItemMeta = $ingredientItemMeta;
$this->outputItemId = $outputItemId;
$this->outputItemMeta = $outputItemMeta;
}
public function getInputPotionType() : int{
return $this->inputPotionType;
public function getInputItemId() : int{
return $this->inputItemId;
}
public function getInputItemMeta() : int{
return $this->inputItemMeta;
}
public function getIngredientItemId() : int{
return $this->ingredientItemId;
}
public function getOutputPotionType() : int{
return $this->outputPotionType;
public function getIngredientItemMeta() : int{
return $this->ingredientItemMeta;
}
public function getOutputItemId() : int{
return $this->outputItemId;
}
public function getOutputItemMeta() : int{
return $this->outputItemMeta;
}
}

View File

@ -42,12 +42,14 @@ final class ShapedRecipe extends RecipeWithTypeId{
private $blockName;
/** @var int */
private $priority;
/** @var int */
private $recipeNetId;
/**
* @param RecipeIngredient[][] $input
* @param ItemStack[] $output
*/
public function __construct(int $typeId, string $recipeId, array $input, array $output, UUID $uuid, string $blockType, int $priority){
public function __construct(int $typeId, string $recipeId, array $input, array $output, UUID $uuid, string $blockType, int $priority, int $recipeNetId){
parent::__construct($typeId);
$rows = count($input);
if($rows < 1 or $rows > 3){
@ -67,6 +69,7 @@ final class ShapedRecipe extends RecipeWithTypeId{
$this->blockName = $blockType;
$this->priority = $priority;
$this->uuid = $uuid;
$this->recipeNetId = $recipeNetId;
}
public function getRecipeId() : string{
@ -107,6 +110,10 @@ final class ShapedRecipe extends RecipeWithTypeId{
return $this->priority;
}
public function getRecipeNetId() : int{
return $this->recipeNetId;
}
public static function decode(int $recipeType, PacketSerializer $in) : self{
$recipeId = $in->getString();
$width = $in->getVarInt();
@ -125,8 +132,9 @@ final class ShapedRecipe extends RecipeWithTypeId{
$uuid = $in->getUUID();
$block = $in->getString();
$priority = $in->getVarInt();
$recipeNetId = $in->readGenericTypeNetworkId();
return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority);
return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority, $recipeNetId);
}
public function encode(PacketSerializer $out) : void{
@ -147,5 +155,6 @@ final class ShapedRecipe extends RecipeWithTypeId{
$out->putUUID($this->uuid);
$out->putString($this->blockName);
$out->putVarInt($this->priority);
$out->writeGenericTypeNetworkId($this->recipeNetId);
}
}

View File

@ -42,12 +42,14 @@ final class ShapelessRecipe extends RecipeWithTypeId{
private $blockName;
/** @var int */
private $priority;
/** @var int */
private $recipeNetId;
/**
* @param RecipeIngredient[] $inputs
* @param ItemStack[] $outputs
*/
public function __construct(int $typeId, string $recipeId, array $inputs, array $outputs, UUID $uuid, string $blockName, int $priority){
public function __construct(int $typeId, string $recipeId, array $inputs, array $outputs, UUID $uuid, string $blockName, int $priority, int $recipeNetId){
parent::__construct($typeId);
$this->recipeId = $recipeId;
$this->inputs = $inputs;
@ -55,6 +57,7 @@ final class ShapelessRecipe extends RecipeWithTypeId{
$this->uuid = $uuid;
$this->blockName = $blockName;
$this->priority = $priority;
$this->recipeNetId = $recipeNetId;
}
public function getRecipeId() : string{
@ -87,6 +90,10 @@ final class ShapelessRecipe extends RecipeWithTypeId{
return $this->priority;
}
public function getRecipeNetId() : int{
return $this->recipeNetId;
}
public static function decode(int $recipeType, PacketSerializer $in) : self{
$recipeId = $in->getString();
$input = [];
@ -100,8 +107,9 @@ final class ShapelessRecipe extends RecipeWithTypeId{
$uuid = $in->getUUID();
$block = $in->getString();
$priority = $in->getVarInt();
$recipeNetId = $in->readGenericTypeNetworkId();
return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority);
return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority, $recipeNetId);
}
public function encode(PacketSerializer $out) : void{
@ -119,5 +127,6 @@ final class ShapelessRecipe extends RecipeWithTypeId{
$out->putUUID($this->uuid);
$out->putString($this->blockName);
$out->putVarInt($this->priority);
$out->writeGenericTypeNetworkId($this->recipeNetId);
}
}

View File

@ -55,7 +55,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
* Sometimes this gets changed when the MCPE-layer protocol gets broken to the point where old and new can't
* communicate. It's important that we check this to avoid catastrophes.
*/
private const MCPE_RAKNET_PROTOCOL_VERSION = 9;
private const MCPE_RAKNET_PROTOCOL_VERSION = 10;
private const MCPE_RAKNET_PACKET_ID = "\xfe";

View File

@ -627,7 +627,12 @@ parameters:
-
message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\BaseNbtSerializer\\:\\:read\\(\\) expects string, string\\|false given\\.$#"
count: 2
count: 1
path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php
-
message: "#^Parameter \\#1 \\$buffer of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer constructor expects string, string\\|false given\\.$#"
count: 1
path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php
-

View File

@ -442,16 +442,11 @@ parameters:
-
message: "#^Cannot call method getString\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#"
count: 3
path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php
-
message: "#^Cannot call method getShort\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#"
count: 1
path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php
-
message: "#^Cannot call method equals\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#"
message: "#^Parameter \\#1 \\$that of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:equals\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\Tag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#"
count: 1
path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php