mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-14 17:59:41 +00:00
Added static create() functions for many packets
There are a few motivations here: 1) Less boilerplate code (this can be written inline) 2) It's possible to provide multiple constructors for different packet variations to reduce the chance of errors. 3) It makes things catch fire on updates in ways that static analysers can understand.
This commit is contained in:
parent
09afb8e772
commit
287c8c2dd4
@ -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(){
|
||||
|
@ -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)]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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{
|
||||
|
@ -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{
|
||||
|
@ -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())]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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{
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user