Merge branch 'master' into api3/network

This commit is contained in:
Dylan K. Taylor 2017-03-25 21:26:46 +00:00
commit 4245274aec
20 changed files with 128 additions and 46 deletions

View File

@ -143,7 +143,7 @@ class CrashDump{
$error = $lastExceptionError;
}else{
$error = (array) error_get_last();
$error["trace"] = @getTrace(3);
$error["trace"] = getTrace(4); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
$errorConversion = [
E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING",

View File

@ -3722,15 +3722,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->dataPacket($pk);
}
public function setHealth($amount){
parent::setHealth($amount);
if($this->spawned === true){
$pk = new SetHealthPacket();
$pk->health = $this->getHealth();
$this->dataPacket($pk);
}
}
public function attack($damage, EntityDamageEvent $source){
if(!$this->isAlive()){
return;

View File

@ -357,7 +357,7 @@ namespace pocketmine {
return -1;
}
function getTrace($start = 1, $trace = null){
function getTrace($start = 0, $trace = null){
if($trace === null){
if(function_exists("xdebug_get_function_stack")){
$trace = array_reverse(xdebug_get_function_stack());

View File

@ -158,6 +158,9 @@ class Server{
private $currentTPS = 20;
private $currentUse = 0;
/** @var bool */
private $doTitleTick = true;
private $sendUsageTicker = 0;
private $dispatchSignals = false;
@ -1466,6 +1469,8 @@ class Server{
$this->alwaysTickPlayers = (int) $this->getProperty("level-settings.always-tick-players", false);
$this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1);
$this->doTitleTick = (bool) $this->getProperty("console.title-tick", true);
$this->scheduler = new ServerScheduler();
if($this->getConfigBoolean("enable-rcon", false) === true){
@ -2040,9 +2045,8 @@ class Server{
$errline = $e->getLine();
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? \LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? \LogLevel::WARNING : \LogLevel::NOTICE);
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$errstr = preg_replace('/\s+/', ' ', trim($errstr));
$errfile = cleanPath($errfile);
@ -2054,7 +2058,7 @@ class Server{
"fullFile" => $e->getFile(),
"file" => $errfile,
"line" => $errline,
"trace" => @getTrace(1, $trace)
"trace" => getTrace(0, $trace)
];
global $lastExceptionError, $lastError;
@ -2263,7 +2267,9 @@ class Server{
}
public function sendUsage($type = SendUsageTask::TYPE_STATUS){
$this->scheduler->scheduleAsyncTask(new SendUsageTask($this, $type, $this->uniquePlayers));
if($this->getProperty("anonymous-statistics.enabled", true)){
$this->scheduler->scheduleAsyncTask(new SendUsageTask($this, $type, $this->uniquePlayers));
}
$this->uniquePlayers = [];
}
@ -2297,10 +2303,6 @@ class Server{
}
private function titleTick(){
if(!Terminal::hasFormattingCodes()){
return;
}
$d = Utils::getRealMemoryUsage();
$u = Utils::getMemoryUsage(true);
@ -2376,7 +2378,9 @@ class Server{
}
if(($this->tickCounter & 0b1111) === 0){
$this->titleTick();
if($this->doTitleTick and Terminal::hasFormattingCodes()){
$this->titleTick();
}
$this->currentTPS = 20;
$this->currentUse = 0;
@ -2441,4 +2445,13 @@ class Server{
return true;
}
/**
* Called when something attempts to serialize the server instance.
*
* @throws \BadMethodCallException because Server instances cannot be serialized
*/
public function __sleep(){
throw new \BadMethodCallException("Cannot serialize Server instance");
}
}

View File

@ -22,7 +22,7 @@
namespace pocketmine\block;
class GlowingObsidian extends Transparent{
class GlowingObsidian extends Solid{
protected $id = self::GLOWING_OBSIDIAN;

View File

@ -32,4 +32,8 @@ class RedstoneTorch extends Torch{
public function getName(){
return "Redstone Torch";
}
public function getLightLevel(){
return 7;
}
}

View File

@ -34,7 +34,7 @@ class Torch extends Flowable{
}
public function getLightLevel(){
return 15;
return 14;
}
public function getName(){

View File

@ -136,7 +136,7 @@ class SimpleCommandMap implements CommandMap{
if($label === null){
$label = $command->getName();
}
$label = strtolower(trim($label));
$label = trim($label);
$fallbackPrefix = strtolower(trim($fallbackPrefix));
$registered = $this->registerAlias($command, false, $fallbackPrefix, $label);
@ -188,7 +188,7 @@ class SimpleCommandMap implements CommandMap{
* @return Command|null
*/
public function matchCommand(string &$commandName, array &$args){
$count = max(count($args), 255);
$count = min(count($args), 255);
for($i = 0; $i < $count; ++$i){
$commandName .= array_shift($args);

View File

@ -470,7 +470,7 @@ abstract class Entity extends Location implements Metadatable{
if(isset($this->effects[$effect->getId()])){
$oldEffect = $this->effects[$effect->getId()];
if(
abs($effect->getAmplifier()) <= ($oldEffect->getAmplifier())
abs($effect->getAmplifier()) < ($oldEffect->getAmplifier())
or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier())
and $effect->getDuration() < $oldEffect->getDuration())
){

View File

@ -408,6 +408,12 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
public function saveNBT(){
parent::saveNBT();
$this->namedtag->foodLevel = new IntTag("foodLevel", $this->getFood());
$this->namedtag->foodExhaustionLevel = new FloatTag("foodExhaustionLevel", $this->getExhaustion());
$this->namedtag->foodSaturationLevel = new FloatTag("foodSaturationLevel", $this->getSaturation());
$this->namedtag->foodTickTimer = new IntTag("foodTickTimer", $this->foodTickTimer);
$this->namedtag->Inventory = new ListTag("Inventory", []);
$this->namedtag->Inventory->setTagType(NBT::TAG_Compound);
if($this->inventory !== null){
@ -437,7 +443,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize();
for($slot = $this->inventory->getHotbarSize(); $slot < $slotCount; ++$slot){
$item = $this->inventory->getItem($slot - 9);
$this->namedtag->Inventory[$slot] = $item->nbtSerialize($slot);
if($item->getId() !== ItemItem::AIR){
$this->namedtag->Inventory[$slot] = $item->nbtSerialize($slot);
}
}
//Armor

View File

@ -25,6 +25,13 @@ use pocketmine\level\Level;
class LevelTimings{
/** @var TimingsHandler */
public $setBlock;
/** @var TimingsHandler */
public $doBlockLightUpdates;
/** @var TimingsHandler */
public $doBlockSkyLightUpdates;
/** @var TimingsHandler */
public $mobSpawn;
/** @var TimingsHandler */
@ -79,6 +86,10 @@ class LevelTimings{
public function __construct(Level $level){
$name = $level->getFolderName() . " - ";
$this->setBlock = new TimingsHandler("** " . $name . "setBlock");
$this->doBlockLightUpdates = new TimingsHandler("** " . $name . "doBlockLightUpdates");
$this->doBlockSkyLightUpdates = new TimingsHandler("** " . $name . "doBlockSkyLightUpdates");
$this->mobSpawn = new TimingsHandler("** " . $name . "mobSpawn");
$this->doChunkUnload = new TimingsHandler("** " . $name . "doChunkUnload");
$this->doTickPending = new TimingsHandler("** " . $name . "doTickPending");

View File

@ -65,13 +65,19 @@ class Item implements ItemIds, \JsonSerializable{
/** @var \SplFixedArray */
public static $list = null;
/** @var Block|null */
protected $block;
/** @var int */
protected $id;
/** @var int */
protected $meta;
/** @var string */
private $tags = "";
/** @var CompoundTag|null */
private $cachedNBT = null;
/** @var int */
public $count;
protected $durability = 0;
/** @var string */
protected $name;
public function canBeActivated(){
@ -1007,4 +1013,12 @@ class Item implements ItemIds, \JsonSerializable{
return $item;
}
public function __clone(){
if($this->block !== null){
$this->block = clone $this->block;
}
$this->cachedNBT = null;
}
}

View File

@ -37,10 +37,6 @@ class ItemBlock extends Item{
$this->block->setDamage($this->meta !== -1 ? $this->meta : 0);
}
public function __clone(){
$this->block = clone $this->block;
}
public function getBlock() : Block{
return $this->block;
}

View File

@ -1286,17 +1286,42 @@ class Level implements ChunkManager, Metadatable{
}
public function updateBlockSkyLight(int $x, int $y, int $z){
$this->timings->doBlockSkyLightUpdates->startTiming();
//TODO
$this->timings->doBlockSkyLightUpdates->stopTiming();
}
/**
* Returns the highest light level available in the positions adjacent to the specified block coordinates.
*
* @param int $x
* @param int $y
* @param int $z
*
* @return int
*/
public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{
return max([
$this->getBlockLightAt($x + 1, $y, $z),
$this->getBlockLightAt($x - 1, $y, $z),
$this->getBlockLightAt($x, $y + 1, $z),
$this->getBlockLightAt($x, $y - 1, $z),
$this->getBlockLightAt($x, $y, $z + 1),
$this->getBlockLightAt($x, $y, $z - 1)
]);
}
public function updateBlockLight(int $x, int $y, int $z){
$this->timings->doBlockLightUpdates->startTiming();
$lightPropagationQueue = new \SplQueue();
$lightRemovalQueue = new \SplQueue();
$visited = [];
$removalVisited = [];
$id = $this->getBlockIdAt($x, $y, $z);
$oldLevel = $this->getBlockLightAt($x, $y, $z);
$newLevel = (int) Block::$light[$this->getBlockIdAt($x, $y, $z)];
$newLevel = max(Block::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - Block::$lightFilter[$id]);
if($oldLevel !== $newLevel){
$this->setBlockLightAt($x, $y, $z, $newLevel);
@ -1328,7 +1353,7 @@ class Level implements ChunkManager, Metadatable{
/** @var Vector3 $node */
$node = $lightPropagationQueue->dequeue();
$lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z) - (int) Block::$lightFilter[$this->getBlockIdAt($node->x, $node->y, $node->z)];
$lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z);
if($lightLevel >= 1){
$this->computeSpreadBlockLight($node->x - 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited);
@ -1339,6 +1364,8 @@ class Level implements ChunkManager, Metadatable{
$this->computeSpreadBlockLight($node->x, $node->y, $node->z + 1, $lightLevel, $lightPropagationQueue, $visited);
}
}
$this->timings->doBlockLightUpdates->stopTiming();
}
private function computeRemoveBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){
@ -1365,6 +1392,7 @@ class Level implements ChunkManager, Metadatable{
private function computeSpreadBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, array &$visited){
if($y < 0) return;
$current = $this->getBlockLightAt($x, $y, $z);
$currentLight -= Block::$lightFilter[$this->getBlockIdAt($x, $y, $z)];
if($current < $currentLight){
$this->setBlockLightAt($x, $y, $z, $currentLight);
@ -1402,6 +1430,8 @@ class Level implements ChunkManager, Metadatable{
return false;
}
$this->timings->setBlock->startTiming();
if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & Level::Y_MASK, $pos->z & 0x0f, $block->getId(), $block->getDamage())){
if(!($pos instanceof Position)){
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
@ -1441,9 +1471,13 @@ class Level implements ChunkManager, Metadatable{
$this->updateAround($pos);
}
$this->timings->setBlock->stopTiming();
return true;
}
$this->timings->setBlock->stopTiming();
return false;
}
@ -1508,7 +1542,7 @@ class Level implements ChunkManager, Metadatable{
if(($player->isSurvival() and $item instanceof Item and !$target->isBreakable($item)) or $player->isSpectator()){
$ev->setCancelled();
}elseif(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){
}elseif(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){
$t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
@ -1645,7 +1679,7 @@ class Level implements ChunkManager, Metadatable{
if($player !== null){
$ev = new PlayerInteractEvent($player, $item, $target, $face, $target->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK);
if(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){
if(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){
$t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
@ -1735,7 +1769,7 @@ class Level implements ChunkManager, Metadatable{
if($player !== null){
$ev = new BlockPlaceEvent($player, $hand, $block, $target, $item);
if(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){
if(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){
$t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this

View File

@ -250,7 +250,7 @@ class Vector3{
if($f < 0 or $f > 1){
return null;
}else{
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
return new Vector3($x, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
}
}
@ -277,7 +277,7 @@ class Vector3{
if($f < 0 or $f > 1){
return null;
}else{
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
return new Vector3($this->x + $xDiff * $f, $y, $this->z + $zDiff * $f);
}
}
@ -304,7 +304,7 @@ class Vector3{
if($f < 0 or $f > 1){
return null;
}else{
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $z);
}
}

View File

@ -47,12 +47,13 @@ abstract class DefaultPermissions{
$parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities"));
$broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent);
self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts);
self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts);
$broadcasts->recalculatePermissibles();
$spawnprotect = self::registerPermission(new Permission(self::ROOT . ".spawnprotect.bypass", "Allows the user to edit blocks within the protected spawn radius", Permission::DEFAULT_OP), $parent);
$spawnprotect->recalculatePermissibles();
$commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent);
$whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands);

View File

@ -185,6 +185,11 @@ timings:
#Choose the host to use for viewing your timings results.
host: mcpetimings.com
console:
#Choose whether to enable server stats reporting on the console title.
#NOTE: The title ticker will be disabled regardless if console colours are not enabled.
title-tick: true
aliases:
#Examples:
#showtheversion: version

View File

@ -63,6 +63,10 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
foreach($this->getInventory()->getViewers() as $player){
$player->removeWindow($this->getRealInventory());
}
$this->inventory = null;
$this->doubleInventory = null;
parent::close();
}
}

View File

@ -92,6 +92,9 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
foreach($this->getInventory()->getViewers() as $player){
$player->removeWindow($this->getInventory());
}
$this->inventory = null;
parent::close();
}
}

View File

@ -134,12 +134,10 @@ class MainLogger extends \AttachableThreadedLogger{
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? LogLevel::WARNING : LogLevel::NOTICE);
}
$errno = $errorConversion[$errno] ?? $errno;
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$errstr = preg_replace('/\s+/', ' ', trim($errstr));
$errfile = \pocketmine\cleanPath($errfile);
$this->log($type, get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline");
foreach(@\pocketmine\getTrace(1, $trace) as $i => $line){
foreach(\pocketmine\getTrace(0, $trace) as $i => $line){
$this->debug($line);
}
}