PHP7 to master

This commit is contained in:
Intyre 2016-02-21 12:47:30 +01:00
commit a6cd526e60
No known key found for this signature in database
GPG Key ID: B06D41D26935005A
153 changed files with 2836 additions and 3536 deletions

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine;
abstract class Collectable extends \Threaded implements \Collectable{
private $isGarbage = false;
public function isGarbage() : bool{
return $this->isGarbage;
}
public function setGarbage(){
$this->isGarbage = true;
}
}

View File

@ -23,10 +23,4 @@ namespace pocketmine;
class CompatibleClassLoader extends \BaseClassLoader{ class CompatibleClassLoader extends \BaseClassLoader{
/**
* @deprecated
*/
public function add($namespace, $paths){
$this->addPath(array_shift($paths));
}
} }

View File

@ -55,13 +55,6 @@ class MemoryManager{
private $chunkCache; private $chunkCache;
private $cacheTrigger; private $cacheTrigger;
/** @var \WeakRef[] */
private $leakWatch = [];
private $leakInfo = [];
private $leakSeed = 0;
public function __construct(Server $server){ public function __construct(Server $server){
$this->server = $server; $this->server = $server;
@ -214,87 +207,6 @@ class MemoryManager{
return $cycles; return $cycles;
} }
/**
* @param object $object
*
* @return string Object identifier for future checks
*/
public function addObjectWatcher($object){
if(!is_object($object)){
throw new \InvalidArgumentException("Not an object!");
}
$identifier = spl_object_hash($object) . ":" . get_class($object);
if(isset($this->leakInfo[$identifier])){
return $this->leakInfo["id"];
}
$this->leakInfo[$identifier] = [
"id" => $id = md5($identifier . ":" . $this->leakSeed++),
"class" => get_class($object),
"hash" => $identifier
];
$this->leakInfo[$id] = $this->leakInfo[$identifier];
$this->leakWatch[$id] = new \WeakRef($object);
return $id;
}
public function isObjectAlive($id){
if(isset($this->leakWatch[$id])){
return $this->leakWatch[$id]->valid();
}
return false;
}
public function removeObjectWatch($id){
if(!isset($this->leakWatch[$id])){
return;
}
unset($this->leakInfo[$this->leakInfo[$id]["hash"]]);
unset($this->leakInfo[$id]);
unset($this->leakWatch[$id]);
}
public function doObjectCleanup(){
foreach($this->leakWatch as $id => $w){
if(!$w->valid()){
$this->removeObjectWatch($id);
}
}
}
public function getObjectInformation($id, $includeObject = false){
if(!isset($this->leakWatch[$id])){
return null;
}
$valid = false;
$references = 0;
$object = null;
if($this->leakWatch[$id]->acquire()){
$object = $this->leakWatch[$id]->get();
$this->leakWatch[$id]->release();
$valid = true;
$references = getReferenceCount($object, false);
}
return [
"id" => $id,
"class" => $this->leakInfo[$id]["class"],
"hash" => $this->leakInfo[$id]["hash"],
"valid" => $valid,
"references" => $references,
"object" => $includeObject ? $object : null
];
}
public function dumpServerMemory($outputFolder, $maxNesting, $maxStringSize){ public function dumpServerMemory($outputFolder, $maxNesting, $maxStringSize){
gc_disable(); gc_disable();

View File

@ -23,7 +23,7 @@ namespace pocketmine;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\plugin\Plugin; use pocketmine\plugin\Plugin;
class OfflinePlayer implements IPlayer{ class OfflinePlayer implements IPlayer{
@ -103,15 +103,15 @@ class OfflinePlayer implements IPlayer{
} }
public function getFirstPlayed(){ public function getFirstPlayed(){
return $this->namedtag instanceof Compound ? $this->namedtag["firstPlayed"] : null; return $this->namedtag instanceof CompoundTag ? $this->namedtag["firstPlayed"] : null;
} }
public function getLastPlayed(){ public function getLastPlayed(){
return $this->namedtag instanceof Compound ? $this->namedtag["lastPlayed"] : null; return $this->namedtag instanceof CompoundTag ? $this->namedtag["lastPlayed"] : null;
} }
public function hasPlayedBefore(){ public function hasPlayedBefore(){
return $this->namedtag instanceof Compound; return $this->namedtag instanceof CompoundTag;
} }
public function setMetadata($metadataKey, MetadataValue $metadataValue){ public function setMetadata($metadataKey, MetadataValue $metadataValue){

View File

@ -21,6 +21,7 @@
namespace pocketmine; namespace pocketmine;
use pocketmine\block\Air;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\entity\Arrow; use pocketmine\entity\Arrow;
@ -76,11 +77,9 @@ use pocketmine\inventory\PlayerInventory;
use pocketmine\inventory\ShapedRecipe; use pocketmine\inventory\ShapedRecipe;
use pocketmine\inventory\ShapelessRecipe; use pocketmine\inventory\ShapelessRecipe;
use pocketmine\inventory\SimpleTransactionGroup; use pocketmine\inventory\SimpleTransactionGroup;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\ChunkLoader; use pocketmine\level\ChunkLoader;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\format\LevelProvider;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Location; use pocketmine\level\Location;
use pocketmine\level\Position; use pocketmine\level\Position;
@ -90,16 +89,15 @@ use pocketmine\math\Vector2;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\LongTag;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\Network;
use pocketmine\network\protocol\AdventureSettingsPacket; use pocketmine\network\protocol\AdventureSettingsPacket;
use pocketmine\network\protocol\AnimatePacket; use pocketmine\network\protocol\AnimatePacket;
use pocketmine\network\protocol\BatchPacket; use pocketmine\network\protocol\BatchPacket;
@ -110,20 +108,19 @@ use pocketmine\network\protocol\DisconnectPacket;
use pocketmine\network\protocol\EntityEventPacket; use pocketmine\network\protocol\EntityEventPacket;
use pocketmine\network\protocol\FullChunkDataPacket; use pocketmine\network\protocol\FullChunkDataPacket;
use pocketmine\network\protocol\Info as ProtocolInfo; use pocketmine\network\protocol\Info as ProtocolInfo;
use pocketmine\network\protocol\MovePlayerPacket;
use pocketmine\network\protocol\PlayerActionPacket; use pocketmine\network\protocol\PlayerActionPacket;
use pocketmine\network\protocol\PlayStatusPacket; use pocketmine\network\protocol\PlayStatusPacket;
use pocketmine\network\protocol\RespawnPacket; use pocketmine\network\protocol\RespawnPacket;
use pocketmine\network\protocol\SetPlayerGameTypePacket;
use pocketmine\network\protocol\TextPacket;
use pocketmine\network\protocol\MovePlayerPacket;
use pocketmine\network\protocol\SetDifficultyPacket; use pocketmine\network\protocol\SetDifficultyPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\network\protocol\SetHealthPacket; use pocketmine\network\protocol\SetHealthPacket;
use pocketmine\network\protocol\SetPlayerGameTypePacket;
use pocketmine\network\protocol\SetSpawnPositionPacket; use pocketmine\network\protocol\SetSpawnPositionPacket;
use pocketmine\network\protocol\SetTimePacket; use pocketmine\network\protocol\SetTimePacket;
use pocketmine\network\protocol\StartGamePacket; use pocketmine\network\protocol\StartGamePacket;
use pocketmine\network\protocol\TakeItemEntityPacket; use pocketmine\network\protocol\TakeItemEntityPacket;
use pocketmine\network\protocol\TextPacket;
use pocketmine\network\protocol\UpdateBlockPacket; use pocketmine\network\protocol\UpdateBlockPacket;
use pocketmine\network\SourceInterface; use pocketmine\network\SourceInterface;
use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleBase;
@ -133,10 +130,9 @@ use pocketmine\tile\Sign;
use pocketmine\tile\Spawnable; use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use raklib\Binary; use raklib\Binary;
/** /**
* Main class that handles networking, recovery, and packet sending to the server part * Main class that handles networking, recovery, and packet sending to the server part
*/ */
@ -183,12 +179,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
protected $isCrafting = false; protected $isCrafting = false;
/**
* @deprecated
* @var array
*/
public $loginData = [];
public $creationTime = 0; public $creationTime = 0;
protected $randomClientId; protected $randomClientId;
@ -227,7 +217,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
protected $viewDistance; protected $viewDistance;
protected $chunksPerTick; protected $chunksPerTick;
protected $spawnThreshold; protected $spawnThreshold;
/** @var null|Position */ /** @var null|Position */
private $spawnPosition = null; private $spawnPosition = null;
@ -296,15 +286,15 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
public function getFirstPlayed(){ public function getFirstPlayed(){
return $this->namedtag instanceof Compound ? $this->namedtag["firstPlayed"] : null; return $this->namedtag instanceof CompoundTag ? $this->namedtag["firstPlayed"] : null;
} }
public function getLastPlayed(){ public function getLastPlayed(){
return $this->namedtag instanceof Compound ? $this->namedtag["lastPlayed"] : null; return $this->namedtag instanceof CompoundTag ? $this->namedtag["lastPlayed"] : null;
} }
public function hasPlayedBefore(){ public function hasPlayedBefore(){
return $this->namedtag instanceof Compound; return $this->namedtag instanceof CompoundTag;
} }
public function setAllowFlight($value){ public function setAllowFlight($value){
@ -503,7 +493,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->interface = $interface; $this->interface = $interface;
$this->windows = new \SplObjectStorage(); $this->windows = new \SplObjectStorage();
$this->perm = new PermissibleBase($this); $this->perm = new PermissibleBase($this);
$this->namedtag = new Compound(); $this->namedtag = new CompoundTag();
$this->server = Server::getInstance(); $this->server = Server::getInstance();
$this->lastBreak = PHP_INT_MAX; $this->lastBreak = PHP_INT_MAX;
$this->ip = $ip; $this->ip = $ip;
@ -511,7 +501,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->clientID = $clientID; $this->clientID = $clientID;
$this->loaderId = Level::generateChunkLoaderId($this); $this->loaderId = Level::generateChunkLoaderId($this);
$this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4);
$this->spawnThreshold = (int) $this->server->getProperty("chunk-sending.spawn-threshold", 56); $this->spawnThreshold = (int) $this->server->getProperty("chunk-sending.spawn-threshold", 56);
$this->spawnPosition = null; $this->spawnPosition = null;
$this->gamemode = $this->server->getGamemode(); $this->gamemode = $this->server->getGamemode();
$this->setLevel($this->server->getDefaultLevel()); $this->setLevel($this->server->getDefaultLevel());
@ -565,9 +555,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return $this->displayName; return $this->displayName;
} }
/** /**
* @param string $name * @param string $name
*/ */
public function setDisplayName($name){ public function setDisplayName($name){
$this->displayName = $name; $this->displayName = $name;
if($this->spawned){ if($this->spawned){
@ -889,11 +879,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return false; return false;
} }
if(!isset($this->batchedPackets[$packet->getChannel()])){ $this->batchedPackets[] = clone $packet;
$this->batchedPackets[$packet->getChannel()] = [];
}
$this->batchedPackets[$packet->getChannel()][] = clone $packet;
$timings->stopTiming(); $timings->stopTiming();
return true; return true;
} }
@ -1100,7 +1086,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->spawnToAll(); $this->spawnToAll();
} }
$this->namedtag->playerGameType = new Int("playerGameType", $this->gamemode); $this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
$pk = new SetPlayerGameTypePacket(); $pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01; $pk->gamemode = $this->gamemode & 0x01;
@ -1216,20 +1202,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return []; return [];
} }
/**
* @deprecated
*/
public function addEntityMotion($entityId, $x, $y, $z){
}
/**
* @deprecated
*/
public function addEntityMovement($entityId, $x, $y, $z, $yaw, $pitch, $headYaw = null){
}
public function setDataProperty($id, $type, $value){ public function setDataProperty($id, $type, $value){
if(parent::setDataProperty($id, $type, $value)){ if(parent::setDataProperty($id, $type, $value)){
$this->sendData($this, [$id => $this->dataProperties[$id]]); $this->sendData($this, [$id => $this->dataProperties[$id]]);
@ -1554,9 +1526,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
if(count($this->batchedPackets) > 0){ if(count($this->batchedPackets) > 0){
foreach($this->batchedPackets as $channel => $list){ $this->server->batchPackets([$this], $this->batchedPackets, false);
$this->server->batchPackets([$this], $list, false, $channel);
}
$this->batchedPackets = []; $this->batchedPackets = [];
} }
@ -1628,14 +1598,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$nbt = $this->server->getOfflinePlayerData($this->username); $nbt = $this->server->getOfflinePlayerData($this->username);
if(!isset($nbt->NameTag)){ if(!isset($nbt->NameTag)){
$nbt->NameTag = new String("NameTag", $this->username); $nbt->NameTag = new StringTag("NameTag", $this->username);
}else{ }else{
$nbt["NameTag"] = $this->username; $nbt["NameTag"] = $this->username;
} }
$this->gamemode = $nbt["playerGameType"] & 0x03; $this->gamemode = $nbt["playerGameType"] & 0x03;
if($this->server->getForceGamemode()){ if($this->server->getForceGamemode()){
$this->gamemode = $this->server->getGamemode(); $this->gamemode = $this->server->getGamemode();
$nbt->playerGameType = new Int("playerGameType", $this->gamemode); $nbt->playerGameType = new IntTag("playerGameType", $this->gamemode);
} }
$this->allowFlight = $this->isCreative(); $this->allowFlight = $this->isCreative();
@ -1651,7 +1621,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->setLevel($level); $this->setLevel($level);
} }
if(!($nbt instanceof Compound)){ if(!($nbt instanceof CompoundTag)){
$this->close($this->getLeaveMessage(), "Invalid data"); $this->close($this->getLeaveMessage(), "Invalid data");
return; return;
@ -1664,7 +1634,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->achievements[$achievement->getName()] = $achievement->getValue() > 0 ? true : false; $this->achievements[$achievement->getName()] = $achievement->getValue() > 0 ? true : false;
} }
$nbt->lastPlayed = new Long("lastPlayed", floor(microtime(true) * 1000)); $nbt->lastPlayed = new LongTag("lastPlayed", floor(microtime(true) * 1000));
if($this->server->getAutoSave()){ if($this->server->getAutoSave()){
$this->server->saveOfflinePlayerData($this->username, $nbt, true); $this->server->saveOfflinePlayerData($this->username, $nbt, true);
} }
@ -1936,13 +1906,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
break; break;
} }
}else{ }else{
if($packet->selectedSlot >= 0 and $packet->selectedSlot < 9){ if($packet->selectedSlot >= 0 and $packet->selectedSlot < 9){
$this->inventory->setHeldItemIndex($packet->selectedSlot); $this->inventory->setHeldItemIndex($packet->selectedSlot);
$this->inventory->setHeldItemSlot($packet->slot); $this->inventory->setHeldItemSlot($packet->slot);
}else{ }else{
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
} }
}elseif($item === null or $slot === -1 or !$item->deepEquals($packet->item)){ // packet error or not implemented }elseif($item === null or $slot === -1 or !$item->deepEquals($packet->item)){ // packet error or not implemented
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
@ -1952,13 +1922,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->inventory->setItem($packet->selectedSlot, $item); $this->inventory->setItem($packet->selectedSlot, $item);
$this->inventory->setHeldItemSlot($packet->selectedSlot); $this->inventory->setHeldItemSlot($packet->selectedSlot);
}else{ }else{
if($packet->selectedSlot >= 0 and $packet->selectedSlot < $this->inventory->getHotbarSize()){ if($packet->selectedSlot >= 0 and $packet->selectedSlot < $this->inventory->getHotbarSize()){
$this->inventory->setHeldItemIndex($packet->selectedSlot); $this->inventory->setHeldItemIndex($packet->selectedSlot);
$this->inventory->setHeldItemSlot($slot); $this->inventory->setHeldItemSlot($slot);
}else{ }else{
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
} }
$this->inventory->sendHeldItem($this->hasSpawned); $this->inventory->sendHeldItem($this->hasSpawned);
@ -2031,20 +2001,20 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
if($item->getId() === Item::SNOWBALL){ if($item->getId() === Item::SNOWBALL){
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $this->x), new DoubleTag("", $this->x),
new Double("", $this->y + $this->getEyeHeight()), new DoubleTag("", $this->y + $this->getEyeHeight()),
new Double("", $this->z) new DoubleTag("", $this->z)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", $aimPos->x), new DoubleTag("", $aimPos->x),
new Double("", $aimPos->y), new DoubleTag("", $aimPos->y),
new Double("", $aimPos->z) new DoubleTag("", $aimPos->z)
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", $this->yaw), new FloatTag("", $this->yaw),
new Float("", $this->pitch) new FloatTag("", $this->pitch)
]), ]),
]); ]);
@ -2092,6 +2062,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->inventory->sendHeldItem($this); $this->inventory->sendHeldItem($this);
break; break;
} }
$block = $target->getSide($packet->face);
if($block->getId() === Block::FIRE){
$this->level->setBlock($block, new Air());
}
$this->lastBreak = microtime(true); $this->lastBreak = microtime(true);
break; break;
case PlayerActionPacket::ACTION_ABORT_BREAK: case PlayerActionPacket::ACTION_ABORT_BREAK:
@ -2099,30 +2073,30 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
break; break;
case PlayerActionPacket::ACTION_RELEASE_ITEM: case PlayerActionPacket::ACTION_RELEASE_ITEM:
if($this->startAction > -1 and $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION)){ if($this->startAction > -1 and $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION)){
if($this->inventory->getItemInHand()->getId() === Item::BOW) { if($this->inventory->getItemInHand()->getId() === Item::BOW){
$bow = $this->inventory->getItemInHand(); $bow = $this->inventory->getItemInHand();
if ($this->isSurvival() and !$this->inventory->contains(Item::get(Item::ARROW, 0, 1))) { if($this->isSurvival() and !$this->inventory->contains(Item::get(Item::ARROW, 0, 1))){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $this->x), new DoubleTag("", $this->x),
new Double("", $this->y + $this->getEyeHeight()), new DoubleTag("", $this->y + $this->getEyeHeight()),
new Double("", $this->z) new DoubleTag("", $this->z)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)), new DoubleTag("", -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)),
new Double("", -sin($this->pitch / 180 * M_PI)), new DoubleTag("", -sin($this->pitch / 180 * M_PI)),
new Double("", cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)) new DoubleTag("", cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI))
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", $this->yaw), new FloatTag("", $this->yaw),
new Float("", $this->pitch) new FloatTag("", $this->pitch)
]), ]),
"Fire" => new Short("Fire", $this->isOnFire() ? 45 * 60 : 0) "Fire" => new ShortTag("Fire", $this->isOnFire() ? 45 * 60 : 0)
]); ]);
$diff = ($this->server->getTick() - $this->startAction); $diff = ($this->server->getTick() - $this->startAction);
@ -2130,35 +2104,35 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$f = min((($p ** 2) + $p * 2) / 3, 1) * 2; $f = min((($p ** 2) + $p * 2) / 3, 1) * 2;
$ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this, $f == 2 ? true : false), $f); $ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this, $f == 2 ? true : false), $f);
if ($f < 0.1 or $diff < 5) { if($f < 0.1 or $diff < 5){
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
if ($ev->isCancelled()) { if($ev->isCancelled()){
$ev->getProjectile()->kill(); $ev->getProjectile()->kill();
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
} else { }else{
$ev->getProjectile()->setMotion($ev->getProjectile()->getMotion()->multiply($ev->getForce())); $ev->getProjectile()->setMotion($ev->getProjectile()->getMotion()->multiply($ev->getForce()));
if($this->isSurvival()){ if($this->isSurvival()){
$this->inventory->removeItem(Item::get(Item::ARROW, 0, 1)); $this->inventory->removeItem(Item::get(Item::ARROW, 0, 1));
$bow->setDamage($bow->getDamage() + 1); $bow->setDamage($bow->getDamage() + 1);
if ($bow->getDamage() >= 385) { if($bow->getDamage() >= 385){
$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 0)); $this->inventory->setItemInHand(Item::get(Item::AIR, 0, 0));
} else { }else{
$this->inventory->setItemInHand($bow); $this->inventory->setItemInHand($bow);
} }
} }
if ($ev->getProjectile() instanceof Projectile) { if($ev->getProjectile() instanceof Projectile){
$this->server->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($ev->getProjectile())); $this->server->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($ev->getProjectile()));
if ($projectileEv->isCancelled()) { if($projectileEv->isCancelled()){
$ev->getProjectile()->kill(); $ev->getProjectile()->kill();
} else { }else{
$ev->getProjectile()->spawnToAll(); $ev->getProjectile()->spawnToAll();
$this->level->addSound(new LaunchSound($this), $this->getViewers()); $this->level->addSound(new LaunchSound($this), $this->getViewers());
} }
} else { }else{
$ev->getProjectile()->spawnToAll(); $ev->getProjectile()->spawnToAll();
} }
} }
@ -2176,7 +2150,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->dataPacket($pk); $this->dataPacket($pk);
Server::broadcastPacket($this->getViewers(), $pk); Server::broadcastPacket($this->getViewers(), $pk);
if ($this->isSurvival()) { if($this->isSurvival()){
$slot = $this->inventory->getItemInHand(); $slot = $this->inventory->getItemInHand();
--$slot->count; --$slot->count;
$this->inventory->setItemInHand($slot); $this->inventory->setItemInHand($slot);
@ -2304,7 +2278,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->level->sendBlocks([$this], [$target], UpdateBlockPacket::FLAG_ALL_PRIORITY); $this->level->sendBlocks([$this], [$target], UpdateBlockPacket::FLAG_ALL_PRIORITY);
$this->inventory->sendHeldItem($this); $this->inventory->sendHeldItem($this);
if($tile instanceof Spawnable){ if($tile instanceof Spawnable){
$tile->spawnTo($this); $tile->spawnTo($this);
@ -2511,7 +2485,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
if(is_array($amount)){ if(is_array($amount)){
$amount = isset($amount[$slot->getDamage()]) ? $amount[$slot->getDamage()] : 0; $amount = isset($amount[$slot->getDamage()]) ? $amount[$slot->getDamage()] : 0;
} }
$ev = new EntityRegainHealthEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING); $ev = new EntityRegainHealthEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING);
$this->heal($ev->getAmount(), $ev); $this->heal($ev->getAmount(), $ev);
--$slot->count; --$slot->count;
@ -2675,7 +2649,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$result = $packet->output[0]; $result = $packet->output[0];
if(!$canCraft or !$recipe->getResult()->deepEquals($result)){ if(!$canCraft or !$recipe->getResult()->deepEquals($result)){
$this->server->getLogger()->debug("Unmatched recipe ". $recipe->getId() ." from player ". $this->getName() .": expected " . $recipe->getResult() . ", got ". $result .", using: " . implode(", ", $ingredients)); $this->server->getLogger()->debug("Unmatched recipe " . $recipe->getId() . " from player " . $this->getName() . ": expected " . $recipe->getResult() . ", got " . $result . ", using: " . implode(", ", $ingredients));
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
@ -2685,7 +2659,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
foreach($ingredients as $ingredient){ foreach($ingredients as $ingredient){
$slot = -1; $slot = -1;
foreach($this->inventory->getContents() as $index => $i){ foreach($this->inventory->getContents() as $index => $i){
if($ingredient->getId() !== 0 and $ingredient->deepEquals($i, $i->getDamage() !== null) and ($i->getCount() - $used[$index]) >= 1){ if($ingredient->getId() !== 0 and $ingredient->deepEquals($i, $ingredient->getDamage() !== null) and ($i->getCount() - $used[$index]) >= 1){
$slot = $index; $slot = $index;
$used[$index]++; $used[$index]++;
break; break;
@ -2699,7 +2673,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
if(!$canCraft){ if(!$canCraft){
$this->server->getLogger()->debug("Unmatched recipe ". $recipe->getId() ." from player ". $this->getName() .": client does not have enough items, using: " . implode(", ", $ingredients)); $this->server->getLogger()->debug("Unmatched recipe " . $recipe->getId() . " from player " . $this->getName() . ": client does not have enough items, using: " . implode(", ", $ingredients));
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
@ -2913,11 +2887,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->server->getPluginManager()->callEvent($ev = new PlayerKickEvent($this, $reason, $this->getLeaveMessage())); $this->server->getPluginManager()->callEvent($ev = new PlayerKickEvent($this, $reason, $this->getLeaveMessage()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
if($isAdmin){ if($isAdmin){
if(!$this->isBanned()) { if(!$this->isBanned()){
$message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""); $message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : "");
}else{ }else{
$message = $reason; $message = $reason;
} }
}else{ }else{
if($reason === ""){ if($reason === ""){
$message = "disconnectionScreen.noReason"; $message = "disconnectionScreen.noReason";
@ -2940,11 +2914,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
*/ */
public function sendMessage($message){ public function sendMessage($message){
if($message instanceof TextContainer){ if($message instanceof TextContainer){
if ($message instanceof TranslationContainer) { if($message instanceof TranslationContainer){
$this->sendTranslation($message->getText(), $message->getParameters()); $this->sendTranslation($message->getText(), $message->getParameters());
return; return;
} }
$message = $message->getText(); $message = $message->getText();
} }
@ -2996,7 +2970,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
* *
* @param string $message Message to be broadcasted * @param string $message Message to be broadcasted
* @param string $reason Reason showed in console * @param string $reason Reason showed in console
* @param bool $notify * @param bool $notify
*/ */
public final function close($message = "", $reason = "generic reason", $notify = true){ public final function close($message = "", $reason = "generic reason", $notify = true){
@ -3092,7 +3066,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
parent::saveNBT(); parent::saveNBT();
if($this->level instanceof Level){ if($this->level instanceof Level){
$this->namedtag->Level = new String("Level", $this->level->getName()); $this->namedtag->Level = new StringTag("Level", $this->level->getName());
if($this->spawnPosition instanceof Position and $this->spawnPosition->getLevel() instanceof Level){ if($this->spawnPosition instanceof Position and $this->spawnPosition->getLevel() instanceof Level){
$this->namedtag["SpawnLevel"] = $this->spawnPosition->getLevel()->getName(); $this->namedtag["SpawnLevel"] = $this->spawnPosition->getLevel()->getName();
$this->namedtag["SpawnX"] = (int) $this->spawnPosition->x; $this->namedtag["SpawnX"] = (int) $this->spawnPosition->x;
@ -3101,13 +3075,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
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 ByteTag($achievement, $status === true ? 1 : 0);
} }
$this->namedtag["playerGameType"] = $this->gamemode; $this->namedtag["playerGameType"] = $this->gamemode;
$this->namedtag["lastPlayed"] = new Long("lastPlayed", floor(microtime(true) * 1000)); $this->namedtag["lastPlayed"] = new LongTag("lastPlayed", floor(microtime(true) * 1000));
if($this->username != "" and $this->namedtag instanceof Compound){ if($this->username != "" and $this->namedtag instanceof CompoundTag){
$this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async); $this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async);
} }
} }
@ -3280,13 +3254,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return; return;
} }
if($this->isCreative() if($this->isCreative()
and $source->getCause() !== EntityDamageEvent::CAUSE_MAGIC and $source->getCause() !== EntityDamageEvent::CAUSE_MAGIC
and $source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE and $source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE
and $source->getCause() !== EntityDamageEvent::CAUSE_VOID and $source->getCause() !== EntityDamageEvent::CAUSE_VOID
){ ){
$source->setCancelled(); $source->setCancelled();
}elseif($this->allowFlight and $source->getCause() === EntityDamageEvent::CAUSE_FALL){ }elseif($this->allowFlight and $source->getCause() === EntityDamageEvent::CAUSE_FALL){
$source->setCancelled(); $source->setCancelled();
} }
@ -3385,11 +3359,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
/** /**
* @param Vector3|Position|Location $pos * @param Vector3|Position|Location $pos
* @param float $yaw * @param float $yaw
* @param float $pitch * @param float $pitch
* *
* @return bool * @return bool
*/ */
public function teleport(Vector3 $pos, $yaw = null, $pitch = null){ public function teleport(Vector3 $pos, $yaw = null, $pitch = null){
if(!$this->isOnline()){ if(!$this->isOnline()){
return false; return false;

View File

@ -73,10 +73,10 @@ namespace pocketmine {
use pocketmine\wizard\Installer; use pocketmine\wizard\Installer;
const VERSION = "1.6dev"; const VERSION = "1.6dev";
const API_VERSION = "1.13.1"; const API_VERSION = "2.0.0";
const CODENAME = "[REDACTED]"; const CODENAME = "[REDACTED]";
const MINECRAFT_VERSION = "v0.13.2 alpha"; const MINECRAFT_VERSION = "v0.14.0.0 alpha";
const MINECRAFT_VERSION_NETWORK = "0.13.2"; const MINECRAFT_VERSION_NETWORK = "0.14.0.0";
/* /*
* Startup code. Do not look at it, it may harm you. * Startup code. Do not look at it, it may harm you.
@ -86,9 +86,15 @@ namespace pocketmine {
*/ */
if(\Phar::running(true) !== ""){ if(\Phar::running(true) !== ""){
@define("pocketmine\\PATH", \Phar::running(true) . "/"); @define('pocketmine\PATH', \Phar::running(true) . "/");
}else{ }else{
@define("pocketmine\\PATH", \getcwd() . DIRECTORY_SEPARATOR); @define('pocketmine\PATH', \getcwd() . DIRECTORY_SEPARATOR);
}
if(version_compare("7.0", PHP_VERSION) > 0){
echo "[CRITICAL] You must use PHP >= 7.0" . PHP_EOL;
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
exit(1);
} }
if(!extension_loaded("pthreads")){ if(!extension_loaded("pthreads")){
@ -98,7 +104,6 @@ namespace pocketmine {
} }
if(!class_exists("ClassLoader", false)){ if(!class_exists("ClassLoader", false)){
require_once(\pocketmine\PATH . "src/spl/ThreadedFactory.php");
require_once(\pocketmine\PATH . "src/spl/ClassLoader.php"); require_once(\pocketmine\PATH . "src/spl/ClassLoader.php");
require_once(\pocketmine\PATH . "src/spl/BaseClassLoader.php"); require_once(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
require_once(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php"); require_once(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
@ -120,16 +125,16 @@ namespace pocketmine {
ini_set("default_charset", "utf-8"); ini_set("default_charset", "utf-8");
ini_set("memory_limit", -1); ini_set("memory_limit", -1);
define("pocketmine\\START_TIME", microtime(true)); define('pocketmine\START_TIME', microtime(true));
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]); $opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]);
define("pocketmine\\DATA", isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR); define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR); define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
Terminal::init(); Terminal::init();
define("pocketmine\\ANSI", Terminal::hasFormattingCodes()); define('pocketmine\ANSI', Terminal::hasFormattingCodes());
if(!file_exists(\pocketmine\DATA)){ if(!file_exists(\pocketmine\DATA)){
mkdir(\pocketmine\DATA, 0777, true); mkdir(\pocketmine\DATA, 0777, true);
@ -137,6 +142,7 @@ namespace pocketmine {
//Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone. //Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone.
date_default_timezone_set("UTC"); date_default_timezone_set("UTC");
$logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI); $logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI);
if(!ini_get("date.timezone")){ if(!ini_get("date.timezone")){
@ -314,7 +320,11 @@ namespace pocketmine {
case "mac": case "mac":
case "linux": case "linux":
default: default:
exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); if(function_exists("posix_kill")){
posix_kill($pid, SIGKILL);
}else{
exec("kill -9 " . ((int)$pid) . " > /dev/null 2>&1");
}
} }
} }
@ -370,15 +380,8 @@ namespace pocketmine {
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/"); return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
} }
set_error_handler([\ExceptionHandler::class, "handler"], -1);
$errors = 0; $errors = 0;
if(version_compare("5.6.0", PHP_VERSION) > 0){
$logger->critical("You must use PHP >= 5.6");
++$errors;
}
if(php_sapi_name() !== "cli"){ if(php_sapi_name() !== "cli"){
$logger->critical("You must run PocketMine-MP using the CLI."); $logger->critical("You must run PocketMine-MP using the CLI.");
++$errors; ++$errors;
@ -393,8 +396,8 @@ namespace pocketmine {
if(substr_count($pthreads_version, ".") < 2){ if(substr_count($pthreads_version, ".") < 2){
$pthreads_version = "0.$pthreads_version"; $pthreads_version = "0.$pthreads_version";
} }
if(version_compare($pthreads_version, "2.0.9") < 0){ if(version_compare($pthreads_version, "3.1.5") < 0){
$logger->critical("pthreads >= 2.0.9 is required, while you have $pthreads_version."); $logger->critical("pthreads >= 3.1.5 is required, while you have $pthreads_version.");
++$errors; ++$errors;
} }
@ -412,23 +415,18 @@ namespace pocketmine {
} }
} }
if(!extension_loaded("Weakref") and !extension_loaded("weakref")){
$logger->critical("Unable to find the Weakref extension.");
++$errors;
}
if(!extension_loaded("curl")){ if(!extension_loaded("curl")){
$logger->critical("Unable to find the cURL extension."); $logger->critical("Unable to find the cURL extension.");
++$errors; ++$errors;
} }
if(!extension_loaded("sqlite3")){ if(!extension_loaded("yaml")){
$logger->critical("Unable to find the SQLite3 extension."); $logger->critical("Unable to find the YAML extension.");
++$errors; ++$errors;
} }
if(!extension_loaded("yaml")){ if(!extension_loaded("sqlite3")){
$logger->critical("Unable to find the YAML extension."); $logger->critical("Unable to find the SQLite3 extension.");
++$errors; ++$errors;
} }
@ -445,9 +443,9 @@ namespace pocketmine {
} }
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));
} }
@define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN)); @define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN));
@ -474,7 +472,6 @@ namespace pocketmine {
$killer = new ServerKiller(8); $killer = new ServerKiller(8);
$killer->start(); $killer->start();
$killer->detach();
$logger->shutdown(); $logger->shutdown();
$logger->join(); $logger->join();

View File

@ -73,15 +73,15 @@ use pocketmine\metadata\EntityMetadataStore;
use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\LevelMetadataStore;
use pocketmine\metadata\PlayerMetadataStore; use pocketmine\metadata\PlayerMetadataStore;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\LongTag;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\CompressBatchedTask; use pocketmine\network\CompressBatchedTask;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\BatchPacket; use pocketmine\network\protocol\BatchPacket;
@ -117,7 +117,6 @@ use pocketmine\utils\ServerException;
use pocketmine\utils\ServerKiller; use pocketmine\utils\ServerKiller;
use pocketmine\utils\Terminal; use pocketmine\utils\Terminal;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use pocketmine\utils\TextWrapper;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
use pocketmine\utils\UUID; use pocketmine\utils\UUID;
use pocketmine\utils\VersionString; use pocketmine\utils\VersionString;
@ -132,6 +131,9 @@ class Server{
/** @var Server */ /** @var Server */
private static $instance = null; private static $instance = null;
/** @var \Threaded */
private static $sleeper = null;
/** @var BanList */ /** @var BanList */
private $banByName = null; private $banByName = null;
@ -360,13 +362,6 @@ class Server{
return $this->getConfigString("server-ip", "0.0.0.0"); return $this->getConfigString("server-ip", "0.0.0.0");
} }
/**
* @deprecated
*/
public function getServerName(){
return $this->getConfigString("motd", "Minecraft: PE Server");
}
public function getServerUniqueId(){ public function getServerUniqueId(){
return $this->serverID; return $this->serverID;
} }
@ -656,56 +651,6 @@ class Server{
return round((array_sum($this->useAverage) / count($this->useAverage)) * 100, 2); return round((array_sum($this->useAverage) / count($this->useAverage)) * 100, 2);
} }
/**
* @deprecated
*
* @param $address
* @param int $timeout
*/
public function blockAddress($address, $timeout = 300){
$this->network->blockAddress($address, $timeout);
}
/**
* @deprecated
*
* @param $address
* @param $port
* @param $payload
*/
public function sendPacket($address, $port, $payload){
$this->network->sendPacket($address, $port, $payload);
}
/**
* @deprecated
*
* @return SourceInterface[]
*/
public function getInterfaces(){
return $this->network->getInterfaces();
}
/**
* @deprecated
*
* @param SourceInterface $interface
*/
public function addInterface(SourceInterface $interface){
$this->network->registerInterface($interface);
}
/**
* @deprecated
*
* @param SourceInterface $interface
*/
public function removeInterface(SourceInterface $interface){
$interface->shutdown();
$this->network->unregisterInterface($interface);
}
/** /**
* @return SimpleCommandMap * @return SimpleCommandMap
*/ */
@ -743,7 +688,7 @@ class Server{
/** /**
* @param string $name * @param string $name
* *
* @return Compound * @return CompoundTag
*/ */
public function getOfflinePlayerData($name){ public function getOfflinePlayerData($name){
$name = strtolower($name); $name = strtolower($name);
@ -754,7 +699,7 @@ class Server{
$nbt->readCompressed(file_get_contents($path . "$name.dat")); $nbt->readCompressed(file_get_contents($path . "$name.dat"));
return $nbt->getData(); return $nbt->getData();
}catch(\Exception $e){ //zlib decode error / corrupt data }catch(\Throwable $e){ //zlib decode error / corrupt data
rename($path . "$name.dat", $path . "$name.dat.bak"); rename($path . "$name.dat", $path . "$name.dat.bak");
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name]));
} }
@ -762,38 +707,38 @@ class Server{
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name]));
} }
$spawn = $this->getDefaultLevel()->getSafeSpawn(); $spawn = $this->getDefaultLevel()->getSafeSpawn();
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Long("firstPlayed", floor(microtime(true) * 1000)), new LongTag("firstPlayed", floor(microtime(true) * 1000)),
new Long("lastPlayed", floor(microtime(true) * 1000)), new LongTag("lastPlayed", floor(microtime(true) * 1000)),
new Enum("Pos", [ new ListTag("Pos", [
new Double(0, $spawn->x), new DoubleTag(0, $spawn->x),
new Double(1, $spawn->y), new DoubleTag(1, $spawn->y),
new Double(2, $spawn->z) new DoubleTag(2, $spawn->z)
]), ]),
new String("Level", $this->getDefaultLevel()->getName()), new StringTag("Level", $this->getDefaultLevel()->getName()),
//new String("SpawnLevel", $this->getDefaultLevel()->getName()), //new StringTag("SpawnLevel", $this->getDefaultLevel()->getName()),
//new Int("SpawnX", (int) $spawn->x), //new IntTag("SpawnX", (int) $spawn->x),
//new Int("SpawnY", (int) $spawn->y), //new IntTag("SpawnY", (int) $spawn->y),
//new Int("SpawnZ", (int) $spawn->z), //new IntTag("SpawnZ", (int) $spawn->z),
//new Byte("SpawnForced", 1), //TODO //new ByteTag("SpawnForced", 1), //TODO
new Enum("Inventory", []), new ListTag("Inventory", []),
new Compound("Achievements", []), new CompoundTag("Achievements", []),
new Int("playerGameType", $this->getGamemode()), new IntTag("playerGameType", $this->getGamemode()),
new Enum("Motion", [ new ListTag("Motion", [
new Double(0, 0.0), new DoubleTag(0, 0.0),
new Double(1, 0.0), new DoubleTag(1, 0.0),
new Double(2, 0.0) new DoubleTag(2, 0.0)
]), ]),
new Enum("Rotation", [ new ListTag("Rotation", [
new Float(0, 0.0), new FloatTag(0, 0.0),
new Float(1, 0.0) new FloatTag(1, 0.0)
]), ]),
new Float("FallDistance", 0.0), new FloatTag("FallDistance", 0.0),
new Short("Fire", 0), new ShortTag("Fire", 0),
new Short("Air", 300), new ShortTag("Air", 300),
new Byte("OnGround", 1), new ByteTag("OnGround", 1),
new Byte("Invulnerable", 0), new ByteTag("Invulnerable", 0),
new String("NameTag", $name), new StringTag("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);
@ -814,39 +759,39 @@ class Server{
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerOld", [$name])); $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerOld", [$name]));
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("", [ $nbt->Inventory[$slot + 9] = new CompoundTag("", [
new Short("id", $item[0]), new ShortTag("id", $item[0]),
new Short("Damage", $item[1]), new ShortTag("Damage", $item[1]),
new Byte("Count", $item[2]), new ByteTag("Count", $item[2]),
new Byte("Slot", $slot + 9), new ByteTag("Slot", $slot + 9),
new Byte("TrueSlot", $slot + 9) new ByteTag("TrueSlot", $slot + 9)
]); ]);
} }
} }
foreach($data->get("hotbar") as $slot => $itemSlot){ foreach($data->get("hotbar") as $slot => $itemSlot){
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("", [ $nbt->Inventory[$slot] = new CompoundTag("", [
new Short("id", $item["id"]), new ShortTag("id", $item["id"]),
new Short("Damage", $item["Damage"]), new ShortTag("Damage", $item["Damage"]),
new Byte("Count", $item["Count"]), new ByteTag("Count", $item["Count"]),
new Byte("Slot", $slot), new ByteTag("Slot", $slot),
new Byte("TrueSlot", $item["TrueSlot"]) new ByteTag("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("", [ $nbt->Inventory[$slot + 100] = new CompoundTag("", [
new Short("id", $item[0]), new ShortTag("id", $item[0]),
new Short("Damage", $item[1]), new ShortTag("Damage", $item[1]),
new Byte("Count", 1), new ByteTag("Count", 1),
new Byte("Slot", $slot + 100) new ByteTag("Slot", $slot + 100)
]); ]);
} }
} }
foreach($data->get("achievements") as $achievement => $status){ foreach($data->get("achievements") as $achievement => $status){
$nbt->Achievements[$achievement] = new Byte($achievement, $status == true ? 1 : 0); $nbt->Achievements[$achievement] = new ByteTag($achievement, $status == true ? 1 : 0);
} }
unlink($path . "$name.yml"); unlink($path . "$name.yml");
} }
@ -858,10 +803,10 @@ class Server{
/** /**
* @param string $name * @param string $name
* @param Compound $nbtTag * @param CompoundTag $nbtTag
* @param bool $async * @param bool $async
*/ */
public function saveOfflinePlayerData($name, Compound $nbtTag, $async = false){ public function saveOfflinePlayerData($name, CompoundTag $nbtTag, $async = false){
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
try{ try{
$nbt->setData($nbtTag); $nbt->setData($nbtTag);
@ -871,11 +816,9 @@ class Server{
}else{ }else{
file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed()); file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed());
} }
}catch(\Exception $e){ }catch(\Throwable $e){
$this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()]));
if(\pocketmine\DEBUG > 1 and $this->logger instanceof MainLogger){ $this->logger->logException($e);
$this->logger->logException($e);
}
} }
} }
@ -1082,12 +1025,10 @@ class Server{
try{ try{
$level = new Level($this, $name, $path, $provider); $level = new Level($this, $name, $path, $provider);
}catch(\Exception $e){ }catch(\Throwable $e){
$this->logger->error($this->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); $this->logger->error($this->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()]));
if($this->logger instanceof MainLogger){ $this->logger->logException($e);
$this->logger->logException($e);
}
return false; return false;
} }
@ -1142,11 +1083,9 @@ class Server{
$level->initLevel(); $level->initLevel();
$level->setTickRate($this->baseTickRate); $level->setTickRate($this->baseTickRate);
}catch(\Exception $e){ }catch(\Throwable $e){
$this->logger->error($this->getLanguage()->translateString("pocketmine.level.generateError", [$name, $e->getMessage()])); $this->logger->error($this->getLanguage()->translateString("pocketmine.level.generateError", [$name, $e->getMessage()]));
if($this->logger instanceof MainLogger){ $this->logger->logException($e);
$this->logger->logException($e);
}
return false; return false;
} }
@ -1438,10 +1377,16 @@ class Server{
/** /**
* @return Server * @return Server
*/ */
public static function getInstance(){ public static function getInstance() : Server{
return self::$instance; return self::$instance;
} }
public static function microSleep(int $microseconds){
Server::$sleeper->synchronized(function(int $ms){
Server::$sleeper->wait($ms);
}, $microseconds);
}
/** /**
* @param \ClassLoader $autoloader * @param \ClassLoader $autoloader
* @param \ThreadedLogger $logger * @param \ThreadedLogger $logger
@ -1451,256 +1396,261 @@ class Server{
*/ */
public function __construct(\ClassLoader $autoloader, \ThreadedLogger $logger, $filePath, $dataPath, $pluginPath){ public function __construct(\ClassLoader $autoloader, \ThreadedLogger $logger, $filePath, $dataPath, $pluginPath){
self::$instance = $this; self::$instance = $this;
self::$sleeper = new \Threaded;
$this->autoloader = $autoloader; $this->autoloader = $autoloader;
$this->logger = $logger; $this->logger = $logger;
$this->filePath = $filePath;
if(!file_exists($dataPath . "worlds/")){
mkdir($dataPath . "worlds/", 0777);
}
if(!file_exists($dataPath . "players/")){ try{
mkdir($dataPath . "players/", 0777);
}
if(!file_exists($pluginPath)){ $this->filePath = $filePath;
mkdir($pluginPath, 0777); if(!file_exists($dataPath . "worlds/")){
} mkdir($dataPath . "worlds/", 0777);
$this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
$this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
$this->console = new CommandReader();
$version = new VersionString($this->getPocketMineVersion());
$this->logger->info("Loading pocketmine.yml...");
if(!file_exists($this->dataPath . "pocketmine.yml")){
$content = file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml");
if($version->isDev()){
$content = str_replace("preferred-channel: stable", "preferred-channel: beta", $content);
} }
@file_put_contents($this->dataPath . "pocketmine.yml", $content);
}
$this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []);
$this->logger->info("Loading server properties..."); if(!file_exists($dataPath . "players/")){
$this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, [ mkdir($dataPath . "players/", 0777);
"motd" => "Minecraft: PE Server",
"server-port" => 19132,
"white-list" => false,
"announce-player-achievements" => true,
"spawn-protection" => 16,
"max-players" => 20,
"allow-flight" => false,
"spawn-animals" => true,
"spawn-mobs" => true,
"gamemode" => 0,
"force-gamemode" => false,
"hardcore" => false,
"pvp" => true,
"difficulty" => 1,
"generator-settings" => "",
"level-name" => "world",
"level-seed" => "",
"level-type" => "DEFAULT",
"enable-query" => true,
"enable-rcon" => false,
"rcon.password" => substr(base64_encode(@Utils::getRandomBytes(20, false)), 3, 10),
"auto-save" => true,
]);
$this->forceLanguage = $this->getProperty("settings.force-language", false);
$this->baseLang = new BaseLang($this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE));
$this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()]));
$this->memoryManager = new MemoryManager($this);
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion()]));
if(($poolSize = $this->getProperty("settings.async-workers", "auto")) === "auto"){
$poolSize = ServerScheduler::$WORKERS;
$processors = Utils::getCoreCount() - 2;
if($processors > 0){
$poolSize = max(1, $processors);
} }
}
ServerScheduler::$WORKERS = $poolSize; if(!file_exists($pluginPath)){
mkdir($pluginPath, 0777);
}
if($this->getProperty("network.batch-threshold", 256) >= 0){ $this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
Network::$BATCH_THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); $this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
}else{
Network::$BATCH_THRESHOLD = -1;
}
$this->networkCompressionLevel = $this->getProperty("network.compression-level", 7);
$this->networkCompressionAsync = $this->getProperty("network.async-compression", true);
$this->autoTickRate = (bool) $this->getProperty("level-settings.auto-tick-rate", true); $this->console = new CommandReader();
$this->autoTickRateLimit = (int) $this->getProperty("level-settings.auto-tick-rate-limit", 20);
$this->alwaysTickPlayers = (int) $this->getProperty("level-settings.always-tick-players", false);
$this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1);
$this->scheduler = new ServerScheduler(); $version = new VersionString($this->getPocketMineVersion());
if($this->getConfigBoolean("enable-rcon", false) === true){ $this->logger->info("Loading pocketmine.yml...");
$this->rcon = new RCON($this, $this->getConfigString("rcon.password", ""), $this->getConfigInt("rcon.port", $this->getPort()), ($ip = $this->getIp()) != "" ? $ip : "0.0.0.0", $this->getConfigInt("rcon.threads", 1), $this->getConfigInt("rcon.clients-per-thread", 50)); if(!file_exists($this->dataPath . "pocketmine.yml")){
} $content = file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml");
if($version->isDev()){
$content = str_replace("preferred-channel: stable", "preferred-channel: beta", $content);
}
@file_put_contents($this->dataPath . "pocketmine.yml", $content);
}
$this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []);
$this->entityMetadata = new EntityMetadataStore(); $this->logger->info("Loading server properties...");
$this->playerMetadata = new PlayerMetadataStore(); $this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, [
$this->levelMetadata = new LevelMetadataStore(); "motd" => "Minecraft: PE Server",
"server-port" => 19132,
"white-list" => false,
"announce-player-achievements" => true,
"spawn-protection" => 16,
"max-players" => 20,
"allow-flight" => false,
"spawn-animals" => true,
"spawn-mobs" => true,
"gamemode" => 0,
"force-gamemode" => false,
"hardcore" => false,
"pvp" => true,
"difficulty" => 1,
"generator-settings" => "",
"level-name" => "world",
"level-seed" => "",
"level-type" => "DEFAULT",
"enable-query" => true,
"enable-rcon" => false,
"rcon.password" => substr(base64_encode(@Utils::getRandomBytes(20, false)), 3, 10),
"auto-save" => true,
]);
$this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM); $this->forceLanguage = $this->getProperty("settings.force-language", false);
$this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM); $this->baseLang = new BaseLang($this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE));
if(file_exists($this->dataPath . "banned.txt") and !file_exists($this->dataPath . "banned-players.txt")){ $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()]));
@rename($this->dataPath . "banned.txt", $this->dataPath . "banned-players.txt");
}
@touch($this->dataPath . "banned-players.txt");
$this->banByName = new BanList($this->dataPath . "banned-players.txt");
$this->banByName->load();
@touch($this->dataPath . "banned-ips.txt");
$this->banByIP = new BanList($this->dataPath . "banned-ips.txt");
$this->banByIP->load();
$this->maxPlayers = $this->getConfigInt("max-players", 20); $this->memoryManager = new MemoryManager($this);
$this->setAutoSave($this->getConfigBoolean("auto-save", true));
if($this->getConfigBoolean("hardcore", false) === true and $this->getDifficulty() < 3){ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion()]));
$this->setConfigInt("difficulty", 3);
}
define("pocketmine\\DEBUG", (int) $this->getProperty("debug.level", 1)); if(($poolSize = $this->getProperty("settings.async-workers", "auto")) === "auto"){
if($this->logger instanceof MainLogger){ $poolSize = ServerScheduler::$WORKERS;
$this->logger->setLogDebug(\pocketmine\DEBUG > 1); $processors = Utils::getCoreCount() - 2;
}
if(\pocketmine\DEBUG >= 0){ if($processors > 0){
@cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); $poolSize = max(1, $processors);
} }
}
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp() === "" ? "*" : $this->getIp(), $this->getPort()])); ServerScheduler::$WORKERS = $poolSize;
define("BOOTUP_RANDOM", @Utils::getRandomBytes(16));
$this->serverID = Utils::getMachineUniqueId($this->getIp() . $this->getPort());
$this->getLogger()->debug("Server unique id: " . $this->getServerUniqueId()); if($this->getProperty("network.batch-threshold", 256) >= 0){
$this->getLogger()->debug("Machine unique id: " . Utils::getMachineUniqueId()); Network::$BATCH_THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256);
}else{
Network::$BATCH_THRESHOLD = -1;
}
$this->networkCompressionLevel = $this->getProperty("network.compression-level", 7);
$this->networkCompressionAsync = $this->getProperty("network.async-compression", true);
$this->network = new Network($this); $this->autoTickRate = (bool) $this->getProperty("level-settings.auto-tick-rate", true);
$this->network->setName($this->getMotd()); $this->autoTickRateLimit = (int) $this->getProperty("level-settings.auto-tick-rate-limit", 20);
$this->alwaysTickPlayers = (int) $this->getProperty("level-settings.always-tick-players", false);
$this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1);
$this->scheduler = new ServerScheduler();
if($this->getConfigBoolean("enable-rcon", false) === true){
$this->rcon = new RCON($this, $this->getConfigString("rcon.password", ""), $this->getConfigInt("rcon.port", $this->getPort()), ($ip = $this->getIp()) != "" ? $ip : "0.0.0.0", $this->getConfigInt("rcon.threads", 1), $this->getConfigInt("rcon.clients-per-thread", 50));
}
$this->entityMetadata = new EntityMetadataStore();
$this->playerMetadata = new PlayerMetadataStore();
$this->levelMetadata = new LevelMetadataStore();
$this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM);
$this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM);
if(file_exists($this->dataPath . "banned.txt") and !file_exists($this->dataPath . "banned-players.txt")){
@rename($this->dataPath . "banned.txt", $this->dataPath . "banned-players.txt");
}
@touch($this->dataPath . "banned-players.txt");
$this->banByName = new BanList($this->dataPath . "banned-players.txt");
$this->banByName->load();
@touch($this->dataPath . "banned-ips.txt");
$this->banByIP = new BanList($this->dataPath . "banned-ips.txt");
$this->banByIP->load();
$this->maxPlayers = $this->getConfigInt("max-players", 20);
$this->setAutoSave($this->getConfigBoolean("auto-save", true));
if($this->getConfigBoolean("hardcore", false) === true and $this->getDifficulty() < 3){
$this->setConfigInt("difficulty", 3);
}
define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1));
ini_set('assert.exception', 1);
if($this->logger instanceof MainLogger){
$this->logger->setLogDebug(\pocketmine\DEBUG > 1);
}
if(\pocketmine\DEBUG >= 0){
@cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion());
}
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp() === "" ? "*" : $this->getIp(), $this->getPort()]));
define("BOOTUP_RANDOM", @Utils::getRandomBytes(16));
$this->serverID = Utils::getMachineUniqueId($this->getIp() . $this->getPort());
$this->getLogger()->debug("Server unique id: " . $this->getServerUniqueId());
$this->getLogger()->debug("Machine unique id: " . Utils::getMachineUniqueId());
$this->network = new Network($this);
$this->network->setName($this->getMotd());
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [
$this->getName(), $this->getName(),
($version->isDev() ? TextFormat::YELLOW : "") . $version->get(true) . TextFormat::WHITE, ($version->isDev() ? TextFormat::YELLOW : "") . $version->get(true) . TextFormat::WHITE,
$this->getCodename(), $this->getCodename(),
$this->getApiVersion() $this->getApiVersion()
])); ]));
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()]));
Timings::init(); Timings::init();
$this->consoleSender = new ConsoleCommandSender(); $this->consoleSender = new ConsoleCommandSender();
$this->commandMap = new SimpleCommandMap($this); $this->commandMap = new SimpleCommandMap($this);
$this->registerEntities(); $this->registerEntities();
$this->registerTiles(); $this->registerTiles();
InventoryType::init(); InventoryType::init();
Block::init(); Block::init();
Item::init(); Item::init();
Biome::init(); Biome::init();
Effect::init(); Effect::init();
Enchantment::init(); Enchantment::init();
Attribute::init(); Attribute::init();
/** TODO: @deprecated */ $this->craftingManager = new CraftingManager();
TextWrapper::init();
$this->craftingManager = new CraftingManager();
$this->pluginManager = new PluginManager($this, $this->commandMap); $this->pluginManager = new PluginManager($this, $this->commandMap);
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender); $this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
$this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false)); $this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false));
$this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20); $this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20);
$this->pluginManager->registerInterface(PharPluginLoader::class); $this->pluginManager->registerInterface(PharPluginLoader::class);
$this->pluginManager->registerInterface(ScriptPluginLoader::class); $this->pluginManager->registerInterface(ScriptPluginLoader::class);
set_exception_handler([$this, "exceptionHandler"]); register_shutdown_function([$this, "crashDump"]);
register_shutdown_function([$this, "crashDump"]);
$this->queryRegenerateTask = new QueryRegenerateEvent($this, 5); $this->queryRegenerateTask = new QueryRegenerateEvent($this, 5);
$this->network->registerInterface(new RakLibInterface($this));
$this->network->registerInterface(new RakLibInterface($this)); $this->pluginManager->loadPlugins($this->pluginPath);
$this->pluginManager->loadPlugins($this->pluginPath); $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "www.pocketmine.net"));
$this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "www.pocketmine.net")); $this->enablePlugins(PluginLoadOrder::STARTUP);
$this->enablePlugins(PluginLoadOrder::STARTUP); LevelProviderManager::addProvider($this, Anvil::class);
LevelProviderManager::addProvider($this, McRegion::class);
LevelProviderManager::addProvider($this, Anvil::class); if(extension_loaded("leveldb")){
LevelProviderManager::addProvider($this, McRegion::class); $this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable"));
if(extension_loaded("leveldb")){ LevelProviderManager::addProvider($this, LevelDB::class);
$this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable")); }
LevelProviderManager::addProvider($this, LevelDB::class);
}
Generator::addGenerator(Flat::class, "flat"); Generator::addGenerator(Flat::class, "flat");
Generator::addGenerator(Normal::class, "normal"); Generator::addGenerator(Normal::class, "normal");
Generator::addGenerator(Normal::class, "default"); Generator::addGenerator(Normal::class, "default");
Generator::addGenerator(Nether::class, "hell"); Generator::addGenerator(Nether::class, "hell");
Generator::addGenerator(Nether::class, "nether"); Generator::addGenerator(Nether::class, "nether");
foreach((array) $this->getProperty("worlds", []) as $name => $worldSetting){ foreach((array) $this->getProperty("worlds", []) as $name => $worldSetting){
if($this->loadLevel($name) === false){ if($this->loadLevel($name) === false){
$seed = $this->getProperty("worlds.$name.seed", time()); $seed = $this->getProperty("worlds.$name.seed", time());
$options = explode(":", $this->getProperty("worlds.$name.generator", Generator::getGenerator("default"))); $options = explode(":", $this->getProperty("worlds.$name.generator", Generator::getGenerator("default")));
$generator = Generator::getGenerator(array_shift($options)); $generator = Generator::getGenerator(array_shift($options));
if(count($options) > 0){ if(count($options) > 0){
$options = [ $options = [
"preset" => implode(":", $options), "preset" => implode(":", $options),
]; ];
}else{ }else{
$options = []; $options = [];
}
$this->generateLevel($name, $seed, $generator, $options);
}
}
if($this->getDefaultLevel() === null){
$default = $this->getConfigString("level-name", "world");
if(trim($default) == ""){
$this->getLogger()->warning("level-name cannot be null, using default");
$default = "world";
$this->setConfigString("level-name", "world");
}
if($this->loadLevel($default) === false){
$seed = $this->getConfigInt("level-seed", time());
$this->generateLevel($default, $seed === 0 ? time() : $seed);
} }
$this->generateLevel($name, $seed, $generator, $options); $this->setDefaultLevel($this->getLevelByName($default));
}
}
if($this->getDefaultLevel() === null){
$default = $this->getConfigString("level-name", "world");
if(trim($default) == ""){
$this->getLogger()->warning("level-name cannot be null, using default");
$default = "world";
$this->setConfigString("level-name", "world");
}
if($this->loadLevel($default) === false){
$seed = $this->getConfigInt("level-seed", time());
$this->generateLevel($default, $seed === 0 ? time() : $seed);
} }
$this->setDefaultLevel($this->getLevelByName($default));
$this->properties->save(true);
if(!($this->getDefaultLevel() instanceof Level)){
$this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError"));
$this->forceShutdown();
return;
}
if($this->getProperty("ticks-per.autosave", 6000) > 0){
$this->autoSaveTicks = (int) $this->getProperty("ticks-per.autosave", 6000);
}
$this->enablePlugins(PluginLoadOrder::POSTWORLD);
$this->start();
}catch(\Throwable $e){
$this->exceptionHandler($e);
} }
$this->properties->save(true);
if(!($this->getDefaultLevel() instanceof Level)){
$this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError"));
$this->forceShutdown();
return;
}
if($this->getProperty("ticks-per.autosave", 6000) > 0){
$this->autoSaveTicks = (int) $this->getProperty("ticks-per.autosave", 6000);
}
$this->enablePlugins(PluginLoadOrder::POSTWORLD);
$this->start();
} }
/** /**
@ -1808,7 +1758,7 @@ class Server{
$packet->encode(); $packet->encode();
$packet->isEncoded = true; $packet->isEncoded = true;
if(Network::$BATCH_THRESHOLD >= 0 and strlen($packet->buffer) >= Network::$BATCH_THRESHOLD){ if(Network::$BATCH_THRESHOLD >= 0 and strlen($packet->buffer) >= Network::$BATCH_THRESHOLD){
Server::getInstance()->batchPackets($players, [$packet->buffer], false, $packet->getChannel()); Server::getInstance()->batchPackets($players, [$packet->buffer], false);
return; return;
} }
@ -1826,9 +1776,8 @@ class Server{
* @param Player[] $players * @param Player[] $players
* @param DataPacket[]|string $packets * @param DataPacket[]|string $packets
* @param bool $forceSync * @param bool $forceSync
* @param int $channel
*/ */
public function batchPackets(array $players, array $packets, $forceSync = false, $channel = 0){ public function batchPackets(array $players, array $packets, $forceSync = false){
Timings::$playerNetworkTimer->startTiming(); Timings::$playerNetworkTimer->startTiming();
$str = ""; $str = "";
@ -1851,7 +1800,7 @@ class Server{
} }
if(!$forceSync and $this->networkCompressionAsync){ if(!$forceSync and $this->networkCompressionAsync){
$task = new CompressBatchedTask($str, $targets, $this->networkCompressionLevel, $channel); $task = new CompressBatchedTask($str, $targets, $this->networkCompressionLevel);
$this->getScheduler()->scheduleAsyncTask($task); $this->getScheduler()->scheduleAsyncTask($task);
}else{ }else{
$this->broadcastPacketsCallback(zlib_encode($str, ZLIB_ENCODING_DEFLATE, $this->networkCompressionLevel), $targets); $this->broadcastPacketsCallback(zlib_encode($str, ZLIB_ENCODING_DEFLATE, $this->networkCompressionLevel), $targets);
@ -1897,15 +1846,6 @@ class Server{
$this->pluginManager->enablePlugin($plugin); $this->pluginManager->enablePlugin($plugin);
} }
/**
* @param Plugin $plugin
*
* @deprecated
*/
public function loadPlugin(Plugin $plugin){
$this->enablePlugin($plugin);
}
public function disablePlugins(){ public function disablePlugins(){
$this->pluginManager->disablePlugins(); $this->pluginManager->disablePlugins();
} }
@ -1932,10 +1872,6 @@ class Server{
* @throws \Exception * @throws \Exception
*/ */
public function dispatchCommand(CommandSender $sender, $commandLine){ public function dispatchCommand(CommandSender $sender, $commandLine){
if(!($sender instanceof CommandSender)){
throw new ServerException("CommandSender is not valid");
}
if($this->commandMap->dispatch($sender, $commandLine)){ if($this->commandMap->dispatch($sender, $commandLine)){
return true; return true;
} }
@ -1970,8 +1906,6 @@ class Server{
$this->reloadWhitelist(); $this->reloadWhitelist();
$this->operators->reload(); $this->operators->reload();
$this->memoryManager->doObjectCleanup();
foreach($this->getIPBans()->getEntries() as $entry){ foreach($this->getIPBans()->getEntries() as $entry){
$this->getNetwork()->blockAddress($entry->getName(), -1); $this->getNetwork()->blockAddress($entry->getName(), -1);
} }
@ -1988,11 +1922,6 @@ class Server{
* Shutdowns the server correctly * Shutdowns the server correctly
*/ */
public function shutdown(){ public function shutdown(){
if($this->isRunning){
$killer = new ServerKiller(90);
$killer->start();
$killer->detach();
}
$this->isRunning = false; $this->isRunning = false;
} }
@ -2041,7 +1970,8 @@ class Server{
$this->properties->save(); $this->properties->save();
$this->getLogger()->debug("Closing console"); $this->getLogger()->debug("Closing console");
$this->console->kill(); $this->console->shutdown();
$this->console->notify();
$this->getLogger()->debug("Stopping network interfaces"); $this->getLogger()->debug("Stopping network interfaces");
foreach($this->network->getInterfaces() as $interface){ foreach($this->network->getInterfaces() as $interface){
@ -2049,11 +1979,10 @@ class Server{
$this->network->unregisterInterface($interface); $this->network->unregisterInterface($interface);
} }
$this->memoryManager->doObjectCleanup();
gc_collect_cycles(); gc_collect_cycles();
}catch(\Exception $e){ }catch(\Throwable $e){
$this->logger->emergency("Crashed while crashing, killing process"); $this->logger->emergency("Crashed while crashing, killing process");
$this->logger->emergency(get_class($e) . ": ". $e->getMessage());
@kill(getmypid()); @kill(getmypid());
} }
@ -2111,7 +2040,7 @@ class Server{
} }
} }
public function exceptionHandler(\Exception $e, $trace = null){ public function exceptionHandler(\Throwable $e, $trace = null){
if($e === null){ if($e === null){
return; return;
} }
@ -2134,9 +2063,7 @@ class Server{
$errfile = cleanPath($errfile); $errfile = cleanPath($errfile);
if($this->logger instanceof MainLogger){ $this->logger->logException($e, $trace);
$this->logger->logException($e, $trace);
}
$lastError = [ $lastError = [
"type" => $type, "type" => $type,
@ -2166,7 +2093,7 @@ class Server{
$this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create")); $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create"));
try{ try{
$dump = new CrashDump($this); $dump = new CrashDump($this);
}catch(\Exception $e){ }catch(\Throwable $e){
$this->logger->critical($this->getLanguage()->translateString("pocketmine.crash.error", $e->getMessage())); $this->logger->critical($this->getLanguage()->translateString("pocketmine.crash.error", $e->getMessage()));
return; return;
} }
@ -2226,7 +2153,7 @@ class Server{
if($next > microtime(true)){ if($next > microtime(true)){
try{ try{
time_sleep_until($next); time_sleep_until($next);
}catch(\Exception $e){ }catch(\Throwable $e){
//Sometimes $next is less than the current time. High load? //Sometimes $next is less than the current time. High load?
} }
} }
@ -2345,11 +2272,9 @@ class Server{
$level->tickRateCounter = $level->getTickRate(); $level->tickRateCounter = $level->getTickRate();
} }
} }
}catch(\Exception $e){ }catch(\Throwable $e){
$this->logger->critical($this->getLanguage()->translateString("pocketmine.level.tickError", [$level->getName(), $e->getMessage()])); $this->logger->critical($this->getLanguage()->translateString("pocketmine.level.tickError", [$level->getName(), $e->getMessage()]));
if(\pocketmine\DEBUG > 1 and $this->logger instanceof MainLogger){ $this->logger->logException($e);
$this->logger->logException($e);
}
} }
} }
} }
@ -2440,11 +2365,9 @@ class Server{
if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){ if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){
$this->queryHandler->handle($address, $port, $payload); $this->queryHandler->handle($address, $port, $payload);
} }
}catch(\Exception $e){ }catch(\Throwable $e){
if(\pocketmine\DEBUG > 1){ if(\pocketmine\DEBUG > 1){
if($this->logger instanceof MainLogger){ $this->logger->logException($e);
$this->logger->logException($e);
}
} }
$this->getNetwork()->blockAddress($address, 600); $this->getNetwork()->blockAddress($address, 600);
@ -2498,10 +2421,8 @@ class Server{
if($this->queryHandler !== null){ if($this->queryHandler !== null){
$this->queryHandler->regenerateInfo(); $this->queryHandler->regenerateInfo();
} }
}catch(\Exception $e){ }catch(\Throwable $e){
if($this->logger instanceof MainLogger){ $this->logger->logException($e);
$this->logger->logException($e);
}
} }
} }

View File

@ -28,6 +28,7 @@ abstract class Thread extends \Thread{
/** @var \ClassLoader */ /** @var \ClassLoader */
protected $classLoader; protected $classLoader;
protected $isKilled = false;
public function getClassLoader(){ public function getClassLoader(){
return $this->classLoader; return $this->classLoader;
@ -51,7 +52,7 @@ abstract class Thread extends \Thread{
} }
} }
public function start($options = PTHREADS_INHERIT_ALL){ public function start(int $options = PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this); ThreadManager::getInstance()->add($this);
if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){ if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){
@ -68,18 +69,14 @@ abstract class Thread extends \Thread{
* Stops the thread using the best way possible. Try to stop it yourself before calling this. * Stops the thread using the best way possible. Try to stop it yourself before calling this.
*/ */
public function quit(){ public function quit(){
if($this->isRunning()){ $this->isKilled = true;
$this->kill();
$this->detach(); $this->notify();
}elseif(!$this->isJoined()){
if(!$this->isJoined()){
if(!$this->isTerminated()){ if(!$this->isTerminated()){
$this->join(); $this->join();
}else{
$this->kill();
$this->detach();
} }
}else{
$this->detach();
} }
ThreadManager::getInstance()->remove($this); ThreadManager::getInstance()->remove($this);

View File

@ -21,7 +21,7 @@
namespace pocketmine; namespace pocketmine;
class ThreadManager extends \Threaded{ class ThreadManager extends \Volatile{
/** @var ThreadManager */ /** @var ThreadManager */
private static $instance = null; private static $instance = null;

View File

@ -29,6 +29,8 @@ abstract class Worker extends \Worker{
/** @var \ClassLoader */ /** @var \ClassLoader */
protected $classLoader; protected $classLoader;
protected $isKilled = false;
public function getClassLoader(){ public function getClassLoader(){
return $this->classLoader; return $this->classLoader;
} }
@ -51,7 +53,7 @@ abstract class Worker extends \Worker{
} }
} }
public function start($options = PTHREADS_INHERIT_ALL){ public function start(int $options = PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this); ThreadManager::getInstance()->add($this);
if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){ if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){
@ -68,19 +70,18 @@ abstract class Worker extends \Worker{
* Stops the thread using the best way possible. Try to stop it yourself before calling this. * Stops the thread using the best way possible. Try to stop it yourself before calling this.
*/ */
public function quit(){ public function quit(){
$this->isKilled = true;
$this->notify();
if($this->isRunning()){ if($this->isRunning()){
$this->shutdown();
$this->notify();
$this->unstack(); $this->unstack();
$this->kill();
$this->detach();
}elseif(!$this->isJoined()){ }elseif(!$this->isJoined()){
if(!$this->isTerminated()){ if(!$this->isTerminated()){
$this->join(); $this->join();
}else{
$this->kill();
$this->detach();
} }
}else{
$this->detach();
} }
ThreadManager::getInstance()->remove($this); ThreadManager::getInstance()->remove($this);

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class ActivatorRail extends Solid {
protected $id = self::ACTIVATOR_RAIL;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Activator Rail";
}
}

View File

@ -63,9 +63,9 @@ class Block extends Position implements Metadatable{
const GOLD_ORE = 14; const GOLD_ORE = 14;
const IRON_ORE = 15; const IRON_ORE = 15;
const COAL_ORE = 16; const COAL_ORE = 16;
const LOG = 17;
const WOOD = 17; const WOOD = 17;
const TRUNK = 17; const TRUNK = 17;
const LOG = 17;
const LEAVES = 18; const LEAVES = 18;
const LEAVE = 18; const LEAVE = 18;
const SPONGE = 19; const SPONGE = 19;
@ -74,18 +74,18 @@ class Block extends Position implements Metadatable{
const LAPIS_BLOCK = 22; const LAPIS_BLOCK = 22;
const SANDSTONE = 24; const SANDSTONE = 24;
const NOTE_BLOCK = 25;
const BED_BLOCK = 26; const BED_BLOCK = 26;
const POWERED_RAIL = 27;
const DETECTOR_RAIL = 28;
const COBWEB = 30; const COBWEB = 30;
const TALL_GRASS = 31; const TALL_GRASS = 31;
const BUSH = 32; const BUSH = 32;
const DEAD_BUSH = 32; const DEAD_BUSH = 32;
const WOOL = 35; const WOOL = 35;
const DANDELION = 37; const DANDELION = 37;
const ROSE = 38;
const POPPY = 38; const POPPY = 38;
const ROSE = 38;
const RED_FLOWER = 38; const RED_FLOWER = 38;
const BROWN_MUSHROOM = 39; const BROWN_MUSHROOM = 39;
const RED_MUSHROOM = 40; const RED_MUSHROOM = 40;
@ -110,7 +110,7 @@ class Block extends Position implements Metadatable{
const OAK_WOOD_STAIRS = 53; const OAK_WOOD_STAIRS = 53;
const OAK_WOODEN_STAIRS = 53; const OAK_WOODEN_STAIRS = 53;
const CHEST = 54; const CHEST = 54;
const REDSTONE_WIRE = 55;
const DIAMOND_ORE = 56; const DIAMOND_ORE = 56;
const DIAMOND_BLOCK = 57; const DIAMOND_BLOCK = 57;
const CRAFTING_TABLE = 58; const CRAFTING_TABLE = 58;
@ -125,17 +125,20 @@ class Block extends Position implements Metadatable{
const WOODEN_DOOR_BLOCK = 64; const WOODEN_DOOR_BLOCK = 64;
const WOOD_DOOR_BLOCK = 64; const WOOD_DOOR_BLOCK = 64;
const LADDER = 65; const LADDER = 65;
const RAIL = 66;
const COBBLE_STAIRS = 67; const COBBLE_STAIRS = 67;
const COBBLESTONE_STAIRS = 67; const COBBLESTONE_STAIRS = 67;
const WALL_SIGN = 68; const WALL_SIGN = 68;
const LEVER = 69;
const STONE_PRESSURE_PLATE = 70;
const IRON_DOOR_BLOCK = 71; const IRON_DOOR_BLOCK = 71;
const WOODEN_PRESSURE_PLATE = 72;
const REDSTONE_ORE = 73; const REDSTONE_ORE = 73;
const GLOWING_REDSTONE_ORE = 74; const GLOWING_REDSTONE_ORE = 74;
const LIT_REDSTONE_ORE = 74; const LIT_REDSTONE_ORE = 74;
const REDSTONE_TORCH = 75;
const LIT_REDSTONE_TORCH = 76;
const STONE_BUTTON = 77;
const SNOW = 78; const SNOW = 78;
const SNOW_LAYER = 78; const SNOW_LAYER = 78;
const ICE = 79; const ICE = 79;
@ -152,18 +155,17 @@ class Block extends Position implements Metadatable{
const GLOWSTONE = 89; const GLOWSTONE = 89;
const GLOWSTONE_BLOCK = 89; const GLOWSTONE_BLOCK = 89;
const PORTAL_BLOCK = 90;
const LIT_PUMPKIN = 91; const LIT_PUMPKIN = 91;
const JACK_O_LANTERN = 91; const JACK_O_LANTERN = 91;
const CAKE_BLOCK = 92; const CAKE_BLOCK = 92;
const TRAPDOOR = 96; const TRAPDOOR = 96;
const WOODEN_TRAPDOOR = 96; const MONSTER_EGG_BLOCK = 97;
const WOOD_TRAPDOOR = 96;
const STONE_BRICKS = 98; const STONE_BRICKS = 98;
const STONE_BRICK = 98; const STONE_BRICK = 98;
const BROWN_MUSHROOM_BLOCK = 99;
const RED_MUSHROOM_BLOCK = 100;
const IRON_BAR = 101; const IRON_BAR = 101;
const IRON_BARS = 101; const IRON_BARS = 101;
const GLASS_PANE = 102; const GLASS_PANE = 102;
@ -183,17 +185,24 @@ class Block extends Position implements Metadatable{
const NETHER_BRICK_BLOCK = 112; const NETHER_BRICK_BLOCK = 112;
const NETHER_BRICK_FENCE = 113; const NETHER_BRICK_FENCE = 113;
const NETHER_BRICKS_STAIRS = 114; const NETHER_BRICKS_STAIRS = 114;
const NETHER_WART_BLOCK = 115;
const ENCHANTING_TABLE = 116; const ENCHANTING_TABLE = 116;
const ENCHANT_TABLE = 116; const ENCHANT_TABLE = 116;
const ENCHANTMENT_TABLE = 116; const ENCHANTMENT_TABLE = 116;
const BREWING_STAND = 117; const BREWING_STAND = 117;
const END_PORTAL_FRAME = 120; const END_PORTAL_FRAME = 120;
const END_STONE = 121; const END_STONE = 121;
const REDSTONE_LAMP = 122;
const LIT_REDSTONE_LAMP = 123;
const ACTIVATOR_RAIL = 126;
const COCOA_BLOCK = 127;
const SANDSTONE_STAIRS = 128; const SANDSTONE_STAIRS = 128;
const EMERALD_ORE = 129; const EMERALD_ORE = 129;
const TRIPWIRE_HOOK = 131;
const TRIPWIRE = 132;
const EMERALD_BLOCK = 133; const EMERALD_BLOCK = 133;
const SPRUCE_WOOD_STAIRS = 134; const SPRUCE_WOOD_STAIRS = 134;
const SPRUCE_WOODEN_STAIRS = 134; const SPRUCE_WOODEN_STAIRS = 134;
@ -208,11 +217,16 @@ class Block extends Position implements Metadatable{
const FLOWER_POT_BLOCK = 140; const FLOWER_POT_BLOCK = 140;
const CARROT_BLOCK = 141; const CARROT_BLOCK = 141;
const POTATO_BLOCK = 142; const POTATO_BLOCK = 142;
const WOODEN_BUTTON = 143;
const MOB_HEAD_BLOCK = 144;
const ANVIL = 145; const ANVIL = 145;
const TRAPPED_CHEST = 146; const TRAPPED_CHEST = 146;
const WEIGHTED_PRESSURE_PLATE_LIGHT = 147;
const WEIGHTED_PRESSURE_PLATE_HEAVY = 148;
const DAYLIGHT_SENSOR = 151;
const REDSTONE_BLOCK = 152; const REDSTONE_BLOCK = 152;
const NETHER_QUARTZ_ORE = 153;
const QUARTZ_BLOCK = 155; const QUARTZ_BLOCK = 155;
const QUARTZ_STAIRS = 156; const QUARTZ_STAIRS = 156;
@ -238,6 +252,7 @@ class Block extends Position implements Metadatable{
const DARK_OAK_WOODEN_STAIRS = 164; const DARK_OAK_WOODEN_STAIRS = 164;
const IRON_TRAPDOOR = 167; const IRON_TRAPDOOR = 167;
const HAY_BALE = 170; const HAY_BALE = 170;
const CARPET = 171; const CARPET = 171;
const HARDENED_CLAY = 172; const HARDENED_CLAY = 172;
@ -245,6 +260,8 @@ class Block extends Position implements Metadatable{
const PACKED_ICE = 174; const PACKED_ICE = 174;
const DOUBLE_PLANT = 175; const DOUBLE_PLANT = 175;
const INVERTED_DAYLIGHT_SENSOR = 178;
const FENCE_GATE_SPRUCE = 183; const FENCE_GATE_SPRUCE = 183;
const FENCE_GATE_BIRCH = 184; const FENCE_GATE_BIRCH = 184;
const FENCE_GATE_JUNGLE = 185; const FENCE_GATE_JUNGLE = 185;
@ -280,32 +297,6 @@ class Block extends Position implements Metadatable{
/** @var AxisAlignedBB */ /** @var AxisAlignedBB */
public $boundingBox = null; public $boundingBox = null;
/**
* Backwards-compatibility with old way to define block properties
*
* @deprecated
*
* @param string $key
*
* @return mixed
*/
public function __get($key){
static $map = [
"hardness" => "getHardness",
"lightLevel" => "getLightLevel",
"frictionFactor" => "getFrictionFactor",
"name" => "getName",
"isPlaceable" => "canBePlaced",
"isReplaceable" => "canBeReplaced",
"isTransparent" => "isTransparent",
"isSolid" => "isSolid",
"isFlowable" => "canBeFlowedInto",
"isActivable" => "canBeActivated",
"hasEntityCollision" => "hasEntityCollision"
];
return isset($map[$key]) ? $this->{$map[$key]}() : null;
}
public static function init(){ public static function init(){
if(self::$list === null){ if(self::$list === null){
self::$list = new \SplFixedArray(256); self::$list = new \SplFixedArray(256);
@ -338,8 +329,13 @@ class Block extends Position implements Metadatable{
self::$list[self::GLASS] = Glass::class; self::$list[self::GLASS] = Glass::class;
self::$list[self::LAPIS_ORE] = LapisOre::class; self::$list[self::LAPIS_ORE] = LapisOre::class;
self::$list[self::LAPIS_BLOCK] = Lapis::class; self::$list[self::LAPIS_BLOCK] = Lapis::class;
self::$list[self::ACTIVATOR_RAIL] = ActivatorRail::class;
self::$list[self::COCOA_BLOCK] = CocoaBlock::class;
self::$list[self::SANDSTONE] = Sandstone::class; self::$list[self::SANDSTONE] = Sandstone::class;
self::$list[self::NOTE_BLOCK] = NoteBlock::class;
self::$list[self::BED_BLOCK] = Bed::class; self::$list[self::BED_BLOCK] = Bed::class;
self::$list[self::POWERED_RAIL] = PoweredRail::class;
self::$list[self::DETECTOR_RAIL] = DetectorRail::class;
self::$list[self::COBWEB] = Cobweb::class; self::$list[self::COBWEB] = Cobweb::class;
self::$list[self::TALL_GRASS] = TallGrass::class; self::$list[self::TALL_GRASS] = TallGrass::class;
self::$list[self::DEAD_BUSH] = DeadBush::class; self::$list[self::DEAD_BUSH] = DeadBush::class;
@ -373,14 +369,20 @@ class Block extends Position implements Metadatable{
self::$list[self::SIGN_POST] = SignPost::class; self::$list[self::SIGN_POST] = SignPost::class;
self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class; self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class;
self::$list[self::LADDER] = Ladder::class; self::$list[self::LADDER] = Ladder::class;
self::$list[self::RAIL] = Rail::class;
self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class; self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class;
self::$list[self::WALL_SIGN] = WallSign::class; self::$list[self::WALL_SIGN] = WallSign::class;
self::$list[self::LEVER] = Lever::class;
self::$list[self::STONE_PRESSURE_PLATE] = StonePressurePlate::class;
self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class; self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class;
self::$list[self::WOODEN_PRESSURE_PLATE] = WoodenPressurePlate::class;
self::$list[self::REDSTONE_ORE] = RedstoneOre::class; self::$list[self::REDSTONE_ORE] = RedstoneOre::class;
self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class; self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class;
self::$list[self::REDSTONE_TORCH] = RedstoneTorch::class;
self::$list[self::LIT_REDSTONE_TORCH] = LitRedstoneTorch::class;
self::$list[self::STONE_BUTTON] = StoneButton::class;
self::$list[self::SNOW_LAYER] = SnowLayer::class; self::$list[self::SNOW_LAYER] = SnowLayer::class;
self::$list[self::ICE] = Ice::class; self::$list[self::ICE] = Ice::class;
self::$list[self::SNOW_BLOCK] = Snow::class; self::$list[self::SNOW_BLOCK] = Snow::class;
@ -421,9 +423,12 @@ class Block extends Position implements Metadatable{
self::$list[self::BREWING_STAND] = BrewingStand::class; self::$list[self::BREWING_STAND] = BrewingStand::class;
self::$list[self::END_PORTAL_FRAME] = EndPortalFrame::class; self::$list[self::END_PORTAL_FRAME] = EndPortalFrame::class;
self::$list[self::END_STONE] = EndStone::class; self::$list[self::END_STONE] = EndStone::class;
self::$list[self::REDSTONE_LAMP] = RedstoneLamp::class;
self::$list[self::LIT_REDSTONE_LAMP] = LitRedstoneLamp::class;
self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class; self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;
self::$list[self::EMERALD_ORE] = EmeraldOre::class; self::$list[self::EMERALD_ORE] = EmeraldOre::class;
self::$list[self::TRIPWIRE_HOOK] = TripwireHook::class;
self::$list[self::TRIPWIRE] = Tripwire::class;
self::$list[self::EMERALD_BLOCK] = Emerald::class; self::$list[self::EMERALD_BLOCK] = Emerald::class;
self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class; self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class;
self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class; self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;
@ -432,8 +437,13 @@ class Block extends Position implements Metadatable{
self::$list[self::FLOWER_POT_BLOCK] = FlowerPot::class; self::$list[self::FLOWER_POT_BLOCK] = FlowerPot::class;
self::$list[self::CARROT_BLOCK] = Carrot::class; self::$list[self::CARROT_BLOCK] = Carrot::class;
self::$list[self::POTATO_BLOCK] = Potato::class; self::$list[self::POTATO_BLOCK] = Potato::class;
self::$list[self::WOODEN_BUTTON] = WoodenButton::class;
self::$list[self::ANVIL] = Anvil::class; self::$list[self::ANVIL] = Anvil::class;
self::$list[self::TRAPPED_CHEST] = TrappedChest::class; self::$list[self::TRAPPED_CHEST] = TrappedChest::class;
self::$list[self::WEIGHTED_PRESSURE_PLATE_LIGHT] = WeightedPressurePlateLight::class;
self::$list[self::WEIGHTED_PRESSURE_PLATE_HEAVY] = WeightedPressurePlateHeavy::class;
self::$list[self::DAYLIGHT_SENSOR] = DaylightSensor::class;
self::$list[self::REDSTONE_BLOCK] = Redstone::class; self::$list[self::REDSTONE_BLOCK] = Redstone::class;
self::$list[self::QUARTZ_BLOCK] = Quartz::class; self::$list[self::QUARTZ_BLOCK] = Quartz::class;

View File

@ -24,10 +24,10 @@ namespace pocketmine\block;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\tile\Furnace; use pocketmine\tile\Furnace;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
@ -69,17 +69,17 @@ class BurningFurnace extends Solid{
]; ];
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0]; $this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
$this->getLevel()->setBlock($block, $this, true, true); $this->getLevel()->setBlock($block, $this, true, true);
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Enum("Items", []), new ListTag("Items", []),
new String("id", Tile::FURNACE), new StringTag("id", Tile::FURNACE),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
if($item->hasCustomName()){ if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $item->getCustomName());
} }
if($item->hasCustomBlockData()){ if($item->hasCustomBlockData()){
@ -106,18 +106,18 @@ class BurningFurnace extends Solid{
if($t instanceof Furnace){ if($t instanceof Furnace){
$furnace = $t; $furnace = $t;
}else{ }else{
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Enum("Items", []), new ListTag("Items", []),
new String("id", Tile::FURNACE), new StringTag("id", Tile::FURNACE),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
} }
if(isset($furnace->namedtag->Lock) and $furnace->namedtag->Lock instanceof String){ if(isset($furnace->namedtag->Lock) and $furnace->namedtag->Lock instanceof StringTag){
if($furnace->namedtag->Lock->getValue() !== $item->getCustomName()){ if($furnace->namedtag->Lock->getValue() !== $item->getCustomName()){
return true; return true;
} }

View File

@ -25,10 +25,10 @@ use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\tile\Chest as TileChest; use pocketmine\tile\Chest as TileChest;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
@ -96,17 +96,17 @@ class Chest extends Transparent{
} }
$this->getLevel()->setBlock($block, $this, true, true); $this->getLevel()->setBlock($block, $this, true, true);
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Enum("Items", []), new ListTag("Items", []),
new String("id", Tile::CHEST), new StringTag("id", Tile::CHEST),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
if($item->hasCustomName()){ if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $item->getCustomName());
} }
if($item->hasCustomBlockData()){ if($item->hasCustomBlockData()){
@ -147,18 +147,18 @@ class Chest extends Transparent{
if($t instanceof TileChest){ if($t instanceof TileChest){
$chest = $t; $chest = $t;
}else{ }else{
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Enum("Items", []), new ListTag("Items", []),
new String("id", Tile::CHEST), new StringTag("id", Tile::CHEST),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
} }
if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof String){ if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag){
if($chest->namedtag->Lock->getValue() !== $item->getCustomName()){ if($chest->namedtag->Lock->getValue() !== $item->getCustomName()){
return true; return true;
} }

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class CocoaBlock extends Solid {
protected $id = self::COCOA_BLOCK;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Cocoa Block";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class DaylightSensor extends Solid {
protected $id = self::DAYLIGHT_SENSOR;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Daylight Sensor";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class DetectorRail extends Solid {
protected $id = self::DETECTOR_RAIL;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Detector Rail";
}
}

View File

@ -51,7 +51,7 @@ class DoubleSlab extends Solid{
6 => "Quartz", 6 => "Quartz",
7 => "Nether Brick", 7 => "Nether Brick",
]; ];
return "Double " . $names[$this->meta & 0x07] . " Slab"; return "DoubleTag " . $names[$this->meta & 0x07] . " Slab";
} }
public function getDrops(Item $item){ public function getDrops(Item $item){

View File

@ -51,7 +51,7 @@ class DoubleWoodSlab extends Solid{
6 => "", 6 => "",
7 => "" 7 => ""
]; ];
return "Double " . $names[$this->meta & 0x07] . " Wooden Slab"; return "DoubleTag " . $names[$this->meta & 0x07] . " Wooden Slab";
} }
public function getDrops(Item $item){ public function getDrops(Item $item){

View File

@ -25,9 +25,9 @@ use pocketmine\inventory\EnchantInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
@ -41,15 +41,15 @@ class EnchantingTable extends Transparent{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$this->getLevel()->setBlock($block, $this, true, true); $this->getLevel()->setBlock($block, $this, true, true);
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new String("id", Tile::ENCHANT_TABLE), new StringTag("id", Tile::ENCHANT_TABLE),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
if($item->hasCustomName()){ if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $item->getCustomName());
} }
if($item->hasCustomBlockData()){ if($item->hasCustomBlockData()){

View File

@ -37,7 +37,7 @@ class EndPortalFrame extends Solid{
} }
public function getName(){ public function getName(){
return "End Portal Frame"; return "EndTag Portal Frame";
} }
public function getHardness(){ public function getHardness(){

View File

@ -33,7 +33,7 @@ class EndStone extends Solid{
} }
public function getName(){ public function getName(){
return "End Stone"; return "EndTag Stone";
} }
public function getToolType(){ public function getToolType(){

View File

@ -25,12 +25,12 @@ use pocketmine\entity\Entity;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\Player; use pocketmine\Player;
abstract class Fallable extends Solid{ abstract class Fallable extends Solid{
@ -45,23 +45,23 @@ abstract class Fallable extends Solid{
if($type === Level::BLOCK_UPDATE_NORMAL){ if($type === Level::BLOCK_UPDATE_NORMAL){
$down = $this->getSide(Vector3::SIDE_DOWN); $down = $this->getSide(Vector3::SIDE_DOWN);
if($down->getId() === self::AIR or ($down instanceof Liquid)){ if($down->getId() === self::AIR or ($down instanceof Liquid)){
$fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [ $fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $this->x + 0.5), new DoubleTag("", $this->x + 0.5),
new Double("", $this->y), new DoubleTag("", $this->y),
new Double("", $this->z + 0.5) new DoubleTag("", $this->z + 0.5)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", 0), new DoubleTag("", 0),
new Double("", 0), new DoubleTag("", 0),
new Double("", 0) new DoubleTag("", 0)
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", 0), new FloatTag("", 0),
new Float("", 0) new FloatTag("", 0)
]), ]),
"TileID" => new Int("TileID", $this->getId()), "TileID" => new IntTag("TileID", $this->getId()),
"Data" => new Byte("Data", $this->getDamage()), "Data" => new ByteTag("Data", $this->getDamage()),
])); ]));
$fall->spawnToAll(); $fall->spawnToAll();

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class Lever extends Solid {
protected $id = self::LEVER;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Lever";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class LitRedstoneLamp extends Solid {
protected $id = self::LIT_REDSTONE_LAMP;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Lit Redstone Lamp";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class LitRedstoneTorch extends Solid {
protected $id = self::REDSTONE_TORCH;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Lit Redstone Torch";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class NoteBlock extends Solid {
protected $id = self::NOTE_BLOCK;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Note Block";
}
}

View File

@ -53,7 +53,7 @@ class Planks extends Solid{
self::BIRCH => "Birch Wood Planks", self::BIRCH => "Birch Wood Planks",
self::JUNGLE => "Jungle Wood Planks", self::JUNGLE => "Jungle Wood Planks",
self::ACACIA => "Acacia Wood Planks", self::ACACIA => "Acacia Wood Planks",
self::DARK_OAK => "Jungle Wood Planks", self::DARK_OAK => "Dark Oak Wood Planks",
"", "",
"" ""
]; ];

View File

@ -0,0 +1,34 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class PoweredRail extends Solid {
protected $id = self::POWERED_RAIL;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Powered Rail";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class Rail extends Solid {
protected $id = self::RAIL;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Rail";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class RedstoneLamp extends Solid {
protected $id = self::REDSTONE_LAMP;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Redstone Lamp";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class RedstoneTorch extends Solid {
protected $id = self::REDSTONE_TORCH;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Redstone Torch";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class StoneButton extends Solid {
protected $id = self::STONE_BUTTON;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Stone Button";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class StonePressurePlate extends Solid {
protected $id = self::STONE_PRESSURE_PLATE;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Stone Pressure Plate";
}
}

View File

@ -23,11 +23,11 @@ namespace pocketmine\block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\Random; use pocketmine\utils\Random;
@ -57,22 +57,22 @@ class TNT extends Solid{
$this->getLevel()->setBlock($this, new Air(), true); $this->getLevel()->setBlock($this, new Air(), true);
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$tnt = Entity::createEntity("PrimedTNT", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [ $tnt = Entity::createEntity("PrimedTNT", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $this->x + 0.5), new DoubleTag("", $this->x + 0.5),
new Double("", $this->y), new DoubleTag("", $this->y),
new Double("", $this->z + 0.5) new DoubleTag("", $this->z + 0.5)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", -sin($mot) * 0.02), new DoubleTag("", -sin($mot) * 0.02),
new Double("", 0.2), new DoubleTag("", 0.2),
new Double("", -cos($mot) * 0.02) new DoubleTag("", -cos($mot) * 0.02)
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", 0), new FloatTag("", 0),
new Float("", 0) new FloatTag("", 0)
]), ]),
"Fuse" => new Byte("Fuse", 80) "Fuse" => new ByteTag("Fuse", 80)
])); ]));
$tnt->spawnToAll(); $tnt->spawnToAll();

View File

@ -25,10 +25,10 @@ use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Int as IntTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String as StringTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\tile\Chest as TileChest; use pocketmine\tile\Chest as TileChest;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
@ -96,17 +96,17 @@ class TrappedChest extends Transparent{
} }
$this->getLevel()->setBlock($block, $this, true, true); $this->getLevel()->setBlock($block, $this, true, true);
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Enum("Items", []), new Enum("Items", []),
new String("id", Tile::CHEST), new StringTag("id", Tile::CHEST),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
if($item->hasCustomName()){ if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $item->getCustomName());
} }
if($item->hasCustomBlockData()){ if($item->hasCustomBlockData()){
@ -147,12 +147,12 @@ class TrappedChest extends Transparent{
if($t instanceof TileChest){ if($t instanceof TileChest){
$chest = $t; $chest = $t;
}else{ }else{
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
new Enum("Items", []), new Enum("Items", []),
new String("id", Tile::CHEST), new StringTag("id", Tile::CHEST),
new Int("x", $this->x), new IntTag("x", $this->x),
new Int("y", $this->y), new IntTag("y", $this->y),
new Int("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class Tripwire extends Solid {
protected $id = self::TRIPWIRE;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Tripwire";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class TripwireHook extends Solid {
protected $id = self::TRIPWIRE_HOOK;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Tripwire Hook";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class WeightedPressurePlateHeavy extends Solid {
protected $id = self::WEIGHTED_PRESSURE_PLATE_HEAVY;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Weighted Pressure Plate Heavy";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class WeightedPressurePlateLight extends Solid {
protected $id = self::WEIGHTED_PRESSURE_PLATE_LIGHT;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Weighted Pressure Plate Light";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class WoodenButton extends Solid {
protected $id = self::WOODEN_BUTTON;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Wooden Button";
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class WoodenPressurePlate extends Solid{
protected $id = self::WOODEN_PRESSURE_PLATE;
public function __construct($meta = 0) {
$this->meta = $meta;
}
public function getName(){
return "Wooden Pressure Plate";
}
}

View File

@ -25,26 +25,36 @@ use pocketmine\Thread;
class CommandReader extends Thread{ class CommandReader extends Thread{
private $readline; private $readline;
/** @var \Threaded */ /** @var \Threaded */
protected $buffer; protected $buffer;
private $shutdown = false;
public function __construct(){ public function __construct(){
$this->buffer = \ThreadedFactory::create(); $this->buffer = new \Threaded;
$this->start(); $this->start();
} }
public function shutdown(){
$this->shutdown = true;
}
private function readLine(){ private function readLine(){
if(!$this->readline){ if(!$this->readline){
$line = trim(fgets(fopen("php://stdin", "r"))); global $stdin;
if(!is_resource($stdin)){
return "";
}
return trim(fgets($stdin));
}else{ }else{
$line = trim(readline("> ")); $line = trim(readline("> "));
if($line != ""){ if($line != ""){
readline_add_history($line); readline_add_history($line);
} }
}
return $line; return $line;
}
} }
/** /**
@ -65,15 +75,20 @@ class CommandReader extends Thread{
if(extension_loaded("readline") and !isset($opts["disable-readline"])){ if(extension_loaded("readline") and !isset($opts["disable-readline"])){
$this->readline = true; $this->readline = true;
}else{ }else{
global $stdin;
$stdin = fopen("php://stdin", "r");
stream_set_blocking($stdin, 0);
$this->readline = false; $this->readline = false;
} }
$lastLine = microtime(true); $lastLine = microtime(true);
while(true){ while(!$this->shutdown){
if(($line = $this->readLine()) !== ""){ if(($line = $this->readLine()) !== ""){
$this->buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line); $this->buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line);
}elseif((microtime(true) - $lastLine) <= 0.1){ //Non blocking! Sleep to save CPU }elseif(!$this->shutdown and (microtime(true) - $lastLine) <= 0.1){ //Non blocking! Sleep to save CPU
usleep(40000); $this->synchronized(function(){
$this->wait(10000);
});
} }
$lastLine = microtime(true); $lastLine = microtime(true);

View File

@ -46,15 +46,12 @@ class FormattedCommandAlias extends Command{
foreach($this->formatStrings as $formatString){ foreach($this->formatStrings as $formatString){
try{ try{
$commands[] = $this->buildCommand($formatString, $args); $commands[] = $this->buildCommand($formatString, $args);
}catch(\Exception $e){ }catch(\Throwable $e){
if($e instanceof \InvalidArgumentException){ if($e instanceof \InvalidArgumentException){
$sender->sendMessage(TextFormat::RED . $e->getMessage()); $sender->sendMessage(TextFormat::RED . $e->getMessage());
}else{ }else{
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.exception")); $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.exception"));
$logger = $sender->getServer()->getLogger(); $sender->getServer()->getLogger()->logException($e);
if($logger instanceof MainLogger){
$logger->logException($e);
}
} }
return false; return false;

View File

@ -193,13 +193,10 @@ class SimpleCommandMap implements CommandMap{
$target->timings->startTiming(); $target->timings->startTiming();
try{ try{
$target->execute($sender, $sentCommandLabel, $args); $target->execute($sender, $sentCommandLabel, $args);
}catch(\Exception $e){ }catch(\Throwable $e){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.exception")); $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.exception"));
$this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.command.exception", [$commandLine, (string) $target, $e->getMessage()])); $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.command.exception", [$commandLine, (string) $target, $e->getMessage()]));
$logger = $sender->getServer()->getLogger(); $sender->getServer()->getLogger()->logException($e);
if($logger instanceof MainLogger){
$logger->logException($e);
}
} }
$target->timings->stopTiming(); $target->timings->stopTiming();

View File

@ -26,7 +26,7 @@ use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
@ -66,11 +66,11 @@ class GiveCommand extends VanillaCommand{
$data = implode(" ", array_slice($args, 3)); $data = implode(" ", array_slice($args, 3));
try{ try{
$tags = NBT::parseJSON($data); $tags = NBT::parseJSON($data);
}catch (\Exception $ex){ }catch (\Throwable $ex){
$exception = $ex; $exception = $ex;
} }
if(!($tags instanceof Compound) or $exception !== null){ if(!($tags instanceof CompoundTag) or $exception !== null){
$sender->sendMessage(new TranslationContainer("commands.give.tagError", [$exception !== null ? $exception->getMessage() : "Invalid tag conversion"])); $sender->sendMessage(new TranslationContainer("commands.give.tagError", [$exception !== null ? $exception->getMessage() : "Invalid tag conversion"]));
return true; return true;
} }

View File

@ -44,6 +44,7 @@ class TeleportCommand extends VanillaCommand{
return true; return true;
} }
$args = array_filter($args);
if(count($args) < 1 or count($args) > 6){ if(count($args) < 1 or count($args) > 6){
$sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage])); $sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage]));

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\particle\CriticalParticle; use pocketmine\level\particle\CriticalParticle;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -42,7 +42,7 @@ class Arrow extends Projectile{
protected $isCritical; protected $isCritical;
public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null, $critical = false){ public function __construct(FullChunk $chunk, CompoundTag $nbt, Entity $shootingEntity = null, $critical = false){
$this->isCritical = (bool) $critical; $this->isCritical = (bool) $critical;
parent::__construct($chunk, $nbt, $shootingEntity); parent::__construct($chunk, $nbt, $shootingEntity);
} }

View File

@ -45,14 +45,15 @@ use pocketmine\math\Vector2;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\metadata\Metadatable; use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\Network;
use pocketmine\network\protocol\MobEffectPacket; use pocketmine\network\protocol\MobEffectPacket;
use pocketmine\network\protocol\RemoveEntityPacket; use pocketmine\network\protocol\RemoveEntityPacket;
use pocketmine\network\protocol\SetEntityDataPacket; use pocketmine\network\protocol\SetEntityDataPacket;
@ -203,10 +204,9 @@ abstract class Entity extends Location implements Metadatable{
protected $isPlayer = false; protected $isPlayer = false;
public function __construct(FullChunk $chunk, Compound $nbt){ public function __construct(FullChunk $chunk, CompoundTag $nbt){
if($chunk === null or $chunk->getProvider() === null){
throw new ChunkException("Invalid garbage Chunk given to Entity"); assert($chunk !== null and $chunk->getProvider() !== null);
}
$this->timings = Timings::getEntityTimings($this); $this->timings = Timings::getEntityTimings($this);
@ -238,28 +238,30 @@ abstract class Entity extends Location implements Metadatable{
); );
$this->setMotion($this->temporalVector->setComponents($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2])); $this->setMotion($this->temporalVector->setComponents($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2]));
assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z));
if(!isset($this->namedtag->FallDistance)){ if(!isset($this->namedtag->FallDistance)){
$this->namedtag->FallDistance = new Float("FallDistance", 0); $this->namedtag->FallDistance = new FloatTag("FallDistance", 0);
} }
$this->fallDistance = $this->namedtag["FallDistance"]; $this->fallDistance = $this->namedtag["FallDistance"];
if(!isset($this->namedtag->Fire)){ if(!isset($this->namedtag->Fire)){
$this->namedtag->Fire = new Short("Fire", 0); $this->namedtag->Fire = new ShortTag("Fire", 0);
} }
$this->fireTicks = $this->namedtag["Fire"]; $this->fireTicks = $this->namedtag["Fire"];
if(!isset($this->namedtag->Air)){ if(!isset($this->namedtag->Air)){
$this->namedtag->Air = new Short("Air", 300); $this->namedtag->Air = new ShortTag("Air", 300);
} }
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $this->namedtag["Air"]); $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $this->namedtag["Air"]);
if(!isset($this->namedtag->OnGround)){ if(!isset($this->namedtag->OnGround)){
$this->namedtag->OnGround = new Byte("OnGround", 0); $this->namedtag->OnGround = new ByteTag("OnGround", 0);
} }
$this->onGround = $this->namedtag["OnGround"] > 0 ? true : false; $this->onGround = $this->namedtag["OnGround"] > 0 ? true : false;
if(!isset($this->namedtag->Invulnerable)){ if(!isset($this->namedtag->Invulnerable)){
$this->namedtag->Invulnerable = new Byte("Invulnerable", 0); $this->namedtag->Invulnerable = new ByteTag("Invulnerable", 0);
} }
$this->invulnerable = $this->namedtag["Invulnerable"] > 0 ? true : false; $this->invulnerable = $this->namedtag["Invulnerable"] > 0 ? true : false;
@ -405,12 +407,12 @@ abstract class Entity extends Location implements Metadatable{
/** /**
* @param int|string $type * @param int|string $type
* @param FullChunk $chunk * @param FullChunk $chunk
* @param Compound $nbt * @param CompoundTag $nbt
* @param $args * @param $args
* *
* @return Entity * @return Entity
*/ */
public static function createEntity($type, FullChunk $chunk, Compound $nbt, ...$args){ public static function createEntity($type, FullChunk $chunk, CompoundTag $nbt, ...$args){
if(isset(self::$knownEntities[$type])){ if(isset(self::$knownEntities[$type])){
$class = self::$knownEntities[$type]; $class = self::$knownEntities[$type];
return new $class($chunk, $nbt, ...$args); return new $class($chunk, $nbt, ...$args);
@ -447,58 +449,60 @@ abstract class Entity extends Location implements Metadatable{
public function saveNBT(){ public function saveNBT(){
if(!($this instanceof Player)){ if(!($this instanceof Player)){
$this->namedtag->id = new String("id", $this->getSaveId()); $this->namedtag->id = new StringTag("id", $this->getSaveId());
if($this->getNameTag() !== ""){ if($this->getNameTag() !== ""){
$this->namedtag->CustomName = new String("CustomName", $this->getNameTag()); $this->namedtag->CustomName = new StringTag("CustomName", $this->getNameTag());
$this->namedtag->CustomNameVisible = new String("CustomNameVisible", $this->isNameTagVisible()); $this->namedtag->CustomNameVisible = new StringTag("CustomNameVisible", $this->isNameTagVisible());
}else{ }else{
unset($this->namedtag->CustomName); unset($this->namedtag->CustomName);
unset($this->namedtag->CustomNameVisible); unset($this->namedtag->CustomNameVisible);
} }
} }
$this->namedtag->Pos = new Enum("Pos", [ $this->namedtag->Pos = new ListTag("Pos", [
new Double(0, $this->x), new DoubleTag(0, $this->x),
new Double(1, $this->y), new DoubleTag(1, $this->y),
new Double(2, $this->z) new DoubleTag(2, $this->z)
]); ]);
$this->namedtag->Motion = new Enum("Motion", [ $this->namedtag->Motion = new ListTag("Motion", [
new Double(0, $this->motionX), new DoubleTag(0, $this->motionX),
new Double(1, $this->motionY), new DoubleTag(1, $this->motionY),
new Double(2, $this->motionZ) new DoubleTag(2, $this->motionZ)
]); ]);
$this->namedtag->Rotation = new Enum("Rotation", [ $this->namedtag->Rotation = new ListTag("Rotation", [
new Float(0, $this->yaw), new FloatTag(0, $this->yaw),
new Float(1, $this->pitch) new FloatTag(1, $this->pitch)
]); ]);
$this->namedtag->FallDistance = new Float("FallDistance", $this->fallDistance); $this->namedtag->FallDistance = new FloatTag("FallDistance", $this->fallDistance);
$this->namedtag->Fire = new Short("Fire", $this->fireTicks); $this->namedtag->Fire = new ShortTag("Fire", $this->fireTicks);
$this->namedtag->Air = new Short("Air", $this->getDataProperty(self::DATA_AIR)); $this->namedtag->Air = new ShortTag("Air", $this->getDataProperty(self::DATA_AIR));
$this->namedtag->OnGround = new Byte("OnGround", $this->onGround == true ? 1 : 0); $this->namedtag->OnGround = new ByteTag("OnGround", $this->onGround == true ? 1 : 0);
$this->namedtag->Invulnerable = new Byte("Invulnerable", $this->invulnerable == true ? 1 : 0); $this->namedtag->Invulnerable = new ByteTag("Invulnerable", $this->invulnerable == true ? 1 : 0);
if(count($this->effects) > 0){ if(count($this->effects) > 0){
$effects = []; $effects = [];
foreach($this->effects as $effect){ foreach($this->effects as $effect){
$effects[$effect->getId()] = new Compound($effect->getId(), [ $effects[$effect->getId()] = new CompoundTag($effect->getId(), [
"Id" => new Byte("Id", $effect->getId()), "Id" => new ByteTag("Id", $effect->getId()),
"Amplifier" => new Byte("Amplifier", $effect->getAmplifier()), "Amplifier" => new ByteTag("Amplifier", $effect->getAmplifier()),
"Duration" => new Int("Duration", $effect->getDuration()), "Duration" => new IntTag("Duration", $effect->getDuration()),
"Ambient" => new Byte("Ambient", 0), "Ambient" => new ByteTag("Ambient", 0),
"ShowParticles" => new Byte("ShowParticles", $effect->isVisible() ? 1 : 0) "ShowParticles" => new ByteTag("ShowParticles", $effect->isVisible() ? 1 : 0)
]); ]);
} }
$this->namedtag->ActiveEffects = new Enum("ActiveEffects", $effects); $this->namedtag->ActiveEffects = new ListTag("ActiveEffects", $effects);
}else{ }else{
unset($this->namedtag->ActiveEffects); unset($this->namedtag->ActiveEffects);
} }
} }
protected function initEntity(){ protected function initEntity(){
assert($this->namedtag instanceof CompoundTag);
if(isset($this->namedtag->ActiveEffects)){ if(isset($this->namedtag->ActiveEffects)){
foreach($this->namedtag->ActiveEffects->getValue() as $e){ foreach($this->namedtag->ActiveEffects->getValue() as $e){
$effect = Effect::getEffect($e["Id"]); $effect = Effect::getEffect($e["Id"]);
@ -553,13 +557,6 @@ abstract class Entity extends Location implements Metadatable{
} }
} }
/**
* @deprecated
*/
public function sendMetadata($player){
$this->sendData($player);
}
/** /**
* @param Player[]|Player $player * @param Player[]|Player $player
* @param array $data Properly formatted entity data, defaults to everything * @param array $data Properly formatted entity data, defaults to everything

View File

@ -30,8 +30,8 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -58,7 +58,7 @@ class FallingSand extends Entity{
$this->blockId = $this->namedtag["TileID"]; $this->blockId = $this->namedtag["TileID"];
}elseif(isset($this->namedtag->Tile)){ }elseif(isset($this->namedtag->Tile)){
$this->blockId = $this->namedtag["Tile"]; $this->blockId = $this->namedtag["Tile"];
$this->namedtag["TileID"] = new Int("TileID", $this->blockId); $this->namedtag["TileID"] = new IntTag("TileID", $this->blockId);
} }
if(isset($this->namedtag->Data)){ if(isset($this->namedtag->Data)){
@ -153,8 +153,8 @@ class FallingSand extends Entity{
} }
public function saveNBT(){ public function saveNBT(){
$this->namedtag->TileID = new Int("TileID", $this->blockId); $this->namedtag->TileID = new IntTag("TileID", $this->blockId);
$this->namedtag->Data = new Byte("Data", $this->damage); $this->namedtag->Data = new ByteTag("Data", $this->damage);
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){

View File

@ -26,11 +26,11 @@ use pocketmine\inventory\PlayerInventory;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\utils\UUID; use pocketmine\utils\UUID;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddPlayerPacket; use pocketmine\network\protocol\AddPlayerPacket;
use pocketmine\network\protocol\RemovePlayerPacket; use pocketmine\network\protocol\RemovePlayerPacket;
@ -111,14 +111,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$this->setNameTag($this->namedtag["NameTag"]); $this->setNameTag($this->namedtag["NameTag"]);
} }
if(isset($this->namedtag->Skin) and $this->namedtag->Skin instanceof Compound){ if(isset($this->namedtag->Skin) and $this->namedtag->Skin instanceof CompoundTag){
$this->setSkin($this->namedtag->Skin["Data"], $this->namedtag->Skin["Name"]); $this->setSkin($this->namedtag->Skin["Data"], $this->namedtag->Skin["Name"]);
} }
$this->uuid = UUID::fromData($this->getId(), $this->getSkinData(), $this->getNameTag()); $this->uuid = UUID::fromData($this->getId(), $this->getSkinData(), $this->getNameTag());
} }
if(isset($this->namedtag->Inventory) and $this->namedtag->Inventory instanceof Enum){ if(isset($this->namedtag->Inventory) and $this->namedtag->Inventory instanceof ListTag){
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->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1); $this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1);
@ -150,7 +150,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
public function saveNBT(){ public function saveNBT(){
parent::saveNBT(); parent::saveNBT();
$this->namedtag->Inventory = new Enum("Inventory", []); $this->namedtag->Inventory = new ListTag("Inventory", []);
$this->namedtag->Inventory->setTagType(NBT::TAG_Compound); $this->namedtag->Inventory->setTagType(NBT::TAG_Compound);
if($this->inventory !== null){ if($this->inventory !== null){
for($slot = 0; $slot < 9; ++$slot){ for($slot = 0; $slot < 9; ++$slot){
@ -159,19 +159,19 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$item = $this->inventory->getItem($hotbarSlot); $item = $this->inventory->getItem($hotbarSlot);
if($item->getId() !== 0 and $item->getCount() > 0){ if($item->getId() !== 0 and $item->getCount() > 0){
$tag = NBT::putItemHelper($item, $slot); $tag = NBT::putItemHelper($item, $slot);
$tag->TrueSlot = new Byte("TrueSlot", $hotbarSlot); $tag->TrueSlot = new ByteTag("TrueSlot", $hotbarSlot);
$this->namedtag->Inventory[$slot] = $tag; $this->namedtag->Inventory[$slot] = $tag;
continue; continue;
} }
} }
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = new CompoundTag("", [
new Byte("Count", 0), new ByteTag("Count", 0),
new Short("Damage", 0), new ShortTag("Damage", 0),
new Byte("Slot", $slot), new ByteTag("Slot", $slot),
new Byte("TrueSlot", -1), new ByteTag("TrueSlot", -1),
new Short("id", 0), new ShortTag("id", 0),
]); ]);
} }
@ -193,9 +193,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
} }
if(strlen($this->getSkinData()) > 0){ if(strlen($this->getSkinData()) > 0){
$this->namedtag->Skin = new Compound("Skin", [ $this->namedtag->Skin = new CompoundTag("Skin", [
"Data" => new String("Data", $this->getSkinData()), "Data" => new StringTag("Data", $this->getSkinData()),
"Name" => new String("Name", $this->getSkinName()) "Name" => new StringTag("Name", $this->getSkinName())
]); ]);
} }
} }

View File

@ -30,8 +30,9 @@ use pocketmine\item\Item as ItemItem;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddItemEntityPacket; use pocketmine\network\protocol\AddItemEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -70,6 +71,9 @@ class Item extends Entity{
if(isset($this->namedtag->Thrower)){ if(isset($this->namedtag->Thrower)){
$this->thrower = $this->namedtag["Thrower"]; $this->thrower = $this->namedtag["Thrower"];
} }
assert($this->namedtag->Item instanceof CompoundTag);
if(!isset($this->namedtag->Item)){ if(!isset($this->namedtag->Item)){
$this->close(); $this->close();
return; return;
@ -160,14 +164,14 @@ class Item extends Entity{
public function saveNBT(){ public function saveNBT(){
parent::saveNBT(); parent::saveNBT();
$this->namedtag->Item = NBT::putItemHelper($this->item); $this->namedtag->Item = NBT::putItemHelper($this->item);
$this->namedtag->Health = new Short("Health", $this->getHealth()); $this->namedtag->Health = new ShortTag("Health", $this->getHealth());
$this->namedtag->Age = new Short("Age", $this->age); $this->namedtag->Age = new ShortTag("Age", $this->age);
$this->namedtag->PickupDelay = new Short("PickupDelay", $this->pickupDelay); $this->namedtag->PickupDelay = new ShortTag("PickupDelay", $this->pickupDelay);
if($this->owner !== null){ if($this->owner !== null){
$this->namedtag->Owner = new String("Owner", $this->owner); $this->namedtag->Owner = new StringTag("Owner", $this->owner);
} }
if($this->thrower !== null){ if($this->thrower !== null){
$this->namedtag->Thrower = new String("Thrower", $this->thrower); $this->namedtag->Thrower = new StringTag("Thrower", $this->thrower);
} }
} }

View File

@ -31,7 +31,7 @@ use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\Timings; use pocketmine\event\Timings;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\EntityEventPacket; use pocketmine\network\protocol\EntityEventPacket;
@ -51,12 +51,12 @@ abstract class Living extends Entity implements Damageable{
parent::initEntity(); parent::initEntity();
if(isset($this->namedtag->HealF)){ if(isset($this->namedtag->HealF)){
$this->namedtag->Health = new Short("Health", (int) $this->namedtag["HealF"]); $this->namedtag->Health = new ShortTag("Health", (int) $this->namedtag["HealF"]);
unset($this->namedtag->HealF); unset($this->namedtag->HealF);
} }
if(!isset($this->namedtag->Health) or !($this->namedtag->Health instanceof Short)){ if(!isset($this->namedtag->Health) or !($this->namedtag->Health instanceof ShortTag)){
$this->namedtag->Health = new Short("Health", $this->getMaxHealth()); $this->namedtag->Health = new ShortTag("Health", $this->getMaxHealth());
} }
$this->setHealth($this->namedtag["Health"]); $this->setHealth($this->namedtag["Health"]);
@ -75,7 +75,7 @@ abstract class Living extends Entity implements Damageable{
public function saveNBT(){ public function saveNBT(){
parent::saveNBT(); parent::saveNBT();
$this->namedtag->Health = new Short("Health", $this->getHealth()); $this->namedtag->Health = new ShortTag("Health", $this->getHealth());
} }
public abstract function getName(); public abstract function getName();

View File

@ -26,7 +26,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\event\entity\ExplosionPrimeEvent;
use pocketmine\level\Explosion; use pocketmine\level\Explosion;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -69,7 +69,7 @@ class PrimedTNT extends Entity implements Explosive{
public function saveNBT(){ public function saveNBT(){
parent::saveNBT(); parent::saveNBT();
$this->namedtag->Fuse = new Byte("Fuse", $this->fuse); $this->namedtag->Fuse = new ByteTag("Fuse", $this->fuse);
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){

View File

@ -31,8 +31,8 @@ use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\MovingObjectPosition; use pocketmine\level\MovingObjectPosition;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
abstract class Projectile extends Entity{ abstract class Projectile extends Entity{
@ -44,7 +44,7 @@ abstract class Projectile extends Entity{
public $hadCollision = false; public $hadCollision = false;
public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null){ public function __construct(FullChunk $chunk, CompoundTag $nbt, Entity $shootingEntity = null){
$this->shootingEntity = $shootingEntity; $this->shootingEntity = $shootingEntity;
if($shootingEntity !== null){ if($shootingEntity !== null){
$this->setDataProperty(self::DATA_SHOOTER_ID, self::DATA_TYPE_LONG, $shootingEntity->getId()); $this->setDataProperty(self::DATA_SHOOTER_ID, self::DATA_TYPE_LONG, $shootingEntity->getId());
@ -75,7 +75,7 @@ abstract class Projectile extends Entity{
public function saveNBT(){ public function saveNBT(){
parent::saveNBT(); parent::saveNBT();
$this->namedtag->Age = new Short("Age", $this->age); $this->namedtag->Age = new ShortTag("Age", $this->age);
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -38,7 +38,7 @@ class Snowball extends Projectile{
protected $gravity = 0.03; protected $gravity = 0.03;
protected $drag = 0.01; protected $drag = 0.01;
public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null){ public function __construct(FullChunk $chunk, CompoundTag $nbt, Entity $shootingEntity = null){
parent::__construct($chunk, $nbt, $shootingEntity); parent::__construct($chunk, $nbt, $shootingEntity);
} }

View File

@ -22,7 +22,7 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -76,7 +76,7 @@ class Villager extends Creature implements NPC, Ageable{
* @param $profession * @param $profession
*/ */
public function setProfession($profession){ public function setProfession($profession){
$this->namedtag->Profession = new Int("Profession", $profession); $this->namedtag->Profession = new IntTag("Profession", $profession);
} }
public function getProfession(){ public function getProfession(){

View File

@ -1,48 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\event\entity;
use pocketmine\entity\Entity;
use pocketmine\Event;
use pocketmine\event\Cancellable;
use pocketmine\math\Vector3;
/**
* @deprecated
*/
class EntityMoveEvent extends EntityEvent implements Cancellable{
public static $handlerList = null;
/** @var \pocketmine\math\Vector3 */
private $pos;
public function __construct(Entity $entity, Vector3 $pos){
$this->entity = $entity;
$this->pos = $pos;
}
public function getVector(){
return $this->pos;
}
}

View File

@ -46,13 +46,6 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
$this->player = $player; $this->player = $player;
$this->message = $message; $this->message = $message;
//TODO: @deprecated (backwards-compativility)
$i = 0;
while(($pos = strpos($format, "%s")) !== false){
$format = substr($format, 0, $pos) . "{%$i}" . substr($format, $pos + 2);
++$i;
}
$this->format = $format; $this->format = $format;
if($recipients === null){ if($recipients === null){
@ -84,13 +77,6 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
} }
public function setFormat($format){ public function setFormat($format){
//TODO: @deprecated (backwards-compativility)
$i = 0;
while(($pos = strpos($format, "%s")) !== false){
$format = substr($format, 0, $pos) . "{%$i}" . substr($format, $pos + 2);
++$i;
}
$this->format = $format; $this->format = $format;
} }

View File

@ -53,7 +53,7 @@ class QueryRegenerateEvent extends ServerEvent{
public function __construct(Server $server, $timeout = 5){ public function __construct(Server $server, $timeout = 5){
$this->timeout = $timeout; $this->timeout = $timeout;
$this->serverName = $server->getServerName(); $this->serverName = $server->getMotd();
$this->listPlugins = $server->getProperty("settings.query-plugins", true); $this->listPlugins = $server->getProperty("settings.query-plugins", true);
$this->plugins = $server->getPluginManager()->getPlugins(); $this->plugins = $server->getPluginManager()->getPlugins();
$this->players = []; $this->players = [];

View File

@ -22,17 +22,10 @@
namespace pocketmine\inventory; namespace pocketmine\inventory;
use pocketmine\block\Planks;
use pocketmine\block\Quartz;
use pocketmine\block\Sandstone;
use pocketmine\block\Slab;
use pocketmine\block\Fence;
use pocketmine\block\Stone;
use pocketmine\block\StoneBricks;
use pocketmine\block\StoneWall;
use pocketmine\block\Wood;
use pocketmine\block\Wood2;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\Server;
use pocketmine\utils\Config;
use pocketmine\utils\MainLogger;
use pocketmine\utils\UUID; use pocketmine\utils\UUID;
class CraftingManager{ class CraftingManager{
@ -49,663 +42,55 @@ class CraftingManager{
private static $RECIPE_COUNT = 0; private static $RECIPE_COUNT = 0;
public function __construct(){ public function __construct(){
// load recipes from src/pocketmine/recipes.json
$this->registerStonecutter(); $recipes = new Config(Server::getInstance()->getFilePath() . "src/pocketmine/resources/recipes.json", Config::JSON, []);
$this->registerFurnace();
MainLogger::getLogger()->info("Loading recipes...");
foreach($recipes->getAll() as $recipe){
$this->registerDyes(); switch($recipe["Type"]){
$this->registerIngots(); case 0:
$this->registerTools(); // TODO: handle multiple result items
$this->registerWeapons(); if(count($recipe["Result"]) == 1){
$this->registerArmor(); $first = $recipe["Result"][0];
$this->registerFood(); $result = new ShapelessRecipe(Item::get($first["ID"], $first["Damage"], $first["Count"]));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::CLAY_BLOCK, 0, 1)))->addIngredient(Item::get(Item::CLAY, 0, 4))); foreach($recipe["Ingredients"] as $ingredient){
$result->addIngredient(Item::get($ingredient["ID"], $ingredient["Damage"], $ingredient["Count"]));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WORKBENCH, 0, 1), }
"XX", $this->registerRecipe($result);
"XX"
))->setIngredient("X", Item::get(Item::WOODEN_PLANK, null)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::GLOWSTONE_BLOCK, 0, 1)))->addIngredient(Item::get(Item::GLOWSTONE_DUST, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::LIT_PUMPKIN, 0, 1)))->addIngredient(Item::get(Item::PUMPKIN, 0, 1))->addIngredient(Item::get(Item::TORCH, 0, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::SNOW_BLOCK, 0, 1),
"XX",
"XX"
))->setIngredient("X", Item::get(Item::SNOWBALL)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_LAYER, 0, 6)))->addIngredient(Item::get(Item::SNOW_BLOCK, 0, 3)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::STICK, 0, 4),
"X ",
"X "
))->setIngredient("X", Item::get(Item::WOODEN_PLANK, null)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::STONECUTTER, 0, 1),
"XX",
"XX"
))->setIngredient("X", Item::get(Item::COBBLESTONE)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD, Wood::OAK, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD, Wood::SPRUCE, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD, Wood::BIRCH, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD, Wood::JUNGLE, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD2, Wood2::ACACIA, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD2, Wood2::DARK_OAK, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOOL, 0, 1),
"XX",
"XX"
))->setIngredient("X", Item::get(Item::STRING, 0, 4)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::TORCH, 0, 4),
"C ",
"S"
))->setIngredient("C", Item::get(Item::COAL,0,1))->setIngredient("S", Item::get(Item::STICK,0,1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::TORCH, 0, 4),
"C ",
"S"
))->setIngredient("C", Item::get(Item::COAL, 1, 1))->setIngredient("S", Item::get(Item::STICK, 0, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::SUGAR, 0, 1),
"S"
))->setIngredient("S", Item::get(Item::SUGARCANE, 0, 1)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BED, 0, 1),
"WWW",
"PPP"
))->setIngredient("W", Item::get(Item::WOOL, null, 3))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::CHEST, 0, 1),
"PPP",
"P P",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 8)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, 0, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::SPRUCE, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::BIRCH, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::JUNGLE, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::ACACIA, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::DARK_OAK, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_SPRUCE, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_BIRCH, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_JUNGLE, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_DARK_OAK, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_ACACIA, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FURNACE, 0, 1),
"CCC",
"C C",
"CCC"
))->setIngredient("C", Item::get(Item::COBBLESTONE, 0, 8)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::GLASS_PANE, 0, 16),
"GGG",
"GGG"
))->setIngredient("G", Item::get(Item::GLASS, 0, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::LADDER, 0, 2),
"S S",
"SSS",
"S S"
))->setIngredient("S", Item::get(Item::STICK, 0, 7)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::TRAPDOOR, 0, 2),
"PPP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOODEN_DOOR, 0, 1),
"PP",
"PP",
"PP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOODEN_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::OAK, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::SPRUCE_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::SPRUCE, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BIRCH_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::BIRCH, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::JUNGLE_WOOD_STAIRS, 0, 4),
"P",
"PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::JUNGLE, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::ACACIA_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::ACACIA, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::DARK_OAK_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::DARK_OAK, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BUCKET, 0, 1),
"I I",
" I"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::CLOCK, 0, 1),
" G",
"GR",
" G"
))->setIngredient("G", Item::get(Item::GOLD_INGOT, 0, 4))->setIngredient("R", Item::get(Item::REDSTONE_DUST, 0, 1)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::COMPASS, 0, 1),
" I ",
"IRI",
" I"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 4))->setIngredient("R", Item::get(Item::REDSTONE_DUST, 0, 1)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::TNT, 0, 1),
"GSG",
"SGS",
"GSG"
))->setIngredient("G", Item::get(Item::GUNPOWDER, 0, 5))->setIngredient("S", Item::get(Item::SAND, null, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOWL, 0, 4),
"P P",
" P"
))->setIngredient("P", Item::get(Item::WOODEN_PLANKS, null, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::MINECART, 0, 1),
"I I",
"III"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 5)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOOK, 0, 1),
"P P",
" P "
))->setIngredient("P", Item::get(Item::PAPER, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOOKSHELF, 0, 1),
"PBP",
"PBP",
"PBP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 6))->setIngredient("B", Item::get(Item::BOOK, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::PAINTING, 0, 1),
"SSS",
"SWS",
"SSS"
))->setIngredient("S", Item::get(Item::STICK, 0, 8))->setIngredient("W", Item::get(Item::WOOL, null, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::PAPER, 0, 3),
"SS",
"S"
))->setIngredient("S", Item::get(Item::SUGARCANE, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::SIGN, 0, 3),
"PPP",
"PPP",
" S"
))->setIngredient("S", Item::get(Item::STICK, 0, 1))->setIngredient("P", Item::get(Item::WOODEN_PLANKS, null, 6))); //TODO: check if it gives one sign or three
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::IRON_BARS, 0, 16),
"III",
"III",
"III"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 9)));
}
protected function registerFurnace(){
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::STONE, 0, 1), Item::get(Item::COBBLESTONE, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::STONE_BRICK, 2, 1), Item::get(Item::STONE_BRICK, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::GLASS, 0, 1), Item::get(Item::SAND, null, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COAL, 1, 1), Item::get(Item::TRUNK, null, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::GOLD_INGOT, 0, 1), Item::get(Item::GOLD_ORE, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::IRON_INGOT, 0, 1), Item::get(Item::IRON_ORE, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::EMERALD, 0, 1), Item::get(Item::EMERALD_ORE, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::DIAMOND, 0, 1), Item::get(Item::DIAMOND_ORE, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::NETHER_BRICK, 0, 1), Item::get(Item::NETHERRACK, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COOKED_PORKCHOP, 0, 1), Item::get(Item::RAW_PORKCHOP, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::BRICK, 0, 1), Item::get(Item::CLAY, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COOKED_FISH, 0, 1), Item::get(Item::RAW_FISH, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COOKED_FISH, 1, 1), Item::get(Item::RAW_FISH, 1, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::DYE, 2, 1), Item::get(Item::CACTUS, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::DYE, 1, 1), Item::get(Item::RED_MUSHROOM, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::STEAK, 0, 1), Item::get(Item::RAW_BEEF, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COOKED_CHICKEN, 0, 1), Item::get(Item::RAW_CHICKEN, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::BAKED_POTATO, 0, 1), Item::get(Item::POTATO, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::HARDENED_CLAY, 0, 1), Item::get(Item::CLAY_BLOCK, 0, 1)));
}
protected function registerStonecutter(){
$shapes = [
"slab" => [
" ",
"XXX",
" "
],
"stairs" => [
"X ",
"XX ",
"XXX"
],
"wall/fence" => [
"XXX",
"XXX",
" "
],
"blockrecipe1" => [
"XX",
"XX"
],
"blockrecipe2X1" => [
" ",
" X ",
" X "
],
"blockrecipe2X2" => [
"AB",
"BA"
],
"blockrecipe1X2" => [
" ",
"AB"
]
];
$buildRecipes = [];
// Single ingedient stone cutter recipes:
$RESULT_ITEMID = 0; $RESULT_META = 1; $INGREDIENT_ITEMID = 2; $INGREDIENT_META = 3; $RECIPE_SHAPE = 4;$RESULT_AMOUNT = 5;
$recipes = [
//RESULT_ITEM_ID RESULT_META INGREDIENT_ITEMID INGREDIENT_META RECIPE_SHAPE RESULT_AMOUNT
[Item::SLAB, Slab::STONE, Item::STONE, Stone::NORMAL, "slab", 6],
[Item::SLAB, Slab::COBBLESTONE, Item::COBBLESTONE, 0, "slab", 6],
[Item::SLAB, Slab::SANDSTONE, Item::SANDSTONE, 0, "slab", 6],
[Item::SLAB, Slab::BRICK, Item::BRICK, 0, "slab", 6],
[Item::SLAB, Slab::STONE_BRICK, Item::STONE_BRICK, StoneBricks::NORMAL,"slab", 6],
[Item::SLAB, Slab::NETHER_BRICK, Item::NETHER_BRICK_BLOCK, 0, "slab", 6],
[Item::SLAB, Slab::QUARTZ, Item::QUARTZ_BLOCK, 0, "slab", 6],
[Item::COBBLESTONE_STAIRS, 0, Item::COBBLESTONE, 0, "stairs", 4],
[Item::SANDSTONE_STAIRS, 0, Item::SANDSTONE, 0, "stairs", 4],
[Item::STONE_BRICK_STAIRS, 0, Item::STONE_BRICK, StoneBricks::NORMAL,"stairs", 4],
[Item::BRICK_STAIRS, 0, Item::BRICKS_BLOCK, 0, "stairs", 4],
[Item::NETHER_BRICKS_STAIRS,0, Item::NETHER_BRICK_BLOCK, 0, "stairs", 4],
[Item::COBBLESTONE_WALL, StoneWall::NONE_MOSSY_WALL, Item::COBBLESTONE, 0, "wall/fence", 6],
[Item::COBBLESTONE_WALL, StoneWall::MOSSY_WALL, Item::MOSSY_STONE, 0, "wall/fence", 6],
[Item::NETHER_BRICK_FENCE, 0, Item::NETHER_BRICK_BLOCK, 0, "wall/fence", 6],
[Item::NETHER_BRICKS, 0, Item::NETHER_BRICK, 0, "blockrecipe1", 1],
[Item::SANDSTONE, SandStone::NORMAL, Item::SAND, 0, "blockrecipe1", 1],
[Item::SANDSTONE, Sandstone::CHISELED, Item::SANDSTONE, SandStone::NORMAL, "blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::NORMAL, "blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_GRANITE,"blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_DIORITE,"blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_ANDESITE,"blockrecipe1",4],
[Item::STONE, Stone::POLISHED_GRANITE, Item::STONE, Stone::GRANITE, "blockrecipe1", 4],
[Item::STONE, Stone::POLISHED_DIORITE, Item::STONE, Stone::DIORITE, "blockrecipe1", 4],
[Item::STONE, Stone::POLISHED_ANDESITE, Item::STONE, Stone::ANDESITE, "blockrecipe1", 4],
[Item::QUARTZ_BLOCK, Quartz::QUARTZ_NORMAL, Item::QUARTZ, Stone::ANDESITE, "blockrecipe1", 4],
[Item::QUARTZ_BLOCK, Quartz::QUARTZ_CHISELED, Item::SLAB, Slab::QUARTZ, "blockrecipe2X1", 1],
[Item::SANDSTONE, SandStone::CHISELED, Item::SLAB, Slab::SANDSTONE, "blockrecipe2X1", 1],
[Item::STONE_BRICK, StoneBricks::CHISELED, Item::SLAB, Slab::STONE_BRICK, "blockrecipe2X1", 1],
];
foreach ($recipes as $recipe){
$buildRecipes[] = $this->createOneIngedientRecipe($shapes[$recipe[$RECIPE_SHAPE]], $recipe[$RESULT_ITEMID], $recipe[$RESULT_META], $recipe[$RESULT_AMOUNT], $recipe[$INGREDIENT_ITEMID], $recipe[$INGREDIENT_META], "X", "Stonecutter");
}
// Multi-ingredient stone recipes:
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE, Stone::GRANITE, 1),
...$shapes["blockrecipe1X2"]
))->setIngredient("A", Item::get(Item::STONE, Stone::DIORITE, 1))->setIngredient("B", Item::get(Item::QUARTZ, Quartz::QUARTZ_NORMAL, 1)));
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE, Stone::DIORITE, 2),
...$shapes["blockrecipe2X2"]
))->setIngredient("A", Item::get(Item::COBBLESTONE, 0, 2))->setIngredient("B", Item::get(Item::QUARTZ, 0, 2)));
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE, Stone::ANDESITE, 2),
...$shapes["blockrecipe1X2"]
))->setIngredient("A", Item::get(Item::COBBLESTONE, 0, 1))->setIngredient("B", Item::get(Item::STONE, Stone::DIORITE, 1)));
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE_BRICK, StoneBricks::MOSSY, 1),
...$shapes["blockrecipe1X2"]
))->setIngredient("A", Item::get(Item::STONE_BRICK, StoneBricks::NORMAL, 1))->setIngredient("B", Item::get(Item::VINES, 0, 1)));
$this->sortAndAddRecipesArray($buildRecipes);
}
private function sortAndAddRecipesArray(&$recipes){
// Sort the recipes based on the result item name with the bubblesort algoritm.
for ($i = 0; $i < count($recipes); ++$i){
$current = $recipes[$i];
$result = $current->getResult();
for ($j = count($recipes)-1; $j > $i; --$j)
{
if ($this->sort($result, $recipes[$j]->getResult())>0){
$swap = $current;
$current = $recipes[$j];
$recipes[$j] = $swap;
$result = $current->getResult();
} }
} break;
$this->registerRecipe($current); case 1:
} // TODO: handle multiple result items
} if(count($recipe["Result"]) == 1){
$first = $recipe["Result"][0];
$result = new ShapedRecipe(Item::get($first["ID"], $first["Damage"], $first["Count"]), $recipe["Height"], $recipe["Width"]);
private function createOneIngedientRecipe($recipeshape, $resultitem, $resultitemmeta, $resultitemamound, $ingedienttype, $ingredientmeta, $ingredientname, $inventoryType = ""){ $shape = array_chunk($recipe["Ingredients"], $recipe["Width"]);
$ingredientamount = 0; foreach($shape as $y => $row){
$height = 0; foreach($row as $x => $ingredient){
// count how many of the ingredient are in the recipe and check height for big or small recipe. $result->addIngredient($x, $y, Item::get($ingredient["ID"], ($ingredient["Damage"] < 0 ? null : $ingredient["Damage"]), $ingredient["Count"]));
foreach ($recipeshape as $line){ }
$height += 1; }
$width = strlen($line); $this->registerRecipe($result);
$ingredientamount += substr_count($line, $ingredientname); }
} break;
$recipe = null; case 2:
if ($height < 3){ $result = $recipe["Result"];
// Process small recipe $resultItem = Item::get($result["ID"], $result["Damage"], $result["Count"]);
$fullClassName = "pocketmine\\inventory\\".$inventoryType."ShapedRecipe";// $ShapeClass."ShapedRecipe"; $this->registerRecipe(new FurnaceRecipe($resultItem, Item::get($recipe["Ingredients"], 0, 1)));
$recipe = ((new $fullClassName(Item::get($resultitem, $resultitemmeta, $resultitemamound), break;
...$recipeshape case 3:
))->setIngredient($ingredientname, Item::get($ingedienttype, $ingredientmeta, $ingredientamount))); $result = $recipe["Result"];
} $resultItem = Item::get($result["ID"], $result["Damage"], $result["Count"]);
else{ $this->registerRecipe(new FurnaceRecipe($resultItem, Item::get($recipe["Ingredients"]["ID"], $recipe["Ingredients"]["Damage"], 1)));
// Process big recipe break;
$fullClassName = "pocketmine\\inventory\\".$inventoryType."BigShapedRecipe"; default:
$recipe = ((new $fullClassName(Item::get($resultitem, $resultitemmeta, $resultitemamound), break;
...$recipeshape
))->setIngredient($ingredientname, Item::get($ingedienttype, $ingredientmeta, $ingredientamount)));
}
return $recipe;
}
protected function registerFood(){
//TODO: check COOKIES
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::MELON_SEEDS, 0, 1)))->addIngredient(Item::get(Item::MELON_SLICE, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::PUMPKIN_SEEDS, 0, 4)))->addIngredient(Item::get(Item::PUMPKIN, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::PUMPKIN_PIE, 0, 1)))->addIngredient(Item::get(Item::PUMPKIN, 0, 1))->addIngredient(Item::get(Item::EGG, 0, 1))->addIngredient(Item::get(Item::SUGAR, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::MUSHROOM_STEW, 0, 1)))->addIngredient(Item::get(Item::BOWL, 0, 1))->addIngredient(Item::get(Item::BROWN_MUSHROOM, 0, 1))->addIngredient(Item::get(Item::RED_MUSHROOM, 0, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::MELON_BLOCK, 0, 1)))->addIngredient(Item::get(Item::MELON_SLICE, 0, 9)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BEETROOT_SOUP, 0, 1)))->addIngredient(Item::get(Item::BEETROOT, 0, 4))->addIngredient(Item::get(Item::BOWL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::BREAD, 0, 1)))->addIngredient(Item::get(Item::WHEAT, 0, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::CAKE, 0, 1)))->addIngredient(Item::get(Item::WHEAT, 0, 3))->addIngredient(Item::get(Item::BUCKET, 1, 3))->addIngredient(Item::get(Item::EGG, 0, 1))->addIngredient(Item::get(Item::SUGAR, 0, 2)));
}
protected function registerArmor(){
$types = [
[Item::LEATHER, Item::FIRE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT],
[Item::LEATHER_CAP, Item::CHAIN_HELMET, Item::IRON_HELMET, Item::DIAMOND_HELMET, Item::GOLD_HELMET],
[Item::LEATHER_TUNIC, Item::CHAIN_CHESTPLATE, Item::IRON_CHESTPLATE, Item::DIAMOND_CHESTPLATE, Item::GOLD_CHESTPLATE],
[Item::LEATHER_PANTS, Item::CHAIN_LEGGINGS, Item::IRON_LEGGINGS, Item::DIAMOND_LEGGINGS, Item::GOLD_LEGGINGS],
[Item::LEATHER_BOOTS, Item::CHAIN_BOOTS, Item::IRON_BOOTS, Item::DIAMOND_BOOTS, Item::GOLD_BOOTS],
];
$shapes = [
[
"XXX",
"X X",
" "
],
[
"X X",
"XXX",
"XXX"
],
[
"XXX",
"X X",
"X X"
],
[
" ",
"X X",
"X X"
]
];
for($i = 1; $i < 5; ++$i){
foreach($types[$i] as $j => $type){
$this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), ...$shapes[$i - 1]))->setIngredient("X", Item::get($types[0][$j], 0, 1)));
} }
} }
} }
protected function registerWeapons(){
$types = [
[Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT],
[Item::WOODEN_SWORD, Item::STONE_SWORD, Item::IRON_SWORD, Item::DIAMOND_SWORD, Item::GOLD_SWORD],
];
for($i = 1; $i < 2; ++$i){
foreach($types[$i] as $j => $type){
$this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1),
" X ",
" X ",
" I "
))->setIngredient("X", Item::get($types[0][$j], null))->setIngredient("I", Item::get(Item::STICK)));
}
}
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::ARROW, 0, 1),
" F ",
" S ",
" P "
))->setIngredient("S", Item::get(Item::STICK))->setIngredient("F", Item::get(Item::FLINT))->setIngredient("P", Item::get(Item::FEATHER)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOW, 0, 1),
" X~",
"X ~",
" X~"
))->setIngredient("~", Item::get(Item::STRING))->setIngredient("X", Item::get(Item::STICK)));
}
protected function registerTools(){
$types = [
[Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT],
[Item::WOODEN_PICKAXE, Item::STONE_PICKAXE, Item::IRON_PICKAXE, Item::DIAMOND_PICKAXE, Item::GOLD_PICKAXE],
[Item::WOODEN_SHOVEL, Item::STONE_SHOVEL, Item::IRON_SHOVEL, Item::DIAMOND_SHOVEL, Item::GOLD_SHOVEL],
[Item::WOODEN_AXE, Item::STONE_AXE, Item::IRON_AXE, Item::DIAMOND_AXE, Item::GOLD_AXE],
[Item::WOODEN_HOE, Item::STONE_HOE, Item::IRON_HOE, Item::DIAMOND_HOE, Item::GOLD_HOE],
];
$shapes = [
[
"XXX",
" I ",
" I "
],
[
" X ",
" I ",
" I "
],
[
"XX ",
"XI ",
" I "
],
[
"XX ",
" I ",
" I "
]
];
for($i = 1; $i < 5; ++$i){
foreach($types[$i] as $j => $type){
$this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), ...$shapes[$i - 1]))->setIngredient("X", Item::get($types[0][$j], null))->setIngredient("I", Item::get(Item::STICK)));
}
}
$this->registerRecipe((new ShapedRecipe(Item::get(Item::FLINT_AND_STEEL, 0, 1),
" S",
"F "
))->setIngredient("F", Item::get(Item::FLINT))->setIngredient("S", Item::get(Item::IRON_INGOT)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::SHEARS, 0, 1),
" X",
"X "
))->setIngredient("X", Item::get(Item::IRON_INGOT)));
}
protected function registerDyes(){
for($i = 0; $i < 16; ++$i){
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::STAINED_CLAY, 15 - $i, 8)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::HARDENED_CLAY, 0, 8)));
//TODO: add glass things?
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::CARPET, $i, 3)))->addIngredient(Item::get(Item::WOOL, $i, 2)));
}
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 11, 2)))->addIngredient(Item::get(Item::DANDELION, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 15, 3)))->addIngredient(Item::get(Item::BONE, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 3, 2)))->addIngredient(Item::get(Item::DYE, 14, 1))->addIngredient(Item::get(Item::DYE, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 3, 3)))->addIngredient(Item::get(Item::DYE, 1, 1))->addIngredient(Item::get(Item::DYE, 0, 1))->addIngredient(Item::get(Item::DYE, 11, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 9, 2)))->addIngredient(Item::get(Item::DYE, 15, 1))->addIngredient(Item::get(Item::DYE, 1, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 14, 2)))->addIngredient(Item::get(Item::DYE, 11, 1))->addIngredient(Item::get(Item::DYE, 1, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 10, 2)))->addIngredient(Item::get(Item::DYE, 2, 1))->addIngredient(Item::get(Item::DYE, 15, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 12, 2)))->addIngredient(Item::get(Item::DYE, 4, 1))->addIngredient(Item::get(Item::DYE, 15, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 6, 2)))->addIngredient(Item::get(Item::DYE, 4, 1))->addIngredient(Item::get(Item::DYE, 2, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 5, 2)))->addIngredient(Item::get(Item::DYE, 4, 1))->addIngredient(Item::get(Item::DYE, 1, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 13, 3)))->addIngredient(Item::get(Item::DYE, 4, 1))->addIngredient(Item::get(Item::DYE, 1, 1))->addIngredient(Item::get(Item::DYE, 15, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 1, 1)))->addIngredient(Item::get(Item::BEETROOT, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 13, 4)))->addIngredient(Item::get(Item::DYE, 15, 1))->addIngredient(Item::get(Item::DYE, 1, 2))->addIngredient(Item::get(Item::DYE, 4, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 13, 2)))->addIngredient(Item::get(Item::DYE, 5, 1))->addIngredient(Item::get(Item::DYE, 9, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 8, 2)))->addIngredient(Item::get(Item::DYE, 0, 1))->addIngredient(Item::get(Item::DYE, 15, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 7, 3)))->addIngredient(Item::get(Item::DYE, 0, 1))->addIngredient(Item::get(Item::DYE, 15, 2)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 7, 2)))->addIngredient(Item::get(Item::DYE, 0, 1))->addIngredient(Item::get(Item::DYE, 8, 1)));
}
protected function registerIngots(){
$ingots = [
Item::GOLD_BLOCK => Item::GOLD_INGOT,
Item::IRON_BLOCK => Item::IRON_INGOT,
Item::DIAMOND_BLOCK => Item::DIAMOND,
Item::EMERALD_BLOCK => Item::EMERALD,
Item::REDSTONE_BLOCK => Item::REDSTONE_DUST,
Item::COAL_BLOCK => Item::COAL,
Item::HAY_BALE => Item::WHEAT,
];
foreach($ingots as $block => $ingot){
$this->registerRecipe((new BigShapelessRecipe(Item::get($block, 0, 1)))->addIngredient(Item::get($ingot, 0, 9)));
$this->registerRecipe((new ShapelessRecipe(Item::get($ingot, 0, 9)))->addIngredient(Item::get($block, 0, 1)));
}
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LAPIS_BLOCK, 0, 1)))->addIngredient(Item::get(Item::DYE, 4, 9)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 4, 9)))->addIngredient(Item::get(Item::LAPIS_BLOCK, 0, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GOLD_INGOT, 0, 1)))->addIngredient(Item::get(Item::GOLD_NUGGET, 0, 9)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::GOLD_NUGGET, 0, 9)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 1)));
}
public function sort(Item $i1, Item $i2){ public function sort(Item $i1, Item $i2){
if($i1->getId() > $i2->getId()){ if($i1->getId() > $i2->getId()){
return 1; return 1;

View File

@ -57,7 +57,7 @@ class InventoryType{
} }
static::$default[static::CHEST] = new InventoryType(27, "Chest", 0); static::$default[static::CHEST] = new InventoryType(27, "Chest", 0);
static::$default[static::DOUBLE_CHEST] = new InventoryType(27 + 27, "Double Chest", 0); static::$default[static::DOUBLE_CHEST] = new InventoryType(27 + 27, "DoubleTag Chest", 0);
static::$default[static::PLAYER] = new InventoryType(40, "Player", 0); //27 CONTAINER, 4 ARMOR (9 reference HOTBAR slots) static::$default[static::PLAYER] = new InventoryType(40, "Player", 0); //27 CONTAINER, 4 ARMOR (9 reference HOTBAR slots)
static::$default[static::FURNACE] = new InventoryType(3, "Furnace", 2); static::$default[static::FURNACE] = new InventoryType(3, "Furnace", 2);
static::$default[static::CRAFTING] = new InventoryType(5, "Crafting", 1); //4 CRAFTING slots, 1 RESULT static::$default[static::CRAFTING] = new InventoryType(5, "Crafting", 1); //4 CRAFTING slots, 1 RESULT

View File

@ -22,9 +22,9 @@
namespace pocketmine\inventory; namespace pocketmine\inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector2;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\UUID; use pocketmine\utils\UUID;
use pocketmine\math\Vector2;
class ShapedRecipe implements Recipe{ class ShapedRecipe implements Recipe{
/** @var Item */ /** @var Item */
@ -41,33 +41,18 @@ class ShapedRecipe implements Recipe{
private $shapeItems = []; private $shapeItems = [];
/** /**
* @param Item $result * @param Item $result
* @param string[] $shape * @param int $height
* @param int $width
* *
* @throws \Exception * @throws \Exception
*/ */
public function __construct(Item $result, ...$shape){ public function __construct(Item $result, $height, $width){
if(count($shape) === 0){ for($h = 0; $h < $height; $h++){
throw new \InvalidArgumentException("Must provide a shape"); if($width === 0 or $width > 3){
} throw new \InvalidStateException("Crafting rows should be 1, 2, 3 wide, not $width");
if(count($shape) > 3){
throw new \InvalidStateException("Crafting recipes should be 1, 2, 3 rows, not " . count($shape));
}
foreach($shape as $y => $row){
if(strlen($row) === 0 or strlen($row) > 3){
throw new \InvalidStateException("Crafting rows should be 1, 2, 3 characters, not " . count($row));
}
$this->ingredients[] = array_fill(0, strlen($row), null);
$len = strlen($row);
for($i = 0; $i < $len; ++$i){
$this->shape[$row{$i}] = null;
if(!isset($this->shapeItems[$row{$i}])){
$this->shapeItems[$row{$i}] = [new Vector2($i, $y)];
}else{
$this->shapeItems[$row{$i}][] = new Vector2($i, $y);
}
} }
$this->ingredients[] = array_fill(0, $width, null);
} }
$this->output = clone $result; $this->output = clone $result;
@ -97,6 +82,11 @@ class ShapedRecipe implements Recipe{
$this->id = $id; $this->id = $id;
} }
public function addIngredient($x, $y, Item $item){
$this->ingredients[$y][$x] = clone $item;
return $this;
}
/** /**
* @param string $key * @param string $key
* @param Item $item * @param Item $item

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class BlazePowder extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::BLAZE_POWDER, $meta, $count, "Blaze Powder");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class Boat extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::BOAT, $meta, $count, "Boat");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class BrewingStand extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::BREWING_STAND, $meta, $count, "Brewing Stand");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class CookedRabbit extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::COOKED_RABBIT, $meta, $count, "Cooked Rabbit");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class FermentedSpiderEye extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::FERMENTED_SPIDER_EYE, $meta, $count, "Fermented Spider Eye");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class GlassBottle extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::GLASS_BOTTLE, $meta, $count, "Glass Bottle");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class GlisteringMelon extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::GLISTERING_MELON, $meta, $count, "Glistering Melon");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class GoldenCarrot extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::GOLDEN_CARROT, $meta, $count, "Golden Carrot");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ use pocketmine\block\Block;
* Class used for Items that can be Blocks * Class used for Items that can be Blocks
*/ */
class ItemBlock extends Item{ class ItemBlock extends Item{
public function __construct(Block $block, $meta = 0, $count = 1){ public function __construct(Block $block, $meta = 0, int $count = 1){
$this->block = $block; $this->block = $block;
parent::__construct($block->getId(), $block->getDamage(), $count, $block->getName()); parent::__construct($block->getId(), $block->getDamage(), $count, $block->getName());
} }
@ -41,7 +41,7 @@ class ItemBlock extends Item{
$this->block = clone $this->block; $this->block = clone $this->block;
} }
public function getBlock(){ public function getBlock() : Block{
return $this->block; return $this->block;
} }

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class MagmaCream extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::MAGMA_CREAM, $meta, $count, "Magma Cream");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class NetherWart extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::NETHER_WART, $meta, $count, "Nether Wart");
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class Potion extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::POTION, $meta, $count, "Potion");
}
}

View File

@ -25,11 +25,11 @@ use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
class SpawnEgg extends Item{ class SpawnEgg extends Item{
@ -49,25 +49,25 @@ class SpawnEgg extends Item{
return false; return false;
} }
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $block->getX() + 0.5), new DoubleTag("", $block->getX() + 0.5),
new Double("", $block->getY()), new DoubleTag("", $block->getY()),
new Double("", $block->getZ() + 0.5) new DoubleTag("", $block->getZ() + 0.5)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", 0), new DoubleTag("", 0),
new Double("", 0), new DoubleTag("", 0),
new Double("", 0) new DoubleTag("", 0)
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", lcg_value() * 360), new FloatTag("", lcg_value() * 360),
new Float("", 0) new FloatTag("", 0)
]), ]),
]); ]);
if($this->hasCustomName()){ if($this->hasCustomName()){
$nbt->CustomName = new String("CustomName", $this->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $this->getCustomName());
} }
$entity = Entity::createEntity($this->meta, $chunk, $nbt); $entity = Entity::createEntity($this->meta, $chunk, $nbt);

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\item;
class SpiderEye extends Item {
public function __construct($meta = 0, $count =1){
parent::__construct(self::SPIDER_EYE, $meta, $count, "Spider Eye");
}
}

View File

@ -24,7 +24,7 @@ namespace pocketmine\item;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
abstract class Tool extends Item{ abstract class Tool extends Item{
const TIER_WOODEN = 1; const TIER_WOODEN = 1;

View File

@ -19,6 +19,8 @@
* *
*/ */
declare(strict_types=1);
namespace pocketmine\level; namespace pocketmine\level;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
@ -33,7 +35,7 @@ interface ChunkManager{
* *
* @return int 0-255 * @return int 0-255
*/ */
public function getBlockIdAt($x, $y, $z); public function getBlockIdAt(int $x, int $y, int $z) : int;
/** /**
* Sets the raw block id. * Sets the raw block id.
@ -43,7 +45,7 @@ interface ChunkManager{
* @param int $z * @param int $z
* @param int $id 0-255 * @param int $id 0-255
*/ */
public function setBlockIdAt($x, $y, $z, $id); public function setBlockIdAt(int $x, int $y, int $z, int $id);
/** /**
* Gets the raw block metadata * Gets the raw block metadata
@ -54,7 +56,7 @@ interface ChunkManager{
* *
* @return int 0-15 * @return int 0-15
*/ */
public function getBlockDataAt($x, $y, $z); public function getBlockDataAt(int $x, int $y, int $z) : int;
/** /**
* Sets the raw block metadata. * Sets the raw block metadata.
@ -64,27 +66,27 @@ interface ChunkManager{
* @param int $z * @param int $z
* @param int $data 0-15 * @param int $data 0-15
*/ */
public function setBlockDataAt($x, $y, $z, $data); public function setBlockDataAt(int $x, int $y, int $z, int $data);
/** /**
* @param int $chunkX * @param int $chunkX
* @param int $chunkZ * @param int $chunkZ
* *
* @return FullChunk * @return FullChunk|null
*/ */
public function getChunk($chunkX, $chunkZ); public function getChunk(int $chunkX, int $chunkZ);
/** /**
* @param int $chunkX * @param int $chunkX
* @param int $chunkZ * @param int $chunkZ
* @param FullChunk $chunk * @param FullChunk $chunk
*/ */
public function setChunk($chunkX, $chunkZ, FullChunk $chunk = null); public function setChunk(int $chunkX, int $chunkZ, FullChunk $chunk = null);
/** /**
* Gets the level seed * Gets the level seed
* *
* @return int * @return int
*/ */
public function getSeed(); public function getSeed() : int;
} }

View File

@ -32,11 +32,11 @@ use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Math; use pocketmine\math\Math;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\ExplodePacket; use pocketmine\network\protocol\ExplodePacket;
@ -63,18 +63,6 @@ class Explosion{
$this->what = $what; $this->what = $what;
} }
/**
* @deprecated
* @return bool
*/
public function explode(){
if($this->explodeA()){
return $this->explodeB();
}
return false;
}
/** /**
* @return bool * @return bool
*/ */
@ -186,22 +174,22 @@ class Explosion{
foreach($this->affectedBlocks as $block){ foreach($this->affectedBlocks as $block){
if($block->getId() === Block::TNT){ if($block->getId() === Block::TNT){
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$tnt = Entity::createEntity("PrimedTNT", $this->level->getChunk($block->x >> 4, $block->z >> 4), new Compound("", [ $tnt = Entity::createEntity("PrimedTNT", $this->level->getChunk($block->x >> 4, $block->z >> 4), new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $block->x + 0.5), new DoubleTag("", $block->x + 0.5),
new Double("", $block->y), new DoubleTag("", $block->y),
new Double("", $block->z + 0.5) new DoubleTag("", $block->z + 0.5)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", -sin($mot) * 0.02), new DoubleTag("", -sin($mot) * 0.02),
new Double("", 0.2), new DoubleTag("", 0.2),
new Double("", -cos($mot) * 0.02) new DoubleTag("", -cos($mot) * 0.02)
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", 0), new FloatTag("", 0),
new Float("", 0) new FloatTag("", 0)
]), ]),
"Fuse" => new Byte("Fuse", mt_rand(10, 30)) "Fuse" => new ByteTag("Fuse", mt_rand(10, 30))
])); ]));
$tnt->spawnToAll(); $tnt->spawnToAll();
}elseif(mt_rand(0, 100) < $yield){ }elseif(mt_rand(0, 100) < $yield){

View File

@ -19,6 +19,8 @@
* *
*/ */
declare(strict_types=1);
/** /**
* All Level related classes are here, like Generators, Populators, Noise, ... * All Level related classes are here, like Generators, Populators, Noise, ...
*/ */
@ -81,13 +83,13 @@ use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\DataPacket; use pocketmine\network\protocol\DataPacket;
use pocketmine\network\protocol\FullChunkDataPacket; use pocketmine\network\protocol\FullChunkDataPacket;
@ -266,23 +268,15 @@ class Level implements ChunkManager, Metadatable{
/** @var Generator */ /** @var Generator */
private $generatorInstance; private $generatorInstance;
/** public static function chunkHash(int $x, int $z){
* Returns the chunk unique hash/key
*
* @param int $x
* @param int $z
*
* @return string
*/
public static function chunkHash($x, $z){
return PHP_INT_SIZE === 8 ? (($x & 0xFFFFFFFF) << 32) | ($z & 0xFFFFFFFF) : $x . ":" . $z; return PHP_INT_SIZE === 8 ? (($x & 0xFFFFFFFF) << 32) | ($z & 0xFFFFFFFF) : $x . ":" . $z;
} }
public static function blockHash($x, $y, $z){ public static function blockHash(int $x, int $y, int $z){
return PHP_INT_SIZE === 8 ? (($x & 0xFFFFFFF) << 35) | (($y & 0x7f) << 28) | ($z & 0xFFFFFFF) : $x . ":" . $y .":". $z; return PHP_INT_SIZE === 8 ? (($x & 0xFFFFFFF) << 35) | (($y & 0x7f) << 28) | ($z & 0xFFFFFFF) : $x . ":" . $y .":". $z;
} }
public static function chunkBlockHash($x, $y, $z){ public static function chunkBlockHash(int $x, int $y, int $z) : int{
return ($x << 11) | ($z << 7) | $y; return ($x << 11) | ($z << 7) | $y;
} }
@ -310,7 +304,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public static function generateChunkLoaderId(ChunkLoader $loader){ public static function generateChunkLoaderId(ChunkLoader $loader) : int{
if($loader->getLoaderId() === 0 or $loader->getLoaderId() === null or $loader->getLoaderId() === null){ if($loader->getLoaderId() === 0 or $loader->getLoaderId() === null or $loader->getLoaderId() === null){
return self::$chunkLoaderCounter++; return self::$chunkLoaderCounter++;
}else{ }else{
@ -328,7 +322,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @throws \Exception * @throws \Exception
*/ */
public function __construct(Server $server, $name, $path, $provider){ public function __construct(Server $server, string $name, string $path, string $provider){
$this->blockStates = Block::$fullList; $this->blockStates = Block::$fullList;
$this->levelId = static::$levelIdCounter++; $this->levelId = static::$levelIdCounter++;
$this->blockMetadata = new BlockMetadataStore($this); $this->blockMetadata = new BlockMetadataStore($this);
@ -367,16 +361,16 @@ class Level implements ChunkManager, Metadatable{
$this->tickRate = 1; $this->tickRate = 1;
} }
public function getTickRate(){ public function getTickRate() : int{
return $this->tickRate; return $this->tickRate;
} }
public function getTickRateTime(){ public function getTickRateTime() : float{
return $this->tickRateTime; return $this->tickRateTime;
} }
public function setTickRate($tickRate){ public function setTickRate(int $tickRate){
$this->tickRate = (int) $tickRate; $this->tickRate = $tickRate;
} }
public function initLevel(){ public function initLevel(){
@ -401,33 +395,22 @@ class Level implements ChunkManager, Metadatable{
} }
} }
/** public function getBlockMetadata() : BlockMetadataStore{
* @return BlockMetadataStore
*/
public function getBlockMetadata(){
return $this->blockMetadata; return $this->blockMetadata;
} }
/** public function getServer() : Server{
* @return Server
*/
public function getServer(){
return $this->server; return $this->server;
} }
/** final public function getProvider() : LevelProvider{
* @return LevelProvider
*/
final public function getProvider(){
return $this->provider; return $this->provider;
} }
/** /**
* Returns the unique level identifier * Returns the unique level identifier
*
* @return int
*/ */
final public function getId(){ final public function getId() : int{
return $this->levelId; return $this->levelId;
} }
@ -498,17 +481,11 @@ class Level implements ChunkManager, Metadatable{
} }
} }
/** public function getAutoSave() : bool{
* @return bool
*/
public function getAutoSave(){
return $this->autoSave; return $this->autoSave;
} }
/** public function setAutoSave(bool $value){
* @param bool $value
*/
public function setAutoSave($value){
$this->autoSave = $value; $this->autoSave = $value;
} }
@ -519,7 +496,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function unload($force = false){ public function unload(bool $force = false) : bool{
$ev = new LevelUnloadEvent($this); $ev = new LevelUnloadEvent($this);
@ -552,13 +529,6 @@ class Level implements ChunkManager, Metadatable{
return true; return true;
} }
/**
* @deprecated Use Level->getChunkPlayers($chunkX, $chunkZ)
*/
public function getUsingChunk($chunkX, $chunkZ){
return $this->getChunkPlayers($chunkX, $chunkZ);
}
/** /**
* Gets the players being used in a specific chunk * Gets the players being used in a specific chunk
* *
@ -567,7 +537,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Player[] * @return Player[]
*/ */
public function getChunkPlayers($chunkX, $chunkZ){ public function getChunkPlayers(int $chunkX, int $chunkZ) : array{
return isset($this->playerLoaders[$index = Level::chunkHash($chunkX, $chunkZ)]) ? $this->playerLoaders[$index] : []; return isset($this->playerLoaders[$index = Level::chunkHash($chunkX, $chunkZ)]) ? $this->playerLoaders[$index] : [];
} }
@ -579,11 +549,11 @@ class Level implements ChunkManager, Metadatable{
* *
* @return ChunkLoader[] * @return ChunkLoader[]
*/ */
public function getChunkLoaders($chunkX, $chunkZ){ public function getChunkLoaders(int $chunkX, int $chunkZ) : array{
return isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)]) ? $this->chunkLoaders[$index] : []; return isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)]) ? $this->chunkLoaders[$index] : [];
} }
public function addChunkPacket($chunkX, $chunkZ, DataPacket $packet){ public function addChunkPacket(int $chunkX, int $chunkZ, DataPacket $packet){
if(!isset($this->chunkPackets[$index = Level::chunkHash($chunkX, $chunkZ)])){ if(!isset($this->chunkPackets[$index = Level::chunkHash($chunkX, $chunkZ)])){
$this->chunkPackets[$index] = [$packet]; $this->chunkPackets[$index] = [$packet];
}else{ }else{
@ -591,7 +561,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public function registerChunkLoader(ChunkLoader $loader, $chunkX, $chunkZ, $autoLoad = true){ public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){
$hash = $loader->getLoaderId(); $hash = $loader->getLoaderId();
if(!isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)])){ if(!isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)])){
@ -620,7 +590,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public function unregisterChunkLoader(ChunkLoader $loader, $chunkX, $chunkZ){ public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){
if(isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)][$hash = $loader->getLoaderId()])){ if(isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)][$hash = $loader->getLoaderId()])){
unset($this->chunkLoaders[$index][$hash]); unset($this->chunkLoaders[$index][$hash]);
unset($this->playerLoaders[$index][$hash]); unset($this->playerLoaders[$index][$hash]);
@ -667,9 +637,8 @@ class Level implements ChunkManager, Metadatable{
* *
* @param int $currentTick * @param int $currentTick
* *
* @return bool
*/ */
public function doTick($currentTick){ public function doTick(int $currentTick){
$this->timings->doTick->startTiming(); $this->timings->doTick->startTiming();
@ -804,7 +773,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public function sendBlockExtraData($x, $y, $z, $id, $data, array $targets = null){ public function sendBlockExtraData(int $x, int $y, int $z, int $id, int $data, array $targets = null){
$pk = new LevelEventPacket; $pk = new LevelEventPacket;
$pk->evid = LevelEventPacket::EVENT_SET_DATA; $pk->evid = LevelEventPacket::EVENT_SET_DATA;
$pk->x = $x + 0.5; $pk->x = $x + 0.5;
@ -821,7 +790,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $flags * @param int $flags
* @param bool $optimizeRebuilds * @param bool $optimizeRebuilds
*/ */
public function sendBlocks(array $target, array $blocks, $flags = UpdateBlockPacket::FLAG_NONE, $optimizeRebuilds = false){ public function sendBlocks(array $target, array $blocks, $flags = UpdateBlockPacket::FLAG_NONE, bool $optimizeRebuilds = false){
$pk = new UpdateBlockPacket(); $pk = new UpdateBlockPacket();
if($optimizeRebuilds){ if($optimizeRebuilds){
@ -862,7 +831,7 @@ class Level implements ChunkManager, Metadatable{
Server::broadcastPacket($target, $pk); Server::broadcastPacket($target, $pk);
} }
public function clearCache($full = false){ public function clearCache(bool $full = false){
if($full){ if($full){
$this->chunkCache = []; $this->chunkCache = [];
$this->blockCache = []; $this->blockCache = [];
@ -879,7 +848,7 @@ class Level implements ChunkManager, Metadatable{
} }
public function clearChunkCache($chunkX, $chunkZ){ public function clearChunkCache(int $chunkX, int $chunkZ){
unset($this->chunkCache[Level::chunkHash($chunkX, $chunkZ)]); unset($this->chunkCache[Level::chunkHash($chunkX, $chunkZ)]);
} }
@ -983,7 +952,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public function __debugInfo(){ public function __debugInfo() : array{
return []; return [];
} }
@ -992,7 +961,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function save($force = false){ public function save(bool $force = false){
if(!$this->getAutoSave() and !$force){ if(!$this->getAutoSave() and !$force){
return false; return false;
@ -1058,7 +1027,7 @@ class Level implements ChunkManager, Metadatable{
* @param Vector3 $pos * @param Vector3 $pos
* @param int $delay * @param int $delay
*/ */
public function scheduleUpdate(Vector3 $pos, $delay){ public function scheduleUpdate(Vector3 $pos, int $delay){
if(isset($this->updateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->updateQueueIndex[$index] <= $delay){ if(isset($this->updateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->updateQueueIndex[$index] <= $delay){
return; return;
} }
@ -1072,7 +1041,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Block[] * @return Block[]
*/ */
public function getCollisionBlocks(AxisAlignedBB $bb, $targetFirst = false){ public function getCollisionBlocks(AxisAlignedBB $bb, bool $targetFirst = false) : array{
$minX = Math::floorFloat($bb->minX); $minX = Math::floorFloat($bb->minX);
$minY = Math::floorFloat($bb->minY); $minY = Math::floorFloat($bb->minY);
$minZ = Math::floorFloat($bb->minZ); $minZ = Math::floorFloat($bb->minZ);
@ -1115,7 +1084,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function isFullBlock(Vector3 $pos){ public function isFullBlock(Vector3 $pos) : bool{
if($pos instanceof Block){ if($pos instanceof Block){
if($pos->isSolid()){ if($pos->isSolid()){
return true; return true;
@ -1135,7 +1104,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return AxisAlignedBB[] * @return AxisAlignedBB[]
*/ */
public function getCollisionCubes(Entity $entity, AxisAlignedBB $bb, $entities = true){ public function getCollisionCubes(Entity $entity, AxisAlignedBB $bb, bool $entities = true) : array{
$minX = Math::floorFloat($bb->minX); $minX = Math::floorFloat($bb->minX);
$minY = Math::floorFloat($bb->minY); $minY = Math::floorFloat($bb->minY);
$minZ = Math::floorFloat($bb->minZ); $minZ = Math::floorFloat($bb->minZ);
@ -1237,10 +1206,10 @@ class Level implements ChunkManager, Metadatable{
} }
*/ */
public function getFullLight(Vector3 $pos){ public function getFullLight(Vector3 $pos) : int{
$chunk = $this->getChunk($pos->x >> 4, $pos->z >> 4, false); $chunk = $this->getChunk($pos->x >> 4, $pos->z >> 4, false);
$level = 0; $level = 0;
if($chunk instanceof FullChunk){ if($chunk !== null){
$level = $chunk->getBlockSkyLight($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f); $level = $chunk->getBlockSkyLight($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f);
//TODO: decrease light level by time of day //TODO: decrease light level by time of day
if($level < 15){ if($level < 15){
@ -1258,7 +1227,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int bitmap, (id << 4) | data * @return int bitmap, (id << 4) | data
*/ */
public function getFullBlock($x, $y, $z){ public function getFullBlock(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y & 0x7f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y & 0x7f, $z & 0x0f);
} }
@ -1270,7 +1239,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Block * @return Block
*/ */
public function getBlock(Vector3 $pos, $cached = true){ public function getBlock(Vector3 $pos, $cached = true) : Block{
$index = Level::blockHash($pos->x, $pos->y, $pos->z); $index = Level::blockHash($pos->x, $pos->y, $pos->z);
if($cached and isset($this->blockCache[$index])){ if($cached and isset($this->blockCache[$index])){
return $this->blockCache[$index]; return $this->blockCache[$index];
@ -1295,11 +1264,11 @@ class Level implements ChunkManager, Metadatable{
$this->updateBlockLight($pos->x, $pos->y, $pos->z); $this->updateBlockLight($pos->x, $pos->y, $pos->z);
} }
public function updateBlockSkyLight($x, $y, $z){ public function updateBlockSkyLight(int $x, int $y, int $z){
//TODO //TODO
} }
public function updateBlockLight($x, $y, $z){ public function updateBlockLight(int $x, int $y, int $z){
$lightPropagationQueue = new \SplQueue(); $lightPropagationQueue = new \SplQueue();
$lightRemovalQueue = new \SplQueue(); $lightRemovalQueue = new \SplQueue();
$visited = []; $visited = [];
@ -1351,7 +1320,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
private function computeRemoveBlockLight($x, $y, $z, $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){ private function computeRemoveBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){
$current = $this->getBlockLightAt($x, $y, $z); $current = $this->getBlockLightAt($x, $y, $z);
if($current !== 0 and $current < $currentLight){ if($current !== 0 and $current < $currentLight){
@ -1371,7 +1340,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
private function computeSpreadBlockLight($x, $y, $z, $currentLight, \SplQueue $queue, array &$visited){ private function computeSpreadBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, array &$visited){
$current = $this->getBlockLightAt($x, $y, $z); $current = $this->getBlockLightAt($x, $y, $z);
if($current < $currentLight){ if($current < $currentLight){
@ -1404,7 +1373,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool Whether the block has been updated or not * @return bool Whether the block has been updated or not
*/ */
public function setBlock(Vector3 $pos, Block $block, $direct = false, $update = true){ public function setBlock(Vector3 $pos, Block $block, bool $direct = false, bool $update = true) : bool{
if($pos->y < 0 or $pos->y >= 128){ if($pos->y < 0 or $pos->y >= 128){
return false; return false;
} }
@ -1460,31 +1429,31 @@ class Level implements ChunkManager, Metadatable{
* @param Vector3 $motion * @param Vector3 $motion
* @param int $delay * @param int $delay
*/ */
public function dropItem(Vector3 $source, Item $item, Vector3 $motion = null, $delay = 10){ public function dropItem(Vector3 $source, Item $item, Vector3 $motion = null, int $delay = 10){
$motion = $motion === null ? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1) : $motion; $motion = $motion === null ? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1) : $motion;
$itemTag = NBT::putItemHelper($item); $itemTag = NBT::putItemHelper($item);
$itemTag->setName("Item"); $itemTag->setName("Item");
if($item->getId() > 0 and $item->getCount() > 0){ if($item->getId() > 0 and $item->getCount() > 0){
$itemEntity = Entity::createEntity("Item", $this->getChunk($source->getX() >> 4, $source->getZ() >> 4, true), new Compound("", [ $itemEntity = Entity::createEntity("Item", $this->getChunk($source->getX() >> 4, $source->getZ() >> 4, true), new CompoundTag("", [
"Pos" => new Enum("Pos", [ "Pos" => new ListTag("Pos", [
new Double("", $source->getX()), new DoubleTag("", $source->getX()),
new Double("", $source->getY()), new DoubleTag("", $source->getY()),
new Double("", $source->getZ()) new DoubleTag("", $source->getZ())
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new ListTag("Motion", [
new Double("", $motion->x), new DoubleTag("", $motion->x),
new Double("", $motion->y), new DoubleTag("", $motion->y),
new Double("", $motion->z) new DoubleTag("", $motion->z)
]), ]),
"Rotation" => new Enum("Rotation", [ "Rotation" => new ListTag("Rotation", [
new Float("", lcg_value() * 360), new FloatTag("", lcg_value() * 360),
new Float("", 0) new FloatTag("", 0)
]), ]),
"Health" => new Short("Health", 5), "Health" => new ShortTag("Health", 5),
"Item" => $itemTag, "Item" => $itemTag,
"PickupDelay" => new Short("PickupDelay", $delay) "PickupDelay" => new ShortTag("PickupDelay", $delay)
])); ]));
$itemEntity->spawnToAll(); $itemEntity->spawnToAll();
@ -1500,9 +1469,9 @@ class Level implements ChunkManager, Metadatable{
* @param Player $player * @param Player $player
* @param bool $createParticles * @param bool $createParticles
* *
* @return boolean * @return boole
*/ */
public function useBreakOn(Vector3 $vector, Item &$item = null, Player $player = null, $createParticles = false){ public function useBreakOn(Vector3 $vector, Item &$item = null, Player $player = null, bool $createParticles = false) : bool{
$target = $this->getBlock($vector); $target = $this->getBlock($vector);
//TODO: Adventure mode checks //TODO: Adventure mode checks
@ -1568,10 +1537,10 @@ class Level implements ChunkManager, Metadatable{
} }
$tag = $item->getNamedTagEntry("CanDestroy"); $tag = $item->getNamedTagEntry("CanDestroy");
if($tag instanceof Enum){ if($tag instanceof ListTag){
$canBreak = false; $canBreak = false;
foreach($tag as $v){ foreach($tag as $v){
if($v instanceof String){ if($v instanceof StringTag){
$entry = Item::fromString($v->getValue()); $entry = Item::fromString($v->getValue());
if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){ if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){
$canBreak = true; $canBreak = true;
@ -1640,9 +1609,9 @@ class Level implements ChunkManager, Metadatable{
* @param float $fz default 0.0 * @param float $fz default 0.0
* @param Player $player default null * @param Player $player default null
* *
* @return boolean * @return bool
*/ */
public function useItemOn(Vector3 $vector, Item &$item, $face, $fx = 0.0, $fy = 0.0, $fz = 0.0, Player $player = null){ public function useItemOn(Vector3 $vector, Item &$item, int $face, float $fx = 0.0, float $fy = 0.0, float $fz = 0.0, Player $player = null) : bool{
$target = $this->getBlock($vector); $target = $this->getBlock($vector);
$block = $target->getSide($face); $block = $target->getSide($face);
@ -1730,10 +1699,10 @@ class Level implements ChunkManager, Metadatable{
} }
$tag = $item->getNamedTagEntry("CanPlaceOn"); $tag = $item->getNamedTagEntry("CanPlaceOn");
if($tag instanceof Enum){ if($tag instanceof ListTag){
$canPlace = false; $canPlace = false;
foreach($tag as $v){ foreach($tag as $v){
if($v instanceof String){ if($v instanceof StringTag){
$entry = Item::fromString($v->getValue()); $entry = Item::fromString($v->getValue());
if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){ if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){
$canPlace = true; $canPlace = true;
@ -1769,19 +1738,19 @@ class Level implements ChunkManager, Metadatable{
if($hand->getId() === Item::SIGN_POST or $hand->getId() === Item::WALL_SIGN){ if($hand->getId() === Item::SIGN_POST or $hand->getId() === Item::WALL_SIGN){
$nbt = new Compound("", [ $nbt = new CompoundTag("", [
"id" => new String("id", Tile::SIGN), "id" => new StringTag("id", Tile::SIGN),
"x" => new Int("x", $block->x), "x" => new IntTag("x", $block->x),
"y" => new Int("y", $block->y), "y" => new IntTag("y", $block->y),
"z" => new Int("z", $block->z), "z" => new IntTag("z", $block->z),
"Text1" => new String("Text1", ""), "Text1" => new StringTag("Text1", ""),
"Text2" => new String("Text2", ""), "Text2" => new StringTag("Text2", ""),
"Text3" => new String("Text3", ""), "Text3" => new StringTag("Text3", ""),
"Text4" => new String("Text4", "") "Text4" => new StringTag("Text4", "")
]); ]);
if($player !== null){ if($player !== null){
$nbt->Creator = new String("Creator", $player->getRawUniqueId()); $nbt->Creator = new StringTag("Creator", $player->getRawUniqueId());
} }
if($item->hasCustomBlockData()){ if($item->hasCustomBlockData()){
@ -1805,7 +1774,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Entity * @return Entity
*/ */
public function getEntity($entityId){ public function getEntity(int $entityId){
return isset($this->entities[$entityId]) ? $this->entities[$entityId] : null; return isset($this->entities[$entityId]) ? $this->entities[$entityId] : null;
} }
@ -1814,7 +1783,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Entity[] * @return Entity[]
*/ */
public function getEntities(){ public function getEntities() : array{
return $this->entities; return $this->entities;
} }
@ -1826,7 +1795,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Entity[] * @return Entity[]
*/ */
public function getCollidingEntities(AxisAlignedBB $bb, Entity $entity = null){ public function getCollidingEntities(AxisAlignedBB $bb, Entity $entity = null) : array{
$nearby = []; $nearby = [];
if($entity === null or $entity->canCollide){ if($entity === null or $entity->canCollide){
@ -1857,7 +1826,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Entity[] * @return Entity[]
*/ */
public function getNearbyEntities(AxisAlignedBB $bb, Entity $entity = null){ public function getNearbyEntities(AxisAlignedBB $bb, Entity $entity = null) : array{
$nearby = []; $nearby = [];
$minX = Math::floorFloat(($bb->minX - 2) / 16); $minX = Math::floorFloat(($bb->minX - 2) / 16);
@ -1883,7 +1852,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Tile[] * @return Tile[]
*/ */
public function getTiles(){ public function getTiles() : array{
return $this->tiles; return $this->tiles;
} }
@ -1892,7 +1861,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Tile * @return Tile
*/ */
public function getTileById($tileId){ public function getTileById(int $tileId){
return isset($this->tiles[$tileId]) ? $this->tiles[$tileId] : null; return isset($this->tiles[$tileId]) ? $this->tiles[$tileId] : null;
} }
@ -1901,14 +1870,14 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Player[] * @return Player[]
*/ */
public function getPlayers(){ public function getPlayers() : array{
return $this->players; return $this->players;
} }
/** /**
* @return ChunkLoader[] * @return ChunkLoader[]
*/ */
public function getLoaders(){ public function getLoaders() : array{
return $this->loaders; return $this->loaders;
} }
@ -1937,7 +1906,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Entity[] * @return Entity[]
*/ */
public function getChunkEntities($X, $Z){ public function getChunkEntities($X, $Z) : array{
return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getEntities() : []; return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getEntities() : [];
} }
@ -1949,7 +1918,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Tile[] * @return Tile[]
*/ */
public function getChunkTiles($X, $Z){ public function getChunkTiles($X, $Z) : array{
return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getTiles() : []; return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getTiles() : [];
} }
@ -1962,7 +1931,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int 0-255 * @return int 0-255
*/ */
public function getBlockIdAt($x, $y, $z){ public function getBlockIdAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockId($x & 0x0f, $y & 0x7f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBlockId($x & 0x0f, $y & 0x7f, $z & 0x0f);
} }
@ -1974,7 +1943,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $z * @param int $z
* @param int $id 0-255 * @param int $id 0-255
*/ */
public function setBlockIdAt($x, $y, $z, $id){ public function setBlockIdAt(int $x, int $y, int $z, int $id){
unset($this->blockCache[Level::blockHash($x, $y, $z)]); unset($this->blockCache[Level::blockHash($x, $y, $z)]);
$this->getChunk($x >> 4, $z >> 4, true)->setBlockId($x & 0x0f, $y & 0x7f, $z & 0x0f, $id & 0xff); $this->getChunk($x >> 4, $z >> 4, true)->setBlockId($x & 0x0f, $y & 0x7f, $z & 0x0f, $id & 0xff);
@ -1996,7 +1965,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int 16-bit * @return int 16-bit
*/ */
public function getBlockExtraDataAt($x, $y, $z){ public function getBlockExtraDataAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockExtraData($x & 0x0f, $y & 0x7f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBlockExtraData($x & 0x0f, $y & 0x7f, $z & 0x0f);
} }
@ -2009,7 +1978,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $id * @param int $id
* @param int $data * @param int $data
*/ */
public function setBlockExtraDataAt($x, $y, $z, $id, $data){ public function setBlockExtraDataAt(int $x, int $y, int $z, int $id, int $data){
$this->getChunk($x >> 4, $z >> 4, true)->setBlockExtraData($x & 0x0f, $y & 0x7f, $z & 0x0f, ($data << 8) | $id); $this->getChunk($x >> 4, $z >> 4, true)->setBlockExtraData($x & 0x0f, $y & 0x7f, $z & 0x0f, ($data << 8) | $id);
$this->sendBlockExtraData($x, $y, $z, $id, $data); $this->sendBlockExtraData($x, $y, $z, $id, $data);
@ -2024,7 +1993,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int 0-15 * @return int 0-15
*/ */
public function getBlockDataAt($x, $y, $z){ public function getBlockDataAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockData($x & 0x0f, $y & 0x7f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBlockData($x & 0x0f, $y & 0x7f, $z & 0x0f);
} }
@ -2036,7 +2005,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $z * @param int $z
* @param int $data 0-15 * @param int $data 0-15
*/ */
public function setBlockDataAt($x, $y, $z, $data){ public function setBlockDataAt(int $x, int $y, int $z, int $data){
unset($this->blockCache[Level::blockHash($x, $y, $z)]); unset($this->blockCache[Level::blockHash($x, $y, $z)]);
$this->getChunk($x >> 4, $z >> 4, true)->setBlockData($x & 0x0f, $y & 0x7f, $z & 0x0f, $data & 0x0f); $this->getChunk($x >> 4, $z >> 4, true)->setBlockData($x & 0x0f, $y & 0x7f, $z & 0x0f, $data & 0x0f);
@ -2058,7 +2027,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int 0-15 * @return int 0-15
*/ */
public function getBlockSkyLightAt($x, $y, $z){ public function getBlockSkyLightAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y & 0x7f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y & 0x7f, $z & 0x0f);
} }
@ -2070,7 +2039,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $z * @param int $z
* @param int $level 0-15 * @param int $level 0-15
*/ */
public function setBlockSkyLightAt($x, $y, $z, $level){ public function setBlockSkyLightAt(int $x, int $y, int $z, int $level){
$this->getChunk($x >> 4, $z >> 4, true)->setBlockSkyLight($x & 0x0f, $y & 0x7f, $z & 0x0f, $level & 0x0f); $this->getChunk($x >> 4, $z >> 4, true)->setBlockSkyLight($x & 0x0f, $y & 0x7f, $z & 0x0f, $level & 0x0f);
} }
@ -2083,7 +2052,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int 0-15 * @return int 0-15
*/ */
public function getBlockLightAt($x, $y, $z){ public function getBlockLightAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y & 0x7f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y & 0x7f, $z & 0x0f);
} }
@ -2095,7 +2064,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $z * @param int $z
* @param int $level 0-15 * @param int $level 0-15
*/ */
public function setBlockLightAt($x, $y, $z, $level){ public function setBlockLightAt(int $x, int $y, int $z, int $level){
$this->getChunk($x >> 4, $z >> 4, true)->setBlockLight($x & 0x0f, $y & 0x7f, $z & 0x0f, $level & 0x0f); $this->getChunk($x >> 4, $z >> 4, true)->setBlockLight($x & 0x0f, $y & 0x7f, $z & 0x0f, $level & 0x0f);
} }
@ -2105,7 +2074,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int * @return int
*/ */
public function getBiomeId($x, $z){ public function getBiomeId(int $x, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f);
} }
@ -2115,7 +2084,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int[] * @return int[]
*/ */
public function getBiomeColor($x, $z){ public function getBiomeColor(int $x, int $z) : array{
return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeColor($x & 0x0f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeColor($x & 0x0f, $z & 0x0f);
} }
@ -2125,7 +2094,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int * @return int
*/ */
public function getHeightMap($x, $z){ public function getHeightMap(int $x, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getHeightMap($x & 0x0f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getHeightMap($x & 0x0f, $z & 0x0f);
} }
@ -2134,7 +2103,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $z * @param int $z
* @param int $biomeId * @param int $biomeId
*/ */
public function setBiomeId($x, $z, $biomeId){ public function setBiomeId(int $x, int $z, int $biomeId){
$this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); $this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId);
} }
@ -2145,7 +2114,7 @@ class Level implements ChunkManager, Metadatable{
* @param int $G * @param int $G
* @param int $B * @param int $B
*/ */
public function setBiomeColor($x, $z, $R, $G, $B){ public function setBiomeColor(int $x, int $z, int $R, int $G, int $B){
$this->getChunk($x >> 4, $z >> 4, true)->setBiomeColor($x & 0x0f, $z & 0x0f, $R, $G, $B); $this->getChunk($x >> 4, $z >> 4, true)->setBiomeColor($x & 0x0f, $z & 0x0f, $R, $G, $B);
} }
@ -2154,14 +2123,14 @@ class Level implements ChunkManager, Metadatable{
* @param int $z * @param int $z
* @param int $value * @param int $value
*/ */
public function setHeightMap($x, $z, $value){ public function setHeightMap(int $x, int $z, int $value){
$this->getChunk($x >> 4, $z >> 4, true)->setHeightMap($x & 0x0f, $z & 0x0f, $value); $this->getChunk($x >> 4, $z >> 4, true)->setHeightMap($x & 0x0f, $z & 0x0f, $value);
} }
/** /**
* @return FullChunk[]|Chunk[] * @return FullChunk[]|Chunk[]
*/ */
public function getChunks(){ public function getChunks() : array{
return $this->chunks; return $this->chunks;
} }
@ -2174,7 +2143,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return FullChunk|Chunk * @return FullChunk|Chunk
*/ */
public function getChunk($x, $z, $create = false){ public function getChunk(int $x, int $z, bool $create = false){
if(isset($this->chunks[$index = Level::chunkHash($x, $z)])){ if(isset($this->chunks[$index = Level::chunkHash($x, $z)])){
return $this->chunks[$index]; return $this->chunks[$index];
}elseif($this->loadChunk($x, $z, $create)){ }elseif($this->loadChunk($x, $z, $create)){
@ -2184,20 +2153,7 @@ class Level implements ChunkManager, Metadatable{
return null; return null;
} }
/** public function generateChunkCallback(int $x, int $z, FullChunk $chunk){
* @param int $x
* @param int $z
* @param bool $create
*
* @return FullChunk|Chunk
*
* @deprecated
*/
public function getChunkAt($x, $z, $create = false){
return $this->getChunk($x, $z, $create);
}
public function generateChunkCallback($x, $z, FullChunk $chunk){
Timings::$generationCallbackTimer->startTiming(); Timings::$generationCallbackTimer->startTiming();
if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)])){ if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)])){
$oldChunk = $this->getChunk($x, $z, false); $oldChunk = $this->getChunk($x, $z, false);
@ -2235,7 +2191,7 @@ class Level implements ChunkManager, Metadatable{
* @param FullChunk $chunk * @param FullChunk $chunk
* @param bool $unload * @param bool $unload
*/ */
public function setChunk($chunkX, $chunkZ, FullChunk $chunk = null, $unload = true){ public function setChunk(int $chunkX, int $chunkZ, FullChunk $chunk = null, bool $unload = true){
if($chunk === null){ if($chunk === null){
return; return;
} }
@ -2284,7 +2240,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int 0-127 * @return int 0-127
*/ */
public function getHighestBlockAt($x, $z){ public function getHighestBlockAt(int $x, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f); return $this->getChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f);
} }
@ -2294,7 +2250,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function isChunkLoaded($x, $z){ public function isChunkLoaded(int $x, int $z) : bool{
return isset($this->chunks[Level::chunkHash($x, $z)]) or $this->provider->isChunkLoaded($x, $z); return isset($this->chunks[Level::chunkHash($x, $z)]) or $this->provider->isChunkLoaded($x, $z);
} }
@ -2304,7 +2260,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function isChunkGenerated($x, $z){ public function isChunkGenerated(int $x, int $z) : bool{
$chunk = $this->getChunk($x, $z); $chunk = $this->getChunk($x, $z);
return $chunk !== null ? $chunk->isGenerated() : false; return $chunk !== null ? $chunk->isGenerated() : false;
} }
@ -2315,7 +2271,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function isChunkPopulated($x, $z){ public function isChunkPopulated(int $x, int $z) : bool{
$chunk = $this->getChunk($x, $z); $chunk = $this->getChunk($x, $z);
return $chunk !== null ? $chunk->isPopulated() : false; return $chunk !== null ? $chunk->isPopulated() : false;
} }
@ -2325,7 +2281,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return Position * @return Position
*/ */
public function getSpawnLocation(){ public function getSpawnLocation() : Position{
return Position::fromObject($this->provider->getSpawn(), $this); return Position::fromObject($this->provider->getSpawn(), $this);
} }
@ -2340,7 +2296,7 @@ class Level implements ChunkManager, Metadatable{
$this->server->getPluginManager()->callEvent(new SpawnChangeEvent($this, $previousSpawn)); $this->server->getPluginManager()->callEvent(new SpawnChangeEvent($this, $previousSpawn));
} }
public function requestChunk($x, $z, Player $player){ public function requestChunk(int $x, int $z, Player $player){
$index = Level::chunkHash($x, $z); $index = Level::chunkHash($x, $z);
if(!isset($this->chunkSendQueue[$index])){ if(!isset($this->chunkSendQueue[$index])){
$this->chunkSendQueue[$index] = []; $this->chunkSendQueue[$index] = [];
@ -2349,7 +2305,7 @@ class Level implements ChunkManager, Metadatable{
$this->chunkSendQueue[$index][$player->getLoaderId()] = $player; $this->chunkSendQueue[$index][$player->getLoaderId()] = $player;
} }
private function sendChunkFromCache($x, $z){ private function sendChunkFromCache(int $x, int $z){
if(isset($this->chunkSendTasks[$index = Level::chunkHash($x, $z)])){ if(isset($this->chunkSendTasks[$index = Level::chunkHash($x, $z)])){
foreach($this->chunkSendQueue[$index] as $player){ foreach($this->chunkSendQueue[$index] as $player){
/** @var Player $player */ /** @var Player $player */
@ -2390,7 +2346,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public function chunkRequestCallback($x, $z, $payload, $ordering = FullChunkDataPacket::ORDER_COLUMNS){ public function chunkRequestCallback(int $x, int $z, string $payload, int $ordering = FullChunkDataPacket::ORDER_COLUMNS){
$this->timings->syncChunkSendTimer->startTiming(); $this->timings->syncChunkSendTimer->startTiming();
$index = Level::chunkHash($x, $z); $index = Level::chunkHash($x, $z);
@ -2487,7 +2443,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function isChunkInUse($x, $z){ public function isChunkInUse(int $x, int $z) : bool{
return isset($this->chunkLoaders[$index = Level::chunkHash($x, $z)]) and count($this->chunkLoaders[$index]) > 0; return isset($this->chunkLoaders[$index = Level::chunkHash($x, $z)]) and count($this->chunkLoaders[$index]) > 0;
} }
@ -2500,7 +2456,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @throws \InvalidStateException * @throws \InvalidStateException
*/ */
public function loadChunk($x, $z, $generate = true){ public function loadChunk(int $x, int $z, bool $generate = true) : bool{
if(isset($this->chunks[$index = Level::chunkHash($x, $z)])){ if(isset($this->chunks[$index = Level::chunkHash($x, $z)])){
return true; return true;
} }
@ -2545,12 +2501,12 @@ class Level implements ChunkManager, Metadatable{
return true; return true;
} }
private function queueUnloadChunk($x, $z){ private function queueUnloadChunk(int $x, int $z){
$this->unloadQueue[$index = Level::chunkHash($x, $z)] = microtime(true); $this->unloadQueue[$index = Level::chunkHash($x, $z)] = microtime(true);
unset($this->chunkTickList[$index]); unset($this->chunkTickList[$index]);
} }
public function unloadChunkRequest($x, $z, $safe = true){ public function unloadChunkRequest(int $x, int $z, bool $safe = true){
if(($safe === true and $this->isChunkInUse($x, $z)) or $this->isSpawnChunk($x, $z)){ if(($safe === true and $this->isChunkInUse($x, $z)) or $this->isSpawnChunk($x, $z)){
return false; return false;
} }
@ -2560,11 +2516,11 @@ class Level implements ChunkManager, Metadatable{
return true; return true;
} }
public function cancelUnloadChunkRequest($x, $z){ public function cancelUnloadChunkRequest(int $x, int $z){
unset($this->unloadQueue[Level::chunkHash($x, $z)]); unset($this->unloadQueue[Level::chunkHash($x, $z)]);
} }
public function unloadChunk($x, $z, $safe = true, $trySave = true){ public function unloadChunk(int $x, int $z, bool $safe = true, bool $trySave = true) : bool{
if(($safe === true and $this->isChunkInUse($x, $z))){ if(($safe === true and $this->isChunkInUse($x, $z))){
return false; return false;
} }
@ -2609,12 +2565,10 @@ class Level implements ChunkManager, Metadatable{
} }
} }
$this->provider->unloadChunk($x, $z, $safe); $this->provider->unloadChunk($x, $z, $safe);
}catch(\Exception $e){ }catch(\Throwable $e){
$logger = $this->server->getLogger(); $logger = $this->server->getLogger();
$logger->error($this->server->getLanguage()->translateString("pocketmine.level.chunkUnloadError", [$e->getMessage()])); $logger->error($this->server->getLanguage()->translateString("pocketmine.level.chunkUnloadError", [$e->getMessage()]));
if($logger instanceof MainLogger){ $logger->logException($e);
$logger->logException($e);
}
} }
unset($this->chunks[$index]); unset($this->chunks[$index]);
@ -2634,23 +2588,13 @@ class Level implements ChunkManager, Metadatable{
* *
* @return bool * @return bool
*/ */
public function isSpawnChunk($X, $Z){ public function isSpawnChunk(int $X, int $Z) : bool{
$spawnX = $this->provider->getSpawn()->getX() >> 4; $spawnX = $this->provider->getSpawn()->getX() >> 4;
$spawnZ = $this->provider->getSpawn()->getZ() >> 4; $spawnZ = $this->provider->getSpawn()->getZ() >> 4;
return abs($X - $spawnX) <= 1 and abs($Z - $spawnZ) <= 1; return abs($X - $spawnX) <= 1 and abs($Z - $spawnZ) <= 1;
} }
/**
* Returns the raw spawnpoint
*
* @deprecated
* @return Position
*/
public function getSpawn(){
return $this->getSpawnLocation();
}
/** /**
* @param Vector3 $spawn default null * @param Vector3 $spawn default null
* *
@ -2704,23 +2648,12 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
/**
* Sets the spawnpoint
*
* @param Vector3 $pos
*
* @deprecated
*/
public function setSpawn(Vector3 $pos){
$this->setSpawnLocation($pos);
}
/** /**
* Gets the current time * Gets the current time
* *
* @return int * @return int
*/ */
public function getTime(){ public function getTime() : int{
return (int) $this->time; return (int) $this->time;
} }
@ -2729,7 +2662,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return string * @return string
*/ */
public function getName(){ public function getName() : string{
return $this->provider->getName(); return $this->provider->getName();
} }
@ -2738,7 +2671,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return string * @return string
*/ */
public function getFolderName(){ public function getFolderName() : string{
return $this->folderName; return $this->folderName;
} }
@ -2747,8 +2680,8 @@ class Level implements ChunkManager, Metadatable{
* *
* @param int $time * @param int $time
*/ */
public function setTime($time){ public function setTime(int $time){
$this->time = (int) $time; $this->time = $time;
$this->sendTime(); $this->sendTime();
} }
@ -2773,7 +2706,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int * @return int
*/ */
public function getSeed(){ public function getSeed() : int{
return $this->provider->getSeed(); return $this->provider->getSeed();
} }
@ -2782,12 +2715,12 @@ class Level implements ChunkManager, Metadatable{
* *
* @param int $seed * @param int $seed
*/ */
public function setSeed($seed){ public function setSeed(int $seed){
$this->provider->setSeed($seed); $this->provider->setSeed($seed);
} }
public function populateChunk($x, $z, $force = false){ public function populateChunk(int $x, int $z, bool $force = false) : bool{
if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){
return false; return false;
} }
@ -2825,7 +2758,7 @@ class Level implements ChunkManager, Metadatable{
return true; return true;
} }
public function generateChunk($x, $z, $force = false){ public function generateChunk(int $x, int $z, bool $force = false){
if(count($this->chunkGenerationQueue) >= $this->chunkGenerationQueueSize and !$force){ if(count($this->chunkGenerationQueue) >= $this->chunkGenerationQueueSize and !$force){
return; return;
} }
@ -2839,7 +2772,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
public function regenerateChunk($x, $z){ public function regenerateChunk(int $x, int $z){
$this->unloadChunk($x, $z, false); $this->unloadChunk($x, $z, false);
$this->cancelUnloadChunkRequest($x, $z); $this->cancelUnloadChunkRequest($x, $z);
@ -2874,7 +2807,7 @@ class Level implements ChunkManager, Metadatable{
$this->timings->doChunkGC->stopTiming(); $this->timings->doChunkGC->stopTiming();
} }
public function unloadChunks($force = false){ public function unloadChunks(bool $force = false){
if(count($this->unloadQueue) > 0){ if(count($this->unloadQueue) > 0){
$maxUnload = 96; $maxUnload = 96;
$now = microtime(true); $now = microtime(true);
@ -2914,14 +2847,14 @@ class Level implements ChunkManager, Metadatable{
$this->server->getLevelMetadata()->removeMetadata($this, $metadataKey, $plugin); $this->server->getLevelMetadata()->removeMetadata($this, $metadataKey, $plugin);
} }
public function addEntityMotion($chunkX, $chunkZ, $entityId, $x, $y, $z){ public function addEntityMotion(int $chunkX, int $chunkZ, int $entityId, float $x, float $y, float $z){
if(!isset($this->motionToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){ if(!isset($this->motionToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){
$this->motionToSend[$index] = []; $this->motionToSend[$index] = [];
} }
$this->motionToSend[$index][$entityId] = [$entityId, $x, $y, $z]; $this->motionToSend[$index][$entityId] = [$entityId, $x, $y, $z];
} }
public function addEntityMovement($chunkX, $chunkZ, $entityId, $x, $y, $z, $yaw, $pitch, $headYaw = null){ public function addEntityMovement(int $chunkX, int $chunkZ, int $entityId, float $x, float $y, float $z, float $yaw, float $pitch, $headYaw = null){
if(!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){ if(!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){
$this->moveToSend[$index] = []; $this->moveToSend[$index] = [];
} }

View File

@ -67,30 +67,6 @@ class Position extends Vector3{
return $this->level !== null; return $this->level !== null;
} }
/**
* Marks the level reference as strong so it won't be collected
* by the garbage collector.
*
* @deprecated
*
* @return bool
*/
public function setStrong(){
return false;
}
/**
* Marks the level reference as weak so it won't have effect against
* the garbage collector decision.
*
* @deprecated
*
* @return bool
*/
public function setWeak(){
return false;
}
/** /**
* Returns a side Vector * Returns a side Vector
* *
@ -102,9 +78,7 @@ class Position extends Vector3{
* @throws LevelException * @throws LevelException
*/ */
public function getSide($side, $step = 1){ public function getSide($side, $step = 1){
if(!$this->isValid()){ assert($this->isValid());
throw new LevelException("Undefined Level reference");
}
return Position::fromObject(parent::getSide($side, $step), $this->level); return Position::fromObject(parent::getSide($side, $step), $this->level);
} }

View File

@ -19,6 +19,8 @@
* *
*/ */
declare(strict_types=1);
namespace pocketmine\level; namespace pocketmine\level;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
@ -43,7 +45,7 @@ class SimpleChunkManager implements ChunkManager{
* *
* @return int 0-255 * @return int 0-255
*/ */
public function getBlockIdAt($x, $y, $z){ public function getBlockIdAt(int $x, int $y, int $z) : int{
if($chunk = $this->getChunk($x >> 4, $z >> 4)){ if($chunk = $this->getChunk($x >> 4, $z >> 4)){
return $chunk->getBlockId($x & 0xf, $y & 0x7f, $z & 0xf); return $chunk->getBlockId($x & 0xf, $y & 0x7f, $z & 0xf);
} }
@ -58,7 +60,7 @@ class SimpleChunkManager implements ChunkManager{
* @param int $z * @param int $z
* @param int $id 0-255 * @param int $id 0-255
*/ */
public function setBlockIdAt($x, $y, $z, $id){ public function setBlockIdAt(int $x, int $y, int $z, int $id){
if($chunk = $this->getChunk($x >> 4, $z >> 4)){ if($chunk = $this->getChunk($x >> 4, $z >> 4)){
$chunk->setBlockId($x & 0xf, $y & 0x7f, $z & 0xf, $id); $chunk->setBlockId($x & 0xf, $y & 0x7f, $z & 0xf, $id);
} }
@ -73,7 +75,7 @@ class SimpleChunkManager implements ChunkManager{
* *
* @return int 0-15 * @return int 0-15
*/ */
public function getBlockDataAt($x, $y, $z){ public function getBlockDataAt(int $x, int $y, int $z) : int{
if($chunk = $this->getChunk($x >> 4, $z >> 4)){ if($chunk = $this->getChunk($x >> 4, $z >> 4)){
return $chunk->getBlockData($x & 0xf, $y & 0x7f, $z & 0xf); return $chunk->getBlockData($x & 0xf, $y & 0x7f, $z & 0xf);
} }
@ -88,7 +90,7 @@ class SimpleChunkManager implements ChunkManager{
* @param int $z * @param int $z
* @param int $data 0-15 * @param int $data 0-15
*/ */
public function setBlockDataAt($x, $y, $z, $data){ public function setBlockDataAt(int $x, int $y, int $z, int $data){
if($chunk = $this->getChunk($x >> 4, $z >> 4)){ if($chunk = $this->getChunk($x >> 4, $z >> 4)){
$chunk->setBlockData($x & 0xf, $y & 0x7f, $z & 0xf, $data); $chunk->setBlockData($x & 0xf, $y & 0x7f, $z & 0xf, $data);
} }
@ -98,9 +100,9 @@ class SimpleChunkManager implements ChunkManager{
* @param int $chunkX * @param int $chunkX
* @param int $chunkZ * @param int $chunkZ
* *
* @return FullChunk * @return FullChunk|null
*/ */
public function getChunk($chunkX, $chunkZ){ public function getChunk(int $chunkX, int $chunkZ){
return isset($this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)]) ? $this->chunks[$index] : null; return isset($this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)]) ? $this->chunks[$index] : null;
} }
@ -109,7 +111,7 @@ class SimpleChunkManager implements ChunkManager{
* @param int $chunkZ * @param int $chunkZ
* @param FullChunk $chunk * @param FullChunk $chunk
*/ */
public function setChunk($chunkX, $chunkZ, FullChunk $chunk = null){ public function setChunk(int $chunkX, int $chunkZ, FullChunk $chunk = null){
if($chunk === null){ if($chunk === null){
unset($this->chunks[Level::chunkHash($chunkX, $chunkZ)]); unset($this->chunks[Level::chunkHash($chunkX, $chunkZ)]);
return; return;
@ -126,7 +128,7 @@ class SimpleChunkManager implements ChunkManager{
* *
* @return int * @return int
*/ */
public function getSeed(){ public function getSeed() : int{
return $this->seed; return $this->seed;
} }
} }

View File

@ -62,19 +62,6 @@ interface ChunkSection{
*/ */
public function setBlockData($x, $y, $z, $data); public function setBlockData($x, $y, $z, $data);
/**
* Modifies $blockId and $meta
*
* @deprecated
*
* @param int $x 0-15
* @param int $y 0-15
* @param int $z 0-15
* @param int &$blockId
* @param int &$meta
*/
public function getBlock($x, $y, $z, &$blockId, &$meta = null);
/** /**
* Gets block and meta in one go * Gets block and meta in one go
* *

View File

@ -50,20 +50,6 @@ interface FullChunk{
*/ */
public function setProvider(LevelProvider $provider); public function setProvider(LevelProvider $provider);
/**
* Modifies $blockId and $meta
*
* @deprecated
*
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
* @param int &$blockId
* @param int &$meta
*/
public function getBlock($x, $y, $z, &$blockId, &$meta = null);
/** /**
* Gets block and meta in one go * Gets block and meta in one go
* *

View File

@ -25,9 +25,9 @@ use pocketmine\level\format\FullChunk;
use pocketmine\level\format\mcregion\McRegion; use pocketmine\level\format\mcregion\McRegion;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\ByteArray; use pocketmine\nbt\tag\ByteArrayTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\protocol\FullChunkDataPacket; use pocketmine\network\protocol\FullChunkDataPacket;
use pocketmine\tile\Spawnable; use pocketmine\tile\Spawnable;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
@ -152,12 +152,12 @@ class Anvil extends McRegion{
} }
public static function createChunkSection($Y){ public static function createChunkSection($Y){
return new ChunkSection(new Compound("", [ return new ChunkSection(new CompoundTag("", [
"Y" => new Byte("Y", $Y), "Y" => new ByteTag("Y", $Y),
"Blocks" => new ByteArray("Blocks", str_repeat("\x00", 4096)), "Blocks" => new ByteArrayTag("Blocks", str_repeat("\x00", 4096)),
"Data" => new ByteArray("Data", str_repeat("\x00", 2048)), "Data" => new ByteArrayTag("Data", str_repeat("\x00", 2048)),
"SkyLight" => new ByteArray("SkyLight", str_repeat("\xff", 2048)), "SkyLight" => new ByteArrayTag("SkyLight", str_repeat("\xff", 2048)),
"BlockLight" => new ByteArray("BlockLight", str_repeat("\x00", 2048)) "BlockLight" => new ByteArrayTag("BlockLight", str_repeat("\x00", 2048))
])); ]));
} }

View File

@ -25,62 +25,62 @@ use pocketmine\level\format\generic\BaseChunk;
use pocketmine\level\format\generic\EmptyChunkSection; use pocketmine\level\format\generic\EmptyChunkSection;
use pocketmine\level\format\LevelProvider; use pocketmine\level\format\LevelProvider;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\ByteArray; use pocketmine\nbt\tag\ByteArrayTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\IntArray; use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\LongTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
class Chunk extends BaseChunk{ class Chunk extends BaseChunk{
/** @var Compound */ /** @var CompoundTag */
protected $nbt; protected $nbt;
public function __construct($level, Compound $nbt = null){ public function __construct($level, CompoundTag $nbt = null){
if($nbt === null){ if($nbt === null){
$this->provider = $level; $this->provider = $level;
$this->nbt = new Compound("Level", []); $this->nbt = new CompoundTag("Level", []);
return; return;
} }
$this->nbt = $nbt; $this->nbt = $nbt;
if(!isset($this->nbt->Entities) or !($this->nbt->Entities instanceof Enum)){ if(!isset($this->nbt->Entities) or !($this->nbt->Entities instanceof ListTag)){
$this->nbt->Entities = new Enum("Entities", []); $this->nbt->Entities = new ListTag("Entities", []);
$this->nbt->Entities->setTagType(NBT::TAG_Compound); $this->nbt->Entities->setTagType(NBT::TAG_Compound);
} }
if(!isset($this->nbt->TileEntities) or !($this->nbt->TileEntities instanceof Enum)){ if(!isset($this->nbt->TileEntities) or !($this->nbt->TileEntities instanceof ListTag)){
$this->nbt->TileEntities = new Enum("TileEntities", []); $this->nbt->TileEntities = new ListTag("TileEntities", []);
$this->nbt->TileEntities->setTagType(NBT::TAG_Compound); $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
} }
if(!isset($this->nbt->TileTicks) or !($this->nbt->TileTicks instanceof Enum)){ if(!isset($this->nbt->TileTicks) or !($this->nbt->TileTicks instanceof ListTag)){
$this->nbt->TileTicks = new Enum("TileTicks", []); $this->nbt->TileTicks = new ListTag("TileTicks", []);
$this->nbt->TileTicks->setTagType(NBT::TAG_Compound); $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
} }
if(!isset($this->nbt->Sections) or !($this->nbt->Sections instanceof Enum)){ if(!isset($this->nbt->Sections) or !($this->nbt->Sections instanceof ListTag)){
$this->nbt->Sections = new Enum("Sections", []); $this->nbt->Sections = new ListTag("Sections", []);
$this->nbt->Sections->setTagType(NBT::TAG_Compound); $this->nbt->Sections->setTagType(NBT::TAG_Compound);
} }
if(!isset($this->nbt->BiomeColors) or !($this->nbt->BiomeColors instanceof IntArray)){ if(!isset($this->nbt->BiomeColors) or !($this->nbt->BiomeColors instanceof IntArrayTag)){
$this->nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 256, 0)); $this->nbt->BiomeColors = new IntArrayTag("BiomeColors", array_fill(0, 256, 0));
} }
if(!isset($this->nbt->HeightMap) or !($this->nbt->HeightMap instanceof IntArray)){ if(!isset($this->nbt->HeightMap) or !($this->nbt->HeightMap instanceof IntArrayTag)){
$this->nbt->HeightMap = new IntArray("HeightMap", array_fill(0, 256, 0)); $this->nbt->HeightMap = new IntArrayTag("HeightMap", array_fill(0, 256, 0));
} }
$sections = []; $sections = [];
foreach($this->nbt->Sections as $section){ foreach($this->nbt->Sections as $section){
if($section instanceof Compound){ if($section instanceof CompoundTag){
$y = (int) $section["Y"]; $y = (int) $section["Y"];
if($y < 8){ if($y < 8){
$sections[$y] = new ChunkSection($section); $sections[$y] = new ChunkSection($section);
@ -95,8 +95,8 @@ class Chunk extends BaseChunk{
$extraData = []; $extraData = [];
if(!isset($this->nbt->ExtraData) or !($this->nbt->ExtraData instanceof ByteArray)){ if(!isset($this->nbt->ExtraData) or !($this->nbt->ExtraData instanceof ByteArrayTag)){
$this->nbt->ExtraData = new ByteArray("ExtraData", Binary::writeInt(0)); $this->nbt->ExtraData = new ByteArrayTag("ExtraData", Binary::writeInt(0));
}else{ }else{
$stream = new BinaryStream($this->nbt->ExtraData->getValue()); $stream = new BinaryStream($this->nbt->ExtraData->getValue());
$count = $stream->getInt(); $count = $stream->getInt();
@ -121,7 +121,7 @@ class Chunk extends BaseChunk{
} }
public function setLightPopulated($value = 1){ public function setLightPopulated($value = 1){
$this->nbt->LightPopulated = new Byte("LightPopulated", $value); $this->nbt->LightPopulated = new ByteTag("LightPopulated", $value);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -136,7 +136,7 @@ class Chunk extends BaseChunk{
* @param int $value * @param int $value
*/ */
public function setPopulated($value = 1){ public function setPopulated($value = 1){
$this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value); $this->nbt->TerrainPopulated = new ByteTag("TerrainPopulated", $value);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -151,12 +151,12 @@ class Chunk extends BaseChunk{
* @param int $value * @param int $value
*/ */
public function setGenerated($value = 1){ public function setGenerated($value = 1){
$this->nbt->TerrainGenerated = new Byte("TerrainGenerated", $value); $this->nbt->TerrainGenerated = new ByteTag("TerrainGenerated", $value);
$this->hasChanged = true; $this->hasChanged = true;
} }
/** /**
* @return Compound * @return CompoundTag
*/ */
public function getNBT(){ public function getNBT(){
return $this->nbt; return $this->nbt;
@ -175,12 +175,12 @@ class Chunk extends BaseChunk{
$nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE); $nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE);
$chunk = $nbt->getData(); $chunk = $nbt->getData();
if(!isset($chunk->Level) or !($chunk->Level instanceof Compound)){ if(!isset($chunk->Level) or !($chunk->Level instanceof CompoundTag)){
return null; return null;
} }
return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level); return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level);
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }
@ -198,12 +198,12 @@ class Chunk extends BaseChunk{
$nbt->read($data); $nbt->read($data);
$chunk = $nbt->getData(); $chunk = $nbt->getData();
if(!isset($chunk->Level) or !($chunk->Level instanceof Compound)){ if(!isset($chunk->Level) or !($chunk->Level instanceof CompoundTag)){
return null; return null;
} }
return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level); return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level);
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }
@ -211,27 +211,27 @@ class Chunk extends BaseChunk{
public function toFastBinary(){ public function toFastBinary(){
$nbt = clone $this->getNBT(); $nbt = clone $this->getNBT();
$nbt->xPos = new Int("xPos", $this->x); $nbt->xPos = new IntTag("xPos", $this->x);
$nbt->zPos = new Int("zPos", $this->z); $nbt->zPos = new IntTag("zPos", $this->z);
$nbt->Sections = new Enum("Sections", []); $nbt->Sections = new ListTag("Sections", []);
$nbt->Sections->setTagType(NBT::TAG_Compound); $nbt->Sections->setTagType(NBT::TAG_Compound);
foreach($this->getSections() as $section){ foreach($this->getSections() as $section){
if($section instanceof EmptyChunkSection){ if($section instanceof EmptyChunkSection){
continue; continue;
} }
$nbt->Sections[$section->getY()] = new Compound(null, [ $nbt->Sections[$section->getY()] = new CompoundTag(null, [
"Y" => new Byte("Y", $section->getY()), "Y" => new ByteTag("Y", $section->getY()),
"Blocks" => new ByteArray("Blocks", $section->getIdArray()), "Blocks" => new ByteArrayTag("Blocks", $section->getIdArray()),
"Data" => new ByteArray("Data", $section->getDataArray()), "Data" => new ByteArrayTag("Data", $section->getDataArray()),
"BlockLight" => new ByteArray("BlockLight", $section->getLightArray()), "BlockLight" => new ByteArrayTag("BlockLight", $section->getLightArray()),
"SkyLight" => new ByteArray("SkyLight", $section->getSkyLightArray()) "SkyLight" => new ByteArrayTag("SkyLight", $section->getSkyLightArray())
]); ]);
} }
$nbt->BiomeColors = new IntArray("BiomeColors", $this->getBiomeColorArray()); $nbt->BiomeColors = new IntArrayTag("BiomeColors", $this->getBiomeColorArray());
$nbt->HeightMap = new IntArray("HeightMap", $this->getHeightMapArray()); $nbt->HeightMap = new IntArrayTag("HeightMap", $this->getHeightMapArray());
$entities = []; $entities = [];
@ -242,7 +242,7 @@ class Chunk extends BaseChunk{
} }
} }
$nbt->Entities = new Enum("Entities", $entities); $nbt->Entities = new ListTag("Entities", $entities);
$nbt->Entities->setTagType(NBT::TAG_Compound); $nbt->Entities->setTagType(NBT::TAG_Compound);
@ -252,7 +252,7 @@ class Chunk extends BaseChunk{
$tiles[] = $tile->namedtag; $tiles[] = $tile->namedtag;
} }
$nbt->TileEntities = new Enum("TileEntities", $tiles); $nbt->TileEntities = new ListTag("TileEntities", $tiles);
$nbt->TileEntities->setTagType(NBT::TAG_Compound); $nbt->TileEntities->setTagType(NBT::TAG_Compound);
$extraData = new BinaryStream(); $extraData = new BinaryStream();
@ -262,11 +262,11 @@ class Chunk extends BaseChunk{
$extraData->putShort($value); $extraData->putShort($value);
} }
$nbt->ExtraData = new ByteArray("ExtraData", $extraData->getBuffer()); $nbt->ExtraData = new ByteArrayTag("ExtraData", $extraData->getBuffer());
$writer = new NBT(NBT::BIG_ENDIAN); $writer = new NBT(NBT::BIG_ENDIAN);
$nbt->setName("Level"); $nbt->setName("Level");
$writer->setData(new Compound("", ["Level" => $nbt])); $writer->setData(new CompoundTag("", ["Level" => $nbt]));
return $writer->write(); return $writer->write();
} }
@ -274,27 +274,27 @@ class Chunk extends BaseChunk{
public function toBinary(){ public function toBinary(){
$nbt = clone $this->getNBT(); $nbt = clone $this->getNBT();
$nbt->xPos = new Int("xPos", $this->x); $nbt->xPos = new IntTag("xPos", $this->x);
$nbt->zPos = new Int("zPos", $this->z); $nbt->zPos = new IntTag("zPos", $this->z);
$nbt->Sections = new Enum("Sections", []); $nbt->Sections = new ListTag("Sections", []);
$nbt->Sections->setTagType(NBT::TAG_Compound); $nbt->Sections->setTagType(NBT::TAG_Compound);
foreach($this->getSections() as $section){ foreach($this->getSections() as $section){
if($section instanceof EmptyChunkSection){ if($section instanceof EmptyChunkSection){
continue; continue;
} }
$nbt->Sections[$section->getY()] = new Compound(null, [ $nbt->Sections[$section->getY()] = new CompoundTag(null, [
"Y" => new Byte("Y", $section->getY()), "Y" => new ByteTag("Y", $section->getY()),
"Blocks" => new ByteArray("Blocks", $section->getIdArray()), "Blocks" => new ByteArrayTag("Blocks", $section->getIdArray()),
"Data" => new ByteArray("Data", $section->getDataArray()), "Data" => new ByteArrayTag("Data", $section->getDataArray()),
"BlockLight" => new ByteArray("BlockLight", $section->getLightArray()), "BlockLight" => new ByteArrayTag("BlockLight", $section->getLightArray()),
"SkyLight" => new ByteArray("SkyLight", $section->getSkyLightArray()) "SkyLight" => new ByteArrayTag("SkyLight", $section->getSkyLightArray())
]); ]);
} }
$nbt->BiomeColors = new IntArray("BiomeColors", $this->getBiomeColorArray()); $nbt->BiomeColors = new IntArrayTag("BiomeColors", $this->getBiomeColorArray());
$nbt->HeightMap = new IntArray("HeightMap", $this->getHeightMapArray()); $nbt->HeightMap = new IntArrayTag("HeightMap", $this->getHeightMapArray());
$entities = []; $entities = [];
@ -305,7 +305,7 @@ class Chunk extends BaseChunk{
} }
} }
$nbt->Entities = new Enum("Entities", $entities); $nbt->Entities = new ListTag("Entities", $entities);
$nbt->Entities->setTagType(NBT::TAG_Compound); $nbt->Entities->setTagType(NBT::TAG_Compound);
@ -315,7 +315,7 @@ class Chunk extends BaseChunk{
$tiles[] = $tile->namedtag; $tiles[] = $tile->namedtag;
} }
$nbt->TileEntities = new Enum("TileEntities", $tiles); $nbt->TileEntities = new ListTag("TileEntities", $tiles);
$nbt->TileEntities->setTagType(NBT::TAG_Compound); $nbt->TileEntities->setTagType(NBT::TAG_Compound);
$extraData = new BinaryStream(); $extraData = new BinaryStream();
@ -325,11 +325,11 @@ class Chunk extends BaseChunk{
$extraData->putShort($value); $extraData->putShort($value);
} }
$nbt->ExtraData = new ByteArray("ExtraData", $extraData->getBuffer()); $nbt->ExtraData = new ByteArrayTag("ExtraData", $extraData->getBuffer());
$writer = new NBT(NBT::BIG_ENDIAN); $writer = new NBT(NBT::BIG_ENDIAN);
$nbt->setName("Level"); $nbt->setName("Level");
$writer->setData(new Compound("", ["Level" => $nbt])); $writer->setData(new CompoundTag("", ["Level" => $nbt]));
return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL);
} }
@ -354,14 +354,14 @@ class Chunk extends BaseChunk{
$chunk->heightMap = array_fill(0, 256, 0); $chunk->heightMap = array_fill(0, 256, 0);
$chunk->biomeColors = array_fill(0, 256, 0); $chunk->biomeColors = array_fill(0, 256, 0);
$chunk->nbt->V = new Byte("V", 1); $chunk->nbt->V = new ByteTag("V", 1);
$chunk->nbt->InhabitedTime = new Long("InhabitedTime", 0); $chunk->nbt->InhabitedTime = new LongTag("InhabitedTime", 0);
$chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", 0); $chunk->nbt->TerrainGenerated = new ByteTag("TerrainGenerated", 0);
$chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", 0); $chunk->nbt->TerrainPopulated = new ByteTag("TerrainPopulated", 0);
$chunk->nbt->LightPopulated = new Byte("LightPopulated", 0); $chunk->nbt->LightPopulated = new ByteTag("LightPopulated", 0);
return $chunk; return $chunk;
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }

View File

@ -21,7 +21,7 @@
namespace pocketmine\level\format\anvil; namespace pocketmine\level\format\anvil;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
class ChunkSection implements \pocketmine\level\format\ChunkSection{ class ChunkSection implements \pocketmine\level\format\ChunkSection{
@ -31,7 +31,7 @@ class ChunkSection implements \pocketmine\level\format\ChunkSection{
private $blockLight; private $blockLight;
private $skyLight; private $skyLight;
public function __construct(Compound $nbt){ public function __construct(CompoundTag $nbt){
$this->y = (int) $nbt["Y"]; $this->y = (int) $nbt["Y"];
$this->blocks = (string) $nbt["Blocks"]; $this->blocks = (string) $nbt["Blocks"];
$this->data = (string) $nbt["Data"]; $this->data = (string) $nbt["Data"];
@ -70,12 +70,6 @@ class ChunkSection implements \pocketmine\level\format\ChunkSection{
} }
} }
public function getBlock($x, $y, $z, &$blockId, &$meta = null){
$full = $this->getFullBlock($x, $y, $z);
$blockId = $full >> 4;
$meta = $full & 0x0f;
}
public function getFullBlock($x, $y, $z){ public function getFullBlock($x, $y, $z){
$i = ($y << 8) + ($z << 4) + $x; $i = ($y << 8) + ($z << 4) + $x;
if(($x & 1) === 0){ if(($x & 1) === 0){

View File

@ -24,7 +24,7 @@ namespace pocketmine\level\format\generic;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
use pocketmine\level\format\ChunkSection; use pocketmine\level\format\ChunkSection;
use pocketmine\level\format\LevelProvider; use pocketmine\level\format\LevelProvider;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\ChunkException; use pocketmine\utils\ChunkException;
@ -40,8 +40,8 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
* @param ChunkSection[] $sections * @param ChunkSection[] $sections
* @param int[] $biomeColors * @param int[] $biomeColors
* @param int[] $heightMap * @param int[] $heightMap
* @param Compound[] $entities * @param CompoundTag[] $entities
* @param Compound[] $tiles * @param CompoundTag[] $tiles
* *
* @throws ChunkException * @throws ChunkException
*/ */
@ -77,12 +77,6 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
$this->NBTentities = $entities; $this->NBTentities = $entities;
} }
public function getBlock($x, $y, $z, &$blockId, &$meta = null){
$full = $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z);
$blockId = $full >> 4;
$meta = $full & 0x0f;
}
public function getFullBlock($x, $y, $z){ public function getFullBlock($x, $y, $z){
return $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z); return $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z);
} }

View File

@ -27,7 +27,7 @@ use pocketmine\level\format\FullChunk;
use pocketmine\level\format\LevelProvider; use pocketmine\level\format\LevelProvider;
use pocketmine\level\generator\biome\Biome; use pocketmine\level\generator\biome\Biome;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
@ -82,8 +82,8 @@ abstract class BaseFullChunk implements FullChunk{
* @param string $blockLight * @param string $blockLight
* @param int[] $biomeColors * @param int[] $biomeColors
* @param int[] $heightMap * @param int[] $heightMap
* @param Compound[] $entities * @param CompoundTag[] $entities
* @param Compound[] $tiles * @param CompoundTag[] $tiles
*/ */
protected function __construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = [], array $extraData = []){ protected function __construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = [], array $extraData = []){
$this->provider = $provider; $this->provider = $provider;
@ -134,7 +134,7 @@ abstract class BaseFullChunk implements FullChunk{
if($this->NBTentities !== null){ if($this->NBTentities !== null){
$this->getProvider()->getLevel()->timings->syncChunkLoadEntitiesTimer->startTiming(); $this->getProvider()->getLevel()->timings->syncChunkLoadEntitiesTimer->startTiming();
foreach($this->NBTentities as $nbt){ foreach($this->NBTentities as $nbt){
if($nbt instanceof Compound){ if($nbt instanceof CompoundTag){
if(!isset($nbt->id)){ if(!isset($nbt->id)){
$this->setChanged(); $this->setChanged();
continue; continue;
@ -157,7 +157,7 @@ abstract class BaseFullChunk implements FullChunk{
$this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->startTiming(); $this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->startTiming();
foreach($this->NBTtiles as $nbt){ foreach($this->NBTtiles as $nbt){
if($nbt instanceof Compound){ if($nbt instanceof CompoundTag){
if(!isset($nbt->id)){ if(!isset($nbt->id)){
$changed = true; $changed = true;
continue; continue;
@ -203,15 +203,6 @@ abstract class BaseFullChunk implements FullChunk{
$this->z = $z; $this->z = $z;
} }
/**
* @return LevelProvider
*
* @deprecated
*/
public function getLevel(){
return $this->getProvider();
}
/** /**
* @return LevelProvider * @return LevelProvider
*/ */

View File

@ -26,9 +26,9 @@ use pocketmine\level\generator\Generator;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\utils\LevelException; use pocketmine\utils\LevelException;
abstract class BaseLevelProvider implements LevelProvider{ abstract class BaseLevelProvider implements LevelProvider{
@ -36,7 +36,7 @@ abstract class BaseLevelProvider implements LevelProvider{
protected $level; protected $level;
/** @var string */ /** @var string */
protected $path; protected $path;
/** @var Compound */ /** @var CompoundTag */
protected $levelData; protected $levelData;
public function __construct(Level $level, $path){ public function __construct(Level $level, $path){
@ -48,18 +48,18 @@ abstract class BaseLevelProvider implements LevelProvider{
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->readCompressed(file_get_contents($this->getPath() . "level.dat")); $nbt->readCompressed(file_get_contents($this->getPath() . "level.dat"));
$levelData = $nbt->getData(); $levelData = $nbt->getData();
if($levelData->Data instanceof Compound){ if($levelData->Data instanceof CompoundTag){
$this->levelData = $levelData->Data; $this->levelData = $levelData->Data;
}else{ }else{
throw new LevelException("Invalid level.dat"); throw new LevelException("Invalid level.dat");
} }
if(!isset($this->levelData->generatorName)){ if(!isset($this->levelData->generatorName)){
$this->levelData->generatorName = new String("generatorName", Generator::getGenerator("DEFAULT")); $this->levelData->generatorName = new StringTag("generatorName", Generator::getGenerator("DEFAULT"));
} }
if(!isset($this->levelData->generatorOptions)){ if(!isset($this->levelData->generatorOptions)){
$this->levelData->generatorOptions = new String("generatorOptions", ""); $this->levelData->generatorOptions = new StringTag("generatorOptions", "");
} }
} }
@ -84,7 +84,7 @@ abstract class BaseLevelProvider implements LevelProvider{
} }
public function setTime($value){ public function setTime($value){
$this->levelData->Time = new Int("Time", (int) $value); $this->levelData->Time = new IntTag("Time", (int) $value);
} }
public function getSeed(){ public function getSeed(){
@ -92,7 +92,7 @@ abstract class BaseLevelProvider implements LevelProvider{
} }
public function setSeed($value){ public function setSeed($value){
$this->levelData->RandomSeed = new Int("RandomSeed", (int) $value); $this->levelData->RandomSeed = new IntTag("RandomSeed", (int) $value);
} }
public function getSpawn(){ public function getSpawn(){
@ -100,9 +100,9 @@ abstract class BaseLevelProvider implements LevelProvider{
} }
public function setSpawn(Vector3 $pos){ public function setSpawn(Vector3 $pos){
$this->levelData->SpawnX = new Int("SpawnX", (int) $pos->x); $this->levelData->SpawnX = new IntTag("SpawnX", (int) $pos->x);
$this->levelData->SpawnY = new Int("SpawnY", (int) $pos->y); $this->levelData->SpawnY = new IntTag("SpawnY", (int) $pos->y);
$this->levelData->SpawnZ = new Int("SpawnZ", (int) $pos->z); $this->levelData->SpawnZ = new IntTag("SpawnZ", (int) $pos->z);
} }
public function doGarbageCollection(){ public function doGarbageCollection(){
@ -110,7 +110,7 @@ abstract class BaseLevelProvider implements LevelProvider{
} }
/** /**
* @return Compound * @return CompoundTag
*/ */
public function getLevelData(){ public function getLevelData(){
return $this->levelData; return $this->levelData;
@ -118,7 +118,7 @@ abstract class BaseLevelProvider implements LevelProvider{
public function saveLevelData(){ public function saveLevelData(){
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new Compound("", [ $nbt->setData(new CompoundTag("", [
"Data" => $this->levelData "Data" => $this->levelData
])); ]));
$buffer = $nbt->writeCompressed(); $buffer = $nbt->writeCompressed();

View File

@ -101,12 +101,6 @@ class Chunk extends BaseFullChunk{
} }
} }
public function getBlock($x, $y, $z, &$blockId, &$meta = null){
$full = $this->getFullBlock($x, $y, $z);
$blockId = $full >> 4;
$meta = $full & 0x0f;
}
public function setBlock($x, $y, $z, $blockId = null, $meta = null){ public function setBlock($x, $y, $z, $blockId = null, $meta = null){
$i = ($x << 11) | ($z << 7) | $y; $i = ($x << 11) | ($z << 7) | $y;
@ -305,7 +299,7 @@ class Chunk extends BaseFullChunk{
$chunk->setLightPopulated(); $chunk->setLightPopulated();
} }
return $chunk; return $chunk;
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }
@ -393,7 +387,7 @@ class Chunk extends BaseFullChunk{
$chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, str_repeat("\x00", self::DATA_LENGTH)); $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, str_repeat("\x00", self::DATA_LENGTH));
$chunk->skyLight = str_repeat("\xff", 16384); $chunk->skyLight = str_repeat("\xff", 16384);
return $chunk; return $chunk;
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }

View File

@ -26,11 +26,11 @@ use pocketmine\level\format\generic\BaseLevelProvider;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\LongTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\tile\Spawnable; use pocketmine\tile\Spawnable;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
@ -62,18 +62,18 @@ class LevelDB extends BaseLevelProvider{
$nbt = new NBT(NBT::LITTLE_ENDIAN); $nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->read(substr(file_get_contents($this->getPath() . "level.dat"), 8)); $nbt->read(substr(file_get_contents($this->getPath() . "level.dat"), 8));
$levelData = $nbt->getData(); $levelData = $nbt->getData();
if($levelData instanceof Compound){ if($levelData instanceof CompoundTag){
$this->levelData = $levelData; $this->levelData = $levelData;
}else{ }else{
throw new LevelException("Invalid level.dat"); throw new LevelException("Invalid level.dat");
} }
if(!isset($this->levelData->generatorName)){ if(!isset($this->levelData->generatorName)){
$this->levelData->generatorName = new String("generatorName", Generator::getGenerator("DEFAULT")); $this->levelData->generatorName = new StringTag("generatorName", Generator::getGenerator("DEFAULT"));
} }
if(!isset($this->levelData->generatorOptions)){ if(!isset($this->levelData->generatorOptions)){
$this->levelData->generatorOptions = new String("generatorOptions", ""); $this->levelData->generatorOptions = new StringTag("generatorOptions", "");
} }
$this->db = new \LevelDB($this->path . "/db", [ $this->db = new \LevelDB($this->path . "/db", [
@ -105,24 +105,24 @@ class LevelDB extends BaseLevelProvider{
mkdir($path . "/db", 0777, true); mkdir($path . "/db", 0777, true);
} }
//TODO, add extra details //TODO, add extra details
$levelData = new Compound("", [ $levelData = new CompoundTag("", [
"hardcore" => new Byte("hardcore", 0), "hardcore" => new ByteTag("hardcore", 0),
"initialized" => new Byte("initialized", 1), "initialized" => new ByteTag("initialized", 1),
"GameType" => new Int("GameType", 0), "GameType" => new IntTag("GameType", 0),
"generatorVersion" => new Int("generatorVersion", 1), //2 in MCPE "generatorVersion" => new IntTag("generatorVersion", 1), //2 in MCPE
"SpawnX" => new Int("SpawnX", 128), "SpawnX" => new IntTag("SpawnX", 128),
"SpawnY" => new Int("SpawnY", 70), "SpawnY" => new IntTag("SpawnY", 70),
"SpawnZ" => new Int("SpawnZ", 128), "SpawnZ" => new IntTag("SpawnZ", 128),
"version" => new Int("version", 19133), "version" => new IntTag("version", 19133),
"DayTime" => new Int("DayTime", 0), "DayTime" => new IntTag("DayTime", 0),
"LastPlayed" => new Long("LastPlayed", microtime(true) * 1000), "LastPlayed" => new LongTag("LastPlayed", microtime(true) * 1000),
"RandomSeed" => new Long("RandomSeed", $seed), "RandomSeed" => new LongTag("RandomSeed", $seed),
"SizeOnDisk" => new Long("SizeOnDisk", 0), "SizeOnDisk" => new LongTag("SizeOnDisk", 0),
"Time" => new Long("Time", 0), "Time" => new LongTag("Time", 0),
"generatorName" => new String("generatorName", Generator::getGeneratorName($generator)), "generatorName" => new StringTag("generatorName", Generator::getGeneratorName($generator)),
"generatorOptions" => new String("generatorOptions", isset($options["preset"]) ? $options["preset"] : ""), "generatorOptions" => new StringTag("generatorOptions", isset($options["preset"]) ? $options["preset"] : ""),
"LevelName" => new String("LevelName", $name), "LevelName" => new StringTag("LevelName", $name),
"GameRules" => new Compound("GameRules", []) "GameRules" => new CompoundTag("GameRules", [])
]); ]);
$nbt = new NBT(NBT::LITTLE_ENDIAN); $nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->setData($levelData); $nbt->setData($levelData);

View File

@ -24,74 +24,74 @@ namespace pocketmine\level\format\mcregion;
use pocketmine\level\format\generic\BaseFullChunk; use pocketmine\level\format\generic\BaseFullChunk;
use pocketmine\level\format\LevelProvider; use pocketmine\level\format\LevelProvider;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\ByteArray; use pocketmine\nbt\tag\ByteArrayTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\IntArray; use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\LongTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
class Chunk extends BaseFullChunk{ class Chunk extends BaseFullChunk{
/** @var Compound */ /** @var CompoundTag */
protected $nbt; protected $nbt;
public function __construct($level, Compound $nbt = null){ public function __construct($level, CompoundTag $nbt = null){
if($nbt === null){ if($nbt === null){
$this->provider = $level; $this->provider = $level;
$this->nbt = new Compound("Level", []); $this->nbt = new CompoundTag("Level", []);
return; return;
} }
$this->nbt = $nbt; $this->nbt = $nbt;
if(isset($this->nbt->Entities) and $this->nbt->Entities instanceof Enum){ if(isset($this->nbt->Entities) and $this->nbt->Entities instanceof ListTag){
$this->nbt->Entities->setTagType(NBT::TAG_Compound); $this->nbt->Entities->setTagType(NBT::TAG_Compound);
}else{ }else{
$this->nbt->Entities = new Enum("Entities", []); $this->nbt->Entities = new ListTag("Entities", []);
$this->nbt->Entities->setTagType(NBT::TAG_Compound); $this->nbt->Entities->setTagType(NBT::TAG_Compound);
} }
if(isset($this->nbt->TileEntities) and $this->nbt->TileEntities instanceof Enum){ if(isset($this->nbt->TileEntities) and $this->nbt->TileEntities instanceof ListTag){
$this->nbt->TileEntities->setTagType(NBT::TAG_Compound); $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
}else{ }else{
$this->nbt->TileEntities = new Enum("TileEntities", []); $this->nbt->TileEntities = new ListTag("TileEntities", []);
$this->nbt->TileEntities->setTagType(NBT::TAG_Compound); $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
} }
if(isset($this->nbt->TileTicks) and $this->nbt->TileTicks instanceof Enum){ if(isset($this->nbt->TileTicks) and $this->nbt->TileTicks instanceof ListTag){
$this->nbt->TileTicks->setTagType(NBT::TAG_Compound); $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
}else{ }else{
$this->nbt->TileTicks = new Enum("TileTicks", []); $this->nbt->TileTicks = new ListTag("TileTicks", []);
$this->nbt->TileTicks->setTagType(NBT::TAG_Compound); $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
} }
if(!isset($this->nbt->BiomeColors) or !($this->nbt->BiomeColors instanceof IntArray)){ if(!isset($this->nbt->BiomeColors) or !($this->nbt->BiomeColors instanceof IntArrayTag)){
$this->nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 256, 0)); $this->nbt->BiomeColors = new IntArrayTag("BiomeColors", array_fill(0, 256, 0));
} }
if(!isset($this->nbt->HeightMap) or !($this->nbt->HeightMap instanceof IntArray)){ if(!isset($this->nbt->HeightMap) or !($this->nbt->HeightMap instanceof IntArrayTag)){
$this->nbt->HeightMap = new IntArray("HeightMap", array_fill(0, 256, 0)); $this->nbt->HeightMap = new IntArrayTag("HeightMap", array_fill(0, 256, 0));
} }
if(!isset($this->nbt->Blocks)){ if(!isset($this->nbt->Blocks)){
$this->nbt->Blocks = new ByteArray("Blocks", str_repeat("\x00", 32768)); $this->nbt->Blocks = new ByteArrayTag("Blocks", str_repeat("\x00", 32768));
} }
if(!isset($this->nbt->Data)){ if(!isset($this->nbt->Data)){
$this->nbt->Data = new ByteArray("Data", $half = str_repeat("\x00", 16384)); $this->nbt->Data = new ByteArrayTag("Data", $half = str_repeat("\x00", 16384));
$this->nbt->SkyLight = new ByteArray("SkyLight", $half); $this->nbt->SkyLight = new ByteArrayTag("SkyLight", $half);
$this->nbt->BlockLight = new ByteArray("BlockLight", $half); $this->nbt->BlockLight = new ByteArrayTag("BlockLight", $half);
} }
$extraData = []; $extraData = [];
if(!isset($this->nbt->ExtraData) or !($this->nbt->ExtraData instanceof ByteArray)){ if(!isset($this->nbt->ExtraData) or !($this->nbt->ExtraData instanceof ByteArrayTag)){
$this->nbt->ExtraData = new ByteArray("ExtraData", Binary::writeInt(0)); $this->nbt->ExtraData = new ByteArrayTag("ExtraData", Binary::writeInt(0));
}else{ }else{
$stream = new BinaryStream($this->nbt->ExtraData->getValue()); $stream = new BinaryStream($this->nbt->ExtraData->getValue());
$count = $stream->getInt(); $count = $stream->getInt();
@ -155,12 +155,6 @@ class Chunk extends BaseFullChunk{
} }
} }
public function getBlock($x, $y, $z, &$blockId, &$meta = null){
$full = $this->getFullBlock($x, $y, $z);
$blockId = $full >> 4;
$meta = $full & 0x0f;
}
public function setBlock($x, $y, $z, $blockId = null, $meta = null){ public function setBlock($x, $y, $z, $blockId = null, $meta = null){
$i = ($x << 11) | ($z << 7) | $y; $i = ($x << 11) | ($z << 7) | $y;
@ -258,7 +252,7 @@ class Chunk extends BaseFullChunk{
} }
public function setLightPopulated($value = 1){ public function setLightPopulated($value = 1){
$this->nbt->LightPopulated = new Byte("LightPopulated", $value ? 1 : 0); $this->nbt->LightPopulated = new ByteTag("LightPopulated", $value ? 1 : 0);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -273,7 +267,7 @@ class Chunk extends BaseFullChunk{
* @param int $value * @param int $value
*/ */
public function setPopulated($value = 1){ public function setPopulated($value = 1){
$this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value ? 1 : 0); $this->nbt->TerrainPopulated = new ByteTag("TerrainPopulated", $value ? 1 : 0);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -293,7 +287,7 @@ class Chunk extends BaseFullChunk{
* @param int $value * @param int $value
*/ */
public function setGenerated($value = 1){ public function setGenerated($value = 1){
$this->nbt->TerrainGenerated = new Byte("TerrainGenerated", (int) $value); $this->nbt->TerrainGenerated = new ByteTag("TerrainGenerated", (int) $value);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -310,12 +304,12 @@ class Chunk extends BaseFullChunk{
$nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE); $nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE);
$chunk = $nbt->getData(); $chunk = $nbt->getData();
if(!isset($chunk->Level) or !($chunk->Level instanceof Compound)){ if(!isset($chunk->Level) or !($chunk->Level instanceof CompoundTag)){
return null; return null;
} }
return new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, $chunk->Level); return new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, $chunk->Level);
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }
@ -348,12 +342,12 @@ class Chunk extends BaseFullChunk{
$flags = ord($data{$offset++}); $flags = ord($data{$offset++});
$chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", $flags & 0b1); $chunk->nbt->TerrainGenerated = new ByteTag("TerrainGenerated", $flags & 0b1);
$chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", ($flags >> 1) & 0b1); $chunk->nbt->TerrainPopulated = new ByteTag("TerrainPopulated", ($flags >> 1) & 0b1);
$chunk->nbt->LightPopulated = new Byte("LightPopulated", ($flags >> 2) & 0b1); $chunk->nbt->LightPopulated = new ByteTag("LightPopulated", ($flags >> 2) & 0b1);
return $chunk; return $chunk;
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }
@ -374,18 +368,18 @@ class Chunk extends BaseFullChunk{
public function toBinary(){ public function toBinary(){
$nbt = clone $this->getNBT(); $nbt = clone $this->getNBT();
$nbt->xPos = new Int("xPos", $this->x); $nbt->xPos = new IntTag("xPos", $this->x);
$nbt->zPos = new Int("zPos", $this->z); $nbt->zPos = new IntTag("zPos", $this->z);
if($this->isGenerated()){ if($this->isGenerated()){
$nbt->Blocks = new ByteArray("Blocks", $this->getBlockIdArray()); $nbt->Blocks = new ByteArrayTag("Blocks", $this->getBlockIdArray());
$nbt->Data = new ByteArray("Data", $this->getBlockDataArray()); $nbt->Data = new ByteArrayTag("Data", $this->getBlockDataArray());
$nbt->SkyLight = new ByteArray("SkyLight", $this->getBlockSkyLightArray()); $nbt->SkyLight = new ByteArrayTag("SkyLight", $this->getBlockSkyLightArray());
$nbt->BlockLight = new ByteArray("BlockLight", $this->getBlockLightArray()); $nbt->BlockLight = new ByteArrayTag("BlockLight", $this->getBlockLightArray());
$nbt->BiomeColors = new IntArray("BiomeColors", $this->getBiomeColorArray()); $nbt->BiomeColors = new IntArrayTag("BiomeColors", $this->getBiomeColorArray());
$nbt->HeightMap = new IntArray("HeightMap", $this->getHeightMapArray()); $nbt->HeightMap = new IntArrayTag("HeightMap", $this->getHeightMapArray());
} }
$entities = []; $entities = [];
@ -397,7 +391,7 @@ class Chunk extends BaseFullChunk{
} }
} }
$nbt->Entities = new Enum("Entities", $entities); $nbt->Entities = new ListTag("Entities", $entities);
$nbt->Entities->setTagType(NBT::TAG_Compound); $nbt->Entities->setTagType(NBT::TAG_Compound);
@ -407,7 +401,7 @@ class Chunk extends BaseFullChunk{
$tiles[] = $tile->namedtag; $tiles[] = $tile->namedtag;
} }
$nbt->TileEntities = new Enum("TileEntities", $tiles); $nbt->TileEntities = new ListTag("TileEntities", $tiles);
$nbt->TileEntities->setTagType(NBT::TAG_Compound); $nbt->TileEntities->setTagType(NBT::TAG_Compound);
$extraData = new BinaryStream(); $extraData = new BinaryStream();
@ -417,17 +411,17 @@ class Chunk extends BaseFullChunk{
$extraData->putShort($value); $extraData->putShort($value);
} }
$nbt->ExtraData = new ByteArray("ExtraData", $extraData->getBuffer()); $nbt->ExtraData = new ByteArrayTag("ExtraData", $extraData->getBuffer());
$writer = new NBT(NBT::BIG_ENDIAN); $writer = new NBT(NBT::BIG_ENDIAN);
$nbt->setName("Level"); $nbt->setName("Level");
$writer->setData(new Compound("", ["Level" => $nbt])); $writer->setData(new CompoundTag("", ["Level" => $nbt]));
return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL);
} }
/** /**
* @return Compound * @return CompoundTag
*/ */
public function getNBT(){ public function getNBT(){
return $this->nbt; return $this->nbt;
@ -454,14 +448,14 @@ class Chunk extends BaseFullChunk{
$chunk->heightMap = array_fill(0, 256, 0); $chunk->heightMap = array_fill(0, 256, 0);
$chunk->biomeColors = array_fill(0, 256, 0); $chunk->biomeColors = array_fill(0, 256, 0);
$chunk->nbt->V = new Byte("V", 1); $chunk->nbt->V = new ByteTag("V", 1);
$chunk->nbt->InhabitedTime = new Long("InhabitedTime", 0); $chunk->nbt->InhabitedTime = new LongTag("InhabitedTime", 0);
$chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", 0); $chunk->nbt->TerrainGenerated = new ByteTag("TerrainGenerated", 0);
$chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", 0); $chunk->nbt->TerrainPopulated = new ByteTag("TerrainPopulated", 0);
$chunk->nbt->LightPopulated = new Byte("LightPopulated", 0); $chunk->nbt->LightPopulated = new ByteTag("LightPopulated", 0);
return $chunk; return $chunk;
}catch(\Exception $e){ }catch(\Throwable $e){
return null; return null;
} }
} }

View File

@ -26,11 +26,11 @@ use pocketmine\level\format\generic\BaseLevelProvider;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\LongTag;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\StringTag;
use pocketmine\tile\Spawnable; use pocketmine\tile\Spawnable;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
@ -81,27 +81,27 @@ class McRegion extends BaseLevelProvider{
mkdir($path . "/region", 0777); mkdir($path . "/region", 0777);
} }
//TODO, add extra details //TODO, add extra details
$levelData = new Compound("Data", [ $levelData = new CompoundTag("Data", [
"hardcore" => new Byte("hardcore", 0), "hardcore" => new ByteTag("hardcore", 0),
"initialized" => new Byte("initialized", 1), "initialized" => new ByteTag("initialized", 1),
"GameType" => new Int("GameType", 0), "GameType" => new IntTag("GameType", 0),
"generatorVersion" => new Int("generatorVersion", 1), //2 in MCPE "generatorVersion" => new IntTag("generatorVersion", 1), //2 in MCPE
"SpawnX" => new Int("SpawnX", 128), "SpawnX" => new IntTag("SpawnX", 128),
"SpawnY" => new Int("SpawnY", 70), "SpawnY" => new IntTag("SpawnY", 70),
"SpawnZ" => new Int("SpawnZ", 128), "SpawnZ" => new IntTag("SpawnZ", 128),
"version" => new Int("version", 19133), "version" => new IntTag("version", 19133),
"DayTime" => new Int("DayTime", 0), "DayTime" => new IntTag("DayTime", 0),
"LastPlayed" => new Long("LastPlayed", microtime(true) * 1000), "LastPlayed" => new LongTag("LastPlayed", microtime(true) * 1000),
"RandomSeed" => new Long("RandomSeed", $seed), "RandomSeed" => new LongTag("RandomSeed", $seed),
"SizeOnDisk" => new Long("SizeOnDisk", 0), "SizeOnDisk" => new LongTag("SizeOnDisk", 0),
"Time" => new Long("Time", 0), "Time" => new LongTag("Time", 0),
"generatorName" => new String("generatorName", Generator::getGeneratorName($generator)), "generatorName" => new StringTag("generatorName", Generator::getGeneratorName($generator)),
"generatorOptions" => new String("generatorOptions", isset($options["preset"]) ? $options["preset"] : ""), "generatorOptions" => new StringTag("generatorOptions", isset($options["preset"]) ? $options["preset"] : ""),
"LevelName" => new String("LevelName", $name), "LevelName" => new StringTag("LevelName", $name),
"GameRules" => new Compound("GameRules", []) "GameRules" => new CompoundTag("GameRules", [])
]); ]);
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new Compound("", [ $nbt->setData(new CompoundTag("", [
"Data" => $levelData "Data" => $levelData
])); ]));
$buffer = $nbt->writeCompressed(); $buffer = $nbt->writeCompressed();

View File

@ -195,7 +195,7 @@ class RegionLoader{
try{ try{
$chunk = zlib_decode(substr($chunk, 5)); $chunk = zlib_decode(substr($chunk, 5));
}catch(\Exception $e){ }catch(\Throwable $e){
$this->locationTable[$i] = [0, 0, 0]; //Corrupted chunk, remove it $this->locationTable[$i] = [0, 0, 0]; //Corrupted chunk, remove it
continue; continue;
} }

View File

@ -123,15 +123,10 @@ abstract class Generator{
* @throws \InvalidArgumentCountException * @throws \InvalidArgumentCountException
*/ */
public static function getFastNoise2D(Noise $noise, $xSize, $zSize, $samplingRate, $x, $y, $z){ public static function getFastNoise2D(Noise $noise, $xSize, $zSize, $samplingRate, $x, $y, $z){
if($samplingRate === 0){ assert($samplingRate !== 0, new \InvalidArgumentException("samplingRate cannot be 0"));
throw new \InvalidArgumentException("samplingRate cannot be 0");
} assert($xSize % $samplingRate === 0, new \InvalidArgumentCountException("xSize % samplingRate must return 0"));
if ($xSize % $samplingRate !== 0) { assert($zSize % $samplingRate === 0, new \InvalidArgumentCountException("zSize % samplingRate must return 0"));
throw new \InvalidArgumentCountException("xSize % samplingRate must return 0");
}
if ($zSize % $samplingRate !== 0) {
throw new \InvalidArgumentCountException("zSize % samplingRate must return 0");
}
$noiseArray = new \SplFixedArray($xSize + 1); $noiseArray = new \SplFixedArray($xSize + 1);
@ -181,24 +176,14 @@ abstract class Generator{
* @throws \InvalidArgumentCountException * @throws \InvalidArgumentCountException
*/ */
public static function getFastNoise3D(Noise $noise, $xSize, $ySize, $zSize, $xSamplingRate, $ySamplingRate, $zSamplingRate, $x, $y, $z){ public static function getFastNoise3D(Noise $noise, $xSize, $ySize, $zSize, $xSamplingRate, $ySamplingRate, $zSamplingRate, $x, $y, $z){
if($xSamplingRate === 0){
throw new \InvalidArgumentException("xSamplingRate cannot be 0"); assert($xSamplingRate !== 0, new \InvalidArgumentException("xSamplingRate cannot be 0"));
} assert($zSamplingRate !== 0, new \InvalidArgumentException("zSamplingRate cannot be 0"));
if($zSamplingRate === 0){ assert($ySamplingRate !== 0, new \InvalidArgumentException("ySamplingRate cannot be 0"));
throw new \InvalidArgumentException("zSamplingRate cannot be 0");
} assert($xSize % $xSamplingRate === 0, new \InvalidArgumentCountException("xSize % xSamplingRate must return 0"));
if($ySamplingRate === 0){ assert($zSize % $zSamplingRate === 0, new \InvalidArgumentCountException("zSize % zSamplingRate must return 0"));
throw new \InvalidArgumentException("ySamplingRate cannot be 0"); assert($ySize % $ySamplingRate === 0, new \InvalidArgumentCountException("ySize % ySamplingRate must return 0"));
}
if ($xSize % $xSamplingRate !== 0) {
throw new \InvalidArgumentCountException("xSize % xSamplingRate must return 0");
}
if ($zSize % $zSamplingRate !== 0) {
throw new \InvalidArgumentCountException("zSize % zSamplingRate must return 0");
}
if ($ySize % $ySamplingRate !== 0) {
throw new \InvalidArgumentCountException("ySize % ySamplingRate must return 0");
}
$noiseArray = array_fill(0, $xSize + 1, array_fill(0, $zSize + 1, [])); $noiseArray = array_fill(0, $xSize + 1, array_fill(0, $zSize + 1, []));

View File

@ -39,7 +39,7 @@ class GeneratorRegisterTask extends AsyncTask{
public function __construct(Level $level, Generator $generator){ public function __construct(Level $level, Generator $generator){
$this->generator = get_class($generator); $this->generator = get_class($generator);
$this->settings = $generator->getSettings(); $this->settings = serialize($generator->getSettings());
$this->seed = $level->getSeed(); $this->seed = $level->getSeed();
$this->levelId = $level->getId(); $this->levelId = $level->getId();
} }
@ -51,7 +51,7 @@ class GeneratorRegisterTask extends AsyncTask{
$this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager); $this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager);
/** @var Generator $generator */ /** @var Generator $generator */
$generator = $this->generator; $generator = $this->generator;
$generator = new $generator($this->settings); $generator = new $generator(unserialize($this->settings));
$generator->init($manager, new Random($manager->getSeed())); $generator->init($manager, new Random($manager->getSeed()));
$this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator); $this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator);
} }

View File

@ -29,7 +29,7 @@ use pocketmine\utils\PluginException;
abstract class MetadataStore{ abstract class MetadataStore{
/** @var \WeakMap[] */ /** @var \WeakMap[] */
private $metadataMap = []; private $metadataMap;
/** /**
* Adds a metadata value to an object. * Adds a metadata value to an object.
@ -48,8 +48,8 @@ abstract class MetadataStore{
$key = $this->disambiguate($subject, $metadataKey); $key = $this->disambiguate($subject, $metadataKey);
if(!isset($this->metadataMap[$key])){ if(!isset($this->metadataMap[$key])){
$entry = new \WeakMap(); //$entry = new \WeakMap();
$this->metadataMap[$key] = $entry; $this->metadataMap[$key] = new \SplObjectStorage();//$entry;
}else{ }else{
$entry = $this->metadataMap[$key]; $entry = $this->metadataMap[$key];
} }

Some files were not shown because too many files have changed in this diff Show More