Protocol changes for 1.6.0.1

This commit is contained in:
Dylan K. Taylor 2018-06-15 19:24:23 +01:00
parent 6fce2b3349
commit 986077e03c
15 changed files with 266 additions and 42 deletions

View File

@ -193,9 +193,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
*/ */
protected $sessionAdapter; protected $sessionAdapter;
/** @var int */
protected $protocol = -1;
/** @var string */ /** @var string */
protected $ip; protected $ip;
/** @var int */ /** @var int */
@ -1839,8 +1836,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false; return false;
} }
$this->protocol = $packet->protocol;
if($packet->protocol !== ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol !== ProtocolInfo::CURRENT_PROTOCOL){
if($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL){
$this->sendPlayStatus(PlayStatusPacket::LOGIN_FAILED_CLIENT, true); $this->sendPlayStatus(PlayStatusPacket::LOGIN_FAILED_CLIENT, true);
@ -1923,7 +1918,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public function sendPlayStatus(int $status, bool $immediate = false){ public function sendPlayStatus(int $status, bool $immediate = false){
$pk = new PlayStatusPacket(); $pk = new PlayStatusPacket();
$pk->status = $status; $pk->status = $status;
$pk->protocol = $this->protocol;
$this->sendDataPacket($pk, false, $immediate); $this->sendDataPacket($pk, false, $immediate);
} }

View File

@ -421,8 +421,8 @@ class BlockFactory{
public static function registerStaticRuntimeIdMappings() : void{ public static function registerStaticRuntimeIdMappings() : void{
/** @var mixed[] $runtimeIdMap */ /** @var mixed[] $runtimeIdMap */
$runtimeIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true); $runtimeIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
foreach($runtimeIdMap as $obj){ foreach($runtimeIdMap as $k => $obj){
self::registerMapping($obj["runtimeID"], $obj["id"], $obj["data"]); self::registerMapping($k, $obj["id"], $obj["data"]);
} }
} }

View File

@ -79,6 +79,7 @@ use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;
use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket;
use pocketmine\network\mcpe\protocol\MoveEntityDeltaPacket; use pocketmine\network\mcpe\protocol\MoveEntityDeltaPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket;
use pocketmine\network\mcpe\protocol\NpcRequestPacket; use pocketmine\network\mcpe\protocol\NpcRequestPacket;
use pocketmine\network\mcpe\protocol\PhotoTransferPacket; use pocketmine\network\mcpe\protocol\PhotoTransferPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket; use pocketmine\network\mcpe\protocol\PlaySoundPacket;
@ -115,6 +116,7 @@ use pocketmine\network\mcpe\protocol\SetLastHurtByPacket;
use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket;
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
use pocketmine\network\mcpe\protocol\SetScorePacket; use pocketmine\network\mcpe\protocol\SetScorePacket;
use pocketmine\network\mcpe\protocol\SetScoreboardIdentityPacket;
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\SetTimePacket;
use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\SetTitlePacket;
@ -134,6 +136,7 @@ use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket; use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket;
use pocketmine\network\mcpe\protocol\UpdateEquipPacket; use pocketmine\network\mcpe\protocol\UpdateEquipPacket;
use pocketmine\network\mcpe\protocol\UpdateSoftEnumPacket;
use pocketmine\network\mcpe\protocol\UpdateTradePacket; use pocketmine\network\mcpe\protocol\UpdateTradePacket;
use pocketmine\network\mcpe\protocol\WSConnectPacket; use pocketmine\network\mcpe\protocol\WSConnectPacket;
@ -585,7 +588,19 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleSetScoreboardIdentity(SetScoreboardIdentityPacket $packet) : bool{
return false;
}
public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{
return false; return false;
} }
public function handleUpdateSoftEnum(UpdateSoftEnumPacket $packet) : bool{
return false;
}
public function handleNetworkStackLatency(NetworkStackLatencyPacket $packet) : bool{
return false;
}
} }

View File

@ -46,7 +46,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
* Sometimes this gets changed when the MCPE-layer protocol gets broken to the point where old and new can't * Sometimes this gets changed when the MCPE-layer protocol gets broken to the point where old and new can't
* communicate. It's important that we check this to avoid catastrophes. * communicate. It's important that we check this to avoid catastrophes.
*/ */
private const MCPE_RAKNET_PROTOCOL_VERSION = 8; private const MCPE_RAKNET_PROTOCOL_VERSION = 9;
/** @var Server */ /** @var Server */
private $server; private $server;

View File

@ -74,10 +74,6 @@ abstract class DataPacket extends NetworkBinaryStream{
protected function decodeHeader(){ protected function decodeHeader(){
$pid = $this->getUnsignedVarInt(); $pid = $this->getUnsignedVarInt();
assert($pid === static::NETWORK_ID); assert($pid === static::NETWORK_ID);
$this->senderSubId = $this->getByte();
$this->recipientSubId = $this->getByte();
assert($this->senderSubId === 0 and $this->recipientSubId === 0, "Got unexpected non-zero split-screen bytes (byte1: $this->senderSubId, byte2: $this->recipientSubId");
} }
/** /**
@ -96,9 +92,6 @@ abstract class DataPacket extends NetworkBinaryStream{
protected function encodeHeader(){ protected function encodeHeader(){
$this->putUnsignedVarInt(static::NETWORK_ID); $this->putUnsignedVarInt(static::NETWORK_ID);
$this->putByte($this->senderSubId);
$this->putByte($this->recipientSubId);
} }
/** /**

View File

@ -79,13 +79,6 @@ class LoginPacket extends DataPacket{
protected function decodePayload(){ protected function decodePayload(){
$this->protocol = $this->getInt(); $this->protocol = $this->getInt();
if($this->protocol !== ProtocolInfo::CURRENT_PROTOCOL){
if($this->protocol > 0xffff){ //guess MCPE <= 1.1
$this->offset -= 6;
$this->protocol = $this->getInt();
}
}
try{ try{
$this->decodeConnectionRequest(); $this->decodeConnectionRequest();
}catch(\Throwable $e){ }catch(\Throwable $e){

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 NetworkStackLatencyPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::NETWORK_STACK_LATENCY_PACKET;
/** @var int */
public $timestamp;
protected function decodePayload(){
$this->timestamp = $this->getLLong();
}
protected function encodePayload(){
$this->putLLong($this->timestamp);
}
public function handle(NetworkSession $session) : bool{
return $session->handleNetworkStackLatency($this);
}
}

View File

@ -142,7 +142,10 @@ class PacketPool{
static::registerPacket(new LabTablePacket()); static::registerPacket(new LabTablePacket());
static::registerPacket(new UpdateBlockSyncedPacket()); static::registerPacket(new UpdateBlockSyncedPacket());
static::registerPacket(new MoveEntityDeltaPacket()); static::registerPacket(new MoveEntityDeltaPacket());
static::registerPacket(new SetScoreboardIdentityPacket());
static::registerPacket(new SetLocalPlayerAsInitializedPacket()); static::registerPacket(new SetLocalPlayerAsInitializedPacket());
static::registerPacket(new UpdateSoftEnumPacket());
static::registerPacket(new NetworkStackLatencyPacket());
static::registerPacket(new BatchPacket()); static::registerPacket(new BatchPacket());
} }

View File

@ -43,12 +43,6 @@ class PlayStatusPacket extends DataPacket{
/** @var int */ /** @var int */
public $status; public $status;
/**
* @var int
* Used to determine how to write the packet when we disconnect incompatible clients.
*/
public $protocol = ProtocolInfo::CURRENT_PROTOCOL;
protected function decodePayload(){ protected function decodePayload(){
$this->status = $this->getInt(); $this->status = $this->getInt();
} }
@ -57,14 +51,6 @@ class PlayStatusPacket extends DataPacket{
return true; return true;
} }
protected function encodeHeader(){
if($this->protocol < 130){ //MCPE <= 1.1
$this->putByte(static::NETWORK_ID);
}else{
parent::encodeHeader();
}
}
protected function encodePayload(){ protected function encodePayload(){
$this->putInt($this->status); $this->putInt($this->status);
} }

View File

@ -39,15 +39,15 @@ interface ProtocolInfo{
/** /**
* Actual Minecraft: PE protocol version * Actual Minecraft: PE protocol version
*/ */
public const CURRENT_PROTOCOL = 274; public const CURRENT_PROTOCOL = 280;
/** /**
* Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version.
*/ */
public const MINECRAFT_VERSION = 'v1.5.0'; public const MINECRAFT_VERSION = 'v1.6.0.1 beta';
/** /**
* Version number sent to clients in ping responses. * Version number sent to clients in ping responses.
*/ */
public const MINECRAFT_VERSION_NETWORK = '1.5.0'; public const MINECRAFT_VERSION_NETWORK = '1.6.0.1';
public const LOGIN_PACKET = 0x01; public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02; public const PLAY_STATUS_PACKET = 0x02;
@ -160,6 +160,9 @@ interface ProtocolInfo{
public const LAB_TABLE_PACKET = 0x6d; public const LAB_TABLE_PACKET = 0x6d;
public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e; public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e;
public const MOVE_ENTITY_DELTA_PACKET = 0x6f; public const MOVE_ENTITY_DELTA_PACKET = 0x6f;
public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x70; public const SET_SCOREBOARD_IDENTITY_PACKET = 0x70;
public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71;
public const UPDATE_SOFT_ENUM_PACKET = 0x72;
public const NETWORK_STACK_LATENCY_PACKET = 0x73;
} }

View File

@ -0,0 +1,69 @@
<?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;
use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry;
class SetScoreboardIdentityPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::SET_SCOREBOARD_IDENTITY_PACKET;
public const TYPE_REGISTER_IDENTITY = 0;
public const TYPE_CLEAR_IDENTITY = 1;
/** @var int */
public $type;
/** @var ScoreboardIdentityPacketEntry[] */
public $entries = [];
protected function decodePayload(){
$this->type = $this->getByte();
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$entry = new ScoreboardIdentityPacketEntry();
$entry->scoreboardId = $this->getVarLong();
if($this->type === self::TYPE_REGISTER_IDENTITY){
$entry->uuid = $this->getUUID();
}
$this->entries[] = $entry;
}
}
protected function encodePayload(){
$this->putByte($this->type);
$this->putUnsignedVarInt(count($this->entries));
foreach($this->entries as $entry){
$this->putVarLong($entry->scoreboardId);
if($this->type === self::TYPE_REGISTER_IDENTITY){
$this->putUUID($entry->uuid);
}
}
}
public function handle(NetworkSession $session) : bool{
return $session->handleSetScoreboardIdentity($this);
}
}

View File

@ -27,12 +27,16 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkBinaryStream;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
class StartGamePacket extends DataPacket{ class StartGamePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET;
/** @var string|null */
private static $runtimeIdTable;
/** @var int */ /** @var int */
public $entityUniqueId; public $entityUniqueId;
/** @var int */ /** @var int */
@ -175,6 +179,12 @@ class StartGamePacket extends DataPacket{
$this->currentTick = $this->getLLong(); $this->currentTick = $this->getLLong();
$this->enchantmentSeed = $this->getVarInt(); $this->enchantmentSeed = $this->getVarInt();
$count = $this->getUnsignedVarInt();
for($i = 0; $i < $count; ++$i){
$this->getString();
$this->getLShort();
}
} }
protected function encodePayload(){ protected function encodePayload(){
@ -226,6 +236,19 @@ class StartGamePacket extends DataPacket{
$this->putLLong($this->currentTick); $this->putLLong($this->currentTick);
$this->putVarInt($this->enchantmentSeed); $this->putVarInt($this->enchantmentSeed);
if(self::$runtimeIdTable === null){
//this is a really nasty hack, but it'll do for now
$stream = new NetworkBinaryStream();
$data = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
$stream->putUnsignedVarInt(count($data));
foreach($data as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
}
self::$runtimeIdTable = $stream->buffer;
}
$this->put(self::$runtimeIdTable);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{

View File

@ -0,0 +1,64 @@
<?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 UpdateSoftEnumPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::UPDATE_SOFT_ENUM_PACKET;
public const TYPE_ADD = 0;
public const TYPE_REMOVE = 1;
public const TYPE_SET = 2;
/** @var string */
public $enumName;
/** @var string[] */
public $values = [];
/** @var int */
public $type;
protected function decodePayload(){
$this->enumName = $this->getString();
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$this->values[] = $this->getString();
}
$this->type = $this->getByte();
}
protected function encodePayload(){
$this->putString($this->enumName);
$this->putUnsignedVarInt(count($this->values));
foreach($this->values as $v){
$this->putString($v);
}
$this->putByte($this->type);
}
public function handle(NetworkSession $session) : bool{
return $session->handleUpdateSoftEnum($this);
}
}

View File

@ -0,0 +1,34 @@
<?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\types;
use pocketmine\utils\UUID;
class ScoreboardIdentityPacketEntry{
/** @var int */
public $scoreboardId;
/** @var UUID|null */
public $uuid;
}

File diff suppressed because one or more lines are too long