Migrate packet creation to use ::create() methods in all but one case

MovePlayerPacket doesn't yet have a ::create() due to a complication with fields that aren't always present.
This commit is contained in:
Dylan K. Taylor 2021-10-23 01:46:01 +01:00
parent c773e43eda
commit c77829f4ad
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
7 changed files with 96 additions and 72 deletions

View File

@ -1418,20 +1418,21 @@ abstract class Entity{
* Called by spawnTo() to send whatever packets needed to spawn the entity to the client.
*/
protected function sendSpawnPacket(Player $player) : void{
$pk = new AddActorPacket();
$pk->actorRuntimeId = $this->getId();
$pk->type = static::getNetworkTypeId();
$pk->position = $this->location->asVector3();
$pk->motion = $this->getMotion();
$pk->yaw = $this->location->yaw;
$pk->headYaw = $this->location->yaw; //TODO
$pk->pitch = $this->location->pitch;
$pk->attributes = array_map(function(Attribute $attr) : NetworkAttribute{
return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue());
}, $this->attributeMap->getAll());
$pk->metadata = $this->getAllNetworkData();
$player->getNetworkSession()->sendDataPacket($pk);
$player->getNetworkSession()->sendDataPacket(AddActorPacket::create(
$this->getId(), //TODO: actor unique ID
$this->getId(),
static::getNetworkTypeId(),
$this->location->asVector3(),
$this->getMotion(),
$this->location->pitch,
$this->location->yaw,
$this->location->yaw, //TODO: head yaw
array_map(function(Attribute $attr) : NetworkAttribute{
return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue());
}, $this->attributeMap->getAll()),
$this->getAllNetworkData(),
[] //TODO: entity links
));
}
public function spawnTo(Player $player) : void{

View File

@ -47,8 +47,10 @@ use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\types\DeviceOS;
use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty;
@ -444,17 +446,24 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$player->getNetworkSession()->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), SkinAdapterSingleton::get()->toSkinData($this->skin))]));
}
$pk = new AddPlayerPacket();
$pk->uuid = $this->getUniqueId();
$pk->username = $this->getName();
$pk->actorRuntimeId = $this->getId();
$pk->position = $this->location->asVector3();
$pk->motion = $this->getMotion();
$pk->yaw = $this->location->yaw;
$pk->pitch = $this->location->pitch;
$pk->item = ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand()));
$pk->metadata = $this->getAllNetworkData();
$player->getNetworkSession()->sendDataPacket($pk);
$player->getNetworkSession()->sendDataPacket(AddPlayerPacket::create(
$this->getUniqueId(),
$this->getName(),
$this->getId(), //TODO: actor unique ID
$this->getId(),
"",
$this->location->asVector3(),
$this->getMotion(),
$this->location->pitch,
$this->location->yaw,
$this->location->yaw, //TODO: head yaw
ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand())),
$this->getAllNetworkData(),
AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->getId()), //TODO
[], //TODO: entity links
"", //device ID (we intentionally don't send this - secvuln)
DeviceOS::UNKNOWN //we intentionally don't send this (secvuln)
));
//TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately
$this->sendData([$player], [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]);

View File

@ -206,14 +206,15 @@ class ItemEntity extends Entity{
}
protected function sendSpawnPacket(Player $player) : void{
$pk = new AddItemActorPacket();
$pk->actorRuntimeId = $this->getId();
$pk->position = $this->location->asVector3();
$pk->motion = $this->getMotion();
$pk->item = ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getItem()));
$pk->metadata = $this->getAllNetworkData();
$player->getNetworkSession()->sendDataPacket($pk);
$player->getNetworkSession()->sendDataPacket(AddItemActorPacket::create(
$this->getId(), //TODO: entity unique ID
$this->getId(),
ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getItem())),
$this->location->asVector3(),
$this->getMotion(),
$this->getAllNetworkData(),
false //TODO: I have no idea what this is needed for, but right now we don't support fishing anyway
));
}
public function getOffsetPosition(Vector3 $vector3) : Vector3{

View File

@ -149,17 +149,17 @@ class Painting extends Entity{
}
protected function sendSpawnPacket(Player $player) : void{
$pk = new AddPaintingPacket();
$pk->actorRuntimeId = $this->getId();
$pk->position = new Vector3(
($this->boundingBox->minX + $this->boundingBox->maxX) / 2,
($this->boundingBox->minY + $this->boundingBox->maxY) / 2,
($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2
);
$pk->direction = self::FACING_TO_DATA[$this->facing];
$pk->title = $this->motive->getName();
$player->getNetworkSession()->sendDataPacket($pk);
$player->getNetworkSession()->sendDataPacket(AddPaintingPacket::create(
$this->getId(), //TODO: entity unique ID
$this->getId(),
new Vector3(
($this->boundingBox->minX + $this->boundingBox->maxX) / 2,
($this->boundingBox->minY + $this->boundingBox->maxY) / 2,
($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2
),
self::FACING_TO_DATA[$this->facing],
$this->motive->getName()
));
}
/**

View File

@ -776,7 +776,15 @@ class NetworkSession{
* TODO: make this less specialized
*/
public function syncAdventureSettings(Player $for) : void{
$pk = new AdventureSettingsPacket();
$isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR);
$pk = AdventureSettingsPacket::create(
0,
$isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL,
0,
$isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER,
0,
$for->getId()
);
$pk->setFlag(AdventureSettingsPacket::WORLD_IMMUTABLE, $for->isSpectator());
$pk->setFlag(AdventureSettingsPacket::NO_PVP, $for->isSpectator());
@ -787,11 +795,6 @@ class NetworkSession{
//TODO: permission flags
$isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR);
$pk->commandPermission = ($isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL);
$pk->playerPermission = ($isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER);
$pk->targetActorUniqueId = $for->getId();
$this->sendDataPacket($pk);
}
@ -828,9 +831,9 @@ class NetworkSession{
}
public function syncAvailableCommands() : void{
$pk = new AvailableCommandsPacket();
$commandData = [];
foreach($this->server->getCommandMap()->getCommands() as $name => $command){
if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this->player)){
if(isset($commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this->player)){
continue;
}
@ -857,10 +860,10 @@ class NetworkSession{
]
);
$pk->commandData[$command->getName()] = $data;
$commandData[$command->getName()] = $data;
}
$this->sendDataPacket($pk);
$this->sendDataPacket(AvailableCommandsPacket::create($commandData, [], [], []));
}
public function onRawChatMessage(string $message) : void{

View File

@ -71,15 +71,14 @@ final class CraftingDataCache{
*/
private function buildCraftingDataCache(CraftingManager $manager) : CraftingDataPacket{
Timings::$craftingDataCacheRebuild->startTiming();
$pk = new CraftingDataPacket();
$pk->cleanRecipes = true;
$counter = 0;
$nullUUID = Uuid::fromString(Uuid::NIL);
$converter = TypeConverter::getInstance();
$recipesWithTypeIds = [];
foreach($manager->getShapelessRecipes() as $list){
foreach($list as $recipe){
$pk->recipesWithTypeIds[] = new ProtocolShapelessRecipe(
$recipesWithTypeIds[] = new ProtocolShapelessRecipe(
CraftingDataPacket::ENTRY_SHAPELESS,
Binary::writeInt(++$counter),
array_map(function(Item $item) use ($converter) : RecipeIngredient{
@ -104,7 +103,7 @@ final class CraftingDataCache{
$inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row));
}
}
$pk->recipesWithTypeIds[] = $r = new ProtocolShapedRecipe(
$recipesWithTypeIds[] = $r = new ProtocolShapedRecipe(
CraftingDataPacket::ENTRY_SHAPED,
Binary::writeInt(++$counter),
$inputs,
@ -128,7 +127,7 @@ final class CraftingDataCache{
};
foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){
$input = $converter->coreItemStackToNet($recipe->getInput());
$pk->recipesWithTypeIds[] = new ProtocolFurnaceRecipe(
$recipesWithTypeIds[] = new ProtocolFurnaceRecipe(
CraftingDataPacket::ENTRY_FURNACE_DATA,
$input->getId(),
$input->getMeta(),
@ -139,6 +138,6 @@ final class CraftingDataCache{
}
Timings::$craftingDataCacheRebuild->stopTiming();
return $pk;
return CraftingDataPacket::create($recipesWithTypeIds, [], [], [], true);
}
}

View File

@ -28,8 +28,10 @@ use pocketmine\entity\Skin;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\types\DeviceOS;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty;
@ -96,22 +98,31 @@ class FloatingTextParticle implements Particle{
$p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, SkinAdapterSingleton::get()->toSkinData(new Skin("Standard_Custom", str_repeat("\x00", 8192))))]);
$pk = new AddPlayerPacket();
$pk->uuid = $uuid;
$pk->username = $name;
$pk->actorRuntimeId = $this->entityId;
$pk->position = $pos; //TODO: check offset
$pk->item = ItemStackWrapper::legacy(ItemStack::null());
$flags = (
$actorFlags = (
1 << EntityMetadataFlags::IMMOBILE
);
$pk->metadata = [
EntityMetadataProperties::FLAGS => new LongMetadataProperty($flags),
$actorMetadata = [
EntityMetadataProperties::FLAGS => new LongMetadataProperty($actorFlags),
EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01) //zero causes problems on debug builds
];
$p[] = $pk;
$p[] = AddPlayerPacket::create(
$uuid,
$name,
$this->entityId, //TODO: actor unique ID
$this->entityId,
"",
$pos, //TODO: check offset
null,
0,
0,
0,
ItemStackWrapper::legacy(ItemStack::null()),
$actorMetadata,
AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->entityId),
[],
"",
DeviceOS::UNKNOWN
);
$p[] = PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($uuid)]);
}