Merge branch 'stable'

This commit is contained in:
Dylan K. Taylor
2019-07-13 18:08:45 +01:00
57 changed files with 1530 additions and 574 deletions

View File

@@ -27,7 +27,7 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\AddEntityPacket;
use pocketmine\network\mcpe\protocol\AddActorPacket;
/**
* @deprecated
@@ -97,7 +97,7 @@ class MonsterSpawner extends Spawnable{
public function readSaveData(CompoundTag $nbt) : void{
if($nbt->hasTag(self::TAG_LEGACY_ENTITY_TYPE_ID, IntTag::class)){
//TODO: this will cause unexpected results when there's no mapping for the entity
$this->entityTypeId = AddEntityPacket::LEGACY_ID_MAP_BC[$nbt->getInt(self::TAG_LEGACY_ENTITY_TYPE_ID)] ?? ":";
$this->entityTypeId = AddActorPacket::LEGACY_ID_MAP_BC[$nbt->getInt(self::TAG_LEGACY_ENTITY_TYPE_ID)] ?? ":";
}elseif($nbt->hasTag(self::TAG_ENTITY_TYPE_ID, StringTag::class)){
$this->entityTypeId = $nbt->getString(self::TAG_ENTITY_TYPE_ID);
}else{

View File

@@ -44,18 +44,18 @@ use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\AddEntityPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket;
use pocketmine\network\mcpe\protocol\types\DataPropertyManager;
use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags;
use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties;
use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes;
use pocketmine\player\Player;
use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\SetActorDataPacket;
use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
use pocketmine\Server;
use pocketmine\timings\Timings;
use pocketmine\timings\TimingsHandler;
@@ -852,7 +852,7 @@ abstract class Entity extends Location implements EntityIds{
}
protected function broadcastMovement(bool $teleport = false) : void{
$pk = new MoveEntityAbsolutePacket();
$pk = new MoveActorAbsolutePacket();
$pk->entityRuntimeId = $this->id;
$pk->position = $this->getOffsetPosition($this);
@@ -864,14 +864,14 @@ abstract class Entity extends Location implements EntityIds{
$pk->zRot = $this->yaw;
if($teleport){
$pk->flags |= MoveEntityAbsolutePacket::FLAG_TELEPORT;
$pk->flags |= MoveActorAbsolutePacket::FLAG_TELEPORT;
}
$this->world->broadcastPacketToViewers($this, $pk);
}
protected function broadcastMotion() : void{
$this->world->broadcastPacketToViewers($this, SetEntityMotionPacket::create($this->id, $this->getMotion()));
$this->world->broadcastPacketToViewers($this, SetActorMotionPacket::create($this->id, $this->getMotion()));
}
public function hasGravity() : bool{
@@ -1592,7 +1592,7 @@ abstract class Entity extends Location implements EntityIds{
* @param Player $player
*/
protected function sendSpawnPacket(Player $player) : void{
$pk = new AddEntityPacket();
$pk = new AddActorPacket();
$pk->entityRuntimeId = $this->getId();
$pk->type = static::NETWORK_ID;
$pk->position = $this->asVector3();
@@ -1642,7 +1642,7 @@ abstract class Entity extends Location implements EntityIds{
$id = spl_object_id($player);
if(isset($this->hasSpawned[$id])){
if($send){
$player->sendDataPacket(RemoveEntityPacket::create($this->id));
$player->sendDataPacket(RemoveActorPacket::create($this->id));
}
unset($this->hasSpawned[$id]);
}
@@ -1769,7 +1769,7 @@ abstract class Entity extends Location implements EntityIds{
$player = [$player];
}
$pk = SetEntityDataPacket::create($this->getId(), $data ?? $this->propertyManager->getAll());
$pk = SetActorDataPacket::create($this->getId(), $data ?? $this->propertyManager->getAll());
foreach($player as $p){
if($p === $this){
@@ -1784,7 +1784,7 @@ abstract class Entity extends Location implements EntityIds{
}
public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{
$this->server->broadcastPacket($players ?? $this->getViewers(), EntityEventPacket::create($this->id, $eventId, $eventData ?? 0));
$this->server->broadcastPacket($players ?? $this->getViewers(), ActorEventPacket::create($this->id, $eventId, $eventData ?? 0));
}
public function broadcastAnimation(?array $players, int $animationId) : void{

View File

@@ -41,8 +41,8 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties;
@@ -319,7 +319,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$this->effectManager->add(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1));
$this->effectManager->add(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1));
$this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM);
$this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM);
$this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound());
$hand = $this->inventory->getItemInHand();

View File

@@ -44,7 +44,7 @@ use pocketmine\math\VoxelRayTrace;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags;
use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties;
use pocketmine\player\Player;
@@ -146,7 +146,7 @@ abstract class Living extends Entity{
parent::setHealth($amount);
$this->attributeMap->getAttribute(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true);
if($this->isAlive() and !$wasAlive){
$this->broadcastEntityEvent(EntityEventPacket::RESPAWN);
$this->broadcastEntityEvent(ActorEventPacket::RESPAWN);
}
}
@@ -454,7 +454,7 @@ abstract class Living extends Entity{
}
protected function doHitAnimation() : void{
$this->broadcastEntityEvent(EntityEventPacket::HURT_ANIMATION);
$this->broadcastEntityEvent(ActorEventPacket::HURT_ANIMATION);
}
public function knockBack(float $x, float $z, float $base = 0.4) : void{
@@ -507,7 +507,7 @@ abstract class Living extends Entity{
}
protected function startDeathAnimation() : void{
$this->broadcastEntityEvent(EntityEventPacket::DEATH_ANIMATION);
$this->broadcastEntityEvent(ActorEventPacket::DEATH_ANIMATION);
}
protected function endDeathAnimation() : void{

View File

@@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\item\VanillaItems;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use function atan2;
use function mt_rand;
use function sqrt;
@@ -68,7 +68,7 @@ class Squid extends WaterAnimal{
$this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize();
}
$this->broadcastEntityEvent(EntityEventPacket::SQUID_INK_CLOUD);
$this->broadcastEntityEvent(ActorEventPacket::SQUID_INK_CLOUD);
}
}

View File

@@ -31,9 +31,9 @@ use pocketmine\event\inventory\InventoryPickupItemEvent;
use pocketmine\item\Item;
use pocketmine\item\ItemIds;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\AddItemEntityPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
use pocketmine\player\Player;
use pocketmine\network\mcpe\protocol\AddItemActorPacket;
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use function get_class;
use function max;
@@ -234,7 +234,7 @@ class ItemEntity extends Entity{
}
protected function sendSpawnPacket(Player $player) : void{
$pk = new AddItemEntityPacket();
$pk = new AddItemActorPacket();
$pk->entityRuntimeId = $this->getId();
$pk->position = $this->asVector3();
$pk->motion = $this->getMotion();
@@ -268,7 +268,7 @@ class ItemEntity extends Entity{
$player->awardAchievement("diamond");
}
$this->server->broadcastPacket($this->getViewers(), TakeItemEntityPacket::create($player->getId(), $this->getId()));
$this->server->broadcastPacket($this->getViewers(), TakeItemActorPacket::create($player->getId(), $this->getId()));
$playerInventory->addItem(clone $item);
$this->flagForDespawn();

View File

@@ -140,9 +140,11 @@ class Painting extends Entity{
protected function sendSpawnPacket(Player $player) : void{
$pk = new AddPaintingPacket();
$pk->entityRuntimeId = $this->getId();
$pk->x = $this->blockIn->x;
$pk->y = $this->blockIn->y;
$pk->z = $this->blockIn->z;
$pk->position = new Vector3(
($this->boundingBox->minX + $this->boundingBox->maxX) / 2,
($this->boundingBox->minY + $this->boundingBox->maxY) / 2,
($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2
);
$pk->direction = $this->direction;
$pk->title = $this->motive;

View File

@@ -30,8 +30,8 @@ use pocketmine\event\inventory\InventoryPickupArrowEvent;
use pocketmine\item\VanillaItems;
use pocketmine\math\RayTraceResult;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags;
use pocketmine\player\Player;
use pocketmine\world\sound\ArrowHitSound;
@@ -143,7 +143,7 @@ class Arrow extends Projectile{
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
parent::onHitBlock($blockHit, $hitResult);
$this->broadcastEntityEvent(EntityEventPacket::ARROW_SHAKE, 7); //7 ticks
$this->broadcastEntityEvent(ActorEventPacket::ARROW_SHAKE, 7); //7 ticks
}
protected function onHitEntity(Entity $entityHit, RayTraceResult $hitResult) : void{
@@ -193,7 +193,7 @@ class Arrow extends Projectile{
return;
}
$this->server->broadcastPacket($this->getViewers(), TakeItemEntityPacket::create($player->getId(), $this->getId()));
$this->server->broadcastPacket($this->getViewers(), TakeItemActorPacket::create($player->getId(), $this->getId()));
$playerInventory->addItem(clone $item);
$this->flagForDespawn();

View File

@@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe;
use pocketmine\network\mcpe\compression\CompressBatchPromise;
use pocketmine\network\mcpe\compression\Zlib;
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
use pocketmine\network\mcpe\protocol\LevelChunkPacket;
use pocketmine\network\mcpe\serializer\ChunkSerializer;
use pocketmine\scheduler\AsyncTask;
use pocketmine\world\format\Chunk;
@@ -60,8 +60,10 @@ class ChunkRequestTask extends AsyncTask{
}
public function onRun() : void{
$chunk = ChunkSerializer::serialize(FastChunkSerializer::deserialize($this->chunk), $this->tiles);
$this->setResult(Zlib::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $chunk))->getBuffer(), $this->compressionLevel));
$chunk = FastChunkSerializer::deserialize($this->chunk);
$subCount = $chunk->getSubChunkSendCount();
$payload = ChunkSerializer::serialize($chunk, $this->tiles);
$this->setResult(Zlib::compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer(), $this->compressionLevel));
}
public function onError() : void{

View File

@@ -39,9 +39,12 @@ use pocketmine\nbt\NbtDataException;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\ActorFallPacket;
use pocketmine\network\mcpe\protocol\ActorPickRequestPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\BookEditPacket;
use pocketmine\network\mcpe\protocol\BossEventPacket;
@@ -49,9 +52,6 @@ use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandRequestPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\EntityFallPacket;
use pocketmine\network\mcpe\protocol\EntityPickRequestPacket;
use pocketmine\network\mcpe\protocol\InteractPacket;
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
@@ -143,16 +143,16 @@ class InGamePacketHandler extends PacketHandler{
return true; //useless leftover from 1.8
}
public function handleEntityEvent(EntityEventPacket $packet) : bool{
public function handleActorEvent(ActorEventPacket $packet) : bool{
$this->player->doCloseInventory();
switch($packet->event){
case EntityEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side
case ActorEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side
if($packet->data === 0){
return false;
}
$this->player->broadcastEntityEvent(EntityEventPacket::EATING_ITEM, $packet->data);
$this->player->broadcastEntityEvent(ActorEventPacket::EATING_ITEM, $packet->data);
break;
default:
return false;
@@ -385,7 +385,7 @@ class InGamePacketHandler extends PacketHandler{
return $this->player->pickBlock(new Vector3($packet->blockX, $packet->blockY, $packet->blockZ), $packet->addUserData);
}
public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{
public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{
return false; //TODO
}
@@ -454,7 +454,7 @@ class InGamePacketHandler extends PacketHandler{
return true;
}
public function handleEntityFall(EntityFallPacket $packet) : bool{
public function handleActorFall(ActorFallPacket $packet) : bool{
return true; //Not used
}
@@ -508,7 +508,7 @@ class InGamePacketHandler extends PacketHandler{
return $handled;
}
public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{
public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
$pos = new Vector3($packet->x, $packet->y, $packet->z);
if($pos->distanceSquared($this->player) > 10000){
return false;

View File

@@ -23,18 +23,22 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\handler;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\ActorFallPacket;
use pocketmine\network\mcpe\protocol\ActorPickRequestPacket;
use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\AddBehaviorTreePacket;
use pocketmine\network\mcpe\protocol\AddEntityPacket;
use pocketmine\network\mcpe\protocol\AddItemEntityPacket;
use pocketmine\network\mcpe\protocol\AddItemActorPacket;
use pocketmine\network\mcpe\protocol\AddPaintingPacket;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\AutomationClientConnectPacket;
use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\AvailableEntityIdentifiersPacket;
use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\BookEditPacket;
@@ -43,6 +47,9 @@ use pocketmine\network\mcpe\protocol\CameraPacket;
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
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\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandOutputPacket;
@@ -53,12 +60,8 @@ use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\EntityFallPacket;
use pocketmine\network\mcpe\protocol\EntityPickRequestPacket;
use pocketmine\network\mcpe\protocol\EventPacket;
use pocketmine\network\mcpe\protocol\ExplodePacket;
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
use pocketmine\network\mcpe\protocol\GameRulesChangedPacket;
use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket;
use pocketmine\network\mcpe\protocol\HurtArmorPacket;
@@ -69,6 +72,8 @@ use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
use pocketmine\network\mcpe\protocol\LabTablePacket;
use pocketmine\network\mcpe\protocol\LecternUpdatePacket;
use pocketmine\network\mcpe\protocol\LevelChunkPacket;
use pocketmine\network\mcpe\protocol\LevelEventGenericPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1;
@@ -81,8 +86,8 @@ use pocketmine\network\mcpe\protocol\MobEffectPacket;
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;
use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;
use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket;
use pocketmine\network\mcpe\protocol\MoveEntityDeltaPacket;
use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket;
use pocketmine\network\mcpe\protocol\MoveActorDeltaPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket;
use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket;
@@ -97,6 +102,7 @@ use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
use pocketmine\network\mcpe\protocol\RemoveObjectivePacket;
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
@@ -112,13 +118,13 @@ use pocketmine\network\mcpe\protocol\ScriptCustomEventPacket;
use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket;
use pocketmine\network\mcpe\protocol\ServerSettingsResponsePacket;
use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket;
use pocketmine\network\mcpe\protocol\SetActorDataPacket;
use pocketmine\network\mcpe\protocol\SetActorLinkPacket;
use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket;
use pocketmine\network\mcpe\protocol\SetDefaultGameTypePacket;
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
use pocketmine\network\mcpe\protocol\SetDisplayObjectivePacket;
use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
use pocketmine\network\mcpe\protocol\SetEntityLinkPacket;
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket;
use pocketmine\network\mcpe\protocol\SetHealthPacket;
use pocketmine\network\mcpe\protocol\SetLastHurtByPacket;
use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket;
@@ -137,12 +143,15 @@ use pocketmine\network\mcpe\protocol\SpawnParticleEffectPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\StopSoundPacket;
use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\StructureTemplateDataExportRequestPacket;
use pocketmine\network\mcpe\protocol\StructureTemplateDataExportResponsePacket;
use pocketmine\network\mcpe\protocol\SubClientLoginPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use pocketmine\network\mcpe\protocol\TextPacket;
use pocketmine\network\mcpe\protocol\TransferPacket;
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
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\UpdateSoftEnumPacket;
@@ -209,23 +218,23 @@ abstract class PacketHandler{
return false;
}
public function handleAddEntity(AddEntityPacket $packet) : bool{
public function handleAddActor(AddActorPacket $packet) : bool{
return false;
}
public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{
public function handleRemoveActor(RemoveActorPacket $packet) : bool{
return false;
}
public function handleAddItemEntity(AddItemEntityPacket $packet) : bool{
public function handleAddItemActor(AddItemActorPacket $packet) : bool{
return false;
}
public function handleTakeItemEntity(TakeItemEntityPacket $packet) : bool{
public function handleTakeItemActor(TakeItemActorPacket $packet) : bool{
return false;
}
public function handleMoveEntityAbsolute(MoveEntityAbsolutePacket $packet) : bool{
public function handleMoveActorAbsolute(MoveActorAbsolutePacket $packet) : bool{
return false;
}
@@ -261,7 +270,7 @@ abstract class PacketHandler{
return false;
}
public function handleEntityEvent(EntityEventPacket $packet) : bool{
public function handleActorEvent(ActorEventPacket $packet) : bool{
return false;
}
@@ -293,7 +302,7 @@ abstract class PacketHandler{
return false;
}
public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{
public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{
return false;
}
@@ -301,7 +310,7 @@ abstract class PacketHandler{
return false;
}
public function handleEntityFall(EntityFallPacket $packet) : bool{
public function handleActorFall(ActorFallPacket $packet) : bool{
return false;
}
@@ -309,15 +318,15 @@ abstract class PacketHandler{
return false;
}
public function handleSetEntityData(SetEntityDataPacket $packet) : bool{
public function handleSetActorData(SetActorDataPacket $packet) : bool{
return false;
}
public function handleSetEntityMotion(SetEntityMotionPacket $packet) : bool{
public function handleSetActorMotion(SetActorMotionPacket $packet) : bool{
return false;
}
public function handleSetEntityLink(SetEntityLinkPacket $packet) : bool{
public function handleSetActorLink(SetActorLinkPacket $packet) : bool{
return false;
}
@@ -377,7 +386,7 @@ abstract class PacketHandler{
return false;
}
public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{
public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
return false;
}
@@ -385,7 +394,7 @@ abstract class PacketHandler{
return false;
}
public function handleFullChunkData(FullChunkDataPacket $packet) : bool{
public function handleLevelChunk(LevelChunkPacket $packet) : bool{
return false;
}
@@ -597,7 +606,7 @@ abstract class PacketHandler{
return false;
}
public function handleMoveEntityDelta(MoveEntityDeltaPacket $packet) : bool{
public function handleMoveActorDelta(MoveActorDeltaPacket $packet) : bool{
return false;
}
@@ -625,7 +634,7 @@ abstract class PacketHandler{
return false;
}
public function handleAvailableEntityIdentifiers(AvailableEntityIdentifiersPacket $packet) : bool{
public function handleAvailableActorIdentifiers(AvailableActorIdentifiersPacket $packet) : bool{
return false;
}
@@ -645,6 +654,10 @@ abstract class PacketHandler{
return false;
}
public function handleLevelEventGeneric(LevelEventGenericPacket $packet) : bool{
return false;
}
public function handleLecternUpdate(LecternUpdatePacket $packet) : bool{
return false;
}
@@ -653,11 +666,43 @@ abstract class PacketHandler{
return false;
}
public function handleMapCreateLockedCopy(MapCreateLockedCopyPacket $packet) : bool{
public function handleAddEntity(AddEntityPacket $packet) : bool{
return false;
}
public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{
return false;
}
public function handleClientCacheStatus(ClientCacheStatusPacket $packet) : bool{
return false;
}
public function handleOnScreenTextureAnimation(OnScreenTextureAnimationPacket $packet) : bool{
return false;
}
public function handleMapCreateLockedCopy(MapCreateLockedCopyPacket $packet) : bool{
return false;
}
public function handleStructureTemplateDataExportRequest(StructureTemplateDataExportRequestPacket $packet) : bool{
return false;
}
public function handleStructureTemplateDataExportResponse(StructureTemplateDataExportResponsePacket $packet) : bool{
return false;
}
public function handleUpdateBlockProperties(UpdateBlockPropertiesPacket $packet) : bool{
return false;
}
public function handleClientCacheBlobStatus(ClientCacheBlobStatusPacket $packet) : bool{
return false;
}
public function handleClientCacheMissResponse(ClientCacheMissResponsePacket $packet) : bool{
return false;
}
}

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\handler;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\AvailableEntityIdentifiersPacket;
use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket;
use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket;
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket;
@@ -78,7 +78,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$pk->worldName = $this->server->getMotd();
$this->session->sendDataPacket($pk);
$this->session->sendDataPacket(new AvailableEntityIdentifiersPacket());
$this->session->sendDataPacket(new AvailableActorIdentifiersPacket());
$this->session->sendDataPacket(new BiomeDefinitionListPacket());
$this->player->setImmobile(); //HACK: fix client-side falling pre-spawn

View File

@@ -25,11 +25,10 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\handler\PacketHandler;
class EntityEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ENTITY_EVENT_PACKET;
class ActorEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET;
public const HURT_ANIMATION = 2;
public const DEATH_ANIMATION = 3;
@@ -111,6 +110,6 @@ class EntityEventPacket extends DataPacket implements ClientboundPacket, Serverb
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleEntityEvent($this);
return $handler->handleActorEvent($this);
}
}

View File

@@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
class EntityFallPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ENTITY_FALL_PACKET;
class ActorFallPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ACTOR_FALL_PACKET;
/** @var int */
public $entityRuntimeId;
@@ -51,6 +51,6 @@ class EntityFallPacket extends DataPacket implements ServerboundPacket{
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleEntityFall($this);
return $handler->handleActorFall($this);
}
}

View File

@@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
class EntityPickRequestPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ENTITY_PICK_REQUEST_PACKET;
class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::ACTOR_PICK_REQUEST_PACKET;
/** @var int */
public $entityUniqueId;
@@ -46,6 +46,6 @@ class EntityPickRequestPacket extends DataPacket implements ServerboundPacket{
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleEntityPickRequest($this);
return $handler->handleActorPickRequest($this);
}
}

View File

@@ -0,0 +1,245 @@
<?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\entity\Attribute;
use pocketmine\entity\EntityIds;
use pocketmine\math\Vector3;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\protocol\types\EntityLink;
use function array_search;
use function count;
class AddActorPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET;
/*
* Really really really really really nasty hack, to preserve backwards compatibility.
* We can't transition to string IDs within 3.x because the network IDs (the integer ones) are exposed
* to the API in some places (for god's sake shoghi).
*
* TODO: remove this on 4.0
*/
public const LEGACY_ID_MAP_BC = [
EntityIds::NPC => "minecraft:npc",
EntityIds::PLAYER => "minecraft:player",
EntityIds::WITHER_SKELETON => "minecraft:wither_skeleton",
EntityIds::HUSK => "minecraft:husk",
EntityIds::STRAY => "minecraft:stray",
EntityIds::WITCH => "minecraft:witch",
EntityIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager",
EntityIds::BLAZE => "minecraft:blaze",
EntityIds::MAGMA_CUBE => "minecraft:magma_cube",
EntityIds::GHAST => "minecraft:ghast",
EntityIds::CAVE_SPIDER => "minecraft:cave_spider",
EntityIds::SILVERFISH => "minecraft:silverfish",
EntityIds::ENDERMAN => "minecraft:enderman",
EntityIds::SLIME => "minecraft:slime",
EntityIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman",
EntityIds::SPIDER => "minecraft:spider",
EntityIds::SKELETON => "minecraft:skeleton",
EntityIds::CREEPER => "minecraft:creeper",
EntityIds::ZOMBIE => "minecraft:zombie",
EntityIds::SKELETON_HORSE => "minecraft:skeleton_horse",
EntityIds::MULE => "minecraft:mule",
EntityIds::DONKEY => "minecraft:donkey",
EntityIds::DOLPHIN => "minecraft:dolphin",
EntityIds::TROPICALFISH => "minecraft:tropicalfish",
EntityIds::WOLF => "minecraft:wolf",
EntityIds::SQUID => "minecraft:squid",
EntityIds::DROWNED => "minecraft:drowned",
EntityIds::SHEEP => "minecraft:sheep",
EntityIds::MOOSHROOM => "minecraft:mooshroom",
EntityIds::PANDA => "minecraft:panda",
EntityIds::SALMON => "minecraft:salmon",
EntityIds::PIG => "minecraft:pig",
EntityIds::VILLAGER => "minecraft:villager",
EntityIds::COD => "minecraft:cod",
EntityIds::PUFFERFISH => "minecraft:pufferfish",
EntityIds::COW => "minecraft:cow",
EntityIds::CHICKEN => "minecraft:chicken",
EntityIds::BALLOON => "minecraft:balloon",
EntityIds::LLAMA => "minecraft:llama",
EntityIds::IRON_GOLEM => "minecraft:iron_golem",
EntityIds::RABBIT => "minecraft:rabbit",
EntityIds::SNOW_GOLEM => "minecraft:snow_golem",
EntityIds::BAT => "minecraft:bat",
EntityIds::OCELOT => "minecraft:ocelot",
EntityIds::HORSE => "minecraft:horse",
EntityIds::CAT => "minecraft:cat",
EntityIds::POLAR_BEAR => "minecraft:polar_bear",
EntityIds::ZOMBIE_HORSE => "minecraft:zombie_horse",
EntityIds::TURTLE => "minecraft:turtle",
EntityIds::PARROT => "minecraft:parrot",
EntityIds::GUARDIAN => "minecraft:guardian",
EntityIds::ELDER_GUARDIAN => "minecraft:elder_guardian",
EntityIds::VINDICATOR => "minecraft:vindicator",
EntityIds::WITHER => "minecraft:wither",
EntityIds::ENDER_DRAGON => "minecraft:ender_dragon",
EntityIds::SHULKER => "minecraft:shulker",
EntityIds::ENDERMITE => "minecraft:endermite",
EntityIds::MINECART => "minecraft:minecart",
EntityIds::HOPPER_MINECART => "minecraft:hopper_minecart",
EntityIds::TNT_MINECART => "minecraft:tnt_minecart",
EntityIds::CHEST_MINECART => "minecraft:chest_minecart",
EntityIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart",
EntityIds::ARMOR_STAND => "minecraft:armor_stand",
EntityIds::ITEM => "minecraft:item",
EntityIds::TNT => "minecraft:tnt",
EntityIds::FALLING_BLOCK => "minecraft:falling_block",
EntityIds::XP_BOTTLE => "minecraft:xp_bottle",
EntityIds::XP_ORB => "minecraft:xp_orb",
EntityIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal",
EntityIds::ENDER_CRYSTAL => "minecraft:ender_crystal",
EntityIds::SHULKER_BULLET => "minecraft:shulker_bullet",
EntityIds::FISHING_HOOK => "minecraft:fishing_hook",
EntityIds::DRAGON_FIREBALL => "minecraft:dragon_fireball",
EntityIds::ARROW => "minecraft:arrow",
EntityIds::SNOWBALL => "minecraft:snowball",
EntityIds::EGG => "minecraft:egg",
EntityIds::PAINTING => "minecraft:painting",
EntityIds::THROWN_TRIDENT => "minecraft:thrown_trident",
EntityIds::FIREBALL => "minecraft:fireball",
EntityIds::SPLASH_POTION => "minecraft:splash_potion",
EntityIds::ENDER_PEARL => "minecraft:ender_pearl",
EntityIds::LEASH_KNOT => "minecraft:leash_knot",
EntityIds::WITHER_SKULL => "minecraft:wither_skull",
EntityIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous",
EntityIds::BOAT => "minecraft:boat",
EntityIds::LIGHTNING_BOLT => "minecraft:lightning_bolt",
EntityIds::SMALL_FIREBALL => "minecraft:small_fireball",
EntityIds::LLAMA_SPIT => "minecraft:llama_spit",
EntityIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud",
EntityIds::LINGERING_POTION => "minecraft:lingering_potion",
EntityIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket",
EntityIds::EVOCATION_FANG => "minecraft:evocation_fang",
EntityIds::EVOCATION_ILLAGER => "minecraft:evocation_illager",
EntityIds::VEX => "minecraft:vex",
EntityIds::AGENT => "minecraft:agent",
EntityIds::ICE_BOMB => "minecraft:ice_bomb",
EntityIds::PHANTOM => "minecraft:phantom",
EntityIds::TRIPOD_CAMERA => "minecraft:tripod_camera"
];
/** @var int|null */
public $entityUniqueId = null; //TODO
/** @var int */
public $entityRuntimeId;
/** @var int */
public $type;
/** @var Vector3 */
public $position;
/** @var Vector3|null */
public $motion;
/** @var float */
public $pitch = 0.0;
/** @var float */
public $yaw = 0.0;
/** @var float */
public $headYaw = 0.0;
/** @var Attribute[] */
public $attributes = [];
/** @var array */
public $metadata = [];
/** @var EntityLink[] */
public $links = [];
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId();
$this->type = array_search($t = $this->getString(), self::LEGACY_ID_MAP_BC, true);
if($this->type === false){
throw new BadPacketException("Can't map ID $t to legacy ID");
}
$this->position = $this->getVector3();
$this->motion = $this->getVector3();
$this->pitch = $this->getLFloat();
$this->yaw = $this->getLFloat();
$this->headYaw = $this->getLFloat();
$attrCount = $this->getUnsignedVarInt();
for($i = 0; $i < $attrCount; ++$i){
$id = $this->getString();
$min = $this->getLFloat();
$current = $this->getLFloat();
$max = $this->getLFloat();
$attr = Attribute::getAttribute($id);
if($attr !== null){
try{
$attr->setMinValue($min);
$attr->setMaxValue($max);
$attr->setValue($current);
}catch(\InvalidArgumentException $e){
throw new BadPacketException($e->getMessage(), 0, $e); //TODO: address this properly
}
$this->attributes[] = $attr;
}else{
throw new BadPacketException("Unknown attribute type \"$id\"");
}
}
$this->metadata = $this->getEntityMetadata();
$linkCount = $this->getUnsignedVarInt();
for($i = 0; $i < $linkCount; ++$i){
$this->links[] = $this->getEntityLink();
}
}
protected function encodePayload() : void{
$this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId);
$this->putEntityRuntimeId($this->entityRuntimeId);
if(!isset(self::LEGACY_ID_MAP_BC[$this->type])){
throw new \InvalidArgumentException("Unknown entity numeric ID $this->type");
}
$this->putString(self::LEGACY_ID_MAP_BC[$this->type]);
$this->putVector3($this->position);
$this->putVector3Nullable($this->motion);
$this->putLFloat($this->pitch);
$this->putLFloat($this->yaw);
$this->putLFloat($this->headYaw);
$this->putUnsignedVarInt(count($this->attributes));
foreach($this->attributes as $attribute){
$this->putString($attribute->getId());
$this->putLFloat($attribute->getMinValue());
$this->putLFloat($attribute->getValue());
$this->putLFloat($attribute->getMaxValue());
}
$this->putEntityMetadata($this->metadata);
$this->putUnsignedVarInt(count($this->links));
foreach($this->links as $link){
$this->putEntityLink($link);
}
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleAddActor($this);
}
}

View File

@@ -25,218 +25,33 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\entity\Attribute;
use pocketmine\entity\EntityIds;
use pocketmine\math\Vector3;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\protocol\types\EntityLink;
use function array_search;
use function count;
class AddEntityPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET;
/*
* Really really really really really nasty hack, to preserve backwards compatibility.
* We can't transition to string IDs within 3.x because the network IDs (the integer ones) are exposed
* to the API in some places (for god's sake shoghi).
*
* TODO: remove this on 4.0
/** @var int */
private $uvarint1;
public static function create(int $uvarint1) : self{
$result = new self;
$result->uvarint1 = $uvarint1;
return $result;
}
/**
* @return int
*/
public const LEGACY_ID_MAP_BC = [
EntityIds::NPC => "minecraft:npc",
EntityIds::PLAYER => "minecraft:player",
EntityIds::WITHER_SKELETON => "minecraft:wither_skeleton",
EntityIds::HUSK => "minecraft:husk",
EntityIds::STRAY => "minecraft:stray",
EntityIds::WITCH => "minecraft:witch",
EntityIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager",
EntityIds::BLAZE => "minecraft:blaze",
EntityIds::MAGMA_CUBE => "minecraft:magma_cube",
EntityIds::GHAST => "minecraft:ghast",
EntityIds::CAVE_SPIDER => "minecraft:cave_spider",
EntityIds::SILVERFISH => "minecraft:silverfish",
EntityIds::ENDERMAN => "minecraft:enderman",
EntityIds::SLIME => "minecraft:slime",
EntityIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman",
EntityIds::SPIDER => "minecraft:spider",
EntityIds::SKELETON => "minecraft:skeleton",
EntityIds::CREEPER => "minecraft:creeper",
EntityIds::ZOMBIE => "minecraft:zombie",
EntityIds::SKELETON_HORSE => "minecraft:skeleton_horse",
EntityIds::MULE => "minecraft:mule",
EntityIds::DONKEY => "minecraft:donkey",
EntityIds::DOLPHIN => "minecraft:dolphin",
EntityIds::TROPICALFISH => "minecraft:tropicalfish",
EntityIds::WOLF => "minecraft:wolf",
EntityIds::SQUID => "minecraft:squid",
EntityIds::DROWNED => "minecraft:drowned",
EntityIds::SHEEP => "minecraft:sheep",
EntityIds::MOOSHROOM => "minecraft:mooshroom",
EntityIds::PANDA => "minecraft:panda",
EntityIds::SALMON => "minecraft:salmon",
EntityIds::PIG => "minecraft:pig",
EntityIds::VILLAGER => "minecraft:villager",
EntityIds::COD => "minecraft:cod",
EntityIds::PUFFERFISH => "minecraft:pufferfish",
EntityIds::COW => "minecraft:cow",
EntityIds::CHICKEN => "minecraft:chicken",
EntityIds::BALLOON => "minecraft:balloon",
EntityIds::LLAMA => "minecraft:llama",
EntityIds::IRON_GOLEM => "minecraft:iron_golem",
EntityIds::RABBIT => "minecraft:rabbit",
EntityIds::SNOW_GOLEM => "minecraft:snow_golem",
EntityIds::BAT => "minecraft:bat",
EntityIds::OCELOT => "minecraft:ocelot",
EntityIds::HORSE => "minecraft:horse",
EntityIds::CAT => "minecraft:cat",
EntityIds::POLAR_BEAR => "minecraft:polar_bear",
EntityIds::ZOMBIE_HORSE => "minecraft:zombie_horse",
EntityIds::TURTLE => "minecraft:turtle",
EntityIds::PARROT => "minecraft:parrot",
EntityIds::GUARDIAN => "minecraft:guardian",
EntityIds::ELDER_GUARDIAN => "minecraft:elder_guardian",
EntityIds::VINDICATOR => "minecraft:vindicator",
EntityIds::WITHER => "minecraft:wither",
EntityIds::ENDER_DRAGON => "minecraft:ender_dragon",
EntityIds::SHULKER => "minecraft:shulker",
EntityIds::ENDERMITE => "minecraft:endermite",
EntityIds::MINECART => "minecraft:minecart",
EntityIds::HOPPER_MINECART => "minecraft:hopper_minecart",
EntityIds::TNT_MINECART => "minecraft:tnt_minecart",
EntityIds::CHEST_MINECART => "minecraft:chest_minecart",
EntityIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart",
EntityIds::ARMOR_STAND => "minecraft:armor_stand",
EntityIds::ITEM => "minecraft:item",
EntityIds::TNT => "minecraft:tnt",
EntityIds::FALLING_BLOCK => "minecraft:falling_block",
EntityIds::XP_BOTTLE => "minecraft:xp_bottle",
EntityIds::XP_ORB => "minecraft:xp_orb",
EntityIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal",
EntityIds::ENDER_CRYSTAL => "minecraft:ender_crystal",
EntityIds::SHULKER_BULLET => "minecraft:shulker_bullet",
EntityIds::FISHING_HOOK => "minecraft:fishing_hook",
EntityIds::DRAGON_FIREBALL => "minecraft:dragon_fireball",
EntityIds::ARROW => "minecraft:arrow",
EntityIds::SNOWBALL => "minecraft:snowball",
EntityIds::EGG => "minecraft:egg",
EntityIds::PAINTING => "minecraft:painting",
EntityIds::THROWN_TRIDENT => "minecraft:thrown_trident",
EntityIds::FIREBALL => "minecraft:fireball",
EntityIds::SPLASH_POTION => "minecraft:splash_potion",
EntityIds::ENDER_PEARL => "minecraft:ender_pearl",
EntityIds::LEASH_KNOT => "minecraft:leash_knot",
EntityIds::WITHER_SKULL => "minecraft:wither_skull",
EntityIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous",
EntityIds::BOAT => "minecraft:boat",
EntityIds::LIGHTNING_BOLT => "minecraft:lightning_bolt",
EntityIds::SMALL_FIREBALL => "minecraft:small_fireball",
EntityIds::LLAMA_SPIT => "minecraft:llama_spit",
EntityIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud",
EntityIds::LINGERING_POTION => "minecraft:lingering_potion",
EntityIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket",
EntityIds::EVOCATION_FANG => "minecraft:evocation_fang",
EntityIds::EVOCATION_ILLAGER => "minecraft:evocation_illager",
EntityIds::VEX => "minecraft:vex",
EntityIds::AGENT => "minecraft:agent",
EntityIds::ICE_BOMB => "minecraft:ice_bomb",
EntityIds::PHANTOM => "minecraft:phantom",
EntityIds::TRIPOD_CAMERA => "minecraft:tripod_camera"
];
/** @var int|null */
public $entityUniqueId = null; //TODO
/** @var int */
public $entityRuntimeId;
/** @var int */
public $type;
/** @var Vector3 */
public $position;
/** @var Vector3|null */
public $motion;
/** @var float */
public $pitch = 0.0;
/** @var float */
public $yaw = 0.0;
/** @var float */
public $headYaw = 0.0;
/** @var Attribute[] */
public $attributes = [];
/** @var array */
public $metadata = [];
/** @var EntityLink[] */
public $links = [];
public function getUvarint1() : int{
return $this->uvarint1;
}
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId();
$this->type = array_search($t = $this->getString(), self::LEGACY_ID_MAP_BC, true);
if($this->type === false){
throw new BadPacketException("Can't map ID $t to legacy ID");
}
$this->position = $this->getVector3();
$this->motion = $this->getVector3();
$this->pitch = $this->getLFloat();
$this->yaw = $this->getLFloat();
$this->headYaw = $this->getLFloat();
$attrCount = $this->getUnsignedVarInt();
for($i = 0; $i < $attrCount; ++$i){
$id = $this->getString();
$min = $this->getLFloat();
$current = $this->getLFloat();
$max = $this->getLFloat();
$attr = Attribute::getAttribute($id);
if($attr !== null){
try{
$attr->setMinValue($min);
$attr->setMaxValue($max);
$attr->setValue($current);
}catch(\InvalidArgumentException $e){
throw new BadPacketException($e->getMessage(), 0, $e); //TODO: address this properly
}
$this->attributes[] = $attr;
}else{
throw new BadPacketException("Unknown attribute type \"$id\"");
}
}
$this->metadata = $this->getEntityMetadata();
$linkCount = $this->getUnsignedVarInt();
for($i = 0; $i < $linkCount; ++$i){
$this->links[] = $this->getEntityLink();
}
$this->uvarint1 = $this->getUnsignedVarInt();
}
protected function encodePayload() : void{
$this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId);
$this->putEntityRuntimeId($this->entityRuntimeId);
if(!isset(self::LEGACY_ID_MAP_BC[$this->type])){
throw new \InvalidArgumentException("Unknown entity numeric ID $this->type");
}
$this->putString(self::LEGACY_ID_MAP_BC[$this->type]);
$this->putVector3($this->position);
$this->putVector3Nullable($this->motion);
$this->putLFloat($this->pitch);
$this->putLFloat($this->yaw);
$this->putLFloat($this->headYaw);
$this->putUnsignedVarInt(count($this->attributes));
foreach($this->attributes as $attribute){
$this->putString($attribute->getId());
$this->putLFloat($attribute->getMinValue());
$this->putLFloat($attribute->getValue());
$this->putLFloat($attribute->getMaxValue());
}
$this->putEntityMetadata($this->metadata);
$this->putUnsignedVarInt(count($this->links));
foreach($this->links as $link){
$this->putEntityLink($link);
}
$this->putUnsignedVarInt($this->uvarint1);
}
public function handle(PacketHandler $handler) : bool{

View File

@@ -29,8 +29,8 @@ use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\handler\PacketHandler;
class AddItemEntityPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ENTITY_PACKET;
class AddItemActorPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ACTOR_PACKET;
/** @var int|null */
public $entityUniqueId = null; //TODO
@@ -68,6 +68,6 @@ class AddItemEntityPacket extends DataPacket implements ClientboundPacket{
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleAddItemEntity($this);
return $handler->handleAddItemActor($this);
}
}

View File

@@ -25,31 +25,27 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\handler\PacketHandler;
class AddPaintingPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET;
/** @var string */
public $title;
/** @var int|null */
public $entityUniqueId = null;
/** @var int */
public $entityRuntimeId;
/** @var int */
public $x;
/** @var int */
public $y;
/** @var int */
public $z;
/** @var Vector3 */
public $position;
/** @var int */
public $direction;
/** @var string */
public $title;
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId();
$this->getBlockPosition($this->x, $this->y, $this->z);
$this->position = $this->getVector3();
$this->direction = $this->getVarInt();
$this->title = $this->getString();
}
@@ -57,7 +53,7 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{
protected function encodePayload() : void{
$this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId);
$this->putEntityRuntimeId($this->entityRuntimeId);
$this->putBlockPosition($this->x, $this->y, $this->z);
$this->putVector3($this->position);
$this->putVarInt($this->direction);
$this->putString($this->title);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::BLOCK_ENTITY_DATA_PACKET;
class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::BLOCK_ACTOR_DATA_PACKET;
/** @var int */
public $x;
@@ -58,6 +58,6 @@ class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, Ser
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleBlockEntityData($this);
return $handler->handleBlockActorData($this);
}
}

View File

@@ -0,0 +1,95 @@
<?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\handler\PacketHandler;
use function count;
class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_BLOB_STATUS_PACKET;
/** @var int[] xxHash64 subchunk data hashes */
private $hitHashes = [];
/** @var int[] xxHash64 subchunk data hashes */
private $missHashes = [];
/**
* @param int[] $hitHashes
* @param int[] $missHashes
*
* @return self
*/
public static function create(array $hitHashes, array $missHashes) : self{
//type checks
(static function(int ...$hashes){})(...$hitHashes);
(static function(int ...$hashes){})(...$missHashes);
$result = new self;
$result->hitHashes = $hitHashes;
$result->missHashes = $missHashes;
return $result;
}
/**
* @return int[]
*/
public function getHitHashes() : array{
return $this->hitHashes;
}
/**
* @return int[]
*/
public function getMissHashes() : array{
return $this->missHashes;
}
protected function decodePayload() : void{
$hitCount = $this->getUnsignedVarInt();
$missCount = $this->getUnsignedVarInt();
for($i = 0; $i < $hitCount; ++$i){
$this->hitHashes[] = $this->getLLong();
}
for($i = 0; $i < $missCount; ++$i){
$this->missHashes[] = $this->getLLong();
}
}
protected function encodePayload() : void{
$this->putUnsignedVarInt(count($this->hitHashes));
$this->putUnsignedVarInt(count($this->missHashes));
foreach($this->hitHashes as $hash){
$this->putLLong($hash);
}
foreach($this->missHashes as $hash){
$this->putLLong($hash);
}
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleClientCacheBlobStatus($this);
}
}

View File

@@ -0,0 +1,78 @@
<?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\handler\PacketHandler;
use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob;
use function count;
class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_MISS_RESPONSE_PACKET;
/** @var ChunkCacheBlob[] */
private $blobs = [];
/**
* @param ChunkCacheBlob[] $blobs
*
* @return self
*/
public static function create(array $blobs) : self{
//type check
(static function(ChunkCacheBlob ...$blobs){})($blobs);
$result = new self;
$result->blobs = $blobs;
return $result;
}
/**
* @return ChunkCacheBlob[]
*/
public function getBlobs() : array{
return $this->blobs;
}
protected function decodePayload() : void{
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$hash = $this->getLLong();
$payload = $this->getString();
$this->blobs[] = new ChunkCacheBlob($hash, $payload);
}
}
protected function encodePayload() : void{
$this->putUnsignedVarInt(count($this->blobs));
foreach($this->blobs as $blob){
$this->putLLong($blob->getHash());
$this->putString($blob->getPayload());
}
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleClientCacheMissResponse($this);
}
}

View File

@@ -0,0 +1,60 @@
<?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\handler\PacketHandler;
class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_STATUS_PACKET;
/** @var bool */
private $enabled;
public static function create(bool $enabled) : self{
$result = new self;
$result->enabled = $enabled;
return $result;
}
/**
* @return bool
*/
public function isEnabled() : bool{
return $this->enabled;
}
protected function decodePayload() : void{
$this->enabled = $this->getBool();
}
protected function encodePayload() : void{
$this->putBool($this->enabled);
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleClientCacheStatus($this);
}
}

View File

@@ -59,6 +59,10 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{
public $name;
/** @var bool */
public $shouldTrackOutput;
/** @var int */
public $tickDelay;
/** @var bool */
public $executeOnFirstTick;
protected function decodePayload() : void{
$this->isBlock = $this->getBool();
@@ -78,6 +82,8 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{
$this->name = $this->getString();
$this->shouldTrackOutput = $this->getBool();
$this->tickDelay = $this->getLInt();
$this->executeOnFirstTick = $this->getBool();
}
protected function encodePayload() : void{
@@ -97,6 +103,8 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{
$this->putString($this->name);
$this->putBool($this->shouldTrackOutput);
$this->putLInt($this->tickDelay);
$this->putBool($this->executeOnFirstTick);
}
public function handle(PacketHandler $handler) : bool{

View File

@@ -34,6 +34,9 @@ use pocketmine\item\ItemFactory;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\serializer\NetworkBinaryStream;
#ifndef COMPILE
use pocketmine\utils\Binary;
#endif
use function count;
use function str_repeat;
@@ -67,11 +70,13 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
case self::ENTRY_SHAPELESS:
case self::ENTRY_SHULKER_BOX:
case self::ENTRY_SHAPELESS_CHEMISTRY:
$entry["recipe_id"] = $this->getString();
$ingredientCount = $this->getUnsignedVarInt();
/** @var Item */
$entry["input"] = [];
for($j = 0; $j < $ingredientCount; ++$j){
$entry["input"][] = $this->getSlot();
$entry["input"][] = $in = $this->getRecipeIngredient();
$in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1
}
$resultCount = $this->getUnsignedVarInt();
$entry["output"] = [];
@@ -80,16 +85,19 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}
$entry["uuid"] = $this->getUUID()->toString();
$entry["block"] = $this->getString();
$entry["priority"] = $this->getVarInt();
break;
case self::ENTRY_SHAPED:
case self::ENTRY_SHAPED_CHEMISTRY:
$entry["recipe_id"] = $this->getString();
$entry["width"] = $this->getVarInt();
$entry["height"] = $this->getVarInt();
$count = $entry["width"] * $entry["height"];
$entry["input"] = [];
for($j = 0; $j < $count; ++$j){
$entry["input"][] = $this->getSlot();
$entry["input"][] = $in = $this->getRecipeIngredient();
$in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system
}
$resultCount = $this->getUnsignedVarInt();
$entry["output"] = [];
@@ -98,6 +106,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}
$entry["uuid"] = $this->getUUID()->toString();
$entry["block"] = $this->getString();
$entry["priority"] = $this->getVarInt();
break;
case self::ENTRY_FURNACE:
@@ -115,7 +124,10 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}catch(\InvalidArgumentException $e){
throw new BadPacketException($e->getMessage(), 0, $e);
}
$entry["output"] = $this->getSlot();
$entry["output"] = $out = $this->getSlot();
if($out->getMeta() === 0x7fff){
$entry["output"] = ItemFactory::get($out->getId(), 0); //TODO HACK: some 1.12 furnace recipe outputs have wildcard damage values
}
$entry["block"] = $this->getString();
break;
@@ -130,11 +142,11 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$this->getBool(); //cleanRecipes
}
private static function writeEntry($entry, NetworkBinaryStream $stream) : int{
private static function writeEntry($entry, NetworkBinaryStream $stream, int $pos) : int{
if($entry instanceof ShapelessRecipe){
return self::writeShapelessRecipe($entry, $stream);
return self::writeShapelessRecipe($entry, $stream, $pos);
}elseif($entry instanceof ShapedRecipe){
return self::writeShapedRecipe($entry, $stream);
return self::writeShapedRecipe($entry, $stream, $pos);
}elseif($entry instanceof FurnaceRecipe){
return self::writeFurnaceRecipe($entry, $stream);
}
@@ -143,10 +155,11 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
return -1;
}
private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream) : int{
private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream, int $pos) : int{
$stream->putString(Binary::writeInt($pos)); //some kind of recipe ID, doesn't matter what it is as long as it's unique
$stream->putUnsignedVarInt($recipe->getIngredientCount());
foreach($recipe->getIngredientList() as $item){
$stream->putSlot($item);
$stream->putRecipeIngredient($item);
}
$results = $recipe->getResults();
@@ -157,17 +170,19 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$stream->put(str_repeat("\x00", 16)); //Null UUID
$stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks)
$stream->putVarInt(50); //TODO: priority
return CraftingDataPacket::ENTRY_SHAPELESS;
}
private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream) : int{
private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream, int $pos) : int{
$stream->putString(Binary::writeInt($pos)); //some kind of recipe ID, doesn't matter what it is as long as it's unique
$stream->putVarInt($recipe->getWidth());
$stream->putVarInt($recipe->getHeight());
for($z = 0; $z < $recipe->getHeight(); ++$z){
for($x = 0; $x < $recipe->getWidth(); ++$x){
$stream->putSlot($recipe->getIngredient($x, $z));
$stream->putRecipeIngredient($recipe->getIngredient($x, $z));
}
}
@@ -179,6 +194,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$stream->put(str_repeat("\x00", 16)); //Null UUID
$stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks)
$stream->putVarInt(50); //TODO: priority
return CraftingDataPacket::ENTRY_SHAPED;
}
@@ -211,8 +227,9 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$this->putUnsignedVarInt(count($this->entries));
$writer = new NetworkBinaryStream();
$counter = 0;
foreach($this->entries as $d){
$entryType = self::writeEntry($d, $writer);
$entryType = self::writeEntry($d, $writer, $counter++);
if($entryType >= 0){
$this->putVarInt($entryType);
$this->put($writer->getBuffer());

View File

@@ -0,0 +1,145 @@
<?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\handler\PacketHandler;
use function count;
class LevelChunkPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::LEVEL_CHUNK_PACKET;
/** @var int */
private $chunkX;
/** @var int */
private $chunkZ;
/** @var int */
private $subChunkCount;
/** @var bool */
private $cacheEnabled;
/** @var int[] */
private $usedBlobHashes = [];
/** @var string */
private $extraPayload;
public static function withoutCache(int $chunkX, int $chunkZ, int $subChunkCount, string $payload) : self{
$result = new self;
$result->chunkX = $chunkX;
$result->chunkZ = $chunkZ;
$result->subChunkCount = $subChunkCount;
$result->extraPayload = $payload;
$result->cacheEnabled = false;
return $result;
}
public static function withCache(int $chunkX, int $chunkZ, int $subChunkCount, array $usedBlobHashes, string $extraPayload) : self{
(static function(int ...$hashes){})($usedBlobHashes);
$result = new self;
$result->chunkX = $chunkX;
$result->chunkZ = $chunkZ;
$result->subChunkCount = $subChunkCount;
$result->extraPayload = $extraPayload;
$result->cacheEnabled = true;
$result->usedBlobHashes = $usedBlobHashes;
return $result;
}
/**
* @return int
*/
public function getChunkX() : int{
return $this->chunkX;
}
/**
* @return int
*/
public function getChunkZ() : int{
return $this->chunkZ;
}
/**
* @return int
*/
public function getSubChunkCount() : int{
return $this->subChunkCount;
}
/**
* @return bool
*/
public function isCacheEnabled() : bool{
return $this->cacheEnabled;
}
/**
* @return int[]
*/
public function getUsedBlobHashes() : array{
return $this->usedBlobHashes;
}
/**
* @return string
*/
public function getExtraPayload() : string{
return $this->extraPayload;
}
protected function decodePayload() : void{
$this->chunkX = $this->getVarInt();
$this->chunkZ = $this->getVarInt();
$this->subChunkCount = $this->getUnsignedVarInt();
$this->cacheEnabled = $this->getBool();
if($this->cacheEnabled){
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$this->usedBlobHashes[] = $this->getLLong();
}
}
$this->extraPayload = $this->getString();
}
protected function encodePayload() : void{
$this->putVarInt($this->chunkX);
$this->putVarInt($this->chunkZ);
$this->putUnsignedVarInt($this->subChunkCount);
$this->putBool($this->cacheEnabled);
if($this->cacheEnabled){
$this->putUnsignedVarInt(count($this->usedBlobHashes));
foreach($this->usedBlobHashes as $hash){
$this->putLLong($hash);
}
}
$this->putString($this->extraPayload);
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleLevelChunk($this);
}
}

View File

@@ -25,40 +25,51 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\serializer\NetworkNbtSerializer;
class FullChunkDataPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::FULL_CHUNK_DATA_PACKET;
class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_GENERIC_PACKET;
/** @var int */
public $chunkX;
/** @var int */
public $chunkZ;
/** @var string */
public $data;
private $eventId;
/** @var string network-format NBT */
private $eventData;
public static function create(int $chunkX, int $chunkZ, string $payload) : self{
public static function create(int $eventId, CompoundTag $data) : self{
$result = new self;
$result->chunkX = $chunkX;
$result->chunkZ = $chunkZ;
$result->data = $payload;
$result->eventId = $eventId;
$result->eventData = (new NetworkNbtSerializer())->write(new TreeRoot($data));
return $result;
}
/**
* @return int
*/
public function getEventId() : int{
return $this->eventId;
}
/**
* @return string
*/
public function getEventData() : string{
return $this->eventData;
}
protected function decodePayload() : void{
$this->chunkX = $this->getVarInt();
$this->chunkZ = $this->getVarInt();
$this->data = $this->getString();
$this->eventId = $this->getVarInt();
$this->eventData = $this->getRemaining();
}
protected function encodePayload() : void{
$this->putVarInt($this->chunkX);
$this->putVarInt($this->chunkZ);
$this->putString($this->data);
$this->putVarInt($this->eventId);
$this->put($this->eventData);
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleFullChunkData($this);
return $handler->handleLevelEventGeneric($this);
}
}

View File

@@ -29,8 +29,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\handler\PacketHandler;
class MoveEntityAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_ABSOLUTE_PACKET;
class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_ABSOLUTE_PACKET;
public const FLAG_GROUND = 0x01;
public const FLAG_TELEPORT = 0x02;
@@ -67,6 +67,6 @@ class MoveEntityAbsolutePacket extends DataPacket implements ClientboundPacket,
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleMoveEntityAbsolute($this);
return $handler->handleMoveActorAbsolute($this);
}
}

View File

@@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\utils\BinaryDataException;
class MoveEntityDeltaPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_DELTA_PACKET;
class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_DELTA_PACKET;
public const FLAG_HAS_X = 0x01;
public const FLAG_HAS_Y = 0x02;
@@ -116,6 +116,6 @@ class MoveEntityDeltaPacket extends DataPacket implements ClientboundPacket{
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleMoveEntityDelta($this);
return $handler->handleMoveActorDelta($this);
}
}

View File

@@ -45,11 +45,11 @@ class PacketPool{
static::registerPacket(new SetTimePacket());
static::registerPacket(new StartGamePacket());
static::registerPacket(new AddPlayerPacket());
static::registerPacket(new AddEntityPacket());
static::registerPacket(new RemoveEntityPacket());
static::registerPacket(new AddItemEntityPacket());
static::registerPacket(new TakeItemEntityPacket());
static::registerPacket(new MoveEntityAbsolutePacket());
static::registerPacket(new AddActorPacket());
static::registerPacket(new RemoveActorPacket());
static::registerPacket(new AddItemActorPacket());
static::registerPacket(new TakeItemActorPacket());
static::registerPacket(new MoveActorAbsolutePacket());
static::registerPacket(new MovePlayerPacket());
static::registerPacket(new RiderJumpPacket());
static::registerPacket(new UpdateBlockPacket());
@@ -58,7 +58,7 @@ class PacketPool{
static::registerPacket(new LevelSoundEventPacketV1());
static::registerPacket(new LevelEventPacket());
static::registerPacket(new BlockEventPacket());
static::registerPacket(new EntityEventPacket());
static::registerPacket(new ActorEventPacket());
static::registerPacket(new MobEffectPacket());
static::registerPacket(new UpdateAttributesPacket());
static::registerPacket(new InventoryTransactionPacket());
@@ -66,13 +66,13 @@ class PacketPool{
static::registerPacket(new MobArmorEquipmentPacket());
static::registerPacket(new InteractPacket());
static::registerPacket(new BlockPickRequestPacket());
static::registerPacket(new EntityPickRequestPacket());
static::registerPacket(new ActorPickRequestPacket());
static::registerPacket(new PlayerActionPacket());
static::registerPacket(new EntityFallPacket());
static::registerPacket(new ActorFallPacket());
static::registerPacket(new HurtArmorPacket());
static::registerPacket(new SetEntityDataPacket());
static::registerPacket(new SetEntityMotionPacket());
static::registerPacket(new SetEntityLinkPacket());
static::registerPacket(new SetActorDataPacket());
static::registerPacket(new SetActorMotionPacket());
static::registerPacket(new SetActorLinkPacket());
static::registerPacket(new SetHealthPacket());
static::registerPacket(new SetSpawnPositionPacket());
static::registerPacket(new AnimatePacket());
@@ -87,9 +87,9 @@ class PacketPool{
static::registerPacket(new CraftingEventPacket());
static::registerPacket(new GuiDataPickItemPacket());
static::registerPacket(new AdventureSettingsPacket());
static::registerPacket(new BlockEntityDataPacket());
static::registerPacket(new BlockActorDataPacket());
static::registerPacket(new PlayerInputPacket());
static::registerPacket(new FullChunkDataPacket());
static::registerPacket(new LevelChunkPacket());
static::registerPacket(new SetCommandsEnabledPacket());
static::registerPacket(new SetDifficultyPacket());
static::registerPacket(new ChangeDimensionPacket());
@@ -142,22 +142,31 @@ class PacketPool{
static::registerPacket(new SetScorePacket());
static::registerPacket(new LabTablePacket());
static::registerPacket(new UpdateBlockSyncedPacket());
static::registerPacket(new MoveEntityDeltaPacket());
static::registerPacket(new MoveActorDeltaPacket());
static::registerPacket(new SetScoreboardIdentityPacket());
static::registerPacket(new SetLocalPlayerAsInitializedPacket());
static::registerPacket(new UpdateSoftEnumPacket());
static::registerPacket(new NetworkStackLatencyPacket());
static::registerPacket(new ScriptCustomEventPacket());
static::registerPacket(new SpawnParticleEffectPacket());
static::registerPacket(new AvailableEntityIdentifiersPacket());
static::registerPacket(new AvailableActorIdentifiersPacket());
static::registerPacket(new LevelSoundEventPacketV2());
static::registerPacket(new NetworkChunkPublisherUpdatePacket());
static::registerPacket(new BiomeDefinitionListPacket());
static::registerPacket(new LevelSoundEventPacket());
static::registerPacket(new LevelEventGenericPacket());
static::registerPacket(new LecternUpdatePacket());
static::registerPacket(new VideoStreamConnectPacket());
static::registerPacket(new MapCreateLockedCopyPacket());
static::registerPacket(new AddEntityPacket());
static::registerPacket(new RemoveEntityPacket());
static::registerPacket(new ClientCacheStatusPacket());
static::registerPacket(new OnScreenTextureAnimationPacket());
static::registerPacket(new MapCreateLockedCopyPacket());
static::registerPacket(new StructureTemplateDataExportRequestPacket());
static::registerPacket(new StructureTemplateDataExportResponsePacket());
static::registerPacket(new UpdateBlockPropertiesPacket());
static::registerPacket(new ClientCacheBlobStatusPacket());
static::registerPacket(new ClientCacheMissResponsePacket());
}
/**

View File

@@ -39,15 +39,15 @@ interface ProtocolInfo{
/**
* Actual Minecraft: PE protocol version
*/
public const CURRENT_PROTOCOL = 354;
public const CURRENT_PROTOCOL = 361;
/**
* Current Minecraft PE version reported by the server. This is usually the earliest currently supported version.
*/
public const MINECRAFT_VERSION = 'v1.11.0';
public const MINECRAFT_VERSION = 'v1.12.0';
/**
* Version number sent to clients in ping responses.
*/
public const MINECRAFT_VERSION_NETWORK = '1.11.0';
public const MINECRAFT_VERSION_NETWORK = '1.12.0';
public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02;
@@ -61,12 +61,12 @@ interface ProtocolInfo{
public const SET_TIME_PACKET = 0x0a;
public const START_GAME_PACKET = 0x0b;
public const ADD_PLAYER_PACKET = 0x0c;
public const ADD_ENTITY_PACKET = 0x0d;
public const REMOVE_ENTITY_PACKET = 0x0e;
public const ADD_ITEM_ENTITY_PACKET = 0x0f;
public const ADD_ACTOR_PACKET = 0x0d;
public const REMOVE_ACTOR_PACKET = 0x0e;
public const ADD_ITEM_ACTOR_PACKET = 0x0f;
public const TAKE_ITEM_ENTITY_PACKET = 0x11;
public const MOVE_ENTITY_ABSOLUTE_PACKET = 0x12;
public const TAKE_ITEM_ACTOR_PACKET = 0x11;
public const MOVE_ACTOR_ABSOLUTE_PACKET = 0x12;
public const MOVE_PLAYER_PACKET = 0x13;
public const RIDER_JUMP_PACKET = 0x14;
public const UPDATE_BLOCK_PACKET = 0x15;
@@ -75,7 +75,7 @@ interface ProtocolInfo{
public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18;
public const LEVEL_EVENT_PACKET = 0x19;
public const BLOCK_EVENT_PACKET = 0x1a;
public const ENTITY_EVENT_PACKET = 0x1b;
public const ACTOR_EVENT_PACKET = 0x1b;
public const MOB_EFFECT_PACKET = 0x1c;
public const UPDATE_ATTRIBUTES_PACKET = 0x1d;
public const INVENTORY_TRANSACTION_PACKET = 0x1e;
@@ -83,13 +83,13 @@ interface ProtocolInfo{
public const MOB_ARMOR_EQUIPMENT_PACKET = 0x20;
public const INTERACT_PACKET = 0x21;
public const BLOCK_PICK_REQUEST_PACKET = 0x22;
public const ENTITY_PICK_REQUEST_PACKET = 0x23;
public const ACTOR_PICK_REQUEST_PACKET = 0x23;
public const PLAYER_ACTION_PACKET = 0x24;
public const ENTITY_FALL_PACKET = 0x25;
public const ACTOR_FALL_PACKET = 0x25;
public const HURT_ARMOR_PACKET = 0x26;
public const SET_ENTITY_DATA_PACKET = 0x27;
public const SET_ENTITY_MOTION_PACKET = 0x28;
public const SET_ENTITY_LINK_PACKET = 0x29;
public const SET_ACTOR_DATA_PACKET = 0x27;
public const SET_ACTOR_MOTION_PACKET = 0x28;
public const SET_ACTOR_LINK_PACKET = 0x29;
public const SET_HEALTH_PACKET = 0x2a;
public const SET_SPAWN_POSITION_PACKET = 0x2b;
public const ANIMATE_PACKET = 0x2c;
@@ -104,9 +104,9 @@ interface ProtocolInfo{
public const CRAFTING_EVENT_PACKET = 0x35;
public const GUI_DATA_PICK_ITEM_PACKET = 0x36;
public const ADVENTURE_SETTINGS_PACKET = 0x37;
public const BLOCK_ENTITY_DATA_PACKET = 0x38;
public const BLOCK_ACTOR_DATA_PACKET = 0x38;
public const PLAYER_INPUT_PACKET = 0x39;
public const FULL_CHUNK_DATA_PACKET = 0x3a;
public const LEVEL_CHUNK_PACKET = 0x3a;
public const SET_COMMANDS_ENABLED_PACKET = 0x3b;
public const SET_DIFFICULTY_PACKET = 0x3c;
public const CHANGE_DIMENSION_PACKET = 0x3d;
@@ -159,7 +159,7 @@ interface ProtocolInfo{
public const SET_SCORE_PACKET = 0x6c;
public const LAB_TABLE_PACKET = 0x6d;
public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e;
public const MOVE_ENTITY_DELTA_PACKET = 0x6f;
public const MOVE_ACTOR_DELTA_PACKET = 0x6f;
public const SET_SCOREBOARD_IDENTITY_PACKET = 0x70;
public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71;
public const UPDATE_SOFT_ENUM_PACKET = 0x72;
@@ -167,14 +167,23 @@ interface ProtocolInfo{
public const SCRIPT_CUSTOM_EVENT_PACKET = 0x75;
public const SPAWN_PARTICLE_EFFECT_PACKET = 0x76;
public const AVAILABLE_ENTITY_IDENTIFIERS_PACKET = 0x77;
public const AVAILABLE_ACTOR_IDENTIFIERS_PACKET = 0x77;
public const LEVEL_SOUND_EVENT_PACKET_V2 = 0x78;
public const NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET = 0x79;
public const BIOME_DEFINITION_LIST_PACKET = 0x7a;
public const LEVEL_SOUND_EVENT_PACKET = 0x7b;
public const LECTERN_UPDATE_PACKET = 0x7c;
public const VIDEO_STREAM_CONNECT_PACKET = 0x7d;
public const MAP_CREATE_LOCKED_COPY_PACKET = 0x7e;
public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x7f;
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;
public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x82;
public const MAP_CREATE_LOCKED_COPY_PACKET = 0x83;
public const STRUCTURE_TEMPLATE_DATA_EXPORT_REQUEST_PACKET = 0x84;
public const STRUCTURE_TEMPLATE_DATA_EXPORT_RESPONSE_PACKET = 0x85;
public const UPDATE_BLOCK_PROPERTIES_PACKET = 0x86;
public const CLIENT_CACHE_BLOB_STATUS_PACKET = 0x87;
public const CLIENT_CACHE_MISS_RESPONSE_PACKET = 0x88;
}

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;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\handler\PacketHandler;
class RemoveActorPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::REMOVE_ACTOR_PACKET;
/** @var int */
public $entityUniqueId;
public static function create(int $entityUniqueId) : self{
$result = new self;
$result->entityUniqueId = $entityUniqueId;
return $result;
}
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
}
protected function encodePayload() : void{
$this->putEntityUniqueId($this->entityUniqueId);
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleRemoveActor($this);
}
}

View File

@@ -25,27 +25,33 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\handler\PacketHandler;
class RemoveEntityPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET;
/** @var int */
public $entityUniqueId;
private $uvarint1;
public static function create(int $entityUniqueId) : self{
public static function create(int $uvarint1) : self{
$result = new self;
$result->entityUniqueId = $entityUniqueId;
$result->uvarint1 = $uvarint1;
return $result;
}
/**
* @return int
*/
public function getUvarint1() : int{
return $this->uvarint1;
}
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
$this->uvarint1 = $this->getUnsignedVarInt();
}
protected function encodePayload() : void{
$this->putEntityUniqueId($this->entityUniqueId);
$this->putUnsignedVarInt($this->uvarint1);
}
public function handle(PacketHandler $handler) : bool{

View File

@@ -42,6 +42,10 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket
public $compressedPackSize;
/** @var string */
public $sha256;
/** @var bool */
public $isPremium = false;
/** @var int */
public $packType = 0; //TODO: check the values for this
public static function create(string $packId, int $maxChunkSize, int $chunkCount, int $compressedPackSize, string $sha256sum) : self{
$result = new self;
@@ -59,6 +63,8 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket
$this->chunkCount = $this->getLInt();
$this->compressedPackSize = $this->getLLong();
$this->sha256 = $this->getString();
$this->isPremium = $this->getBool();
$this->packType = $this->getByte();
}
protected function encodePayload() : void{
@@ -67,6 +73,8 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket
$this->putLInt($this->chunkCount);
$this->putLLong($this->compressedPackSize);
$this->putString($this->sha256);
$this->putBool($this->isPremium);
$this->putByte($this->packType);
}
public function handle(PacketHandler $handler) : bool{

View File

@@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
class SetEntityDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound
public const NETWORK_ID = ProtocolInfo::SET_ENTITY_DATA_PACKET;
class SetActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound
public const NETWORK_ID = ProtocolInfo::SET_ACTOR_DATA_PACKET;
/** @var int */
public $entityRuntimeId;
@@ -54,6 +54,6 @@ class SetEntityDataPacket extends DataPacket implements ClientboundPacket, Serve
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleSetEntityData($this);
return $handler->handleSetActorData($this);
}
}

View File

@@ -29,8 +29,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\protocol\types\EntityLink;
class SetEntityLinkPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::SET_ENTITY_LINK_PACKET;
class SetActorLinkPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::SET_ACTOR_LINK_PACKET;
/** @var EntityLink */
public $link;
@@ -44,6 +44,6 @@ class SetEntityLinkPacket extends DataPacket implements ClientboundPacket{
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleSetEntityLink($this);
return $handler->handleSetActorLink($this);
}
}

View File

@@ -32,8 +32,8 @@ use pocketmine\network\mcpe\handler\PacketHandler;
/**
* TODO: This packet is (erroneously) sent to the server when the client is riding a vehicle.
*/
class SetEntityMotionPacket extends DataPacket implements ClientboundPacket, GarbageServerboundPacket{
public const NETWORK_ID = ProtocolInfo::SET_ENTITY_MOTION_PACKET;
class SetActorMotionPacket extends DataPacket implements ClientboundPacket, GarbageServerboundPacket{
public const NETWORK_ID = ProtocolInfo::SET_ACTOR_MOTION_PACKET;
/** @var int */
public $entityRuntimeId;
@@ -58,6 +58,6 @@ class SetEntityMotionPacket extends DataPacket implements ClientboundPacket, Gar
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleSetEntityMotion($this);
return $handler->handleSetActorMotion($this);
}
}

View File

@@ -32,12 +32,17 @@ use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\network\mcpe\serializer\NetworkBinaryStream;
use function count;
use function file_get_contents;
use function json_decode;
use const pocketmine\RESOURCE_PATH;
class StartGamePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET;
/** @var string|null */
private static $runtimeIdTableCache;
private static $blockTableCache = null;
/** @var string|null */
private static $itemTableCache = null;
/** @var int */
public $entityUniqueId;
@@ -122,6 +127,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public $isFromWorldTemplate = false;
/** @var bool */
public $isWorldTemplateOptionLocked = false;
/** @var bool */
public $onlySpawnV1Villagers = false;
/** @var string */
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
@@ -138,11 +145,10 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
/** @var string */
public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort
/** @var bool */
public $onlySpawnV1Villagers = false;
/** @var array|null each entry must have a "name" (string) and "data" (int16) element */
public $runtimeIdTable = null;
/** @var array|null ["name" (string), "data" (int16), "legacy_id" (int16)] */
public $blockTable = null;
/** @var array|null string (name) => int16 (legacyID) */
public $itemTable = null;
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
@@ -185,6 +191,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->useMsaGamertagsOnly = $this->getBool();
$this->isFromWorldTemplate = $this->getBool();
$this->isWorldTemplateOptionLocked = $this->getBool();
$this->onlySpawnV1Villagers = $this->getBool();
$this->levelId = $this->getString();
$this->worldName = $this->getString();
@@ -194,18 +201,23 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->enchantmentSeed = $this->getVarInt();
$count = $this->getUnsignedVarInt();
$table = [];
for($i = 0; $i < $count; ++$i){
$this->blockTable = [];
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$id = $this->getString();
$data = $this->getLShort();
$data = $this->getSignedLShort();
$unknown = $this->getSignedLShort();
$table[$i] = ["name" => $id, "data" => $data];
$this->blockTable[$i] = ["name" => $id, "data" => $data, "legacy_id" => $unknown];
}
$this->itemTable = [];
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$id = $this->getString();
$legacyId = $this->getSignedLShort();
$this->itemTable[$id] = $legacyId;
}
$this->runtimeIdTable = $table;
$this->multiplayerCorrelationId = $this->getString();
$this->onlySpawnV1Villagers = $this->getBool();
}
protected function encodePayload() : void{
@@ -249,6 +261,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->putBool($this->useMsaGamertagsOnly);
$this->putBool($this->isFromWorldTemplate);
$this->putBool($this->isWorldTemplateOptionLocked);
$this->putBool($this->onlySpawnV1Villagers);
$this->putString($this->levelId);
$this->putString($this->worldName);
@@ -258,18 +271,25 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->putVarInt($this->enchantmentSeed);
if($this->runtimeIdTable === null){
if(self::$runtimeIdTableCache === null){
if($this->blockTable === null){
if(self::$blockTableCache === null){
//this is a really nasty hack, but it'll do for now
self::$runtimeIdTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates());
self::$blockTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates());
}
$this->put(self::$runtimeIdTableCache);
$this->put(self::$blockTableCache);
}else{
$this->put(self::serializeBlockTable($this->runtimeIdTable));
$this->put(self::serializeBlockTable($this->blockTable));
}
if($this->itemTable === null){
if(self::$itemTableCache === null){
self::$itemTableCache = self::serializeItemTable(json_decode(file_get_contents(RESOURCE_PATH . '/vanilla/item_id_map.json'), true));
}
$this->put(self::$itemTableCache);
}else{
$this->put(self::serializeItemTable($this->itemTable));
}
$this->putString($this->multiplayerCorrelationId);
$this->putBool($this->onlySpawnV1Villagers);
}
private static function serializeBlockTable(array $table) : string{
@@ -278,6 +298,17 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
foreach($table as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
$stream->putLShort($v["legacy_id"]);
}
return $stream->getBuffer();
}
private static function serializeItemTable(array $table) : string{
$stream = new NetworkBinaryStream();
$stream->putUnsignedVarInt(count($table));
foreach($table as $name => $legacyId){
$stream->putString($name);
$stream->putLShort($legacyId);
}
return $stream->getBuffer();
}

View File

@@ -0,0 +1,44 @@
<?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\handler\PacketHandler;
class StructureTemplateDataExportRequestPacket extends DataPacket implements ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_EXPORT_REQUEST_PACKET;
protected function decodePayload() : void{
//TODO
}
protected function encodePayload() : void{
//TODO
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleStructureTemplateDataExportRequest($this);
}
}

View File

@@ -0,0 +1,44 @@
<?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\handler\PacketHandler;
class StructureTemplateDataExportResponsePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_EXPORT_RESPONSE_PACKET;
protected function decodePayload() : void{
//TODO
}
protected function encodePayload() : void{
//TODO
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleStructureTemplateDataExportResponse($this);
}
}

View File

@@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ENTITY_PACKET;
class TakeItemActorPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ACTOR_PACKET;
/** @var int */
public $target;
@@ -54,6 +54,6 @@ class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleTakeItemEntity($this);
return $handler->handleTakeItemActor($this);
}
}

View File

@@ -0,0 +1,56 @@
<?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\nbt\tag\CompoundTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\serializer\NetworkNbtSerializer;
class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PROPERTIES_PACKET;
/** @var string */
private $nbt;
public static function create(CompoundTag $data) : self{
$result = new self;
$result->nbt = (new NetworkNbtSerializer())->write(new TreeRoot($data));
return $result;
}
protected function decodePayload() : void{
$this->nbt = $this->getRemaining();
}
protected function encodePayload() : void{
$this->put($this->nbt);
}
public function handle(PacketHandler $handler) : bool{
return $handler->handleUpdateBlockProperties($this);
}
}

View File

@@ -39,17 +39,25 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{
public $frameSendFrequency;
/** @var int */
public $action;
/** @var int */
public $resolutionX;
/** @var int */
public $resolutionY;
protected function decodePayload() : void{
$this->serverUri = $this->getString();
$this->frameSendFrequency = $this->getLFloat();
$this->action = $this->getByte();
$this->resolutionX = $this->getLInt();
$this->resolutionY = $this->getLInt();
}
protected function encodePayload() : void{
$this->putString($this->serverUri);
$this->putLFloat($this->frameSendFrequency);
$this->putByte($this->action);
$this->putLInt($this->resolutionX);
$this->putLInt($this->resolutionY);
}
public function handle(PacketHandler $handler) : bool{

View File

@@ -0,0 +1,56 @@
<?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;
class ChunkCacheBlob{
/** @var int */
private $hash;
/** @var string */
private $payload;
/**
* ChunkCacheBlob constructor.
*
* @param int $hash
* @param string $payload
*/
public function __construct(int $hash, string $payload){
$this->hash = $hash;
$this->payload = $payload;
}
/**
* @return int
*/
public function getHash() : int{
return $this->hash;
}
/**
* @return string
*/
public function getPayload() : string{
return $this->payload;
}
}

View File

@@ -76,68 +76,74 @@ final class EntityMetadataProperties{
public const LEAD_HOLDER_EID = 37; //long
public const SCALE = 38; //float
public const HAS_NPC_COMPONENT = 39; //byte (???)
public const SKIN_ID = 40; //string
public const NPC_SKIN_ID = 41; //string
public const URL_TAG = 42; //string
public const MAX_AIR = 43; //short
public const MARK_VARIANT = 44; //int
public const CONTAINER_TYPE = 45; //byte (ContainerComponent)
public const CONTAINER_BASE_SIZE = 46; //int (ContainerComponent)
public const CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 47; //int (used for llamas, inventory size is baseSize + thisProp * strength)
public const BLOCK_TARGET = 48; //block coords (ender crystal)
public const WITHER_INVULNERABLE_TICKS = 49; //int
public const WITHER_TARGET_1 = 50; //long
public const WITHER_TARGET_2 = 51; //long
public const WITHER_TARGET_3 = 52; //long
/* 53 (short) */
public const BOUNDING_BOX_WIDTH = 54; //float
public const BOUNDING_BOX_HEIGHT = 55; //float
public const FUSE_LENGTH = 56; //int
public const RIDER_SEAT_POSITION = 57; //vector3f
public const RIDER_ROTATION_LOCKED = 58; //byte
public const RIDER_MAX_ROTATION = 59; //float
public const RIDER_MIN_ROTATION = 60; //float
public const AREA_EFFECT_CLOUD_RADIUS = 61; //float
public const AREA_EFFECT_CLOUD_WAITING = 62; //int
public const AREA_EFFECT_CLOUD_PARTICLE_ID = 63; //int
/* 64 (int) shulker-related */
public const SHULKER_ATTACH_FACE = 65; //byte
/* 66 (short) shulker-related */
public const SHULKER_ATTACH_POS = 67; //block coords
public const TRADING_PLAYER_EID = 68; //long
public const NPC_SKIN_INDEX = 40; //string
public const NPC_ACTIONS = 41; //string (maybe JSON blob?)
public const MAX_AIR = 42; //short
public const MARK_VARIANT = 43; //int
public const CONTAINER_TYPE = 44; //byte (ContainerComponent)
public const CONTAINER_BASE_SIZE = 45; //int (ContainerComponent)
public const CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 46; //int (used for llamas, inventory size is baseSize + thisProp * strength)
public const BLOCK_TARGET = 47; //block coords (ender crystal)
public const WITHER_INVULNERABLE_TICKS = 48; //int
public const WITHER_TARGET_1 = 49; //long
public const WITHER_TARGET_2 = 50; //long
public const WITHER_TARGET_3 = 51; //long
/* 52 (short) */
public const BOUNDING_BOX_WIDTH = 53; //float
public const BOUNDING_BOX_HEIGHT = 54; //float
public const FUSE_LENGTH = 55; //int
public const RIDER_SEAT_POSITION = 56; //vector3f
public const RIDER_ROTATION_LOCKED = 57; //byte
public const RIDER_MAX_ROTATION = 58; //float
public const RIDER_MIN_ROTATION = 59; //float
public const AREA_EFFECT_CLOUD_RADIUS = 60; //float
public const AREA_EFFECT_CLOUD_WAITING = 61; //int
public const AREA_EFFECT_CLOUD_PARTICLE_ID = 62; //int
/* 63 (int) shulker-related */
public const SHULKER_ATTACH_FACE = 64; //byte
/* 65 (short) shulker-related */
public const SHULKER_ATTACH_POS = 66; //block coords
public const TRADING_PLAYER_EID = 67; //long
/* 70 (byte) command-block */
public const COMMAND_BLOCK_COMMAND = 71; //string
public const COMMAND_BLOCK_LAST_OUTPUT = 72; //string
public const COMMAND_BLOCK_TRACK_OUTPUT = 73; //byte
public const CONTROLLING_RIDER_SEAT_NUMBER = 74; //byte
public const STRENGTH = 75; //int
public const MAX_STRENGTH = 76; //int
/* 77 (int) */
public const LIMITED_LIFE = 78;
public const ARMOR_STAND_POSE_INDEX = 79; //int
public const ENDER_CRYSTAL_TIME_OFFSET = 80; //int
public const ALWAYS_SHOW_NAMETAG = 81; //byte: -1 = default, 0 = only when looked at, 1 = always
public const COLOR_2 = 82; //byte
/* 83 (unknown) */
public const SCORE_TAG = 84; //string
public const BALLOON_ATTACHED_ENTITY = 85; //int64, entity unique ID of owner
public const PUFFERFISH_SIZE = 86; //byte
public const BOAT_BUBBLE_TIME = 87; //int (time in bubble column)
public const PLAYER_AGENT_EID = 88; //long
/* 89 (float) related to panda sitting
* 90 (float) related to panda sitting */
public const EAT_COUNTER = 91; //int (used by pandas)
public const FLAGS2 = 92; //long (extended data flags)
/* 93 (float) related to panda lying down
* 94 (float) related to panda lying down */
public const AREA_EFFECT_CLOUD_DURATION = 95; //int
public const AREA_EFFECT_CLOUD_SPAWN_TIME = 96; //int
public const AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 97; //float, usually negative
public const AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 98; //float
public const AREA_EFFECT_CLOUD_PICKUP_COUNT = 99; //int
public const INTERACTIVE_TAG = 100; //string (button text)
public const TRADE_TIER = 101; //int
public const MAX_TRADE_TIER = 102; //int
public const TRADE_XP = 103; //int
/* 69 (byte) command-block */
public const COMMAND_BLOCK_COMMAND = 70; //string
public const COMMAND_BLOCK_LAST_OUTPUT = 71; //string
public const COMMAND_BLOCK_TRACK_OUTPUT = 72; //byte
public const CONTROLLING_RIDER_SEAT_NUMBER = 73; //byte
public const STRENGTH = 74; //int
public const MAX_STRENGTH = 75; //int
/* 76 (int) */
public const LIMITED_LIFE = 77;
public const ARMOR_STAND_POSE_INDEX = 78; //int
public const ENDER_CRYSTAL_TIME_OFFSET = 79; //int
public const ALWAYS_SHOW_NAMETAG = 80; //byte: -1 = default, 0 = only when looked at, 1 = always
public const COLOR_2 = 81; //byte
/* 82 (unknown) */
public const SCORE_TAG = 83; //string
public const BALLOON_ATTACHED_ENTITY = 84; //int64, entity unique ID of owner
public const PUFFERFISH_SIZE = 85; //byte
public const BOAT_BUBBLE_TIME = 86; //int (time in bubble column)
public const PLAYER_AGENT_EID = 87; //long
/* 88 (float) related to panda sitting
* 89 (float) related to panda sitting */
public const EAT_COUNTER = 90; //int (used by pandas)
public const FLAGS2 = 91; //long (extended data flags)
/* 92 (float) related to panda lying down
* 93 (float) related to panda lying down */
public const AREA_EFFECT_CLOUD_DURATION = 94; //int
public const AREA_EFFECT_CLOUD_SPAWN_TIME = 95; //int
public const AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 96; //float, usually negative
public const AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 97; //float
public const AREA_EFFECT_CLOUD_PICKUP_COUNT = 98; //int
public const INTERACTIVE_TAG = 99; //string (button text)
public const TRADE_TIER = 100; //int
public const MAX_TRADE_TIER = 101; //int
public const TRADE_XP = 102; //int
public const SKIN_ID = 103; //int ???
/* 104 (int) related to wither */
public const COMMAND_BLOCK_TICK_DELAY = 105; //int
public const COMMAND_BLOCK_EXECUTE_ON_FIRST_TICK = 106; //byte
public const AMBIENT_SOUND_INTERVAL_MIN = 107; //float
public const AMBIENT_SOUND_INTERVAL_RANGE = 108; //float
public const AMBIENT_SOUND_EVENT = 109; //string
}

View File

@@ -56,9 +56,11 @@ final class RuntimeBlockMapping{
foreach($compressedTable as $prefix => $entries){
foreach($entries as $shortStringId => $states){
foreach($states as $state){
$name = "$prefix:$shortStringId";
$decompressed[] = [
"name" => "$prefix:$shortStringId",
"data" => $state
"name" => $name,
"data" => $state,
"legacy_id" => $legacyIdMap[$name]
];
}
}
@@ -66,11 +68,12 @@ final class RuntimeBlockMapping{
self::$bedrockKnownStates = self::randomizeTable($decompressed);
foreach(self::$bedrockKnownStates as $k => $obj){
//this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries
if(!isset($legacyIdMap[$obj["name"]])){
if($obj["data"] > 15){
//TODO: in 1.12 they started using data values bigger than 4 bits which we can't handle right now
continue;
}
self::registerMapping($k, $legacyIdMap[$obj["name"]], $obj["data"]);
//this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries
self::registerMapping($k, $obj["legacy_id"], $obj["data"]);
}
}

View File

@@ -28,7 +28,6 @@ use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\utils\BinaryStream;
use pocketmine\world\format\Chunk;
use function count;
use function pack;
final class ChunkSerializer{
@@ -46,8 +45,6 @@ final class ChunkSerializer{
public static function serialize(Chunk $chunk, ?string $tiles = null) : string{
$stream = new NetworkBinaryStream();
$subChunkCount = $chunk->getSubChunkSendCount();
$stream->putByte($subChunkCount);
for($y = 0; $y < $subChunkCount; ++$y){
$layers = $chunk->getSubChunk($y)->getBlockLayers();
$stream->putByte(8); //version
@@ -64,7 +61,6 @@ final class ChunkSerializer{
}
}
}
$stream->put(pack("v*", ...$chunk->getHeightMapArray()));
$stream->put($chunk->getBiomeIdArray());
$stream->putByte(0); //border block array count
//Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client.

View File

@@ -26,12 +26,14 @@ namespace pocketmine\network\mcpe\serializer;
#include <rules/DataPacket.h>
use pocketmine\entity\Attribute;
use pocketmine\item\Durable;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\ItemIds;
use pocketmine\math\Vector3;
use pocketmine\nbt\NbtDataException;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\protocol\types\CommandOriginData;
@@ -45,6 +47,9 @@ use function strlen;
class NetworkBinaryStream extends BinaryStream{
private const DAMAGE_TAG = "Damage"; //TAG_Int
private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___";
/**
* @return string
* @throws BinaryDataException
@@ -93,12 +98,10 @@ class NetworkBinaryStream extends BinaryStream{
$auxValue = $this->getVarInt();
$data = $auxValue >> 8;
if($data === 0x7fff){
$data = -1;
}
$cnt = $auxValue & 0xff;
$nbtLen = $this->getLShort();
/** @var CompoundTag|null $compound */
$compound = null;
if($nbtLen === 0xffff){
@@ -129,6 +132,21 @@ class NetworkBinaryStream extends BinaryStream{
$this->getVarLong(); //"blocking tick" (ffs mojang)
}
if($compound !== null){
if($compound->hasTag(self::DAMAGE_TAG, IntTag::class)){
$data = $compound->getInt(self::DAMAGE_TAG);
$compound->removeTag(self::DAMAGE_TAG);
if($compound->count() === 0){
$compound = null;
goto end;
}
}
if(($conflicted = $compound->getTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION)) !== null){
$compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION);
$compound->setTag(self::DAMAGE_TAG, $conflicted);
}
}
end:
try{
return ItemFactory::get($id, $data, $cnt, $compound);
}catch(\InvalidArgumentException $e){
@@ -148,10 +166,26 @@ class NetworkBinaryStream extends BinaryStream{
$auxValue = (($item->getMeta() & 0x7fff) << 8) | $item->getCount();
$this->putVarInt($auxValue);
$nbt = null;
if($item->hasNamedTag()){
$nbt = clone $item->getNamedTag();
}
if($item instanceof Durable and $item->getDamage() > 0){
if($nbt !== null){
if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){
$nbt->removeTag(self::DAMAGE_TAG);
$nbt->setTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION, $existing);
}
}else{
$nbt = new CompoundTag();
}
$nbt->setInt(self::DAMAGE_TAG, $item->getDamage());
}
if($nbt !== null){
$this->putLShort(0xffff);
$this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0
$this->put((new NetworkNbtSerializer())->write(new TreeRoot($item->getNamedTag())));
$this->put((new NetworkNbtSerializer())->write(new TreeRoot($nbt)));
}else{
$this->putLShort(0);
}
@@ -164,6 +198,29 @@ class NetworkBinaryStream extends BinaryStream{
}
}
public function getRecipeIngredient() : Item{
$id = $this->getVarInt();
if($id === 0){
return ItemFactory::get(ItemIds::AIR, 0, 0);
}
$meta = $this->getVarInt();
if($meta === 0x7fff){
$meta = -1;
}
$count = $this->getVarInt();
return ItemFactory::get($id, $meta, $count);
}
public function putRecipeIngredient(Item $item) : void{
if($item->isNull()){
$this->putVarInt(0);
}else{
$this->putVarInt($item->getId());
$this->putVarInt($item->getMeta() & 0x7fff);
$this->putVarInt($item->getCount());
}
}
/**
* Decodes entity metadata from the stream.
*

View File

@@ -84,9 +84,9 @@ use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\SetTitlePacket;
@@ -1760,7 +1760,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
if($ev->isCancelled()){
return false;
}
$this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers());
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
if($target->onAttack($this->inventory->getItemInHand(), $face, $this)){
return true;
}
@@ -1785,7 +1785,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
public function continueBreakBlock(Vector3 $pos, int $face) : void{
$block = $this->world->getBlock($pos);
$this->world->addParticle($pos, new PunchBlockParticle($block, $face));
$this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers());
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
//TODO: destroy-progress level event
}
@@ -1805,7 +1805,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
$this->doCloseInventory();
if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){
$this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers());
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
$item = $this->inventory->getItemInHand();
$oldItem = clone $item;
if($this->world->useBreakOn($pos, $item, $this, true)){
@@ -1833,7 +1833,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
$this->setUsingItem(false);
if($this->canInteract($pos->add(0.5, 0.5, 0.5), 13) and !$this->isSpectator()){
$this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers());
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
$item = $this->inventory->getItemInHand(); //this is a copy of the real item
$oldItem = clone $item;
if($this->world->useItemOn($pos, $item, $face, $clickOffset, $this, true)){
@@ -1893,7 +1893,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
if($ev->isCancelled()){
return false;
}
$this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers());
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0){
$entity->broadcastAnimation(null, AnimatePacket::ACTION_CRITICAL_HIT);
@@ -1970,7 +1970,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
* @param Item $item
*/
public function dropItem(Item $item) : void{
$this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers());
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
$this->world->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40);
}

View File

@@ -53,7 +53,7 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
@@ -902,7 +902,7 @@ class World implements ChunkManager{
$tile = $this->getTileAt($b->x, $b->y, $b->z);
if($tile instanceof Spawnable){
$packets[] = BlockEntityDataPacket::create($tile->x, $tile->y, $tile->z, $tile->getSerializedSpawnCompound());
$packets[] = BlockActorDataPacket::create($tile->x, $tile->y, $tile->z, $tile->getSerializedSpawnCompound());
}
}

View File

@@ -29,7 +29,7 @@ use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags;
use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties;
use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes;
@@ -84,7 +84,7 @@ class FloatingTextParticle implements Particle{
if($this->entityId === null){
$this->entityId = EntityFactory::nextRuntimeId();
}else{
$p[] = RemoveEntityPacket::create($this->entityId);
$p[] = RemoveActorPacket::create($this->entityId);
}
if(!$this->invisible){