Initial update to 1.13

This commit is contained in:
Drew 2019-10-30 21:36:08 -04:00
parent 5edff79f5f
commit cd2b60a860
20 changed files with 408 additions and 164 deletions

View File

@ -160,6 +160,8 @@ use pocketmine\tile\ItemFrame;
use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile;
use pocketmine\timings\Timings;
use pocketmine\utils\SerializedImage;
use pocketmine\utils\SkinAnimation;
use pocketmine\utils\TextFormat;
use pocketmine\utils\UUID;
use function abs;
@ -834,12 +836,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Plugin developers should not use this, use setSkin() and sendSkin() instead.
*
* @param Skin $skin
* @param string $newSkinName
* @param string $oldSkinName
*
* @return bool
*/
public function changeSkin(Skin $skin, string $newSkinName, string $oldSkinName) : bool{
public function changeSkin(Skin $skin) : bool{
if(!$skin->isValid()){
return false;
}
@ -1112,9 +1112,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
protected function sendRespawnPacket(Vector3 $pos){
protected function sendRespawnPacket(Vector3 $pos, int $respawnState = 1){
$pk = new RespawnPacket();
$pk->position = $pos->add(0, $this->baseOffset, 0);
$pk->respawnState = $respawnState;
$pk->entityRuntimeId = $this->getId();
$this->dataPacket($pk);
}
@ -1913,12 +1915,22 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->uuid = UUID::fromString($packet->clientUUID);
$this->rawUUID = $this->uuid->toBinary();
$animations = [];
foreach($packet->clientData["AnimatedImageData"] as $animatedData){
$animations[] = new SkinAnimation(new SerializedImage($animatedData["ImageWidth"], $animatedData["ImageHeight"], base64_decode($animatedData["Image"])), $animatedData["Type"], $animatedData["Frames"]);
}
$skin = new Skin(
$packet->clientData["SkinId"],
base64_decode($packet->clientData["SkinData"] ?? ""),
base64_decode($packet->clientData["CapeData"] ?? ""),
$packet->clientData["SkinGeometryName"] ?? "",
base64_decode($packet->clientData["SkinGeometry"] ?? "")
base64_decode($packet->clientData["SkinResourcePatch"] ?? ""),
new SerializedImage($packet->clientData["SkinImageHeight"], $packet->clientData["SkinImageWidth"], base64_decode($packet->clientData["SkinData" ?? ""])), //SerializedImage
$animations,
new SerializedImage($packet->clientData["CapeImageHeight"], $packet->clientData["CapeImageWidth"], base64_decode($packet->clientData["CapeData"] ?? "")),
base64_decode($packet->clientData["SkinGeometryData"] ?? ""),
base64_decode($packet->clientData["SkinAnimationData"] ?? ""),
(bool) $packet->clientData["PremiumSkin"] ?? false,
(bool) $packet->clientData["PersonaSkin"] ?? false,
(bool) $packet->clientData["CapeOnClassicSkin"] ?? false,
$packet->clientData["CapeId"] ?? ""
);
if(!$skin->isValid()){

View File

@ -24,6 +24,8 @@ declare(strict_types=1);
namespace pocketmine\entity;
use Ahc\Json\Comment as CommentedJsonDecoder;
use pocketmine\utils\SerializedImage;
use pocketmine\utils\SkinAnimation;
use function implode;
use function in_array;
use function json_encode;
@ -39,20 +41,38 @@ class Skin{
/** @var string */
private $skinId;
/** @var string */
private $skinResourcePatch;
/** @var SerializedImage */
private $skinData;
/** @var string */
/** @var SkinAnimation[] */
private $animations = [];
/** @var SerializedImage */
private $capeData;
/** @var string */
private $geometryName;
/** @var string */
private $geometryData;
/** @var string */
private $animationData;
/** @var bool */
private $premium;
/** @var bool */
private $persona;
/** @var bool */
private $capeOnClassic;
/** @var string */
private $capeId;
public function __construct(string $skinId, string $skinData, string $capeData = "", string $geometryName = "", string $geometryData = ""){
public function __construct(string $skinId, string $skinResourcePatch, SerializedImage $skinData, array $animations = [], SerializedImage $capeData = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $capeOnClassic = false, string $capeId = ""){
$this->skinId = $skinId;
$this->skinResourcePatch = $skinResourcePatch;
$this->skinData = $skinData;
$this->animations = $animations;
$this->capeData = $capeData;
$this->geometryName = $geometryName;
$this->geometryData = $geometryData;
$this->animationData = $animationData;
$this->premium = $premium;
$this->persona = $persona;
$this->capeOnClassic = $capeOnClassic;
$this->capeId = $capeId;
}
/**
@ -75,13 +95,14 @@ class Skin{
if($this->skinId === ""){
throw new \InvalidArgumentException("Skin ID must not be empty");
}
$len = strlen($this->skinData);
//Broken with Persona skins
/*$len = strlen($this->skinData->getData());
if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){
throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")");
}
if($this->capeData !== "" and strlen($this->capeData) !== 8192){
throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData) . " bytes (must be exactly 8192 bytes)");
}
if($this->capeData->getData() !== "" and strlen($this->capeData->getData()) !== 8192){
throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData->getData()) . " bytes (must be exactly 8192 bytes)");
}*/
//TODO: validate geometry
}
@ -95,22 +116,29 @@ class Skin{
/**
* @return string
*/
public function getSkinData() : string{
public function getSkinResourcePatch() : string{
return $this->skinResourcePatch;
}
/**
* @return SerializedImage
*/
public function getSkinData() : SerializedImage{
return $this->skinData;
}
/**
* @return string
* @return SkinAnimation[]
*/
public function getCapeData() : string{
return $this->capeData;
public function getAnimations() : array{
return $this->animations;
}
/**
* @return string
* @return SerializedImage
*/
public function getGeometryName() : string{
return $this->geometryName;
public function getCapeData() : SerializedImage{
return $this->capeData;
}
/**
@ -120,6 +148,48 @@ class Skin{
return $this->geometryData;
}
/**
* @return string
*/
public function getAnimationData() : string{
return $this->animationData;
}
/**
* @return bool
*/
public function getPremium() : bool{
return $this->premium;
}
/**
* @return bool
*/
public function getPersona() : bool{
return $this->persona;
}
/**
* @return bool
*/
public function getCapeOnClassic() : bool{
return $this->capeOnClassic;
}
/**
* @return string
*/
public function getCapeId() : string{
return $this->capeId;
}
/**
* @return string
*/
public function getFullSkinId() : string{
return $this->skinId . "_" . $this->capeId;
}
/**
* Hack to cut down on network overhead due to skins, by un-pretty-printing geometry JSON.
*

View File

@ -38,7 +38,6 @@ use pocketmine\level\particle\HugeExplodeSeedParticle;
use pocketmine\level\utils\SubChunkIteratorManager;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\ExplodePacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\tile\Chest;
use pocketmine\tile\Container;
@ -260,12 +259,6 @@ 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->level->broadcastPacketToViewers($source, $pk);
$this->level->addParticle(new HugeExplodeSeedParticle($source));
$this->level->broadcastLevelSoundEvent($source, LevelSoundEventPacket::SOUND_EXPLODE);

View File

@ -39,6 +39,7 @@ use pocketmine\network\mcpe\protocol\types\CommandOriginData;
use pocketmine\network\mcpe\protocol\types\EntityLink;
use pocketmine\network\mcpe\protocol\types\StructureSettings;
use pocketmine\utils\BinaryStream;
use pocketmine\utils\SerializedImage;
use pocketmine\utils\UUID;
use function count;
use function strlen;
@ -74,6 +75,19 @@ class NetworkBinaryStream extends BinaryStream{
$this->putLInt($uuid->getPart(2));
}
public function putImage(SerializedImage $image) : void{
$this->putLInt($image->getWidth());
$this->putLInt($image->getHeight());
$this->putString($image->getData());
}
public function getImage() : SerializedImage{
$width = $this->getLInt();
$height = $this->getLInt();
$data = $this->getString();
return new SerializedImage($height, $width, $data);
}
public function getSlot() : Item{
$id = $this->getVarInt();
if($id === 0){

View File

@ -247,10 +247,6 @@ abstract class NetworkSession{
return false;
}
public function handleExplode(ExplodePacket $packet) : bool{
return false;
}
public function handleLevelSoundEventPacketV1(LevelSoundEventPacketV1 $packet) : bool{
return false;
}

View File

@ -248,7 +248,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
}
public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{
return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName);
return $this->player->changeSkin($packet->skin);
}
public function handleBookEdit(BookEditPacket $packet) : bool{

View File

@ -1,73 +0,0 @@
<?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 function count;
class ExplodePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::EXPLODE_PACKET;
/** @var Vector3 */
public $position;
/** @var float */
public $radius;
/** @var Vector3[] */
public $records = [];
public function clean(){
$this->records = [];
return parent::clean();
}
protected function decodePayload(){
$this->position = $this->getVector3();
$this->radius = (float) ($this->getVarInt() / 32);
$count = $this->getUnsignedVarInt();
for($i = 0; $i < $count; ++$i){
$x = $y = $z = null;
$this->getSignedBlockPosition($x, $y, $z);
$this->records[$i] = new Vector3($x, $y, $z);
}
}
protected function encodePayload(){
$this->putVector3($this->position);
$this->putVarInt((int) ($this->radius * 32));
$this->putUnsignedVarInt(count($this->records));
if(count($this->records) > 0){
foreach($this->records as $record){
$this->putSignedBlockPosition((int) $record->x, (int) $record->y, (int) $record->z);
}
}
}
public function handle(NetworkSession $session) : bool{
return $session->handleExplode($this);
}
}

View File

@ -54,7 +54,6 @@ class PacketPool{
static::registerPacket(new RiderJumpPacket());
static::registerPacket(new UpdateBlockPacket());
static::registerPacket(new AddPaintingPacket());
static::registerPacket(new ExplodePacket());
static::registerPacket(new LevelSoundEventPacketV1());
static::registerPacket(new LevelEventPacket());
static::registerPacket(new BlockEventPacket());

View File

@ -29,6 +29,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\entity\Skin;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use pocketmine\utils\SerializedImage;
use pocketmine\utils\SkinAnimation;
use function count;
class PlayerListPacket extends DataPacket{
@ -57,22 +59,32 @@ class PlayerListPacket extends DataPacket{
$entry->uuid = $this->getUUID();
$entry->entityUniqueId = $this->getEntityUniqueId();
$entry->username = $this->getString();
$skinId = $this->getString();
$skinData = $this->getString();
$capeData = $this->getString();
$geometryName = $this->getString();
$geometryData = $this->getString();
$entry->skin = new Skin(
$skinId,
$skinData,
$capeData,
$geometryName,
$geometryData
);
$entry->xboxUserId = $this->getString();
$entry->platformChatId = $this->getString();
$entry->buildPlatform = $this->getLInt();
$skinId = $this->getString();
$skinResourcePatch = $this->getString();
$skinData = $this->getImage();
$animations = [];
for($i = 0; $i < $this->getLInt(); ++$i){
$animations[] = new SkinAnimation($this->getImage(), $this->getLInt(), $this->getLFloat());
}
$capeData = $this->getImage();
$geometryData = $this->getString();
$animationData = $this->getString();
$premium = $this->getBool();
$persona = $this->getBool();
$capeOnClassic = $this->getBool();
$capeId = $this->getString();
$fullSkinId = $this->getString();
$entry->skin = new Skin(
$skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId
);
$entry->isTeacher = $this->getBool();
$entry->isHost = $this->getBool();
}else{
$entry->uuid = $this->getUUID();
}
@ -89,13 +101,30 @@ class PlayerListPacket extends DataPacket{
$this->putUUID($entry->uuid);
$this->putEntityUniqueId($entry->entityUniqueId);
$this->putString($entry->username);
$this->putString($entry->skin->getSkinId());
$this->putString($entry->skin->getSkinData());
$this->putString($entry->skin->getCapeData());
$this->putString($entry->skin->getGeometryName());
$this->putString($entry->skin->getGeometryData());
$this->putString($entry->xboxUserId);
$this->putString($entry->platformChatId);
$this->putLInt($entry->buildPlatform);
$this->putString($entry->skin->getSkinId());
$this->putString($entry->skin->getSkinResourcePatch());
$this->putImage($entry->skin->getSkinData());
$this->putLInt(count($entry->skin->getAnimations()));
foreach($entry->skin->getAnimations() as $animation){
$this->putImage($animation->getImage());
$this->putLInt($animation->getType());
$this->putLFloat($animation->getFrames());
}
$this->putImage($entry->skin->getCapeData());
$this->putString($entry->skin->getGeometryData());
$this->putString($entry->skin->getAnimationData());
$this->putBool($entry->skin->getPremium());
$this->putBool($entry->skin->getPersona());
$this->putBool($entry->skin->getCapeOnClassic());
$this->putString($entry->skin->getCapeId());
$this->putString($entry->skin->getFullSkinId());
$this->putBool($entry->isTeacher);
$this->putBool($entry->isHost);
}else{
$this->putUUID($entry->uuid);
}

View File

@ -27,6 +27,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\entity\Skin;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\utils\SerializedImage;
use pocketmine\utils\SkinAnimation;
use pocketmine\utils\UUID;
class PlayerSkinPacket extends DataPacket{
@ -34,43 +36,53 @@ class PlayerSkinPacket extends DataPacket{
/** @var UUID */
public $uuid;
/** @var string */
public $oldSkinName = "";
/** @var string */
public $newSkinName = "";
/** @var Skin */
public $skin;
/** @var bool */
public $premiumSkin = false;
protected function decodePayload(){
$this->uuid = $this->getUUID();
$skinId = $this->getString();
$this->newSkinName = $this->getString();
$this->oldSkinName = $this->getString();
$skinData = $this->getString();
$capeData = $this->getString();
$geometryModel = $this->getString();
$skinResourcePatch = $this->getString();
$skinData = $this->getImage();
$animations = [];
for($i = 0; $i < $this->getLInt(); ++$i){
$animations[] = new SkinAnimation($this->getImage(), $this->getLInt(), $this->getLFloat());
}
$capeData = $this->getImage();
$geometryData = $this->getString();
$animationData = $this->getString();
$premium = $this->getBool();
$persona = $this->getBool();
$capeOnClassic = $this->getBool();
$capeId = $this->getString();
$fullSkinId = $this->getString();
$this->skin = new Skin($skinId, $skinData, $capeData, $geometryModel, $geometryData);
$this->premiumSkin = $this->getBool();
$this->skin = new Skin(
$skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId
);
}
protected function encodePayload(){
$this->putUUID($this->uuid);
$this->putString($this->skin->getSkinId());
$this->putString($this->newSkinName);
$this->putString($this->oldSkinName);
$this->putString($this->skin->getSkinData());
$this->putString($this->skin->getCapeData());
$this->putString($this->skin->getGeometryName());
$this->putString($this->skin->getSkinResourcePatch());
$this->putImage($this->skin->getSkinData());
$this->putLInt(count($this->skin->getAnimations()));
foreach($this->skin->getAnimations() as $animation){
$this->putImage($animation->getImage());
$this->putLInt($animation->getType());
$this->putLFloat($animation->getFrames());
}
$this->putImage($this->skin->getCapeData());
$this->putString($this->skin->getGeometryData());
$this->putBool($this->premiumSkin);
$this->putString($this->skin->getAnimationData());
$this->putBool($this->skin->getPremium());
$this->putBool($this->skin->getPersona());
$this->putBool($this->skin->getCapeOnClassic());
$this->putString($this->skin->getCapeId());
$this->putString($this->skin->getFullSkinId());
}
public function handle(NetworkSession $session) : bool{

View File

@ -39,15 +39,15 @@ interface ProtocolInfo{
/**
* Actual Minecraft: PE protocol version
*/
public const CURRENT_PROTOCOL = 361;
public const CURRENT_PROTOCOL = 388;
/**
* Current Minecraft PE version reported by the server. This is usually the earliest currently supported version.
*/
public const MINECRAFT_VERSION = 'v1.12.0';
public const MINECRAFT_VERSION = 'v1.13.0';
/**
* Version number sent to clients in ping responses.
*/
public const MINECRAFT_VERSION_NETWORK = '1.12.0';
public const MINECRAFT_VERSION_NETWORK = '1.13.0';
public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02;
@ -71,7 +71,7 @@ interface ProtocolInfo{
public const RIDER_JUMP_PACKET = 0x14;
public const UPDATE_BLOCK_PACKET = 0x15;
public const ADD_PAINTING_PACKET = 0x16;
public const EXPLODE_PACKET = 0x17;
public const TICK_SYNC_PACKET = 0x17;
public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18;
public const LEVEL_EVENT_PACKET = 0x19;
public const BLOCK_EVENT_PACKET = 0x1a;
@ -185,5 +185,13 @@ interface ProtocolInfo{
public const UPDATE_BLOCK_PROPERTIES_PACKET = 0x86;
public const CLIENT_CACHE_BLOB_STATUS_PACKET = 0x87;
public const CLIENT_CACHE_MISS_RESPONSE_PACKET = 0x88;
public const EDUCATION_SETTINGS_PACKET = 0x89;
public const EMOTE_PACKET = 0x8a;
public const MULTIPLAYER_SETTINGS_PACKET = 0x8b;
public const SETTINGS_COMMAND_PACKET = 0x8c;
public const ANVIL_DAMAGE_PACKET = 0x8d;
public const COMPLETED_USING_ITEM_PACKET = 0x8e;
public const NETWORK_SETTINGS_PACKET = 0x8f;
public const PLAYER_AUTH_INPUT_PACKET = 0x90;
}

View File

@ -46,15 +46,14 @@ class ResourcePackChunkDataPacket extends DataPacket{
$this->packId = $this->getString();
$this->chunkIndex = $this->getLInt();
$this->progress = $this->getLLong();
$this->data = $this->get($this->getLInt());
$this->data = $this->getString();
}
protected function encodePayload(){
$this->putString($this->packId);
$this->putLInt($this->chunkIndex);
$this->putLLong($this->progress);
$this->putLInt(strlen($this->data));
$this->put($this->data);
$this->putString($this->data);
}
public function handle(NetworkSession $session) : bool{

View File

@ -34,13 +34,21 @@ class RespawnPacket extends DataPacket{
/** @var Vector3 */
public $position;
/** @var int */
public $respawnState = 1; //TODO: Add
/** @var int */
public $entityRuntimeId;
protected function decodePayload(){
$this->position = $this->getVector3();
$this->respawnState = $this->getInt();
$this->entityRuntimeId = $this->getEntityRuntimeId();
}
protected function encodePayload(){
$this->putVector3($this->position);
$this->putInt($this->respawnState);
$this->putEntityRuntimeId($this->entityRuntimeId);
}
public function handle(NetworkSession $session) : bool{

View File

@ -27,6 +27,10 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\math\Vector3;
use pocketmine\nbt\NetworkLittleEndianNBTStream;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\NetworkBinaryStream;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
@ -130,6 +134,8 @@ class StartGamePacket extends DataPacket{
/** @var bool */
public $onlySpawnV1Villagers = false;
/** @var string */
public $vanillaVersion = ProtocolInfo::MINECRAFT_VERSION_NETWORK;
/** @var string */
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
/** @var string */
@ -138,6 +144,8 @@ class StartGamePacket extends DataPacket{
public $premiumWorldTemplateId = "";
/** @var bool */
public $isTrial = false;
/** @var bool */
public $isMovementServerAuthoritative = false;
/** @var int */
public $currentTick = 0; //only used if isTrial is true
/** @var int */
@ -193,10 +201,12 @@ class StartGamePacket extends DataPacket{
$this->isWorldTemplateOptionLocked = $this->getBool();
$this->onlySpawnV1Villagers = $this->getBool();
$this->vanillaVersion = $this->getString();
$this->levelId = $this->getString();
$this->worldName = $this->getString();
$this->premiumWorldTemplateId = $this->getString();
$this->isTrial = $this->getBool();
$this->isMovementServerAuthoritative = $this->getBool();
$this->currentTick = $this->getLLong();
$this->enchantmentSeed = $this->getVarInt();
@ -263,10 +273,12 @@ class StartGamePacket extends DataPacket{
$this->putBool($this->isWorldTemplateOptionLocked);
$this->putBool($this->onlySpawnV1Villagers);
$this->putString($this->vanillaVersion);
$this->putString($this->levelId);
$this->putString($this->worldName);
$this->putString($this->premiumWorldTemplateId);
$this->putBool($this->isTrial);
$this->putBool($this->isMovementServerAuthoritative);
$this->putLLong($this->currentTick);
$this->putVarInt($this->enchantmentSeed);
@ -293,14 +305,27 @@ class StartGamePacket extends DataPacket{
}
private static function serializeBlockTable(array $table) : string{
$stream = new NetworkBinaryStream();
$states = new ListTag();
foreach($table as $v){
$state = new CompoundTag();
$state->setTag(new CompoundTag("block", [
new StringTag("name", $v["name"]),
$v["states"]
]));
$state->setShort("id", $v["legacy_id"]);
$states->push($state);
}
($stream = new NetworkLittleEndianNBTStream())->writeTag($states);
return $stream->buffer;
/*$stream = new NetworkBinaryStream();
$stream->putUnsignedVarInt(count($table));
foreach($table as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
$stream->putLShort($v["legacy_id"]);
}
return $stream->getBuffer();
return $stream->getBuffer();*/
}
private static function serializeItemTable(array $table) : string{

View File

@ -34,12 +34,18 @@ class PlayerListEntry{
public $entityUniqueId;
/** @var string */
public $username;
/** @var Skin */
public $skin;
/** @var string */
public $xboxUserId;
/** @var string */
public $platformChatId = "";
/** @var int */
public $buildPlatform = 0; //Unknown
/** @var Skin */
public $skin;
/** @var bool */
public $isTeacher = false;
/** @var bool */
public $isHost = false;
public static function createRemovalEntry(UUID $uuid) : PlayerListEntry{
$entry = new PlayerListEntry();
@ -48,7 +54,7 @@ class PlayerListEntry{
return $entry;
}
public static function createAdditionEntry(UUID $uuid, int $entityUniqueId, string $username, Skin $skin, string $xboxUserId = "", string $platformChatId = "") : PlayerListEntry{
public static function createAdditionEntry(UUID $uuid, int $entityUniqueId, string $username, Skin $skin, string $xboxUserId = "", string $platformChatId = "", int $buildPlatform = 0, bool $isTeacher = false, bool $isHost = false) : PlayerListEntry{
$entry = new PlayerListEntry();
$entry->uuid = $uuid;
$entry->entityUniqueId = $entityUniqueId;
@ -56,6 +62,9 @@ class PlayerListEntry{
$entry->skin = $skin;
$entry->xboxUserId = $xboxUserId;
$entry->platformChatId = $platformChatId;
$entry->buildPlatform = $buildPlatform;
$entry->isTeacher = $isTeacher;
$entry->isHost = $isHost;
return $entry;
}

View File

@ -29,6 +29,7 @@ final class ResourcePackType{
//NOOP
}
//Needs updated
public const INVALID = 0;
public const RESOURCES = 1;
public const BEHAVIORS = 2;

View File

@ -24,6 +24,9 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
use pocketmine\block\BlockIds;
use pocketmine\nbt\BigEndianNBTStream;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\utils\BinaryDataException;
use function file_get_contents;
use function getmypid;
use function json_decode;
@ -51,8 +54,29 @@ final class RuntimeBlockMapping{
$legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/block_id_map.json"), true);
$compressedTable = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/required_block_states.json"), true);
try{
/** @var CompoundTag $tag */
$tag = (new BigEndianNBTStream())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "runtime_block_states.dat"));
}catch(BinaryDataException $e){
throw new \RuntimeException("", 0, $e);
}
$decompressed = [];
$states = $tag->getListTag("Palette");
foreach($states as $state){
/** @var CompoundTag $state */
$block = $state->getCompoundTag("block");
$decompressed[] = [
"name" => $block->getString("name"),
"states" => $block->getCompoundTag("states"),
"data" => $state->getShort("meta"),
"legacy_id" => $state->getShort("id"),
];
}
/*
foreach($compressedTable as $prefix => $entries){
foreach($entries as $shortStringId => $states){
foreach($states as $state){
@ -63,8 +87,7 @@ final class RuntimeBlockMapping{
"legacy_id" => $legacyIdMap[$name]
];
}
}
}
}*/
self::$bedrockKnownStates = self::randomizeTable($decompressed);
foreach(self::$bedrockKnownStates as $k => $obj){

Binary file not shown.

View File

@ -0,0 +1,67 @@
<?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\utils;
class SerializedImage{
/** @var int */
private $height;
/** @var int */
private $width;
/** @var string */
private $data;
public function __construct(int $height, int $width, string $data){
$this->height = $height;
$this->width = $width;
$this->data = $data;
}
public static function fromLegacy(string $data) : SerializedImage{
switch(strlen($data)){
case 64 * 32 * 4:
return new self(64, 32, $data);
case 64 * 64 * 4:
return new self(64, 64, $data);
case 128 * 64 * 4:
return new self(128, 64, $data);
case 128 * 128 * 4:
return new self(128, 128, $data);
}
throw new \InvalidArgumentException("Unknown size");
}
public function getHeight() : int{
return $this->height;
}
public function getWidth() : int{
return $this->width;
}
public function getData() : string{
return $this->data;
}
}

View File

@ -0,0 +1,52 @@
<?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\utils;
class SkinAnimation{
/** @var SerializedImage */
private $image;
/** @var int */
private $type;
/** @var float */
private $frames;
public function __construct(SerializedImage $image, int $type, float $frames){
$this->image = $image;
$this->type = $type;
$this->frames = $frames;
}
public function getImage() : SerializedImage{
return $this->image;
}
public function getType() : int{
return $this->type;
}
public function getFrames() : float{
return $this->frames;
}
}