Merge master into api3/network

This commit is contained in:
Dylan K. Taylor 2017-04-10 21:21:29 +01:00 committed by GitHub
commit e312c697fd
9 changed files with 141 additions and 32 deletions

View File

@ -345,7 +345,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
public function isBanned(){ public function isBanned(){
return $this->server->getNameBans()->isBanned(strtolower($this->getName())); return $this->server->getNameBans()->isBanned($this->iusername);
} }
public function setBanned($value){ public function setBanned($value){
@ -358,14 +358,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
public function isWhitelisted(){ public function isWhitelisted(){
return $this->server->isWhitelisted(strtolower($this->getName())); return $this->server->isWhitelisted($this->iusername);
} }
public function setWhitelisted($value){ public function setWhitelisted($value){
if($value === true){ if($value === true){
$this->server->addWhitelist(strtolower($this->getName())); $this->server->addWhitelist($this->iusername);
}else{ }else{
$this->server->removeWhitelist(strtolower($this->getName())); $this->server->removeWhitelist($this->iusername);
} }
} }
@ -1731,18 +1731,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
protected function processLogin(){ protected function processLogin(){
if(!$this->server->isWhitelisted(strtolower($this->getName()))){ if(!$this->server->isWhitelisted($this->iusername)){
$this->close($this->getLeaveMessage(), "Server is white-listed"); $this->close($this->getLeaveMessage(), "Server is white-listed");
return; return;
}elseif($this->server->getNameBans()->isBanned(strtolower($this->getName())) or $this->server->getIPBans()->isBanned($this->getAddress())){ }elseif($this->server->getNameBans()->isBanned($this->iusername) or $this->server->getIPBans()->isBanned($this->getAddress())){
$this->close($this->getLeaveMessage(), "You are banned"); $this->close($this->getLeaveMessage(), "You are banned");
return; return;
} }
foreach($this->server->getOnlinePlayers() as $p){ foreach($this->server->getOnlinePlayers() as $p){
if($p !== $this and strtolower($p->getName()) === strtolower($this->getName())){ if($p !== $this and $p->iusername === $this->iusername){
if($p->kick("logged in from another location") === false){ if($p->kick("logged in from another location") === false){
$this->close($this->getLeaveMessage(), "Logged in from another location"); $this->close($this->getLeaveMessage(), "Logged in from another location");

View File

@ -128,7 +128,6 @@ namespace pocketmine {
set_time_limit(0); //Who set it to 30 seconds?!?! set_time_limit(0); //Who set it to 30 seconds?!?!
gc_enable();
error_reporting(-1); error_reporting(-1);
ini_set("allow_url_fopen", 1); ini_set("allow_url_fopen", 1);
ini_set("display_errors", 1); ini_set("display_errors", 1);

View File

@ -64,7 +64,7 @@ class Lava extends Liquid{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$ret = $this->getLevel()->setBlock($this, $this, true, false); $ret = $this->getLevel()->setBlock($this, $this, true, false);
$this->getLevel()->scheduleUpdate($this, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
return $ret; return $ret;
} }

View File

@ -189,7 +189,7 @@ abstract class Liquid extends Transparent{
public function onUpdate($type){ public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){ if($type === Level::BLOCK_UPDATE_NORMAL){
$this->checkForHarden(); $this->checkForHarden();
$this->getLevel()->scheduleUpdate($this, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
}elseif($type === Level::BLOCK_UPDATE_SCHEDULED){ }elseif($type === Level::BLOCK_UPDATE_SCHEDULED){
if($this->temporalVector === null){ if($this->temporalVector === null){
$this->temporalVector = new Vector3(0, 0, 0); $this->temporalVector = new Vector3(0, 0, 0);
@ -242,7 +242,7 @@ abstract class Liquid extends Transparent{
$this->getLevel()->setBlock($this, new Air(), true); $this->getLevel()->setBlock($this, new Air(), true);
}else{ }else{
$this->getLevel()->setBlock($this, Block::get($this->id, $decay), true); $this->getLevel()->setBlock($this, Block::get($this->id, $decay), true);
$this->getLevel()->scheduleUpdate($this, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
} }
}elseif($flag){ }elseif($flag){
//$this->getLevel()->scheduleUpdate($this, $this->tickRate()); //$this->getLevel()->scheduleUpdate($this, $this->tickRate());
@ -262,10 +262,10 @@ abstract class Liquid extends Transparent{
if($decay >= 8){ if($decay >= 8){
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay), true); $this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay), true);
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($bottomBlock, $this->tickRate());
}else{ }else{
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay + 8), true); $this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay + 8), true);
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($bottomBlock, $this->tickRate());
} }
}elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->canBeFlowedInto())){ }elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->canBeFlowedInto())){
$flags = $this->getOptimalFlowDirections(); $flags = $this->getOptimalFlowDirections();
@ -310,7 +310,7 @@ abstract class Liquid extends Transparent{
} }
$this->getLevel()->setBlock($block, Block::get($this->getId(), $newFlowDecay), true); $this->getLevel()->setBlock($block, Block::get($this->getId(), $newFlowDecay), true);
$this->getLevel()->scheduleUpdate($block, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($block, $this->tickRate());
} }
} }

View File

@ -48,7 +48,7 @@ class Water extends Liquid{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$ret = $this->getLevel()->setBlock($this, $this, true, false); $ret = $this->getLevel()->setBlock($this, $this, true, false);
$this->getLevel()->scheduleUpdate($this, $this->tickRate()); $this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
return $ret; return $ret;
} }

View File

@ -30,8 +30,6 @@ abstract class Event{
* Any callable event must declare the static variable * Any callable event must declare the static variable
* *
* public static $handlerList = null; * public static $handlerList = null;
* public static $eventPool = [];
* public static $nextEvent = 0;
* *
* Not doing so will deny the proper event initialization * Not doing so will deny the proper event initialization
*/ */
@ -85,4 +83,4 @@ abstract class Event{
return static::$handlerList; return static::$handlerList;
} }
} }

View File

@ -201,7 +201,7 @@ class Explosion{
$pos = new Vector3($block->x, $block->y, $block->z); $pos = new Vector3($block->x, $block->y, $block->z);
for($side = 0; $side < 5; $side++){ for($side = 0; $side <= 5; $side++){
$sideBlock = $pos->getSide($side); $sideBlock = $pos->getSide($side);
if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){ if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock))); $this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock)));

View File

@ -190,8 +190,11 @@ class Level implements ChunkManager, Metadatable{
private $changedBlocks = []; private $changedBlocks = [];
/** @var ReversePriorityQueue */ /** @var ReversePriorityQueue */
private $updateQueue; private $scheduledBlockUpdateQueue;
private $updateQueueIndex = []; private $scheduledBlockUpdateQueueIndex = [];
/** @var \SplQueue */
private $neighbourBlockUpdateQueue = [];
/** @var Player[][] */ /** @var Player[][] */
private $chunkSendQueue = []; private $chunkSendQueue = [];
@ -333,8 +336,11 @@ class Level implements ChunkManager, Metadatable{
$this->generator = Generator::getGenerator($this->provider->getGenerator()); $this->generator = Generator::getGenerator($this->provider->getGenerator());
$this->folderName = $name; $this->folderName = $name;
$this->updateQueue = new ReversePriorityQueue(); $this->scheduledBlockUpdateQueue = new ReversePriorityQueue();
$this->updateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); $this->scheduledBlockUpdateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
$this->neighbourBlockUpdateQueue = new \SplQueue();
$this->time = (int) $this->provider->getTime(); $this->time = (int) $this->provider->getTime();
$this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4))); $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4)));
@ -662,11 +668,24 @@ class Level implements ChunkManager, Metadatable{
//Do block updates //Do block updates
$this->timings->doTickPending->startTiming(); $this->timings->doTickPending->startTiming();
while($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick){
$block = $this->getBlock($this->updateQueue->extract()["data"]); //Delayed updates
unset($this->updateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]); while($this->scheduledBlockUpdateQueue->count() > 0 and $this->scheduledBlockUpdateQueue->current()["priority"] <= $currentTick){
$block = $this->getBlock($this->scheduledBlockUpdateQueue->extract()["data"]);
unset($this->scheduledBlockUpdateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]);
$block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED);
} }
//Normal updates
while($this->neighbourBlockUpdateQueue->count() > 0){
$index = $this->neighbourBlockUpdateQueue->dequeue();
Level::getBlockXYZ($index, $x, $y, $z);
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($x, $y, $z))));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
}
$this->timings->doTickPending->stopTiming(); $this->timings->doTickPending->stopTiming();
$this->timings->entityTick->startTiming(); $this->timings->entityTick->startTiming();
@ -1017,15 +1036,45 @@ class Level implements ChunkManager, Metadatable{
} }
/** /**
* @deprecated This method will be removed in the future due to misleading/ambiguous name. Use {@link Level#scheduleDelayedBlockUpdate} instead.
*
* @param Vector3 $pos * @param Vector3 $pos
* @param int $delay * @param int $delay
*/ */
public function scheduleUpdate(Vector3 $pos, int $delay){ public function scheduleUpdate(Vector3 $pos, int $delay){
if(isset($this->updateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->updateQueueIndex[$index] <= $delay){ $this->scheduleDelayedBlockUpdate($pos, $delay);
}
/**
* Schedules a block update to be executed after the specified number of ticks.
* Blocks will be updated with the scheduled update type.
*
* @param Vector3 $pos
* @param int $delay
*/
public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay){
if(isset($this->scheduledBlockUpdateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->scheduledBlockUpdateQueueIndex[$index] <= $delay){
return; return;
} }
$this->updateQueueIndex[$index] = $delay; $this->scheduledBlockUpdateQueueIndex[$index] = $delay;
$this->updateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), (int) $delay + $this->server->getTick()); $this->scheduledBlockUpdateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), (int) $delay + $this->server->getTick());
}
/**
* Schedules the blocks around the specified position to be updated at the end of this tick.
* Blocks will be updated with the normal update type.
*
* @param Vector3 $pos
*/
public function scheduleNeighbourBlockUpdates(Vector3 $pos){
$pos = $pos->floor();
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x + 1, $pos->y, $pos->z));
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x - 1, $pos->y, $pos->z));
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y + 1, $pos->z));
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y - 1, $pos->z));
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y, $pos->z + 1));
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y, $pos->z - 1));
} }
/** /**
@ -1439,9 +1488,8 @@ class Level implements ChunkManager, Metadatable{
$entity->scheduleUpdate(); $entity->scheduleUpdate();
} }
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
$this->scheduleNeighbourBlockUpdates($pos);
} }
$this->updateAround($pos);
} }
$this->timings->setBlock->stopTiming(); $this->timings->setBlock->stopTiming();

View File

@ -50,6 +50,8 @@ class Config{
private $correct = false; private $correct = false;
/** @var int */ /** @var int */
private $type = Config::DETECT; private $type = Config::DETECT;
/** @var int */
private $jsonOptions = JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING;
public static $formats = [ public static $formats = [
"properties" => Config::PROPERTIES, "properties" => Config::PROPERTIES,
@ -187,7 +189,7 @@ class Config{
$content = $this->writeProperties(); $content = $this->writeProperties();
break; break;
case Config::JSON: case Config::JSON:
$content = json_encode($this->config, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING); $content = json_encode($this->config, $this->jsonOptions);
break; break;
case Config::YAML: case Config::YAML:
$content = yaml_emit($this->config, YAML_UTF8_ENCODING); $content = yaml_emit($this->config, YAML_UTF8_ENCODING);
@ -219,6 +221,68 @@ class Config{
} }
} }
/**
* Sets the options for the JSON encoding when saving
*
* @param int $options
* @return Config $this
* @throws \RuntimeException if the Config is not in JSON
* @see json_encode
*/
public function setJsonOptions(int $options) : Config{
if($this->type !== Config::JSON){
throw new \RuntimeException("Attempt to set JSON options for non-JSON config");
}
$this->jsonOptions = $options;
return $this;
}
/**
* Enables the given option in addition to the currently set JSON options
*
* @param int $option
* @return Config $this
* @throws \RuntimeException if the Config is not in JSON
* @see json_encode
*/
public function enableJsonOption(int $option) : Config{
if($this->type !== Config::JSON){
throw new \RuntimeException("Attempt to enable JSON option for non-JSON config");
}
$this->jsonOptions |= $option;
return $this;
}
/**
* Disables the given option for the JSON encoding when saving
*
* @param int $option
* @return Config $this
* @throws \RuntimeException if the Config is not in JSON
* @see json_encode
*/
public function disableJsonOption(int $option) : Config{
if($this->type !== Config::JSON){
throw new \RuntimeException("Attempt to disable JSON option for non-JSON config");
}
$this->jsonOptions &= ~$option;
return $this;
}
/**
* Returns the options for the JSON encoding when saving
*
* @return int
* @throws \RuntimeException if the Config is not in JSON
* @see json_encode
*/
public function getJsonOptions() : int{
if($this->type !== Config::JSON){
throw new \RuntimeException("Attempt to get JSON options for non-JSON config");
}
return $this->jsonOptions;
}
/** /**
* @param $k * @param $k
* *