Made some changes for 0.12

This commit is contained in:
Shoghi Cervantes 2015-06-26 13:49:38 -07:00 committed by Shoghi Cervantes
parent 0380e9009a
commit 4258e22c02
18 changed files with 227 additions and 108 deletions

View File

@ -127,6 +127,7 @@ use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use raklib\Binary;
/**
* Main class that handles networking, recovery, and packet sending to the server part
@ -652,7 +653,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
}
}
public function sendChunk($x, $z, $payload){
public function sendChunk($x, $z, $payload, $ordering = FullChunkDataPacket::ORDER_COLUMNS){
if($this->connected === false){
return;
}
@ -666,6 +667,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk = new FullChunkDataPacket();
$pk->chunkX = $x;
$pk->chunkZ = $z;
$pk->order = $ordering;
$pk->data = $payload;
$this->batchDataPacket($pk->setChannel($this->spawned ? Network::CHANNEL_WORLD_CHUNKS : Network::CHANNEL_PRIORITY));
}
@ -1944,8 +1946,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->craftingType = 0;
$packet->eid = $this->id;
if($packet->face >= 0 and $packet->face <= 5){ //Use Block, place
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false);
@ -1956,7 +1956,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
break;
}
}elseif($this->inventory->getItemInHand()->getId() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
}elseif(!$this->inventory->getItemInHand()->equals($packet->item, true)){
$this->inventory->sendHeldItem($this);
}else{
$item = $this->inventory->getItemInHand();
@ -1986,7 +1986,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
if($this->isCreative()){
$item = $this->inventory->getItemInHand();
}elseif($this->inventory->getItemInHand()->getId() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
}elseif(!$this->inventory->getItemInHand()->equals($packet->item, true)){
$this->inventory->sendHeldItem($this);
break;
}else{
@ -3423,15 +3423,16 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
*
* @return DataPacket
*/
public static function getChunkCacheFromData($chunkX, $chunkZ, $payload){
public static function getChunkCacheFromData($chunkX, $chunkZ, $payload, $ordering = FullChunkDataPacket::ORDER_COLUMNS){
$pk = new FullChunkDataPacket();
$pk->chunkX = $chunkX;
$pk->chunkZ = $chunkZ;
$pk->order = $ordering;
$pk->data = $payload;
$pk->encode();
$batch = new BatchPacket();
$batch->payload = zlib_encode($pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel);
$batch->payload = zlib_encode(Binary::writeInt(strlen($pk->getBuffer())) . $pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel);
$batch->setChannel(Network::CHANNEL_WORLD_CHUNKS);
$batch->encode();

View File

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

View File

@ -33,6 +33,8 @@ use pocketmine\entity\Zombie;
use pocketmine\inventory\Fuel;
use pocketmine\level\Level;
use pocketmine\Player;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\NBT;
class Item{
//All Block IDs are here too
@ -402,6 +404,7 @@ class Item{
protected $block;
protected $id;
protected $meta;
protected $nbt;
public $count;
protected $durability = 0;
protected $name;
@ -846,18 +849,18 @@ class Item{
return -1;
}
public static function get($id, $meta = 0, $count = 1){
public static function get($id, $meta = 0, $count = 1, $nbt = ""){
try{
$class = self::$list[$id];
if($class === null){
return new Item($id, $meta, $count);
return (new Item($id, $meta, $count))->setCompoundTag($nbt);
}elseif($id < 256){
return new ItemBlock(new $class($meta), $meta, $count);
return (new ItemBlock(new $class($meta), $meta, $count))->setCompoundTag($nbt);
}else{
return new $class($meta, $count);
return (new $class($meta, $count))->setCompoundTag($nbt);
}
}catch(\RuntimeException $e){
return new Item($id, $meta, $count);
return (new Item($id, $meta, $count))->setCompoundTag($nbt);
}
}
@ -900,7 +903,41 @@ class Item{
$this->name = $this->block->getName();
}
}
public function setCompoundTag($nbt){
if($nbt instanceof Compound){
$this->setNamedTag($nbt);
}else{
$this->nbt = $nbt;
}
return $this;
}
public function getCompoundTag(){
return $this->nbt;
}
public function hasCompoundTag(){
return $this->nbt !== "";
}
public function getNamedTag(){
if($this->nbt === ""){
return null;
}
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->read($this->nbt);
return $nbt->getData();
}
public function setNamedTag(Compound $tag){
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->setData($tag);
$this->nbt = $nbt->write($this->nbt);
return $this;
}
public function getCount(){
return $this->count;

View File

@ -89,6 +89,7 @@ use pocketmine\nbt\tag\Short;
use pocketmine\nbt\tag\String;
use pocketmine\network\Network;
use pocketmine\network\protocol\DataPacket;
use pocketmine\network\protocol\FullChunkDataPacket;
use pocketmine\network\protocol\LevelEventPacket;
use pocketmine\network\protocol\MoveEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket;
@ -2301,13 +2302,13 @@ class Level implements ChunkManager, Metadatable{
}
}
public function chunkRequestCallback($x, $z, $payload){
public function chunkRequestCallback($x, $z, $payload, $ordering = FullChunkDataPacket::ORDER_COLUMNS){
$this->timings->syncChunkSendTimer->startTiming();
$index = Level::chunkHash($x, $z);
if(!isset($this->chunkCache[$index]) and $this->cacheChunks and $this->server->getMemoryManager()->canUseChunkCache()){
$this->chunkCache[$index] = Player::getChunkCacheFromData($x, $z, $payload);
$this->chunkCache[$index] = Player::getChunkCacheFromData($x, $z, $payload, $ordering);
$this->sendChunkFromCache($x, $z);
$this->timings->syncChunkSendTimer->stopTiming();
return;
@ -2317,7 +2318,7 @@ class Level implements ChunkManager, Metadatable{
foreach($this->chunkSendQueue[$index] as $player){
/** @var Player $player */
if($player->isConnected() and isset($player->usedChunks[$index])){
$player->sendChunk($x, $z, $payload);
$player->sendChunk($x, $z, $payload, $ordering);
}
}
unset($this->chunkSendQueue[$index]);

View File

@ -24,9 +24,12 @@ namespace pocketmine\level\format\anvil;
use pocketmine\level\format\FullChunk;
use pocketmine\level\format\mcregion\McRegion;
use pocketmine\level\Level;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\ByteArray;
use pocketmine\nbt\tag\Compound;
use pocketmine\network\protocol\FullChunkDataPacket;
use pocketmine\tile\Spawnable;
use pocketmine\utils\ChunkException;
class Anvil extends McRegion{
@ -66,7 +69,36 @@ class Anvil extends McRegion{
}
public function requestChunkTask($x, $z){
return new ChunkRequestTask($this->getLevel(), $this->getChunk($x, $z, true));
$chunk = $this->getChunk($x, $z, false);
if(!($chunk instanceof Chunk)){
throw new ChunkException("Invalid Chunk sent");
}
$tiles = "";
if(count($chunk->getTiles()) > 0){
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$list = [];
foreach($chunk->getTiles() as $tile){
if($tile instanceof Spawnable){
$list[] = $tile->getSpawnCompound();
}
}
$nbt->setData($list);
$tiles = $nbt->write();
}
$ordered = $chunk->getBlockIdArray() .
$chunk->getBlockDataArray() .
$chunk->getBlockSkyLightArray() .
$chunk->getBlockLightArray() .
pack("C*", ...$chunk->getHeightMapArray()) .
pack("N*", ...$chunk->getBiomeColorArray()) .
$tiles;
$this->getLevel()->chunkRequestCallback($x, $z, $ordered, FullChunkDataPacket::ORDER_LAYERED);
return null;
}
/**

View File

@ -133,17 +133,12 @@ class McRegion extends BaseLevelProvider{
$tiles = $nbt->write();
}
$heightmap = pack("C*", ...$chunk->getHeightMapArray());
$biomeColors = pack("N*", ...$chunk->getBiomeColorArray());
$ordered = $chunk->getBlockIdArray() .
$chunk->getBlockDataArray() .
$chunk->getBlockSkyLightArray() .
$chunk->getBlockLightArray() .
$heightmap .
$biomeColors .
pack("C*", ...$chunk->getHeightMapArray()) .
pack("N*", ...$chunk->getBiomeColorArray()) .
$tiles;
$this->getLevel()->chunkRequestCallback($x, $z, $ordered);

View File

@ -74,6 +74,7 @@ use pocketmine\network\protocol\UpdateBlockPacket;
use pocketmine\network\protocol\UseItemPacket;
use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\Binary;
use pocketmine\utils\MainLogger;
class Network{
@ -219,14 +220,22 @@ class Network{
$offset = 0;
try{
while($offset < $len){
if(($pk = $this->getPacket(ord($str{$offset++}))) !== null){
$pkLen = Binary::readInt(substr($str, $offset, 4));
$offset += 4;
$buf = substr($str, $offset, $pkLen);
$offset += $pkLen;
if(($pk = $this->getPacket(ord($buf{0}))) !== null){
if($pk::NETWORK_ID === Info::BATCH_PACKET){
throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
}
$pk->setBuffer($str, $offset);
$pk->setBuffer($buf, 1);
$pk->decode();
$p->handleDataPacket($pk);
$offset += $pk->getOffset();
if($pk->getOffset() <= 0){
return;
}

View File

@ -163,20 +163,45 @@ abstract class DataPacket extends \stdClass{
}
protected function getSlot(){
$id = $this->getShort();
$id = $this->getShort(false);
if($id == 0xffff){
return Item::get(0, 0, 0);
}
$cnt = $this->getByte();
$data = $this->getShort();
$nbtLen = $this->getShort();
$nbt = "";
if($nbtLen > 0){
$nbt = $this->get($nbtLen);
}
return Item::get(
$id,
$this->getShort(),
$cnt
$data,
$cnt,
$nbt
);
}
protected function putSlot(Item $item){
if($item->getId() === 0){
$this->putShort(0xffff);
return;
}
$this->putShort($item->getId());
$this->putByte($item->getCount());
$this->putShort($item->getDamage());
$nbt = $item->getCompoundTag();
$this->putShort(strlen($nbt));
$this->put($nbt);
}
protected function getString(){
@ -198,4 +223,4 @@ abstract class DataPacket extends \stdClass{
$this->offset = 0;
return $this;
}
}
}

View File

@ -26,9 +26,13 @@ namespace pocketmine\network\protocol;
class FullChunkDataPacket extends DataPacket{
const NETWORK_ID = Info::FULL_CHUNK_DATA_PACKET;
const ORDER_COLUMNS = 0;
const ORDER_LAYERED = 1;
public $chunkX;
public $chunkZ;
public $order = self::ORDER_COLUMNS;
public $data;
public function decode(){
@ -39,8 +43,9 @@ class FullChunkDataPacket extends DataPacket{
$this->reset();
$this->putInt($this->chunkX);
$this->putInt($this->chunkZ);
$this->putByte($this->order);
$this->putInt(strlen($this->data));
$this->put($this->data);
}
}
}

View File

@ -30,66 +30,63 @@ interface Info{
/**
* Actual Minecraft: PE protocol version
*/
const CURRENT_PROTOCOL = 27;
const CURRENT_PROTOCOL = 28;
const LOGIN_PACKET = 0x82;
const PLAY_STATUS_PACKET = 0x83;
const DISCONNECT_PACKET = 0x84;
const TEXT_PACKET = 0x85;
const SET_TIME_PACKET = 0x86;
const START_GAME_PACKET = 0x87;
const ADD_PLAYER_PACKET = 0x88;
const REMOVE_PLAYER_PACKET = 0x89;
const ADD_ENTITY_PACKET = 0x8a;
const REMOVE_ENTITY_PACKET = 0x8b;
const ADD_ITEM_ENTITY_PACKET = 0x8c;
const TAKE_ITEM_ENTITY_PACKET = 0x8d;
const MOVE_ENTITY_PACKET = 0x8e;
const MOVE_PLAYER_PACKET = 0x8f;
const REMOVE_BLOCK_PACKET = 0x90;
const UPDATE_BLOCK_PACKET = 0x91;
const ADD_PAINTING_PACKET = 0x92;
const EXPLODE_PACKET = 0x93;
const LEVEL_EVENT_PACKET = 0x94;
const TILE_EVENT_PACKET = 0x95;
const ENTITY_EVENT_PACKET = 0x96;
const MOB_EFFECT_PACKET = 0x97;
const PLAYER_EQUIPMENT_PACKET = 0x98;
const PLAYER_ARMOR_EQUIPMENT_PACKET = 0x99;
const INTERACT_PACKET = 0x9a;
const USE_ITEM_PACKET = 0x9b;
const PLAYER_ACTION_PACKET = 0x9c;
const HURT_ARMOR_PACKET = 0x9d;
const SET_ENTITY_DATA_PACKET = 0x9e;
const SET_ENTITY_MOTION_PACKET = 0x9f;
const SET_ENTITY_LINK_PACKET = 0xa0;
const SET_HEALTH_PACKET = 0xa1;
const SET_SPAWN_POSITION_PACKET = 0xa2;
const ANIMATE_PACKET = 0xa3;
const RESPAWN_PACKET = 0xa4;
const DROP_ITEM_PACKET = 0xa5;
const CONTAINER_OPEN_PACKET = 0xa6;
const CONTAINER_CLOSE_PACKET = 0xa7;
const CONTAINER_SET_SLOT_PACKET = 0xa8;
const CONTAINER_SET_DATA_PACKET = 0xa9;
const CONTAINER_SET_CONTENT_PACKET = 0xaa;
//const CONTAINER_ACK_PACKET = 0xab;
const ADVENTURE_SETTINGS_PACKET = 0xac;
const TILE_ENTITY_DATA_PACKET = 0xad;
//const PLAYER_INPUT_PACKET = 0xae;
const FULL_CHUNK_DATA_PACKET = 0xaf;
const SET_DIFFICULTY_PACKET = 0xb0;
const BATCH_PACKET = 0xb1;
const DISCONNECT_PACKET = 0x84;
const BATCH_PACKET = 0x85;
const TEXT_PACKET = 0x86;
const SET_TIME_PACKET = 0x87;
const START_GAME_PACKET = 0x88;
const ADD_PLAYER_PACKET = 0x89;
const REMOVE_PLAYER_PACKET = 0x8a;
const ADD_ENTITY_PACKET = 0x8b;
const REMOVE_ENTITY_PACKET = 0x8c;
const ADD_ITEM_ENTITY_PACKET = 0x8d;
const TAKE_ITEM_ENTITY_PACKET = 0x8e;
const MOVE_ENTITY_PACKET = 0x8f;
const MOVE_PLAYER_PACKET = 0x90;
const REMOVE_BLOCK_PACKET = 0x91;
const UPDATE_BLOCK_PACKET = 0x92;
const ADD_PAINTING_PACKET = 0x93;
const EXPLODE_PACKET = 0x94;
const LEVEL_EVENT_PACKET = 0x95;
const TILE_EVENT_PACKET = 0x96;
const ENTITY_EVENT_PACKET = 0x97;
const MOB_EFFECT_PACKET = 0x98;
const UPDATE_ATTRIBUTES_PACKET = 0x99;
const PLAYER_EQUIPMENT_PACKET = 0x9a;
const PLAYER_ARMOR_EQUIPMENT_PACKET = 0x9b;
const INTERACT_PACKET = 0x9c;
const USE_ITEM_PACKET = 0x9d;
const PLAYER_ACTION_PACKET = 0x9e;
const HURT_ARMOR_PACKET = 0x9f;
const SET_ENTITY_DATA_PACKET = 0xa0;
const SET_ENTITY_MOTION_PACKET = 0xa1;
const SET_ENTITY_LINK_PACKET = 0xa2;
const SET_HEALTH_PACKET = 0xa3;
const SET_SPAWN_POSITION_PACKET = 0xa4;
const ANIMATE_PACKET = 0xa5;
const RESPAWN_PACKET = 0xa6;
const DROP_ITEM_PACKET = 0xa7;
const CONTAINER_OPEN_PACKET = 0xa8;
const CONTAINER_CLOSE_PACKET = 0xa9;
const CONTAINER_SET_SLOT_PACKET = 0xaa;
const CONTAINER_SET_DATA_PACKET = 0xab;
const CONTAINER_SET_CONTENT_PACKET = 0xac;
const ADVENTURE_SETTINGS_PACKET = 0xad;
const TILE_ENTITY_DATA_PACKET = 0xae;
//const PLAYER_INPUT_PACKET = 0xaf;
const FULL_CHUNK_DATA_PACKET = 0xb0;
const SET_DIFFICULTY_PACKET = 0xb1;
//const CHANGE_DIMENSION_PACKET = 0xb2;
//const SET_PLAYER_GAMETYPE_PACKET = 0xb3;
//const PLAYER_LIST_PACKET = 0xb4;
}

View File

@ -39,11 +39,11 @@ class LoginPacket extends DataPacket{
$this->username = $this->getString();
$this->protocol1 = $this->getInt();
$this->protocol2 = $this->getInt();
$this->clientId = $this->getInt();
if($this->protocol1 < 21){ //New fields!
if($this->protocol1 < 22){ //New fields!
$this->setBuffer(null, 0); //Skip batch packet handling
return;
}
$this->clientId = $this->getLong();
$this->slim = $this->getByte() > 0;
$this->skin = $this->getString();
}

View File

@ -28,8 +28,8 @@ class SetSpawnPositionPacket extends DataPacket{
const NETWORK_ID = Info::SET_SPAWN_POSITION_PACKET;
public $x;
public $z;
public $y;
public $z;
public function decode(){
@ -38,8 +38,8 @@ class SetSpawnPositionPacket extends DataPacket{
public function encode(){
$this->reset();
$this->putInt($this->x);
$this->putInt($this->y);
$this->putInt($this->z);
$this->putByte($this->y);
}
}
}

View File

@ -39,7 +39,7 @@ class SetTimePacket extends DataPacket{
public function encode(){
$this->reset();
$this->putInt((int) (($this->time / Level::TIME_FULL) * 19200));
$this->putByte($this->started == true ? 0x80 : 0x00);
$this->putByte($this->started ? 1 : 0);
}
}
}

View File

@ -28,6 +28,7 @@ class StartGamePacket extends DataPacket{
const NETWORK_ID = Info::START_GAME_PACKET;
public $seed;
public $dimension;
public $generator;
public $gamemode;
public $eid;
@ -45,6 +46,7 @@ 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);

View File

@ -34,7 +34,7 @@ class TileEntityDataPacket extends DataPacket{
public function decode(){
$this->x = $this->getInt();
$this->y = $this->getByte();
$this->y = $this->getInt();
$this->z = $this->getInt();
$this->namedtag = $this->get(true);
}
@ -42,7 +42,7 @@ class TileEntityDataPacket extends DataPacket{
public function encode(){
$this->reset();
$this->putInt($this->x);
$this->putByte($this->y);
$this->putInt($this->y);
$this->putInt($this->z);
$this->put($this->namedtag);
}

View File

@ -32,8 +32,6 @@ class UseItemPacket extends DataPacket{
public $z;
public $face;
public $item;
public $meta;
public $eid;
public $fx;
public $fy;
public $fz;
@ -46,15 +44,14 @@ class UseItemPacket extends DataPacket{
$this->y = $this->getInt();
$this->z = $this->getInt();
$this->face = $this->getByte();
$this->item = $this->getShort();
$this->meta = $this->getShort();
$this->eid = $this->getLong();
$this->fx = $this->getFloat();
$this->fy = $this->getFloat();
$this->fz = $this->getFloat();
$this->posX = $this->getFloat();
$this->posY = $this->getFloat();
$this->posZ = $this->getFloat();
$this->item = $this->getSlot();
}
public function encode(){

View File

@ -111,7 +111,11 @@ class Chest extends Spawnable implements InventoryHolder, Container{
if($i < 0){
return Item::get(Item::AIR, 0, 0);
}else{
return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
$item = Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
if(isset($this->namedtag->Items[$i]["tag"])){
$item->setNamedTag($this->namedtag->Items[$i]["tag"]);
}
return $item;
}
}
@ -132,6 +136,11 @@ class Chest extends Spawnable implements InventoryHolder, Container{
new Short("id", $item->getId()),
new Short("Damage", $item->getDamage()),
]);
if($item->hasCompoundTag() and ($tag = $item->getNamedTag()) !== null){
$tag->setName("tag");
$d->tag = $tag;
}
if($item->getId() === Item::AIR or $item->getCount() <= 0){
if($i >= 0){
@ -270,4 +279,4 @@ class Chest extends Spawnable implements InventoryHolder, Container{
]);
}
}
}
}

View File

@ -120,7 +120,11 @@ class Furnace extends Tile implements InventoryHolder, Container{
if($i < 0){
return Item::get(Item::AIR, 0, 0);
}else{
return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
$item = Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
if(isset($this->namedtag->Items[$i]["tag"])){
$item->setNamedTag($this->namedtag->Items[$i]["tag"]);
}
return $item;
}
}
@ -141,6 +145,11 @@ class Furnace extends Tile implements InventoryHolder, Container{
new Short("id", $item->getId()),
new Short("Damage", $item->getDamage()),
]);
if($item->hasCompoundTag() and ($tag = $item->getNamedTag()) !== null){
$tag->setName("tag");
$d->tag = $tag;
}
if($item->getId() === Item::AIR or $item->getCount() <= 0){
if($i >= 0){