Protocol changes for 1.8.0 release

This commit is contained in:
Dylan K. Taylor
2018-10-12 11:45:20 +01:00
parent f704061618
commit 30f5a8fac6
21 changed files with 494 additions and 30 deletions

View File

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

View File

@ -0,0 +1,47 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class AvailableEntityIdentifiersPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::AVAILABLE_ENTITY_IDENTIFIERS_PACKET;
/** @var string */
public $namedtag;
protected function decodePayload(){
$this->namedtag = $this->getRemaining();
}
protected function encodePayload(){
$this->put($this->namedtag);
}
public function handle(NetworkSession $session) : bool{
return $session->handleAvailableEntityIdentifiers($this);
}
}

View File

@ -0,0 +1,47 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class BiomeDefinitionListPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::BIOME_DEFINITION_LIST_PACKET;
/** @var string */
public $namedtag;
protected function decodePayload(){
$this->namedtag = $this->getRemaining();
}
protected function encodePayload(){
$this->put($this->namedtag);
}
public function handle(NetworkSession $session) : bool{
return $session->handleBiomeDefinitionList($this);
}
}

View File

@ -249,9 +249,9 @@ class LevelSoundEventPacket extends DataPacket{
/** @var Vector3 */
public $position;
/** @var int */
public $extraData = -1;
/** @var int */
public $pitch = 1;
public $extraData = 0;
/** @var string */
public $entityType = ":"; //???
/** @var bool */
public $isBabyMob = false; //...
/** @var bool */
@ -261,7 +261,7 @@ class LevelSoundEventPacket extends DataPacket{
$this->sound = $this->getByte();
$this->position = $this->getVector3();
$this->extraData = $this->getVarInt();
$this->pitch = $this->getVarInt();
$this->entityType = $this->getString();
$this->isBabyMob = $this->getBool();
$this->disableRelativeVolume = $this->getBool();
}
@ -270,7 +270,7 @@ class LevelSoundEventPacket extends DataPacket{
$this->putByte($this->sound);
$this->putVector3($this->position);
$this->putVarInt($this->extraData);
$this->putVarInt($this->pitch);
$this->putString($this->entityType);
$this->putBool($this->isBabyMob);
$this->putBool($this->disableRelativeVolume);
}

View File

@ -0,0 +1,71 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession;
/**
* Useless leftover from a 1.8 refactor, does nothing
*/
class LevelSoundEventPacketV1 extends DataPacket{
public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET_V1;
/** @var int */
public $sound;
/** @var Vector3 */
public $position;
/** @var int */
public $extraData = 0;
/** @var int */
public $entityType = 1;
/** @var bool */
public $isBabyMob = false; //...
/** @var bool */
public $disableRelativeVolume = false;
protected function decodePayload(){
$this->sound = $this->getByte();
$this->position = $this->getVector3();
$this->extraData = $this->getVarInt();
$this->entityType = $this->getVarInt();
$this->isBabyMob = $this->getBool();
$this->disableRelativeVolume = $this->getBool();
}
protected function encodePayload(){
$this->putByte($this->sound);
$this->putVector3($this->position);
$this->putVarInt($this->extraData);
$this->putVarInt($this->entityType);
$this->putBool($this->isBabyMob);
$this->putBool($this->disableRelativeVolume);
}
public function handle(NetworkSession $session) : bool{
return $session->handleLevelSoundEventPacketV1($this);
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class NetworkChunkPublisherUpdatePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET;
/** @var int */
public $x;
/** @var int */
public $y;
/** @var int */
public $z;
/** @var int */
public $radius;
protected function decodePayload(){
$this->getSignedBlockPosition($this->x, $this->y, $this->z);
$this->radius = $this->getUnsignedVarInt();
}
protected function encodePayload(){
$this->putSignedBlockPosition($this->x, $this->y, $this->z);
$this->putUnsignedVarInt($this->radius);
}
public function handle(NetworkSession $session) : bool{
return $session->handleNetworkChunkPublisherUpdate($this);
}
}

View File

@ -54,7 +54,7 @@ class PacketPool{
static::registerPacket(new UpdateBlockPacket());
static::registerPacket(new AddPaintingPacket());
static::registerPacket(new ExplodePacket());
static::registerPacket(new LevelSoundEventPacket());
static::registerPacket(new LevelSoundEventPacketV1());
static::registerPacket(new LevelEventPacket());
static::registerPacket(new BlockEventPacket());
static::registerPacket(new EntityEventPacket());
@ -147,6 +147,11 @@ class PacketPool{
static::registerPacket(new UpdateSoftEnumPacket());
static::registerPacket(new NetworkStackLatencyPacket());
static::registerPacket(new ScriptCustomEventPacket());
static::registerPacket(new SpawnParticleEffectPacket());
static::registerPacket(new AvailableEntityIdentifiersPacket());
static::registerPacket(new LevelSoundEventPacket());
static::registerPacket(new NetworkChunkPublisherUpdatePacket());
static::registerPacket(new BiomeDefinitionListPacket());
static::registerPacket(new BatchPacket());
}
@ -178,4 +183,5 @@ class PacketPool{
return $pk;
}
}

View File

@ -39,15 +39,15 @@ interface ProtocolInfo{
/**
* Actual Minecraft: PE protocol version
*/
public const CURRENT_PROTOCOL = 291;
public const CURRENT_PROTOCOL = 313;
/**
* Current Minecraft PE version reported by the server. This is usually the earliest currently supported version.
*/
public const MINECRAFT_VERSION = 'v1.7.0';
public const MINECRAFT_VERSION = 'v1.8.0';
/**
* Version number sent to clients in ping responses.
*/
public const MINECRAFT_VERSION_NETWORK = '1.7.0';
public const MINECRAFT_VERSION_NETWORK = '1.8.0';
public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02;
@ -72,7 +72,7 @@ interface ProtocolInfo{
public const UPDATE_BLOCK_PACKET = 0x15;
public const ADD_PAINTING_PACKET = 0x16;
public const EXPLODE_PACKET = 0x17;
public const LEVEL_SOUND_EVENT_PACKET = 0x18;
public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18;
public const LEVEL_EVENT_PACKET = 0x19;
public const BLOCK_EVENT_PACKET = 0x1a;
public const ENTITY_EVENT_PACKET = 0x1b;
@ -164,6 +164,12 @@ interface ProtocolInfo{
public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71;
public const UPDATE_SOFT_ENUM_PACKET = 0x72;
public const NETWORK_STACK_LATENCY_PACKET = 0x73;
public const SCRIPT_CUSTOM_EVENT_PACKET = 0x75;
public const SPAWN_PARTICLE_EFFECT_PACKET = 0x76;
public const AVAILABLE_ENTITY_IDENTIFIERS_PACKET = 0x77;
public const LEVEL_SOUND_EVENT_PACKET = 0x78;
public const NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET = 0x79;
public const BIOME_DEFINITION_LIST_PACKET = 0x7a;
}

View File

@ -41,6 +41,9 @@ class ResourcePackStackPacket extends DataPacket{
/** @var ResourcePack[] */
public $resourcePackStack = [];
/** @var bool */
public $isExperimental = false;
protected function decodePayload(){
$this->mustAccept = $this->getBool();
$behaviorPackCount = $this->getUnsignedVarInt();
@ -56,6 +59,8 @@ class ResourcePackStackPacket extends DataPacket{
$this->getString();
$this->getString();
}
$this->isExperimental = $this->getBool();
}
protected function encodePayload(){
@ -74,6 +79,8 @@ class ResourcePackStackPacket extends DataPacket{
$this->putString($entry->getPackVersion());
$this->putString(""); //TODO: subpack name
}
$this->putBool($this->isExperimental);
}
public function handle(NetworkSession $session) : bool{

View File

@ -0,0 +1,57 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
class SpawnParticleEffectPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::SPAWN_PARTICLE_EFFECT_PACKET;
/** @var int */
public $dimensionId = DimensionIds::OVERWORLD; //wtf mojang
/** @var Vector3 */
public $position;
/** @var string */
public $particleName;
protected function decodePayload(){
$this->dimensionId = $this->getByte();
$this->position = $this->getVector3();
$this->particleName = $this->getString();
}
protected function encodePayload(){
$this->putByte($this->dimensionId);
$this->putVector3($this->position);
$this->putString($this->particleName);
}
public function handle(NetworkSession $session) : bool{
return $session->handleSpawnParticleEffect($this);
}
}

View File

@ -118,6 +118,10 @@ class StartGamePacket extends DataPacket{
public $isFromLockedWorldTemplate = false;
/** @var bool */
public $useMsaGamertagsOnly = false;
/** @var bool */
public $isFromWorldTemplate = false;
/** @var bool */
public $isWorldTemplateOptionLocked = false;
/** @var string */
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
@ -176,6 +180,8 @@ class StartGamePacket extends DataPacket{
$this->hasLockedResourcePack = $this->getBool();
$this->isFromLockedWorldTemplate = $this->getBool();
$this->useMsaGamertagsOnly = $this->getBool();
$this->isFromWorldTemplate = $this->getBool();
$this->isWorldTemplateOptionLocked = $this->getBool();
$this->levelId = $this->getString();
$this->worldName = $this->getString();
@ -236,6 +242,8 @@ class StartGamePacket extends DataPacket{
$this->putBool($this->hasLockedResourcePack);
$this->putBool($this->isFromLockedWorldTemplate);
$this->putBool($this->useMsaGamertagsOnly);
$this->putBool($this->isFromWorldTemplate);
$this->putBool($this->isWorldTemplateOptionLocked);
$this->putString($this->levelId);
$this->putString($this->worldName);

View File

@ -43,6 +43,8 @@ class UpdateTradePacket extends DataPacket{
public $varint1;
/** @var int */
public $varint2;
/** @var int */
public $varint3;
/** @var bool */
public $isWilling;
/** @var int */
@ -59,6 +61,7 @@ class UpdateTradePacket extends DataPacket{
$this->windowType = $this->getByte();
$this->varint1 = $this->getVarInt();
$this->varint2 = $this->getVarInt();
$this->varint3 = $this->getVarInt();
$this->isWilling = $this->getBool();
$this->traderEid = $this->getEntityUniqueId();
$this->playerEid = $this->getEntityUniqueId();
@ -71,6 +74,7 @@ class UpdateTradePacket extends DataPacket{
$this->putByte($this->windowType);
$this->putVarInt($this->varint1);
$this->putVarInt($this->varint2);
$this->putVarInt($this->varint3);
$this->putBool($this->isWilling);
$this->putEntityUniqueId($this->traderEid);
$this->putEntityUniqueId($this->playerEid);