diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index dac695b85..4f97edf69 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2908,7 +2908,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function handleBookEdit(BookEditPacket $packet) : bool{ /** @var WritableBook $oldBook */ - $oldBook = $this->inventory->getItem($packet->inventorySlot - 9); + $oldBook = $this->inventory->getItem($packet->inventorySlot); if($oldBook->getId() !== Item::WRITABLE_BOOK){ return false; } @@ -2949,7 +2949,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - $this->getInventory()->setItem($packet->inventorySlot - 9, $event->getNewBook()); + $this->getInventory()->setItem($packet->inventorySlot, $event->getNewBook()); return true; } @@ -3255,7 +3255,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function sendWhisper(string $sender, string $message){ $pk = new TextPacket(); $pk->type = TextPacket::TYPE_WHISPER; - $pk->source = $sender; + $pk->sourceName = $sender; $pk->message = $message; $this->dataPacket($pk); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 6aedf35a3..8b3264fbc 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2339,7 +2339,8 @@ class Server{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_ADD; - $pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, $skin); + $pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, "", 0, $skin); + $this->broadcastPacket($players ?? $this->playerList, $pk); } @@ -2361,7 +2362,7 @@ class Server{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_ADD; foreach($this->playerList as $player){ - $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin()); + $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), "", 0, $player->getSkin()); } $p->dataPacket($pk); diff --git a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php index a70425e4b..1b7318308 100644 --- a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php @@ -44,6 +44,8 @@ class AddItemEntityPacket extends DataPacket{ public $motion; /** @var array */ public $metadata = []; + /** @var bool */ + public $bool1 = false; protected function decodePayload(){ $this->entityUniqueId = $this->getEntityUniqueId(); @@ -52,6 +54,7 @@ class AddItemEntityPacket extends DataPacket{ $this->position = $this->getVector3(); $this->motion = $this->getVector3(); $this->metadata = $this->getEntityMetadata(); + $this->bool1 = $this->getBool(); } protected function encodePayload(){ @@ -61,6 +64,7 @@ class AddItemEntityPacket extends DataPacket{ $this->putVector3($this->position); $this->putVector3Nullable($this->motion); $this->putEntityMetadata($this->metadata); + $this->putBool($this->bool1); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index 22c7c2263..330371b75 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -38,10 +38,16 @@ class AddPlayerPacket extends DataPacket{ public $uuid; /** @var string */ public $username; + /** @var string */ + public $thirdPartyName = ""; + /** @var int */ + public $platform = 0; /** @var int|null */ public $entityUniqueId = null; //TODO /** @var int */ public $entityRuntimeId; + /** @var string */ + public $string1 = ""; /** @var Vector3 */ public $position; /** @var Vector3|null */ @@ -72,8 +78,11 @@ class AddPlayerPacket extends DataPacket{ protected function decodePayload(){ $this->uuid = $this->getUUID(); $this->username = $this->getString(); + $this->thirdPartyName = $this->getString(); + $this->platform = $this->getVarInt(); $this->entityUniqueId = $this->getEntityUniqueId(); $this->entityRuntimeId = $this->getEntityRuntimeId(); + $this->string1 = $this->getString(); $this->position = $this->getVector3(); $this->motion = $this->getVector3(); $this->pitch = $this->getLFloat(); @@ -99,8 +108,11 @@ class AddPlayerPacket extends DataPacket{ protected function encodePayload(){ $this->putUUID($this->uuid); $this->putString($this->username); + $this->putString($this->thirdPartyName); + $this->putVarInt($this->platform); $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $this->putEntityRuntimeId($this->entityRuntimeId); + $this->putString($this->string1); $this->putVector3($this->position); $this->putVector3Nullable($this->motion); $this->putLFloat($this->pitch); diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php index 335720f1c..d211b7f15 100644 --- a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php @@ -54,6 +54,8 @@ class BookEditPacket extends DataPacket{ public $title; /** @var string */ public $author; + /** @var string */ + public $xuid; protected function decodePayload(){ $this->type = $this->getByte(); @@ -76,6 +78,7 @@ class BookEditPacket extends DataPacket{ case self::TYPE_SIGN_BOOK: $this->title = $this->getString(); $this->author = $this->getString(); + $this->xuid = $this->getString(); break; default: throw new \UnexpectedValueException("Unknown book edit type $this->type!"); @@ -103,6 +106,7 @@ class BookEditPacket extends DataPacket{ case self::TYPE_SIGN_BOOK: $this->putString($this->title); $this->putString($this->author); + $this->putString($this->xuid); break; default: throw new \UnexpectedValueException("Unknown book edit type $this->type!"); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php index 0aa4be7ff..969270982 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php @@ -31,6 +31,9 @@ use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\utils\Binary; #endif +/** + * One of the most useless packets. + */ class PlayerHotbarPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET; @@ -38,28 +41,18 @@ class PlayerHotbarPacket extends DataPacket{ public $selectedHotbarSlot; /** @var int */ public $windowId = ContainerIds::INVENTORY; - /** @var int[] */ - public $slots = []; /** @var bool */ public $selectHotbarSlot = true; protected function decodePayload(){ $this->selectedHotbarSlot = $this->getUnsignedVarInt(); $this->windowId = $this->getByte(); - $count = $this->getUnsignedVarInt(); - for($i = 0; $i < $count; ++$i){ - $this->slots[$i] = Binary::signInt($this->getUnsignedVarInt()); - } $this->selectHotbarSlot = $this->getBool(); } protected function encodePayload(){ $this->putUnsignedVarInt($this->selectedHotbarSlot); $this->putByte($this->windowId); - $this->putUnsignedVarInt(count($this->slots)); - foreach($this->slots as $slot){ - $this->putUnsignedVarInt($slot); - } $this->putBool($this->selectHotbarSlot); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 6e28dc02f..1b92810a9 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -56,14 +56,28 @@ class PlayerListPacket extends DataPacket{ $entry->uuid = $this->getUUID(); $entry->entityUniqueId = $this->getEntityUniqueId(); $entry->username = $this->getString(); + $entry->thirdPartyName = $this->getString(); + $entry->platform = $this->getVarInt(); + + $skinId = $this->getString(); + $this->getLInt(); //always 1 + $skinData = $this->getString(); + $capeData = ""; + if($this->getLInt() !== 0){ + $capeData = $this->getString(); + } + $geometryName = $this->getString(); + $geometryData = $this->getString(); + $entry->skin = new Skin( - $this->getString(), //id - $this->getString(), //data - $this->getString(), //cape - $this->getString(), //geometry name - $this->getString() //geometry data + $skinId, + $skinData, + $capeData, + $geometryName, + $geometryData ); $entry->xboxUserId = $this->getString(); + $this->getString(); //unknown }else{ $entry->uuid = $this->getUUID(); } @@ -80,12 +94,24 @@ class PlayerListPacket extends DataPacket{ $this->putUUID($entry->uuid); $this->putEntityUniqueId($entry->entityUniqueId); $this->putString($entry->username); + $this->putString($entry->thirdPartyName); + $this->putVarInt($entry->platform); $this->putString($entry->skin->getSkinId()); + + $this->putLInt(1); $this->putString($entry->skin->getSkinData()); - $this->putString($entry->skin->getCapeData()); + + $capeData = $entry->skin->getCapeData(); + if($capeData !== ""){ + $this->putLInt(1); + $this->putString($capeData); + }else{ + $this->putLInt(0); + } $this->putString($entry->skin->getGeometryName()); $this->putString($entry->skin->getGeometryData()); $this->putString($entry->xboxUserId); + $this->putString(""); }else{ $this->putUUID($entry->uuid); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index 2fa531419..165d16d7d 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -48,8 +48,15 @@ class PlayerSkinPacket extends DataPacket{ $skinId = $this->getString(); $this->newSkinName = $this->getString(); $this->oldSkinName = $this->getString(); + + $this->getLInt(); //always 1 + $this->getLInt(); //length, unneeded $skinData = $this->getString(); + + $this->getLInt(); //0 if there's no cape, 1 if there is + $this->getLInt(); //length, again unneeded. $capeData = $this->getString(); + $geometryModel = $this->getString(); $geometryData = $this->getString(); @@ -62,8 +69,17 @@ class PlayerSkinPacket extends DataPacket{ $this->putString($this->skin->getSkinId()); $this->putString($this->newSkinName); $this->putString($this->oldSkinName); - $this->putString($this->skin->getSkinData()); - $this->putString($this->skin->getCapeData()); + + $skinData = $this->skin->getSkinData(); + $this->putLInt(1); + $this->putLInt(strlen($skinData)); + $this->putString($skinData); + + $capeData = $this->skin->getCapeData(); + $this->putLInt($capeData !== "" ? 1 : 0); + $this->putLInt(strlen($capeData)); + $this->putString($capeData); + $this->putString($this->skin->getGeometryName()); $this->putString($this->skin->getGeometryData()); } diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php index b7e0641bc..2be3ef491 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -39,15 +39,15 @@ interface ProtocolInfo{ /** * Actual Minecraft: PE protocol version */ - public const CURRENT_PROTOCOL = 201; + public const CURRENT_PROTOCOL = 200; /** * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - public const MINECRAFT_VERSION = 'v1.2.10'; + public const MINECRAFT_VERSION = 'v1.2.10.1 beta'; /** * Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.2.10'; + public const MINECRAFT_VERSION_NETWORK = '1.2.10.1'; public const LOGIN_PACKET = 0x01; public const PLAY_STATUS_PACKET = 0x02; diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index f7923239f..f7ee2b280 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -98,6 +98,12 @@ class StartGamePacket extends DataPacket{ public $xboxLiveBroadcastMode = 0; //TODO: find values /** @var int */ public $serverChunkTickRadius = 4; //TODO (leave as default for now) + /** @var bool */ + public $hasPlatformBroadcast = false; + /** @var int */ + public $platformBroadcastMode = 0; + /** @var bool */ + public $xboxLiveBroadcastIntent = false; /** @var string */ public $levelId = ""; //base64 string, usually the same as world folder name in vanilla @@ -146,6 +152,9 @@ class StartGamePacket extends DataPacket{ $this->defaultPlayerPermission = $this->getVarInt(); $this->xboxLiveBroadcastMode = $this->getVarInt(); $this->serverChunkTickRadius = $this->getLInt(); + $this->hasPlatformBroadcast = $this->getBool(); + $this->platformBroadcastMode = $this->getUnsignedVarInt(); + $this->xboxLiveBroadcastIntent = $this->getBool(); $this->levelId = $this->getString(); $this->worldName = $this->getString(); @@ -190,6 +199,9 @@ class StartGamePacket extends DataPacket{ $this->putVarInt($this->defaultPlayerPermission); $this->putVarInt($this->xboxLiveBroadcastMode); $this->putLInt($this->serverChunkTickRadius); + $this->putBool($this->hasPlatformBroadcast); + $this->putUnsignedVarInt($this->platformBroadcastMode); + $this->putBool($this->xboxLiveBroadcastIntent); $this->putString($this->levelId); $this->putString($this->worldName); diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index 71b606b82..a321665c9 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -46,13 +46,19 @@ class TextPacket extends DataPacket{ /** @var bool */ public $needsTranslation = false; /** @var string */ - public $source; + public $sourceName; + /** @var string */ + public $sourceThirdPartyName = ""; + /** @var int */ + public $sourcePlatform = 0; /** @var string */ public $message; /** @var string[] */ public $parameters = []; /** @var string */ public $xboxUserId = ""; + /** @var string */ + public $string1 = ""; protected function decodePayload(){ $this->type = $this->getByte(); @@ -62,7 +68,9 @@ class TextPacket extends DataPacket{ case self::TYPE_WHISPER: /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_ANNOUNCEMENT: - $this->source = $this->getString(); + $this->sourceName = $this->getString(); + $this->sourceThirdPartyName = $this->getString(); + $this->sourcePlatform = $this->getVarInt(); case self::TYPE_RAW: case self::TYPE_TIP: case self::TYPE_SYSTEM: @@ -81,6 +89,7 @@ class TextPacket extends DataPacket{ } $this->xboxUserId = $this->getString(); + $this->string1 = $this->getString(); } protected function encodePayload(){ @@ -91,7 +100,9 @@ class TextPacket extends DataPacket{ case self::TYPE_WHISPER: /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_ANNOUNCEMENT: - $this->putString($this->source); + $this->putString($this->sourceName); + $this->putString($this->sourceThirdPartyName); + $this->putVarInt($this->sourcePlatform); case self::TYPE_RAW: case self::TYPE_TIP: case self::TYPE_SYSTEM: @@ -110,6 +121,7 @@ class TextPacket extends DataPacket{ } $this->putString($this->xboxUserId); + $this->putString($this->string1); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php b/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php index fd8d4bfb5..4f7db5ba0 100644 --- a/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php +++ b/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php @@ -34,6 +34,12 @@ class PlayerListEntry{ public $entityUniqueId; /** @var string */ public $username; + /** @var string */ + public $thirdPartyName = ""; + /** @var int */ + public $platform = 0; + /** @var string */ + public $string1 = ""; /** @var Skin */ public $skin; /** @var string */ @@ -46,11 +52,13 @@ class PlayerListEntry{ return $entry; } - public static function createAdditionEntry(UUID $uuid, int $entityUniqueId, string $username, Skin $skin, string $xboxUserId = "") : PlayerListEntry{ + public static function createAdditionEntry(UUID $uuid, int $entityUniqueId, string $username, string $thirdPartyName, int $platform, Skin $skin, string $xboxUserId = "") : PlayerListEntry{ $entry = new PlayerListEntry(); $entry->uuid = $uuid; $entry->entityUniqueId = $entityUniqueId; $entry->username = $username; + $entry->thirdPartyName = $thirdPartyName; + $entry->platform = $platform; $entry->skin = $skin; $entry->xboxUserId = $xboxUserId;