Updated NBT library to remove read overhead

This commit is contained in:
Shoghi Cervantes 2014-03-12 22:40:19 +01:00
parent cc5a30a0c2
commit 63542a2f13
32 changed files with 446 additions and 500 deletions

View File

@ -333,7 +333,7 @@ $this->updateMetadata();
}else{ }else{
$hasUpdate = true; $hasUpdate = true;
} }
if(($this->player instanceof Player) and ($this->player->gamemode & 0x01) === CREATIVE){ //Remove fire effects in next tick if(($this->player instanceof Player) and ($this->player->gamemode & 0x01) === 1){ //Remove fire effects in next tick
$this->fire = 1; $this->fire = 1;
} }
} }

View File

@ -21,7 +21,7 @@
namespace PocketMine; namespace PocketMine;
use PocketMine\Block\Block; use PocketMine\Block;
use PocketMine\Item\Item; use PocketMine\Item\Item;
use PocketMine\Level\Level; use PocketMine\Level\Level;
use PocketMine\Level\Position; use PocketMine\Level\Position;
@ -196,10 +196,12 @@ class BlockAPI{
[Item::CLOCK, 0], [Item::CLOCK, 0],
[Item::COMPASS, 0], [Item::COMPASS, 0],
[Item::MINECART, 0], [Item::MINECART, 0],
[Item::SPAWN_EGG, MOB_CHICKEN], [Item::SPAWN_EGG, 10], //Chicken
[Item::SPAWN_EGG, MOB_COW], [Item::SPAWN_EGG, 11], //Cow
[Item::SPAWN_EGG, MOB_PIG], [Item::SPAWN_EGG, 12], //Pig
[Item::SPAWN_EGG, MOB_SHEEP], [Item::SPAWN_EGG, 13], //Sheep
//TODO: Replace with Entity constants
//Seeds //Seeds
[Item::SUGARCANE, 0], [Item::SUGARCANE, 0],
@ -230,35 +232,6 @@ class BlockAPI{
); );
public static function fromString($str, $multiple = false){
if($multiple === true){
$blocks = array();
foreach(explode(",", $str) as $b){
$blocks[] = BlockAPI::fromString($b, false);
}
return $blocks;
} else{
$b = explode(":", str_replace(" ", "_", trim($str)));
if(!isset($b[1])){
$meta = 0;
} else{
$meta = ((int) $b[1]) & 0xFFFF;
}
if(defined(strtoupper($b[0]))){
$item = Item::get(constant(strtoupper($b[0])), $meta);
if($item->getID() === AIR and strtoupper($b[0]) !== "AIR"){
$item = Item::get(((int) $b[0]) & 0xFFFF, $meta);
}
} else{
$item = Item::get(((int) $b[0]) & 0xFFFF, $meta);
}
return $item;
}
}
function __construct(){ function __construct(){
$this->server = ServerAPI::request(); $this->server = ServerAPI::request();
} }
@ -306,7 +279,7 @@ class BlockAPI{
return $output; return $output;
} }
private function cancelAction(Block $block, Player $player, $send = true){ private function cancelAction(Block\Block $block, Player $player, $send = true){
$pk = new UpdateBlockPacket; $pk = new UpdateBlockPacket;
$pk->x = $block->x; $pk->x = $block->x;
$pk->y = $block->y; $pk->y = $block->y;
@ -321,7 +294,7 @@ class BlockAPI{
return false; return false;
} }
public function playerBlockBreak(Player $player, Math\Math\Vector3 $vector){ public function playerBlockBreak(Player $player, Math\Vector3 $vector){
$target = $player->level->getBlock($vector); $target = $player->level->getBlock($vector);
$item = $player->getSlot($player->slot); $item = $player->getSlot($player->slot);
@ -345,7 +318,7 @@ class BlockAPI{
return $this->cancelAction($target, $player, false); return $this->cancelAction($target, $player, false);
} }
if(($player->gamemode & 0x01) === 0 and $item->useOn($target) and $item->getMetadata() >= $item->getMaxDurability()){ if(($player->gamemode & 0x01) === 0 and $item->useOn($target) and $item->getMetadata() >= $item->getMaxDurability()){
$player->setSlot($player->slot, new Item(AIR, 0, 0)); $player->setSlot($player->slot, new Item(Item::AIR, 0, 0));
} }
} else{ } else{
return $this->cancelAction($target, $player, false); return $this->cancelAction($target, $player, false);
@ -362,7 +335,7 @@ class BlockAPI{
return false; return false;
} }
public function playerBlockAction(Player $player, Math\Math\Vector3 $vector, $face, $fx, $fy, $fz){ public function playerBlockAction(Player $player, Math\Vector3 $vector, $face, $fx, $fy, $fz){
if($face < 0 or $face > 5){ if($face < 0 or $face > 5){
return false; return false;
} }
@ -375,7 +348,7 @@ class BlockAPI{
$item = Item::get(BlockAPI::$creative[$player->slot][0], BlockAPI::$creative[$player->slot][1], 1); $item = Item::get(BlockAPI::$creative[$player->slot][0], BlockAPI::$creative[$player->slot][1], 1);
} }
if($target->getID() === AIR and $this->server->api->dhandle("player.block.place.invalid", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== true){ //If no block exists or not allowed in CREATIVE if($target->getID() === Item::AIR and $this->server->api->dhandle("player.block.place.invalid", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== true){ //If no block exists or not allowed in CREATIVE
if($this->server->api->dhandle("player.block.place.bypass", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== true){ if($this->server->api->dhandle("player.block.place.bypass", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== true){
$this->cancelAction($target, $player); $this->cancelAction($target, $player);
@ -408,7 +381,7 @@ class BlockAPI{
if($item->isActivable === true and $item->onActivate($player->level, $player, $block, $target, $face, $fx, $fy, $fz) === true){ if($item->isActivable === true and $item->onActivate($player->level, $player, $block, $target, $face, $fx, $fy, $fz) === true){
if($item->getCount() <= 0){ if($item->getCount() <= 0){
$player->setSlot($player->slot, Item::get(AIR, 0, 0)); $player->setSlot($player->slot, Item::get(Item::AIR, 0, 0));
} }
return false; return false;
@ -417,15 +390,15 @@ class BlockAPI{
if($item->isPlaceable()){ if($item->isPlaceable()){
$hand = $item->getBlock(); $hand = $item->getBlock();
$hand->position($block); $hand->position($block);
} elseif($block->getID() === FIRE){ } elseif($block->getID() === Item::FIRE){
$player->level->setBlock($block, new Block\AirBlock(), true, false, true); $player->level->setBlock($block, new Block\Air(), true, false, true);
return false; return false;
} else{ } else{
return $this->cancelAction($block, $player, false); return $this->cancelAction($block, $player, false);
} }
if(!($block->isReplaceable === true or ($hand->getID() === SLAB and $block->getID() === SLAB))){ if(!($block->isReplaceable === true or ($hand->getID() === Item::SLAB and $block->getID() === Item::SLAB))){
return $this->cancelAction($block, $player, false); return $this->cancelAction($block, $player, false);
} }
@ -445,24 +418,24 @@ class BlockAPI{
} elseif($hand->place($item, $player, $block, $target, $face, $fx, $fy, $fz) === false){ } elseif($hand->place($item, $player, $block, $target, $face, $fx, $fy, $fz) === false){
return $this->cancelAction($block, $player, false); return $this->cancelAction($block, $player, false);
} }
if($hand->getID() === SIGN_POST or $hand->getID() === WALL_SIGN){ if($hand->getID() === Item::SIGN_POST or $hand->getID() === Item::WALL_SIGN){
new Sign($player->level, new Compound(false, array( new Sign($player->level, new Compound(false, array(
"id" => new String("id", Tile::Sign), new String("id", Tile\Tile::SIGN),
"x" => new Int("x", $block->x), new Int("x", $block->x),
"y" => new Int("y", $block->y), new Int("y", $block->y),
"z" => new Int("z", $block->z), new Int("z", $block->z),
"Text1" => new String("Text1", ""), new String("Text1", ""),
"Text2" => new String("Text2", ""), new String("Text2", ""),
"Text3" => new String("Text3", ""), new String("Text3", ""),
"Text4" => new String("Text4", ""), new String("Text4", ""),
"creator" => new String("creator", $player->getUsername()) new String("creator", $player->getUsername())
))); )));
} }
if(($player->getGamemode() & 0x01) === 0){ if(($player->getGamemode() & 0x01) === 0){
$item->setCount($item->getCount() - 1); $item->setCount($item->getCount() - 1);
if($item->getCount() <= 0){ if($item->getCount() <= 0){
$player->setSlot($player->slot, Item::get(AIR, 0, 0)); $player->setSlot($player->slot, Item::get(Item::AIR, 0, 0));
} }
} }
@ -488,7 +461,7 @@ class BlockAPI{
} }
public function blockUpdate(Position $pos, $type = Level::BLOCK_UPDATE_NORMAL){ public function blockUpdate(Position $pos, $type = Level::BLOCK_UPDATE_NORMAL){
if(!($pos instanceof Block)){ if(!($pos instanceof BLock\Block)){
$block = $pos->level->getBlock($pos); $block = $pos->level->getBlock($pos);
} else{ } else{
$pos = new Position($pos->x, $pos->y, $pos->z, $pos->level); $pos = new Position($pos->x, $pos->y, $pos->z, $pos->level);

View File

@ -64,20 +64,20 @@ class ConsoleAPI{
switch($cmd){ switch($cmd){
case "defaultgamemode": case "defaultgamemode":
$gms = array( $gms = array(
"0" => SURVIVAL, "0" => 0,
"survival" => SURVIVAL, "survival" => 0,
"s" => SURVIVAL, "s" => 0,
"1" => CREATIVE, "1" => 1,
"creative" => CREATIVE, "creative" => 1,
"c" => CREATIVE, "c" => 1,
"2" => ADVENTURE, "2" => 2,
"adventure" => ADVENTURE, "adventure" => 2,
"a" => ADVENTURE, "a" => 2,
"3" => VIEW, "3" => 3,
"view" => VIEW, "view" => 3,
"viewer" => VIEW, "viewer" => 3,
"spectator" => VIEW, "spectator" => 3,
"v" => VIEW, "v" => 3,
); );
if(!isset($gms[strtolower($params[0])])){ if(!isset($gms[strtolower($params[0])])){
$output .= "Usage: /$cmd <mode>\n"; $output .= "Usage: /$cmd <mode>\n";

View File

@ -178,36 +178,35 @@ class Player extends RealHuman{
if(!file_exists(\PocketMine\DATA . "players/" . $iname . ".dat")){ if(!file_exists(\PocketMine\DATA . "players/" . $iname . ".dat")){
$spawn = Level::getDefault()->getSafeSpawn(); $spawn = Level::getDefault()->getSafeSpawn();
$nbt = new Compound(false, array( $nbt = new Compound(false, array(
"Pos" => new Enum("Pos", array( new Enum("Pos", array(
0 => new Double(0, $spawn->x), new Double(0, $spawn->x),
1 => new Double(1, $spawn->y), new Double(1, $spawn->y),
2 => new Double(2, $spawn->z) new Double(2, $spawn->z)
)), )),
"Level" => new String("Level", Level::getDefault()->getName()), new String("Level", Level::getDefault()->getName()),
"SpawnLevel" => new String("SpawnLevel", Level::getDefault()->getName()), new String("SpawnLevel", Level::getDefault()->getName()),
"SpawnX" => new Int("SpawnX", (int) $spawn->x), new Int("SpawnX", (int) $spawn->x),
"SpawnY" => new Int("SpawnY", (int) $spawn->y), new Int("SpawnY", (int) $spawn->y),
"SpawnZ" => new Int("SpawnZ", (int) $spawn->z), new Int("SpawnZ", (int) $spawn->z),
"SpawnForced" => new Byte("SpawnForced", 1), //TODO new Byte("SpawnForced", 1), //TODO
"Inventory" => new Enum("Inventory", array()), new Enum("Inventory", array()),
"Achievements" => new Compound("Achievements", array()), new Compound("Achievements", array()),
"playerGameType" => new Int("playerGameType", $server->gamemode), new Int("playerGameType", $server->gamemode),
"Motion" => new Enum("Motion", array( new Enum("Motion", array(
0 => new Double(0, 0.0), new Double(0, 0.0),
1 => new Double(1, 0.0), new Double(1, 0.0),
2 => new Double(2, 0.0) new Double(2, 0.0)
)), )),
"Rotation" => new Enum("Rotation", array( new Enum("Rotation", array(
0 => new Float(0, 0.0), new Float(0, 0.0),
1 => new Float(1, 0.0) new Float(1, 0.0)
)), )),
"FallDistance" => new Float("FallDistance", 0.0), new Float("FallDistance", 0.0),
"Fire" => new Short("Fire", 0), new Short("Fire", 0),
"Air" => new Short("Air", 0), new Short("Air", 0),
"OnGround" => new Byte("OnGround", 1), new Byte("OnGround", 1),
"Invulnerable" => new Byte("Invulnerable", 0), new Byte("Invulnerable", 0),
new String("NameTag", $name),
"NameTag" => new String("NameTag", $name),
)); ));
$nbt->Pos->setTagType(NBT::TAG_Double); $nbt->Pos->setTagType(NBT::TAG_Double);
$nbt->Inventory->setTagType(NBT::TAG_Compound); $nbt->Inventory->setTagType(NBT::TAG_Compound);
@ -215,24 +214,24 @@ class Player extends RealHuman{
$nbt->Rotation->setTagType(NBT::TAG_Float); $nbt->Rotation->setTagType(NBT::TAG_Float);
if(file_exists(\PocketMine\DATA . "players/" . $iname . ".yml")){ if(file_exists(\PocketMine\DATA . "players/" . $iname . ".yml")){
$data = new Config(\PocketMine\DATA . "players/" . $iname . ".yml", Config::YAML, array()); $data = new Config(\PocketMine\DATA . "players/" . $iname . ".yml", Config::YAML, array());
$nbt->playerGameType = (int) $data->get("gamemode"); $nbt["playerGameType"] = (int) $data->get("gamemode");
$nbt->Level = $data->get("position")["level"]; $nbt["Level"] = $data->get("position")["level"];
$nbt->Pos[0] = $data->get("position")["x"]; $nbt["Pos"][0] = $data->get("position")["x"];
$nbt->Pos[1] = $data->get("position")["y"]; $nbt["Pos"][1] = $data->get("position")["y"];
$nbt->Pos[2] = $data->get("position")["z"]; $nbt["Pos"][2] = $data->get("position")["z"];
$nbt->SpawnLevel = $data->get("spawn")["level"]; $nbt["SpawnLevel"] = $data->get("spawn")["level"];
$nbt->SpawnX = (int) $data->get("spawn")["x"]; $nbt["SpawnX"] = (int) $data->get("spawn")["x"];
$nbt->SpawnY = (int) $data->get("spawn")["y"]; $nbt["SpawnY"] = (int) $data->get("spawn")["y"];
$nbt->SpawnZ = (int) $data->get("spawn")["z"]; $nbt["SpawnZ"] = (int) $data->get("spawn")["z"];
console("[NOTICE] Old Player data found for \"" . $iname . "\", upgrading profile"); console("[NOTICE] Old Player data found for \"" . $iname . "\", upgrading profile");
foreach($data->get("inventory") as $slot => $item){ foreach($data->get("inventory") as $slot => $item){
if(count($item) === 3){ if(count($item) === 3){
$nbt->Inventory[$slot + 9] = new Compound(false, array( $nbt->Inventory[$slot + 9] = new Compound(false, array(
"id" => new Short("id", $item[0]), new Short("id", $item[0]),
"Damage" => new Short("Damage", $item[1]), new Short("Damage", $item[1]),
"Count" => new Byte("Count", $item[2]), new Byte("Count", $item[2]),
"Slot" => new Byte("Slot", $slot + 9), new Byte("Slot", $slot + 9),
"TrueSlot" => new Byte("TrueSlot", $slot + 9) new Byte("TrueSlot", $slot + 9)
)); ));
} }
} }
@ -240,21 +239,21 @@ class Player extends RealHuman{
if(isset($nbt->Inventory[$itemSlot + 9])){ if(isset($nbt->Inventory[$itemSlot + 9])){
$item = $nbt->Inventory[$itemSlot + 9]; $item = $nbt->Inventory[$itemSlot + 9];
$nbt->Inventory[$slot] = new Compound(false, array( $nbt->Inventory[$slot] = new Compound(false, array(
"id" => new Short("id", $item->id), new Short("id", $item->id),
"Damage" => new Short("Damage", $item->Damage), new Short("Damage", $item->Damage),
"Count" => new Byte("Count", $item->Count), new Byte("Count", $item->Count),
"Slot" => new Byte("Slot", $slot), new Byte("Slot", $slot),
"TrueSlot" => new Byte("TrueSlot", $item->TrueSlot) new Byte("TrueSlot", $item->TrueSlot)
)); ));
} }
} }
foreach($data->get("armor") as $slot => $item){ foreach($data->get("armor") as $slot => $item){
if(count($item) === 2){ if(count($item) === 2){
$nbt->Inventory[$slot + 100] = new Compound(false, array( $nbt->Inventory[$slot + 100] = new Compound(false, array(
"id" => new Short("id", $item[0]), new Short("id", $item[0]),
"Damage" => new Short("Damage", $item[1]), new Short("Damage", $item[1]),
"Count" => new Byte("Count", 1), new Byte("Count", 1),
"Slot" => new Byte("Slot", $slot + 100) new Byte("Slot", $slot + 100)
)); ));
} }
} }
@ -269,12 +268,11 @@ class Player extends RealHuman{
} else{ } else{
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->read(file_get_contents(\PocketMine\DATA . "players/" . $iname . ".dat")); $nbt->readCompressed(file_get_contents(\PocketMine\DATA . "players/" . $iname . ".dat"));
$nbt = $nbt->getData(); $nbt = $nbt->getData();
} }
$server->handle("player.offline.get", $nbt); $server->handle("player.offline.get", $nbt);
return $nbt; return $nbt;
} }
@ -282,7 +280,7 @@ class Player extends RealHuman{
ServerAPI::request()->handle("player.offline.save", $nbtTag); ServerAPI::request()->handle("player.offline.save", $nbtTag);
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData($nbtTag); $nbt->setData($nbtTag);
file_put_contents(\PocketMine\DATA . "players/" . strtolower($name) . ".dat", $nbt->write()); file_put_contents(\PocketMine\DATA . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed());
} }
public static function broadcastPacket(array $players, DataPacket $packet){ public static function broadcastPacket(array $players, DataPacket $packet){
@ -558,18 +556,17 @@ class Player extends RealHuman{
public function save(){ public function save(){
parent::saveNBT(); parent::saveNBT();
unset($this->namedtag->NameTag); $this->namedtag["Level"] = $this->level->getName();
$this->namedtag->Level = $this->level->getName(); $this->namedtag["SpawnLevel"] = $this->level->getName();
$this->namedtag->SpawnLevel = $this->level->getName(); $this->namedtag["SpawnX"] = (int) $this->spawnPosition->x;
$this->namedtag->SpawnX = (int) $this->spawnPosition->x; $this->namedtag["SpawnY"] = (int) $this->spawnPosition->y;
$this->namedtag->SpawnY = (int) $this->spawnPosition->y; $this->namedtag["SpawnZ"] = (int) $this->spawnPosition->z;
$this->namedtag->SpawnZ = (int) $this->spawnPosition->z;
foreach($this->achievements as $achievement => $status){ foreach($this->achievements as $achievement => $status){
$this->namedtag->Achievements[$achievement] = new Byte($achievement, $status === true ? 1 : 0); $this->namedtag->Achievements[$achievement] = new Byte($achievement, $status === true ? 1 : 0);
} }
$this->namedtag->playerGameType = $this->gamemode; $this->namedtag["playerGameType"] = $this->gamemode;
//$this->data->set("health", $this->getHealth()); //$this->data->set("health", $this->getHealth());
} }
@ -677,7 +674,7 @@ class Player extends RealHuman{
$pk = new ContainerSetSlotPacket; $pk = new ContainerSetSlotPacket;
$pk->windowid = 0; $pk->windowid = 0;
$pk->slot = (int) $s; $pk->slot = (int) $s;
$pk->item = Item::get(AIR, 0, 0); $pk->item = Item::get(Item::AIR, 0, 0);
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -1000,13 +997,13 @@ class Player extends RealHuman{
public function getGamemodeString(){ public function getGamemodeString(){
switch($this->gamemode){ switch($this->gamemode){
case SURVIVAL: case 0:
return "survival"; return "survival";
case CREATIVE: case 1:
return "creative"; return "creative";
case ADVENTURE: case 2:
return "adventure"; return "adventure";
case VIEW: case 3:
return "view"; return "view";
} }
} }
@ -1322,14 +1319,18 @@ class Player extends RealHuman{
} }
$nbt = Player::getOffline($this->username); $nbt = Player::getOffline($this->username);
$nbt->NameTag = $this->username; if(!isset($nbt->NameTag)){
$this->gamemode = $nbt->playerGameType & 0x03; $nbt->NameTag = new String("NameTag", $this->username);
if(($this->level = Level::get($nbt->Level)) === false){ }else{
$nbt["NameTag"] = $this->username;
}
$this->gamemode = $nbt["playerGameType"] & 0x03;
if(($this->level = Level::get($nbt["Level"])) === false){
$this->level = Level::getDefault(); $this->level = Level::getDefault();
$nbt->Level = $this->level->getName(); $nbt["Level"] = $this->level->getName();
$nbt->Pos[0] = $this->level->getSpawn()->x; $nbt["Pos"][0] = $this->level->getSpawn()->x;
$nbt->Pos[1] = $this->level->getSpawn()->y; $nbt["Pos"][1] = $this->level->getSpawn()->y;
$nbt->Pos[2] = $this->level->getSpawn()->z; $nbt["Pos"][2] = $this->level->getSpawn()->z;
} }
if($this->server->api->handle("player.join", $this) === false){ if($this->server->api->handle("player.join", $this) === false){
@ -1376,8 +1377,8 @@ class Player extends RealHuman{
$this->dataPacket($pk); $this->dataPacket($pk);
if(($level = Level::get($this->namedtag->SpawnLevel)) !== false){ if(($level = Level::get($this->namedtag["SpawnLevel"])) !== false){
$this->spawnPosition = new Position($this->namedtag->SpawnX, $this->namedtag->SpawnY, $this->namedtag->SpawnZ, $level); $this->spawnPosition = new Position($this->namedtag["SpawnX"], $this->namedtag["SpawnY"], $this->namedtag["SpawnZ"], $level);
$pk = new SetSpawnPositionPacket; $pk = new SetSpawnPositionPacket;
$pk->x = (int) $this->spawnPosition->x; $pk->x = (int) $this->spawnPosition->x;
@ -1476,7 +1477,7 @@ class Player extends RealHuman{
$packet->slot -= 9; $packet->slot -= 9;
} }
if(($this->gamemode & 0x01) === CREATIVE){ if(($this->gamemode & 0x01) === 1){
$packet->slot = false; $packet->slot = false;
foreach(BlockAPI::$creative as $i => $d){ foreach(BlockAPI::$creative as $i => $d){
if($d[0] === $packet->item and $d[1] === $packet->meta){ if($d[0] === $packet->item and $d[1] === $packet->meta){
@ -1494,7 +1495,7 @@ class Player extends RealHuman{
} else{ } else{
$this->setEquipmentSlot(0, $packet->slot); $this->setEquipmentSlot(0, $packet->slot);
$this->setCurrentEquipmentSlot(0); $this->setCurrentEquipmentSlot(0);
if(($this->gamemode & 0x01) === SURVIVAL){ if(($this->gamemode & 0x01) === 0){
if(!in_array($this->slot, $this->hotbar)){ if(!in_array($this->slot, $this->hotbar)){
array_pop($this->hotbar); array_pop($this->hotbar);
array_unshift($this->hotbar, $this->slot); array_unshift($this->hotbar, $this->slot);
@ -2195,7 +2196,7 @@ class Player extends RealHuman{
} }
public function sendInventory(){ public function sendInventory(){
if(($this->gamemode & 0x01) === CREATIVE){ if(($this->gamemode & 0x01) === 1){
return; return;
} }
$hotbar = array(); $hotbar = array();

View File

@ -189,20 +189,20 @@ class PlayerAPI{
$player = false; $player = false;
$setgm = false; $setgm = false;
$gms = array( $gms = array(
"0" => SURVIVAL, "0" => 0,
"survival" => SURVIVAL, "survival" => 0,
"s" => SURVIVAL, "s" => 0,
"1" => CREATIVE, "1" => 1,
"creative" => CREATIVE, "creative" => 1,
"c" => CREATIVE, "c" => 1,
"2" => ADVENTURE, "2" => 2,
"adventure" => ADVENTURE, "adventure" => 2,
"a" => ADVENTURE, "a" => 2,
"3" => VIEW, "3" => 3,
"view" => VIEW, "view" => 3,
"viewer" => VIEW, "viewer" => 3,
"spectator" => VIEW, "spectator" => 3,
"v" => VIEW, "v" => 3,
); );
if(isset($params[1])){ if(isset($params[1])){
if(Player::get($params[1]) instanceof Player){ if(Player::get($params[1]) instanceof Player){

View File

@ -370,9 +370,9 @@ namespace PocketMine {
$gitsha1 = false; $gitsha1 = false;
if(file_exists(\PocketMine\PATH . ".git/refs/heads/master")){ //Found Git information! if(file_exists(\PocketMine\PATH . ".git/refs/heads/master")){ //Found Git information!
define("PocketMine\GIT_COMMIT", strtolower(trim(file_get_contents(\PocketMine\PATH . ".git/refs/heads/master")))); define("PocketMine\\GIT_COMMIT", strtolower(trim(file_get_contents(\PocketMine\PATH . ".git/refs/heads/master"))));
} else{ //Unknown :( } else{ //Unknown :(
define("PocketMine\GIT_COMMIT", str_repeat("00", 20)); define("PocketMine\\GIT_COMMIT", str_repeat("00", 20));
} }
ini_set("opcache.mmap_base", bin2hex(Utils\Utils::getRandomBytes(8, false))); //Fix OPCache address errors ini_set("opcache.mmap_base", bin2hex(Utils\Utils::getRandomBytes(8, false))); //Fix OPCache address errors
@ -380,7 +380,7 @@ namespace PocketMine {
require_once(\PocketMine\PATH . "src/pthreads.php"); require_once(\PocketMine\PATH . "src/pthreads.php");
if(!file_exists(\PocketMine\DATA . "server.properties") and !isset($opts["no-wizard"])){ if(!file_exists(\PocketMine\DATA . "server.properties") and !isset($opts["no-wizard"])){
$installer = new Wizard\Installer(); new Wizard\Installer();
} }
if(!defined("PARENT_API_EXISTENT")){ if(!defined("PARENT_API_EXISTENT")){

View File

@ -83,7 +83,7 @@ class Server{
} }
} }
function __construct($name, $gamemode = SURVIVAL, $seed = false, $port = 19132, $serverip = "0.0.0.0"){ function __construct($name, $gamemode = 0, $seed = false, $port = 19132, $serverip = "0.0.0.0"){
$this->port = (int) $port; $this->port = (int) $port;
$this->doTick = true; $this->doTick = true;
$this->gamemode = (int) $gamemode; $this->gamemode = (int) $gamemode;
@ -368,17 +368,18 @@ class Server{
} }
/** /**
* TODO
* @return string * @return string
*/ */
public function getGamemode(){ public function getGamemode(){
switch($this->gamemode){ switch($this->gamemode){
case SURVIVAL: case 0:
return "survival"; return "survival";
case CREATIVE: case 1:
return "creative"; return "creative";
case ADVENTURE: case 2:
return "adventure"; return "adventure";
case VIEW: case 3:
return "view"; return "view";
} }
} }

View File

@ -128,7 +128,7 @@ class ServerAPI{
"allow-flight" => false, "allow-flight" => false,
"spawn-animals" => true, "spawn-animals" => true,
"spawn-mobs" => true, "spawn-mobs" => true,
"gamemode" => SURVIVAL, "gamemode" => 0,
"hardcore" => false, "hardcore" => false,
"pvp" => true, "pvp" => true,
"difficulty" => 1, "difficulty" => 1,
@ -158,7 +158,7 @@ class ServerAPI{
$this->server = new Server($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed : false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip : "0.0.0.0"); $this->server = new Server($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed : false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip : "0.0.0.0");
$this->server->api = $this; $this->server->api = $this;
self::$serverRequest = $this->server; self::$serverRequest = $this->server;
console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . VERSION . TextFormat::RESET . " \"" . CODENAME . "\" (MCPE: " . MINECRAFT_VERSION . ") (API " . API_VERSION . ")", true, true, 0); console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . VERSION . TextFormat::RESET . " \"" . CODENAME . "\" (API " . API_VERSION . ")", true, true, 0);
console("[INFO] PocketMine-MP is distributed under the LGPL License", true, true, 0); console("[INFO] PocketMine-MP is distributed under the LGPL License", true, true, 0);
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){ if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){

View File

@ -21,7 +21,7 @@
namespace PocketMine; namespace PocketMine;
use PocketMine\Level; use PocketMine\Level\Level;
class TimeAPI{ class TimeAPI{
public static $phases = array( public static $phases = array(

View File

@ -378,6 +378,11 @@ abstract class Block extends Position{
return $block; return $block;
} }
/**
* @param int $id
* @param int $meta
* @param string $name
*/
public function __construct($id, $meta = 0, $name = "Unknown"){ public function __construct($id, $meta = 0, $name = "Unknown"){
$this->id = (int) $id; $this->id = (int) $id;
$this->meta = (int) $meta; $this->meta = (int) $meta;
@ -442,7 +447,7 @@ abstract class Block extends Position{
* @return array * @return array
*/ */
public function getDrops(Item $item, PocketMine\Player $player){ public function getDrops(Item $item, PocketMine\Player $player){
if(!isset(self::$class[$this->id])){ //Unknown blocks if(!isset(self::$list[$this->id])){ //Unknown blocks
return array(); return array();
} else{ } else{
return array( return array(
@ -459,7 +464,6 @@ abstract class Block extends Position{
* *
* @return float * @return float
*/ */
public function getBreakTime(Item $item, PocketMine\Player $player){ public function getBreakTime(Item $item, PocketMine\Player $player){
if(($player->gamemode & 0x01) === 0x01){ if(($player->gamemode & 0x01) === 0x01){
return 0.15; return 0.15;
@ -484,6 +488,9 @@ abstract class Block extends Position{
return $v; return $v;
} }
/**
* @return string
*/
final public function __toString(){ final public function __toString(){
return "Block " . $this->name . " (" . $this->id . ":" . $this->meta . ")"; return "Block " . $this->name . " (" . $this->id . ":" . $this->meta . ")";
} }

View File

@ -29,6 +29,7 @@ use PocketMine\NBT\Tag\String;
use PocketMine\Tile\Furnace; use PocketMine\Tile\Furnace;
use PocketMine\Tile\Tile; use PocketMine\Tile\Tile;
use PocketMine; use PocketMine;
use PocketMine\NBT\NBT;
class BurningFurnace extends Solid{ class BurningFurnace extends Solid{
public function __construct($meta = 0){ public function __construct($meta = 0){
@ -47,14 +48,14 @@ class BurningFurnace extends Solid{
$this->meta = $faces[$player->getDirection()]; $this->meta = $faces[$player->getDirection()];
$this->level->setBlock($block, $this, true, false, true); $this->level->setBlock($block, $this, true, false, true);
$nbt = new Compound(false, array( $nbt = new Compound(false, array(
"Items" => new Enum("Items", array()), new Enum("Items", array()),
"id" => new String("id", Tile::FURNACE), new String("id", Tile::FURNACE),
"x" => new Int("x", $this->x), new Int("x", $this->x),
"y" => new Int("y", $this->y), new Int("y", $this->y),
"z" => new Int("z", $this->z) new Int("z", $this->z)
)); ));
$nbt->Items->setTagType(NBT\Tag_Compound); $nbt->Items->setTagType(NBT::Tag_Compound);
$furnace = new Furnace($this->level, $nbt); new Furnace($this->level, $nbt);
return true; return true;
} }
@ -73,13 +74,13 @@ class BurningFurnace extends Solid{
$furnace = $t; $furnace = $t;
} else{ } else{
$nbt = new Compound(false, array( $nbt = new Compound(false, array(
"Items" => new Enum("Items", array()), new Enum("Items", array()),
"id" => new String("id", Tile::FURNACE), new String("id", Tile::FURNACE),
"x" => new Int("x", $this->x), new Int("x", $this->x),
"y" => new Int("y", $this->y), new Int("y", $this->y),
"z" => new Int("z", $this->z) new Int("z", $this->z)
)); ));
$nbt->Items->setTagType(NBT\Tag_Compound); $nbt->Items->setTagType(NBT::Tag_Compound);
$furnace = new Furnace($this->level, $nbt); $furnace = new Furnace($this->level, $nbt);
} }
@ -115,13 +116,13 @@ class BurningFurnace extends Solid{
public function getDrops(Item $item, PocketMine\Player $player){ public function getDrops(Item $item, PocketMine\Player $player){
$drops = array(); $drops = array();
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= 1){
$drops[] = array(FURNACE, 0, 1); $drops[] = array(Item::FURNACE, 0, 1);
} }
$t = $this->level->getTile($this); $t = $this->level->getTile($this);
if($t instanceof Furnace){ if($t instanceof Furnace){
for($s = 0; $s < Furnace::SLOTS; ++$s){ for($s = 0; $s < Furnace::SLOTS; ++$s){
$slot = $t->getSlot($s); $slot = $t->getSlot($s);
if($slot->getID() > AIR and $slot->getCount() > 0){ if($slot->getID() > Item::AIR and $slot->getCount() > 0){
$drops[] = array($slot->getID(), $slot->getMetadata(), $slot->getCount()); $drops[] = array($slot->getID(), $slot->getMetadata(), $slot->getCount());
} }
} }

View File

@ -29,6 +29,7 @@ use PocketMine\NBT\Tag\String;
use PocketMine\Tile\Chest as TileChest; use PocketMine\Tile\Chest as TileChest;
use PocketMine\Tile\Tile; use PocketMine\Tile\Tile;
use PocketMine; use PocketMine;
use PocketMine\NBT\NBT;
class Chest extends Transparent{ class Chest extends Transparent{
public function __construct($meta = 0){ public function __construct($meta = 0){
@ -65,13 +66,13 @@ class Chest extends Transparent{
$this->level->setBlock($block, $this, true, false, true); $this->level->setBlock($block, $this, true, false, true);
$nbt = new Compound(false, array( $nbt = new Compound(false, array(
"Items" => new Enum("Items", array()), new Enum("Items", array()),
"id" => new String("id", Tile::CHEST), new String("id", Tile::CHEST),
"x" => new Int("x", $this->x), new Int("x", $this->x),
"y" => new Int("y", $this->y), new Int("y", $this->y),
"z" => new Int("z", $this->z) new Int("z", $this->z)
)); ));
$nbt->Items->setTagType(NBT\Tag_Compound); $nbt->Items->setTagType(NBT::Tag_Compound);
$tile = new TileChest($this->level, $nbt); $tile = new TileChest($this->level, $nbt);
if($chest instanceof TileChest){ if($chest instanceof TileChest){
@ -104,13 +105,13 @@ class Chest extends Transparent{
$chest = $t; $chest = $t;
} else{ } else{
$nbt = new Compound(false, array( $nbt = new Compound(false, array(
"Items" => new Enum("Items", array()), new Enum("Items", array()),
"id" => new String("id", Tile::CHEST), new String("id", Tile::CHEST),
"x" => new Int("x", $this->x), new Int("x", $this->x),
"y" => new Int("y", $this->y), new Int("y", $this->y),
"z" => new Int("z", $this->z) new Int("z", $this->z)
)); ));
$nbt->Items->setTagType(NBT\Tag_Compound); $nbt->Items->setTagType(NBT::Tag_Compound);
$chest = new TileChest($this->level, $nbt); $chest = new TileChest($this->level, $nbt);
} }

View File

@ -21,14 +21,6 @@
namespace PocketMine; namespace PocketMine;
//Gamemodes
const SURVIVAL = 0;
const CREATIVE = 1;
const ADVENTURE = 2;
const VIEW = 3;
const VIEWER = 3;
//Entities //Entities
const ENTITY_PLAYER = 1; const ENTITY_PLAYER = 1;

View File

@ -40,6 +40,7 @@ use PocketMine\Network\Protocol\RemoveEntityPacket;
use PocketMine\Network\Protocol\SetEntityMotionPacket; use PocketMine\Network\Protocol\SetEntityMotionPacket;
use PocketMine\Player; use PocketMine\Player;
use PocketMine\PMF\LevelFormat; use PocketMine\PMF\LevelFormat;
use PocketMine\ServerAPI;
use PocketMine; use PocketMine;
abstract class Entity extends Position{ abstract class Entity extends Position{
@ -112,14 +113,14 @@ abstract class Entity extends Position{
$this->level = $level; $this->level = $level;
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
$this->setPositionAndRotation(new Vector3($this->namedtag->Pos[0], $this->namedtag->Pos[1], $this->namedtag->Pos[2]), $this->namedtag->Rotation[0], $this->namedtag->Rotation[1]); $this->setPositionAndRotation(new Vector3($this->namedtag["Pos"][0], $this->namedtag["Pos"][1], $this->namedtag["Pos"][2]), $this->namedtag->Rotation[0], $this->namedtag->Rotation[1]);
$this->setMotion(new Vector3($this->namedtag->Motion[0], $this->namedtag->Motion[1], $this->namedtag->Motion[2])); $this->setMotion(new Vector3($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2]));
$this->fallDistance = $this->namedtag->FallDistance; $this->fallDistance = $this->namedtag["FallDistance"];
$this->fireTicks = $this->namedtag->Fire; $this->fireTicks = $this->namedtag["Fire"];
$this->airTicks = $this->namedtag->Air; $this->airTicks = $this->namedtag["Air"];
$this->onGround = $this->namedtag->OnGround > 0 ? true : false; $this->onGround = $this->namedtag["OnGround"] > 0 ? true : false;
$this->invulnerable = $this->namedtag->Invulnerable > 0 ? true : false; $this->invulnerable = $this->namedtag["Invulnerable"] > 0 ? true : false;
$index = LevelFormat::getIndex($this->x >> 4, $this->z >> 4); $index = LevelFormat::getIndex($this->x >> 4, $this->z >> 4);
$this->chunkIndex = $index; $this->chunkIndex = $index;
@ -128,26 +129,26 @@ abstract class Entity extends Position{
$this->level->chunkEntities[$this->chunkIndex][$this->id] = $this; $this->level->chunkEntities[$this->chunkIndex][$this->id] = $this;
$this->lastUpdate = microtime(true); $this->lastUpdate = microtime(true);
$this->initEntity(); $this->initEntity();
$this->server->api->dhandle("entity.add", $this); ServerAPI::request()->api->dhandle("entity.add", $this);
} }
public function saveNBT(){ public function saveNBT(){
$this->namedtag->Pos[0] = $this->x; $this->namedtag["Pos"][0] = $this->x;
$this->namedtag->Pos[1] = $this->y; $this->namedtag["Pos"][1] = $this->y;
$this->namedtag->Pos[2] = $this->z; $this->namedtag["Pos"][2] = $this->z;
$this->namedtag->Motion[0] = $this->motionX; $this->namedtag["Motion"][0] = $this->motionX;
$this->namedtag->Motion[1] = $this->motionY; $this->namedtag["Motion"][1] = $this->motionY;
$this->namedtag->Motion[2] = $this->motionZ; $this->namedtag["Motion"][2] = $this->motionZ;
$this->namedtag->Rotation[0] = $this->yaw; $this->namedtag["Rotation"][0] = $this->yaw;
$this->namedtag->Rotation[1] = $this->pitch; $this->namedtag["Rotation"][1] = $this->pitch;
$this->namedtag->FallDistance = $this->fallDistance; $this->namedtag["FallDistance"] = $this->fallDistance;
$this->namedtag->Fire = $this->fireTicks; $this->namedtag["Fire"] = $this->fireTicks;
$this->namedtag->Air = $this->airTicks; $this->namedtag["Air"] = $this->airTicks;
$this->namedtag->OnGround = $this->onGround == true ? 1 : 0; $this->namedtag["OnGround"] = $this->onGround == true ? 1 : 0;
$this->namedtag->Invulnerable = $this->invulnerable == true ? 1 : 0; $this->namedtag["Invulnerable"] = $this->invulnerable == true ? 1 : 0;
} }
protected abstract function initEntity(); protected abstract function initEntity();

View File

@ -48,7 +48,7 @@ class Human extends Creature implements ProjectileSource, InventorySource{
protected function initEntity(){ protected function initEntity(){
if(isset($this->namedtag->NameTag)){ if(isset($this->namedtag->NameTag)){
$this->nameTag = $this->namedtag->NameTag; $this->nameTag = $this->namedtag["NameTag"];
} }
$this->hotbar = array(-1, -1, -1, -1, -1, -1, -1, -1, -1); $this->hotbar = array(-1, -1, -1, -1, -1, -1, -1, -1, -1);
$this->armor = array( $this->armor = array(
@ -59,12 +59,12 @@ class Human extends Creature implements ProjectileSource, InventorySource{
); );
foreach($this->namedtag->Inventory as $item){ foreach($this->namedtag->Inventory as $item){
if($item->Slot >= 0 and $item->Slot < 9){ //Hotbar if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
$this->hotbar[$item->Slot] = isset($item->TrueSlot) ? $item->TrueSlot : -1; $this->hotbar[$item["Slot"]] = isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1;
} elseif($item->Slot >= 100 and $item->Slot < 104){ //Armor } elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
$this->armor[$item->Slot - 100] = Item::get($item->id, $item->Damage, $item->Count); $this->armor[$item["Slot"] - 100] = Item::get($item["id"], $item["Damage"], $item["Count"]);
} else{ } else{
$this->inventory[$item->Slot - 9] = Item::get($item->id, $item->Damage, $item->Count); $this->inventory[$item["Slot"] - 9] = Item::get($item["id"], $item["Damage"], $item["Count"]);
} }
} }
$this->slot = $this->hotbar[0]; $this->slot = $this->hotbar[0];
@ -78,35 +78,35 @@ class Human extends Creature implements ProjectileSource, InventorySource{
for($slot = 0; $slot < 9; ++$slot){ for($slot = 0; $slot < 9; ++$slot){
if(isset($this->hotbar[$slot]) and $this->hotbar[$slot] !== -1){ if(isset($this->hotbar[$slot]) and $this->hotbar[$slot] !== -1){
$item = $this->getSlot($this->hotbar[$slot]); $item = $this->getSlot($this->hotbar[$slot]);
if($item->getID() !== AIR and $item->getCount() > 0){ if($item->getID() !== 0 and $item->getCount() > 0){
$this->namedtag->Inventory[$slot] = new Compound(false, array( $this->namedtag->Inventory[$slot] = new Compound(false, array(
"Count" => new Byte("Count", $item->getCount()), new Byte("Count", $item->getCount()),
"Damage" => new Short("Damage", $item->getMetadata()), new Short("Damage", $item->getMetadata()),
"Slot" => new Byte("Slot", $slot), new Byte("Slot", $slot),
"TrueSlot" => new Byte("TrueSlot", $this->hotbar[$slot]), new Byte("TrueSlot", $this->hotbar[$slot]),
"id" => new Short("id", $item->getID()), new Short("id", $item->getID()),
)); ));
continue; continue;
} }
} }
$this->namedtag->Inventory[$slot] = new Compound(false, array( $this->namedtag->Inventory[$slot] = new Compound(false, array(
"Count" => new Byte("Count", 0), new Byte("Count", 0),
"Damage" => new Short("Damage", 0), new Short("Damage", 0),
"Slot" => new Byte("Slot", $slot), new Byte("Slot", $slot),
"TrueSlot" => new Byte("Slot", -1), new Byte("Slot", -1),
"id" => new Short("id", 0), new Short("id", 0),
)); ));
} }
//Normal inventory //Normal inventory
$slotCount = (($this->gamemode & 0x01) === 0 ? Player::SURVIVAL_SLOTS : Player::CREATIVE_SLOTS) + 9; $slotCount = (($this instanceof Player and ($this->gamemode & 0x01) === 1) ? Player::CREATIVE_SLOTS : Player::SURVIVAL_SLOTS) + 9;
for($slot = 9; $slot < $slotCount; ++$slot){ for($slot = 9; $slot < $slotCount; ++$slot){
$item = $this->getSlot($slot); $item = $this->getSlot($slot);
$this->namedtag->Inventory[$slot] = new Compound(false, array( $this->namedtag->Inventory[$slot] = new Compound(false, array(
"Count" => new Byte("Count", $item->getCount()), new Byte("Count", $item->getCount()),
"Damage" => new Short("Damage", $item->getMetadata()), new Short("Damage", $item->getMetadata()),
"Slot" => new Byte("Slot", $slot), new Byte("Slot", $slot),
"id" => new Short("id", $item->getID()), new Short("id", $item->getID()),
)); ));
} }
@ -115,10 +115,10 @@ class Human extends Creature implements ProjectileSource, InventorySource{
$item = $this->armor[$slot - 100]; $item = $this->armor[$slot - 100];
if($item instanceof Item){ if($item instanceof Item){
$this->namedtag->Inventory[$slot] = new Compound(false, array( $this->namedtag->Inventory[$slot] = new Compound(false, array(
"Count" => new Byte("Count", $item->getCount()), new Byte("Count", $item->getCount()),
"Damage" => new Short("Damage", $item->getMetadata()), new Short("Damage", $item->getMetadata()),
"Slot" => new Byte("Slot", $slot), new Byte("Slot", $slot),
"id" => new Short("id", $item->getID()), new Short("id", $item->getID()),
)); ));
} }
} }
@ -383,6 +383,11 @@ class Human extends Creature implements ProjectileSource, InventorySource{
return true; return true;
} }
/**
* @param int $slot
*
* @return Item
*/
public function getSlot($slot){ public function getSlot($slot){
$slot = (int) $slot; $slot = (int) $slot;
if(!isset($this->inventory[$slot])){ if(!isset($this->inventory[$slot])){

View File

@ -25,7 +25,7 @@
namespace PocketMine\Event\Tile; namespace PocketMine\Event\Tile;
use PocketMine; use PocketMine;
use PocketMine\Event; use PocketMine\Event\Event;
abstract class TileEvent extends Event{ abstract class TileEvent extends Event{
protected $tile; protected $tile;

View File

@ -25,6 +25,7 @@ use PocketMine\Event;
use PocketMine\Item\Item; use PocketMine\Item\Item;
use PocketMine; use PocketMine;
use PocketMine\Tile\Tile; use PocketMine\Tile\Tile;
use PocketMine\Event\CancellableEvent;
class TileInventoryChangeEvent extends TileEvent implements CancellableEvent{ class TileInventoryChangeEvent extends TileEvent implements CancellableEvent{
public static $handlers; public static $handlers;

View File

@ -48,6 +48,9 @@ use PocketMine\Utils\Config;
use PocketMine\Utils\Random; use PocketMine\Utils\Random;
use PocketMine\Utils\Utils; use PocketMine\Utils\Utils;
use PocketMine; use PocketMine;
use PocketMine\NBT\Tag\Byte;
use PocketMine\NBT\Tag\String;
use PocketMine\NBT\Tag\Int;
/** /**
* Class Level * Class Level
@ -130,7 +133,7 @@ class Level{
* @return bool|Level * @return bool|Level
*/ */
public static function get($name){ public static function get($name){
if(isset(self::$list[$name])){ if($name !== "" and isset(self::$list[$name])){
return self::$list[$name]; return self::$list[$name];
} }
@ -553,8 +556,8 @@ class Level{
LevelFormat::getXZ($index, $X, $Z); LevelFormat::getXZ($index, $X, $Z);
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new Compound("", array( $nbt->setData(new Compound("", array(
"Entities" => new Enum("Entities", array()), new Enum("Entities", array()),
"TileEntities" => new Enum("TileEntities", array()), new Enum("TileEntities", array()),
))); )));
$nbt->Entities->setTagType(NBT::TAG_Compound); $nbt->Entities->setTagType(NBT::TAG_Compound);
$nbt->TileEntities->setTagType(NBT::TAG_Compound); $nbt->TileEntities->setTagType(NBT::TAG_Compound);
@ -562,7 +565,7 @@ class Level{
$i = 0; $i = 0;
foreach($this->chunkEntities[$index] as $entity){ foreach($this->chunkEntities[$index] as $entity){
if($entity->closed !== true){ if($entity->closed !== true){
$nbt->Entities[$i]->saveNBT(); $entity->saveNBT();
$nbt->Entities[$i] = $entity->namedtag; $nbt->Entities[$i] = $entity->namedtag;
++$i; ++$i;
} }
@ -759,14 +762,14 @@ class Level{
$tags = $this->level->getChunkNBT($X, $Z); $tags = $this->level->getChunkNBT($X, $Z);
if(isset($tags->Entities)){ if(isset($tags->Entities)){
foreach($tags->Entities as $nbt){ foreach($tags->Entities as $nbt){
switch($nbt->id){ switch($nbt["id"]){
//TODO: spawn entities //TODO: spawn entities
} }
} }
} }
if(isset($tags->TileEntities)){ if(isset($tags->TileEntities)){
foreach($tags->TileEntities as $nbt){ foreach($tags->TileEntities as $nbt){
switch($nbt->id){ switch($nbt["id"]){
case Tile::CHEST: case Tile::CHEST:
new Chest($this, $nbt); new Chest($this, $nbt);
break; break;

View File

@ -44,8 +44,8 @@ class LevelImport{
$nbt = new NBT(NBT::LITTLE_ENDIAN); $nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->read(substr(file_get_contents($this->path . "level.dat"), 8)); $nbt->read(substr(file_get_contents($this->path . "level.dat"), 8));
$level = $nbt->getData(); $level = $nbt->getData();
if($level->LevelName == ""){ if($level["LevelName"] == ""){
$level->LevelName = "world" . time(); $level["LevelName"] = "world" . time();
} }
console("[INFO] Importing Pocket level \"" . $level->LevelName . "\" to PMF format"); console("[INFO] Importing Pocket level \"" . $level->LevelName . "\" to PMF format");
unset($level->Player); unset($level->Player);

View File

@ -41,7 +41,13 @@ use PocketMine\NBT\Tag\Tag;
use PocketMine\Utils\Utils; use PocketMine\Utils\Utils;
use PocketMine; use PocketMine;
class NBT implements \ArrayAccess{ /**
* Named Binary Tag encoder/decoder
*
* Class NBT
* @package PocketMine\NBT
*/
class NBT{
const LITTLE_ENDIAN = 0; const LITTLE_ENDIAN = 0;
const BIG_ENDIAN = 1; const BIG_ENDIAN = 1;
const TAG_End = 0; const TAG_End = 0;
@ -63,7 +69,7 @@ class NBT implements \ArrayAccess{
private $data; private $data;
public function get($len){ public function get($len){
if($len <= 0){ if($len < 0){
$this->offset = strlen($this->buffer) - 1; $this->offset = strlen($this->buffer) - 1;
return ""; return "";
@ -99,6 +105,10 @@ class NBT implements \ArrayAccess{
$this->buffer = ""; $this->buffer = "";
} }
public function readCompressed($buffer){
$this->read(\gzdecode($buffer));
}
public function write(){ public function write(){
$this->offset = 0; $this->offset = 0;
if($this->data instanceof Compound){ if($this->data instanceof Compound){
@ -110,6 +120,13 @@ class NBT implements \ArrayAccess{
} }
} }
public function writeCompressed(){
if(($write = $this->write()) !== false){
return \gzencode($write, 9);
}
return false;
}
public function readTag(){ public function readTag(){
switch($this->getByte()){ switch($this->getByte()){
case NBT::TAG_Byte: case NBT::TAG_Byte:
@ -230,40 +247,6 @@ class NBT implements \ArrayAccess{
$this->buffer .= $v; $this->buffer .= $v;
} }
public function &__get($name){
$ret = $this->data instanceof Compound ? $this->data[$name] : false;
return $ret;
}
public function __isset($name){
return $this->data instanceof Compound ? isset($this->data[$name]) : false;
}
public function __unset($name){
if($this->data instanceof Compound){
unset($this->data[$name]);
}
}
public function offsetExists($name){
return $this->__isset($name);
}
public function &offsetGet($name){
return $this->__get($name);
}
public function offsetSet($name, $value){
if($this->data instanceof Compound){
$this->data[$name] = $value;
}
}
public function offsetUnset($name){
$this->__unset($name);
}
public function getData(){ public function getData(){
return $this->data; return $this->data;
} }

View File

@ -24,101 +24,59 @@ namespace PocketMine\NBT\Tag;
use PocketMine; use PocketMine;
use PocketMine\NBT\NBT; use PocketMine\NBT\NBT;
class Compound extends NamedTag implements \ArrayAccess, \Iterator{ class Compound extends NamedTag implements \ArrayAccess{
protected $value = array();
public function __construct($name = "", $value = array()){ public function __construct($name = "", $value = array()){
$this->name = $name; $this->name = $name;
$this->value = $value; foreach($value as $tag){
$this->{$tag->getName()} = $tag;
}
}
public function offsetExists($offset){
return isset($this->{$offset});
}
public function offsetGet($offset){
if($this->{$offset} instanceof Tag){
if($this->{$offset} instanceof \ArrayAccess){
return $this->{$offset};
}else{
return $this->{$offset}->getValue();
}
}
return null;
}
public function offsetSet($offset, $value){
if($value instanceof Tag){
$this->{$offset} = $value;
}elseif($this->{$offset} instanceof Tag){
$this->{$offset}->setValue($value);
}
}
public function offsetUnset($offset){
unset($this->{$offset});
} }
public function getType(){ public function getType(){
return NBT::TAG_Compound; return NBT::TAG_Compound;
} }
public function rewind(){
reset($this->value);
}
public function current(){
return current($this->value);
}
public function key(){
return key($this->value);
}
public function next(){
return next($this->value);
}
public function valid(){
$key = key($this->value);
return $key !== null and $key !== false;
}
public function offsetExists($name){
return $this->__isset($name);
}
public function &offsetGet($name){
return $this->__get($name);
}
public function offsetSet($name, $value){
$this->value[$name] = $value;
}
public function offsetUnset($name){
$this->__unset($name);
}
public function &__get($name){
$ret = isset($this->value[$name]) ? $this->value[$name] : false;
if(!is_object($ret) or $ret instanceof \ArrayAccess){
return $ret;
} else{
return $ret->getValue();
}
}
/*public function __set($name, $value){
if($value instanceof Tag){
if($value instanceof NamedTag and $value->getName() !== "" and $value->getName() !== false){
$this->value[$value->getName()] = $value;
} else{
$this->value[$name] = $value;
}
}elseif(isset($this->value[$name])){
$this->value[$name]->setValue($value);
}
}*/
public function __isset($name){
return isset($this->value[$name]);
}
public function __unset($name){
unset($this->value[$name]);
}
public function read(NBT $nbt){ public function read(NBT $nbt){
$this->value = array(); $this->value = array();
do{ do{
$tag = $nbt->readTag(); $tag = $nbt->readTag();
if($tag instanceof NamedTag and $tag->getName() !== ""){ if($tag instanceof NamedTag and $tag->getName() !== ""){
$this->value[$tag->getName()] = $tag; $this->{$tag->getName()} = $tag;
} elseif(!($tag instanceof End)){
$this->value[] = $tag;
} }
} while(!($tag instanceof End) and !$nbt->feof()); } while(!($tag instanceof End) and !$nbt->feof());
} }
public function write(NBT $nbt){ public function write(NBT $nbt){
foreach($this->value as $tag){ foreach($this as $tag){
if(!($tag instanceof End)){ if($tag instanceof Tag and !($tag instanceof End)){
$nbt->writeTag($tag); $nbt->writeTag($tag);
} }
} }

View File

@ -25,14 +25,42 @@ use PocketMine\NBT\NBT;
use PocketMine; use PocketMine;
use PocketMine\NBT\Tag\Enum as TagEnum; use PocketMine\NBT\Tag\Enum as TagEnum;
class Enum extends NamedTag implements \ArrayAccess, \Iterator{ class Enum extends NamedTag implements \ArrayAccess{
private $tagType; private $tagType;
protected $value = array();
public function __construct($name = "", $value = array()){ public function __construct($name = "", $value = array()){
$this->name = $name; $this->name = $name;
$this->value = $value; foreach($value as $k => $v){
$this->{$k} = $v;
}
}
public function offsetExists($offset){
return isset($this->{$offset});
}
public function offsetGet($offset){
if($this->{$offset} instanceof Tag){
if($this->{$offset} instanceof \ArrayAccess){
return $this->{$offset};
}else{
return $this->{$offset}->getValue();
}
}
return null;
}
public function offsetSet($offset, $value){
if($value instanceof Tag){
$this->{$offset} = $value;
}elseif($this->{$offset} instanceof Tag){
$this->{$offset}->setValue($value);
}
}
public function offsetUnset($offset){
unset($this->{$offset});
} }
public function getType(){ public function getType(){
@ -47,61 +75,6 @@ class Enum extends NamedTag implements \ArrayAccess, \Iterator{
return $this->tagType; return $this->tagType;
} }
public function rewind(){
reset($this->value);
}
public function current(){
return current($this->value);
}
public function key(){
return key($this->value);
}
public function next(){
return next($this->value);
}
public function valid(){
$key = key($this->value);
return $key !== null and $key !== false;
}
public function offsetExists($name){
return $this->__isset($name);
}
public function &offsetGet($name){
return $this->__get($name);
}
public function offsetSet($name, $value){
$this->value[$name] = $value;
}
public function offsetUnset($name){
$this->__unset($name);
}
public function &__get($name){
$ret = isset($this->value[$name]) ? $this->value[$name] : false;
if(!is_object($ret) or $ret instanceof \ArrayAccess){
return $ret;
} else{
return $ret->getValue();
}
}
public function __isset($name){
return isset($this->value[$name]);
}
public function __unset($name){
unset($this->value[$name]);
}
public function read(NBT $nbt){ public function read(NBT $nbt){
$this->value = array(); $this->value = array();
$this->tagType = $nbt->getByte(); $this->tagType = $nbt->getByte();
@ -111,57 +84,57 @@ class Enum extends NamedTag implements \ArrayAccess, \Iterator{
case NBT::TAG_Byte: case NBT::TAG_Byte:
$tag = new Byte(false); $tag = new Byte(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Short: case NBT::TAG_Short:
$tag = new Short(false); $tag = new Short(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Int: case NBT::TAG_Int:
$tag = new Int(false); $tag = new Int(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Long: case NBT::TAG_Long:
$tag = new Long(false); $tag = new Long(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Float: case NBT::TAG_Float:
$tag = new Float(false); $tag = new Float(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Double: case NBT::TAG_Double:
$tag = new Double(false); $tag = new Double(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Byte_Array: case NBT::TAG_Byte_Array:
$tag = new Byte_Array(false); $tag = new Byte_Array(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_String: case NBT::TAG_String:
$tag = new String(false); $tag = new String(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Enum: case NBT::TAG_Enum:
$tag = new TagEnum(false); $tag = new TagEnum(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Compound: case NBT::TAG_Compound:
$tag = new Compound(false); $tag = new Compound(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
case NBT::TAG_Int_Array: case NBT::TAG_Int_Array:
$tag = new Int_Array(false); $tag = new Int_Array(false);
$tag->read($nbt); $tag->read($nbt);
$this->value[] = $tag; $this->{$i} = $tag;
break; break;
} }
} }
@ -169,22 +142,29 @@ class Enum extends NamedTag implements \ArrayAccess, \Iterator{
public function write(NBT $nbt){ public function write(NBT $nbt){
if(!isset($this->tagType)){ if(!isset($this->tagType)){
foreach($this->value as $tag){ foreach($this as $tag){
if($tag instanceof Tag){
if(!isset($id)){ if(!isset($id)){
$id = $tag->getType(); $id = $tag->getType();
} elseif($id !== $tag->getType()){ }elseif($id !== $tag->getType()){
return false; return false;
} }
} }
$this->tagType = $id; }
$this->tagType = @$id;
} }
$nbt->putByte($this->tagType); $nbt->putByte($this->tagType);
$nbt->putInt(count($this->value));
foreach($this->value as $tag){ $tags = array();
foreach($this as $tag){
if($tag instanceof Tag){ if($tag instanceof Tag){
$tags[] = $tag;
}
}
$nbt->putInt(count($tags));
foreach($tags as $tag){
$tag->write($nbt); $tag->write($nbt);
} }
} }
}
} }

View File

@ -64,6 +64,10 @@ class LevelFormat extends PMF{
$this->close(); $this->close();
} }
/**
* @param string $file
* @param bool|array $blank default false
*/
public function __construct($file, $blank = false){ public function __construct($file, $blank = false){
$this->chunks = array(); $this->chunks = array();
$this->chunkChange = array(); $this->chunkChange = array();
@ -186,8 +190,8 @@ class LevelFormat extends PMF{
console("[NOTICE] Old PMF Level format version #1 detected, upgrading to version #2"); console("[NOTICE] Old PMF Level format version #1 detected, upgrading to version #2");
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new Compound("", array( $nbt->setData(new Compound("", array(
"Entities" => new Enum("Entities", array()), new Enum("Entities", array()),
"TileEntities" => new Enum("TileEntities", array()) new Enum("TileEntities", array())
))); )));
$nbt->Entities->setTagType(NBT::TAG_Compound); $nbt->Entities->setTagType(NBT::TAG_Compound);
$nbt->TileEntities->setTagType(NBT::TAG_Compound); $nbt->TileEntities->setTagType(NBT::TAG_Compound);
@ -417,8 +421,8 @@ class LevelFormat extends PMF{
); );
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new Compound("", array( $nbt->setData(new Compound("", array(
"Entities" => new Enum("Entities", array()), new Enum("Entities", array()),
"TileEntities" => new Enum("TileEntities", array()) new Enum("TileEntities", array())
))); )));
$nbt->Entities->setTagType(NBT::TAG_Compound); $nbt->Entities->setTagType(NBT::TAG_Compound);
$nbt->TileEntities->setTagType(NBT::TAG_Compound); $nbt->TileEntities->setTagType(NBT::TAG_Compound);

View File

@ -24,7 +24,6 @@
*/ */
namespace PocketMine\Recipes; namespace PocketMine\Recipes;
use PocketMine\BlockAPI;
use PocketMine\Item\Item; use PocketMine\Item\Item;
use PocketMine\ServerAPI; use PocketMine\ServerAPI;
use PocketMine; use PocketMine;
@ -241,7 +240,7 @@ abstract class Crafting{
$meta = array_pop($id); $meta = array_pop($id);
$id = $id[0]; $id = $id[0];
$it = BlockAPI::fromString($id); $it = Item::fromString($id);
$craftItem = array($it->getID(), intval($meta) & 0xFFFF, intval($item[1])); $craftItem = array($it->getID(), intval($meta) & 0xFFFF, intval($item[1]));

View File

@ -35,7 +35,7 @@ class Chest extends Spawnable{
const SLOTS = 27; const SLOTS = 27;
public function __construct(Level $level, Compound $nbt){ public function __construct(Level $level, Compound $nbt){
$nbt->id = Tile::CHEST; $nbt["id"] = Tile::CHEST;
parent::__construct($level, $nbt); parent::__construct($level, $nbt);
} }

View File

@ -29,6 +29,7 @@ use PocketMine\NBT\Tag\Byte;
use PocketMine\NBT\Tag\Compound; use PocketMine\NBT\Tag\Compound;
use PocketMine\NBT\Tag\Short; use PocketMine\NBT\Tag\Short;
use PocketMine\Player; use PocketMine\Player;
use PocketMine\Network;
use PocketMine; use PocketMine;
trait Container{ trait Container{
@ -52,9 +53,9 @@ trait Container{
$player->windows[$id] = $this; $player->windows[$id] = $this;
} }
$pk = new ContainerOpenPacket; $pk = new Network\Protocol\ContainerOpenPacket;
$pk->windowid = $id; $pk->windowid = $id;
$pk->type = WINDOW_CHEST; $pk->type = 0;
$pk->slots = is_array($player->windows[$id]) ? Chest::SLOTS << 1 : Chest::SLOTS; $pk->slots = is_array($player->windows[$id]) ? Chest::SLOTS << 1 : Chest::SLOTS;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -65,7 +66,7 @@ trait Container{
if(is_array($player->windows[$id])){ if(is_array($player->windows[$id])){
$all = $this->level->getPlayers(); $all = $this->level->getPlayers();
foreach($player->windows[$id] as $ob){ foreach($player->windows[$id] as $ob){
$pk = new TileEventPacket; $pk = new Network\Protocol\TileEventPacket;
$pk->x = $ob->x; $pk->x = $ob->x;
$pk->y = $ob->y; $pk->y = $ob->y;
$pk->z = $ob->z; $pk->z = $ob->z;
@ -74,15 +75,15 @@ trait Container{
Player::broadcastPacket($all, $pk); Player::broadcastPacket($all, $pk);
for($s = 0; $s < Chest::SLOTS; ++$s){ for($s = 0; $s < Chest::SLOTS; ++$s){
$slot = $ob->getSlot($s); $slot = $ob->getSlot($s);
if($slot->getID() > AIR and $slot->getCount() > 0){ if($slot->getID() > Item::AIR and $slot->getCount() > 0){
$slots[] = $slot; $slots[] = $slot;
} else{ } else{
$slots[] = Item::get(AIR, 0, 0); $slots[] = Item::get(Item::AIR, 0, 0);
} }
} }
} }
} else{ } else{
$pk = new TileEventPacket; $pk = new Network\Protocol\TileEventPacket;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;
@ -91,15 +92,15 @@ trait Container{
Player::broadcastPacket($this->level->getPlayers(), $pk); Player::broadcastPacket($this->level->getPlayers(), $pk);
for($s = 0; $s < Chest::SLOTS; ++$s){ for($s = 0; $s < Chest::SLOTS; ++$s){
$slot = $this->getSlot($s); $slot = $this->getSlot($s);
if($slot->getID() > AIR and $slot->getCount() > 0){ if($slot->getID() > Item::AIR and $slot->getCount() > 0){
$slots[] = $slot; $slots[] = $slot;
} else{ } else{
$slots[] = Item::get(AIR, 0, 0); $slots[] = Item::get(Item::AIR, 0, 0);
} }
} }
} }
$pk = new ContainerSetContentPacket; $pk = new Network\Protocol\ContainerSetContentPacket;
$pk->windowid = $id; $pk->windowid = $id;
$pk->slots = $slots; $pk->slots = $slots;
$player->dataPacket($pk); $player->dataPacket($pk);
@ -110,9 +111,9 @@ trait Container{
$player->windowCnt = $id = max(2, $player->windowCnt % 99); $player->windowCnt = $id = max(2, $player->windowCnt % 99);
$player->windows[$id] = $this; $player->windows[$id] = $this;
$pk = new ContainerOpenPacket; $pk = new Network\Protocol\ContainerOpenPacket;
$pk->windowid = $id; $pk->windowid = $id;
$pk->type = WINDOW_FURNACE; $pk->type = 2;
$pk->slots = Furnace::SLOTS; $pk->slots = Furnace::SLOTS;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -122,13 +123,13 @@ trait Container{
$slots = array(); $slots = array();
for($s = 0; $s < Furnace::SLOTS; ++$s){ for($s = 0; $s < Furnace::SLOTS; ++$s){
$slot = $this->getSlot($s); $slot = $this->getSlot($s);
if($slot->getID() > AIR and $slot->getCount() > 0){ if($slot->getID() > Item::AIR and $slot->getCount() > 0){
$slots[] = $slot; $slots[] = $slot;
} else{ } else{
$slots[] = Item::get(AIR, 0, 0); $slots[] = Item::get(Item::AIR, 0, 0);
} }
} }
$pk = new ContainerSetContentPacket; $pk = new Network\Protocol\ContainerSetContentPacket;
$pk->windowid = $id; $pk->windowid = $id;
$pk->slots = $slots; $pk->slots = $slots;
$player->dataPacket($pk); $player->dataPacket($pk);
@ -139,7 +140,7 @@ trait Container{
public function getSlotIndex($s){ public function getSlotIndex($s){
foreach($this->namedtag->Items as $i => $slot){ foreach($this->namedtag->Items as $i => $slot){
if($slot->Slot === $s){ if($slot["Slot"] === $s){
return $i; return $i;
} }
} }
@ -150,9 +151,9 @@ trait Container{
public function getSlot($s){ public function getSlot($s){
$i = $this->getSlotIndex($s); $i = $this->getSlotIndex($s);
if($i === false or $i < 0){ if($i === false or $i < 0){
return Item::get(AIR, 0, 0); return Item::get(Item::AIR, 0, 0);
} else{ } else{
return Item::get($this->namedtag->Items[$i]->id, $this->namedtag->Items[$i]->Damage, $this->namedtag->Items[$i]->Count); return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
} }
} }
@ -165,13 +166,13 @@ trait Container{
$item = $ev->getNewItem(); $item = $ev->getNewItem();
$d = new Compound(false, array( $d = new Compound(false, array(
"Count" => new Byte("Count", $item->getCount()), new Byte("Count", $item->getCount()),
"Slot" => new Byte("Slot", $s), new Byte("Slot", $s),
"id" => new Short("id", $item->getID()), new Short("id", $item->getID()),
"Damage" => new Short("Damage", $item->getMetadata()), new Short("Damage", $item->getMetadata()),
)); ));
if($item->getID() === AIR or $item->getCount() <= 0){ if($item->getID() === Item::AIR or $item->getCount() <= 0){
if($i >= 0){ if($i >= 0){
unset($this->namedtag->Items[$i]); unset($this->namedtag->Items[$i]);
} }

View File

@ -33,7 +33,7 @@ class Furnace extends Tile{
const SLOTS = 3; const SLOTS = 3;
public function __construct(Level $level, Compound $nbt){ public function __construct(Level $level, Compound $nbt){
$nbt->id = Tile::FURNACE; $nbt["id"] = Tile::FURNACE;
parent::__construct($level, $nbt); parent::__construct($level, $nbt);
if(!isset($this->namedtag->BurnTime) or $this->namedtag->BurnTime < 0){ if(!isset($this->namedtag->BurnTime) or $this->namedtag->BurnTime < 0){
$this->namedtag->BurnTime = 0; $this->namedtag->BurnTime = 0;

View File

@ -32,7 +32,7 @@ use PocketMine;
class Sign extends Spawnable{ class Sign extends Spawnable{
public function __construct(Level $level, Compound $nbt){ public function __construct(Level $level, Compound $nbt){
$nbt->id = Tile::SIGN; $nbt["id"] = Tile::SIGN;
parent::__construct($level, $nbt); parent::__construct($level, $nbt);
} }

View File

@ -33,7 +33,7 @@ class Installer{
const DEFAULT_PORT = 19132; const DEFAULT_PORT = 19132;
const DEFAULT_MEMORY = 128; const DEFAULT_MEMORY = 128;
const DEFAULT_PLAYERS = 20; const DEFAULT_PLAYERS = 20;
const DEFAULT_GAMEMODE = SURVIVAL; const DEFAULT_GAMEMODE = 0;
private $lang, $config; private $lang, $config;

View File

@ -46,6 +46,7 @@ COMPILE_OPENSSL="no"
COMPILE_CURL="default" COMPILE_CURL="default"
COMPILE_LIBEDIT="no" COMPILE_LIBEDIT="no"
IS_CROSSCOMPILE="no" IS_CROSSCOMPILE="no"
IS_WINDOWS="no"
DO_OPTIMIZE="no" DO_OPTIMIZE="no"
DO_STATIC="no" DO_STATIC="no"
while getopts "::t:oj:scxff:" OPTION; do while getopts "::t:oj:scxff:" OPTION; do
@ -99,7 +100,27 @@ while getopts "::t:oj:scxff:" OPTION; do
done done
if [ "$IS_CROSSCOMPILE" == "yes" ]; then if [ "$IS_CROSSCOMPILE" == "yes" ]; then
if [ "$COMPILE_TARGET" == "android" ] || [ "$COMPILE_TARGET" == "android-armv6" ]; then if [ "$COMPILE_TARGET" == "win" ] || [ "$COMPILE_TARGET" == "win32" ]; then
TOOLCHAIN_PREFIX="i686-w64-mingw32"
[ -z "$march" ] && march=i686;
[ -z "$mtune" ] && mtune=pentium4;
CFLAGS="$CFLAGS -mconsole"
export CC="$TOOLCHAIN_PREFIX-gcc"
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --target=$TOOLCHAIN_PREFIX --build=$TOOLCHAIN_PREFIX"
OPENSSL_TARGET="mingw"
IS_WINDOWS="yes"
echo "[INFO] Cross-compiling for Windows 32-bit"
elif [ "$COMPILE_TARGET" == "win64" ]; then
TOOLCHAIN_PREFIX="x86_64-w64-mingw32"
[ -z "$march" ] && march=x86_64;
[ -z "$mtune" ] && mtune=nocona;
CFLAGS="$CFLAGS -mconsole"
export CC="$TOOLCHAIN_PREFIX-gcc"
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --target=$TOOLCHAIN_PREFIX --build=$TOOLCHAIN_PREFIX"
OPENSSL_TARGET="mingw"
IS_WINDOWS="yes"
echo "[INFO] Cross-compiling for Windows 64-bit"
elif [ "$COMPILE_TARGET" == "android" ] || [ "$COMPILE_TARGET" == "android-armv6" ]; then
COMPILE_FOR_ANDROID=yes COMPILE_FOR_ANDROID=yes
[ -z "$march" ] && march=armv6; [ -z "$march" ] && march=armv6;
[ -z "$mtune" ] && mtune=arm1136jf-s; [ -z "$mtune" ] && mtune=arm1136jf-s;
@ -165,7 +186,7 @@ if [ "$IS_CROSSCOMPILE" == "yes" ]; then
CFLAGS="$CFLAGS -mfpu=neon" CFLAGS="$CFLAGS -mfpu=neon"
fi fi
else else
echo "Please supply a proper platform [android android-armv6 android-armv7 rpi mac ios ios-armv6 ios-armv7] to cross-compile" echo "Please supply a proper platform [android android-armv6 android-armv7 rpi mac ios ios-armv6 ios-armv7 win win32 win64] to cross-compile"
exit 1 exit 1
fi fi
elif [ "$COMPILE_TARGET" == "rpi" ]; then elif [ "$COMPILE_TARGET" == "rpi" ]; then
@ -444,6 +465,7 @@ RANLIB=$RANLIB ./configure \
--prefix="$DIR/bin/php5" \ --prefix="$DIR/bin/php5" \
$EXTRA_FLAGS \ $EXTRA_FLAGS \
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1 $CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
sed -i=".backup" 's/ tests win32/ win32/g' Makefile
echo -n " compiling..." echo -n " compiling..."
make -j $THREADS >> "$DIR/install.log" 2>&1 make -j $THREADS >> "$DIR/install.log" 2>&1
echo -n " installing..." echo -n " installing..."
@ -469,9 +491,22 @@ rm -f ./configure >> "$DIR/install.log" 2>&1
./buildconf --force >> "$DIR/install.log" 2>&1 ./buildconf --force >> "$DIR/install.log" 2>&1
if [ "$IS_CROSSCOMPILE" == "yes" ]; then if [ "$IS_CROSSCOMPILE" == "yes" ]; then
sed -i=".backup" 's/pthreads_working=no/pthreads_working=yes/' ./configure sed -i=".backup" 's/pthreads_working=no/pthreads_working=yes/' ./configure
export LIBS="-lpthread -ldl -lresolv" if [ "$IS_WINDOWS" != "yes" ]; then
export LIBS="$LIBS -lpthread -ldl -lresolv"
else
export LIBS="$LIBS -lpthread"
fi
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no" CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no"
fi fi
if [ "$IS_WINDOWS" != "yes" ]; then
HAVE_PCNTL="--enable-pcntl"
else
HAVE_PCNTL="--disable-pcntl"
cp -f ./win32/build/config.* ./main >> "$DIR/install.log" 2>&1
sed 's:@PREFIX@:$DIR/bin/php5:' ./main/config.w32.h.in > ./wmain/config.w32.h 2>> "$DIR/install.log"
fi
RANLIB=$RANLIB ./configure $PHP_OPTIMIZATION--prefix="$DIR/bin/php5" \ RANLIB=$RANLIB ./configure $PHP_OPTIMIZATION--prefix="$DIR/bin/php5" \
--exec-prefix="$DIR/bin/php5" \ --exec-prefix="$DIR/bin/php5" \
--with-curl="$HAVE_CURL" \ --with-curl="$HAVE_CURL" \
@ -497,10 +532,10 @@ $HAVE_LIBEDIT \
--enable-shared=no \ --enable-shared=no \
--enable-static=yes \ --enable-static=yes \
--enable-shmop \ --enable-shmop \
--enable-pcntl \
--enable-pthreads \ --enable-pthreads \
--enable-maintainer-zts \ --enable-maintainer-zts \
--enable-zend-signals \ --enable-zend-signals \
$HAVE_PCNTL \
$HAVE_MYSQLI \ $HAVE_MYSQLI \
--enable-embedded-mysqli \ --enable-embedded-mysqli \
--enable-bcmath \ --enable-bcmath \
@ -558,10 +593,10 @@ echo " done!"
cd "$DIR" cd "$DIR"
echo -n "[INFO] Cleaning up..." echo -n "[INFO] Cleaning up..."
rm -r -f install_data/ >> "$DIR/install.log" 2>&1 rm -r -f install_data/ >> "$DIR/install.log" 2>&1
rm -f bin/php5/bin/curl >> "$DIR/install.log" 2>&1 rm -f bin/php5/bin/curl* >> "$DIR/install.log" 2>&1
rm -f bin/php5/bin/curl-config >> "$DIR/install.log" 2>&1 rm -f bin/php5/bin/curl-config* >> "$DIR/install.log" 2>&1
rm -f bin/php5/bin/c_rehash >> "$DIR/install.log" 2>&1 rm -f bin/php5/bin/c_rehash* >> "$DIR/install.log" 2>&1
rm -f bin/php5/bin/openssl >> "$DIR/install.log" 2>&1 rm -f bin/php5/bin/openssl* >> "$DIR/install.log" 2>&1
rm -r -f bin/php5/man >> "$DIR/install.log" 2>&1 rm -r -f bin/php5/man >> "$DIR/install.log" 2>&1
rm -r -f bin/php5/php >> "$DIR/install.log" 2>&1 rm -r -f bin/php5/php >> "$DIR/install.log" 2>&1
rm -r -f bin/php5/share >> "$DIR/install.log" 2>&1 rm -r -f bin/php5/share >> "$DIR/install.log" 2>&1

View File

@ -57,7 +57,7 @@ class AsyncMultipleQueue extends Thread{
private function get($len){ private function get($len){
$str = ""; $str = "";
if($len <= 0){ if($len <= 0){
return $len; return "";
} }
$offset = 0; $offset = 0;
while(!isset($str{$len - 1})){ while(!isset($str{$len - 1})){

View File

@ -59,7 +59,7 @@ class ServerSuiteTest{
public function hook(){ public function hook(){
testCase("event fired", true, true); testCase("event fired", true, true);
$server = \PocketMine\ServerAPI::request(); $server = \PocketMine\ServerAPI::request();
//testCase("defaultgamemode", $server->getGamemode(), "survival"); testCase("defaultgamemode", $server->getGamemode(), "survival");
//Everything done! //Everything done!