Merge branch 'stable'

This commit is contained in:
Dylan K. Taylor 2019-04-25 15:27:13 +01:00
commit c5ca623124
20 changed files with 722 additions and 307 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 33566f555fc720b3d4a5af1acf7c744a98e37170
Subproject commit 44366c633f31ab19ecb916b451ca1aeacd4972c2

View File

@ -36,10 +36,7 @@ namespace pocketmine {
use pocketmine\utils\VersionString;
use pocketmine\wizard\SetupWizard;
const NAME = "PocketMine-MP";
const BASE_VERSION = "4.0.0";
const IS_DEVELOPMENT_BUILD = true;
const BUILD_NUMBER = 0;
require_once __DIR__ . '/VersionInfo.php';
const MIN_PHP_VERSION = "7.2.0";

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
namespace pocketmine;
const NAME = "PocketMine-MP";
const BASE_VERSION = "4.0.0";
const IS_DEVELOPMENT_BUILD = true;
const BUILD_NUMBER = 0;

View File

@ -141,68 +141,70 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_LEAD_HOLDER_EID = 37; //long
public const DATA_SCALE = 38; //float
public const DATA_HAS_NPC_COMPONENT = 39; //byte (???)
public const DATA_NPC_SKIN_ID = 40; //string
public const DATA_URL_TAG = 41; //string
public const DATA_MAX_AIR = 42; //short
public const DATA_MARK_VARIANT = 43; //int
public const DATA_CONTAINER_TYPE = 44; //byte (ContainerComponent)
public const DATA_CONTAINER_BASE_SIZE = 45; //int (ContainerComponent)
public const DATA_CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 46; //int (used for llamas, inventory size is baseSize + thisProp * strength)
public const DATA_BLOCK_TARGET = 47; //block coords (ender crystal)
public const DATA_WITHER_INVULNERABLE_TICKS = 48; //int
public const DATA_WITHER_TARGET_1 = 49; //long
public const DATA_WITHER_TARGET_2 = 50; //long
public const DATA_WITHER_TARGET_3 = 51; //long
/* 52 (short) */
public const DATA_BOUNDING_BOX_WIDTH = 53; //float
public const DATA_BOUNDING_BOX_HEIGHT = 54; //float
public const DATA_FUSE_LENGTH = 55; //int
public const DATA_RIDER_SEAT_POSITION = 56; //vector3f
public const DATA_RIDER_ROTATION_LOCKED = 57; //byte
public const DATA_RIDER_MAX_ROTATION = 58; //float
public const DATA_RIDER_MIN_ROTATION = 59; //float
public const DATA_AREA_EFFECT_CLOUD_RADIUS = 60; //float
public const DATA_AREA_EFFECT_CLOUD_WAITING = 61; //int
public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 62; //int
/* 63 (int) shulker-related */
public const DATA_SHULKER_ATTACH_FACE = 64; //byte
/* 65 (short) shulker-related */
public const DATA_SHULKER_ATTACH_POS = 66; //block coords
public const DATA_TRADING_PLAYER_EID = 67; //long
public const DATA_SKIN_ID = 40; //string
public const DATA_NPC_SKIN_ID = 41; //string
public const DATA_URL_TAG = 42; //string
public const DATA_MAX_AIR = 43; //short
public const DATA_MARK_VARIANT = 44; //int
public const DATA_CONTAINER_TYPE = 45; //byte (ContainerComponent)
public const DATA_CONTAINER_BASE_SIZE = 46; //int (ContainerComponent)
public const DATA_CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 47; //int (used for llamas, inventory size is baseSize + thisProp * strength)
public const DATA_BLOCK_TARGET = 48; //block coords (ender crystal)
public const DATA_WITHER_INVULNERABLE_TICKS = 49; //int
public const DATA_WITHER_TARGET_1 = 50; //long
public const DATA_WITHER_TARGET_2 = 51; //long
public const DATA_WITHER_TARGET_3 = 52; //long
/* 53 (short) */
public const DATA_BOUNDING_BOX_WIDTH = 54; //float
public const DATA_BOUNDING_BOX_HEIGHT = 55; //float
public const DATA_FUSE_LENGTH = 56; //int
public const DATA_RIDER_SEAT_POSITION = 57; //vector3f
public const DATA_RIDER_ROTATION_LOCKED = 58; //byte
public const DATA_RIDER_MAX_ROTATION = 59; //float
public const DATA_RIDER_MIN_ROTATION = 60; //float
public const DATA_AREA_EFFECT_CLOUD_RADIUS = 61; //float
public const DATA_AREA_EFFECT_CLOUD_WAITING = 62; //int
public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 63; //int
/* 64 (int) shulker-related */
public const DATA_SHULKER_ATTACH_FACE = 65; //byte
/* 66 (short) shulker-related */
public const DATA_SHULKER_ATTACH_POS = 67; //block coords
public const DATA_TRADING_PLAYER_EID = 68; //long
/* 69 (byte) command-block */
public const DATA_COMMAND_BLOCK_COMMAND = 70; //string
public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 71; //string
public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 72; //byte
public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 73; //byte
public const DATA_STRENGTH = 74; //int
public const DATA_MAX_STRENGTH = 75; //int
/* 76 (int) */
public const DATA_LIMITED_LIFE = 77;
public const DATA_ARMOR_STAND_POSE_INDEX = 78; //int
public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 79; //int
public const DATA_ALWAYS_SHOW_NAMETAG = 80; //byte: -1 = default, 0 = only when looked at, 1 = always
public const DATA_COLOR_2 = 81; //byte
/* 82 (unknown) */
public const DATA_SCORE_TAG = 83; //string
public const DATA_BALLOON_ATTACHED_ENTITY = 84; //int64, entity unique ID of owner
public const DATA_PUFFERFISH_SIZE = 85; //byte
public const DATA_BOAT_BUBBLE_TIME = 86; //int (time in bubble column)
public const DATA_PLAYER_AGENT_EID = 87; //long
/* 88 (float) related to panda sitting
* 89 (float) related to panda sitting */
public const DATA_EAT_COUNTER = 90; //int (used by pandas)
public const DATA_FLAGS2 = 91; //long (extended data flags)
/* 92 (float) related to panda lying down
* 93 (float) related to panda lying down */
public const DATA_AREA_EFFECT_CLOUD_DURATION = 94; //int
public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 95; //int
public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 96; //float, usually negative
public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 97; //float
public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 98; //int
public const DATA_INTERACTIVE_TAG = 99; //string (button text)
public const DATA_TRADE_TIER = 100; //int
public const DATA_MAX_TRADE_TIER = 101; //int
/* 70 (byte) command-block */
public const DATA_COMMAND_BLOCK_COMMAND = 71; //string
public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 72; //string
public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 73; //byte
public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 74; //byte
public const DATA_STRENGTH = 75; //int
public const DATA_MAX_STRENGTH = 76; //int
/* 77 (int) */
public const DATA_LIMITED_LIFE = 78;
public const DATA_ARMOR_STAND_POSE_INDEX = 79; //int
public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 80; //int
public const DATA_ALWAYS_SHOW_NAMETAG = 81; //byte: -1 = default, 0 = only when looked at, 1 = always
public const DATA_COLOR_2 = 82; //byte
/* 83 (unknown) */
public const DATA_SCORE_TAG = 84; //string
public const DATA_BALLOON_ATTACHED_ENTITY = 85; //int64, entity unique ID of owner
public const DATA_PUFFERFISH_SIZE = 86; //byte
public const DATA_BOAT_BUBBLE_TIME = 87; //int (time in bubble column)
public const DATA_PLAYER_AGENT_EID = 88; //long
/* 89 (float) related to panda sitting
* 90 (float) related to panda sitting */
public const DATA_EAT_COUNTER = 91; //int (used by pandas)
public const DATA_FLAGS2 = 92; //long (extended data flags)
/* 93 (float) related to panda lying down
* 94 (float) related to panda lying down */
public const DATA_AREA_EFFECT_CLOUD_DURATION = 95; //int
public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 96; //int
public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 97; //float, usually negative
public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 98; //float
public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 99; //int
public const DATA_INTERACTIVE_TAG = 100; //string (button text)
public const DATA_TRADE_TIER = 101; //int
public const DATA_MAX_TRADE_TIER = 102; //int
public const DATA_TRADE_XP = 103; //int
public const DATA_FLAG_ONFIRE = 0;
public const DATA_FLAG_SNEAKING = 1;
@ -278,12 +280,20 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_FLAG_BLOCKING = 71; //shield
public const DATA_FLAG_DISABLE_BLOCKING = 72;
//73 is set when a player is attacked while using shield, unclear on purpose
public const DATA_FLAG_SLEEPING = 74;
//75 related to sleeping, unclear usage
public const DATA_FLAG_TRADE_INTEREST = 76;
public const DATA_FLAG_DOOR_BREAKER = 77; //...
public const DATA_FLAG_BREAKING_OBSTRUCTION = 78;
public const DATA_FLAG_DOOR_OPENER = 79; //...
//74 related to shield usage, needs further investigation
public const DATA_FLAG_SLEEPING = 75;
//76 related to sleeping, unclear usage
public const DATA_FLAG_TRADE_INTEREST = 77;
public const DATA_FLAG_DOOR_BREAKER = 78; //...
public const DATA_FLAG_BREAKING_OBSTRUCTION = 79;
public const DATA_FLAG_DOOR_OPENER = 80; //...
public const DATA_FLAG_ILLAGER_CAPTAIN = 81;
public const DATA_FLAG_STUNNED = 82;
public const DATA_FLAG_ROARING = 83;
public const DATA_FLAG_DELAYED_ATTACKING = 84;
public const DATA_FLAG_AVOIDING_MOBS = 85;
//86 used by RangedAttackGoal
//87 used by NearestAttackableTargetGoal
public const DATA_PLAYER_FLAG_SLEEP = 1;
public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK

View File

@ -58,12 +58,18 @@ class CraftingManager{
foreach($recipes as $recipe){
switch($recipe["type"]){
case 0:
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
break;
}
$this->registerShapelessRecipe(new ShapelessRecipe(
array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["input"]),
array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["output"])
));
break;
case 1:
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
break;
}
$this->registerShapedRecipe(new ShapedRecipe(
$recipe["shape"],
array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["input"]),
@ -72,6 +78,9 @@ class CraftingManager{
break;
case 2:
case 3:
if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics
break;
}
$result = $recipe["output"];
$resultItem = Item::jsonDeserialize($result);
$this->registerFurnaceRecipe(new FurnaceRecipe($resultItem, ItemFactory::get($recipe["inputId"], $recipe["inputDamage"] ?? -1, 1)));

View File

@ -74,6 +74,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV2;
use pocketmine\network\mcpe\protocol\LoginPacket;
use pocketmine\network\mcpe\protocol\MapCreateLockedCopyPacket;
use pocketmine\network\mcpe\protocol\MapInfoRequestPacket;
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
use pocketmine\network\mcpe\protocol\MobEffectPacket;
@ -86,6 +87,7 @@ use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket;
use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket;
use pocketmine\network\mcpe\protocol\NpcRequestPacket;
use pocketmine\network\mcpe\protocol\OnScreenTextureAnimationPacket;
use pocketmine\network\mcpe\protocol\PhotoTransferPacket;
use pocketmine\network\mcpe\protocol\PlayerActionPacket;
use pocketmine\network\mcpe\protocol\PlayerHotbarPacket;
@ -650,4 +652,12 @@ abstract class SessionHandler{
public function handleVideoStreamConnect(VideoStreamConnectPacket $packet) : bool{
return false;
}
public function handleMapCreateLockedCopy(MapCreateLockedCopyPacket $packet) : bool{
return false;
}
public function handleOnScreenTextureAnimation(OnScreenTextureAnimationPacket $packet) : bool{
return false;
}
}

File diff suppressed because one or more lines are too long

View File

@ -50,6 +50,8 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack
public $type;
/** @var int */
public $dimensionId = DimensionIds::OVERWORLD;
/** @var bool */
public $isLocked = false;
/** @var int[] */
public $eids = [];
@ -76,6 +78,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack
$this->mapId = $this->getEntityUniqueId();
$this->type = $this->getUnsignedVarInt();
$this->dimensionId = $this->getByte();
$this->isLocked = $this->getBool();
if(($this->type & 0x08) !== 0){
$count = $this->getUnsignedVarInt();
@ -148,6 +151,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack
$this->putUnsignedVarInt($type);
$this->putByte($this->dimensionId);
$this->putBool($this->isLocked);
if(($type & 0x08) !== 0){ //TODO: find out what these are for
$this->putUnsignedVarInt($eidsCount);

View File

@ -78,6 +78,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$entry["output"][] = $this->getSlot();
}
$entry["uuid"] = $this->getUUID()->toString();
$entry["block"] = $this->getString();
break;
case self::ENTRY_SHAPED:
@ -95,6 +96,8 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$entry["output"][] = $this->getSlot();
}
$entry["uuid"] = $this->getUUID()->toString();
$entry["block"] = $this->getString();
break;
case self::ENTRY_FURNACE:
case self::ENTRY_FURNACE_DATA:
@ -103,6 +106,8 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
$entry["inputDamage"] = $this->getVarInt();
}
$entry["output"] = $this->getSlot();
$entry["block"] = $this->getString();
break;
case self::ENTRY_MULTI:
$entry["uuid"] = $this->getUUID()->toString();
@ -141,6 +146,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}
$stream->put(str_repeat("\x00", 16)); //Null UUID
$stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks)
return CraftingDataPacket::ENTRY_SHAPELESS;
}
@ -162,23 +168,21 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{
}
$stream->put(str_repeat("\x00", 16)); //Null UUID
$stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks)
return CraftingDataPacket::ENTRY_SHAPED;
}
private static function writeFurnaceRecipe(FurnaceRecipe $recipe, NetworkBinaryStream $stream) : int{
private static function writeFurnaceRecipe(FurnaceRecipe $recipe, NetworkBinaryStream $stream){
$stream->putVarInt($recipe->getInput()->getId());
$result = CraftingDataPacket::ENTRY_FURNACE;
if(!$recipe->getInput()->hasAnyDamageValue()){ //Data recipe
$stream->putVarInt($recipe->getInput()->getId());
$stream->putVarInt($recipe->getInput()->getMeta());
$stream->putSlot($recipe->getResult());
return CraftingDataPacket::ENTRY_FURNACE_DATA;
}else{
$stream->putVarInt($recipe->getInput()->getId());
$stream->putSlot($recipe->getResult());
return CraftingDataPacket::ENTRY_FURNACE;
$result = CraftingDataPacket::ENTRY_FURNACE_DATA;
}
$stream->putSlot($recipe->getResult());
$stream->putString("furnace"); //TODO: blocktype (no prefix) (this might require internal API breaks)
return $result;
}
public function addShapelessRecipe(ShapelessRecipe $recipe) : void{

View File

@ -33,6 +33,8 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{
/** @var int */
public $page;
/** @var int */
public $totalPages;
/** @var int */
public $x;
/** @var int */
public $y;
@ -43,12 +45,14 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{
protected function decodePayload() : void{
$this->page = $this->getByte();
$this->totalPages = $this->getByte();
$this->getBlockPosition($this->x, $this->y, $this->z);
$this->dropBook = $this->getBool();
}
protected function encodePayload() : void{
$this->putByte($this->page);
$this->putByte($this->totalPages);
$this->putBlockPosition($this->x, $this->y, $this->z);
$this->putBool($this->dropBook);
}

View File

@ -218,7 +218,7 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser
public const SOUND_ITEM_TRIDENT_THUNDER = 184;
public const SOUND_ITEM_TRIDENT_HIT_GROUND = 185;
public const SOUND_DEFAULT = 186;
public const SOUND_BLOCK_FLETCHING_TABLE_USE = 187;
public const SOUND_ELEMCONSTRUCT_OPEN = 188;
public const SOUND_ICEBOMB_HIT = 189;
public const SOUND_BALLOONPOP = 190;
@ -283,7 +283,26 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser
public const SOUND_AMBIENT_AGGRESSIVE = 252;
public const SOUND_AMBIENT_WORRIED = 253;
public const SOUND_CANT_BREED = 254;
public const SOUND_UNDEFINED = 255;
public const SOUND_ITEM_SHIELD_BLOCK = 255;
public const SOUND_ITEM_BOOK_PUT = 256;
public const SOUND_BLOCK_GRINDSTONE_USE = 257;
public const SOUND_BLOCK_BELL_HIT = 258;
public const SOUND_BLOCK_CAMPFIRE_CRACKLE = 259;
public const SOUND_ROAR = 260;
public const SOUND_STUN = 261;
public const SOUND_BLOCK_SWEET_BERRY_BUSH_HURT = 262;
public const SOUND_BLOCK_SWEET_BERRY_BUSH_PICK = 263;
public const SOUND_UI_CARTOGRAPHY_TABLE_TAKE_RESULT = 264;
public const SOUND_UI_STONECUTTER_TAKE_RESULT = 265;
public const SOUND_BLOCK_COMPOSTER_EMPTY = 266;
public const SOUND_BLOCK_COMPOSTER_FILL = 267;
public const SOUND_BLOCK_COMPOSTER_FILL_SUCCESS = 268;
public const SOUND_BLOCK_COMPOSTER_READY = 269;
public const SOUND_BLOCK_BARREL_OPEN = 270;
public const SOUND_BLOCK_BARREL_CLOSE = 271;
public const SOUND_RAID_HORN = 272;
public const SOUND_BLOCK_LOOM_USE = 273;
public const SOUND_UNDEFINED = 274;
public static function create(int $sound, ?Vector3 $pos, int $extraData = -1, string $entityType = ":", bool $isBabyMob = false) : self{
$result = new self;

View File

@ -0,0 +1,51 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\handler\SessionHandler;
class MapCreateLockedCopyPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET;
/** @var int */
public $originalMapId;
/** @var int */
public $newMapId;
protected function decodePayload() : void{
$this->originalMapId = $this->getEntityUniqueId();
$this->newMapId = $this->getEntityUniqueId();
}
protected function encodePayload() : void{
$this->putEntityUniqueId($this->originalMapId);
$this->putEntityUniqueId($this->newMapId);
}
public function handle(SessionHandler $handler) : bool{
return $handler->handleMapCreateLockedCopy($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\handler\SessionHandler;
class OnScreenTextureAnimationPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET;
/** @var int */
public $effectId;
protected function decodePayload() : void{
$this->effectId = $this->getLInt(); //unsigned
}
protected function encodePayload() : void{
$this->putLInt($this->effectId);
}
public function handle(SessionHandler $handler) : bool{
return $handler->handleOnScreenTextureAnimation($this);
}
}

View File

@ -156,6 +156,8 @@ class PacketPool{
static::registerPacket(new LevelSoundEventPacket());
static::registerPacket(new LecternUpdatePacket());
static::registerPacket(new VideoStreamConnectPacket());
static::registerPacket(new MapCreateLockedCopyPacket());
static::registerPacket(new OnScreenTextureAnimationPacket());
}
/**

View File

@ -39,15 +39,15 @@ interface ProtocolInfo{
/**
* Actual Minecraft: PE protocol version
*/
public const CURRENT_PROTOCOL = 340;
public const CURRENT_PROTOCOL = 354;
/**
* Current Minecraft PE version reported by the server. This is usually the earliest currently supported version.
*/
public const MINECRAFT_VERSION = 'v1.10.0';
public const MINECRAFT_VERSION = 'v1.11.0';
/**
* Version number sent to clients in ping responses.
*/
public const MINECRAFT_VERSION_NETWORK = '1.10.0';
public const MINECRAFT_VERSION_NETWORK = '1.11.0';
public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02;
@ -174,5 +174,7 @@ interface ProtocolInfo{
public const LEVEL_SOUND_EVENT_PACKET = 0x7b;
public const LECTERN_UPDATE_PACKET = 0x7c;
public const VIDEO_STREAM_CONNECT_PACKET = 0x7d;
public const MAP_CREATE_LOCKED_COPY_PACKET = 0x7e;
public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x7f;
}

View File

@ -37,7 +37,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET;
/** @var string|null */
private static $runtimeIdTable;
private static $runtimeIdTableCache;
/** @var int */
public $entityUniqueId;
@ -138,6 +138,9 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
/** @var string */
public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort
/** @var array|null each entry must have a "name" (string) and "data" (int16) element */
public $runtimeIdTable = null;
protected function decodePayload() : void{
$this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId();
@ -189,10 +192,14 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->enchantmentSeed = $this->getVarInt();
$count = $this->getUnsignedVarInt();
$table = [];
for($i = 0; $i < $count; ++$i){
$this->getString();
$this->getLShort();
$id = $this->getString();
$data = $this->getLShort();
$table[$i] = ["name" => $id, "data" => $data];
}
$this->runtimeIdTable = $table;
$this->multiplayerCorrelationId = $this->getString();
}
@ -247,22 +254,29 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->putVarInt($this->enchantmentSeed);
if(self::$runtimeIdTable === null){
//this is a really nasty hack, but it'll do for now
$stream = new NetworkBinaryStream();
$data = RuntimeBlockMapping::getBedrockKnownStates();
$stream->putUnsignedVarInt(count($data));
foreach($data as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
if($this->runtimeIdTable === null){
if(self::$runtimeIdTableCache === null){
//this is a really nasty hack, but it'll do for now
self::$runtimeIdTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates());
}
self::$runtimeIdTable = $stream->getBuffer();
$this->put(self::$runtimeIdTableCache);
}else{
$this->put(self::serializeBlockTable($this->runtimeIdTable));
}
$this->put(self::$runtimeIdTable);
$this->putString($this->multiplayerCorrelationId);
}
private static function serializeBlockTable(array $table) : string{
$stream = new NetworkBinaryStream();
$stream->putUnsignedVarInt(count($table));
foreach($table as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
}
return $stream->getBuffer();
}
public function handle(SessionHandler $handler) : bool{
return $handler->handleStartGame($this);
}

View File

@ -40,45 +40,45 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{
/** @var int */
public $windowType = WindowTypes::TRADING; //Mojang hardcoded this -_-
/** @var int */
public $varint1;
public $thisIsAlwaysZero = 0; //hardcoded to 0
/** @var int */
public $varint2;
/** @var int */
public $varint3;
/** @var bool */
public $isWilling;
public $tradeTier;
/** @var int */
public $traderEid;
/** @var int */
public $playerEid;
/** @var string */
public $displayName;
/** @var bool */
public $isWilling;
/** @var bool */
public $isV2Trading;
/** @var string */
public $offers;
protected function decodePayload() : void{
$this->windowId = $this->getByte();
$this->windowType = $this->getByte();
$this->varint1 = $this->getVarInt();
$this->varint2 = $this->getVarInt();
$this->varint3 = $this->getVarInt();
$this->isWilling = $this->getBool();
$this->thisIsAlwaysZero = $this->getVarInt();
$this->tradeTier = $this->getVarInt();
$this->traderEid = $this->getEntityUniqueId();
$this->playerEid = $this->getEntityUniqueId();
$this->displayName = $this->getString();
$this->isWilling = $this->getBool();
$this->isV2Trading = $this->getBool();
$this->offers = $this->getRemaining();
}
protected function encodePayload() : void{
$this->putByte($this->windowId);
$this->putByte($this->windowType);
$this->putVarInt($this->varint1);
$this->putVarInt($this->varint2);
$this->putVarInt($this->varint3);
$this->putBool($this->isWilling);
$this->putVarInt($this->thisIsAlwaysZero);
$this->putVarInt($this->tradeTier);
$this->putEntityUniqueId($this->traderEid);
$this->putEntityUniqueId($this->playerEid);
$this->putString($this->displayName);
$this->putBool($this->isWilling);
$this->putBool($this->isV2Trading);
$this->put($this->offers);
}

View File

@ -27,6 +27,8 @@ namespace pocketmine\network\mcpe\protocol\types;
interface WindowTypes{
public const NONE = -9;
public const INVENTORY = -1;
public const CONTAINER = 0;
public const WORKBENCH = 1;
@ -47,4 +49,13 @@ interface WindowTypes{
public const COMMAND_BLOCK = 16;
public const JUKEBOX = 17;
public const COMPOUND_CREATOR = 20;
public const ELEMENT_CONSTRUCTOR = 21;
public const MATERIAL_REDUCER = 22;
public const LAB_TABLE = 23;
public const BLAST_FURNACE = 27;
public const SMOKER = 28;
public const STONECUTTER = 29;
}