diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 6040a2abf..ee58ad42e 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -874,11 +874,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function broadcastMotion() : void{ - $pk = new SetEntityMotionPacket(); - $pk->entityRuntimeId = $this->id; - $pk->motion = $this->getMotion(); - - $this->world->broadcastPacketToViewers($this, $pk); + $this->world->broadcastPacketToViewers($this, SetEntityMotionPacket::create($this->id, $this->getMotion())); } public function hasGravity() : bool{ @@ -1649,9 +1645,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $id = spl_object_id($player); if(isset($this->hasSpawned[$id])){ if($send){ - $pk = new RemoveEntityPacket(); - $pk->entityUniqueId = $this->id; - $player->sendDataPacket($pk); + $player->sendDataPacket(RemoveEntityPacket::create($this->id)); } unset($this->hasSpawned[$id]); } @@ -1778,9 +1772,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $player = [$player]; } - $pk = new SetEntityDataPacket(); - $pk->entityRuntimeId = $this->getId(); - $pk->metadata = $data ?? $this->propertyManager->getAll(); + $pk = SetEntityDataPacket::create($this->getId(), $data ?? $this->propertyManager->getAll()); foreach($player as $p){ if($p === $this){ @@ -1795,19 +1787,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ - $pk = new EntityEventPacket(); - $pk->entityRuntimeId = $this->id; - $pk->event = $eventId; - $pk->data = $eventData ?? 0; - - $this->server->broadcastPacket($players ?? $this->getViewers(), $pk); + $this->server->broadcastPacket($players ?? $this->getViewers(), EntityEventPacket::create($this->id, $eventId, $eventData ?? 0)); } public function broadcastAnimation(?array $players, int $animationId) : void{ - $pk = new AnimatePacket(); - $pk->entityRuntimeId = $this->id; - $pk->action = $animationId; - $this->server->broadcastPacket($players ?? $this->getViewers(), $pk); + $this->server->broadcastPacket($players ?? $this->getViewers(), AnimatePacket::create($this->id, $animationId)); } public function __destruct(){ diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index edca17db8..03150df89 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -829,10 +829,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ protected function sendSpawnPacket(Player $player) : void{ if(!($this instanceof Player)){ /* we don't use Server->updatePlayerListData() because that uses batches, which could cause race conditions in async compression mode */ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - $pk->entries = [PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)]; - $player->sendDataPacket($pk); + $player->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)])); } $pk = new AddPlayerPacket(); @@ -853,10 +850,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $player->getNetworkSession()->onMobArmorChange($this); if(!($this instanceof Player)){ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_REMOVE; - $pk->entries = [PlayerListEntry::createRemovalEntry($this->uuid)]; - $player->sendDataPacket($pk); + $player->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)])); } } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 0dadfdd23..d2a14732a 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -268,10 +268,7 @@ class ItemEntity extends Entity{ $player->awardAchievement("diamond"); } - $pk = new TakeItemEntityPacket(); - $pk->eid = $player->getId(); - $pk->target = $this->getId(); - $this->server->broadcastPacket($this->getViewers(), $pk); + $this->server->broadcastPacket($this->getViewers(), TakeItemEntityPacket::create($player->getId(), $this->getId())); $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 0dde2ed11..f3c6c6a2a 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -194,10 +194,7 @@ class Arrow extends Projectile{ return; } - $pk = new TakeItemEntityPacket(); - $pk->eid = $player->getId(); - $pk->target = $this->getId(); - $this->server->broadcastPacket($this->getViewers(), $pk); + $this->server->broadcastPacket($this->getViewers(), TakeItemEntityPacket::create($player->getId(), $this->getId())); $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 8a41a73a4..bc827dd76 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -40,31 +40,20 @@ abstract class ContainerInventory extends BaseInventory{ protected function onOpen(Player $who) : void{ parent::onOpen($who); - $pk = new ContainerOpenPacket(); - $pk->windowId = $who->getWindowId($this); - $pk->type = $this->getNetworkType(); + + $windowId = $who->getWindowId($this); $holder = $this->getHolder(); - - $pk->x = $pk->y = $pk->z = 0; - $pk->entityUniqueId = -1; - if($holder instanceof Entity){ - $pk->entityUniqueId = $holder->getId(); + $who->sendDataPacket(ContainerOpenPacket::entityInv($windowId, $this->getNetworkType(), $holder->getId())); }elseif($holder instanceof Vector3){ - $pk->x = $holder->getFloorX(); - $pk->y = $holder->getFloorY(); - $pk->z = $holder->getFloorZ(); + $who->sendDataPacket(ContainerOpenPacket::blockInv($windowId, $this->getNetworkType(), $holder->getFloorX(), $holder->getFloorY(), $holder->getFloorZ())); } - $who->sendDataPacket($pk); - $this->sendContents($who); } protected function onClose(Player $who) : void{ - $pk = new ContainerClosePacket(); - $pk->windowId = $who->getWindowId($this); - $who->sendDataPacket($pk); + $who->sendDataPacket(ContainerClosePacket::create($who->getWindowId($this))); parent::onClose($who); } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 8d91a5c15..4224923b7 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -133,11 +133,7 @@ class PlayerInventory extends BaseInventory{ public function sendHeldItem($target) : void{ $item = $this->getItemInHand(); - $pk = new MobEquipmentPacket(); - $pk->entityRuntimeId = $this->getHolder()->getId(); - $pk->item = $item; - $pk->inventorySlot = $pk->hotbarSlot = $this->getHeldItemIndex(); - $pk->windowId = ContainerIds::INVENTORY; + $pk = MobEquipmentPacket::create($this->getHolder()->getId(), $item, $this->getHeldItemIndex(), ContainerIds::INVENTORY); if(!is_array($target)){ $target->sendDataPacket($pk); @@ -166,16 +162,15 @@ class PlayerInventory extends BaseInventory{ if(!($holder instanceof Player)){ throw new \LogicException("Cannot send creative inventory contents to non-player inventory holder"); } - $pk = new InventoryContentPacket(); - $pk->windowId = ContainerIds::CREATIVE; + $items = []; if(!$holder->isSpectator()){ //fill it for all gamemodes except spectator foreach(Item::getCreativeItems() as $i => $item){ - $pk->items[$i] = clone $item; + $items[$i] = clone $item; } } - $holder->sendDataPacket($pk); + $holder->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items)); } /** diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index e01926ad1..e208ae70d 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -152,9 +152,7 @@ class CraftingTransaction extends InventoryTransaction{ * So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting * transaction goes wrong. */ - $pk = new ContainerClosePacket(); - $pk->windowId = ContainerIds::NONE; - $this->source->sendDataPacket($pk); + $this->source->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); } public function execute() : bool{ diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 635348367..cc5ec7d7f 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\world\format\Chunk; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; +use pocketmine\world\format\Chunk; class ChunkRequestTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; @@ -52,12 +52,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onRun() : void{ - $pk = new FullChunkDataPacket(); - $pk->chunkX = $this->chunkX; - $pk->chunkZ = $this->chunkZ; - $pk->data = $this->chunk; - - $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets($pk)->getBuffer(), $this->compressionLevel)); + $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $this->chunk))->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 064fb374c..46dfd06f3 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -79,6 +79,7 @@ use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; use pocketmine\utils\Utils; use pocketmine\world\Position; +use function array_map; use function bin2hex; use function count; use function get_class; @@ -460,10 +461,7 @@ class NetworkSession{ */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ $this->tryDisconnect(function() use($ip, $port, $reason){ - $pk = new TransferPacket(); - $pk->address = $ip; - $pk->port = $port; - $this->sendDataPacket($pk, true); + $this->sendDataPacket(TransferPacket::create($ip, $port), true); $this->disconnect($reason, false); if($this->player !== null){ $this->player->disconnect($reason, null, false); @@ -492,10 +490,7 @@ class NetworkSession{ */ private function doServerDisconnect(string $reason, bool $notify = true) : void{ if($notify){ - $pk = new DisconnectPacket(); - $pk->message = $reason; - $pk->hideDisconnectionScreen = $reason === ""; - $this->sendDataPacket($pk, true); + $this->sendDataPacket($reason === "" ? DisconnectPacket::silent() : DisconnectPacket::message($reason), true); } $this->interface->close($this, $notify ? $reason : ""); @@ -544,9 +539,7 @@ class NetworkSession{ } public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ - $pk = new ServerToClientHandshakePacket(); - $pk->jwt = $handshakeJwt; - $this->sendDataPacket($pk, true); //make sure this gets sent before encryption is enabled + $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled $this->cipher = new NetworkCipher($encryptionKey); @@ -557,9 +550,7 @@ class NetworkSession{ public function onLoginSuccess() : void{ $this->loggedIn = true; - $pk = new PlayStatusPacket(); - $pk->status = PlayStatusPacket::LOGIN_SUCCESS; - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); $this->setHandler(new ResourcePacksSessionHandler($this, $this->server->getResourcePackManager())); } @@ -571,9 +562,7 @@ class NetworkSession{ } public function onTerrainReady() : void{ - $pk = new PlayStatusPacket(); - $pk->status = PlayStatusPacket::PLAYER_SPAWN; - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); } public function onSpawn() : void{ @@ -604,34 +593,19 @@ class NetworkSession{ } public function syncViewAreaRadius(int $distance) : void{ - $pk = new ChunkRadiusUpdatedPacket(); - $pk->radius = $distance; - $this->sendDataPacket($pk); + $this->sendDataPacket(ChunkRadiusUpdatedPacket::create($distance)); } public function syncViewAreaCenterPoint(Vector3 $newPos, int $viewDistance) : void{ - $pk = new NetworkChunkPublisherUpdatePacket(); - $pk->x = $newPos->getFloorX(); - $pk->y = $newPos->getFloorY(); - $pk->z = $newPos->getFloorZ(); - $pk->radius = $viewDistance * 16; //blocks, not chunks >.> - $this->sendDataPacket($pk); + $this->sendDataPacket(NetworkChunkPublisherUpdatePacket::create($newPos->getFloorX(), $newPos->getFloorY(), $newPos->getFloorZ(), $viewDistance * 16)); //blocks, not chunks >.> } public function syncPlayerSpawnPoint(Position $newSpawn) : void{ - $pk = new SetSpawnPositionPacket(); - $pk->x = $newSpawn->getFloorX(); - $pk->y = $newSpawn->getFloorY(); - $pk->z = $newSpawn->getFloorZ(); - $pk->spawnType = SetSpawnPositionPacket::TYPE_PLAYER_SPAWN; - $pk->spawnForced = false; - $this->sendDataPacket($pk); + $this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), false)); //TODO: spawn forced } public function syncGameMode(GameMode $mode) : void{ - $pk = new SetPlayerGameTypePacket(); - $pk->gamemode = self::getClientFriendlyGamemode($mode); - $this->sendDataPacket($pk); + $this->sendDataPacket(SetPlayerGameTypePacket::create(self::getClientFriendlyGamemode($mode))); } /** @@ -661,10 +635,7 @@ class NetworkSession{ public function syncAttributes(Living $entity, bool $sendAll = false){ $entries = $sendAll ? $entity->getAttributeMap()->getAll() : $entity->getAttributeMap()->needSend(); if(count($entries) > 0){ - $pk = new UpdateAttributesPacket(); - $pk->entityRuntimeId = $entity->getId(); - $pk->entries = $entries; - $this->sendDataPacket($pk); + $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), $entries)); foreach($entries as $entry){ $entry->markSynchronized(); } @@ -672,24 +643,11 @@ class NetworkSession{ } public function onEntityEffectAdded(Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $entity->getId(); - $pk->eventId = $replacesOldEffect ? MobEffectPacket::EVENT_MODIFY : MobEffectPacket::EVENT_ADD; - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); - - $this->sendDataPacket($pk); + $this->sendDataPacket(MobEffectPacket::add($entity->getId(), $replacesOldEffect, $effect->getId(), $effect->getAmplifier(), $effect->isVisible(), $effect->getDuration())); } public function onEntityEffectRemoved(Living $entity, EffectInstance $effect) : void{ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $entity->getId(); - $pk->eventId = MobEffectPacket::EVENT_REMOVE; - $pk->effectId = $effect->getId(); - - $this->sendDataPacket($pk); + $this->sendDataPacket(MobEffectPacket::remove($entity->getId(), $effect->getId())); } public function syncAvailableCommands() : void{ @@ -730,43 +688,27 @@ class NetworkSession{ } public function onRawChatMessage(string $message) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_RAW; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::raw($message)); } public function onTranslatedChatMessage(string $key, array $parameters) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_TRANSLATION; - $pk->needsTranslation = true; - $pk->message = $key; - $pk->parameters = $parameters; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::translation($key, $parameters)); } public function onPopup(string $message) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_POPUP; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::popup($message)); } public function onTip(string $message) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_TIP; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::tip($message)); } public function onFormSent(int $id, Form $form) : bool{ - $pk = new ModalFormRequestPacket(); - $pk->formId = $id; - $pk->formData = json_encode($form); - if($pk->formData === false){ + $formData = json_encode($form); + if($formData === false){ throw new \InvalidArgumentException("Failed to encode form JSON: " . json_last_error_msg()); } - return $this->sendDataPacket($pk); + return $this->sendDataPacket(ModalFormRequestPacket::create($id, $formData)); } /** @@ -803,21 +745,14 @@ class NetworkSession{ public function syncInventorySlot(Inventory $inventory, int $slot) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ - $pk = new InventorySlotPacket(); - $pk->inventorySlot = $slot; - $pk->item = $inventory->getItem($slot); - $pk->windowId = $windowId; - $this->sendDataPacket($pk); + $this->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $inventory->getItem($slot))); } } public function syncInventoryContents(Inventory $inventory) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ - $pk = new InventoryContentPacket(); - $pk->items = $inventory->getContents(true); - $pk->windowId = $windowId; - $this->sendDataPacket($pk); + $this->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); } } @@ -830,48 +765,28 @@ class NetworkSession{ public function syncInventoryData(Inventory $inventory, int $propertyId, int $value) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ - $pk = new ContainerSetDataPacket(); - $pk->property = $propertyId; - $pk->value = $value; - $pk->windowId = $windowId; - $this->sendDataPacket($pk); + $this->sendDataPacket(ContainerSetDataPacket::create($windowId, $propertyId, $value)); } } public function onMobArmorChange(Living $mob) : void{ - $pk = new MobArmorEquipmentPacket(); - $pk->entityRuntimeId = $mob->getId(); $inv = $mob->getArmorInventory(); - $pk->head = $inv->getHelmet(); - $pk->chest = $inv->getChestplate(); - $pk->legs = $inv->getLeggings(); - $pk->feet = $inv->getBoots(); - $this->sendDataPacket($pk); + $this->sendDataPacket(MobArmorEquipmentPacket::create($mob->getId(), $inv->getHelmet(), $inv->getChestplate(), $inv->getLeggings(), $inv->getBoots())); } public function syncPlayerList() : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - foreach($this->server->getOnlinePlayers() as $player){ - $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); - } - - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayerListPacket::add(array_map(function(Player $player){ + return PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); + }, $this->server->getOnlinePlayers()))); } public function onPlayerAdded(Player $p) : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - $pk->entries[] = PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getName(), $p->getSkin(), $p->getXuid()); - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getName(), $p->getSkin(), $p->getXuid())])); } public function onPlayerRemoved(Player $p) : void{ if($p !== $this->player){ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_REMOVE; - $pk->entries[] = PlayerListEntry::createRemovalEntry($p->getUniqueId()); - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($p->getUniqueId())])); } } diff --git a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php b/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php index 0333fb7f1..e7096d0ac 100644 --- a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php @@ -41,9 +41,7 @@ class DeathSessionHandler extends SessionHandler{ } public function setUp() : void{ - $pk = new RespawnPacket(); - $pk->position = $this->player->getOffsetPosition($this->player->getSpawn()); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(RespawnPacket::create($this->player->getOffsetPosition($this->player->getSpawn()))); } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index e9416f68b..203e0f77a 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -55,10 +55,7 @@ class LoginSessionHandler extends SessionHandler{ public function handleLogin(LoginPacket $packet) : bool{ if(!$this->isCompatibleProtocol($packet->protocol)){ - $pk = new PlayStatusPacket(); - $pk->status = $packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? - PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER; - $this->session->sendDataPacket($pk, true); + $this->session->sendDataPacket(PlayStatusPacket::create($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER), true); //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) $this->session->disconnect( diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index be6dd90e1..877efcfc5 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -59,10 +59,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ } public function setUp() : void{ - $pk = new ResourcePacksInfoPacket(); - $pk->resourcePackEntries = $this->resourcePackManager->getResourceStack(); - $pk->mustAccept = $this->resourcePackManager->resourcePacksRequired(); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePacksInfoPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); } private function disconnectWithError(string $error) : void{ @@ -91,21 +88,18 @@ class ResourcePacksSessionHandler extends SessionHandler{ return false; } - $pk = new ResourcePackDataInfoPacket(); - $pk->packId = $pack->getPackId(); - $pk->maxChunkSize = self::PACK_CHUNK_SIZE; //1MB - $pk->chunkCount = (int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE); - $pk->compressedPackSize = $pack->getPackSize(); - $pk->sha256 = $pack->getSha256(); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePackDataInfoPacket::create( + $pack->getPackId(), + self::PACK_CHUNK_SIZE, + (int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE), + $pack->getPackSize(), + $pack->getSha256() + )); } break; case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: - $pk = new ResourcePackStackPacket(); - $pk->resourcePackStack = $this->resourcePackManager->getResourceStack(); - $pk->mustAccept = $this->resourcePackManager->resourcePacksRequired(); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePackStackPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: $this->session->onResourcePacksDone(); @@ -143,12 +137,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ $this->downloadedChunks[$packId][$packet->chunkIndex] = true; } - $pk = new ResourcePackChunkDataPacket(); - $pk->packId = $packId; - $pk->chunkIndex = $packet->chunkIndex; - $pk->data = $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE); - $pk->progress = $offset; - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePackChunkDataPacket::create($packId, $packet->chunkIndex, $offset, $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE))); return true; } diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 49f9c59bc..86fc70124 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -43,6 +43,19 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound /** @var float */ public $float = 0.0; //TODO (Boat rowing time?) + public static function create(int $entityRuntimeId, int $actionId) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->action = $actionId; + return $result; + } + + public static function boatHack(int $entityRuntimeId, int $actionId, float $data) : self{ + $result = self::create($entityRuntimeId, $actionId); + $result->float = $data; + return $result; + } + protected function decodePayload() : void{ $this->action = $this->getVarInt(); $this->entityRuntimeId = $this->getEntityRuntimeId(); diff --git a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php index 663c24227..c60faaca5 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php @@ -40,6 +40,13 @@ class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, Ser /** @var string */ public $namedtag; + public static function create(int $x, int $y, int $z, string $nbt) : self{ + $result = new self; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + $result->namedtag = $nbt; + return $result; + } + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->namedtag = $this->getRemaining(); diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 7fe8c056b..8dfd37080 100644 --- a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -34,6 +34,12 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $radius; + public static function create(int $radius) : self{ + $result = new self; + $result->radius = $radius; + return $result; + } + protected function decodePayload() : void{ $this->radius = $this->getVarInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php index 55132bf99..5cc935168 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php @@ -34,6 +34,12 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv /** @var int */ public $windowId; + public static function create(int $windowId) : self{ + $result = new self; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getByte(); } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php index eb7b893a4..de24c6055 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php @@ -44,6 +44,22 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $entityUniqueId = -1; + public static function blockInv(int $windowId, int $windowType, int $x, int $y, int $z) : self{ + $result = new self; + $result->windowId = $windowId; + $result->type = $windowType; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + return $result; + } + + public static function entityInv(int $windowId, int $windowType, int $entityUniqueId) : self{ + $result = new self; + $result->windowId = $windowId; + $result->type = $windowType; + $result->entityUniqueId = $entityUniqueId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->type = $this->getByte(); diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php index 54f9fcb34..93c5473e2 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php @@ -48,6 +48,14 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $value; + public static function create(int $windowId, int $propertyId, int $value) : self{ + $result = new self; + $result->property = $propertyId; + $result->value = $value; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->property = $this->getVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php index 437ec6b90..513f8f8ec 100644 --- a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php @@ -36,6 +36,19 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var string */ public $message = ""; + public static function silent() : self{ + $result = new self; + $result->hideDisconnectionScreen = true; + return $result; + } + + public static function message(string $message) : self{ + $result = new self; + $result->hideDisconnectionScreen = false; + $result->message = $message; + return $result; + } + public function canBeSentBeforeLogin() : bool{ return true; } diff --git a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php index 8a87b490a..86e33d3be 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php @@ -90,6 +90,14 @@ class EntityEventPacket extends DataPacket implements ClientboundPacket, Serverb /** @var int */ public $data = 0; + public static function create(int $entityRuntimeId, int $eventId, int $eventData) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->event = $eventId; + $result->data = $eventData; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->event = $this->getByte(); diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index 17a2141be..fada68783 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -40,6 +40,22 @@ class ExplodePacket extends DataPacket implements ClientboundPacket{ /** @var Vector3[] */ public $records = []; + /** + * @param Vector3 $center + * @param float $radius + * @param Vector3[] $records + * + * @return ExplodePacket + */ + public static function create(Vector3 $center, float $radius, array $records) : self{ + (function(Vector3 ...$_){})($records); + $result = new self; + $result->position = $center; + $result->radius = $radius; + $result->records = $records; + return $result; + } + protected function decodePayload() : void{ $this->position = $this->getVector3(); $this->radius = (float) ($this->getVarInt() / 32); diff --git a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php index 2503772c8..abe1c936a 100644 --- a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php @@ -38,6 +38,14 @@ class FullChunkDataPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $data; + public static function create(int $chunkX, int $chunkZ, string $payload) : self{ + $result = new self; + $result->chunkX = $chunkX; + $result->chunkZ = $chunkZ; + $result->data = $payload; + return $result; + } + protected function decodePayload() : void{ $this->chunkX = $this->getVarInt(); $this->chunkZ = $this->getVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php index 4e82aacea..bf5bab448 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php @@ -37,6 +37,20 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ /** @var Item[] */ public $items = []; + /** + * @param int $windowId + * @param Item[] $items + * + * @return InventoryContentPacket + */ + public static function create(int $windowId, array $items) : self{ + (function(Item ...$items){})(...$items); //type check + $result = new self; + $result->windowId = $windowId; + $result->items = $items; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getUnsignedVarInt(); $count = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php index 4f21e7526..e34adbeba 100644 --- a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php @@ -38,6 +38,14 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ /** @var Item */ public $item; + public static function create(int $windowId, int $slot, Item $item) : self{ + $result = new self; + $result->inventorySlot = $slot; + $result->item = $item; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getUnsignedVarInt(); $this->inventorySlot = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php index 99b3923c5..0888c9f2f 100644 --- a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -46,6 +46,16 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S /** @var Item */ public $feet; + public static function create(int $entityRuntimeId, Item $head, Item $chest, Item $legs, Item $feet) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->head = $head; + $result->chest = $chest; + $result->legs = $legs; + $result->feet = $feet; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->head = $this->getSlot(); diff --git a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php index c40509edb..108b57ad7 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php @@ -48,6 +48,25 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $duration = 0; + public static function add(int $entityRuntimeId, bool $replace, int $effectId, int $amplifier, bool $particles, int $duration) : self{ + $result = new self; + $result->eventId = $replace ? self::EVENT_MODIFY : self::EVENT_ADD; + $result->entityRuntimeId = $entityRuntimeId; + $result->effectId = $effectId; + $result->amplifier = $amplifier; + $result->particles = $particles; + $result->duration = $duration; + return $result; + } + + public static function remove(int $entityRuntimeId, int $effectId) : self{ + $pk = new self; + $pk->eventId = self::EVENT_REMOVE; + $pk->entityRuntimeId = $entityRuntimeId; + $pk->effectId = $effectId; + return $pk; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->eventId = $this->getByte(); diff --git a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php index 6ea86df84..9676e966f 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php @@ -43,6 +43,16 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server /** @var int */ public $windowId = 0; + public static function create(int $entityRuntimeId, Item $item, int $inventorySlot, int $windowId) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->item = $item; + $result->inventorySlot = $inventorySlot; + $result->hotbarSlot = $inventorySlot; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->item = $this->getSlot(); diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php index 09a65c4f1..cd1c9d42a 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php @@ -35,6 +35,13 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $formData; //json + public static function create(int $formId, string $formData) : self{ + $result = new self; + $result->formId = $formId; + $result->formData = $formData; + return $result; + } + protected function decodePayload() : void{ $this->formId = $this->getUnsignedVarInt(); $this->formData = $this->getString(); diff --git a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index 7075d0dfa..1d39454d6 100644 --- a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -39,6 +39,15 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun /** @var int */ public $radius; + public static function create(int $x, int $y, int $z, int $blockRadius) : self{ + $result = new self; + $result->x = $x; + $result->y = $y; + $result->z = $z; + $result->radius = $blockRadius; + return $result; + } + protected function decodePayload() : void{ $this->getSignedBlockPosition($this->x, $this->y, $this->z); $this->radius = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php index 83ca723c8..f2c435461 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php @@ -43,6 +43,12 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $status; + public static function create(int $status) : self{ + $result = new self; + $result->status = $status; + return $result; + } + protected function decodePayload() : void{ $this->status = $this->getInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index ec4f1af24..8910b7323 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -43,6 +43,22 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; + public static function add(array $entries) : self{ + (function(PlayerListEntry ...$_){})($entries); + $result = new self; + $result->type = self::TYPE_ADD; + $result->entries = $entries; + return $result; + } + + public static function remove(array $entries) : self{ + (function(PlayerListEntry ...$_){})($entries); + $result = new self; + $result->type = self::TYPE_REMOVE; + $result->entries = $entries; + return $result; + } + protected function decodePayload() : void{ $this->type = $this->getByte(); $count = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php index 7aad4b7bc..e9b1c32cc 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php @@ -34,6 +34,12 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ /** @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(); } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 0e6c3ab01..f51384d7f 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -42,6 +42,15 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke /** @var string */ public $data; + public static function create(string $packId, int $chunkIndex, int $chunkOffset, string $data) : self{ + $result = new self; + $result->packId = $packId; + $result->chunkIndex = $chunkIndex; + $result->progress = $chunkOffset; + $result->data = $data; + return $result; + } + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->chunkIndex = $this->getLInt(); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php index 26882732f..e28abefb7 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -43,6 +43,16 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket /** @var string */ public $sha256; + public static function create(string $packId, int $maxChunkSize, int $chunkCount, int $compressedPackSize, string $sha256sum) : self{ + $result = new self; + $result->packId = $packId; + $result->maxChunkSize = $maxChunkSize; + $result->chunkCount = $chunkCount; + $result->compressedPackSize = $compressedPackSize; + $result->sha256 = $sha256sum; + return $result; + } + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->maxChunkSize = $this->getLInt(); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index 95fe5078e..eed28a945 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -45,6 +45,25 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $isExperimental = false; + /** + * @param ResourcePack[] $resourcePacks + * @param ResourcePack[] $behaviorPacks + * @param bool $mustAccept + * @param bool $isExperimental + * + * @return ResourcePackStackPacket + */ + public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $isExperimental = false) : self{ + (function(ResourcePack ...$_){})($resourcePacks); + (function(ResourcePack ...$_){})($behaviorPacks); + $result = new self; + $result->mustAccept = $mustAccept; + $result->resourcePackStack = $resourcePacks; + $result->behaviorPackStack = $behaviorPacks; + $result->isExperimental = $isExperimental; + return $result; + } + protected function decodePayload() : void{ $this->mustAccept = $this->getBool(); $behaviorPackCount = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index ebd00b40b..bf55daf45 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -42,6 +42,25 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ /** @var ResourcePack[] */ public $resourcePackEntries = []; + /** + * @param ResourcePack[] $resourcePacks + * @param ResourcePack[] $behaviorPacks + * @param bool $mustAccept + * @param bool $hasScripts + * + * @return ResourcePacksInfoPacket + */ + public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $hasScripts = false) : self{ + (function(ResourcePack ...$_){})($resourcePacks); + (function(ResourcePack ...$_){})($behaviorPacks); + $result = new self; + $result->mustAccept = $mustAccept; + $result->hasScripts = $hasScripts; + $result->resourcePackEntries = $resourcePacks; + $result->behaviorPackEntries = $behaviorPacks; + return $result; + } + protected function decodePayload() : void{ $this->mustAccept = $this->getBool(); $this->hasScripts = $this->getBool(); diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php index ad7b29540..b4f79446a 100644 --- a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php @@ -35,6 +35,12 @@ class RespawnPacket extends DataPacket implements ClientboundPacket{ /** @var Vector3 */ public $position; + public static function create(Vector3 $position) : self{ + $result = new self; + $result->position = $position->asVector3(); + return $result; + } + protected function decodePayload() : void{ $this->position = $this->getVector3(); } diff --git a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php index 9a223f18a..1759999ea 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -37,6 +37,12 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac */ public $jwt; + public static function create(string $jwt) : self{ + $result = new self; + $result->jwt = $jwt; + return $result; + } + public function canBeSentBeforeLogin() : bool{ return true; } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php index 500453955..d92cb057a 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php @@ -36,6 +36,13 @@ class SetEntityDataPacket extends DataPacket implements ClientboundPacket, Serve /** @var array */ public $metadata; + public static function create(int $entityRuntimeId, array $metadata) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->metadata = $metadata; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->metadata = $this->getEntityMetadata(); diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php index d0576a052..7f4a863c6 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php @@ -37,6 +37,13 @@ class SetEntityMotionPacket extends DataPacket implements ClientboundPacket{ /** @var Vector3 */ public $motion; + public static function create(int $entityRuntimeId, Vector3 $motion) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->motion = $motion->asVector3(); + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->motion = $this->getVector3(); diff --git a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php index 6ca085859..6e1652773 100644 --- a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -34,6 +34,12 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S /** @var int */ public $gamemode; + public static function create(int $gamemode) : self{ + $pk = new self; + $pk->gamemode = $gamemode; + return $pk; + } + protected function decodePayload() : void{ $this->gamemode = $this->getVarInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php index 21240dd57..8c1231cdf 100644 --- a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -45,6 +45,21 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $spawnForced; + public static function playerSpawn(int $x, int $y, int $z, bool $forced) : self{ + $result = new self; + $result->spawnType = self::TYPE_PLAYER_SPAWN; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + $result->spawnForced = $forced; + return $result; + } + + public static function worldSpawn(int $x, int $y, int $z) : self{ + $result = new self; + $result->spawnType = self::TYPE_WORLD_SPAWN; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + return $result; + } + protected function decodePayload() : void{ $this->spawnType = $this->getVarInt(); $this->getBlockPosition($this->x, $this->y, $this->z); diff --git a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php index b3cd6845a..80acfeebb 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php @@ -33,6 +33,12 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $time; + public static function create(int $time) : self{ + $result = new self; + $result->time = $time; + return $result; + } + protected function decodePayload() : void{ $this->time = $this->getVarInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php index 05c14f4d3..27911c09b 100644 --- a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php @@ -36,6 +36,13 @@ class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $eid; + public static function create(int $takerEntityRuntimeId, int $itemEntityRuntimeId) : self{ + $result = new self; + $result->target = $takerEntityRuntimeId; + $result->eid = $itemEntityRuntimeId; + return $result; + } + protected function decodePayload() : void{ $this->target = $this->getEntityRuntimeId(); $this->eid = $this->getEntityRuntimeId(); diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index 2d7ff0fb7..6d372522a 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -58,6 +58,65 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac /** @var string */ public $platformChatId = ""; + private static function messageOnly(int $type, string $message) : self{ + $result = new self; + $result->type = $type; + $result->message = $message; + return $result; + } + + private static function baseTranslation(int $type, string $key, array $parameters) : self{ + (function(string ...$_){})(...$parameters); + $result = new self; + $result->type = $type; + $result->needsTranslation = true; + $result->message = $key; + $result->parameters = $parameters; + return $result; + } + + public static function raw(string $message) : self{ + return self::messageOnly(self::TYPE_RAW, $message); + } + + /** + * @param string $key + * @param string[] $parameters + * + * @return TextPacket + */ + public static function translation(string $key, array $parameters = []) : self{ + return self::baseTranslation(self::TYPE_TRANSLATION, $key, $parameters); + } + + public static function popup(string $message) : self{ + return self::messageOnly(self::TYPE_POPUP, $message); + } + + /** + * @param string $key + * @param string[] $parameters + * + * @return TextPacket + */ + public static function translatedPopup(string $key, array $parameters = []) : self{ + return self::baseTranslation(self::TYPE_POPUP, $key, $parameters); + } + + /** + * @param string $key + * @param string[] $parameters + * + * @return TextPacket + */ + public static function jukeboxPopup(string $key, array $parameters = []) : self{ + return self::baseTranslation(self::TYPE_JUKEBOX_POPUP, $key, $parameters); + } + + public static function tip(string $message) : self{ + return self::messageOnly(self::TYPE_TIP, $message); + } + protected function decodePayload() : void{ $this->type = $this->getByte(); $this->needsTranslation = $this->getBool(); diff --git a/src/pocketmine/network/mcpe/protocol/TransferPacket.php b/src/pocketmine/network/mcpe/protocol/TransferPacket.php index c32da8c9f..c1cadb556 100644 --- a/src/pocketmine/network/mcpe/protocol/TransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TransferPacket.php @@ -35,6 +35,13 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $port = 19132; + public static function create(string $address, int $port) : self{ + $result = new self; + $result->address = $address; + $result->port = $port; + return $result; + } + protected function decodePayload() : void{ $this->address = $this->getString(); $this->port = $this->getLShort(); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index 92ebc6b23..c40c99295 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -38,6 +38,20 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ /** @var Attribute[] */ public $entries = []; + /** + * @param int $entityRuntimeId + * @param Attribute[] $attributes + * + * @return UpdateAttributesPacket + */ + public static function create(int $entityRuntimeId, array $attributes) : self{ + (function(Attribute ...$attributes){})(...$attributes); + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->entries = $attributes; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->entries = $this->getAttributeList(); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php index 62e13f711..dbad6185f 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php @@ -51,6 +51,14 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $dataLayerId = self::DATA_LAYER_NORMAL; + public static function create(int $x, int $y, int $z, int $blockRuntimeId, int $dataLayerId = self::DATA_LAYER_NORMAL) : self{ + $result = new self; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + $result->blockRuntimeId = $blockRuntimeId; + $result->dataLayerId = $dataLayerId; + return $result; + } + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->blockRuntimeId = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/world/Explosion.php b/src/pocketmine/world/Explosion.php index ee0b86c9e..a7d19bdb1 100644 --- a/src/pocketmine/world/Explosion.php +++ b/src/pocketmine/world/Explosion.php @@ -240,11 +240,7 @@ class Explosion{ $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z); } - $pk = new ExplodePacket(); - $pk->position = $this->source->asVector3(); - $pk->radius = $this->size; - $pk->records = $send; - $this->world->broadcastPacketToViewers($source, $pk); + $this->world->broadcastPacketToViewers($source, ExplodePacket::create($this->source->asVector3(), $this->size, $send)); $this->world->addParticle($source, new HugeExplodeSeedParticle()); $this->world->addSound($source, new ExplodeSound()); diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index f826650c1..9183e525a 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -715,8 +715,7 @@ class World implements ChunkManager, Metadatable{ * @param Player ...$targets If empty, will send to all players in the world. */ public function sendTime(Player ...$targets){ - $pk = new SetTimePacket(); - $pk->time = $this->time & 0xffffffff; //avoid overflowing the field, since the packet uses an int32 + $pk = SetTimePacket::create($this->time & 0xffffffff); //avoid overflowing the field, since the packet uses an int32 if(empty($targets)){ $this->broadcastGlobalPacket($pk); @@ -934,28 +933,17 @@ class World implements ChunkManager, Metadatable{ if(!($b instanceof Vector3)){ throw new \TypeError("Expected Vector3 in blocks array, got " . (is_object($b) ? get_class($b) : gettype($b))); } - $pk = new UpdateBlockPacket(); - - $pk->x = $b->x; - $pk->y = $b->y; - $pk->z = $b->z; if($b instanceof Block){ - $pk->blockRuntimeId = $b->getRuntimeId(); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, $b->getRuntimeId()); }else{ $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); - $pk->blockRuntimeId = RuntimeBlockMapping::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf)); } - $packets[] = $pk; $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ - $tilepk = new BlockEntityDataPacket(); - $tilepk->x = $tile->x; - $tilepk->y = $tile->y; - $tilepk->z = $tile->z; - $tilepk->namedtag = $tile->getSerializedSpawnCompound(); - $packets[] = $tilepk; + $packets[] = BlockEntityDataPacket::create($tile->x, $tile->y, $tile->z, $tile->getSerializedSpawnCompound()); } } diff --git a/src/pocketmine/world/particle/FloatingTextParticle.php b/src/pocketmine/world/particle/FloatingTextParticle.php index d8efe445b..02ea68a3f 100644 --- a/src/pocketmine/world/particle/FloatingTextParticle.php +++ b/src/pocketmine/world/particle/FloatingTextParticle.php @@ -84,20 +84,14 @@ class FloatingTextParticle implements Particle{ if($this->entityId === null){ $this->entityId = EntityFactory::nextRuntimeId(); }else{ - $pk0 = new RemoveEntityPacket(); - $pk0->entityUniqueId = $this->entityId; - - $p[] = $pk0; + $p[] = RemoveEntityPacket::create($this->entityId); } if(!$this->invisible){ $uuid = UUID::fromRandom(); $name = $this->title . ($this->text !== "" ? "\n" . $this->text : ""); - $add = new PlayerListPacket(); - $add->type = PlayerListPacket::TYPE_ADD; - $add->entries = [PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, new Skin("Standard_Custom", str_repeat("\x00", 8192)))]; - $p[] = $add; + $p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, new Skin("Standard_Custom", str_repeat("\x00", 8192)))]); $pk = new AddPlayerPacket(); $pk->uuid = $uuid; @@ -116,10 +110,7 @@ class FloatingTextParticle implements Particle{ $p[] = $pk; - $remove = new PlayerListPacket(); - $remove->type = PlayerListPacket::TYPE_REMOVE; - $remove->entries = [PlayerListEntry::createRemovalEntry($uuid)]; - $p[] = $remove; + $p[] = PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($uuid)]); } return $p;