Merge branch 'master' into 0.10

This commit is contained in:
Shoghi Cervantes 2014-11-05 19:04:36 +01:00
commit 522b75645c
106 changed files with 1022 additions and 1138 deletions

View File

@ -137,7 +137,7 @@ class CrashDump{
$error = $lastExceptionError; $error = $lastExceptionError;
}else{ }else{
$error = (array) error_get_last(); $error = (array) error_get_last();
$error["trace"] = getTrace(4); $error["trace"] = @getTrace(4);
$errorConversion = [ $errorConversion = [
E_ERROR => "E_ERROR", E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING", E_WARNING => "E_WARNING",

View File

@ -47,6 +47,7 @@ use pocketmine\event\player\PlayerCommandPreprocessEvent;
use pocketmine\event\player\PlayerDeathEvent; use pocketmine\event\player\PlayerDeathEvent;
use pocketmine\event\player\PlayerDropItemEvent; use pocketmine\event\player\PlayerDropItemEvent;
use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerGameModeChangeEvent;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\event\player\PlayerItemConsumeEvent; use pocketmine\event\player\PlayerItemConsumeEvent;
use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\event\player\PlayerKickEvent; use pocketmine\event\player\PlayerKickEvent;
@ -140,7 +141,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
protected $sendIndex = 0; protected $sendIndex = 0;
public $blocked = true; public $blocked = false;
public $achievements = []; public $achievements = [];
public $lastCorrect; public $lastCorrect;
/** @var SimpleTransactionGroup */ /** @var SimpleTransactionGroup */
@ -244,7 +245,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
* @param Player $player * @param Player $player
*/ */
public function spawnTo(Player $player){ public function spawnTo(Player $player){
if($this->spawned === true and $this->dead !== true and $player->getLevel() === $this->level and $player->canSee($this)){ if($this->spawned === true and $this->dead !== true and $this !== $player and $player->getLevel() === $this->level and $player->canSee($this)){
parent::spawnTo($player); parent::spawnTo($player);
} }
} }
@ -422,7 +423,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->port = $port; $this->port = $port;
$this->clientID = $clientID; $this->clientID = $clientID;
$this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4);
$this->spawnPosition = $this->server->getDefaultLevel()->getSafeSpawn(); $this->spawnPosition = null;
$this->gamemode = $this->server->getGamemode(); $this->gamemode = $this->server->getGamemode();
$this->setLevel($this->server->getDefaultLevel(), true); $this->setLevel($this->server->getDefaultLevel(), true);
$this->viewDistance = $this->server->getViewDistance(); $this->viewDistance = $this->server->getViewDistance();
@ -531,9 +532,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
$this->level->freeChunk($x, $z, $this);
unset($this->usedChunks[$index]); unset($this->usedChunks[$index]);
} }
$this->level->freeChunk($x, $z, $this);
unset($this->loadQueue[$index]); unset($this->loadQueue[$index]);
} }
@ -584,7 +585,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$pk = FullChunkDataPacket::getFromPool(); $pk = new FullChunkDataPacket();
$pk->chunkX = $x; $pk->chunkX = $x;
$pk->chunkZ = $z; $pk->chunkZ = $z;
$pk->data = $payload; $pk->data = $payload;
@ -597,7 +598,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
protected function sendNextChunk(){ protected function sendNextChunk(){
if($this->connected === false){ if($this->connected === false){
return false; return;
} }
$count = 0; $count = 0;
@ -625,13 +626,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->level->requestChunk($X, $Z, $this, LevelProvider::ORDER_ZXY); $this->level->requestChunk($X, $Z, $this, LevelProvider::ORDER_ZXY);
} }
if(count($this->usedChunks) < 16 and $this->spawned === true){
$this->blocked = true;
}elseif($this->spawned === true){
$this->blocked = false; //TODO: reason of block to revert
}
if(count($this->usedChunks) >= 56 and $this->spawned === false){ if(count($this->usedChunks) >= 56 and $this->spawned === false){
$spawned = 0; $spawned = 0;
foreach($this->usedChunks as $d){ foreach($this->usedChunks as $d){
@ -641,21 +635,19 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($spawned < 56){ if($spawned < 56){
return true; return;
} }
$this->spawned = true; $this->spawned = true;
$this->blocked = false; $pk = new SetTimePacket();
$pk = SetTimePacket::getFromPool();
$pk->time = $this->level->getTime(); $pk->time = $this->level->getTime();
$pk->started = $this->level->stopTime == false; $pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
$pos = $this->level->getSafeSpawn($this); $pos = $this->level->getSafeSpawn($this);
$this->server->getPluginManager()->callEvent($ev = PlayerRespawnEvent::createEvent($this, $pos)); $this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos));
$this->teleport($ev->getRespawnPosition()); $this->teleport($ev->getRespawnPosition());
@ -663,7 +655,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
$this->inventory->sendArmorContents($this); $this->inventory->sendArmorContents($this);
$this->server->getPluginManager()->callEvent($ev = PlayerJoinEvent::createEvent($this, TextFormat::YELLOW . $this->getName() . " joined the game")); $this->server->getPluginManager()->callEvent($ev = new PlayerJoinEvent($this, TextFormat::YELLOW . $this->getName() . " joined the game"));
if(strlen(trim($ev->getJoinMessage())) > 0){ if(strlen(trim($ev->getJoinMessage())) > 0){
$this->server->broadcastMessage($ev->getJoinMessage()); $this->server->broadcastMessage($ev->getJoinMessage());
} }
@ -724,13 +716,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$X = null; $X = null;
$Z = null; $Z = null;
Level::getXZ($index, $X, $Z); Level::getXZ($index, $X, $Z);
foreach($this->level->getChunkEntities($X, $Z) as $entity){ $this->unloadChunk($X, $Z);
if($entity !== $this){
$entity->despawnFrom($this);
}
}
unset($this->usedChunks[$index]);
} }
return true; return true;
@ -748,7 +734,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->connected === false){ if($this->connected === false){
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = $packet->getSendEvent($this)); $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -774,7 +760,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->connected === false){ if($this->connected === false){
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = DataPacketSendEvent::createEvent($this, $packet)); $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -806,13 +792,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
$this->server->getPluginManager()->callEvent($ev = PlayerBedEnterEvent::createEvent($this, $this->level->getBlock($pos))); $this->server->getPluginManager()->callEvent($ev = new PlayerBedEnterEvent($this, $this->level->getBlock($pos)));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
$this->sleeping = clone $pos; $this->sleeping = clone $pos;
$this->teleport(Position::createPosition($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level)); $this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level));
$this->sendMetadata($this->getViewers()); $this->sendMetadata($this->getViewers());
$this->sendMetadata($this); $this->sendMetadata($this);
@ -836,7 +822,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$level = $pos->getLevel(); $level = $pos->getLevel();
} }
$this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level); $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level);
$pk = SetSpawnPositionPacket::getFromPool(); $pk = new SetSpawnPositionPacket();
$pk->x = (int) $this->spawnPosition->x; $pk->x = (int) $this->spawnPosition->x;
$pk->y = (int) $this->spawnPosition->y; $pk->y = (int) $this->spawnPosition->y;
$pk->z = (int) $this->spawnPosition->z; $pk->z = (int) $this->spawnPosition->z;
@ -845,7 +831,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
public function stopSleep(){ public function stopSleep(){
if($this->sleeping instanceof Vector3){ if($this->sleeping instanceof Vector3){
$this->server->getPluginManager()->callEvent($ev = PlayerBedLeaveEvent::createEvent($this, $this->level->getBlock($this->sleeping))); $this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $this->level->getBlock($this->sleeping)));
$this->sleeping = null; $this->sleeping = null;
@ -895,7 +881,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return false; return false;
} }
} }
$this->server->getPluginManager()->callEvent($ev = PlayerAchievementAwardedEvent::createEvent($this, $achievementId)); $this->server->getPluginManager()->callEvent($ev = new PlayerAchievementAwardedEvent($this, $achievementId));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->achievements[$achievementId] = true; $this->achievements[$achievementId] = true;
Achievement::broadcast($this, $achievementId); Achievement::broadcast($this, $achievementId);
@ -929,7 +915,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = PlayerGameModeChangeEvent::createEvent($this, (int) $gm)); $this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -949,7 +935,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$spawnPosition = $this->getSpawn(); $spawnPosition = $this->getSpawn();
$pk = StartGamePacket::getFromPool(); $pk = new StartGamePacket();
$pk->seed = $this->level->getSeed(); $pk->seed = $this->level->getSeed();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y + $this->getEyeHeight(); $pk->y = $this->y + $this->getEyeHeight();
@ -1019,7 +1005,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$flags |= 0x20; //Show Nametags $flags |= 0x20; //Show Nametags
} }
$pk = AdventureSettingsPacket::getFromPool(); $pk = new AdventureSettingsPacket();
$pk->flags = $flags; $pk->flags = $flags;
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -1122,7 +1108,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->lastYaw = $to->yaw; $this->lastYaw = $to->yaw;
$this->lastPitch = $to->pitch; $this->lastPitch = $to->pitch;
$ev = PlayerMoveEvent::createEvent($this, $from, $to); $ev = new PlayerMoveEvent($this, $from, $to);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
@ -1130,7 +1116,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($to->distance($ev->getTo()) > 0.1){ //If plugins modify the destination if($to->distance($ev->getTo()) > 0.1){ //If plugins modify the destination
$this->teleport($ev->getTo()); $this->teleport($ev->getTo());
}else{ }else{
$pk = MovePlayerPacket::getFromPool(); $pk = new MovePlayerPacket();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -1145,7 +1131,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($revert){ if($revert){
$pk = MovePlayerPacket::getFromPool(); $pk = new MovePlayerPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $from->x; $pk->x = $from->x;
$pk->y = $from->y + $this->getEyeHeight() + 0.01; $pk->y = $from->y + $this->getEyeHeight() + 0.01;
@ -1206,20 +1192,20 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
continue; continue;
} }
$this->server->getPluginManager()->callEvent($ev = InventoryPickupArrowEvent::createEvent($this->inventory, $entity)); $this->server->getPluginManager()->callEvent($ev = new InventoryPickupArrowEvent($this->inventory, $entity));
if($ev->isCancelled()){ if($ev->isCancelled()){
continue; continue;
} }
$pk = TakeItemEntityPacket::getFromPool(); $pk = new TakeItemEntityPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->target = $entity->getID(); $pk->target = $entity->getID();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = TakeItemEntityPacket::getFromPool(); $pk = new TakeItemEntityPacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->target = $entity->getID(); $pk->target = $entity->getID();
Server::broadcastPacket($entity->getViewers(), $pk); Server::broadcastPacket($entity->getViewers(), $pk);
$this->inventory->addItem(clone $item); $this->inventory->addItem(clone $item, $this);
$entity->kill(); $entity->kill();
} }
}elseif($entity instanceof DroppedItem){ }elseif($entity instanceof DroppedItem){
@ -1231,7 +1217,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
continue; continue;
} }
$this->server->getPluginManager()->callEvent($ev = InventoryPickupItemEvent::createEvent($this->inventory, $entity)); $this->server->getPluginManager()->callEvent($ev = new InventoryPickupItemEvent($this->inventory, $entity));
if($ev->isCancelled()){ if($ev->isCancelled()){
continue; continue;
} }
@ -1245,15 +1231,15 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
break; break;
} }
$pk = TakeItemEntityPacket::getFromPool(); $pk = new TakeItemEntityPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->target = $entity->getID(); $pk->target = $entity->getID();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = TakeItemEntityPacket::getFromPool(); $pk = new TakeItemEntityPacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->target = $entity->getID(); $pk->target = $entity->getID();
Server::broadcastPacket($entity->getViewers(), $pk); Server::broadcastPacket($entity->getViewers(), $pk);
$this->inventory->addItem(clone $item); $this->inventory->addItem(clone $item, $this);
$entity->kill(); $entity->kill();
} }
} }
@ -1261,11 +1247,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
if($this->nextChunkOrderRun-- <= 0){ if($this->nextChunkOrderRun-- <= 0 or $this->chunk === null){
$this->orderChunks(); $this->orderChunks();
} }
if(count($this->loadQueue) > 0){ if(count($this->loadQueue) > 0 or !$this->spawned){
$this->sendNextChunk(); $this->sendNextChunk();
} }
@ -1288,7 +1274,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$this->server->getPluginManager()->callEvent($ev = $packet->getReceiveEvent($this)); $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet));
if($ev->isCancelled()){ if($ev->isCancelled()){
return; return;
} }
@ -1312,11 +1298,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($packet->protocol1 !== ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol1 !== ProtocolInfo::CURRENT_PROTOCOL){
if($packet->protocol1 < ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol1 < ProtocolInfo::CURRENT_PROTOCOL){
$pk = LoginStatusPacket::getFromPool(); $pk = new LoginStatusPacket();
$pk->status = 1; $pk->status = 1;
$this->dataPacket($pk); $this->dataPacket($pk);
}else{ }else{
$pk = LoginStatusPacket::getFromPool(); $pk = new LoginStatusPacket();
$pk->status = 2; $pk->status = 2;
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -1330,7 +1316,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$this->server->getPluginManager()->callEvent($ev = PlayerPreLoginEvent::createEvent($this, "Plugin reason")); $this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($this, "Plugin reason"));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->close("", $ev->getKickMessage()); $this->close("", $ev->getKickMessage());
@ -1405,7 +1391,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
parent::__construct($this->level->getChunk($nbt["Pos"][0] >> 4, $nbt["Pos"][2] >> 4, true), $nbt); parent::__construct($this->level->getChunk($nbt["Pos"][0] >> 4, $nbt["Pos"][2] >> 4, true), $nbt);
$this->loggedIn = true; $this->loggedIn = true;
$this->server->getPluginManager()->callEvent($ev = PlayerLoginEvent::createEvent($this, "Plugin reason")); $this->server->getPluginManager()->callEvent($ev = new PlayerLoginEvent($this, "Plugin reason"));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->close(TextFormat::YELLOW . $this->username . " has left the game", $ev->getKickMessage()); $this->close(TextFormat::YELLOW . $this->username . " has left the game", $ev->getKickMessage());
@ -1418,7 +1404,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->inventory->setHeldItemSlot(0); $this->inventory->setHeldItemSlot(0);
} }
$pk = LoginStatusPacket::getFromPool(); $pk = new LoginStatusPacket();
$pk->status = 0; $pk->status = 0;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -1430,7 +1416,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->dead = false; $this->dead = false;
$pk = StartGamePacket::getFromPool(); $pk = new StartGamePacket();
$pk->seed = $this->level->getSeed(); $pk->seed = $this->level->getSeed();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -1443,18 +1429,18 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$pk->eid = 0; //Always use EntityID as zero for the actual player $pk->eid = 0; //Always use EntityID as zero for the actual player
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = SetTimePacket::getFromPool(); $pk = new SetTimePacket();
$pk->time = $this->level->getTime(); $pk->time = $this->level->getTime();
$pk->started = $this->level->stopTime == false; $pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = SetSpawnPositionPacket::getFromPool(); $pk = new SetSpawnPositionPacket();
$pk->x = (int) $spawnPosition->x; $pk->x = (int) $spawnPosition->x;
$pk->y = (int) $spawnPosition->y; $pk->y = (int) $spawnPosition->y;
$pk->z = (int) $spawnPosition->z; $pk->z = (int) $spawnPosition->z;
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = SetHealthPacket::getFromPool(); $pk = new SetHealthPacket();
$pk->health = $this->getHealth(); $pk->health = $this->getHealth();
$this->dataPacket($pk); $this->dataPacket($pk);
if($this->getHealth() <= 0){ if($this->getHealth() <= 0){
@ -1484,7 +1470,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($this->forceMovement instanceof Vector3 and ($revert or $newPos->distance($this->forceMovement) > 0.2)){ if($this->forceMovement instanceof Vector3 and ($revert or $newPos->distance($this->forceMovement) > 0.2)){
$pk = MovePlayerPacket::getFromPool(); $pk = new MovePlayerPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $this->forceMovement->x; $pk->x = $this->forceMovement->x;
$pk->y = $this->forceMovement->y + $this->getEyeHeight() + 0.01; $pk->y = $this->forceMovement->y + $this->getEyeHeight() + 0.01;
@ -1567,36 +1553,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
break; break;
case ProtocolInfo::USE_ITEM_PACKET: case ProtocolInfo::USE_ITEM_PACKET:
if($this->spawned === false or $this->dead === true){ if($this->spawned === false or $this->dead === true or $this->blocked){
break; break;
} }
$blockVector = Vector3::createVector($packet->x, $packet->y, $packet->z); $blockVector = new Vector3($packet->x, $packet->y, $packet->z);
$this->craftingType = 0; $this->craftingType = 0;
if(($this->spawned === false or $this->blocked === true or $this->dead === true) and $packet->face >= 0 and $packet->face <= 5){
$target = $this->level->getBlock($blockVector);
$block = $target->getSide($packet->face);
$pk = UpdateBlockPacket::getFromPool();
$pk->x = $target->x;
$pk->y = $target->y;
$pk->z = $target->z;
$pk->block = $target->getID();
$pk->meta = $target->getDamage();
$this->dataPacket($pk);
$pk = UpdateBlockPacket::getFromPool();
$pk->x = $block->x;
$pk->y = $block->y;
$pk->z = $block->z;
$pk->block = $block->getID();
$pk->meta = $block->getDamage();
$this->dataPacket($pk);
break;
}
$packet->eid = $this->id; $packet->eid = $this->id;
if($packet->face >= 0 and $packet->face <= 5){ //Use Block, place if($packet->face >= 0 and $packet->face <= 5){ //Use Block, place
@ -1615,7 +1579,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
}elseif($this->inventory->getItemInHand()->getID() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){ }elseif($this->inventory->getItemInHand()->getID() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
$this->inventory->sendHeldItem($this); $this->inventory->sendHeldItem($this);
}else{ }else{
$item = clone $this->inventory->getItemInHand(); $item = $this->inventory->getItemInHand();
//TODO: Implement adventure mode checks //TODO: Implement adventure mode checks
if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){ if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
$this->inventory->setItemInHand($item, $this); $this->inventory->setItemInHand($item, $this);
@ -1626,7 +1590,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$target = $this->level->getBlock($blockVector); $target = $this->level->getBlock($blockVector);
$block = $target->getSide($packet->face); $block = $target->getSide($packet->face);
$pk = UpdateBlockPacket::getFromPool(); $pk = new UpdateBlockPacket();
$pk->x = $target->x; $pk->x = $target->x;
$pk->y = $target->y; $pk->y = $target->y;
$pk->z = $target->z; $pk->z = $target->z;
@ -1634,7 +1598,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$pk->meta = $target->getDamage(); $pk->meta = $target->getDamage();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = UpdateBlockPacket::getFromPool(); $pk = new UpdateBlockPacket();
$pk->x = $block->x; $pk->x = $block->x;
$pk->y = $block->y; $pk->y = $block->y;
$pk->z = $block->z; $pk->z = $block->z;
@ -1643,7 +1607,25 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->dataPacket($pk); $this->dataPacket($pk);
break; break;
}elseif($packet->face === 0xff){ }elseif($packet->face === 0xff){
$item = $this->inventory->getItemInHand(); if($this->isCreative()){
$item = $this->inventory->getItemInHand();
}elseif($this->inventory->getItemInHand()->getID() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
$this->inventory->sendHeldItem($this);
break;
}else{
$item = $this->inventory->getItemInHand();
}
$target = $this->level->getBlock($blockVector);
$ev = new PlayerInteractEvent($this, $item, $target, $packet->face);
$this->server->getPluginManager()->callEvent($ev);
if($ev->isCancelled()){
$this->inventory->sendHeldItem($this);
break;
}
if($item->getID() === Item::SNOWBALL){ if($item->getID() === Item::SNOWBALL){
$nbt = new Compound("", [ $nbt = new Compound("", [
"Pos" => new Enum("Pos", [ "Pos" => new Enum("Pos", [
@ -1666,10 +1648,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$snowball = Entity::createEntity("Snowball", $this->chunk, $nbt, $this); $snowball = Entity::createEntity("Snowball", $this->chunk, $nbt, $this);
$snowball->setMotion($snowball->getMotion()->multiply($f)); $snowball->setMotion($snowball->getMotion()->multiply($f));
if($this->isSurvival()){ if($this->isSurvival()){
$this->inventory->removeItem(Item::get(Item::SNOWBALL, 0, 1)); $this->inventory->removeItem(Item::get(Item::SNOWBALL, 0, 1), $this);
} }
if($snowball instanceof Projectile){ if($snowball instanceof Projectile){
$this->server->getPluginManager()->callEvent($projectileEv = ProjectileLaunchEvent::createEvent($snowball)); $this->server->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($snowball));
if($projectileEv->isCancelled()){ if($projectileEv->isCancelled()){
$snowball->kill(); $snowball->kill();
}else{ }else{
@ -1722,7 +1704,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
]); ]);
$f = 1.5; $f = 1.5;
$ev = EntityShootBowEvent::createEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this), $f); $ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this), $f);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
@ -1731,7 +1713,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
}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), $this);
$bow->setDamage($bow->getDamage() + 1); $bow->setDamage($bow->getDamage() + 1);
$this->inventory->setItemInHand($bow, $this); $this->inventory->setItemInHand($bow, $this);
if($bow->getDamage() >= 385){ if($bow->getDamage() >= 385){
@ -1739,7 +1721,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
if($ev->getProjectile() instanceof Projectile){ if($ev->getProjectile() instanceof Projectile){
$this->server->getPluginManager()->callEvent($projectileEv = ProjectileLaunchEvent::createEvent($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{
@ -1766,7 +1748,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$this->craftingType = 0; $this->craftingType = 0;
$vector = Vector3::createVector($packet->x, $packet->y, $packet->z); $vector = new Vector3($packet->x, $packet->y, $packet->z);
if($this->isCreative()){ if($this->isCreative()){
@ -1787,7 +1769,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$target = $this->level->getBlock($vector); $target = $this->level->getBlock($vector);
$tile = $this->level->getTile($vector); $tile = $this->level->getTile($vector);
$pk = UpdateBlockPacket::getFromPool(); $pk = new UpdateBlockPacket();
$pk->x = $target->x; $pk->x = $target->x;
$pk->y = $target->y; $pk->y = $target->y;
$pk->z = $target->z; $pk->z = $target->z;
@ -1804,7 +1786,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
break; break;
case ProtocolInfo::INTERACT_PACKET: case ProtocolInfo::INTERACT_PACKET:
if($this->spawned === false or $this->dead === true){ if($this->spawned === false or $this->dead === true or $this->blocked){
break; break;
} }
@ -1822,7 +1804,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$cancelled = true; $cancelled = true;
} }
if($target instanceof Entity and $this->getGamemode() !== Player::VIEW and $this->blocked === false and $this->dead !== true and $target->dead !== true){ if($target instanceof Entity and $this->getGamemode() !== Player::VIEW and $this->dead !== true and $target->dead !== true){
if($target instanceof DroppedItem or $target instanceof Arrow){ if($target instanceof DroppedItem or $target instanceof Arrow){
$this->kick("Attempting to attack an invalid entity"); $this->kick("Attempting to attack an invalid entity");
$this->server->getLogger()->warning("Player ". $this->getName() ." tried to attack an invalid entity"); $this->server->getLogger()->warning("Player ". $this->getName() ." tried to attack an invalid entity");
@ -1898,10 +1880,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
$damage[EntityDamageEvent::MODIFIER_ARMOR] = -intval($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04); $damage[EntityDamageEvent::MODIFIER_ARMOR] = -floor($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04);
} }
$ev = EntityDamageByEntityEvent::createEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage); $ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage);
if($cancelled){ if($cancelled){
$ev->setCancelled(); $ev->setCancelled();
} }
@ -1931,12 +1913,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
break; break;
} }
$this->server->getPluginManager()->callEvent($ev = PlayerAnimationEvent::createEvent($this, $packet->action)); $this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $packet->action));
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
$pk = AnimatePacket::getFromPool(); $pk = new AnimatePacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->action = $ev->getAnimationType(); $pk->action = $ev->getAnimationType();
Server::broadcastPacket($this->getViewers(), $pk); Server::broadcastPacket($this->getViewers(), $pk);
@ -1948,7 +1930,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->craftingType = 0; $this->craftingType = 0;
$this->server->getPluginManager()->callEvent($ev = PlayerRespawnEvent::createEvent($this, $this->getSpawn())); $this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn()));
$this->teleport($ev->getRespawnPosition()); $this->teleport($ev->getRespawnPosition());
$this->fireTicks = 0; $this->fireTicks = 0;
@ -2004,13 +1986,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
]; ];
$slot = $this->inventory->getItemInHand(); $slot = $this->inventory->getItemInHand();
if($this->getHealth() < 20 and isset($items[$slot->getID()])){ if($this->getHealth() < 20 and isset($items[$slot->getID()])){
$this->server->getPluginManager()->callEvent($ev = PlayerItemConsumeEvent::createEvent($this, $slot)); $this->server->getPluginManager()->callEvent($ev = new PlayerItemConsumeEvent($this, $slot));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
$pk = EntityEventPacket::getFromPool(); $pk = new EntityEventPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->event = 9; $pk->event = 9;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -2018,7 +2000,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
Server::broadcastPacket($this->getViewers(), $pk); Server::broadcastPacket($this->getViewers(), $pk);
$amount = $items[$slot->getID()]; $amount = $items[$slot->getID()];
$this->server->getPluginManager()->callEvent($ev = EntityRegainHealthEvent::createEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING)); $this->server->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->heal($ev->getAmount(), $ev); $this->heal($ev->getAmount(), $ev);
} }
@ -2026,7 +2008,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
--$slot->count; --$slot->count;
$this->inventory->setItemInHand($slot, $this); $this->inventory->setItemInHand($slot, $this);
if($slot->getID() === Item::MUSHROOM_STEW or $slot->getID() === Item::BEETROOT_SOUP){ if($slot->getID() === Item::MUSHROOM_STEW or $slot->getID() === Item::BEETROOT_SOUP){
$this->inventory->addItem(Item::get(Item::BOWL, 0, 1)); $this->inventory->addItem(Item::get(Item::BOWL, 0, 1), $this);
} }
} }
break; break;
@ -2038,7 +2020,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$packet->eid = $this->id; $packet->eid = $this->id;
$item = $this->inventory->getItemInHand(); $item = $this->inventory->getItemInHand();
$ev = PlayerDropItemEvent::createEvent($this, $item); $ev = new PlayerDropItemEvent($this, $item);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
@ -2063,7 +2045,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$packet->message = TextFormat::clean($packet->message); $packet->message = TextFormat::clean($packet->message);
if(trim($packet->message) != "" and strlen($packet->message) <= 255){ if(trim($packet->message) != "" and strlen($packet->message) <= 255){
$message = $packet->message; $message = $packet->message;
$this->server->getPluginManager()->callEvent($ev = PlayerCommandPreprocessEvent::createEvent($this, $message)); $this->server->getPluginManager()->callEvent($ev = new PlayerCommandPreprocessEvent($this, $message));
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
@ -2072,7 +2054,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1)); $this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1));
Timings::$playerCommandTimer->stopTiming(); Timings::$playerCommandTimer->stopTiming();
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = PlayerChatEvent::createEvent($this, $ev->getMessage())); $this->server->getPluginManager()->callEvent($ev = new PlayerChatEvent($this, $ev->getMessage()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->server->broadcastMessage(sprintf($ev->getFormat(), $ev->getPlayer()->getDisplayName(), $ev->getMessage()), $ev->getRecipients()); $this->server->broadcastMessage(sprintf($ev->getFormat(), $ev->getPlayer()->getDisplayName(), $ev->getMessage()), $ev->getRecipients());
} }
@ -2086,7 +2068,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->craftingType = 0; $this->craftingType = 0;
$this->currentTransaction = null; $this->currentTransaction = null;
if(isset($this->windowIndex[$packet->windowid])){ if(isset($this->windowIndex[$packet->windowid])){
$this->server->getPluginManager()->callEvent(InventoryCloseEvent::createEvent($this->windowIndex[$packet->windowid], $this)); $this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$packet->windowid], $this));
$this->removeWindow($this->windowIndex[$packet->windowid]); $this->removeWindow($this->windowIndex[$packet->windowid]);
}else{ }else{
unset($this->windowIndex[$packet->windowid]); unset($this->windowIndex[$packet->windowid]);
@ -2135,10 +2117,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 0.4)){ if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 0.4)){
if($this->currentTransaction instanceof SimpleTransactionGroup){ if($this->currentTransaction instanceof SimpleTransactionGroup){
foreach($this->currentTransaction->getInventories() as $inventory){ foreach($this->currentTransaction->getInventories() as $inventory){
$inventory->sendContents($inventory->getViewers());
if($inventory instanceof PlayerInventory){ if($inventory instanceof PlayerInventory){
$inventory->sendArmorContents($inventory->getViewers()); $inventory->sendArmorContents($this);
} }
$inventory->sendContents($this);
} }
} }
$this->currentTransaction = new SimpleTransactionGroup($this); $this->currentTransaction = new SimpleTransactionGroup($this);
@ -2196,7 +2178,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
case Item::CAKE: case Item::CAKE:
//TODO: detect complex recipes like cake that leave remains //TODO: detect complex recipes like cake that leave remains
$this->awardAchievement("bakeCake"); $this->awardAchievement("bakeCake");
$this->inventory->addItem(Item::get(Item::BUCKET, 0, 3)); $this->inventory->addItem(Item::get(Item::BUCKET, 0, 3), $this);
break; break;
case Item::STONE_PICKAXE: case Item::STONE_PICKAXE:
case Item::GOLD_PICKAXE: case Item::GOLD_PICKAXE:
@ -2233,7 +2215,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$this->craftingType = 0; $this->craftingType = 0;
$t = $this->level->getTile(Vector3::createVector($packet->x, $packet->y, $packet->z)); $t = $this->level->getTile(new Vector3($packet->x, $packet->y, $packet->z));
if($t instanceof Sign){ if($t instanceof Sign){
$nbt = new NBT(NBT::LITTLE_ENDIAN); $nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->read($packet->namedtag); $nbt->read($packet->namedtag);
@ -2241,7 +2223,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($nbt["id"] !== Tile::SIGN){ if($nbt["id"] !== Tile::SIGN){
$t->spawnTo($this); $t->spawnTo($this);
}else{ }else{
$ev = SignChangeEvent::createEvent($t->getBlock(), $this, [ $ev = new SignChangeEvent($t->getBlock(), $this, [
$nbt["Text1"], $nbt["Text2"], $nbt["Text3"], $nbt["Text4"] $nbt["Text1"], $nbt["Text2"], $nbt["Text3"], $nbt["Text4"]
]); ]);
@ -2272,7 +2254,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
* @return bool * @return bool
*/ */
public function kick($reason = ""){ public function kick($reason = ""){
$this->server->getPluginManager()->callEvent($ev = PlayerKickEvent::createEvent($this, $reason, TextFormat::YELLOW . $this->username . " has left the game")); $this->server->getPluginManager()->callEvent($ev = new PlayerKickEvent($this, $reason, TextFormat::YELLOW . $this->username . " has left the game"));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""); $message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : "");
$this->sendMessage($message); $this->sendMessage($message);
@ -2296,7 +2278,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$mes = explode("\n", $message); $mes = explode("\n", $message);
foreach($mes as $m){ foreach($mes as $m){
if($m !== ""){ if($m !== ""){
$pk = MessagePacket::getFromPool(); $pk = new MessagePacket();
$pk->source = ""; //Do not use this ;) $pk->source = ""; //Do not use this ;)
$pk->message = $m; $pk->message = $m;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -2318,7 +2300,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->connected and !$this->closed){ if($this->connected and !$this->closed){
$this->connected = false; $this->connected = false;
if($this->username != ""){ if($this->username != ""){
$this->server->getPluginManager()->callEvent($ev = PlayerQuitEvent::createEvent($this, $message)); $this->server->getPluginManager()->callEvent($ev = new PlayerQuitEvent($this, $message));
if($this->server->getAutoSave() and $this->loggedIn === true){ if($this->server->getAutoSave() and $this->loggedIn === true){
$this->save(); $this->save();
} }
@ -2329,7 +2311,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$this->interface->close($this, $reason); $this->interface->close($this, $reason);
$this->level->freeAllChunks($this);
$chunkX = $chunkZ = null;
foreach($this->usedChunks as $index => $d){
Level::getXZ($index, $chunkX, $chunkZ);
$this->level->freeChunk($chunkX, $chunkZ, $this);
}
parent::close(); parent::close();
@ -2346,6 +2333,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->windowIndex = []; $this->windowIndex = [];
$this->usedChunks = []; $this->usedChunks = [];
$this->loadQueue = []; $this->loadQueue = [];
$this->hasSpawned = [];
$this->spawnPosition = null; $this->spawnPosition = null;
unset($this->buffer); unset($this->buffer);
} }
@ -2488,7 +2476,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
Entity::kill(); Entity::kill();
$this->server->getPluginManager()->callEvent($ev = PlayerDeathEvent::createEvent($this, $this->getDrops(), $message)); $this->server->getPluginManager()->callEvent($ev = new PlayerDeathEvent($this, $this->getDrops(), $message));
if(!$ev->getKeepInventory()){ if(!$ev->getKeepInventory()){
foreach($ev->getDrops() as $item){ foreach($ev->getDrops() as $item){
@ -2511,7 +2499,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
public function setHealth($amount){ public function setHealth($amount){
parent::setHealth($amount); parent::setHealth($amount);
if($this->spawned === true){ if($this->spawned === true){
$pk = SetHealthPacket::getFromPool(); $pk = new SetHealthPacket();
$pk->health = $this->getHealth(); $pk->health = $this->getHealth();
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -2548,7 +2536,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($this->getLastDamageCause() === $source){ if($this->getLastDamageCause() === $source){
$pk = EntityEventPacket::getFromPool(); $pk = new EntityEventPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->event = 2; $pk->event = 2;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -2594,10 +2582,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->forceMovement = $pos; $this->forceMovement = $pos;
$this->newPosition = $pos; $this->newPosition = $pos;
$pk = MovePlayerPacket::getFromPool(); $pk = new MovePlayerPacket();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y + $this->getEyeHeight() + 0.01; $pk->y = $this->y + $this->getEyeHeight();
$pk->z = $this->z; $pk->z = $this->z;
$pk->bodyYaw = $this->yaw; $pk->bodyYaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;

View File

@ -121,11 +121,14 @@ namespace pocketmine {
$opts = getopt("", ["enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard", "enable-profiler"]); $opts = getopt("", ["enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard", "enable-profiler"]);
define("pocketmine\\DATA", isset($opts["data"]) ? realpath($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"]) ? realpath($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);
define("pocketmine\\ANSI", (Utils::getOS() !== "win" or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])); define("pocketmine\\ANSI", (Utils::getOS() !== "win" or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"]));
@mkdir(\pocketmine\DATA, 0777, true);
//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);

View File

@ -40,7 +40,6 @@ use pocketmine\entity\PrimedTNT;
use pocketmine\entity\Snowball; use pocketmine\entity\Snowball;
use pocketmine\entity\Villager; use pocketmine\entity\Villager;
use pocketmine\entity\Zombie; use pocketmine\entity\Zombie;
use pocketmine\event\Event;
use pocketmine\event\HandlerList; use pocketmine\event\HandlerList;
use pocketmine\event\level\LevelInitEvent; use pocketmine\event\level\LevelInitEvent;
use pocketmine\event\level\LevelLoadEvent; use pocketmine\event\level\LevelLoadEvent;
@ -60,9 +59,6 @@ use pocketmine\level\generator\GenerationRequestManager;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\generator\Normal; use pocketmine\level\generator\Normal;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\EntityMetadataStore;
use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\LevelMetadataStore;
use pocketmine\metadata\PlayerMetadataStore; use pocketmine\metadata\PlayerMetadataStore;
@ -132,6 +128,8 @@ class Server{
/** @var bool */ /** @var bool */
private $isRunning = true; private $isRunning = true;
private $hasStopped = false;
/** @var PluginManager */ /** @var PluginManager */
private $pluginManager = null; private $pluginManager = null;
@ -629,9 +627,16 @@ class Server{
* @param string $payload * @param string $payload
*/ */
public function handlePacket($address, $port, $payload){ public function handlePacket($address, $port, $payload){
if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){ try{
$this->queryHandler->handle($address, $port, $payload); if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){
} //TODO: add raw packet events $this->queryHandler->handle($address, $port, $payload);
}
}catch(\Exception $e){
if($this->logger instanceof MainLogger){
$this->logger->logException($e);
}
}
//TODO: add raw packet events
} }
/** /**
@ -934,7 +939,6 @@ class Server{
*/ */
public function unloadLevel(Level $level, $forceUnload = false){ public function unloadLevel(Level $level, $forceUnload = false){
if($level->unload($forceUnload) === true){ if($level->unload($forceUnload) === true){
Position::clearPositions();
unset($this->levels[$level->getID()]); unset($this->levels[$level->getID()]);
return true; return true;
@ -990,7 +994,7 @@ class Server{
$level->initLevel(); $level->initLevel();
$this->getPluginManager()->callEvent(LevelLoadEvent::createEvent($level)); $this->getPluginManager()->callEvent(new LevelLoadEvent($level));
/*foreach($entities->getAll() as $entity){ /*foreach($entities->getAll() as $entity){
if(!isset($entity["id"])){ if(!isset($entity["id"])){
@ -1125,9 +1129,9 @@ class Server{
$level->initLevel(); $level->initLevel();
$this->getPluginManager()->callEvent(LevelInitEvent::createEvent($level)); $this->getPluginManager()->callEvent(new LevelInitEvent($level));
$this->getPluginManager()->callEvent(LevelLoadEvent::createEvent($level)); $this->getPluginManager()->callEvent(new LevelLoadEvent($level));
$this->getLogger()->notice("Spawn terrain for level \"$name\" is being generated in the background"); $this->getLogger()->notice("Spawn terrain for level \"$name\" is being generated in the background");
@ -1447,11 +1451,12 @@ class Server{
$this->autoloader = $autoloader; $this->autoloader = $autoloader;
$this->logger = $logger; $this->logger = $logger;
$this->filePath = $filePath; $this->filePath = $filePath;
$this->dataPath = $dataPath; @mkdir($dataPath . "worlds/", 0777);
$this->pluginPath = $pluginPath; @mkdir($dataPath . "players/", 0777);
@mkdir($this->dataPath . "worlds/", 0777, true); @mkdir($pluginPath, 0777);
@mkdir($this->dataPath . "players/", 0777);
@mkdir($this->pluginPath, 0777); $this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
$this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
$this->entityMetadata = new EntityMetadataStore(); $this->entityMetadata = new EntityMetadataStore();
$this->playerMetadata = new PlayerMetadataStore(); $this->playerMetadata = new PlayerMetadataStore();
@ -1584,7 +1589,6 @@ class Server{
set_exception_handler([$this, "exceptionHandler"]); set_exception_handler([$this, "exceptionHandler"]);
register_shutdown_function([$this, "crashDump"]); register_shutdown_function([$this, "crashDump"]);
register_shutdown_function([$this, "forceShutdown"]);
$this->pluginManager->loadPlugins($this->pluginPath); $this->pluginManager->loadPlugins($this->pluginPath);
@ -1765,7 +1769,7 @@ class Server{
public function checkConsole(){ public function checkConsole(){
Timings::$serverCommandTimer->startTiming(); Timings::$serverCommandTimer->startTiming();
if(($line = $this->console->getLine()) !== null){ if(($line = $this->console->getLine()) !== null){
$this->pluginManager->callEvent($ev = ServerCommandEvent::createEvent($this->consoleSender, $line)); $this->pluginManager->callEvent($ev = new ServerCommandEvent($this->consoleSender, $line));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->dispatchCommand($ev->getSender(), $ev->getCommand()); $this->dispatchCommand($ev->getSender(), $ev->getCommand());
} }
@ -1853,40 +1857,54 @@ class Server{
} }
public function forceShutdown(){ public function forceShutdown(){
$this->shutdown(); if($this->hasStopped){
if($this->rcon instanceof RCON){ return;
$this->rcon->stop();
} }
if($this->getProperty("settings.upnp-forwarding", false) === true){ try{
$this->logger->info("[UPnP] Removing port forward..."); $this->hasStopped = true;
UPnP::RemovePortForward($this->getPort());
$this->shutdown();
if($this->rcon instanceof RCON){
$this->rcon->stop();
}
if($this->getProperty("settings.upnp-forwarding", false) === true){
$this->logger->info("[UPnP] Removing port forward...");
UPnP::RemovePortForward($this->getPort());
}
$this->pluginManager->disablePlugins();
foreach($this->players as $player){
$player->close(TextFormat::YELLOW . $player->getName() . " has left the game", $this->getProperty("settings.shutdown-message", "Server closed"));
}
foreach($this->getLevels() as $level){
$this->unloadLevel($level, true);
}
if($this->generationManager instanceof GenerationRequestManager){
$this->generationManager->shutdown();
}
HandlerList::unregisterAll();
$this->scheduler->cancelAllTasks();
$this->scheduler->mainThreadHeartbeat(PHP_INT_MAX);
$this->properties->save();
$this->console->kill();
foreach($this->interfaces as $interface){
$interface->shutdown();
}
}catch (\Exception $e){
$this->logger->emergency("Crashed while crashing, killing process");
@kill(getmypid());
} }
$this->pluginManager->disablePlugins();
foreach($this->players as $player){
$player->close(TextFormat::YELLOW . $player->getName() . " has left the game", $this->getProperty("settings.shutdown-message", "Server closed"));
}
foreach($this->getLevels() as $level){
$this->unloadLevel($level, true);
}
if($this->generationManager instanceof GenerationRequestManager){
$this->generationManager->shutdown();
}
HandlerList::unregisterAll();
$this->scheduler->cancelAllTasks();
$this->scheduler->mainThreadHeartbeat(PHP_INT_MAX);
$this->properties->save();
$this->console->kill();
foreach($this->interfaces as $interface){
$interface->shutdown();
}
} }
/** /**
@ -1984,22 +2002,23 @@ class Server{
"fullFile" => $e->getFile(), "fullFile" => $e->getFile(),
"file" => $errfile, "file" => $errfile,
"line" => $errline, "line" => $errline,
"trace" => getTrace($trace === null ? 3 : 0, $trace) "trace" => @getTrace($trace === null ? 3 : 0, $trace)
]; ];
global $lastExceptionError, $lastError; global $lastExceptionError, $lastError;
$lastExceptionError = $lastError; $lastExceptionError = $lastError;
$this->crashDump(); $this->crashDump();
$this->forceShutdown();
kill(getmypid());
exit(1);
} }
public function crashDump(){ public function crashDump(){
if($this->isRunning === false){ if($this->isRunning === false){
return; return;
} }
ini_set("memory_limit", "-1"); //Fix error dump not dumped on memory problems $this->isRunning = false;
$this->hasStopped = false;
ini_set("error_reporting", 0);
ini_set("memory_limit", -1); //Fix error dump not dumped on memory problems
$this->logger->emergency("An unrecoverable error has occurred and the server has crashed. Creating a crash dump"); $this->logger->emergency("An unrecoverable error has occurred and the server has crashed. Creating a crash dump");
$dump = new CrashDump($this); $dump = new CrashDump($this);
@ -2007,36 +2026,42 @@ class Server{
if($this->getProperty("auto-report.enabled", true) !== false){ if($this->getProperty("auto-report.enabled", true) !== false){
$report = true;
$plugin = $dump->getData()["plugin"]; $plugin = $dump->getData()["plugin"];
if(is_string($plugin)){ if(is_string($plugin)){
$p = $this->pluginManager->getPlugin($plugin); $p = $this->pluginManager->getPlugin($plugin);
if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){ if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){
return; $report = false;
} }
}elseif(\Phar::running(true) == ""){ }elseif(\Phar::running(true) == ""){
return; $report = false;
} }
if($dump->getData()["error"]["type"] === "E_PARSE" or $dump->getData()["error"]["type"] === "E_COMPILE_ERROR"){ if($dump->getData()["error"]["type"] === "E_PARSE" or $dump->getData()["error"]["type"] === "E_COMPILE_ERROR"){
return; $report = false;
} }
$reply = Utils::postURL("http://" . $this->getProperty("auto-report.host", "crash.pocketmine.net") . "/submit/api", [ if($report){
"report" => "yes", $reply = Utils::postURL("http://" . $this->getProperty("auto-report.host", "crash.pocketmine.net") . "/submit/api", [
"name" => $this->getName() . " " . $this->getPocketMineVersion(), "report" => "yes",
"email" => "crash@pocketmine.net", "name" => $this->getName() . " " . $this->getPocketMineVersion(),
"reportPaste" => base64_encode($dump->getEncodedData()) "email" => "crash@pocketmine.net",
]); "reportPaste" => base64_encode($dump->getEncodedData())
]);
if(($data = json_decode($reply)) !== false and isset($data->crashId)){ if(($data = json_decode($reply)) !== false and isset($data->crashId)){
$reportId = $data->crashId; $reportId = $data->crashId;
$reportUrl = $data->crashUrl; $reportUrl = $data->crashUrl;
$this->logger->emergency("The crash dump has been automatically submitted to the Crash Archive. You can view it on $reportUrl or use the ID #$reportId."); $this->logger->emergency("The crash dump has been automatically submitted to the Crash Archive. You can view it on $reportUrl or use the ID #$reportId.");
}
} }
} }
//$this->checkMemory(); //$this->checkMemory();
//$dump .= "Memory Usage Tracking: \r\n" . chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9))) . "\r\n"; //$dump .= "Memory Usage Tracking: \r\n" . chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9))) . "\r\n";
$this->forceShutdown();
@kill(getmypid());
exit(1);
} }
public function __debugInfo(){ public function __debugInfo(){
@ -2157,26 +2182,25 @@ class Server{
if(($this->tickCounter & 0b1111) === 0){ if(($this->tickCounter & 0b1111) === 0){
$this->titleTick(); $this->titleTick();
if(isset($this->queryHandler) and ($this->tickCounter & 0b111111111) === 0){ if(isset($this->queryHandler) and ($this->tickCounter & 0b111111111) === 0){
$this->queryHandler->regenerateInfo(); try{
$this->queryHandler->regenerateInfo();
}catch(\Exception $e){
if($this->logger instanceof MainLogger){
$this->logger->logException($e);
}
}
} }
} }
$this->generationManager->process(); $this->generationManager->process();
if(($this->tickCounter % 100) === 0){
Vector3::clearVectorList(); foreach($this->levels as $level){
Position::clearPositionList(); $level->clearCache();
if(($this->tickCounter % 4) === 0){
Event::clearAllPools();
if(($this->tickCounter % 80) === 0){
foreach($this->levels as $level){
$level->clearCache();
}
AxisAlignedBB::clearBoundingBoxPool();
} }
} }
Timings::$serverTickTimer->stopTiming(); Timings::$serverTickTimer->stopTiming();
TimingsHandler::tick(); TimingsHandler::tick();

View File

@ -36,7 +36,7 @@ class Bed extends Transparent{
} }
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -53,7 +53,7 @@ class Bed extends Transparent{
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE); $isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
if($player instanceof Player and !$isNight){ if($player instanceof Player and !$isNight){
$pk = ChatPacket::getFromPool(); $pk = new ChatPacket();
$pk->message = "You can only sleep at night"; $pk->message = "You can only sleep at night";
$player->dataPacket($pk); $player->dataPacket($pk);
@ -77,7 +77,7 @@ class Bed extends Transparent{
$b = $blockWest; $b = $blockWest;
}else{ }else{
if($player instanceof Player){ if($player instanceof Player){
$pk = ChatPacket::getFromPool(); $pk = new ChatPacket();
$pk->message = "This bed is incomplete"; $pk->message = "This bed is incomplete";
$player->dataPacket($pk); $player->dataPacket($pk);
} }
@ -87,7 +87,7 @@ class Bed extends Transparent{
} }
if($player instanceof Player and $player->sleepOn($b) === false){ if($player instanceof Player and $player->sleepOn($b) === false){
$pk = ChatPacket::getFromPool(); $pk = new ChatPacket();
$pk->message = "This bed is occupied"; $pk->message = "This bed is occupied";
$player->dataPacket($pk); $player->dataPacket($pk);
} }

View File

@ -526,8 +526,8 @@ class Block extends Position implements Metadatable{
]; ];
/** @var Block[] */ /** @var \SplFixedArray */
public static $list = []; public static $list = null;
protected $id; protected $id;
protected $meta; protected $meta;
protected $name = "Unknown"; protected $name = "Unknown";
@ -553,156 +553,155 @@ class Block extends Position implements Metadatable{
protected $boundingBox = null; protected $boundingBox = null;
public static function init(){ public static function init(){
if(count(self::$list) === 0){ if(self::$list === null){
self::$list = [ self::$list = new \SplFixedArray(256);
self::AIR => Air::class, self::$list[self::AIR] = Air::class;;
self::STONE => Stone::class, self::$list[self::STONE] = Stone::class;;
self::GRASS => Grass::class, self::$list[self::GRASS] = Grass::class;;
self::DIRT => Dirt::class, self::$list[self::DIRT] = Dirt::class;;
self::COBBLESTONE => Cobblestone::class, self::$list[self::COBBLESTONE] = Cobblestone::class;;
self::PLANKS => Planks::class, self::$list[self::PLANKS] = Planks::class;;
self::SAPLING => Sapling::class, self::$list[self::SAPLING] = Sapling::class;;
self::BEDROCK => Bedrock::class, self::$list[self::BEDROCK] = Bedrock::class;;
self::WATER => Water::class, self::$list[self::WATER] = Water::class;;
self::STILL_WATER => StillWater::class, self::$list[self::STILL_WATER] = StillWater::class;;
self::LAVA => Lava::class, self::$list[self::LAVA] = Lava::class;;
self::STILL_LAVA => StillLava::class, self::$list[self::STILL_LAVA] = StillLava::class;;
self::SAND => Sand::class, self::$list[self::SAND] = Sand::class;;
self::GRAVEL => Gravel::class, self::$list[self::GRAVEL] = Gravel::class;;
self::GOLD_ORE => GoldOre::class, self::$list[self::GOLD_ORE] = GoldOre::class;;
self::IRON_ORE => IronOre::class, self::$list[self::IRON_ORE] = IronOre::class;;
self::COAL_ORE => CoalOre::class, self::$list[self::COAL_ORE] = CoalOre::class;;
self::WOOD => Wood::class, self::$list[self::WOOD] = Wood::class;;
self::LEAVES => Leaves::class, self::$list[self::LEAVES] = Leaves::class;;
self::SPONGE => Sponge::class, self::$list[self::SPONGE] = Sponge::class;;
self::GLASS => Glass::class, self::$list[self::GLASS] = Glass::class;;
self::LAPIS_ORE => LapisOre::class, self::$list[self::LAPIS_ORE] = LapisOre::class;;
self::LAPIS_BLOCK => Lapis::class, self::$list[self::LAPIS_BLOCK] = Lapis::class;;
self::SANDSTONE => Sandstone::class, self::$list[self::SANDSTONE] = Sandstone::class;;
self::BED_BLOCK => Bed::class, self::$list[self::BED_BLOCK] = Bed::class;;
self::COBWEB => Cobweb::class, self::$list[self::COBWEB] = Cobweb::class;;
self::TALL_GRASS => TallGrass::class, self::$list[self::TALL_GRASS] = TallGrass::class;;
self::DEAD_BUSH => DeadBush::class, self::$list[self::DEAD_BUSH] = DeadBush::class;;
self::WOOL => Wool::class, self::$list[self::WOOL] = Wool::class;;
self::DANDELION => Dandelion::class, self::$list[self::DANDELION] = Dandelion::class;;
self::POPPY => CyanFlower::class, self::$list[self::POPPY] = CyanFlower::class;;
self::BROWN_MUSHROOM => BrownMushroom::class, self::$list[self::BROWN_MUSHROOM] = BrownMushroom::class;;
self::RED_MUSHROOM => RedMushroom::class, self::$list[self::RED_MUSHROOM] = RedMushroom::class;;
self::GOLD_BLOCK => Gold::class, self::$list[self::GOLD_BLOCK] = Gold::class;;
self::IRON_BLOCK => Iron::class, self::$list[self::IRON_BLOCK] = Iron::class;;
self::DOUBLE_SLAB => DoubleSlab::class, self::$list[self::DOUBLE_SLAB] = DoubleSlab::class;;
self::SLAB => Slab::class, self::$list[self::SLAB] = Slab::class;;
self::BRICKS_BLOCK => Bricks::class, self::$list[self::BRICKS_BLOCK] = Bricks::class;;
self::TNT => TNT::class, self::$list[self::TNT] = TNT::class;;
self::BOOKSHELF => Bookshelf::class, self::$list[self::BOOKSHELF] = Bookshelf::class;;
self::MOSS_STONE => MossStone::class, self::$list[self::MOSS_STONE] = MossStone::class;;
self::OBSIDIAN => Obsidian::class, self::$list[self::OBSIDIAN] = Obsidian::class;;
self::TORCH => Torch::class, self::$list[self::TORCH] = Torch::class;;
self::FIRE => Fire::class, self::$list[self::FIRE] = Fire::class;;
self::MONSTER_SPAWNER => MonsterSpawner::class, self::$list[self::MONSTER_SPAWNER] = MonsterSpawner::class;;
self::WOOD_STAIRS => WoodStairs::class, self::$list[self::WOOD_STAIRS] = WoodStairs::class;;
self::CHEST => Chest::class, self::$list[self::CHEST] = Chest::class;;
self::DIAMOND_ORE => DiamondOre::class, self::$list[self::DIAMOND_ORE] = DiamondOre::class;;
self::DIAMOND_BLOCK => Diamond::class, self::$list[self::DIAMOND_BLOCK] = Diamond::class;;
self::WORKBENCH => Workbench::class, self::$list[self::WORKBENCH] = Workbench::class;;
self::WHEAT_BLOCK => Wheat::class, self::$list[self::WHEAT_BLOCK] = Wheat::class;;
self::FARMLAND => Farmland::class, self::$list[self::FARMLAND] = Farmland::class;;
self::FURNACE => Furnace::class, self::$list[self::FURNACE] = Furnace::class;;
self::BURNING_FURNACE => BurningFurnace::class, self::$list[self::BURNING_FURNACE] = BurningFurnace::class;;
self::SIGN_POST => SignPost::class, self::$list[self::SIGN_POST] = SignPost::class;;
self::WOOD_DOOR_BLOCK => WoodDoor::class, self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class;;
self::LADDER => Ladder::class, self::$list[self::LADDER] = Ladder::class;;
self::COBBLESTONE_STAIRS => CobblestoneStairs::class, self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class;;
self::WALL_SIGN => WallSign::class, self::$list[self::WALL_SIGN] = WallSign::class;;
self::IRON_DOOR_BLOCK => IronDoor::class, self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class;;
self::REDSTONE_ORE => RedstoneOre::class, self::$list[self::REDSTONE_ORE] = RedstoneOre::class;;
self::GLOWING_REDSTONE_ORE => GlowingRedstoneOre::class, self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class;;
self::SNOW_LAYER => SnowLayer::class, self::$list[self::SNOW_LAYER] = SnowLayer::class;;
self::ICE => Ice::class, self::$list[self::ICE] = Ice::class;;
self::SNOW_BLOCK => Snow::class, self::$list[self::SNOW_BLOCK] = Snow::class;;
self::CACTUS => Cactus::class, self::$list[self::CACTUS] = Cactus::class;;
self::CLAY_BLOCK => Clay::class, self::$list[self::CLAY_BLOCK] = Clay::class;;
self::SUGARCANE_BLOCK => Sugarcane::class, self::$list[self::SUGARCANE_BLOCK] = Sugarcane::class;;
self::FENCE => Fence::class, self::$list[self::FENCE] = Fence::class;;
self::PUMPKIN => Pumpkin::class, self::$list[self::PUMPKIN] = Pumpkin::class;;
self::NETHERRACK => Netherrack::class, self::$list[self::NETHERRACK] = Netherrack::class;;
self::SOUL_SAND => SoulSand::class, self::$list[self::SOUL_SAND] = SoulSand::class;;
self::GLOWSTONE_BLOCK => Glowstone::class, self::$list[self::GLOWSTONE_BLOCK] = Glowstone::class;;
self::LIT_PUMPKIN => LitPumpkin::class, self::$list[self::LIT_PUMPKIN] = LitPumpkin::class;;
self::CAKE_BLOCK => Cake::class, self::$list[self::CAKE_BLOCK] = Cake::class;;
self::TRAPDOOR => Trapdoor::class, self::$list[self::TRAPDOOR] = Trapdoor::class;;
self::STONE_BRICKS => StoneBricks::class, self::$list[self::STONE_BRICKS] = StoneBricks::class;;
self::IRON_BARS => IronBars::class, self::$list[self::IRON_BARS] = IronBars::class;;
self::GLASS_PANE => GlassPane::class, self::$list[self::GLASS_PANE] = GlassPane::class;;
self::MELON_BLOCK => Melon::class, self::$list[self::MELON_BLOCK] = Melon::class;;
self::PUMPKIN_STEM => PumpkinStem::class, self::$list[self::PUMPKIN_STEM] = PumpkinStem::class;;
self::MELON_STEM => MelonStem::class, self::$list[self::MELON_STEM] = MelonStem::class;;
self::VINE => Vine::class, self::$list[self::VINE] = Vine::class;;
self::FENCE_GATE => FenceGate::class, self::$list[self::FENCE_GATE] = FenceGate::class;;
self::BRICK_STAIRS => BrickStairs::class, self::$list[self::BRICK_STAIRS] = BrickStairs::class;;
self::STONE_BRICK_STAIRS => StoneBrickStairs::class, self::$list[self::STONE_BRICK_STAIRS] = StoneBrickStairs::class;;
self::MYCELIUM => Mycelium::class, self::$list[self::MYCELIUM] = Mycelium::class;;
self::NETHER_BRICKS => NetherBrick::class, self::$list[self::NETHER_BRICKS] = NetherBrick::class;;
self::NETHER_BRICKS_STAIRS => NetherBrickStairs::class, self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class;;
self::END_PORTAL => EndPortal::class, self::$list[self::END_PORTAL] = EndPortal::class;;
self::END_STONE => EndStone::class, self::$list[self::END_STONE] = EndStone::class;;
self::SANDSTONE_STAIRS => SandstoneStairs::class, self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;;
self::EMERALD_ORE => EmeraldOre::class, self::$list[self::EMERALD_ORE] = EmeraldOre::class;;
self::EMERALD_BLOCK => Emerald::class, self::$list[self::EMERALD_BLOCK] = Emerald::class;;
self::SPRUCE_WOOD_STAIRS => SpruceWoodStairs::class, self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class;;
self::BIRCH_WOOD_STAIRS => BirchWoodStairs::class, self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;;
self::JUNGLE_WOOD_STAIRS => JungleWoodStairs::class, self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class;;
self::STONE_WALL => StoneWall::class, self::$list[self::STONE_WALL] = StoneWall::class;;
self::CARROT_BLOCK => Carrot::class, self::$list[self::CARROT_BLOCK] = Carrot::class;;
self::POTATO_BLOCK => Potato::class, self::$list[self::POTATO_BLOCK] = Potato::class;;
self::QUARTZ_BLOCK => Quartz::class, self::$list[self::QUARTZ_BLOCK] = Quartz::class;;
self::QUARTZ_STAIRS => QuartzStairs::class, self::$list[self::QUARTZ_STAIRS] = QuartzStairs::class;;
self::DOUBLE_WOOD_SLAB => DoubleWoodSlab::class, self::$list[self::DOUBLE_WOOD_SLAB] = DoubleWoodSlab::class;;
self::WOOD_SLAB => WoodSlab::class, self::$list[self::WOOD_SLAB] = WoodSlab::class;;
self::STAINED_CLAY => StainedClay::class, self::$list[self::STAINED_CLAY] = StainedClay::class;;
self::LEAVES2 => Leaves2::class, self::$list[self::LEAVES2] = Leaves2::class;;
self::WOOD2 => Wood2::class, self::$list[self::WOOD2] = Wood2::class;;
self::ACACIA_WOOD_STAIRS => AcaciaWoodStairs::class, self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class;;
self::DARK_OAK_WOOD_STAIRS => DarkOakWoodStairs::class, self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class;;
self::HAY_BALE => HayBale::class, self::$list[self::HAY_BALE] = HayBale::class;;
self::CARPET => Carpet::class, self::$list[self::CARPET] = Carpet::class;;
self::HARDENED_CLAY => HardenedClay::class, self::$list[self::HARDENED_CLAY] = HardenedClay::class;;
self::COAL_BLOCK => Coal::class, self::$list[self::COAL_BLOCK] = Coal::class;;
self::FENCE_GATE_SPRUCE => FenceGateSpruce::class, self::$list[self::FENCE_GATE_SPRUCE] = FenceGateSpruce::class;
self::FENCE_GATE_BIRCH => FenceGateBirch::class, self::$list[self::FENCE_GATE_BIRCH] = FenceGateBirch::class;
self::FENCE_GATE_JUNGLE => FenceGateJungle::class, self::$list[self::FENCE_GATE_JUNGLE] = FenceGateJungle::class;
self::FENCE_GATE_DARK_OAK => FenceGateDarkOak::class, self::$list[self::FENCE_GATE_DARK_OAK] = FenceGateDarkOak::class;
self::FENCE_GATE_ACACIA => FenceGateAcacia::class, self::$list[self::FENCE_GATE_ACACIA] = FenceGateAcacia::class;
self::FENCE_SPRUCE => FenceSpruce::class, self::$list[self::FENCE_SPRUCE] = FenceSpruce::class;
self::FENCE_BIRCH => FenceBirch::class, self::$list[self::FENCE_BIRCH] = FenceBirch::class;
self::FENCE_DARK_OAK => FenceDarkOak::class, self::$list[self::FENCE_DARK_OAK] = FenceDarkOak::class;
self::FENCE_JUNGLE => FenceJungle::class, self::$list[self::FENCE_JUNGLE] = FenceJungle::class;
self::FENCE_ACACIA => FenceAcacia::class, self::$list[self::FENCE_ACACIA] = FenceAcacia::class;
self::PODZOL => Podzol::class, self::$list[self::PODZOL] = Podzol::class;;
self::BEETROOT_BLOCK => Beetroot::class, self::$list[self::BEETROOT_BLOCK] = Beetroot::class;;
self::STONECUTTER => Stonecutter::class, self::$list[self::STONECUTTER] = Stonecutter::class;;
self::GLOWING_OBSIDIAN => GlowingObsidian::class, self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class;;
self::NETHER_REACTOR => NetherReactor::class, self::$list[self::NETHER_REACTOR] = NetherReactor::class;;
];
} }
} }
@ -714,10 +713,14 @@ class Block extends Position implements Metadatable{
* @return Block * @return Block
*/ */
public static function get($id, $meta = 0, Position $pos = null){ public static function get($id, $meta = 0, Position $pos = null){
if(isset(self::$list[$id])){ try{
$block = self::$list[$id]; $block = self::$list[$id];
$block = new $block($meta); if($block !== null){
}else{ $block = new $block($meta);
}else{
$block = new Block($id, $meta);
}
}catch(\RuntimeException $e){
$block = new Block($id, $meta); $block = new Block($id, $meta);
} }
@ -822,7 +825,7 @@ class Block extends Position implements Metadatable{
/** /**
* @return int * @return int
*/ */
final public function getID(){ final public function getId(){
return $this->id; return $this->id;
} }
@ -943,7 +946,7 @@ class Block extends Position implements Metadatable{
* @return AxisAlignedBB * @return AxisAlignedBB
*/ */
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -44,7 +44,7 @@ class Cactus extends Transparent{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + 0.0625, $this->x + 0.0625,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,
@ -55,7 +55,7 @@ class Cactus extends Transparent{
} }
public function onEntityCollide(Entity $entity){ public function onEntityCollide(Entity $entity){
$ev = EntityDamageByBlockEvent::createEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
$entity->attack($ev->getFinalDamage(), $ev); $entity->attack($ev->getFinalDamage(), $ev);
} }
@ -76,9 +76,9 @@ class Cactus extends Transparent{
if($this->getSide(0)->getID() !== self::CACTUS){ if($this->getSide(0)->getID() !== self::CACTUS){
if($this->meta == 0x0F){ if($this->meta == 0x0F){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(Vector3::createVector($this->x, $this->y + $y, $this->z)); $b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
if($b->getID() === self::AIR){ if($b->getID() === self::AIR){
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($b, new Cactus())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($b, $ev->getNewState(), true); $this->getLevel()->setBlock($b, $ev->getNewState(), true);
} }

View File

@ -41,7 +41,7 @@ class Cake extends Transparent{
$f = (1 + $this->getDamage() * 2) / 16; $f = (1 + $this->getDamage() * 2) / 16;
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,
@ -81,7 +81,7 @@ class Cake extends Transparent{
public function onActivate(Item $item, Player $player = null){ public function onActivate(Item $item, Player $player = null){
if($player instanceof Player and $player->getHealth() < 20){ if($player instanceof Player and $player->getHealth() < 20){
++$this->meta; ++$this->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = EntityRegainHealthEvent::createEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->heal($ev->getAmount(), $ev); $player->heal($ev->getAmount(), $ev);
} }

View File

@ -55,7 +55,7 @@ class Carpet extends Flowable{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -44,7 +44,7 @@ class Chest extends Transparent{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + 0.0625, $this->x + 0.0625,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,

View File

@ -57,7 +57,7 @@ abstract class Crops extends Flowable{
$block->meta = 7; $block->meta = 7;
} }
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true); $this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
@ -82,7 +82,7 @@ abstract class Crops extends Flowable{
if($this->meta < 0x07){ if($this->meta < 0x07){
$block = clone $this; $block = clone $this;
++$block->meta; ++$block->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true); $this->getLevel()->setBlock($this, $ev->getNewState(), true, true);

View File

@ -57,7 +57,7 @@ abstract class Door extends Transparent{
$f = 0.1875; $f = 0.1875;
$damage = $this->getFullDamage(); $damage = $this->getFullDamage();
$bb = AxisAlignedBB::getBoundingBoxFromPool( $bb = new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -271,7 +271,7 @@ abstract class Door extends Transparent{
if($player instanceof Player){ if($player instanceof Player){
unset($players[$player->getID()]); unset($players[$player->getID()]);
} }
$pk = LevelEventPacket::getFromPool(); $pk = new LevelEventPacket();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;
@ -290,7 +290,7 @@ abstract class Door extends Transparent{
if($player instanceof Player){ if($player instanceof Player){
unset($players[$player->getID()]); unset($players[$player->getID()]);
} }
$pk = LevelEventPacket::getFromPool(); $pk = new LevelEventPacket();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;

View File

@ -31,7 +31,7 @@ class EndPortal extends Solid{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -32,7 +32,7 @@ class Farmland extends Solid{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -42,7 +42,7 @@ class Fence extends Transparent{
$f2 = $flag ? 0 : 0.375; $f2 = $flag ? 0 : 0.375;
$f3 = $flag1 ? 1 : 0.625; $f3 = $flag1 ? 1 : 0.625;
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + $f2, $this->z + $f2,

View File

@ -46,7 +46,7 @@ class FenceGate extends Transparent{
$i = ($this->getDamage() & 0x03); $i = ($this->getDamage() & 0x03);
if($i === 2 and $i === 0){ if($i === 2 and $i === 0){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 0.375, $this->z + 0.375,
@ -55,7 +55,7 @@ class FenceGate extends Transparent{
$this->z + 0.625 $this->z + 0.625
); );
}else{ }else{
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + 0.375, $this->x + 0.375,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -46,10 +46,10 @@ class Fire extends Flowable{
} }
public function onEntityCollide(Entity $entity){ public function onEntityCollide(Entity $entity){
$ev = EntityDamageByBlockEvent::createEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
$entity->attack($ev->getFinalDamage(), $ev); $entity->attack($ev->getFinalDamage(), $ev);
$ev = EntityCombustByBlockEvent::createEvent($this, $entity, 8); $ev = new EntityCombustByBlockEvent($this, $entity, 8);
Server::getInstance()->getPluginManager()->callEvent($ev); Server::getInstance()->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$entity->setOnFire($ev->getDuration()); $entity->setOnFire($ev->getDuration());

View File

@ -25,7 +25,6 @@ use pocketmine\event\block\BlockSpreadEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\generator\object\TallGrass as TallGrassObject; use pocketmine\level\generator\object\TallGrass as TallGrassObject;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;
@ -55,10 +54,10 @@ class Grass extends Solid{
$x = mt_rand($this->x - 1, $this->x + 1); $x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 2, $this->y + 2); $y = mt_rand($this->y - 2, $this->y + 2);
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z)); $block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
if($block->getID() === Block::DIRT){ if($block->getID() === Block::DIRT){
if($block->getSide(1) instanceof Transparent){ if($block->getSide(1) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = BlockSpreadEvent::createEvent($block, $this, new Grass())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($block, $ev->getNewState()); $this->getLevel()->setBlock($block, $ev->getNewState());
} }

View File

@ -48,7 +48,7 @@ class Ladder extends Transparent{
$f = 0.125; $f = 0.125;
if($this->meta === 2){ if($this->meta === 2){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 1 - $f, $this->z + 1 - $f,
@ -57,7 +57,7 @@ class Ladder extends Transparent{
$this->z + 1 $this->z + 1
); );
}elseif($this->meta === 3){ }elseif($this->meta === 3){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -66,7 +66,7 @@ class Ladder extends Transparent{
$this->z + $f $this->z + $f
); );
}elseif($this->meta === 4){ }elseif($this->meta === 4){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + 1 - $f, $this->x + 1 - $f,
$this->y, $this->y,
$this->z, $this->z,
@ -75,7 +75,7 @@ class Ladder extends Transparent{
$this->z + 1 $this->z + 1
); );
}elseif($this->meta === 5){ }elseif($this->meta === 5){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -38,10 +38,10 @@ class Lava extends Liquid{
public function onEntityCollide(Entity $entity){ public function onEntityCollide(Entity $entity){
$entity->fallDistance *= 0.5; $entity->fallDistance *= 0.5;
$ev = EntityDamageByBlockEvent::createEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4);
$entity->attack($ev->getFinalDamage(), $ev); $entity->attack($ev->getFinalDamage(), $ev);
$ev = EntityCombustByBlockEvent::createEvent($this, $entity, 15); $ev = new EntityCombustByBlockEvent($this, $entity, 15);
Server::getInstance()->getPluginManager()->callEvent($ev); Server::getInstance()->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$entity->setOnFire($ev->getDuration()); $entity->setOnFire($ev->getDuration());

View File

@ -124,7 +124,7 @@ class Leaves extends Transparent{
$visited = []; $visited = [];
$check = 0; $check = 0;
Server::getInstance()->getPluginManager()->callEvent($ev = LeavesDecayEvent::createEvent($this)); Server::getInstance()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this));
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){ if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
$this->getLevel()->setBlock($this, $this, false, false); $this->getLevel()->setBlock($this, $this, false, false);

View File

@ -116,7 +116,7 @@ class Leaves2 extends Leaves{
$visited = []; $visited = [];
$check = 0; $check = 0;
Server::getInstance()->getPluginManager()->callEvent($ev = LeavesDecayEvent::createEvent($this)); Server::getInstance()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this));
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){ if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
$this->getLevel()->setBlock($this, $this, false, false); $this->getLevel()->setBlock($this, $this, false, false);

View File

@ -80,7 +80,7 @@ abstract class Liquid extends Transparent{
} }
public function getFlowVector(){ public function getFlowVector(){
$vector = Vector3::createVector(0, 0, 0); $vector = new Vector3(0, 0, 0);
$decay = $this->getEffectiveFlowDecay($this); $decay = $this->getEffectiveFlowDecay($this);
@ -99,7 +99,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$sideBlock = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z)); $sideBlock = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
$blockDecay = $this->getEffectiveFlowDecay($sideBlock); $blockDecay = $this->getEffectiveFlowDecay($sideBlock);
if($blockDecay < 0){ if($blockDecay < 0){
@ -314,7 +314,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$blockSide = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z)); $blockSide = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
if(!$blockSide->isFlowable and !($blockSide instanceof Liquid)){ if(!$blockSide->isFlowable and !($blockSide instanceof Liquid)){
continue; continue;
@ -356,7 +356,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$block = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z)); $block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
if(!$block->isFlowable and !($block instanceof Liquid)){ if(!$block->isFlowable and !($block instanceof Liquid)){
continue; continue;

View File

@ -42,7 +42,7 @@ class MelonStem extends Crops{
if($this->meta < 0x07){ if($this->meta < 0x07){
$block = clone $this; $block = clone $this;
++$block->meta; ++$block->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true); $this->getLevel()->setBlock($this, $ev->getNewState(), true);
} }
@ -58,7 +58,7 @@ class MelonStem extends Crops{
$side = $this->getSide(mt_rand(2, 5)); $side = $this->getSide(mt_rand(2, 5));
$d = $side->getSide(0); $d = $side->getSide(0);
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){ if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($side, new Melon())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, new Melon()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($side, $ev->getNewState(), true); $this->getLevel()->setBlock($side, $ev->getNewState(), true);
} }

View File

@ -24,7 +24,6 @@ namespace pocketmine\block;
use pocketmine\event\block\BlockSpreadEvent; use pocketmine\event\block\BlockSpreadEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\Server; use pocketmine\Server;
@ -46,10 +45,10 @@ class Mycelium extends Solid{
$x = mt_rand($this->x - 1, $this->x + 1); $x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 2, $this->y + 2); $y = mt_rand($this->y - 2, $this->y + 2);
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z)); $block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
if($block->getID() === Block::DIRT){ if($block->getID() === Block::DIRT){
if($block->getSide(1) instanceof Transparent){ if($block->getSide(1) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = BlockSpreadEvent::createEvent($block, $this, new Mycelium())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($block, $ev->getNewState()); $this->getLevel()->setBlock($block, $ev->getNewState());
} }

View File

@ -42,7 +42,7 @@ class PumpkinStem extends Crops{
if($this->meta < 0x07){ if($this->meta < 0x07){
$block = clone $this; $block = clone $this;
++$block->meta; ++$block->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true); $this->getLevel()->setBlock($this, $ev->getNewState(), true);
} }
@ -58,7 +58,7 @@ class PumpkinStem extends Crops{
$side = $this->getSide(mt_rand(2, 5)); $side = $this->getSide(mt_rand(2, 5));
$d = $side->getSide(0); $d = $side->getSide(0);
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){ if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($side, new Pumpkin())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, new Pumpkin()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($side, $ev->getNewState(), true); $this->getLevel()->setBlock($side, $ev->getNewState(), true);
} }

View File

@ -50,7 +50,7 @@ class Slab extends Transparent{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
if(($this->meta & 0x08) > 0){ if(($this->meta & 0x08) > 0){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y + 0.5, $this->y + 0.5,
$this->z, $this->z,
@ -59,7 +59,7 @@ class Slab extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -32,7 +32,7 @@ class SoulSand extends Solid{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -116,7 +116,7 @@ abstract class Stair extends Transparent{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
if(($this->getDamage() & 0x04) > 0){ if(($this->getDamage() & 0x04) > 0){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y + 0.5, $this->y + 0.5,
$this->z, $this->z,
@ -125,7 +125,7 @@ abstract class Stair extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -22,6 +22,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\Tool;
class Stone extends Solid{ class Stone extends Solid{
const NORMAL = 0; const NORMAL = 0;
@ -45,6 +46,7 @@ class Stone extends Solid{
self::POLISHED_DIORITE => "Polished Diorite", self::POLISHED_DIORITE => "Polished Diorite",
self::ANDESITE => "Andesite", self::ANDESITE => "Andesite",
self::POLISHED_ANDESITE => "Polished Andesite", self::POLISHED_ANDESITE => "Polished Andesite",
7 => "Unknown Stone",
]; ];
$this->name = $names[$this->meta & 0x07]; $this->name = $names[$this->meta & 0x07];
} }
@ -67,7 +69,7 @@ class Stone extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::COBBLESTONE, 0, 1], [Item::COBBLESTONE, 0, 1],
]; ];

View File

@ -59,7 +59,7 @@ class StoneWall extends Transparent{
$f3 = 0.6875; $f3 = 0.6875;
} }
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + $f2, $this->z + $f2,

View File

@ -49,9 +49,9 @@ class Sugarcane extends Flowable{
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){ if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(Vector3::createVector($this->x, $this->y + $y, $this->z)); $b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
if($b->getID() === self::AIR){ if($b->getID() === self::AIR){
Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($b, new Sugarcane())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Sugarcane()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($b, $ev->getNewState(), true); $this->getLevel()->setBlock($b, $ev->getNewState(), true);
} }
@ -83,7 +83,7 @@ class Sugarcane extends Flowable{
if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){ if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){
if($this->meta === 0x0F){ if($this->meta === 0x0F){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(Vector3::createVector($this->x, $this->y + $y, $this->z)); $b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
if($b->getID() === self::AIR){ if($b->getID() === self::AIR){
$this->getLevel()->setBlock($b, new Sugarcane(), true); $this->getLevel()->setBlock($b, new Sugarcane(), true);
break; break;

View File

@ -63,7 +63,7 @@ abstract class Thin extends Transparent{
$f3 = 1; $f3 = 1;
} }
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + $f2, $this->z + $f2,

View File

@ -44,7 +44,7 @@ class Trapdoor extends Transparent{
$f = 0.1875; $f = 0.1875;
if(($damage & 0x08) > 0){ if(($damage & 0x08) > 0){
$bb = AxisAlignedBB::getBoundingBoxFromPool( $bb = new AxisAlignedBB(
$this->x, $this->x,
$this->y + 1 - $f, $this->y + 1 - $f,
$this->z, $this->z,
@ -53,7 +53,7 @@ class Trapdoor extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
$bb = AxisAlignedBB::getBoundingBoxFromPool( $bb = new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -93,7 +93,7 @@ class Vine extends Transparent{
$f6 = 1; $f6 = 1;
} }
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x + $f1, $this->x + $f1,
$this->y + $f2, $this->y + $f2,
$this->z + $f3, $this->z + $f3,

View File

@ -48,7 +48,7 @@ class WoodSlab extends Transparent{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
if(($this->meta & 0x08) > 0){ if(($this->meta & 0x08) > 0){
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y + 0.5, $this->y + 0.5,
$this->z, $this->z,
@ -57,7 +57,7 @@ class WoodSlab extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
return AxisAlignedBB::getBoundingBoxFromPool( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -44,7 +44,7 @@ class KillCommand extends VanillaCommand{
} }
if($sender instanceof Player){ if($sender instanceof Player){
$sender->getServer()->getPluginManager()->callEvent($ev = EntityDamageEvent::createEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000)); $sender->getServer()->getPluginManager()->callEvent($ev = new EntityDamageEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000));
if($ev->isCancelled()){ if($ev->isCancelled()){
return true; return true;

View File

@ -46,8 +46,7 @@ class SetWorldSpawnCommand extends VanillaCommand{
if(count($args) === 0){ if(count($args) === 0){
if($sender instanceof Player){ if($sender instanceof Player){
$level = $sender->getLevel(); $level = $sender->getLevel();
$pos = Vector3::cloneVector($sender); $pos = (new Vector3($sender->x, $sender->y, $sender->z))->round();
$pos = $pos->round();
}else{ }else{
$sender->sendMessage(TextFormat::RED . "You can only perform this command as a player"); $sender->sendMessage(TextFormat::RED . "You can only perform this command as a player");

View File

@ -70,14 +70,14 @@ class SpawnpointCommand extends VanillaCommand{
$x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]); $x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]);
$y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128); $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128);
$z = $this->getRelativeDouble($pos->z, $sender, $args[3]); $z = $this->getRelativeDouble($pos->z, $sender, $args[3]);
$target->setSpawn(Position::createPosition($x, $y, $z, $level)); $target->setSpawn(new Position($x, $y, $z, $level));
Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z);
return true; return true;
} }
}elseif(count($args) <= 1){ }elseif(count($args) <= 1){
if($sender instanceof Player){ if($sender instanceof Player){
$pos = Position::createPosition((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel()); $pos = new Position((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel());
$target->setSpawn($pos); $target->setSpawn($pos);
Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);

View File

@ -23,7 +23,6 @@ namespace pocketmine\command\defaults;
use pocketmine\command\Command; use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
@ -88,8 +87,7 @@ class TeleportCommand extends VanillaCommand{
} }
if(count($args) < 3){ if(count($args) < 3){
$pos = Position::clonePosition($target); $origin->teleport($target);
$origin->teleport($pos);
Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName()); Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName());
return true; return true;
@ -98,7 +96,7 @@ class TeleportCommand extends VanillaCommand{
$x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]); $x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]);
$y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 128); $y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 128);
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos]); $z = $this->getRelativeDouble($target->z, $sender, $args[$pos]);
$target->teleport(Vector3::createVector($x, $y, $z)); $target->teleport(new Vector3($x, $y, $z));
Command::broadcastCommandMessage($sender, "Teleported " . $target->getDisplayName() . " to " . round($x, 2) . ", " . round($y, 2) . ", " . round($z, 2)); Command::broadcastCommandMessage($sender, "Teleported " . $target->getDisplayName() . " to " . round($x, 2) . ", " . round($y, 2) . ", " . round($z, 2));
return true; return true;

View File

@ -32,12 +32,47 @@ class TimeCommand extends VanillaCommand{
parent::__construct( parent::__construct(
$name, $name,
"Changes the time on each world", "Changes the time on each world",
"/time set <value>\n/time add <value>" "/time set <value>\n/time add <value>\n/time start|stop"
); );
$this->setPermission("pocketmine.command.time.add;pocketmine.command.time.set"); $this->setPermission("pocketmine.command.time.add;pocketmine.command.time.set;pocketmine.command.time.start;pocketmine.command.time.stop");
} }
public function execute(CommandSender $sender, $currentAlias, array $args){ public function execute(CommandSender $sender, $currentAlias, array $args){
if(count($args) < 1){
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
return false;
}
if($args[0] === "start"){
if(!$sender->hasPermission("pocketmine.command.time.start")){
$sender->sendMessage(TextFormat::RED . "You don't have permission to restart the time");
return true;
}
foreach($sender->getServer()->getLevels() as $level){
$level->checkTime();
$level->startTime();
$level->checkTime();
}
Command::broadcastCommandMessage($sender, "Restarted the time");
return true;
}elseif($args[0] === "stop"){
if(!$sender->hasPermission("pocketmine.command.time.stop")){
$sender->sendMessage(TextFormat::RED . "You don't have permission to stop the time");
return true;
}
foreach($sender->getServer()->getLevels() as $level){
$level->checkTime();
$level->stopTime();
$level->checkTime();
}
Command::broadcastCommandMessage($sender, "Stopped the time");
return true;
}
if(count($args) < 2){ if(count($args) < 2){
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage); $sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
@ -78,6 +113,7 @@ class TimeCommand extends VanillaCommand{
$level->setTime($level->getTime() + $value); $level->setTime($level->getTime() + $value);
$level->checkTime(); $level->checkTime();
} }
Command::broadcastCommandMessage($sender, "Added " . $value ." to time");
}else{ }else{
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage); $sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
} }

View File

@ -93,40 +93,39 @@ class TimingsCommand extends VanillaCommand{
if($paste){ if($paste){
fseek($fileTimings, 0); fseek($fileTimings, 0);
$data = [ $data = [
"public" => false, "syntax" => "text",
"description" => $sender->getServer()->getName() . " Timings", "poster" => $sender->getServer()->getName(),
"files" => [ "content" => stream_get_contents($fileTimings)
"timings.txt" => [
"content" => stream_get_contents($fileTimings)
]
]
]; ];
$ch = curl_init("https://api.github.com/gists"); $ch = curl_init("http://paste.ubuntu.com/");
curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1); curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_SLASHES)); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json", "User-Agent: " . $this->getName() . " " . $sender->getServer()->getPocketMineVersion()]); curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["User-Agent: " . $this->getName() . " " . $sender->getServer()->getPocketMineVersion()]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch); $data = curl_exec($ch);
$data = json_decode($ret);
curl_close($ch); curl_close($ch);
if($data === false or $data === null or !isset($data->html_url)){ if(preg_match('#^Location: http://paste\\.ubuntu\\.com/([0-9]{1,})/#m', $data, $matches) == 0){
$sender->sendMessage("An error happened while pasting the report"); $sender->sendMessage("An error happened while pasting the report");
return true; return true;
} }
$timings = $data->html_url;
}
fclose($fileTimings);
$sender->sendMessage("Timings written to " . $timings); $sender->sendMessage("Timings uploaded to http://paste.ubuntu.com/".$matches[1]."/");
$sender->sendMessage("Paste contents of file into form at http://aikar.co/timings.php to read results."); $sender->sendMessage("You can read the results at http://timings.aikar.co/?url=".$matches[1]);
fclose($fileTimings);
}else{
fclose($fileTimings);
$sender->sendMessage("Timings written to " . $timings);
}
} }
return true; return true;

View File

@ -23,7 +23,6 @@ namespace pocketmine\entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
@ -45,12 +44,6 @@ class Arrow extends Projectile{
parent::__construct($chunk, $nbt); parent::__construct($chunk, $nbt);
} }
protected function initEntity(){
$this->namedtag->id = new String("id", "Arrow");
parent::initEntity();
}
public function onUpdate($currentTick){ public function onUpdate($currentTick){
if($this->closed){ if($this->closed){
return false; return false;
@ -71,7 +64,7 @@ class Arrow extends Projectile{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddEntityPacket::getFromPool(); $pk = new AddEntityPacket();
$pk->type = Arrow::NETWORK_ID; $pk->type = Arrow::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
@ -80,7 +73,7 @@ class Arrow extends Projectile{
$pk->did = 0; //TODO: send motion here $pk->did = 0; //TODO: send motion here
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -22,11 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Chicken extends Animal{ class Chicken extends Animal{
protected function initEntity(){
$this->namedtag->id = new String("id", "Chicken");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Cow extends Animal{ class Cow extends Animal{
protected function initEntity(){
$this->namedtag->id = new String("id", "Cow");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Creeper extends Monster implements Explosive{ class Creeper extends Monster implements Explosive{
protected function initEntity(){
$this->namedtag->id = new String("id", "Creeper");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Egg extends Projectile{ class Egg extends Projectile{
protected function initEntity(){
$this->namedtag->id = new String("id", "Egg");
}
} }

View File

@ -23,10 +23,7 @@ namespace pocketmine\entity;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\nbt\tag\String;
class Enderman extends Monster implements InventoryHolder{ class Enderman extends Monster implements InventoryHolder{
protected function initEntity(){
$this->namedtag->id = new String("id", "Enderman");
}
} }

View File

@ -49,6 +49,7 @@ use pocketmine\nbt\tag\Double;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\Float;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\Short;
use pocketmine\nbt\tag\String;
use pocketmine\Network; use pocketmine\Network;
use pocketmine\network\protocol\MoveEntityPacket; use pocketmine\network\protocol\MoveEntityPacket;
use pocketmine\network\protocol\MovePlayerPacket; use pocketmine\network\protocol\MovePlayerPacket;
@ -69,6 +70,7 @@ abstract class Entity extends Location implements Metadatable{
public static $entityCount = 1; public static $entityCount = 1;
/** @var Entity[] */ /** @var Entity[] */
private static $knownEntities = []; private static $knownEntities = [];
private static $shortNames = [];
/** /**
* @var Player[] * @var Player[]
@ -138,7 +140,10 @@ abstract class Entity extends Location implements Metadatable{
public $canCollide = true; public $canCollide = true;
protected $isStatic = false; protected $isStatic = false;
protected $isColliding = false;
public $isCollided = false;
public $isCollidedHorizontally = false;
public $isCollidedVertically = false;
public $noDamageTicks; public $noDamageTicks;
private $justCreated; private $justCreated;
@ -177,7 +182,7 @@ abstract class Entity extends Location implements Metadatable{
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
$this->setPositionAndRotation( $this->setPositionAndRotation(
Vector3::createVector( new Vector3(
$this->namedtag["Pos"][0], $this->namedtag["Pos"][0],
$this->namedtag["Pos"][1], $this->namedtag["Pos"][1],
$this->namedtag["Pos"][2] $this->namedtag["Pos"][2]
@ -186,7 +191,7 @@ abstract class Entity extends Location implements Metadatable{
$this->namedtag->Rotation[1], $this->namedtag->Rotation[1],
true true
); );
$this->setMotion(Vector3::createVector($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2])); $this->setMotion(new Vector3($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2]));
if(!isset($this->namedtag->FallDistance)){ if(!isset($this->namedtag->FallDistance)){
$this->namedtag->FallDistance = new Float("FallDistance", 0); $this->namedtag->FallDistance = new Float("FallDistance", 0);
@ -217,7 +222,7 @@ abstract class Entity extends Location implements Metadatable{
$this->level->addEntity($this); $this->level->addEntity($this);
$this->initEntity(); $this->initEntity();
$this->lastUpdate = $this->server->getTick(); $this->lastUpdate = $this->server->getTick();
$this->server->getPluginManager()->callEvent(EntitySpawnEvent::createEvent($this)); $this->server->getPluginManager()->callEvent(new EntitySpawnEvent($this));
$this->scheduleUpdate(); $this->scheduleUpdate();
@ -250,13 +255,27 @@ abstract class Entity extends Location implements Metadatable{
} }
self::$knownEntities[$class->getShortName()] = $className; self::$knownEntities[$class->getShortName()] = $className;
self::$shortNames[$className] = $class->getShortName();
return true; return true;
} }
return false; return false;
} }
/**
* Returns the short save name
*
* @return string
*/
public function getSaveId(){
return self::$shortNames[static::class];
}
public function saveNBT(){ public function saveNBT(){
if(!($this instanceof Player)){
$this->namedtag->id = new String("id", $this->getSaveId());
}
$this->namedtag->Pos = new Enum("Pos", [ $this->namedtag->Pos = new Enum("Pos", [
new Double(0, $this->x), new Double(0, $this->x),
new Double(1, $this->y), new Double(1, $this->y),
@ -307,7 +326,7 @@ abstract class Entity extends Location implements Metadatable{
$player = [$player]; $player = [$player];
} }
$pk = SetEntityDataPacket::getFromPool(); $pk = new SetEntityDataPacket();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$pk->encode(); $pk->encode();
@ -315,7 +334,7 @@ abstract class Entity extends Location implements Metadatable{
foreach($player as $p){ foreach($player as $p){
if($p === $this){ if($p === $this){
/** @var Player $p */ /** @var Player $p */
$pk2 = SetEntityDataPacket::getFromPool(); $pk2 = new SetEntityDataPacket();
$pk2->eid = 0; $pk2->eid = 0;
$pk2->metadata = $this->getData(); $pk2->metadata = $this->getData();
$p->dataPacket($pk2); $p->dataPacket($pk2);
@ -330,7 +349,7 @@ abstract class Entity extends Location implements Metadatable{
*/ */
public function despawnFrom(Player $player){ public function despawnFrom(Player $player){
if(isset($this->hasSpawned[$player->getID()])){ if(isset($this->hasSpawned[$player->getID()])){
$pk = RemoveEntityPacket::getFromPool(); $pk = new RemoveEntityPacket();
$pk->eid = $this->id; $pk->eid = $this->id;
$player->dataPacket($pk); $player->dataPacket($pk);
unset($this->hasSpawned[$player->getID()]); unset($this->hasSpawned[$player->getID()]);
@ -424,7 +443,7 @@ abstract class Entity extends Location implements Metadatable{
$list = $this->level->getCollisionBlocks($this->boundingBox); $list = $this->level->getCollisionBlocks($this->boundingBox);
$v = Vector3::createVector($i, $j, $k); $v = new Vector3($i, $j, $k);
if(count($list) === 0 and !$this->level->isFullBlock($v->setComponents($i, $j, $k))){ if(count($list) === 0 and !$this->level->isFullBlock($v->setComponents($i, $j, $k))){
return false; return false;
@ -522,7 +541,7 @@ abstract class Entity extends Location implements Metadatable{
$this->checkBlockCollision(); $this->checkBlockCollision();
if($this->y < 0 and $this->dead !== true){ if($this->y < 0 and $this->dead !== true){
$ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_VOID, 10); $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10);
$this->attack($ev->getFinalDamage(), $ev); $this->attack($ev->getFinalDamage(), $ev);
$hasUpdate = true; $hasUpdate = true;
} }
@ -535,7 +554,7 @@ abstract class Entity extends Location implements Metadatable{
} }
}else{ }else{
if(($this->fireTicks % 20) === 0 or $tickDiff > 20){ if(($this->fireTicks % 20) === 0 or $tickDiff > 20){
$ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1); $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1);
$this->attack($ev->getFinalDamage(), $ev); $this->attack($ev->getFinalDamage(), $ev);
} }
$this->fireTicks -= $tickDiff; $this->fireTicks -= $tickDiff;
@ -566,7 +585,7 @@ abstract class Entity extends Location implements Metadatable{
$this->lastPitch = $this->pitch; $this->lastPitch = $this->pitch;
if($this instanceof Human){ if($this instanceof Human){
$pk = MovePlayerPacket::getFromPool(); $pk = new MovePlayerPacket();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -576,7 +595,7 @@ abstract class Entity extends Location implements Metadatable{
$pk->bodyYaw = $this->yaw; $pk->bodyYaw = $this->yaw;
}else{ }else{
//TODO: add to move list //TODO: add to move list
$pk = MoveEntityPacket::getFromPool(); $pk = new MoveEntityPacket();
$pk->entities = [ $pk->entities = [
[$this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch] [$this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch]
]; ];
@ -590,7 +609,7 @@ abstract class Entity extends Location implements Metadatable{
$this->lastMotionY = $this->motionY; $this->lastMotionY = $this->motionY;
$this->lastMotionZ = $this->motionZ; $this->lastMotionZ = $this->motionZ;
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -617,7 +636,7 @@ abstract class Entity extends Location implements Metadatable{
$x = -$xz * sin(deg2rad($this->yaw)); $x = -$xz * sin(deg2rad($this->yaw));
$z = $xz * cos(deg2rad($this->yaw)); $z = $xz * cos(deg2rad($this->yaw));
return Vector3::createVector($x, $y, $z); return new Vector3($x, $y, $z);
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){
@ -709,7 +728,7 @@ abstract class Entity extends Location implements Metadatable{
public function fall($fallDistance){ public function fall($fallDistance){
$damage = floor($fallDistance - 3); $damage = floor($fallDistance - 3);
if($damage > 0){ if($damage > 0){
$ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage);
$this->attack($ev->getFinalDamage(), $ev); $this->attack($ev->getFinalDamage(), $ev);
} }
} }
@ -732,32 +751,30 @@ abstract class Entity extends Location implements Metadatable{
protected function switchLevel(Level $targetLevel){ protected function switchLevel(Level $targetLevel){
if($this->isValid()){ if($this->isValid()){
$this->server->getPluginManager()->callEvent($ev = EntityLevelChangeEvent::createEvent($this, $this->level, $targetLevel)); $this->server->getPluginManager()->callEvent($ev = new EntityLevelChangeEvent($this, $this->level, $targetLevel));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
$this->level->removeEntity($this); $this->level->removeEntity($this);
$this->chunk->removeEntity($this); if($this->chunk !== null){
$this->chunk->removeEntity($this);
}
$this->despawnFromAll(); $this->despawnFromAll();
if($this instanceof Player){ if($this instanceof Player){
foreach($this->usedChunks as $index => $d){ foreach($this->usedChunks as $index => $d){
$X = null; $X = null;
$Z = null; $Z = null;
Level::getXZ($index, $X, $Z); Level::getXZ($index, $X, $Z);
foreach($this->level->getChunkEntities($X, $Z) as $entity){ $this->unloadChunk($X, $Z);
$entity->despawnFrom($this);
}
} }
$this->level->freeAllChunks($this);
} }
} }
$this->setLevel($targetLevel, $this instanceof Player ? true : false); //Hard reference $this->setLevel($targetLevel);
$this->level->addEntity($this); $this->level->addEntity($this);
if($this instanceof Player){ if($this instanceof Player){
$this->usedChunks = []; $this->usedChunks = [];
$pk = SetTimePacket::getFromPool(); $pk = new SetTimePacket();
$pk->time = $this->level->getTime(); $pk->time = $this->level->getTime();
$pk->started = $this->level->stopTime == false; $pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -768,7 +785,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function getPosition(){ public function getPosition(){
return Position::createPosition($this->x, $this->y, $this->z, $this->level); return new Position($this->x, $this->y, $this->z, $this->level);
} }
public function getLocation(){ public function getLocation(){
@ -776,7 +793,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function isInsideOfWater(){ public function isInsideOfWater(){
$block = $this->level->getBlock(Vector3::createVector(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z))); $block = $this->level->getBlock(new Vector3(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z)));
if($block instanceof Water){ if($block instanceof Water){
$f = ($block->y + 1) - ($block->getFluidHeightPercent() - 0.1111111); $f = ($block->y + 1) - ($block->getFluidHeightPercent() - 0.1111111);
@ -787,7 +804,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function isInsideOfSolid(){ public function isInsideOfSolid(){
$block = $this->level->getBlock(Vector3::createVector(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z))); $block = $this->level->getBlock(new Vector3(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z)));
$bb = $block->getBoundingBox(); $bb = $block->getBoundingBox();
@ -797,11 +814,6 @@ abstract class Entity extends Location implements Metadatable{
return false; return false;
} }
public function collision(){
$this->isColliding = true;
$this->fallDistance = 0;
}
public function move($dx, $dy, $dz){ public function move($dx, $dy, $dz){
if($dx == 0 and $dz == 0 and $dy == 0){ if($dx == 0 and $dz == 0 and $dy == 0){
@ -810,7 +822,7 @@ abstract class Entity extends Location implements Metadatable{
if($this->keepMovement){ if($this->keepMovement){
$this->boundingBox->offset($dx, $dy, $dz); $this->boundingBox->offset($dx, $dy, $dz);
$this->setPosition(Vector3::createVector(($this->boundingBox->minX + $this->boundingBox->maxX) / 2, $this->boundingBox->minY - $this->ySize, ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2)); $this->setPosition(new Vector3(($this->boundingBox->minX + $this->boundingBox->maxX) / 2, $this->boundingBox->minY - $this->ySize, ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2));
$this->onGround = $this instanceof Player ? true : false; $this->onGround = $this instanceof Player ? true : false;
}else{ }else{
@ -834,7 +846,7 @@ abstract class Entity extends Location implements Metadatable{
$movY = $dy; $movY = $dy;
$movZ = $dz; $movZ = $dz;
$axisalignedbb = AxisAlignedBB::cloneBoundingBoxFromPool($this->boundingBox); $axisalignedbb = clone $this->boundingBox;
/*$sneakFlag = $this->onGround and $this instanceof Player; /*$sneakFlag = $this->onGround and $this instanceof Player;
@ -912,7 +924,7 @@ abstract class Entity extends Location implements Metadatable{
$dy = $this->stepHeight; $dy = $this->stepHeight;
$dz = $movZ; $dz = $movZ;
$axisalignedbb1 = AxisAlignedBB::cloneBoundingBoxFromPool($this->boundingBox); $axisalignedbb1 = clone $this->boundingBox;
$this->boundingBox->setBB($axisalignedbb); $this->boundingBox->setBB($axisalignedbb);
@ -972,7 +984,7 @@ abstract class Entity extends Location implements Metadatable{
} }
$pos = Vector3::createVector( $pos = new Vector3(
($this->boundingBox->minX + $this->boundingBox->maxX) / 2, ($this->boundingBox->minX + $this->boundingBox->maxX) / 2,
$this->boundingBox->minY - $this->ySize, $this->boundingBox->minY - $this->ySize,
($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2 ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2
@ -987,7 +999,7 @@ abstract class Entity extends Location implements Metadatable{
if($this instanceof Player){ if($this instanceof Player){
if(!$this->onGround or $movY != 0){ if(!$this->onGround or $movY != 0){
$bb = AxisAlignedBB::cloneBoundingBoxFromPool($this->boundingBox); $bb = clone $this->boundingBox;
$bb->maxY = $bb->minY + 1; $bb->maxY = $bb->minY + 1;
if(count($this->level->getCollisionBlocks($bb->expand(0.01, 0.01, 0.01))) > 0){ if(count($this->level->getCollisionBlocks($bb->expand(0.01, 0.01, 0.01))) > 0){
$this->onGround = true; $this->onGround = true;
@ -995,7 +1007,11 @@ abstract class Entity extends Location implements Metadatable{
$this->onGround = false; $this->onGround = false;
} }
} }
$this->isCollided = $this->onGround;
}else{ }else{
$this->isCollidedVertically = $movY != $dy;
$this->isCollidedHorizontally = ($movX != $dx or $movZ != $dz);
$this->isCollided = ($this->isCollidedHorizontally or $this->isCollidedVertically);
$this->onGround = ($movY != $dy and $movY < 0); $this->onGround = ($movY != $dy and $movY < 0);
} }
$this->updateFallState($dy, $this->onGround); $this->updateFallState($dy, $this->onGround);
@ -1029,8 +1045,8 @@ abstract class Entity extends Location implements Metadatable{
$maxY = Math::floorFloat($this->boundingBox->maxY - 0.001); $maxY = Math::floorFloat($this->boundingBox->maxY - 0.001);
$maxZ = Math::floorFloat($this->boundingBox->maxZ - 0.001); $maxZ = Math::floorFloat($this->boundingBox->maxZ - 0.001);
$vector = Vector3::createVector(0, 0, 0); $vector = new Vector3(0, 0, 0);
$v = Vector3::createVector(0, 0, 0); $v = new Vector3(0, 0, 0);
for($v->z = $minZ; $v->z <= $maxZ; ++$v->z){ for($v->z = $minZ; $v->z <= $maxZ; ++$v->z){
for($v->x = $minX; $v->x <= $maxX; ++$v->x){ for($v->x = $minX; $v->x <= $maxX; ++$v->x){
@ -1072,6 +1088,10 @@ abstract class Entity extends Location implements Metadatable{
} }
public function setPosition(Vector3 $pos){ public function setPosition(Vector3 $pos){
if($this->closed){
return false;
}
if($pos instanceof Position and $pos->level instanceof Level and $pos->level !== $this->level){ if($pos instanceof Position and $pos->level instanceof Level and $pos->level !== $this->level){
if($this->switchLevel($pos->getLevel()) === false){ if($this->switchLevel($pos->getLevel()) === false){
return false; return false;
@ -1114,12 +1134,12 @@ abstract class Entity extends Location implements Metadatable{
} }
public function getMotion(){ public function getMotion(){
return Vector3::createVector($this->motionX, $this->motionY, $this->motionZ); return new Vector3($this->motionX, $this->motionY, $this->motionZ);
} }
public function setMotion(Vector3 $motion){ public function setMotion(Vector3 $motion){
if(!$this->justCreated){ if(!$this->justCreated){
$this->server->getPluginManager()->callEvent($ev = EntityMotionEvent::createEvent($this, $motion)); $this->server->getPluginManager()->callEvent($ev = new EntityMotionEvent($this, $motion));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1131,7 +1151,7 @@ abstract class Entity extends Location implements Metadatable{
if(!$this->justCreated){ if(!$this->justCreated){
if($this instanceof Player){ if($this instanceof Player){
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[0, $this->motionX, $this->motionY, $this->motionZ] [0, $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -1170,14 +1190,14 @@ abstract class Entity extends Location implements Metadatable{
} }
$from = Position::fromObject($this, $this->level); $from = Position::fromObject($this, $this->level);
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level); $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level);
$this->server->getPluginManager()->callEvent($ev = EntityTeleportEvent::createEvent($this, $from, $to)); $this->server->getPluginManager()->callEvent($ev = new EntityTeleportEvent($this, $from, $to));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
$this->ySize = 0; $this->ySize = 0;
$pos = $ev->getTo(); $pos = $ev->getTo();
$this->setMotion(Vector3::createVector(0, 0, 0)); $this->setMotion(new Vector3(0, 0, 0));
if($this->setPositionAndRotation($pos, $yaw === null ? $this->yaw : $yaw, $pitch === null ? $this->pitch : $pitch, true) !== false){ if($this->setPositionAndRotation($pos, $yaw === null ? $this->yaw : $yaw, $pitch === null ? $this->pitch : $pitch, true) !== false){
$this->fallDistance = 0; $this->fallDistance = 0;
$this->onGround = true; $this->onGround = true;
@ -1208,7 +1228,7 @@ abstract class Entity extends Location implements Metadatable{
public function close(){ public function close(){
if(!$this->closed){ if(!$this->closed){
$this->server->getPluginManager()->callEvent(EntityDespawnEvent::createEvent($this)); $this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this));
$this->closed = true; $this->closed = true;
unset($this->level->updateEntities[$this->id]); unset($this->level->updateEntities[$this->id]);
if($this->chunk instanceof FullChunk){ if($this->chunk instanceof FullChunk){

View File

@ -30,7 +30,6 @@ use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
@ -50,7 +49,6 @@ class FallingSand extends Entity{
public $canCollide = false; public $canCollide = false;
protected function initEntity(){ protected function initEntity(){
$this->namedtag->id = new String("id", "FallingSand");
if(isset($this->namedtag->TileID)){ if(isset($this->namedtag->TileID)){
$this->blockId = $this->namedtag["TileID"]; $this->blockId = $this->namedtag["TileID"];
}elseif(isset($this->namedtag->Tile)){ }elseif(isset($this->namedtag->Tile)){
@ -90,8 +88,7 @@ class FallingSand extends Entity{
if(!$this->dead){ if(!$this->dead){
if($this->ticksLived === 1){ if($this->ticksLived === 1){
$pos = Vector3::cloneVector($this); $block = $this->level->getBlock($pos = (new Vector3($this->x, $this->y, $this->z))->floor());
$block = $this->level->getBlock($pos->floor());
if($block->getID() != $this->blockId){ if($block->getID() != $this->blockId){
$this->kill(); $this->kill();
return true; return true;
@ -110,8 +107,7 @@ class FallingSand extends Entity{
$this->motionY *= 1 - $this->drag; $this->motionY *= 1 - $this->drag;
$this->motionZ *= $friction; $this->motionZ *= $friction;
$pos = Vector3::cloneVector($this); $pos = (new Vector3($this->x, $this->y, $this->z))->floor();
$pos = $pos->floor();
if($this->onGround){ if($this->onGround){
$this->kill(); $this->kill();
@ -119,7 +115,7 @@ class FallingSand extends Entity{
if(!$block->isFullBlock){ if(!$block->isFullBlock){
$this->getLevel()->dropItem($this, ItemItem::get($this->getBlock(), $this->getDamage(), 1)); $this->getLevel()->dropItem($this, ItemItem::get($this->getBlock(), $this->getDamage(), 1));
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = EntityBlockChangeEvent::createEvent($this, $block, Block::get($this->getBlock(), $this->getDamage()))); $this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, Block::get($this->getBlock(), $this->getDamage())));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($pos, $ev->getTo(), true); $this->getLevel()->setBlock($pos, $ev->getTo(), true);
} }
@ -154,7 +150,7 @@ class FallingSand extends Entity{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddEntityPacket::getFromPool(); $pk = new AddEntityPacket();
$pk->type = FallingSand::NETWORK_ID; $pk->type = FallingSand::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
@ -163,7 +159,7 @@ class FallingSand extends Entity{
$pk->did = -($this->getBlock() | $this->getDamage() << 0x10); $pk->did = -($this->getBlock() | $this->getDamage() << 0x10);
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -156,7 +156,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($player !== $this and !isset($this->hasSpawned[$player->getID()])){ if($player !== $this and !isset($this->hasSpawned[$player->getID()])){
$this->hasSpawned[$player->getID()] = $player; $this->hasSpawned[$player->getID()] = $player;
$pk = AddPlayerPacket::getFromPool(); $pk = new AddPlayerPacket();
$pk->clientID = 0; $pk->clientID = 0;
if($player->getRemoveFormat()){ if($player->getRemoveFormat()){
$pk->username = TextFormat::clean($this->nameTag); $pk->username = TextFormat::clean($this->nameTag);
@ -174,7 +174,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -188,7 +188,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
public function despawnFrom(Player $player){ public function despawnFrom(Player $player){
if(isset($this->hasSpawned[$player->getID()])){ if(isset($this->hasSpawned[$player->getID()])){
$pk = RemovePlayerPacket::getFromPool(); $pk = new RemovePlayerPacket();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->clientID = 0; $pk->clientID = 0;
$player->dataPacket($pk); $player->dataPacket($pk);

View File

@ -53,7 +53,6 @@ class Item extends Entity{
public $canCollide = false; public $canCollide = false;
protected function initEntity(){ protected function initEntity(){
$this->namedtag->id = new String("id", "Item");
$this->setMaxHealth(5); $this->setMaxHealth(5);
$this->setHealth($this->namedtag["Health"]); $this->setHealth($this->namedtag["Health"]);
if(isset($this->namedtag->Age)){ if(isset($this->namedtag->Age)){
@ -71,7 +70,7 @@ class Item extends Entity{
$this->item = ItemItem::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]); $this->item = ItemItem::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]);
$this->server->getPluginManager()->callEvent(ItemSpawnEvent::createEvent($this)); $this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this));
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){
@ -100,7 +99,7 @@ class Item extends Entity{
$friction = 1 - $this->drag; $friction = 1 - $this->drag;
if($this->onGround and ($this->motionX != 0 or $this->motionZ != 0)){ if($this->onGround and ($this->motionX != 0 or $this->motionZ != 0)){
$friction = $this->getLevel()->getBlock(Vector3::createVector($this->getFloorX(), $this->getFloorY() - 1, $this->getFloorZ()))->frictionFactor * $friction; $friction = $this->getLevel()->getBlock(new Vector3($this->getFloorX(), $this->getFloorY() - 1, $this->getFloorZ()))->frictionFactor * $friction;
} }
$this->motionX *= $friction; $this->motionX *= $friction;
@ -114,7 +113,7 @@ class Item extends Entity{
} }
if($this->age > 6000){ if($this->age > 6000){
$this->server->getPluginManager()->callEvent($ev = ItemDespawnEvent::createEvent($this)); $this->server->getPluginManager()->callEvent($ev = new ItemDespawnEvent($this));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->age = 0; $this->age = 0;
}else{ }else{
@ -227,7 +226,7 @@ class Item extends Entity{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddItemEntityPacket::getFromPool(); $pk = new AddItemEntityPacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -238,7 +237,7 @@ class Item extends Entity{
$pk->item = $this->getItem(); $pk->item = $this->getItem();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -91,7 +91,7 @@ abstract class Living extends Entity implements Damageable{
} }
} }
$pk = EntityEventPacket::getFromPool(); $pk = new EntityEventPacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->event = 2; //Ouch! $pk->event = 2; //Ouch!
Server::broadcastPacket($this->hasSpawned, $pk); Server::broadcastPacket($this->hasSpawned, $pk);
@ -114,7 +114,7 @@ abstract class Living extends Entity implements Damageable{
$f = sqrt($x ** 2 + $z ** 2); $f = sqrt($x ** 2 + $z ** 2);
$base = 0.4; $base = 0.4;
$motion = Vector3::createVector($this->motionX, $this->motionY, $this->motionZ); $motion = new Vector3($this->motionX, $this->motionY, $this->motionZ);
$motion->x /= 2; $motion->x /= 2;
$motion->y /= 2; $motion->y /= 2;
@ -139,7 +139,7 @@ abstract class Living extends Entity implements Damageable{
return; return;
} }
parent::kill(); parent::kill();
$this->server->getPluginManager()->callEvent($ev = EntityDeathEvent::createEvent($this, $this->getDrops())); $this->server->getPluginManager()->callEvent($ev = new EntityDeathEvent($this, $this->getDrops()));
foreach($ev->getDrops() as $item){ foreach($ev->getDrops() as $item){
$this->getLevel()->dropItem($this, $item); $this->getLevel()->dropItem($this, $item);
} }
@ -147,10 +147,10 @@ abstract class Living extends Entity implements Damageable{
public function entityBaseTick($tickDiff = 1){ public function entityBaseTick($tickDiff = 1){
Timings::$timerEntityBaseTick->startTiming(); Timings::$timerEntityBaseTick->startTiming();
parent::entityBaseTick(); parent::entityBaseTick($tickDiff);
if($this->dead !== true and $this->isInsideOfSolid()){ if($this->dead !== true and $this->isInsideOfSolid()){
$ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 1); $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 1);
$this->attack($ev->getFinalDamage(), $ev); $this->attack($ev->getFinalDamage(), $ev);
} }
@ -159,7 +159,7 @@ abstract class Living extends Entity implements Damageable{
if($this->airTicks <= -20){ if($this->airTicks <= -20){
$this->airTicks = 0; $this->airTicks = 0;
$ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2); $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2);
$this->attack($ev->getFinalDamage(), $ev); $this->attack($ev->getFinalDamage(), $ev);
} }
}else{ }else{

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String; class Ozelot extends Animal implements Tameable{
class Ocelot extends Animal implements Tameable{
protected function initEntity(){
$this->namedtag->id = new String("id", "Ozelot");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Painting extends Hanging{ class Painting extends Hanging{
protected function initEntity(){
$this->namedtag->id = new String("id", "Painting");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Pig extends Animal implements Rideable{ class Pig extends Animal implements Rideable{
protected function initEntity(){
$this->namedtag->id = new String("id", "Pig");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class PigZombie extends Zombie{ class PigZombie extends Zombie{
protected function initEntity(){
$this->namedtag->id = new String("id", "PigZombie");
}
} }

View File

@ -27,7 +27,6 @@ use pocketmine\event\entity\EntityRegainHealthEvent;
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\Byte;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
@ -47,7 +46,6 @@ class PrimedTNT extends Entity implements Explosive{
public $canCollide = false; public $canCollide = false;
protected function initEntity(){ protected function initEntity(){
$this->namedtag->id = new String("id", "PrimedTNT");
if(isset($this->namedtag->Fuse)){ if(isset($this->namedtag->Fuse)){
$this->fuse = $this->namedtag["Fuse"]; $this->fuse = $this->namedtag["Fuse"];
}else{ }else{
@ -128,7 +126,7 @@ class PrimedTNT extends Entity implements Explosive{
} }
public function explode(){ public function explode(){
$this->server->getPluginManager()->callEvent($ev = ExplosionPrimeEvent::createEvent($this, 4)); $this->server->getPluginManager()->callEvent($ev = new ExplosionPrimeEvent($this, 4));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$explosion = new Explosion($this, $ev->getForce(), $this); $explosion = new Explosion($this, $ev->getForce(), $this);
@ -140,7 +138,7 @@ class PrimedTNT extends Entity implements Explosive{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddEntityPacket::getFromPool(); $pk = new AddEntityPacket();
$pk->type = PrimedTNT::NETWORK_ID; $pk->type = PrimedTNT::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
@ -149,7 +147,7 @@ class PrimedTNT extends Entity implements Explosive{
$pk->did = 0; $pk->did = 0;
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -23,6 +23,7 @@ namespace pocketmine\entity;
use pocketmine\event\entity\EntityCombustByEntityEvent; use pocketmine\event\entity\EntityCombustByEntityEvent;
use pocketmine\event\entity\EntityDamageByChildEntityEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntityRegainHealthEvent;
@ -36,6 +37,8 @@ abstract class Projectile extends Entity{
public $shootingEntity = null; public $shootingEntity = null;
protected $damage = 0; protected $damage = 0;
private $hadCollision = false;
protected function initEntity(){ protected function initEntity(){
$this->setMaxHealth(1); $this->setMaxHealth(1);
$this->setHealth(1); $this->setHealth(1);
@ -89,11 +92,13 @@ abstract class Projectile extends Entity{
$movingObjectPosition = null; $movingObjectPosition = null;
$this->motionY -= $this->gravity; if(!$this->isCollided){
$this->motionY -= $this->gravity;
}
$this->keepMovement = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z); $this->keepMovement = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z);
$moveVector = Vector3::createVector($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ); $moveVector = new Vector3($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ);
$list = $this->getLevel()->getCollidingEntities($this->boundingBox->addCoord($this->motionX, $this->motionY, $this->motionZ)->expand(1, 1, 1), $this); $list = $this->getLevel()->getCollidingEntities($this->boundingBox->addCoord($this->motionX, $this->motionY, $this->motionZ)->expand(1, 1, 1), $this);
@ -129,18 +134,22 @@ abstract class Projectile extends Entity{
if($movingObjectPosition !== null){ if($movingObjectPosition !== null){
if($movingObjectPosition->entityHit !== null){ if($movingObjectPosition->entityHit !== null){
$this->server->getPluginManager()->callEvent(ProjectileHitEvent::createEvent($this)); $this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
$motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2); $motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2);
$damage = ceil($motion * $this->damage); $damage = ceil($motion * $this->damage);
if($this->shootingEntity === null){
$ev = new EntityDamageByEntityEvent($this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
}else{
$ev = new EntityDamageByChildEntityEvent($this->shootingEntity, $this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
}
$ev = EntityDamageByEntityEvent::createEvent($this->shootingEntity === null ? $this : $this->shootingEntity, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
$movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev); $movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev);
if($this->fireTicks > 0){ if($this->fireTicks > 0){
$ev = EntityCombustByEntityEvent::createEvent($this, $movingObjectPosition->entityHit, 5); $ev = new EntityCombustByEntityEvent($this, $movingObjectPosition->entityHit, 5);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$movingObjectPosition->entityHit->setOnFire($ev->getDuration()); $movingObjectPosition->entityHit->setOnFire($ev->getDuration());
@ -154,12 +163,16 @@ abstract class Projectile extends Entity{
$this->move($this->motionX, $this->motionY, $this->motionZ); $this->move($this->motionX, $this->motionY, $this->motionZ);
if($this->onGround and ($this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0)){ if($this->isCollided and !$this->hadCollision){
$this->hadCollision = true;
$this->motionX = 0; $this->motionX = 0;
$this->motionY = 0; $this->motionY = 0;
$this->motionZ = 0; $this->motionZ = 0;
$this->server->getPluginManager()->callEvent(ProjectileHitEvent::createEvent($this)); $this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
}elseif(!$this->isCollided and !$this->hadCollision){
$this->hadCollision = false;
} }
if(!$this->onGround or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0){ if(!$this->onGround or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0){

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Sheep extends Animal implements Colorable{ class Sheep extends Animal implements Colorable{
protected function initEntity(){
$this->namedtag->id = new String("id", "Sheep");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Silverfish extends Monster{ class Silverfish extends Monster{
protected function initEntity(){
$this->namedtag->id = new String("id", "Silverfish");
}
} }

View File

@ -21,10 +21,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Skeleton extends Monster implements ProjectileSource{ class Skeleton extends Monster implements ProjectileSource{
protected function initEntity(){
$this->namedtag->id = new String("id", "Skeleton");
}
} }

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Slime extends Living{ class Slime extends Living{
protected function initEntity(){
$this->namedtag->id = new String("id", "Slime");
}
} }

View File

@ -24,7 +24,6 @@ namespace pocketmine\entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
@ -53,7 +52,7 @@ class Snowball extends Projectile{
$hasUpdate = parent::onUpdate($currentTick); $hasUpdate = parent::onUpdate($currentTick);
if($this->age > 1200 or $this->onGround){ if($this->age > 1200 or $this->isCollided){
$this->kill(); $this->kill();
$hasUpdate = true; $hasUpdate = true;
} }
@ -63,13 +62,8 @@ class Snowball extends Projectile{
return $hasUpdate; return $hasUpdate;
} }
protected function initEntity(){
$this->namedtag->id = new String("id", "Snowball");
parent::initEntity();
}
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddEntityPacket::getFromPool(); $pk = new AddEntityPacket();
$pk->type = Snowball::NETWORK_ID; $pk->type = Snowball::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
@ -78,7 +72,7 @@ class Snowball extends Projectile{
$pk->did = 0; //TODO: send motion here $pk->did = 0; //TODO: send motion here
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Spider extends Monster{ class Spider extends Monster{
protected function initEntity(){
$this->namedtag->id = new String("id", "Spider");
}
} }

View File

@ -23,7 +23,6 @@ namespace pocketmine\entity;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddMobPacket; use pocketmine\network\protocol\AddMobPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
@ -48,14 +47,13 @@ class Villager extends Creature implements NPC, Ageable{
protected function initEntity(){ protected function initEntity(){
parent::initEntity(); parent::initEntity();
$this->namedtag->id = new String("id", "Villager");
if(!isset($this->namedtag->Profession)){ if(!isset($this->namedtag->Profession)){
$this->setProfession(self::PROFESSION_GENERIC); $this->setProfession(self::PROFESSION_GENERIC);
} }
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddMobPacket::getFromPool(); $pk = new AddMobPacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->type = Villager::NETWORK_ID; $pk->type = Villager::NETWORK_ID;
$pk->x = $this->x; $pk->x = $this->x;
@ -66,7 +64,7 @@ class Villager extends Creature implements NPC, Ageable{
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -22,10 +22,6 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\nbt\tag\String;
class Wolf extends Animal implements Tameable{ class Wolf extends Animal implements Tameable{
protected function initEntity(){
$this->namedtag->id = new String("id", "Wolf");
}
} }

View File

@ -24,7 +24,6 @@ namespace pocketmine\entity;
use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddMobPacket; use pocketmine\network\protocol\AddMobPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
@ -36,17 +35,13 @@ class Zombie extends Monster{
public $length = 0.6; public $length = 0.6;
public $height = 1.8; public $height = 1.8;
protected function initEntity(){
$this->namedtag->id = new String("id", "Zombie");
}
public function getName(){ public function getName(){
return "Zombie"; return "Zombie";
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = AddMobPacket::getFromPool(); $pk = new AddMobPacket();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->type = Zombie::NETWORK_ID; $pk->type = Zombie::NETWORK_ID;
$pk->x = $this->x; $pk->x = $this->x;
@ -57,7 +52,7 @@ class Zombie extends Monster{
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool(); $pk = new SetEntityMotionPacket();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -36,13 +36,6 @@ abstract class Event{
* Not doing so will deny the proper event initialization * Not doing so will deny the proper event initialization
*/ */
/** @var Event[] */
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Event[] */
private static $knownEvents = [];
protected $eventName = null; protected $eventName = null;
private $isCancelled = false; private $isCancelled = false;
@ -94,40 +87,4 @@ abstract class Event{
return static::$handlerList; return static::$handlerList;
} }
public static function clearEventPool(){
static::$nextEvent = 0;
}
public static function clearAllPools(){
foreach(self::$knownEvents as $event){
$event::clearEventPool();
}
}
/**
* @param $params
*
* @return static
*/
public static function createEvent(...$params){
if(static::$nextEvent >= count(static::$eventPool)){
static::$eventPool[] = new static(...$params);
return static::$eventPool[static::$nextEvent++];
}
$ev = static::$eventPool[static::$nextEvent++];
$ev->__construct(...$params);
if($ev instanceof Cancellable){
$ev->setCancelled(false);
}
return $ev;
}
public static function onClassLoaded(){
self::$knownEvents[static::class] = static::class;
}
public static function getKnownEvents(){
return self::$knownEvents;
}
} }

View File

@ -0,0 +1,54 @@
<?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;
class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Entity */
private $childEntity;
/**
* @param Entity $damager
* @param Entity $childEntity
* @param Entity $entity
* @param int $cause
* @param int|int[] $damage
*/
public function __construct(Entity $damager, Entity $childEntity, Entity $entity, $cause, $damage){
$this->childEntity = $childEntity;
parent::__construct($damager, $entity, $cause, $damage);
}
/**
* @return Entity
*/
public function getChild(){
return $this->childEntity;
}
}

View File

@ -125,16 +125,14 @@ abstract class BaseInventory implements Inventory{
if($index < 0 or $index >= $this->size){ if($index < 0 or $index >= $this->size){
return false; return false;
}elseif($item->getID() === 0 or $item->getCount() <= 0){ }elseif($item->getID() === 0 or $item->getCount() <= 0){
$this->clear($index, $source); return $this->clear($index, $source);
return true;
} }
$holder = $this->getHolder(); $holder = $this->getHolder();
if($holder instanceof Entity){ if($holder instanceof Entity){
Server::getInstance()->getPluginManager()->callEvent($ev = EntityInventoryChangeEvent::createEvent($holder, $this->getItem($index), $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $this->getItem($index), $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendContents($this->getViewers()); $this->sendSlot($index, $this->getViewers());
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
@ -227,6 +225,14 @@ abstract class BaseInventory implements Inventory{
} }
public function addItem(...$slots){ public function addItem(...$slots){
if(isset($slots[$end = count($slots) - 1]) and $slots[$end] instanceof Player){
/** @var Player $source */
$source = $slots[$end];
unset($slots[$end]);
}else{
$source = null;
}
/** @var Item[] $slots */ /** @var Item[] $slots */
foreach($slots as $i => $slot){ foreach($slots as $i => $slot){
$slots[$i] = clone $slot; $slots[$i] = clone $slot;
@ -235,12 +241,12 @@ abstract class BaseInventory implements Inventory{
for($i = 0; $i < $this->getSize(); ++$i){ for($i = 0; $i < $this->getSize(); ++$i){
$item = $this->getItem($i); $item = $this->getItem($i);
foreach($slots as $index => $slot){ foreach($slots as $index => $slot){
if($item->getID() === Item::AIR){ if($item->getID() === Item::AIR or $item->getCount() <= 0){
$amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize());
$slot->setCount($slot->getCount() - $amount); $slot->setCount($slot->getCount() - $amount);
$item = clone $slot; $item = clone $slot;
$item->setCount($amount); $item->setCount($amount);
$this->setItem($i, $item); $this->setItem($i, $item, $source);
$item = $this->getItem($i); $item = $this->getItem($i);
if($slot->getCount() <= 0){ if($slot->getCount() <= 0){
unset($slots[$index]); unset($slots[$index]);
@ -249,7 +255,7 @@ abstract class BaseInventory implements Inventory{
$amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize());
$slot->setCount($slot->getCount() - $amount); $slot->setCount($slot->getCount() - $amount);
$item->setCount($item->getCount() + $amount); $item->setCount($item->getCount() + $amount);
$this->setItem($i, $item); $this->setItem($i, $item, $source);
if($slot->getCount() <= 0){ if($slot->getCount() <= 0){
unset($slots[$index]); unset($slots[$index]);
} }
@ -265,6 +271,14 @@ abstract class BaseInventory implements Inventory{
} }
public function removeItem(...$slots){ public function removeItem(...$slots){
if(isset($slots[$end = count($slots) - 1]) and $slots[$end] instanceof Player){
/** @var Player $source */
$source = $slots[$end];
unset($slots[$end]);
}else{
$source = null;
}
/** @var Item[] $slots */ /** @var Item[] $slots */
for($i = 0; $i < $this->getSize(); ++$i){ for($i = 0; $i < $this->getSize(); ++$i){
$item = $this->getItem($i); $item = $this->getItem($i);
@ -277,7 +291,7 @@ abstract class BaseInventory implements Inventory{
$amount = min($item->getCount(), $slot->getCount()); $amount = min($item->getCount(), $slot->getCount());
$slot->setCount($slot->getCount() - $amount); $slot->setCount($slot->getCount() - $amount);
$item->setCount($item->getCount() - $amount); $item->setCount($item->getCount() - $amount);
$this->setItem($i, $item); $this->setItem($i, $item, $source);
if($slot->getCount() <= 0){ if($slot->getCount() <= 0){
unset($slots[$index]); unset($slots[$index]);
} }
@ -298,10 +312,9 @@ abstract class BaseInventory implements Inventory{
$old = $this->slots[$index]; $old = $this->slots[$index];
$holder = $this->getHolder(); $holder = $this->getHolder();
if($holder instanceof Entity){ if($holder instanceof Entity){
Server::getInstance()->getPluginManager()->callEvent($ev = EntityInventoryChangeEvent::createEvent($holder, $old, $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $old, $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendContents($this->getViewers()); $this->sendSlot($index, $this->getViewers());
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
@ -350,7 +363,7 @@ abstract class BaseInventory implements Inventory{
} }
public function open(Player $who){ public function open(Player $who){
$who->getServer()->getPluginManager()->callEvent($ev = InventoryOpenEvent::createEvent($this, $who)); $who->getServer()->getPluginManager()->callEvent($ev = new InventoryOpenEvent($this, $who));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -384,7 +397,7 @@ abstract class BaseInventory implements Inventory{
$target = [$target]; $target = [$target];
} }
$pk = ContainerSetContentPacket::getFromPool(); $pk = new ContainerSetContentPacket();
$pk->slots = []; $pk->slots = [];
for($i = 0; $i < $this->getSize(); ++$i){ for($i = 0; $i < $this->getSize(); ++$i){
$pk->slots[$i] = $this->getItem($i); $pk->slots[$i] = $this->getItem($i);
@ -409,7 +422,7 @@ abstract class BaseInventory implements Inventory{
$target = [$target]; $target = [$target];
} }
$pk = ContainerSetSlotPacket::getFromPool(); $pk = new ContainerSetSlotPacket();
$pk->slot = $index; $pk->slot = $index;
$pk->item = clone $this->getItem($index); $pk->item = clone $this->getItem($index);

View File

@ -43,7 +43,7 @@ class ChestInventory extends ContainerInventory{
parent::onOpen($who); parent::onOpen($who);
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = TileEventPacket::getFromPool(); $pk = new TileEventPacket();
$pk->x = $this->getHolder()->getX(); $pk->x = $this->getHolder()->getX();
$pk->y = $this->getHolder()->getY(); $pk->y = $this->getHolder()->getY();
$pk->z = $this->getHolder()->getZ(); $pk->z = $this->getHolder()->getZ();
@ -57,7 +57,7 @@ class ChestInventory extends ContainerInventory{
public function onClose(Player $who){ public function onClose(Player $who){
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = TileEventPacket::getFromPool(); $pk = new TileEventPacket();
$pk->x = $this->getHolder()->getX(); $pk->x = $this->getHolder()->getX();
$pk->y = $this->getHolder()->getY(); $pk->y = $this->getHolder()->getY();
$pk->z = $this->getHolder()->getZ(); $pk->z = $this->getHolder()->getZ();

View File

@ -29,7 +29,7 @@ use pocketmine\Player;
abstract class ContainerInventory extends BaseInventory{ abstract class ContainerInventory extends BaseInventory{
public function onOpen(Player $who){ public function onOpen(Player $who){
parent::onOpen($who); parent::onOpen($who);
$pk = ContainerOpenPacket::getFromPool(); $pk = new ContainerOpenPacket();
$pk->windowid = $who->getWindowId($this); $pk->windowid = $who->getWindowId($this);
$pk->type = $this->getType()->getNetworkType(); $pk->type = $this->getType()->getNetworkType();
$pk->slots = $this->getSize(); $pk->slots = $this->getSize();
@ -48,7 +48,7 @@ abstract class ContainerInventory extends BaseInventory{
} }
public function onClose(Player $who){ public function onClose(Player $who){
$pk = ContainerClosePacket::getFromPool(); $pk = new ContainerClosePacket();
$pk->windowid = $who->getWindowId($this); $pk->windowid = $who->getWindowId($this);
$who->dataPacket($pk); $who->dataPacket($pk);
parent::onClose($who); parent::onClose($who);

View File

@ -55,7 +55,7 @@ class CraftingManager{
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WORKBENCH, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 4))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WORKBENCH, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 4)));
$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::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 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 ShapelessRecipe(Item::get(Item::SNOW_BLOCK, 0, 1)))->addIngredient(Item::get(Item::SNOWBALL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_BLOCK, 0, 1)))->addIngredient(Item::get(Item::SNOWBALL, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::STICK, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 2))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::STICK, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 2)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::STONECUTTER, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 4))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::STONECUTTER, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4)))->addIngredient(Item::get(Item::WOOD, Wood::OAK, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4)))->addIngredient(Item::get(Item::WOOD, Wood::OAK, 1)));
@ -64,7 +64,7 @@ class CraftingManager{
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::JUNGLE, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::JUNGLE, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::ACACIA, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::ACACIA, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::DARK_OAK, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::DARK_OAK, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, null, 1))->addIngredient(Item::get(Item::STICK, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, null, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SUGAR, 0, 1)))->addIngredient(Item::get(Item::SUGARCANE, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::SUGAR, 0, 1)))->addIngredient(Item::get(Item::SUGARCANE, 0, 1)));
@ -85,7 +85,7 @@ class CraftingManager{
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_ACACIA, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 2))->addIngredient(Item::get(Item::STICK, 0, 4))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_ACACIA, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 2))->addIngredient(Item::get(Item::STICK, 0, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FURNACE, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 8))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FURNACE, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 8)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GLASS_PANE, 0, 16)))->addIngredient(Item::get(Item::GLASS, 0, 6))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GLASS_PANE, 0, 16)))->addIngredient(Item::get(Item::GLASS, 0, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LADDER, 0, 2)))->addIngredient(Item::get(Item::STICK, 0, 7))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LADDER, 0, 3)))->addIngredient(Item::get(Item::STICK, 0, 7)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::NETHER_REACTOR, 0, 1)))->addIngredient(Item::get(Item::DIAMOND, 0, 3))->addIngredient(Item::get(Item::IRON_INGOT, 0, 6))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::NETHER_REACTOR, 0, 1)))->addIngredient(Item::get(Item::DIAMOND, 0, 3))->addIngredient(Item::get(Item::IRON_INGOT, 0, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::TRAPDOOR, 0, 2)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::TRAPDOOR, 0, 2)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOODEN_DOOR, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOODEN_DOOR, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6)));
@ -105,7 +105,7 @@ class CraftingManager{
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BUCKET, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 3))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BUCKET, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::CLOCK, 0, 1)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 4))->addIngredient(Item::get(Item::REDSTONE_DUST, 0, 1))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::CLOCK, 0, 1)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 4))->addIngredient(Item::get(Item::REDSTONE_DUST, 0, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::COMPASS, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 4))->addIngredient(Item::get(Item::REDSTONE_DUST, 0, 1))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::COMPASS, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 4))->addIngredient(Item::get(Item::REDSTONE_DUST, 0, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::TNT, 0, 1)))->addIngredient(Item::get(Item::GUNPOWDER, 0, 5))->addIngredient(Item::get(Item::SAND, null, 4))); //TODO: check if TNT can be crafted with red sand $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::TNT, 0, 1)))->addIngredient(Item::get(Item::GUNPOWDER, 0, 5))->addIngredient(Item::get(Item::SAND, null, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOWL, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANKS, null, 3))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOWL, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANKS, null, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::MINECART, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 5))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::MINECART, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 5)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOOK, 0, 1)))->addIngredient(Item::get(Item::PAPER, 0, 3))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOOK, 0, 1)))->addIngredient(Item::get(Item::PAPER, 0, 3)));
@ -118,7 +118,7 @@ class CraftingManager{
protected function registerFurnace(){ 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, 0, 1), Item::get(Item::COBBLESTONE, 0, 1)));
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::GLASS, 0, 1), Item::get(Item::SAND, 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::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::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::IRON_INGOT, 0, 1), Item::get(Item::IRON_ORE, 0, 1)));
@ -245,7 +245,7 @@ class CraftingManager{
} }
$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, 11, 2)))->addIngredient(Item::get(Item::DANDELION, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 15, 1)))->addIngredient(Item::get(Item::BONE, 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, 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, 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, 9, 2)))->addIngredient(Item::get(Item::DYE, 15, 1))->addIngredient(Item::get(Item::DYE, 1, 1)));

View File

@ -92,7 +92,7 @@ class CraftingTransactionGroup extends SimpleTransactionGroup{
return false; return false;
} }
Server::getInstance()->getPluginManager()->callEvent($ev = CraftItemEvent::createEvent($this, $this->getMatchingRecipe())); Server::getInstance()->getPluginManager()->callEvent($ev = new CraftItemEvent($this, $this->getMatchingRecipe()));
if($ev->isCancelled()){ if($ev->isCancelled()){
foreach($this->inventories as $inventory){ foreach($this->inventories as $inventory){
$inventory->sendContents($inventory->getViewers()); $inventory->sendContents($inventory->getViewers());

View File

@ -91,7 +91,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
parent::onOpen($who); parent::onOpen($who);
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = TileEventPacket::getFromPool(); $pk = new TileEventPacket();
$pk->x = $this->right->getHolder()->getX(); $pk->x = $this->right->getHolder()->getX();
$pk->y = $this->right->getHolder()->getY(); $pk->y = $this->right->getHolder()->getY();
$pk->z = $this->right->getHolder()->getZ(); $pk->z = $this->right->getHolder()->getZ();
@ -105,7 +105,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
public function onClose(Player $who){ public function onClose(Player $who){
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = TileEventPacket::getFromPool(); $pk = new TileEventPacket();
$pk->x = $this->right->getHolder()->getX(); $pk->x = $this->right->getHolder()->getX();
$pk->y = $this->right->getHolder()->getY(); $pk->y = $this->right->getHolder()->getY();
$pk->z = $this->right->getHolder()->getZ(); $pk->z = $this->right->getHolder()->getZ();

View File

@ -67,7 +67,7 @@ interface Inventory{
* Stores the given Items in the inventory. This will try to fill * Stores the given Items in the inventory. This will try to fill
* existing stacks and empty slots as well as it can. * existing stacks and empty slots as well as it can.
* *
* Returns the Items that did not fit * Returns the Items that did not fit. A Player source can be set at the end
* *
* @param Item ...$item * @param Item ...$item
* *
@ -86,7 +86,7 @@ interface Inventory{
/** /**
* Removes the given Item from the inventory. * Removes the given Item from the inventory.
* It will return the Items that couldn't be removed. * It will return the Items that couldn't be removed. A Player source can be set at the end
* *
* @param Item ...$item * @param Item ...$item
* *

View File

@ -23,6 +23,7 @@ namespace pocketmine\inventory;
use pocketmine\entity\Human; use pocketmine\entity\Human;
use pocketmine\event\entity\EntityArmorChangeEvent; use pocketmine\event\entity\EntityArmorChangeEvent;
use pocketmine\event\entity\EntityInventoryChangeEvent;
use pocketmine\event\player\PlayerItemHeldEvent; use pocketmine\event\player\PlayerItemHeldEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\network\protocol\ContainerSetContentPacket; use pocketmine\network\protocol\ContainerSetContentPacket;
@ -66,7 +67,7 @@ class PlayerInventory extends BaseInventory{
$this->itemInHandIndex = $index; $this->itemInHandIndex = $index;
$item = $this->getItemInHand(); $item = $this->getItemInHand();
$pk = PlayerEquipmentPacket::getFromPool(); $pk = new PlayerEquipmentPacket();
$pk->eid = $this->getHolder()->getID(); $pk->eid = $this->getHolder()->getID();
$pk->item = $item->getID(); $pk->item = $item->getID();
$pk->meta = $item->getDamage(); $pk->meta = $item->getDamage();
@ -103,7 +104,7 @@ class PlayerInventory extends BaseInventory{
if($slot >= -1 and $slot < $this->getSize()){ if($slot >= -1 and $slot < $this->getSize()){
$item = $this->getItem($slot); $item = $this->getItem($slot);
if($this->getHolder() instanceof Player){ if($this->getHolder() instanceof Player){
Server::getInstance()->getPluginManager()->callEvent($ev = PlayerItemHeldEvent::createEvent($this->getHolder(), $item, $slot, $this->itemInHandIndex)); Server::getInstance()->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this->getHolder(), $item, $slot, $this->itemInHandIndex));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendHeldItem($this->getHolder()); $this->sendHeldItem($this->getHolder());
@ -126,7 +127,7 @@ class PlayerInventory extends BaseInventory{
$item = $this->getItemInHand(); $item = $this->getItemInHand();
$pk = PlayerEquipmentPacket::getFromPool(); $pk = new PlayerEquipmentPacket();
$pk->eid = $this->getHolder()->getID(); $pk->eid = $this->getHolder()->getID();
$pk->item = $item->getID(); $pk->item = $item->getID();
$pk->meta = $item->getDamage(); $pk->meta = $item->getDamage();
@ -149,7 +150,8 @@ class PlayerInventory extends BaseInventory{
parent::onSlotChange($index, $before, $source); parent::onSlotChange($index, $before, $source);
if($index >= $this->getSize()){ if($index >= $this->getSize()){
$this->sendArmorContents($this->getHolder()->getViewers()); $this->sendArmorSlot($index, $this->getViewers($source));
$this->sendArmorSlot($index, $this->getHolder()->getViewers());
} }
} }
@ -200,26 +202,38 @@ class PlayerInventory extends BaseInventory{
public function setItem($index, Item $item, $source = null){ public function setItem($index, Item $item, $source = null){
if($index < 0 or $index >= $this->size){ if($index < 0 or $index >= $this->size){
return false; return false;
}elseif($item->getID() === 0){
$this->clear($index, $source);
} }
if($index >= $this->getSize()){ //Armor change if($index >= $this->getSize()){ //Armor change
Server::getInstance()->getPluginManager()->callEvent($ev = EntityArmorChangeEvent::createEvent($this->getHolder(), $this->getItem($index), $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $this->getItem($index), $item, $index));
if($ev->isCancelled() and $this->getHolder() instanceof Player){ if($ev->isCancelled() and $this->getHolder() instanceof Player){
$this->sendArmorContents($this->getViewers()); if($index >= $this->size){
$this->sendContents($this->getViewers()); $this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false;
}
$item = $ev->getNewItem();
}else{
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $this->getItem($index), $item, $index));
if($ev->isCancelled()){
if($index >= $this->size){
$this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
} }
if($item->getID() === 0){
$this->clear($index, $source); $old = $this->getItem($index);
}else{ $this->slots[$index] = clone $item;
$old = $this->getItem($index); $this->onSlotChange($index, $old, $source);
$this->slots[$index] = clone $item;
$this->onSlotChange($index, $old, $source);
}
return true; return true;
} }
@ -229,12 +243,25 @@ class PlayerInventory extends BaseInventory{
$item = Item::get(Item::AIR, null, 0); $item = Item::get(Item::AIR, null, 0);
$old = $this->slots[$index]; $old = $this->slots[$index];
if($index >= $this->getSize() and $index < $this->size){ //Armor change if($index >= $this->getSize() and $index < $this->size){ //Armor change
Server::getInstance()->getPluginManager()->callEvent($ev = EntityArmorChangeEvent::createEvent($this->getHolder(), $old, $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $old, $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendArmorContents($this->getViewers()); if($index >= $this->size){
$this->sendContents($this->getViewers()); $this->sendArmorSlot($index, $this->getViewers());
}else{
return; $this->sendSlot($index, $this->getViewers());
}
return false;
}
$item = $ev->getNewItem();
}else{
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $old, $item, $index));
if($ev->isCancelled()){
if($index >= $this->size){
$this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
} }
@ -246,6 +273,8 @@ class PlayerInventory extends BaseInventory{
$this->onSlotChange($index, $old, $source); $this->onSlotChange($index, $old, $source);
} }
return true;
} }
/** /**
@ -286,7 +315,7 @@ class PlayerInventory extends BaseInventory{
} }
} }
$pk = PlayerArmorEquipmentPacket::getFromPool(); $pk = new PlayerArmorEquipmentPacket();
$pk->eid = $this->getHolder()->getID(); $pk->eid = $this->getHolder()->getID();
$pk->slots = $slots; $pk->slots = $slots;
$pk->encode(); $pk->encode();
@ -298,7 +327,7 @@ class PlayerInventory extends BaseInventory{
//$pk2 = clone $pk; //$pk2 = clone $pk;
//$pk2->eid = 0; //$pk2->eid = 0;
$pk2 = ContainerSetContentPacket::getFromPool(); $pk2 = new ContainerSetContentPacket();
$pk2->windowid = 0x78; //Armor window id constant $pk2->windowid = 0x78; //Armor window id constant
$pk2->slots = $armor; $pk2->slots = $armor;
$player->dataPacket($pk2); $player->dataPacket($pk2);
@ -325,6 +354,51 @@ class PlayerInventory extends BaseInventory{
} }
} }
/**
* @param int $index
* @param Player|Player[] $target
*/
public function sendArmorSlot($index, $target){
if($target instanceof Player){
$target = [$target];
}
$armor = $this->getArmorContents();
$slots = [];
foreach($armor as $i => $slot){
if($slot->getID() === Item::AIR){
$slots[$i] = 255;
}else{
$slots[$i] = $slot->getID();
}
}
$pk = new PlayerArmorEquipmentPacket();
$pk->eid = $this->getHolder()->getID();
$pk->slots = $slots;
$pk->encode();
$pk->isEncoded = true;
foreach($target as $player){
if($player === $this->getHolder()){
/** @var Player $player */
//$pk2 = clone $pk;
//$pk2->eid = 0;
$pk2 = new ContainerSetSlotPacket();
$pk2->windowid = 0x78; //Armor window id constant
$pk2->slot = $index;
$pk2->item = $this->getItem($index);
$player->dataPacket($pk2);
}else{
$player->dataPacket($pk);
}
}
}
/** /**
* @param Player|Player[] $target * @param Player|Player[] $target
*/ */
@ -333,7 +407,7 @@ class PlayerInventory extends BaseInventory{
$target = [$target]; $target = [$target];
} }
$pk = ContainerSetContentPacket::getFromPool(); $pk = new ContainerSetContentPacket();
$pk->slots = []; $pk->slots = [];
for($i = 0; $i < $this->getSize(); ++$i){ //Do not send armor by error here for($i = 0; $i < $this->getSize(); ++$i){ //Do not send armor by error here
$pk->slots[$i] = $this->getItem($i); $pk->slots[$i] = $this->getItem($i);
@ -365,15 +439,14 @@ class PlayerInventory extends BaseInventory{
$target = [$target]; $target = [$target];
} }
$pk = ContainerSetSlotPacket::getFromPool(); $pk = new ContainerSetSlotPacket();
$pk->slot = $index; $pk->slot = $index;
$pk->item = clone $this->getItem($index); $pk->item = clone $this->getItem($index);
foreach($target as $player){ foreach($target as $player){
if($player === $this->getHolder()){ if($player === $this->getHolder()){
/** @var Player $player */ /** @var Player $player */
//TODO: Check if Mojang has implemented this (for the player inventory) on Minecraft: PE 0.9.0 $this->sendContents($player); //#blamemojang
$this->sendContents($player);
}else{ }else{
if(($id = $player->getWindowId($this)) === -1){ if(($id = $player->getWindowId($this)) === -1){
$this->close($player); $this->close($player);

View File

@ -138,13 +138,13 @@ class SimpleTransactionGroup implements TransactionGroup{
return false; return false;
} }
Server::getInstance()->getPluginManager()->callEvent($ev = InventoryTransactionEvent::createEvent($this)); Server::getInstance()->getPluginManager()->callEvent($ev = new InventoryTransactionEvent($this));
if($ev->isCancelled()){ if($ev->isCancelled()){
foreach($this->inventories as $inventory){ foreach($this->inventories as $inventory){
$inventory->sendContents($inventory->getViewers());
if($inventory instanceof PlayerInventory){ if($inventory instanceof PlayerInventory){
$inventory->sendArmorContents($inventory->getViewers()); $inventory->sendArmorContents($this->getSource());
} }
$inventory->sendContents($this->getSource());
} }
return false; return false;

View File

@ -42,7 +42,7 @@ class Bucket extends Item{
if($target instanceof Liquid and $target->getDamage() === 0){ if($target instanceof Liquid and $target->getDamage() === 0){
$result = clone $this; $result = clone $this;
$result->setDamage($target->getID()); $result->setDamage($target->getID());
$player->getServer()->getPluginManager()->callEvent($ev = PlayerBucketFillEvent::createEvent($player, $block, $face, $this, $result)); $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($target, new Air(), true, true); $player->getLevel()->setBlock($target, new Air(), true, true);
if($player->isSurvival()){ if($player->isSurvival()){
@ -56,7 +56,7 @@ class Bucket extends Item{
}elseif($targetBlock instanceof Liquid){ }elseif($targetBlock instanceof Liquid){
$result = clone $this; $result = clone $this;
$result->setDamage(0); $result->setDamage(0);
$player->getServer()->getPluginManager()->callEvent($ev = PlayerBucketFillEvent::createEvent($player, $block, $face, $this, $result)); $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($block, $targetBlock, true, true); $player->getLevel()->setBlock($block, $targetBlock, true, true);
if($player->isSurvival()){ if($player->isSurvival()){

View File

@ -390,8 +390,8 @@ class Item{
const BEETROOT_SOUP = 459; const BEETROOT_SOUP = 459;
/** @var Item[] */ /** @var \SplFixedArray */
public static $list = []; public static $list = null;
protected $block; protected $block;
protected $id; protected $id;
protected $meta; protected $meta;
@ -402,83 +402,84 @@ class Item{
public $isActivable = false; public $isActivable = false;
public static function init(){ public static function init(){
if(count(self::$list) === 0){ if(self::$list === null){
self::$list = [ self::$list = new \SplFixedArray(65536);
self::SUGARCANE => Sugarcane::class, self::$list[self::SUGARCANE] = Sugarcane::class;;
self::WHEAT_SEEDS => WheatSeeds::class, self::$list[self::WHEAT_SEEDS] = WheatSeeds::class;;
self::PUMPKIN_SEEDS => PumpkinSeeds::class, self::$list[self::PUMPKIN_SEEDS] = PumpkinSeeds::class;;
self::MELON_SEEDS => MelonSeeds::class, self::$list[self::MELON_SEEDS] = MelonSeeds::class;;
self::MUSHROOM_STEW => MushroomStew::class, self::$list[self::MUSHROOM_STEW] = MushroomStew::class;;
self::BEETROOT_SOUP => BeetrootSoup::class, self::$list[self::BEETROOT_SOUP] = BeetrootSoup::class;;
self::CARROT => Carrot::class, self::$list[self::CARROT] = Carrot::class;;
self::POTATO => Potato::class, self::$list[self::POTATO] = Potato::class;;
self::BEETROOT_SEEDS => BeetrootSeeds::class, self::$list[self::BEETROOT_SEEDS] = BeetrootSeeds::class;;
self::SIGN => Sign::class, self::$list[self::SIGN] = Sign::class;;
self::WOODEN_DOOR => WoodenDoor::class, self::$list[self::WOODEN_DOOR] = WoodenDoor::class;;
self::BUCKET => Bucket::class, self::$list[self::BUCKET] = Bucket::class;;
self::IRON_DOOR => IronDoor::class, self::$list[self::IRON_DOOR] = IronDoor::class;;
self::CAKE => Cake::class, self::$list[self::CAKE] = Cake::class;;
self::BED => Bed::class, self::$list[self::BED] = Bed::class;;
self::PAINTING => Painting::class, self::$list[self::PAINTING] = Painting::class;;
self::COAL => Coal::class, self::$list[self::COAL] = Coal::class;;
self::APPLE => Apple::class, self::$list[self::APPLE] = Apple::class;;
self::SPAWN_EGG => SpawnEgg::class, self::$list[self::SPAWN_EGG] = SpawnEgg::class;;
self::DIAMOND => Diamond::class, self::$list[self::DIAMOND] = Diamond::class;;
self::STICK => Stick::class, self::$list[self::STICK] = Stick::class;;
self::BOWL => Bowl::class, self::$list[self::BOWL] = Bowl::class;;
self::FEATHER => Feather::class, self::$list[self::FEATHER] = Feather::class;;
self::BRICK => Brick::class, self::$list[self::BRICK] = Brick::class;;
self::IRON_SWORD => IronSword::class, self::$list[self::IRON_SWORD] = IronSword::class;;
self::IRON_INGOT => IronIngot::class, self::$list[self::IRON_INGOT] = IronIngot::class;;
self::GOLD_INGOT => GoldIngot::class, self::$list[self::GOLD_INGOT] = GoldIngot::class;;
self::IRON_SHOVEL => IronShovel::class, self::$list[self::IRON_SHOVEL] = IronShovel::class;;
self::IRON_PICKAXE => IronPickaxe::class, self::$list[self::IRON_PICKAXE] = IronPickaxe::class;;
self::IRON_AXE => IronAxe::class, self::$list[self::IRON_AXE] = IronAxe::class;;
self::IRON_HOE => IronHoe::class, self::$list[self::IRON_HOE] = IronHoe::class;;
self::DIAMOND_SWORD => DiamondSword::class, self::$list[self::DIAMOND_SWORD] = DiamondSword::class;;
self::DIAMOND_SHOVEL => DiamondShovel::class, self::$list[self::DIAMOND_SHOVEL] = DiamondShovel::class;;
self::DIAMOND_PICKAXE => DiamondPickaxe::class, self::$list[self::DIAMOND_PICKAXE] = DiamondPickaxe::class;;
self::DIAMOND_AXE => DiamondAxe::class, self::$list[self::DIAMOND_AXE] = DiamondAxe::class;;
self::DIAMOND_HOE => DiamondHoe::class, self::$list[self::DIAMOND_HOE] = DiamondHoe::class;;
self::GOLD_SWORD => GoldSword::class, self::$list[self::GOLD_SWORD] = GoldSword::class;;
self::GOLD_SHOVEL => GoldShovel::class, self::$list[self::GOLD_SHOVEL] = GoldShovel::class;;
self::GOLD_PICKAXE => GoldPickaxe::class, self::$list[self::GOLD_PICKAXE] = GoldPickaxe::class;;
self::GOLD_AXE => GoldAxe::class, self::$list[self::GOLD_AXE] = GoldAxe::class;;
self::GOLD_HOE => GoldHoe::class, self::$list[self::GOLD_HOE] = GoldHoe::class;;
self::STONE_SWORD => StoneSword::class, self::$list[self::STONE_SWORD] = StoneSword::class;;
self::STONE_SHOVEL => StoneShovel::class, self::$list[self::STONE_SHOVEL] = StoneShovel::class;;
self::STONE_PICKAXE => StonePickaxe::class, self::$list[self::STONE_PICKAXE] = StonePickaxe::class;;
self::STONE_AXE => StoneAxe::class, self::$list[self::STONE_AXE] = StoneAxe::class;;
self::STONE_HOE => StoneHoe::class, self::$list[self::STONE_HOE] = StoneHoe::class;;
self::WOODEN_SWORD => WoodenSword::class, self::$list[self::WOODEN_SWORD] = WoodenSword::class;;
self::WOODEN_SHOVEL => WoodenShovel::class, self::$list[self::WOODEN_SHOVEL] = WoodenShovel::class;;
self::WOODEN_PICKAXE => WoodenPickaxe::class, self::$list[self::WOODEN_PICKAXE] = WoodenPickaxe::class;;
self::WOODEN_AXE => WoodenAxe::class, self::$list[self::WOODEN_AXE] = WoodenAxe::class;;
self::WOODEN_HOE => WoodenHoe::class, self::$list[self::WOODEN_HOE] = WoodenHoe::class;;
self::FLINT_STEEL => FlintSteel::class, self::$list[self::FLINT_STEEL] = FlintSteel::class;;
self::SHEARS => Shears::class, self::$list[self::SHEARS] = Shears::class;;
self::BOW => Bow::class, self::$list[self::BOW] = Bow::class;;
];
foreach(Block::$list as $id => $class){
self::$list[$id] = $class;
}
for($i = 0; $i < 256; ++$i){
if(Block::$list[$i] !== null){
self::$list[$i] = Block::$list[$i];
}
}
} }
} }
public static function get($id, $meta = 0, $count = 1){ public static function get($id, $meta = 0, $count = 1){
if(isset(self::$list[$id])){ try{
$class = self::$list[$id]; $class = self::$list[$id];
if($id < 256){ if($class === null){
$item = new ItemBlock(new $class($meta), $meta, $count); return new Item($id, $meta, $count);
}elseif($id < 256){
return new ItemBlock(new $class($meta), $meta, $count);
}else{ }else{
$item = new $class($meta, $count); return new $class($meta, $count);
} }
}else{ }catch(\RuntimeException $e){
$item = new Item($id, $meta, $count); return new Item($id, $meta, $count);
} }
return $item;
} }
public static function fromString($str, $multiple = false){ public static function fromString($str, $multiple = false){
@ -549,7 +550,7 @@ class Item{
} }
} }
final public function getID(){ final public function getId(){
return $this->id; return $this->id;
} }

View File

@ -83,9 +83,9 @@ class Explosion{
return false; return false;
} }
$pointer = Vector3::createVector(0, 0, 0); $pointer = new Vector3(0, 0, 0);
$vector = Vector3::createVector(0, 0, 0); $vector = new Vector3(0, 0, 0);
$vBlock = Vector3::createVector(0, 0, 0); $vBlock = new Vector3(0, 0, 0);
$mRays = $this->rays - 1; $mRays = $this->rays - 1;
for($i = 0; $i < $this->rays; ++$i){ for($i = 0; $i < $this->rays; ++$i){
@ -130,12 +130,11 @@ class Explosion{
public function explodeB(){ public function explodeB(){
$send = []; $send = [];
$source = Vector3::cloneVector($this->source); $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor();
$source = $source->floor();
$yield = (1 / $this->size) * 100; $yield = (1 / $this->size) * 100;
if($this->what instanceof Entity){ if($this->what instanceof Entity){
$this->level->getServer()->getPluginManager()->callEvent($ev = EntityExplodeEvent::createEvent($this->what, $this->source, $this->affectedBlocks, $yield)); $this->level->getServer()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
}else{ }else{
@ -152,7 +151,7 @@ class Explosion{
$minZ = Math::floorFloat($this->source->z - $explosionSize - 1); $minZ = Math::floorFloat($this->source->z - $explosionSize - 1);
$maxZ = Math::floorFloat($this->source->z + $explosionSize + 1); $maxZ = Math::floorFloat($this->source->z + $explosionSize + 1);
$explosionBB = AxisAlignedBB::getBoundingBoxFromPool($minX, $minY, $minZ, $maxX, $maxY, $maxZ); $explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
$list = $this->level->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null); $list = $this->level->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null);
foreach($list as $entity){ foreach($list as $entity){
@ -166,11 +165,11 @@ class Explosion{
$damage = (int) ((($impact * $impact + $impact) / 2) * 8 * $explosionSize + 1); $damage = (int) ((($impact * $impact + $impact) / 2) * 8 * $explosionSize + 1);
if($this->what instanceof Entity){ if($this->what instanceof Entity){
$ev = EntityDamageByEntityEvent::createEvent($this->what, $entity, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION, $damage); $ev = new EntityDamageByEntityEvent($this->what, $entity, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION, $damage);
}elseif($this->what instanceof Block){ }elseif($this->what instanceof Block){
$ev = EntityDamageByBlockEvent::createEvent($this->what, $entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage); $ev = new EntityDamageByBlockEvent($this->what, $entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage);
}else{ }else{
$ev = EntityDamageEvent::createEvent($entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage); $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage);
} }
$entity->attack($ev->getFinalDamage(), $ev); $entity->attack($ev->getFinalDamage(), $ev);
@ -212,7 +211,7 @@ class Explosion{
$this->level->setBlockIdAt($block->x, $block->y, $block->z, 0); $this->level->setBlockIdAt($block->x, $block->y, $block->z, 0);
$send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z); $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
} }
$pk = ExplodePacket::getFromPool(); $pk = new ExplodePacket();
$pk->x = $this->source->x; $pk->x = $this->source->x;
$pk->y = $this->source->y; $pk->y = $this->source->y;
$pk->z = $this->source->z; $pk->z = $this->source->z;

View File

@ -307,7 +307,7 @@ class Level implements ChunkManager, Metadatable{
* *
* @return int * @return int
*/ */
final public function getID(){ final public function getId(){
return $this->levelId; return $this->levelId;
} }
@ -352,7 +352,7 @@ class Level implements ChunkManager, Metadatable{
*/ */
public function unload($force = false){ public function unload($force = false){
$ev = LevelUnloadEvent::createEvent($this); $ev = new LevelUnloadEvent($this);
if($this === $this->server->getDefaultLevel() and $force !== true){ if($this === $this->server->getDefaultLevel() and $force !== true){
$ev->setCancelled(true); $ev->setCancelled(true);
@ -409,18 +409,6 @@ class Level implements ChunkManager, Metadatable{
$this->usedChunks[$index][$player->getID()] = $player; $this->usedChunks[$index][$player->getID()] = $player;
} }
/**
* WARNING: Do not use this, it's only for internal use.
* Changes to this function won't be recorded on the version.
*
* @param Player $player
*/
public function freeAllChunks(Player $player){
foreach($this->usedChunks as $i => $c){
unset($this->usedChunks[$i][$player->getID()]);
}
}
/** /**
* WARNING: Do not use this, it's only for internal use. * WARNING: Do not use this, it's only for internal use.
* Changes to this function won't be recorded on the version. * Changes to this function won't be recorded on the version.
@ -451,7 +439,7 @@ class Level implements ChunkManager, Metadatable{
* Changes to this function won't be recorded on the version. * Changes to this function won't be recorded on the version.
*/ */
public function sendTime(){ public function sendTime(){
$pk = SetTimePacket::getFromPool(); $pk = new SetTimePacket();
$pk->time = (int) $this->time; $pk->time = (int) $this->time;
$pk->started = $this->stopTime == false; $pk->started = $this->stopTime == false;
@ -544,7 +532,7 @@ class Level implements ChunkManager, Metadatable{
foreach($mini as $blocks){ foreach($mini as $blocks){
/** @var Block $b */ /** @var Block $b */
foreach($blocks as $b){ foreach($blocks as $b){
$pk = UpdateBlockPacket::getFromPool(); $pk = new UpdateBlockPacket();
$pk->x = $b->x; $pk->x = $b->x;
$pk->y = $b->y; $pk->y = $b->y;
$pk->z = $b->z; $pk->z = $b->z;
@ -583,7 +571,7 @@ class Level implements ChunkManager, Metadatable{
foreach($this->players as $player){ foreach($this->players as $player){
$x = $player->x >> 4; $x = $player->x >> 4;
$z = $player->x >> 4; $z = $player->z >> 4;
$index = "$x:$z"; $index = "$x:$z";
$existingPlayers = max(0, isset($this->chunkTickList[$index]) ? $this->chunkTickList[$index] : 0); $existingPlayers = max(0, isset($this->chunkTickList[$index]) ? $this->chunkTickList[$index] : 0);
@ -684,7 +672,7 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
$this->server->getPluginManager()->callEvent(LevelSaveEvent::createEvent($this)); $this->server->getPluginManager()->callEvent(new LevelSaveEvent($this));
$this->provider->setTime((int) $this->time); $this->provider->setTime((int) $this->time);
$this->saveChunks(); $this->saveChunks();
@ -716,7 +704,7 @@ class Level implements ChunkManager, Metadatable{
} }
for($side = 0; $side <= 5; ++$side){ for($side = 0; $side <= 5; ++$side){
$this->server->getPluginManager()->callEvent($ev = BlockUpdateEvent::createEvent($block->getSide($side))); $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block->getSide($side)));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
} }
@ -813,7 +801,7 @@ class Level implements ChunkManager, Metadatable{
if($entities){ if($entities){
foreach($this->getCollidingEntities($bb->grow(0.25, 0.25, 0.25), $entity) as $ent){ foreach($this->getCollidingEntities($bb->grow(0.25, 0.25, 0.25), $entity) as $ent){
$collides[] = AxisAlignedBB::cloneBoundingBoxFromPool($ent->boundingBox); $collides[] = clone $ent->boundingBox;
} }
} }
@ -958,7 +946,7 @@ class Level implements ChunkManager, Metadatable{
} }
//if($direct === true){ //if($direct === true){
$pk = UpdateBlockPacket::getFromPool(); $pk = new UpdateBlockPacket();
$pk->x = $pos->x; $pk->x = $pos->x;
$pk->y = $pos->y; $pk->y = $pos->y;
$pk->z = $pos->z; $pk->z = $pos->z;
@ -985,10 +973,10 @@ class Level implements ChunkManager, Metadatable{
if($update === true){ if($update === true){
$this->updateAround($pos); $this->updateAround($pos);
$this->server->getPluginManager()->callEvent($ev = BlockUpdateEvent::createEvent($block)); $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
foreach($this->getNearbyEntities(AxisAlignedBB::getBoundingBoxFromPool($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){ foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){
$entity->scheduleUpdate(); $entity->scheduleUpdate();
} }
} }
@ -1003,7 +991,7 @@ class Level implements ChunkManager, Metadatable{
* @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, $delay = 10){
$motion = $motion === null ? Vector3::createVector(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;
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), new Compound("", [ $itemEntity = Entity::createEntity("Item", $this->getChunk($source->getX() >> 4, $source->getZ() >> 4), new Compound("", [
"Pos" => new Enum("Pos", [ "Pos" => new Enum("Pos", [
@ -1053,7 +1041,7 @@ class Level implements ChunkManager, Metadatable{
} }
if($player instanceof Player){ if($player instanceof Player){
$ev = BlockBreakEvent::createEvent($player, $target, $item, ($player->getGamemode() & 0x01) === 1 ? true : false); $ev = new BlockBreakEvent($player, $target, $item, ($player->getGamemode() & 0x01) === 1 ? true : false);
$lastTime = $player->lastBreak - 0.1; //TODO: replace with true lag $lastTime = $player->lastBreak - 0.1; //TODO: replace with true lag
if(($player->getGamemode() & 0x01) > 0){ if(($player->getGamemode() & 0x01) > 0){
@ -1086,7 +1074,7 @@ class Level implements ChunkManager, Metadatable{
$level = $target->getLevel(); $level = $target->getLevel();
if($level instanceof Level){ if($level instanceof Level){
$above = $level->getBlock(Vector3::createVector($target->x, $target->y + 1, $target->z)); $above = $level->getBlock(new Vector3($target->x, $target->y + 1, $target->z));
if($above instanceof Block){ if($above instanceof Block){
if($above->getID() === Item::FIRE){ if($above->getID() === Item::FIRE){
$level->setBlock($above, new Air(), true); $level->setBlock($above, new Air(), true);
@ -1154,7 +1142,7 @@ class Level implements ChunkManager, Metadatable{
} }
if($player instanceof Player){ if($player instanceof Player){
$ev = PlayerInteractEvent::createEvent($player, $item, $target, $face); $ev = new PlayerInteractEvent($player, $item, $target, $face);
if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){ if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){
$t = new Vector2($target->x, $target->z); $t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z); $s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
@ -1219,7 +1207,7 @@ class Level implements ChunkManager, Metadatable{
if($player instanceof Player){ if($player instanceof Player){
$ev = BlockPlaceEvent::createEvent($player, $hand, $block, $target, $item); $ev = new BlockPlaceEvent($player, $hand, $block, $target, $item);
if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){ if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){
$t = new Vector2($target->x, $target->z); $t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z); $s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
@ -1594,7 +1582,7 @@ class Level implements ChunkManager, Metadatable{
$this->setChunk($x, $z, $chunk); $this->setChunk($x, $z, $chunk);
$chunk = $this->getChunk($x, $z); $chunk = $this->getChunk($x, $z);
if($chunk instanceof FullChunk and (!($oldChunk instanceof FullChunk) or $oldChunk->isPopulated() === false) and $chunk->isPopulated()){ if($chunk instanceof FullChunk and (!($oldChunk instanceof FullChunk) or $oldChunk->isPopulated() === false) and $chunk->isPopulated()){
$this->server->getPluginManager()->callEvent(ChunkPopulateEvent::createEvent($chunk)); $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk));
} }
} }
@ -1681,7 +1669,7 @@ class Level implements ChunkManager, Metadatable{
public function setSpawnLocation(Vector3 $pos){ public function setSpawnLocation(Vector3 $pos){
$previousSpawn = $this->getSpawnLocation(); $previousSpawn = $this->getSpawnLocation();
$this->provider->setSpawn($pos); $this->provider->setSpawn($pos);
$this->server->getPluginManager()->callEvent(SpawnChangeEvent::createEvent($this, $previousSpawn)); $this->server->getPluginManager()->callEvent(new SpawnChangeEvent($this, $previousSpawn));
} }
public function requestChunk($x, $z, Player $player, $order = LevelProvider::ORDER_ZXY){ public function requestChunk($x, $z, Player $player, $order = LevelProvider::ORDER_ZXY){
@ -1707,7 +1695,7 @@ class Level implements ChunkManager, Metadatable{
if(ADVANCED_CACHE == true and ($cache = Cache::get("world:" . $this->getID() . ":" . $index)) !== false){ if(ADVANCED_CACHE == true and ($cache = Cache::get("world:" . $this->getID() . ":" . $index)) !== false){
/** @var Player[] $players */ /** @var Player[] $players */
foreach($players as $player){ foreach($players as $player){
if(isset($player->usedChunks[$index])){ if($player->isConnected() and isset($player->usedChunks[$index])){
$player->sendChunk($x, $z, $cache); $player->sendChunk($x, $z, $cache);
} }
} }
@ -1736,7 +1724,7 @@ class Level implements ChunkManager, Metadatable{
} }
foreach($this->chunkSendQueue[$index] as $player){ foreach($this->chunkSendQueue[$index] as $player){
/** @var Player $player */ /** @var Player $player */
if(isset($player->usedChunks[$index])){ if($player->isConnected() and isset($player->usedChunks[$index])){
$player->sendChunk($x, $z, $payload); $player->sendChunk($x, $z, $payload);
} }
} }
@ -1850,7 +1838,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
$this->server->getPluginManager()->callEvent(ChunkLoadEvent::createEvent($chunk, !$chunk->isGenerated())); $this->server->getPluginManager()->callEvent(new ChunkLoadEvent($chunk, !$chunk->isGenerated()));
return true; return true;
} }
@ -1860,7 +1848,7 @@ class Level implements ChunkManager, Metadatable{
} }
public function unloadChunkRequest($x, $z, $safe = true){ public function unloadChunkRequest($x, $z, $safe = true){
if($safe === true and $this->isChunkInUse($x, $z)){ if(($safe === true and $this->isChunkInUse($x, $z)) or $this->isSpawnChunk($x, $z)){
return false; return false;
} }
@ -1874,18 +1862,18 @@ class Level implements ChunkManager, Metadatable{
} }
public function unloadChunk($x, $z, $safe = true){ public function unloadChunk($x, $z, $safe = true){
if($safe === true and $this->isChunkInUse($x, $z)){ if(($safe === true and $this->isChunkInUse($x, $z))){
return false; return false;
} }
$this->timings->doChunkUnload->startTiming(); $this->timings->doChunkUnload->startTiming();
$index = "$x:$z"; $index = Level::chunkHash($x, $z);
$chunk = $this->getChunk($x, $z); $chunk = $this->getChunk($x, $z);
if($chunk instanceof FullChunk){ if($chunk instanceof FullChunk){
$this->server->getPluginManager()->callEvent($ev = ChunkUnloadEvent::createEvent($chunk)); $this->server->getPluginManager()->callEvent($ev = new ChunkUnloadEvent($chunk));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1896,10 +1884,10 @@ class Level implements ChunkManager, Metadatable{
$this->provider->saveChunk($x, $z); $this->provider->saveChunk($x, $z);
} }
unset($this->chunks[$index]);
$this->provider->unloadChunk($x, $z, $safe); $this->provider->unloadChunk($x, $z, $safe);
unset($this->chunks[$index]);
unset($this->usedChunks[$index]); unset($this->usedChunks[$index]);
Cache::remove("world:" . $this->getID() . ":$x:$z"); Cache::remove("world:" . $this->getID() . ":$index");
$this->timings->doChunkUnload->stopTiming(); $this->timings->doChunkUnload->stopTiming();
@ -1941,29 +1929,27 @@ class Level implements ChunkManager, Metadatable{
$spawn = $this->getSpawnLocation(); $spawn = $this->getSpawnLocation();
} }
if($spawn instanceof Vector3){ if($spawn instanceof Vector3){
$x = Math::floorFloat($spawn->x); $v = $spawn->floor();
$y = Math::floorFloat($spawn->y); for(; $v->y > 0; $v->y -= 2){
$z = Math::floorFloat($spawn->z); $b = $this->getBlock($v);
$v = Vector3::createVector($x, $y, $z);
for(; $v->y > 0; --$v->y){
$b = $this->getBlock($v->getSide(0));
if($b === null){ if($b === null){
return $spawn; return $spawn;
}elseif(!($b instanceof Air)){ }elseif(!($b instanceof Air)){
$v->y += 1;
break; break;
} }
} }
for(; $v->y < 128; ++$v->y){ for(; $v->y < 128; ++$v->y){
if($this->getBlock($v->getSide(1)) instanceof Air){ if($this->getBlock($v->getSide(1)) instanceof Air){
if($this->getBlock($v) instanceof Air){ if($this->getBlock($v) instanceof Air){
return Position::createPosition($spawn->x, $v->y === Math::floorFloat($spawn->y) ? $spawn->y : $v->y, $spawn->z, $this); return new Position($spawn->x, $v->y === Math::floorFloat($spawn->y) ? $spawn->y : $v->y, $spawn->z, $this);
} }
}else{ }else{
++$v->y; ++$v->y;
} }
} }
return Position::createPosition($spawn->x, $v->y, $spawn->z, $this); return new Position($spawn->x, $v->y, $spawn->z, $this);
} }
return false; return false;

View File

@ -64,7 +64,7 @@ class MovingObjectPosition{
$ob->blockX = $x; $ob->blockX = $x;
$ob->blockY = $y; $ob->blockY = $y;
$ob->blockZ = $z; $ob->blockZ = $z;
$ob->hitVector = Vector3::createVector($hitVector->x, $hitVector->y, $hitVector->z); $ob->hitVector = new Vector3($hitVector->x, $hitVector->y, $hitVector->z);
return $ob; return $ob;
} }
@ -77,7 +77,7 @@ class MovingObjectPosition{
$ob = new MovingObjectPosition; $ob = new MovingObjectPosition;
$ob->typeOfHit = 1; $ob->typeOfHit = 1;
$ob->entityHit = $entity; $ob->entityHit = $entity;
$ob->hitVector = Vector3::createVector($entity->x, $entity->y, $entity->z); $ob->hitVector = new Vector3($entity->x, $entity->y, $entity->z);
return $ob; return $ob;
} }
} }

View File

@ -25,51 +25,10 @@ use pocketmine\math\Vector3;
use pocketmine\utils\LevelException; use pocketmine\utils\LevelException;
class Position extends Vector3{ class Position extends Vector3{
/** @var Position[] */
private static $positionList = [];
private static $nextPosition = 0;
/** @var Level */ /** @var Level */
public $level = null; public $level = null;
public static function clearPositions(){
self::$nextPosition = 0;
self::$positionList = [];
}
public static function clearPositionList(){
if(self::$nextPosition > 65536){
self::clearVectors();
}else{
self::$nextPosition = 0;
}
}
/**
* @param $x
* @param $y
* @param $z
* @param Level $level
*
* @return Position
*/
public static function createPosition($x, $y, $z, Level $level){
if(self::$nextPosition >= count(self::$positionList)){
self::$positionList[] = new Position(0, 0, 0, null);
}
return self::$positionList[self::$nextPosition++]->setLevel($level)->setComponents($x, $y, $z);
}
public static function clonePosition(Position $pos){
if(self::$nextPosition >= count(self::$positionList)){
self::$positionList[] = new Position(0, 0, 0, null);
}
return self::$positionList[self::$nextPosition++]->setLevel($pos->level)->setComponents($pos->x, $pos->y, $pos->z);
}
/** /**
* @param int $x * @param int $x
* @param int $y * @param int $y
@ -84,7 +43,7 @@ class Position extends Vector3{
} }
public static function fromObject(Vector3 $pos, Level $level = null){ public static function fromObject(Vector3 $pos, Level $level = null){
return self::createPosition($pos->x, $pos->y, $pos->z, $level); return new Position($pos->x, $pos->y, $pos->z, $level);
} }
/** /**

View File

@ -193,9 +193,10 @@ class McRegion extends BaseLevelProvider{
$chunk = $this->getChunk($x, $z, false); $chunk = $this->getChunk($x, $z, false);
if($chunk instanceof FullChunk and $chunk->unload(false, $safe)){ if($chunk instanceof FullChunk and $chunk->unload(false, $safe)){
unset($this->chunks[Level::chunkHash($x, $z)]); unset($this->chunks[Level::chunkHash($x, $z)]);
return true;
} }
return true; return false;
} }
public function saveChunk($x, $z){ public function saveChunk($x, $z){

View File

@ -66,7 +66,7 @@ class GenerationChunkManager implements ChunkManager{
/** /**
* @return int * @return int
*/ */
public function getID(){ public function getId(){
return $this->levelID; return $this->levelID;
} }

View File

@ -24,11 +24,6 @@ use pocketmine\level\MovingObjectPosition;
class AxisAlignedBB{ class AxisAlignedBB{
/** @var AxisAlignedBB[] */
public static $boundingBoxes = [];
public static $nextBoundingBox = 0;
public $minX; public $minX;
public $minY; public $minY;
public $minZ; public $minZ;
@ -45,50 +40,6 @@ class AxisAlignedBB{
$this->maxZ = $maxZ; $this->maxZ = $maxZ;
} }
public static function clearBoundingBoxes(){
self::$nextBoundingBox = 0;
self::$boundingBoxes = [];
}
public static function clearBoundingBoxPool(){
if(self::$nextBoundingBox > 65536){
self::clearBoundingBoxes();
}else{
self::$nextBoundingBox = 0;
}
}
/**
* @param $minX
* @param $minY
* @param $minZ
* @param $maxX
* @param $maxY
* @param $maxZ
*
* @return AxisAlignedBB
*/
public static function getBoundingBoxFromPool($minX, $minY, $minZ, $maxX, $maxY, $maxZ){
if(self::$nextBoundingBox >= count(self::$boundingBoxes)){
self::$boundingBoxes[] = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
}
return self::$boundingBoxes[self::$nextBoundingBox++]->setBounds($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
}
/**
* @param AxisAlignedBB $bb
*
* @return AxisAlignedBB
*/
public static function cloneBoundingBoxFromPool(AxisAlignedBB $bb){
if(self::$nextBoundingBox >= count(self::$boundingBoxes)){
self::$boundingBoxes[] = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
}
return self::$boundingBoxes[self::$nextBoundingBox++]->setBounds($bb->minX, $bb->minY, $bb->minZ, $bb->maxX, $bb->maxY, $bb->maxZ);
}
public function setBounds($minX, $minY, $minZ, $maxX, $maxY, $maxZ){ public function setBounds($minX, $minY, $minZ, $maxX, $maxY, $maxZ){
$this->minX = $minX; $this->minX = $minX;
$this->minY = $minY; $this->minY = $minY;
@ -126,11 +77,11 @@ class AxisAlignedBB{
$maxZ += $z; $maxZ += $z;
} }
return AxisAlignedBB::getBoundingBoxFromPool($minX, $minY, $minZ, $maxX, $maxY, $maxZ); return new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
} }
public function grow($x, $y, $z){ public function grow($x, $y, $z){
return AxisAlignedBB::getBoundingBoxFromPool($this->minX - $x, $this->minY - $y, $this->minZ - $z, $this->maxX + $x, $this->maxY + $y, $this->maxZ + $z); return new AxisAlignedBB($this->minX - $x, $this->minY - $y, $this->minZ - $z, $this->maxX + $x, $this->maxY + $y, $this->maxZ + $z);
} }
public function expand($x, $y, $z){ public function expand($x, $y, $z){
@ -156,7 +107,7 @@ class AxisAlignedBB{
} }
public function shrink($x, $y, $z){ public function shrink($x, $y, $z){
return AxisAlignedBB::getBoundingBoxFromPool($this->minX + $x, $this->minY + $y, $this->minZ + $z, $this->maxX - $x, $this->maxY - $y, $this->maxZ - $z); return new AxisAlignedBB($this->minX + $x, $this->minY + $y, $this->minZ + $z, $this->maxX - $x, $this->maxY - $y, $this->maxZ - $z);
} }
public function contract($x, $y, $z){ public function contract($x, $y, $z){
@ -181,7 +132,7 @@ class AxisAlignedBB{
} }
public function getOffsetBoundingBox($x, $y, $z){ public function getOffsetBoundingBox($x, $y, $z){
return AxisAlignedBB::getBoundingBoxFromPool($this->minX + $x, $this->minY + $y, $this->minZ + $z, $this->maxX + $x, $this->maxY + $y, $this->maxZ + $z); return new AxisAlignedBB($this->minX + $x, $this->minY + $y, $this->minZ + $z, $this->maxX + $x, $this->maxY + $y, $this->maxZ + $z);
} }
public function calculateXOffset(AxisAlignedBB $bb, $x){ public function calculateXOffset(AxisAlignedBB $bb, $x){

View File

@ -23,10 +23,6 @@ namespace pocketmine\math;
class Vector3{ class Vector3{
/** @var Vector3[] */
public static $vectorList = [];
public static $nextVector = 0;
const SIDE_DOWN = 0; const SIDE_DOWN = 0;
const SIDE_UP = 1; const SIDE_UP = 1;
const SIDE_NORTH = 2; const SIDE_NORTH = 2;
@ -44,47 +40,6 @@ class Vector3{
$this->z = $z; $this->z = $z;
} }
public static function clearVectors(){
Vector3::$nextVector = 0;
Vector3::$vectorList = [];
}
public static function clearVectorList(){
if(Vector3::$nextVector > 65536){
Vector3::clearVectors();
}else{
Vector3::$nextVector = 0;
}
}
/**
* @param $x
* @param $y
* @param $z
*
* @return Vector3
*/
public static function createVector($x, $y, $z){
if(Vector3::$nextVector >= count(Vector3::$vectorList)){
Vector3::$vectorList[] = new Vector3(0, 0, 0);
}
return Vector3::$vectorList[Vector3::$nextVector++]->setComponents($x, $y, $z);
}
/**
* @param Vector3 $vector
*
* @return Vector3
*/
public static function cloneVector(Vector3 $vector){
if(Vector3::$nextVector >= count(Vector3::$vectorList)){
Vector3::$vectorList[] = new Vector3(0, 0, 0);
}
return Vector3::$vectorList[Vector3::$nextVector++]->setComponents($vector->x, $vector->y, $vector->z);
}
public function getX(){ public function getX(){
return $this->x; return $this->x;
} }
@ -138,9 +93,9 @@ class Vector3{
*/ */
public function add($x, $y = 0, $z = 0){ public function add($x, $y = 0, $z = 0){
if($x instanceof Vector3){ if($x instanceof Vector3){
return Vector3::createVector($this->x + $x->x, $this->y + $x->y, $this->z + $x->z); return new Vector3($this->x + $x->x, $this->y + $x->y, $this->z + $x->z);
}else{ }else{
return Vector3::createVector($this->x + $x, $this->y + $y, $this->z + $z); return new Vector3($this->x + $x, $this->y + $y, $this->z + $z);
} }
} }
@ -160,46 +115,46 @@ class Vector3{
} }
public function multiply($number){ public function multiply($number){
return Vector3::createVector($this->x * $number, $this->y * $number, $this->z * $number); return new Vector3($this->x * $number, $this->y * $number, $this->z * $number);
} }
public function divide($number){ public function divide($number){
return Vector3::createVector($this->x / $number, $this->y / $number, $this->z / $number); return new Vector3($this->x / $number, $this->y / $number, $this->z / $number);
} }
public function ceil(){ public function ceil(){
return Vector3::createVector((int) ($this->x + 1), (int) ($this->y + 1), (int) ($this->z + 1)); return new Vector3((int) ($this->x + 1), (int) ($this->y + 1), (int) ($this->z + 1));
} }
public function floor(){ public function floor(){
$x = (int) $this->x; $x = (int) $this->x;
$y = (int) $this->y; $y = (int) $this->y;
$z = (int) $this->z; $z = (int) $this->z;
return Vector3::createVector($this->x >= $x ? $x : $x - 1, $this->y >= $y ? $y : $y - 1, $this->z >= $z ? $z : $z - 1); return new Vector3($this->x >= $x ? $x : $x - 1, $this->y >= $y ? $y : $y - 1, $this->z >= $z ? $z : $z - 1);
} }
public function round(){ public function round(){
return Vector3::createVector(round($this->x), round($this->y), round($this->z)); return new Vector3(round($this->x), round($this->y), round($this->z));
} }
public function abs(){ public function abs(){
return Vector3::createVector(abs($this->x), abs($this->y), abs($this->z)); return new Vector3(abs($this->x), abs($this->y), abs($this->z));
} }
public function getSide($side, $step = 1){ public function getSide($side, $step = 1){
switch((int) $side){ switch((int) $side){
case Vector3::SIDE_DOWN: case Vector3::SIDE_DOWN:
return Vector3::createVector($this->x, $this->y - $step, $this->z); return new Vector3($this->x, $this->y - $step, $this->z);
case Vector3::SIDE_UP: case Vector3::SIDE_UP:
return Vector3::createVector($this->x, $this->y + $step, $this->z); return new Vector3($this->x, $this->y + $step, $this->z);
case Vector3::SIDE_NORTH: case Vector3::SIDE_NORTH:
return Vector3::createVector($this->x, $this->y, $this->z - $step); return new Vector3($this->x, $this->y, $this->z - $step);
case Vector3::SIDE_SOUTH: case Vector3::SIDE_SOUTH:
return Vector3::createVector($this->x, $this->y, $this->z + $step); return new Vector3($this->x, $this->y, $this->z + $step);
case Vector3::SIDE_WEST: case Vector3::SIDE_WEST:
return Vector3::createVector($this->x - $step, $this->y, $this->z); return new Vector3($this->x - $step, $this->y, $this->z);
case Vector3::SIDE_EAST: case Vector3::SIDE_EAST:
return Vector3::createVector($this->x + $step, $this->y, $this->z); return new Vector3($this->x + $step, $this->y, $this->z);
default: default:
return $this; return $this;
} }
@ -259,7 +214,7 @@ class Vector3{
return $this->divide($len); return $this->divide($len);
} }
return Vector3::createVector(0, 0, 0); return new Vector3(0, 0, 0);
} }
public function dot(Vector3 $v){ public function dot(Vector3 $v){
@ -267,7 +222,7 @@ class Vector3{
} }
public function cross(Vector3 $v){ public function cross(Vector3 $v){
return Vector3::createVector( return new Vector3(
$this->y * $v->z - $this->z * $v->y, $this->y * $v->z - $this->z * $v->y,
$this->z * $v->x - $this->x * $v->z, $this->z * $v->x - $this->x * $v->z,
$this->x * $v->y - $this->y * $v->x $this->x * $v->y - $this->y * $v->x
@ -297,7 +252,7 @@ class Vector3{
if($f < 0 or $f > 1){ if($f < 0 or $f > 1){
return null; return null;
}else{ }else{
return Vector3::createVector($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f); return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
} }
} }
@ -324,7 +279,7 @@ class Vector3{
if($f < 0 or $f > 1){ if($f < 0 or $f > 1){
return null; return null;
}else{ }else{
return Vector3::createVector($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f); return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
} }
} }
@ -351,7 +306,7 @@ class Vector3{
if($f < 0 or $f > 1){ if($f < 0 or $f > 1){
return null; return null;
}else{ }else{
return Vector3::createVector($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f); return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
} }
} }

View File

@ -75,20 +75,12 @@ class NBT{
public function get($len){ public function get($len){
if($len < 0){ if($len < 0){
$this->offset = strlen($this->buffer) - 1; $this->offset = strlen($this->buffer) - 1;
return ""; return "";
}elseif($len === true){ }elseif($len === true){
return substr($this->buffer, $this->offset); return substr($this->buffer, $this->offset);
} }
if($len > 16){
return substr($this->buffer, ($this->offset += $len) - $len, $len);
}
$buffer = "";
for(; $len > 0; --$len, ++$this->offset){
$buffer .= $this->buffer{$this->offset};
}
return $buffer; return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len);
} }
public function put($v){ public function put($v){

View File

@ -74,6 +74,7 @@ use pocketmine\network\protocol\UpdateBlockPacket;
use pocketmine\network\protocol\UseItemPacket; use pocketmine\network\protocol\UseItemPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\MainLogger;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use raklib\protocol\EncapsulatedPacket; use raklib\protocol\EncapsulatedPacket;
use raklib\RakLib; use raklib\RakLib;
@ -83,7 +84,8 @@ use raklib\server\ServerInstance;
class RakLibInterface implements ServerInstance, SourceInterface{ class RakLibInterface implements ServerInstance, SourceInterface{
private $packetPool = []; /** @var \SplFixedArray */
private $packetPool;
private $server; private $server;
/** @var Player[] */ /** @var Player[] */
@ -120,8 +122,6 @@ class RakLibInterface implements ServerInstance, SourceInterface{
} }
public function doTick(){ public function doTick(){
$this->cleanPacketPool();
EncapsulatedPacket::cleanPacketPool();
$this->interface->sendTick(); $this->interface->sendTick();
} }
@ -175,9 +175,19 @@ class RakLibInterface implements ServerInstance, SourceInterface{
public function handleEncapsulated($identifier, EncapsulatedPacket $packet, $flags){ public function handleEncapsulated($identifier, EncapsulatedPacket $packet, $flags){
if(isset($this->players[$identifier])){ if(isset($this->players[$identifier])){
$pk = $this->getPacket($packet->buffer); try{
$pk->decode(); $pk = $this->getPacket($packet->buffer);
$this->players[$identifier]->handleDataPacket($pk); $pk->decode();
$this->players[$identifier]->handleDataPacket($pk);
}catch (\Exception $e){
if(\pocketmine\DEBUG > 1){
$logger = $this->server->getLogger();
if($logger instanceof MainLogger){
$logger->logException($e);
$logger->debug("Packet ".get_class($pk)." 0x".bin2hex($packet->buffer));
}
}
}
} }
} }
@ -225,7 +235,6 @@ class RakLibInterface implements ServerInstance, SourceInterface{
$pk = null; $pk = null;
if(!$packet->isEncoded){ if(!$packet->isEncoded){
$packet->encode(); $packet->encode();
unset($packet->__encapsulatedPacket);
}elseif(!$needACK){ }elseif(!$needACK){
if(!isset($packet->__encapsulatedPacket)){ if(!isset($packet->__encapsulatedPacket)){
$packet->__encapsulatedPacket = new CachedEncapsulatedPacket; $packet->__encapsulatedPacket = new CachedEncapsulatedPacket;
@ -237,13 +246,11 @@ class RakLibInterface implements ServerInstance, SourceInterface{
} }
if($pk === null){ if($pk === null){
$pk = EncapsulatedPacket::getPacketFromPool(); $pk = new EncapsulatedPacket();
$pk->buffer = $packet->buffer; $pk->buffer = $packet->buffer;
$pk->reliability = 2; $pk->reliability = 2;
if($needACK === true){ if($needACK === true){
$pk->identifierACK = $this->identifiersACK[$identifier]++; $pk->identifierACK = $this->identifiersACK[$identifier]++;
}else{
$pk->identifierACK = null;
} }
} }
@ -265,23 +272,17 @@ class RakLibInterface implements ServerInstance, SourceInterface{
* @return DataPacket * @return DataPacket
*/ */
public function getPacketFromPool($id){ public function getPacketFromPool($id){
if(isset($this->packetPool[$id])){ /** @var DataPacket $class */
/** @var DataPacket $class */ $class = $this->packetPool[$id];
$class = $this->packetPool[$id]; if($class !== null){
return $class::getFromPool(); return new $class;
} }
return null; return null;
} }
public function cleanPacketPool(){
foreach($this->packetPool as $class){
/** @var DataPacket $class */
$class::cleanPool();
}
}
private function registerPackets(){ private function registerPackets(){
$this->packetPool = new \SplFixedArray(256);
$this->registerPacket(ProtocolInfo::LOGIN_PACKET, LoginPacket::class); $this->registerPacket(ProtocolInfo::LOGIN_PACKET, LoginPacket::class);
$this->registerPacket(ProtocolInfo::LOGIN_STATUS_PACKET, LoginStatusPacket::class); $this->registerPacket(ProtocolInfo::LOGIN_STATUS_PACKET, LoginStatusPacket::class);
$this->registerPacket(ProtocolInfo::MESSAGE_PACKET, MessagePacket::class); $this->registerPacket(ProtocolInfo::MESSAGE_PACKET, MessagePacket::class);
@ -333,7 +334,7 @@ class RakLibInterface implements ServerInstance, SourceInterface{
$pid = ord($buffer{0}); $pid = ord($buffer{0});
if(($data = $this->getPacketFromPool($pid)) === null){ if(($data = $this->getPacketFromPool($pid)) === null){
$data = UnknownPacket::getFromPool(); $data = new UnknownPacket();
$data->packetID = $pid; $data->packetID = $pid;
} }
$data->setBuffer(substr($buffer, 1)); $data->setBuffer(substr($buffer, 1));

View File

@ -27,69 +27,11 @@ namespace pocketmine\network\protocol;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
#endif #endif
use pocketmine\event\server\DataPacketSendEvent;
use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\Player;
abstract class DataPacket extends \stdClass{ abstract class DataPacket extends \stdClass{
/** @var DataPacket[] */
public static $pool = [];
public static $next = 0;
/** @var DataPacketSendEvent */
private $sendEvent = null;
/** @var DataPacketReceiveEvent */
private $receiveEvent = null;
public static function getFromPool(){
if(static::$next >= count(static::$pool)){
static::$pool[] = new static;
}
return static::$pool[static::$next++]->clean();
}
public static function cleanPool(){
if(static::$next > 16384){
static::$pool = [];
}
static::$next = 0;
}
/**
* @param Player $player
*
* @return DataPacketReceiveEvent
*/
public function getReceiveEvent(Player $player){
if($this->receiveEvent === null){
$this->receiveEvent = new DataPacketReceiveEvent($player, $this);
}else{
$this->receiveEvent->setCancelled(false);
$this->receiveEvent->__construct($player, $this);
}
return $this->receiveEvent;
}
/**
* @param Player $player
*
* @return DataPacketSendEvent
*/
public function getSendEvent(Player $player){
if($this->sendEvent === null){
$this->sendEvent = new DataPacketSendEvent($player, $this);
}else{
$this->sendEvent->setCancelled(false);
$this->sendEvent->__construct($player, $this);
}
return $this->sendEvent;
}
private $offset = 0; private $offset = 0;
public $buffer = ""; public $buffer = "";
public $isEncoded = false; public $isEncoded = false;
@ -115,20 +57,14 @@ abstract class DataPacket extends \stdClass{
} }
protected function get($len){ protected function get($len){
if($len <= 0){ if($len < 0){
$this->offset = strlen($this->buffer) - 1; $this->offset = strlen($this->buffer) - 1;
return ""; return "";
}elseif($len === true){ }elseif($len === true){
return substr($this->buffer, $this->offset); return substr($this->buffer, $this->offset);
} }
$buffer = ""; return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len);
for(; $len > 0; --$len, ++$this->offset){
$buffer .= $this->buffer{$this->offset};
}
return $buffer;
} }
protected function put($str){ protected function put($str){
@ -177,11 +113,11 @@ abstract class DataPacket extends \stdClass{
protected function getLTriad(){ protected function getLTriad(){
return Binary::readTriad(strrev($this->get(3))); return Binary::readLTriad($this->get(3));
} }
protected function putLTriad($v){ protected function putLTriad($v){
$this->buffer .= strrev(Binary::writeTriad($v)); $this->buffer .= Binary::writeLTriad($v);
} }
protected function getByte(){ protected function getByte(){

View File

@ -58,7 +58,7 @@ class QueryHandler{
} }
public function regenerateInfo(){ public function regenerateInfo(){
$this->server->getPluginManager()->callEvent($ev = QueryRegenerateEvent::createEvent($this->server, 5)); $this->server->getPluginManager()->callEvent($ev = new QueryRegenerateEvent($this->server, 5));
$this->longData = $ev->getLongQuery(); $this->longData = $ev->getLongQuery();
$this->shortData = $ev->getShortQuery(); $this->shortData = $ev->getShortQuery();
$this->timeout = microtime(true) + $ev->getTimeout(); $this->timeout = microtime(true) + $ev->getTimeout();

View File

@ -94,7 +94,7 @@ class RCON{
$response = new RemoteConsoleCommandSender(); $response = new RemoteConsoleCommandSender();
$command = $this->workers[$n]->cmd; $command = $this->workers[$n]->cmd;
$this->server->getPluginManager()->callEvent($ev = RemoteServerCommandEvent::createEvent($response, $command)); $this->server->getPluginManager()->callEvent($ev = new RemoteServerCommandEvent($response, $command));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->server->dispatchCommand($ev->getSender(), $ev->getCommand()); $this->server->dispatchCommand($ev->getSender(), $ev->getCommand());

View File

@ -88,6 +88,8 @@ abstract class DefaultPermissions{
$time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands); $time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time); self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time); self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), $time);
$time->recalculatePermissibles(); $time->recalculatePermissibles();
self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $commands); self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $commands);

View File

@ -122,7 +122,7 @@ class PharPluginLoader implements PluginLoader{
$plugin->setEnabled(true); $plugin->setEnabled(true);
$this->server->getPluginManager()->callEvent(PluginEnableEvent::createEvent($plugin)); $this->server->getPluginManager()->callEvent(new PluginEnableEvent($plugin));
} }
} }
@ -133,7 +133,7 @@ class PharPluginLoader implements PluginLoader{
if($plugin instanceof PluginBase and $plugin->isEnabled()){ if($plugin instanceof PluginBase and $plugin->isEnabled()){
$this->server->getLogger()->info("Disabling " . $plugin->getDescription()->getFullName()); $this->server->getLogger()->info("Disabling " . $plugin->getDescription()->getFullName());
$this->server->getPluginManager()->callEvent(PluginDisableEvent::createEvent($plugin)); $this->server->getPluginManager()->callEvent(new PluginDisableEvent($plugin));
$plugin->setEnabled(false); $plugin->setEnabled(false);
} }

View File

@ -144,7 +144,7 @@ class ServerScheduler{
} }
$this->tasks = []; $this->tasks = [];
$this->asyncTaskStorage = []; $this->asyncTaskStorage = [];
$this->asyncPool->shutdown(); //$this->asyncPool->shutdown();
$this->asyncTasks = 0; $this->asyncTasks = 0;
$this->queue = new ReversePriorityQueue(); $this->queue = new ReversePriorityQueue();
$this->asyncPool = new \Pool(self::$WORKERS, AsyncWorker::class); $this->asyncPool = new \Pool(self::$WORKERS, AsyncWorker::class);

View File

@ -43,7 +43,6 @@ class Chest extends Spawnable implements InventoryHolder, Container{
protected $doubleInventory = null; protected $doubleInventory = null;
public function __construct(FullChunk $chunk, Compound $nbt){ public function __construct(FullChunk $chunk, Compound $nbt){
$nbt->id = new String("id", Tile::CHEST);
parent::__construct($chunk, $nbt); parent::__construct($chunk, $nbt);
$this->inventory = new ChestInventory($this); $this->inventory = new ChestInventory($this);
@ -197,7 +196,7 @@ class Chest extends Spawnable implements InventoryHolder, Container{
*/ */
public function getPair(){ public function getPair(){
if($this->isPaired()){ if($this->isPaired()){
$tile = $this->getLevel()->getTile(Vector3::createVector((int) $this->namedtag["pairx"], $this->y, (int) $this->namedtag["pairz"])); $tile = $this->getLevel()->getTile(new Vector3((int) $this->namedtag["pairx"], $this->y, (int) $this->namedtag["pairz"]));
if($tile instanceof Chest){ if($tile instanceof Chest){
return $tile; return $tile;
} }

View File

@ -34,7 +34,6 @@ use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\Short;
use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\ContainerSetDataPacket; use pocketmine\network\protocol\ContainerSetDataPacket;
class Furnace extends Tile implements InventoryHolder, Container{ class Furnace extends Tile implements InventoryHolder, Container{
@ -42,7 +41,6 @@ class Furnace extends Tile implements InventoryHolder, Container{
protected $inventory; protected $inventory;
public function __construct(FullChunk $chunk, Compound $nbt){ public function __construct(FullChunk $chunk, Compound $nbt){
$nbt->id = new String("id", Tile::FURNACE);
parent::__construct($chunk, $nbt); parent::__construct($chunk, $nbt);
$this->inventory = new FurnaceInventory($this); $this->inventory = new FurnaceInventory($this);
@ -169,7 +167,7 @@ class Furnace extends Tile implements InventoryHolder, Container{
} }
protected function checkFuel(Item $fuel){ protected function checkFuel(Item $fuel){
$this->server->getPluginManager()->callEvent($ev = FurnaceBurnEvent::createEvent($this, $fuel, $fuel->getFuelTime())); $this->server->getPluginManager()->callEvent($ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime()));
if($ev->isCancelled()){ if($ev->isCancelled()){
return; return;
@ -219,7 +217,7 @@ class Furnace extends Tile implements InventoryHolder, Container{
if($this->namedtag["CookTime"] >= 200){ //10 seconds if($this->namedtag["CookTime"] >= 200){ //10 seconds
$product = Item::get($smelt->getResult()->getID(), $smelt->getResult()->getDamage(), $product->getCount() + 1); $product = Item::get($smelt->getResult()->getID(), $smelt->getResult()->getDamage(), $product->getCount() + 1);
$this->server->getPluginManager()->callEvent($ev = FurnaceSmeltEvent::createEvent($this, $raw, $product)); $this->server->getPluginManager()->callEvent($ev = new FurnaceSmeltEvent($this, $raw, $product));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->inventory->setResult($ev->getResult()); $this->inventory->setResult($ev->getResult());
@ -252,13 +250,13 @@ class Furnace extends Tile implements InventoryHolder, Container{
foreach($this->getInventory()->getViewers() as $player){ foreach($this->getInventory()->getViewers() as $player){
$windowId = $player->getWindowId($this->getInventory()); $windowId = $player->getWindowId($this->getInventory());
if($windowId > 0){ if($windowId > 0){
$pk = ContainerSetDataPacket::getFromPool(); $pk = new ContainerSetDataPacket();
$pk->windowid = $windowId; $pk->windowid = $windowId;
$pk->property = 0; //Smelting $pk->property = 0; //Smelting
$pk->value = floor($this->namedtag["CookTime"]); $pk->value = floor($this->namedtag["CookTime"]);
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = ContainerSetDataPacket::getFromPool(); $pk = new ContainerSetDataPacket();
$pk->windowid = $windowId; $pk->windowid = $windowId;
$pk->property = 1; //Fire icon $pk->property = 1; //Fire icon
$pk->value = $this->namedtag["BurnTicks"]; $pk->value = $this->namedtag["BurnTicks"];

View File

@ -29,7 +29,6 @@ use pocketmine\nbt\tag\String;
class Sign extends Spawnable{ class Sign extends Spawnable{
public function __construct(FullChunk $chunk, Compound $nbt){ public function __construct(FullChunk $chunk, Compound $nbt){
$nbt->id = new String("id", Tile::SIGN);
if(!isset($nbt->Text1)){ if(!isset($nbt->Text1)){
$nbt->Text1 = new String("Text1", ""); $nbt->Text1 = new String("Text1", "");
} }

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