Initial spawn on 0.16

This commit is contained in:
Dylan K. Taylor 2016-10-04 12:29:26 +01:00
parent bb9ab525b6
commit dd0c5efb56
10 changed files with 239 additions and 117 deletions

View File

@ -132,9 +132,9 @@ use pocketmine\plugin\Plugin;
use pocketmine\tile\Sign;
use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile;
use pocketmine\utils\Binary;
use pocketmine\utils\TextFormat;
use pocketmine\utils\UUID;
use raklib\Binary;
/**
@ -1689,17 +1689,26 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$spawnPosition = $this->getSpawn();
$pk = new StartGamePacket();
$pk->seed = -1;
$pk->dimension = 0;
$pk->entityUniqueId = 0;
$pk->entityRuntimeId = 0;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->spawnX = (int) $spawnPosition->x;
$pk->spawnY = (int) $spawnPosition->y;
$pk->spawnZ = (int) $spawnPosition->z;
$pk->generator = 1; //0 old, 1 infinite, 2 flat
$pk->seed = -1;
$pk->dimension = 0; //TODO: implement this properly
$pk->gamemode = $this->gamemode & 0x01;
$pk->eid = 0; //Always use EntityID as zero for the actual player
$pk->difficulty = $this->server->getDifficulty();
$pk->spawnX = $spawnPosition->getFloorX();
$pk->spawnY = $spawnPosition->getFloorY();
$pk->spawnZ = $spawnPosition->getFloorZ();
$pk->hasBeenLoadedInCreative = 1;
$pk->dayCycleStopTime = -1; //TODO: implement this properly
$pk->eduMode = 0;
$pk->rainLevel = 0; //TODO: implement these properly
$pk->lightningLevel = 0;
$pk->commandsEnabled = 0;
$pk->unknown = "UNKNOWN";
$pk->worldName = $this->server->getMotd();
$this->dataPacket($pk);
$pk = new SetTimePacket();
@ -1707,20 +1716,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk->started = $this->level->stopTime == false;
$this->dataPacket($pk);
$pk = new SetSpawnPositionPacket();
$pk->x = (int) $spawnPosition->x;
$pk->y = (int) $spawnPosition->y;
$pk->z = (int) $spawnPosition->z;
$this->dataPacket($pk);
$pk = new SetHealthPacket();
$pk->health = $this->getHealth();
$this->dataPacket($pk);
$pk = new SetDifficultyPacket();
$pk->difficulty = $this->server->getDifficulty();
$this->dataPacket($pk);
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [
TextFormat::AQUA . $this->username . TextFormat::WHITE,
$this->ip,
@ -3504,7 +3503,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk->encode();
$batch = new BatchPacket();
$batch->payload = zlib_encode(Binary::writeInt(strlen($pk->getBuffer())) . $pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel);
$batch->payload = zlib_encode(Binary::writeUnsignedVarInt(strlen($pk->getBuffer())) . $pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel);
$batch->encode();
$batch->isEncoded = true;

View File

@ -75,8 +75,8 @@ namespace pocketmine {
const VERSION = "1.6dev";
const API_VERSION = "2.0.0";
const CODENAME = "Unleashed";
const MINECRAFT_VERSION = "v0.15.10.0 alpha";
const MINECRAFT_VERSION_NETWORK = "0.15.10.0";
const MINECRAFT_VERSION = "v0.15.90.7 alpha";
const MINECRAFT_VERSION_NETWORK = "0.15.90.7";
/*
* Startup code. Do not look at it, it may harm you.

View File

@ -1798,9 +1798,9 @@ class Server{
if(!$p->isEncoded){
$p->encode();
}
$str .= Binary::writeInt(strlen($p->buffer)) . $p->buffer;
$str .= Binary::writeUnsignedVarInt(strlen($p->buffer)) . $p->buffer;
}else{
$str .= Binary::writeInt(strlen($p)) . $p;
$str .= Binary::writeUnsignedVarInt(strlen($p)) . $p;
}
}

View File

@ -81,6 +81,7 @@ use pocketmine\network\protocol\UseItemPacket;
use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\Binary;
use pocketmine\utils\BinaryStream;
class Network{
@ -209,17 +210,19 @@ class Network{
public function processBatch(BatchPacket $packet, Player $p){
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
$len = strlen($str);
$offset = 0;
try{
while($offset < $len){
$pkLen = Binary::readInt(substr($str, $offset, 4));
$offset += 4;
$len = strlen($str);
$buf = substr($str, $offset, $pkLen);
$offset += $pkLen;
if($len === 0){
throw new \InvalidStateException("Empty or invalid BatchPacket received");
}
if(($pk = $this->getPacket(ord($buf{0}))) !== null){ // #blameshoghi
$stream = new BinaryStream($str);
while($stream->offset < $len){
$buf = $stream->getString();
if(($pk = $this->getPacket(ord($buf{0}))) !== null){
if($pk::NETWORK_ID === Info::BATCH_PACKET){
throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
}
@ -228,10 +231,6 @@ class Network{
$pk->decode();
$p->handleDataPacket($pk);
if($pk->getOffset() <= 0){
return;
}
}
}
}catch(\Throwable $e){

View File

@ -30,14 +30,12 @@ class BatchPacket extends DataPacket{
public $payload;
public function decode(){
$size = $this->getInt();
$this->payload = $this->get($size);
$this->payload = $this->getString();
}
public function encode(){
$this->reset();
$this->putInt(strlen($this->payload));
$this->put($this->payload);
$this->putString($this->payload);
}
}

View File

@ -30,7 +30,7 @@ interface Info{
/**
* Actual Minecraft: PE protocol version
*/
const CURRENT_PROTOCOL = 84;
const CURRENT_PROTOCOL = 90;
const LOGIN_PACKET = 0x01;
const PLAY_STATUS_PACKET = 0x02;
@ -45,57 +45,66 @@ interface Info{
const ADD_ENTITY_PACKET = 0x0b;
const REMOVE_ENTITY_PACKET = 0x0c;
const ADD_ITEM_ENTITY_PACKET = 0x0d;
const TAKE_ITEM_ENTITY_PACKET = 0x0e;
const MOVE_ENTITY_PACKET = 0x0f;
const MOVE_PLAYER_PACKET = 0x10;
const RIDER_JUMP_PACKET = 0x11;
const REMOVE_BLOCK_PACKET = 0x12;
const UPDATE_BLOCK_PACKET = 0x13;
const ADD_PAINTING_PACKET = 0x14;
const EXPLODE_PACKET = 0x15;
const LEVEL_EVENT_PACKET = 0x16;
const BLOCK_EVENT_PACKET = 0x17;
const ENTITY_EVENT_PACKET = 0x18;
const MOB_EFFECT_PACKET = 0x19;
const UPDATE_ATTRIBUTES_PACKET = 0x1a;
const MOB_EQUIPMENT_PACKET = 0x1b;
const MOB_ARMOR_EQUIPMENT_PACKET = 0x1c;
const INTERACT_PACKET = 0x1e;
const USE_ITEM_PACKET = 0x1f;
const PLAYER_ACTION_PACKET = 0x20;
const HURT_ARMOR_PACKET = 0x21;
const SET_ENTITY_DATA_PACKET = 0x22;
const SET_ENTITY_MOTION_PACKET = 0x23;
const SET_ENTITY_LINK_PACKET = 0x24;
const SET_HEALTH_PACKET = 0x25;
const SET_SPAWN_POSITION_PACKET = 0x26;
const ANIMATE_PACKET = 0x27;
const RESPAWN_PACKET = 0x28;
const DROP_ITEM_PACKET = 0x29;
const CONTAINER_OPEN_PACKET = 0x2a;
const CONTAINER_CLOSE_PACKET = 0x2b;
const CONTAINER_SET_SLOT_PACKET = 0x2c;
const CONTAINER_SET_DATA_PACKET = 0x2d;
const CONTAINER_SET_CONTENT_PACKET = 0x2e;
const CRAFTING_DATA_PACKET = 0x2f;
const CRAFTING_EVENT_PACKET = 0x30;
const ADVENTURE_SETTINGS_PACKET = 0x31;
const BLOCK_ENTITY_DATA_PACKET = 0x32;
const PLAYER_INPUT_PACKET = 0x33;
const FULL_CHUNK_DATA_PACKET = 0x34;
const SET_DIFFICULTY_PACKET = 0x35;
const CHANGE_DIMENSION_PACKET = 0x36;
const SET_PLAYER_GAMETYPE_PACKET = 0x37;
const PLAYER_LIST_PACKET = 0x38;
const TELEMETRY_EVENT_PACKET = 0x39;
const SPAWN_EXPERIENCE_ORB_PACKET = 0x3a;
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x3b;
const MAP_INFO_REQUEST_PACKET = 0x3c;
const REQUEST_CHUNK_RADIUS_PACKET = 0x3d;
const CHUNK_RADIUS_UPDATED_PACKET = 0x3e;
const ITEM_FRAME_DROP_ITEM_PACKET = 0x3f;
const REPLACE_SELECTED_ITEM_PACKET = 0x40;
const ADD_ITEM_PACKET = 0x41;
const ADD_HANGING_ENTITY_PACKET = 0x0e;
const TAKE_ITEM_ENTITY_PACKET = 0x0f;
const MOVE_ENTITY_PACKET = 0x10;
const MOVE_PLAYER_PACKET = 0x11;
const RIDER_JUMP_PACKET = 0x12;
const REMOVE_BLOCK_PACKET = 0x13;
const UPDATE_BLOCK_PACKET = 0x14;
const ADD_PAINTING_PACKET = 0x15;
const EXPLODE_PACKET = 0x16;
const LEVEL_SOUND_EVENT_PACKET = 0x17;
const LEVEL_EVENT_PACKET = 0x18;
const BLOCK_EVENT_PACKET = 0x19;
const ENTITY_EVENT_PACKET = 0x1a;
const MOB_EFFECT_PACKET = 0x1b;
const UPDATE_ATTRIBUTES_PACKET = 0x1c;
const MOB_EQUIPMENT_PACKET = 0x1d;
const MOB_ARMOR_EQUIPMENT_PACKET = 0x1e;
const INTERACT_PACKET = 0x1f;
const USE_ITEM_PACKET = 0x20;
const PLAYER_ACTION_PACKET = 0x21;
const HURT_ARMOR_PACKET = 0x22;
const SET_ENTITY_DATA_PACKET = 0x23;
const SET_ENTITY_MOTION_PACKET = 0x24;
const SET_ENTITY_LINK_PACKET = 0x25;
const SET_HEALTH_PACKET = 0x26;
const SET_SPAWN_POSITION_PACKET = 0x27;
const ANIMATE_PACKET = 0x28;
const RESPAWN_PACKET = 0x29;
const DROP_ITEM_PACKET = 0x2a;
const INVENTORY_ACTION_PACKET = 0x2b;
const CONTAINER_OPEN_PACKET = 0x2c;
const CONTAINER_CLOSE_PACKET = 0x2d;
const CONTAINER_SET_SLOT_PACKET = 0x2e;
const CONTAINER_SET_DATA_PACKET = 0x2f;
const CONTAINER_SET_CONTENT_PACKET = 0x30;
const CRAFTING_DATA_PACKET = 0x31;
const CRAFTING_EVENT_PACKET = 0x32;
const ADVENTURE_SETTINGS_PACKET = 0x33;
const BLOCK_ENTITY_DATA_PACKET = 0x34;
const PLAYER_INPUT_PACKET = 0x35;
const FULL_CHUNK_DATA_PACKET = 0x36;
const SET_COMMANDS_ENABLED_PACKET = 0x37;
const SET_DIFFICULTY_PACKET = 0x38;
const CHANGE_DIMENSION_PACKET = 0x39;
const SET_PLAYER_GAMETYPE_PACKET = 0x3a;
const PLAYER_LIST_PACKET = 0x3b;
const TELEMETRY_EVENT_PACKET = 0x3c;
const SPAWN_EXPERIENCE_ORB_PACKET = 0x3d;
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x3e;
const MAP_INFO_REQUEST_PACKET = 0x3f;
const REQUEST_CHUNK_RADIUS_PACKET = 0x40;
const CHUNK_RADIUS_UPDATED_PACKET = 0x41;
const ITEM_FRAME_DROP_ITEM_PACKET = 0x42;
const REPLACE_SELECTED_ITEM_PACKET = 0x43;
const GAME_RULES_CHANGED_PACKET = 0x44;
const CAMERA_PACKET = 0x45;
const ADD_ITEM_PACKET = 0x46;
const BOSS_EVENT_PACKET = 0x47;
const AVAILABLE_COMMANDS_PACKET = 0x48;
const COMMAND_STEP_PACKET = 0x49;
}

View File

@ -27,9 +27,11 @@ namespace pocketmine\network\protocol;
class LoginPacket extends DataPacket{
const NETWORK_ID = Info::LOGIN_PACKET;
const EDITION_POCKET = 0;
public $username;
public $protocol;
public $gameEdition;
public $clientUUID;
public $clientId;
public $identityPublicKey;
@ -44,7 +46,10 @@ class LoginPacket extends DataPacket{
if($this->protocol !== Info::CURRENT_PROTOCOL){
return; //Do not attempt to decode for non-accepted protocols
}
$str = zlib_decode($this->get($this->getInt()), 1024 * 1024 * 64);
$this->gameEdition = $this->getByte();
$str = zlib_decode($this->getString(), 1024 * 1024 * 64);
$this->setBuffer($str, 0);

View File

@ -27,18 +27,27 @@ namespace pocketmine\network\protocol;
class StartGamePacket extends DataPacket{
const NETWORK_ID = Info::START_GAME_PACKET;
public $seed;
public $dimension;
public $generator;
public $gamemode;
public $eid;
public $spawnX;
public $spawnY;
public $spawnZ;
public $entityUniqueId;
public $entityRuntimeId;
public $x;
public $y;
public $z;
public $seed;
public $dimension;
public $generator = 1; //default infinite - 0 old, 1 infinite, 2 flat
public $gamemode;
public $difficulty;
public $spawnX;
public $spawnY;
public $spawnZ;
public $hasBeenLoadedInCreative = 1;
public $dayCycleStopTime = -1; //-1 = not stopped, any positive value = stopped at that time
public $eduMode = 0;
public $rainLevel;
public $lightningLevel;
public $commandsEnabled;
public $unknown;
public $worldName;
public function decode(){
@ -46,21 +55,25 @@ class StartGamePacket extends DataPacket{
public function encode(){
$this->reset();
$this->putInt($this->seed);
$this->putByte($this->dimension);
$this->putInt($this->generator);
$this->putInt($this->gamemode);
$this->putLong($this->eid);
$this->putInt($this->spawnX);
$this->putInt($this->spawnY);
$this->putInt($this->spawnZ);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putByte(1);
$this->putByte(1);
$this->putByte(0);
$this->putEntityId($this->entityUniqueId); //EntityUniqueID
$this->putEntityId($this->entityRuntimeId); //EntityRuntimeID
$this->putVector3f($this->x, $this->y, $this->z);
$this->putLFloat(0); //TODO: find out what these are (yaw/pitch?)
$this->putLFloat(0);
$this->putVarInt($this->seed);
$this->putVarInt($this->dimension);
$this->putVarInt($this->generator);
$this->putVarInt($this->gamemode);
$this->putVarInt($this->difficulty);
$this->putBlockCoords($this->spawnX, $this->spawnY, $this->spawnZ);
$this->putByte($this->hasBeenLoadedInCreative);
$this->putVarInt($this->dayCycleStopTime);
$this->putByte($this->eduMode);
$this->putLFloat($this->rainLevel);
$this->putLFloat($this->lightningLevel);
$this->putByte($this->commandsEnabled);
$this->putString($this->unknown);
$this->putString($this->worldName);
}
}

View File

@ -428,8 +428,45 @@ class Binary{
return self::readLong(strrev($str));
}
//TODO: varlong, length checks
public static function writeLLong($value){
return strrev(self::writeLong($value));
}
public static function readVarInt($stream){
$raw = self::readUnsignedVarInt($stream);
$temp = ((($raw << 31) >> 31) ^ $raw) >> 1;
return $temp ^ ($raw & (1 << 31));
}
public static function readUnsignedVarInt($stream){
$value = 0;
$i = 0;
do{
$value |= ((($b = $stream->getByte()) & 0x7f) << $i);
$i += 7;
}while($b & 0x80);
return $value;
}
public static function writeVarInt($v){
return self::writeUnsignedVarInt(($v << 1) ^ ($v >> 31));
}
public static function writeUnsignedVarInt($v){
$buf = "";
do{
$w = $v & 0x7f;
if(($v >> 7) !== 0){
$w = $v | 0x80;
}
$buf .= self::writeByte($w);
$v >>= 7;
}while($v);
return $buf;
}
}

View File

@ -233,14 +233,76 @@ class BinaryStream extends \stdClass{
}
public function getString(){
return $this->get($this->getShort());
return $this->get($this->getUnsignedVarInt());
}
public function putString($v){
$this->putShort(strlen($v));
$this->putUnsignedVarInt(strlen($v));
$this->put($v);
}
//TODO: varint64
/**
* Reads an unsigned varint32 from the stream.
*/
public function getUnsignedVarInt(){
return Binary::readUnsignedVarInt($this);
}
/**
* Writes an unsigned varint32 to the stream.
*/
public function putUnsignedVarInt($v){
$this->put(Binary::writeUnsignedVarInt($v));
}
/**
* Reads a signed varint32 from the stream.
*/
public function getVarInt(){
return Binary::readVarInt($this);
}
/**
* Writes a signed varint32 to the stream.
*/
public function putVarInt($v){
$this->put(Binary::writeVarInt($v));
}
public function getEntityId(){
return $this->getVarInt();
}
public function putEntityId($v){
$this->putVarInt($v);
}
public function getBlockCoords(&$x, &$y, &$z){
$x = $this->getVarInt();
$y = $this->getByte();
$z = $this->getVarInt();
}
public function putBlockCoords(int $x, int $y, int $z){
$this->putVarInt($x);
$this->putByte($y);
$this->putVarInt($z);
}
public function getVector3f(&$x, &$y, &$z){
$x = $this->getLFloat();
$y = $this->getLFloat();
$z = $this->getLFloat();
}
public function putVector3f(float $x, float $y, float $z){
$this->putLFloat($x);
$this->putLFloat($y);
$this->putLFloat($z);
}
public function feof(){
return !isset($this->buffer{$this->offset});
}