mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 09:19:42 +00:00
Improved world generation manager, UUIDs (some work for future usage)
This commit is contained in:
parent
514ce0fb04
commit
1578fc3ddb
@ -122,6 +122,7 @@ use pocketmine\tile\Sign;
|
|||||||
use pocketmine\tile\Spawnable;
|
use pocketmine\tile\Spawnable;
|
||||||
use pocketmine\tile\Tile;
|
use pocketmine\tile\Tile;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class that handles networking, recovery, and packet sending to the server part
|
* Main class that handles networking, recovery, and packet sending to the server part
|
||||||
@ -175,6 +176,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
public $loginData = [];
|
public $loginData = [];
|
||||||
|
|
||||||
protected $randomClientId;
|
protected $randomClientId;
|
||||||
|
protected $uuid;
|
||||||
|
|
||||||
protected $lastMovement = 0;
|
protected $lastMovement = 0;
|
||||||
/** @var Vector3 */
|
/** @var Vector3 */
|
||||||
@ -235,6 +237,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
return $this->randomClientId;
|
return $this->randomClientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUniqueId(){
|
||||||
|
return $this->uuid;
|
||||||
|
}
|
||||||
|
|
||||||
public function isBanned(){
|
public function isBanned(){
|
||||||
return $this->server->getNameBans()->isBanned(strtolower($this->getName()));
|
return $this->server->getNameBans()->isBanned(strtolower($this->getName()));
|
||||||
}
|
}
|
||||||
@ -461,6 +467,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$this->viewDistance = $this->server->getViewDistance();
|
$this->viewDistance = $this->server->getViewDistance();
|
||||||
$this->newPosition = new Vector3(0, 0, 0);
|
$this->newPosition = new Vector3(0, 0, 0);
|
||||||
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
$this->uuid = Utils::dataToUUID($ip, $port, $clientID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1099,6 +1107,66 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$this->moveToSend[$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch];
|
$this->moveToSend[$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function checkNearEntities($currentTick){
|
||||||
|
foreach($this->level->getNearbyEntities($this->boundingBox->grow(1, 0.5, 1), $this) as $entity){
|
||||||
|
if(($currentTick - $entity->lastUpdate) > 1){
|
||||||
|
$entity->scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($entity instanceof Arrow and $entity->hadCollision){
|
||||||
|
if($entity->dead !== true){
|
||||||
|
$item = Item::get(Item::ARROW, 0, 1);
|
||||||
|
if($this->isSurvival() and !$this->inventory->canAddItem($item)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupArrowEvent($this->inventory, $entity));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = new TakeItemEntityPacket();
|
||||||
|
$pk->eid = $this->getId();
|
||||||
|
$pk->target = $entity->getId();
|
||||||
|
Server::broadcastPacket($entity->getViewers(), $pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING));
|
||||||
|
$this->inventory->addItem(clone $item);
|
||||||
|
$entity->kill();
|
||||||
|
}
|
||||||
|
}elseif($entity instanceof DroppedItem){
|
||||||
|
if($entity->dead !== true and $entity->getPickupDelay() <= 0){
|
||||||
|
$item = $entity->getItem();
|
||||||
|
|
||||||
|
if($item instanceof Item){
|
||||||
|
if($this->isSurvival() and !$this->inventory->canAddItem($item)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupItemEvent($this->inventory, $entity));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($item->getId()){
|
||||||
|
case Item::WOOD:
|
||||||
|
$this->awardAchievement("mineWood");
|
||||||
|
break;
|
||||||
|
case Item::DIAMOND:
|
||||||
|
$this->awardAchievement("diamond");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = new TakeItemEntityPacket();
|
||||||
|
$pk->eid = $this->getId();
|
||||||
|
$pk->target = $entity->getId();
|
||||||
|
Server::broadcastPacket($entity->getViewers(), $pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING));
|
||||||
|
$this->inventory->addItem(clone $item);
|
||||||
|
$entity->kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function processMovement($currentTick){
|
protected function processMovement($currentTick){
|
||||||
if($this->dead or !$this->spawned or !($this->newPosition instanceof Vector3)){
|
if($this->dead or !$this->spawned or !($this->newPosition instanceof Vector3)){
|
||||||
return;
|
return;
|
||||||
@ -1192,6 +1260,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->checkNearEntities($currentTick);
|
||||||
|
|
||||||
$this->speed = $from->subtract($to);
|
$this->speed = $from->subtract($to);
|
||||||
}elseif($distanceSquared == 0){
|
}elseif($distanceSquared == 0){
|
||||||
$this->speed = new Vector3(0, 0, 0);
|
$this->speed = new Vector3(0, 0, 0);
|
||||||
@ -1269,64 +1339,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
|
|
||||||
++$this->inAirTicks;
|
++$this->inAirTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->level->getNearbyEntities($this->boundingBox->grow(1, 0.5, 1), $this) as $entity){
|
|
||||||
if(($currentTick - $entity->lastUpdate) > 1){
|
|
||||||
$entity->scheduleUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($entity instanceof Arrow and $entity->hadCollision){
|
|
||||||
if($entity->dead !== true){
|
|
||||||
$item = Item::get(Item::ARROW, 0, 1);
|
|
||||||
if($this->isSurvival() and !$this->inventory->canAddItem($item)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupArrowEvent($this->inventory, $entity));
|
|
||||||
if($ev->isCancelled()){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new TakeItemEntityPacket();
|
|
||||||
$pk->eid = $this->getId();
|
|
||||||
$pk->target = $entity->getId();
|
|
||||||
Server::broadcastPacket($entity->getViewers(), $pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING));
|
|
||||||
$this->inventory->addItem(clone $item);
|
|
||||||
$entity->kill();
|
|
||||||
}
|
|
||||||
}elseif($entity instanceof DroppedItem){
|
|
||||||
if($entity->dead !== true and $entity->getPickupDelay() <= 0){
|
|
||||||
$item = $entity->getItem();
|
|
||||||
|
|
||||||
if($item instanceof Item){
|
|
||||||
if($this->isSurvival() and !$this->inventory->canAddItem($item)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupItemEvent($this->inventory, $entity));
|
|
||||||
if($ev->isCancelled()){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($item->getId()){
|
|
||||||
case Item::WOOD:
|
|
||||||
$this->awardAchievement("mineWood");
|
|
||||||
break;
|
|
||||||
case Item::DIAMOND:
|
|
||||||
$this->awardAchievement("diamond");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new TakeItemEntityPacket();
|
|
||||||
$pk->eid = $this->getId();
|
|
||||||
$pk->target = $entity->getId();
|
|
||||||
Server::broadcastPacket($entity->getViewers(), $pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING));
|
|
||||||
$this->inventory->addItem(clone $item);
|
|
||||||
$entity->kill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->nextChunkOrderRun-- <= 0 or $this->chunk === null){
|
if($this->nextChunkOrderRun-- <= 0 or $this->chunk === null){
|
||||||
@ -1441,6 +1453,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
|
|
||||||
$this->setSkin($packet->skin, $packet->slim);
|
$this->setSkin($packet->skin, $packet->slim);
|
||||||
|
|
||||||
|
|
||||||
|
$this->uuid = Utils::dataToUUID($this->getClientId(), $this->iusername, $this->getAddress());
|
||||||
|
|
||||||
$this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($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());
|
||||||
@ -2578,8 +2593,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
/**
|
/**
|
||||||
* @param string $message Message to be broadcasted
|
* @param string $message Message to be broadcasted
|
||||||
* @param string $reason Reason showed in console
|
* @param string $reason Reason showed in console
|
||||||
|
* @param bool $notify
|
||||||
*/
|
*/
|
||||||
public function close($message = "", $reason = "generic reason"){
|
public function close($message = "", $reason = "generic reason", $notify = true){
|
||||||
|
|
||||||
foreach($this->tasks as $task){
|
foreach($this->tasks as $task){
|
||||||
$task->cancel();
|
$task->cancel();
|
||||||
@ -2587,7 +2603,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$this->tasks = [];
|
$this->tasks = [];
|
||||||
|
|
||||||
if($this->connected and !$this->closed){
|
if($this->connected and !$this->closed){
|
||||||
if($reason != ""){
|
if($notify and $reason != ""){
|
||||||
$pk = new DisconnectPacket;
|
$pk = new DisconnectPacket;
|
||||||
$pk->message = $reason;
|
$pk->message = $reason;
|
||||||
$this->directDataPacket($pk->setChannel(Network::CHANNEL_PRIORITY));
|
$this->directDataPacket($pk->setChannel(Network::CHANNEL_PRIORITY));
|
||||||
@ -2612,7 +2628,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$this->removeWindow($window);
|
$this->removeWindow($window);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->interface->close($this, $reason);
|
$this->interface->close($this, $notify ? $reason : "");
|
||||||
|
|
||||||
$chunkX = $chunkZ = null;
|
$chunkX = $chunkZ = null;
|
||||||
foreach($this->usedChunks as $index => $d){
|
foreach($this->usedChunks as $index => $d){
|
||||||
|
@ -480,8 +480,13 @@ namespace pocketmine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}elseif(!$thread->isJoined()){
|
}elseif(!$thread->isJoined()){
|
||||||
$logger->debug("Joining " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
if(!$thread->isTerminated()){
|
||||||
$thread->join();
|
$logger->debug("Joining " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
||||||
|
$thread->join();
|
||||||
|
}else{
|
||||||
|
$logger->debug("Killing " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
||||||
|
$thread->kill();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,7 +1602,7 @@ class Server{
|
|||||||
|
|
||||||
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp() === "" ? "*" : $this->getIp(), $this->getPort()]));
|
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp() === "" ? "*" : $this->getIp(), $this->getPort()]));
|
||||||
define("BOOTUP_RANDOM", @Utils::getRandomBytes(16));
|
define("BOOTUP_RANDOM", @Utils::getRandomBytes(16));
|
||||||
$this->serverID = Binary::readLong(substr(Utils::getUniqueID(true, $this->getIp() . $this->getPort()), 0, 8));
|
$this->serverID = Utils::getServerUniqueId($this->getIp() . $this->getPort());
|
||||||
|
|
||||||
$this->network = new Network($this);
|
$this->network = new Network($this);
|
||||||
$this->network->setName($this->getMotd());
|
$this->network->setName($this->getMotd());
|
||||||
@ -2234,7 +2234,7 @@ class Server{
|
|||||||
|
|
||||||
$version = new VersionString();
|
$version = new VersionString();
|
||||||
$this->lastSendUsage = new SendUsageTask("https://stats.pocketmine.net/usage.php", [
|
$this->lastSendUsage = new SendUsageTask("https://stats.pocketmine.net/usage.php", [
|
||||||
"serverid" => $this->serverID,
|
"serverid" => Binary::readLong(substr(hex2bin(str_replace("-", "", $this->serverID)), 0, 8)),
|
||||||
"port" => $this->getPort(),
|
"port" => $this->getPort(),
|
||||||
"os" => Utils::getOS(),
|
"os" => Utils::getOS(),
|
||||||
"name" => $this->getName(),
|
"name" => $this->getName(),
|
||||||
|
@ -68,6 +68,8 @@ use pocketmine\level\format\generic\EmptyChunkSection;
|
|||||||
use pocketmine\level\format\LevelProvider;
|
use pocketmine\level\format\LevelProvider;
|
||||||
use pocketmine\level\generator\GenerationTask;
|
use pocketmine\level\generator\GenerationTask;
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
|
use pocketmine\level\generator\GeneratorRegisterTask;
|
||||||
|
use pocketmine\level\generator\GeneratorUnregisterTask;
|
||||||
use pocketmine\level\generator\PopulationTask;
|
use pocketmine\level\generator\PopulationTask;
|
||||||
use pocketmine\math\AxisAlignedBB;
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\math\Math;
|
use pocketmine\math\Math;
|
||||||
@ -341,6 +343,22 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$generator = $this->generator;
|
$generator = $this->generator;
|
||||||
$this->generatorInstance = new $generator($this->provider->getGeneratorOptions());
|
$this->generatorInstance = new $generator($this->provider->getGeneratorOptions());
|
||||||
$this->generatorInstance->init($this, new Random($this->getSeed()));
|
$this->generatorInstance->init($this, new Random($this->getSeed()));
|
||||||
|
|
||||||
|
$this->registerGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerGenerator(){
|
||||||
|
$size = $this->server->getScheduler()->getAsyncTaskPoolSize();
|
||||||
|
for($i = 0; $i < $size; ++$i){
|
||||||
|
$this->server->getScheduler()->scheduleAsyncTaskToWorker(new GeneratorRegisterTask($this, $this->generatorInstance), $i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unregisterGenerator(){
|
||||||
|
$size = $this->server->getScheduler()->getAsyncTaskPoolSize();
|
||||||
|
for($i = 0; $i < $size; ++$i){
|
||||||
|
$this->server->getScheduler()->scheduleAsyncTaskToWorker(new GeneratorUnregisterTask($this, $this->generatorInstance), $i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -383,6 +401,8 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->unloadChunk($chunk->getX(), $chunk->getZ(), false);
|
$this->unloadChunk($chunk->getX(), $chunk->getZ(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->unregisterGenerator();
|
||||||
|
|
||||||
$this->provider->close();
|
$this->provider->close();
|
||||||
$this->provider = null;
|
$this->provider = null;
|
||||||
$this->blockMetadata = null;
|
$this->blockMetadata = null;
|
||||||
@ -2378,7 +2398,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true;
|
$this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$task = new PopulationTask($this, $this->generatorInstance, $this->getChunk($x, $z, true));
|
$task = new PopulationTask($this, $this->getChunk($x, $z, true));
|
||||||
$this->server->getScheduler()->scheduleAsyncTask($task);
|
$this->server->getScheduler()->scheduleAsyncTask($task);
|
||||||
}
|
}
|
||||||
Timings::$generationTimer->stopTiming();
|
Timings::$generationTimer->stopTiming();
|
||||||
@ -2400,7 +2420,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
if(!isset($this->chunkGenerationQueue[$index = Level::chunkHash($x, $z)])){
|
if(!isset($this->chunkGenerationQueue[$index = Level::chunkHash($x, $z)])){
|
||||||
Timings::$generationTimer->startTiming();
|
Timings::$generationTimer->startTiming();
|
||||||
$this->chunkGenerationQueue[$index] = true;
|
$this->chunkGenerationQueue[$index] = true;
|
||||||
$task = new GenerationTask($this, $this->generatorInstance, $this->getChunk($x, $z, true));
|
$task = new GenerationTask($this, $this->getChunk($x, $z, true));
|
||||||
$this->server->getScheduler()->scheduleAsyncTask($task);
|
$this->server->getScheduler()->scheduleAsyncTask($task);
|
||||||
Timings::$generationTimer->stopTiming();
|
Timings::$generationTimer->stopTiming();
|
||||||
}
|
}
|
||||||
|
@ -32,17 +32,13 @@ use pocketmine\utils\Random;
|
|||||||
|
|
||||||
class GenerationTask extends AsyncTask{
|
class GenerationTask extends AsyncTask{
|
||||||
|
|
||||||
public $generator;
|
public $state;
|
||||||
public $settings;
|
|
||||||
public $seed;
|
|
||||||
public $levelId;
|
public $levelId;
|
||||||
public $chunk;
|
public $chunk;
|
||||||
public $chunkClass;
|
public $chunkClass;
|
||||||
|
|
||||||
public function __construct(Level $level, Generator $generator, FullChunk $chunk){
|
public function __construct(Level $level, FullChunk $chunk){
|
||||||
$this->generator = get_class($generator);
|
$this->state = true;
|
||||||
$this->settings = $generator->getSettings();
|
|
||||||
$this->seed = $level->getSeed();
|
|
||||||
$this->levelId = $level->getId();
|
$this->levelId = $level->getId();
|
||||||
$this->chunk = $chunk->toFastBinary();
|
$this->chunk = $chunk->toFastBinary();
|
||||||
$this->chunkClass = get_class($chunk);
|
$this->chunkClass = get_class($chunk);
|
||||||
@ -50,19 +46,12 @@ class GenerationTask extends AsyncTask{
|
|||||||
|
|
||||||
public function onRun(){
|
public function onRun(){
|
||||||
/** @var SimpleChunkManager $manager */
|
/** @var SimpleChunkManager $manager */
|
||||||
$manager = $this->getFromThreadStore($key = "generation.level{$this->levelId}.manager");
|
$manager = $this->getFromThreadStore("generation.level{$this->levelId}.manager");
|
||||||
/** @var Generator $generator */
|
/** @var Generator $generator */
|
||||||
$generator = $this->getFromThreadStore($gKey = "generation.level{$this->levelId}.generator");
|
$generator = $this->getFromThreadStore("generation.level{$this->levelId}.generator");
|
||||||
if($manager === null or $generator === null){
|
if($manager === null or $generator === null){
|
||||||
Block::init();
|
$this->state = false;
|
||||||
Biome::init();
|
return;
|
||||||
$manager = new SimpleChunkManager($this->seed);
|
|
||||||
$this->saveToThreadStore($key, $manager);
|
|
||||||
/** @var Generator $generator */
|
|
||||||
$generator = $this->generator;
|
|
||||||
$generator = new $generator($this->settings);
|
|
||||||
$generator->init($manager, new Random($manager->getSeed()));
|
|
||||||
$this->saveToThreadStore($gKey, $generator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var FullChunk $chunk */
|
/** @var FullChunk $chunk */
|
||||||
@ -87,6 +76,10 @@ class GenerationTask extends AsyncTask{
|
|||||||
public function onCompletion(Server $server){
|
public function onCompletion(Server $server){
|
||||||
$level = $server->getLevel($this->levelId);
|
$level = $server->getLevel($this->levelId);
|
||||||
if($level !== null){
|
if($level !== null){
|
||||||
|
if($this->state === false){
|
||||||
|
$level->registerGenerator();
|
||||||
|
return;
|
||||||
|
}
|
||||||
/** @var FullChunk $chunk */
|
/** @var FullChunk $chunk */
|
||||||
$chunk = $this->chunkClass;
|
$chunk = $this->chunkClass;
|
||||||
$chunk = $chunk::fromFastBinary($this->chunk, $level->getProvider());
|
$chunk = $chunk::fromFastBinary($this->chunk, $level->getProvider());
|
||||||
|
58
src/pocketmine/level/generator/GeneratorRegisterTask.php
Normal file
58
src/pocketmine/level/generator/GeneratorRegisterTask.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?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\level\generator;
|
||||||
|
|
||||||
|
use pocketmine\block\Block;
|
||||||
|
use pocketmine\level\format\FullChunk;
|
||||||
|
use pocketmine\level\generator\biome\Biome;
|
||||||
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\level\SimpleChunkManager;
|
||||||
|
use pocketmine\scheduler\AsyncTask;
|
||||||
|
use pocketmine\Server;
|
||||||
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
|
class GeneratorRegisterTask extends AsyncTask{
|
||||||
|
|
||||||
|
public $generator;
|
||||||
|
public $settings;
|
||||||
|
public $seed;
|
||||||
|
public $levelId;
|
||||||
|
|
||||||
|
public function __construct(Level $level, Generator $generator){
|
||||||
|
$this->generator = get_class($generator);
|
||||||
|
$this->settings = $generator->getSettings();
|
||||||
|
$this->seed = $level->getSeed();
|
||||||
|
$this->levelId = $level->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onRun(){
|
||||||
|
Block::init();
|
||||||
|
Biome::init();
|
||||||
|
$manager = new SimpleChunkManager($this->seed);
|
||||||
|
$this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager);
|
||||||
|
/** @var Generator $generator */
|
||||||
|
$generator = $this->generator;
|
||||||
|
$generator = new $generator($this->settings);
|
||||||
|
$generator->init($manager, new Random($manager->getSeed()));
|
||||||
|
$this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator);
|
||||||
|
}
|
||||||
|
}
|
45
src/pocketmine/level/generator/GeneratorUnregisterTask.php
Normal file
45
src/pocketmine/level/generator/GeneratorUnregisterTask.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?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\level\generator;
|
||||||
|
|
||||||
|
use pocketmine\block\Block;
|
||||||
|
use pocketmine\level\format\FullChunk;
|
||||||
|
use pocketmine\level\generator\biome\Biome;
|
||||||
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\level\SimpleChunkManager;
|
||||||
|
use pocketmine\scheduler\AsyncTask;
|
||||||
|
use pocketmine\Server;
|
||||||
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
|
class GeneratorUnregisterTask extends AsyncTask{
|
||||||
|
|
||||||
|
public $levelId;
|
||||||
|
|
||||||
|
public function __construct(Level $level){
|
||||||
|
$this->levelId = $level->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onRun(){
|
||||||
|
$this->saveToThreadStore("generation.level{$this->levelId}.manager", null);
|
||||||
|
$this->saveToThreadStore("generation.level{$this->levelId}.generator", null);
|
||||||
|
}
|
||||||
|
}
|
@ -32,9 +32,8 @@ use pocketmine\utils\Random;
|
|||||||
|
|
||||||
class PopulationTask extends AsyncTask{
|
class PopulationTask extends AsyncTask{
|
||||||
|
|
||||||
public $generator;
|
|
||||||
public $settings;
|
public $state;
|
||||||
public $seed;
|
|
||||||
public $levelId;
|
public $levelId;
|
||||||
public $chunk;
|
public $chunk;
|
||||||
public $chunkClass;
|
public $chunkClass;
|
||||||
@ -49,10 +48,8 @@ class PopulationTask extends AsyncTask{
|
|||||||
public $chunk21;
|
public $chunk21;
|
||||||
public $chunk22;
|
public $chunk22;
|
||||||
|
|
||||||
public function __construct(Level $level, Generator $generator, FullChunk $chunk){
|
public function __construct(Level $level, FullChunk $chunk){
|
||||||
$this->generator = get_class($generator);
|
$this->state = true;
|
||||||
$this->settings = $generator->getSettings();
|
|
||||||
$this->seed = $level->getSeed();
|
|
||||||
$this->levelId = $level->getId();
|
$this->levelId = $level->getId();
|
||||||
$this->chunk = $chunk->toFastBinary();
|
$this->chunk = $chunk->toFastBinary();
|
||||||
$this->chunkClass = get_class($chunk);
|
$this->chunkClass = get_class($chunk);
|
||||||
@ -70,19 +67,12 @@ class PopulationTask extends AsyncTask{
|
|||||||
|
|
||||||
public function onRun(){
|
public function onRun(){
|
||||||
/** @var SimpleChunkManager $manager */
|
/** @var SimpleChunkManager $manager */
|
||||||
$manager = $this->getFromThreadStore($key = "generation.level{$this->levelId}.manager");
|
$manager = $this->getFromThreadStore("generation.level{$this->levelId}.manager");
|
||||||
/** @var Generator $generator */
|
/** @var Generator $generator */
|
||||||
$generator = $this->getFromThreadStore($gKey = "generation.level{$this->levelId}.generator");
|
$generator = $this->getFromThreadStore("generation.level{$this->levelId}.generator");
|
||||||
if($manager === null or $generator === null){
|
if($manager === null or $generator === null){
|
||||||
Block::init();
|
$this->state = false;
|
||||||
Biome::init();
|
return;
|
||||||
$manager = new SimpleChunkManager($this->seed);
|
|
||||||
$this->saveToThreadStore($key, $manager);
|
|
||||||
/** @var Generator $generator */
|
|
||||||
$generator = $this->generator;
|
|
||||||
$generator = new $generator($this->settings);
|
|
||||||
$generator->init($manager, new Random($manager->getSeed()));
|
|
||||||
$this->saveToThreadStore($gKey, $generator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var FullChunk[] $chunks */
|
/** @var FullChunk[] $chunks */
|
||||||
@ -149,6 +139,10 @@ class PopulationTask extends AsyncTask{
|
|||||||
public function onCompletion(Server $server){
|
public function onCompletion(Server $server){
|
||||||
$level = $server->getLevel($this->levelId);
|
$level = $server->getLevel($this->levelId);
|
||||||
if($level !== null){
|
if($level !== null){
|
||||||
|
if($this->state === false){
|
||||||
|
$level->registerGenerator();
|
||||||
|
return;
|
||||||
|
}
|
||||||
/** @var FullChunk[] $chunks */
|
/** @var FullChunk[] $chunks */
|
||||||
$chunks = [];
|
$chunks = [];
|
||||||
/** @var FullChunk $chunkC */
|
/** @var FullChunk $chunkC */
|
||||||
|
@ -48,18 +48,36 @@ class Utils{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function randomUUID(){
|
||||||
|
return Utils::toUUID(Binary::writeInt(time()) . Binary::writeShort(getmypid()) . Binary::writeShort(getmyuid()) . Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)) . Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dataToUUID(...$params){
|
||||||
|
return Utils::toUUID(hash("md5", implode($params), true), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function toUUID($data, $version = 2, $fixed = "8"){
|
||||||
|
if(strlen($data) !== 16){
|
||||||
|
throw new \InvalidArgumentException("Data bust be 16 bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
$hex = bin2hex($data);
|
||||||
|
|
||||||
|
//xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 8-4-4-12
|
||||||
|
return substr($hex, 0, 8) . "-" . substr($hex, 8, 4) . "-" . hexdec($version) . substr($hex, 13, 3) . "-" . $fixed{0} . substr($hex, 17, 3) . "-" . substr($hex, 20, 12);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this machine / server instance unique ID
|
* Gets this machine / server instance unique ID
|
||||||
* Returns a hash, the first 32 characters (or 16 if raw)
|
* Returns a hash, the first 32 characters (or 16 if raw)
|
||||||
* will be an identifier that won't change frequently.
|
* will be an identifier that won't change frequently.
|
||||||
* The rest of the hash will change depending on other factors.
|
* The rest of the hash will change depending on other factors.
|
||||||
*
|
*
|
||||||
* @param bool $raw default false, if true, returns the raw identifier, not hexadecimal
|
|
||||||
* @param string $extra optional, additional data to identify the machine
|
* @param string $extra optional, additional data to identify the machine
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getUniqueID($raw = false, $extra = ""){
|
public static function getServerUniqueId($extra = ""){
|
||||||
$machine = php_uname("a");
|
$machine = php_uname("a");
|
||||||
$machine .= file_exists("/proc/cpuinfo") ? implode(preg_grep("/model name/", file("/proc/cpuinfo"))) : "";
|
$machine .= file_exists("/proc/cpuinfo") ? implode(preg_grep("/model name/", file("/proc/cpuinfo"))) : "";
|
||||||
$machine .= sys_get_temp_dir();
|
$machine .= sys_get_temp_dir();
|
||||||
@ -96,7 +114,7 @@ class Utils{
|
|||||||
$data .= $ext . ":" . phpversion($ext);
|
$data .= $ext . ":" . phpversion($ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash("md5", $machine, $raw) . hash("sha512", $data, $raw);
|
return Utils::dataToUUID($machine, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user