mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-30 15:19:56 +00:00
Working Threaded Generation
This commit is contained in:
parent
392eb74901
commit
fa50cbf4b3
@ -519,16 +519,16 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
unset($this->chunksLoaded[$index]);
|
unset($this->chunksLoaded[$index]);
|
||||||
}
|
}
|
||||||
}else{*/
|
}else{*/
|
||||||
foreach($this->getLevel()->getChunkEntities($this->lastChunk[0], $this->lastChunk[1]) as $entity){
|
foreach($this->getLevel()->getChunkEntities($this->lastChunk[0], $this->lastChunk[1]) as $entity){
|
||||||
if($entity !== $this){
|
if($entity !== $this){
|
||||||
$entity->spawnTo($this);
|
$entity->spawnTo($this);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foreach($this->getLevel()->getChunkTiles($this->lastChunk[0], $this->lastChunk[1]) as $tile){
|
}
|
||||||
if($tile instanceof Spawnable){
|
foreach($this->getLevel()->getChunkTiles($this->lastChunk[0], $this->lastChunk[1]) as $tile){
|
||||||
$tile->spawnTo($this);
|
if($tile instanceof Spawnable){
|
||||||
}
|
$tile->spawnTo($this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//}
|
//}
|
||||||
$this->lastChunk = false;
|
$this->lastChunk = false;
|
||||||
}
|
}
|
||||||
@ -696,6 +696,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
|
|
||||||
if($needACK and $identifier !== null){
|
if($needACK and $identifier !== null){
|
||||||
$this->needACK[$identifier] = false;
|
$this->needACK[$identifier] = false;
|
||||||
|
|
||||||
return $identifier;
|
return $identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,6 +722,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
|
|
||||||
if($needACK and $identifier !== null){
|
if($needACK and $identifier !== null){
|
||||||
$this->needACK[$identifier] = false;
|
$this->needACK[$identifier] = false;
|
||||||
|
|
||||||
return $identifier;
|
return $identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,6 +972,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
return $i;
|
return $i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,6 +1160,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$this->server->getPluginManager()->callEvent($ev = new PlayerLoginEvent($this, "Plugin reason"));
|
$this->server->getPluginManager()->callEvent($ev = new PlayerLoginEvent($this, "Plugin reason"));
|
||||||
if($ev->isCancelled()){
|
if($ev->isCancelled()){
|
||||||
$this->close($ev->getKickMessage(), "Plugin reason");
|
$this->close($ev->getKickMessage(), "Plugin reason");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace pocketmine {
|
namespace pocketmine {
|
||||||
|
use LogLevel;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use \LogLevel;
|
|
||||||
use pocketmine\utils\MainLogger;
|
use pocketmine\utils\MainLogger;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
use pocketmine\wizard\Installer;
|
use pocketmine\wizard\Installer;
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
namespace pocketmine;
|
namespace pocketmine;
|
||||||
|
|
||||||
use pocketmine\block\Block;
|
use pocketmine\block\Block;
|
||||||
use pocketmine\block\Chest;
|
|
||||||
use pocketmine\block\Furnace;
|
|
||||||
use pocketmine\command\CommandReader;
|
use pocketmine\command\CommandReader;
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\command\ConsoleCommandSender;
|
use pocketmine\command\ConsoleCommandSender;
|
||||||
@ -40,10 +38,9 @@ use pocketmine\inventory\CraftingManager;
|
|||||||
use pocketmine\inventory\InventoryType;
|
use pocketmine\inventory\InventoryType;
|
||||||
use pocketmine\inventory\Recipe;
|
use pocketmine\inventory\Recipe;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
use pocketmine\level\format\LevelProviderManager;
|
||||||
use pocketmine\level\generator\Flat;
|
use pocketmine\level\generator\GenerationRequestManager;
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\level\generator\Normal;
|
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\level\LevelImport;
|
use pocketmine\level\LevelImport;
|
||||||
use pocketmine\level\WorldGenerator;
|
use pocketmine\level\WorldGenerator;
|
||||||
@ -61,10 +58,11 @@ use pocketmine\nbt\tag\Long;
|
|||||||
use pocketmine\nbt\tag\Short;
|
use pocketmine\nbt\tag\Short;
|
||||||
use pocketmine\nbt\tag\String;
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\network\protocol\DataPacket;
|
use pocketmine\network\protocol\DataPacket;
|
||||||
|
use pocketmine\network\protocol\Info;
|
||||||
use pocketmine\network\query\QueryHandler;
|
use pocketmine\network\query\QueryHandler;
|
||||||
use pocketmine\network\query\QueryPacket;
|
|
||||||
use pocketmine\network\RakLibInterface;
|
use pocketmine\network\RakLibInterface;
|
||||||
use pocketmine\network\rcon\RCON;
|
use pocketmine\network\rcon\RCON;
|
||||||
|
use pocketmine\network\SourceInterface;
|
||||||
use pocketmine\network\upnp\UPnP;
|
use pocketmine\network\upnp\UPnP;
|
||||||
use pocketmine\permission\BanList;
|
use pocketmine\permission\BanList;
|
||||||
use pocketmine\permission\DefaultPermissions;
|
use pocketmine\permission\DefaultPermissions;
|
||||||
@ -75,7 +73,6 @@ use pocketmine\scheduler\CallbackTask;
|
|||||||
use pocketmine\scheduler\SendUsageTask;
|
use pocketmine\scheduler\SendUsageTask;
|
||||||
use pocketmine\scheduler\ServerScheduler;
|
use pocketmine\scheduler\ServerScheduler;
|
||||||
use pocketmine\scheduler\TickScheduler;
|
use pocketmine\scheduler\TickScheduler;
|
||||||
use pocketmine\tile\Sign;
|
|
||||||
use pocketmine\tile\Tile;
|
use pocketmine\tile\Tile;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Config;
|
use pocketmine\utils\Config;
|
||||||
@ -83,7 +80,6 @@ use pocketmine\utils\MainLogger;
|
|||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
use pocketmine\utils\VersionString;
|
use pocketmine\utils\VersionString;
|
||||||
use pocketmine\network\SourceInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class that manages everything
|
* The class that manages everything
|
||||||
@ -116,6 +112,9 @@ class Server{
|
|||||||
/** @var ServerScheduler */
|
/** @var ServerScheduler */
|
||||||
private $scheduler = null;
|
private $scheduler = null;
|
||||||
|
|
||||||
|
/** @var GenerationRequestManager */
|
||||||
|
private $generationManager = null;
|
||||||
|
|
||||||
/** @var TickScheduler */
|
/** @var TickScheduler */
|
||||||
private $tickScheduler = null;
|
private $tickScheduler = null;
|
||||||
|
|
||||||
@ -493,6 +492,13 @@ class Server{
|
|||||||
return $this->scheduler;
|
return $this->scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return GenerationRequestManager
|
||||||
|
*/
|
||||||
|
public function getGenerationManager(){
|
||||||
|
return $this->generationManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@ -781,17 +787,32 @@ class Server{
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isLevelLoaded($name){
|
public function isLevelLoaded($name){
|
||||||
return isset($this->levels[$name]);
|
return $this->getLevelByName($name) instanceof Level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param int $levelId
|
||||||
*
|
*
|
||||||
* @return Level
|
* @return Level
|
||||||
*/
|
*/
|
||||||
public function getLevel($name){
|
public function getLevel($levelId){
|
||||||
if(isset($this->levels[$name])){
|
if(isset($this->levels[$levelId])){
|
||||||
return $this->levels[$name];
|
return $this->levels[$levelId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
*
|
||||||
|
* @return Level
|
||||||
|
*/
|
||||||
|
public function getLevelByName($name){
|
||||||
|
foreach($this->getLevels() as $level){
|
||||||
|
if($level->getName() === $name){
|
||||||
|
return $level;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -802,8 +823,8 @@ class Server{
|
|||||||
* @param bool $forceUnload
|
* @param bool $forceUnload
|
||||||
*/
|
*/
|
||||||
public function unloadLevel(Level $level, $forceUnload = false){
|
public function unloadLevel(Level $level, $forceUnload = false){
|
||||||
if((!$level->isLoaded() or $level->unload($forceUnload) === true) and $this->isLevelLoaded($level->getName())){
|
if($level->unload($forceUnload) === true and $this->isLevelLoaded($level->getName())){
|
||||||
unset($this->levels[$level->getName()]);
|
unset($this->levels[$level->getID()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,20 +850,20 @@ class Server{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||||
$this->logger->info("Preparing level \"" . $name . "\"");
|
|
||||||
$level = new LevelFormat($path . "level.pmf");
|
$provider = LevelProviderManager::getProvider($path);
|
||||||
if(!$level->isLoaded){
|
if($provider === null){
|
||||||
$this->logger->error("Could not load level \"" . $name . "\"");
|
$this->logger->error("Could not load level \"" . $name . "\"");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//$entities = new Config($path."entities.yml", Config::YAML);
|
//$entities = new Config($path."entities.yml", Config::YAML);
|
||||||
if(file_exists($path . "tileEntities.yml")){
|
//if(file_exists($path . "tileEntities.yml")){
|
||||||
@rename($path . "tileEntities.yml", $path . "tiles.yml");
|
// @rename($path . "tileEntities.yml", $path . "tiles.yml");
|
||||||
}
|
//}
|
||||||
|
|
||||||
$level = new Level($this, $level, $name);
|
$level = new Level($this, $path, $provider);
|
||||||
$this->levels[$level->getName()] = $level;
|
$this->levels[$level->getID()] = $level;
|
||||||
/*foreach($entities->getAll() as $entity){
|
/*foreach($entities->getAll() as $entity){
|
||||||
if(!isset($entity["id"])){
|
if(!isset($entity["id"])){
|
||||||
break;
|
break;
|
||||||
@ -872,7 +893,7 @@ class Server{
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if(file_exists($path . "tiles.yml")){
|
/*if(file_exists($path . "tiles.yml")){
|
||||||
$tiles = new Config($path . "tiles.yml", Config::YAML);
|
$tiles = new Config($path . "tiles.yml", Config::YAML);
|
||||||
foreach($tiles->getAll() as $tile){
|
foreach($tiles->getAll() as $tile){
|
||||||
if(!isset($tile["id"])){
|
if(!isset($tile["id"])){
|
||||||
@ -934,7 +955,7 @@ class Server{
|
|||||||
}
|
}
|
||||||
unlink($path . "tiles.yml");
|
unlink($path . "tiles.yml");
|
||||||
$level->save(true, true);
|
$level->save(true, true);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -954,20 +975,32 @@ class Server{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$seed = $seed === null ? Binary::readInt(Utils::getRandomBytes(4, false)) : (int) $seed;
|
||||||
|
|
||||||
if($generator !== null and class_exists($generator) and is_subclass_of($generator, "pocketmine\\level\\generator\\Generator")){
|
if($generator !== null and class_exists($generator) and is_subclass_of($generator, "pocketmine\\level\\generator\\Generator")){
|
||||||
$generator = new $generator($options);
|
$generator = new $generator($options);
|
||||||
}else{
|
}else{
|
||||||
if(strtoupper($this->getLevelType()) == "FLAT"){
|
if(strtoupper($this->getLevelType()) == "FLAT"){
|
||||||
$generator = new Flat($options);
|
$generator = Generator::getGenerator("flat");
|
||||||
$options["preset"] = $this->getConfigString("generator-settings", "");
|
$options["preset"] = $this->getConfigString("generator-settings", "");
|
||||||
}else{
|
}else{
|
||||||
$generator = new Normal($options);
|
$generator = Generator::getGenerator("normal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$gen = new WorldGenerator($this, $generator, $name, $seed === null ? Binary::readInt(Utils::getRandomBytes(4, false)) : (int) $seed);
|
$provider = "pocketmine\\level\\format\\anvil\\Anvil";
|
||||||
$gen->generate();
|
|
||||||
$gen->close();
|
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||||
|
/** @var \pocketmine\level\format\LevelProvider $provider */
|
||||||
|
$provider::generate($path, $name, $seed, $generator, $options);
|
||||||
|
|
||||||
|
$level = new Level($this, $path, $provider);
|
||||||
|
$this->levels[$level->getID()] = $level;
|
||||||
|
for($Z = 6; $Z <= 10; ++$Z){
|
||||||
|
for($X = 6; $X <= 10; ++$X){
|
||||||
|
$level->generateChunk($X, $Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -982,7 +1015,7 @@ class Server{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||||
if(!($this->getLevel($name) instanceof Level) and !file_exists($path . "level.pmf")){
|
if(!($this->getLevelByName($name) instanceof Level) and !file_exists($path . "level.pmf")){
|
||||||
if(file_exists($path)){
|
if(file_exists($path)){
|
||||||
$level = new LevelImport($path);
|
$level = new LevelImport($path);
|
||||||
if($level->import() === false){ //Try importing a world
|
if($level->import() === false){ //Try importing a world
|
||||||
@ -1318,6 +1351,10 @@ class Server{
|
|||||||
|
|
||||||
$this->enablePlugins(PluginLoadOrder::STARTUP);
|
$this->enablePlugins(PluginLoadOrder::STARTUP);
|
||||||
|
|
||||||
|
$this->generationManager = new GenerationRequestManager($this);
|
||||||
|
|
||||||
|
LevelProviderManager::addProvider($this, "pocketmine\\level\\format\\anvil\\Anvil");
|
||||||
|
|
||||||
|
|
||||||
Generator::addGenerator("pocketmine\\level\\generator\\Flat", "flat");
|
Generator::addGenerator("pocketmine\\level\\generator\\Flat", "flat");
|
||||||
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "normal");
|
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "normal");
|
||||||
@ -1333,10 +1370,9 @@ class Server{
|
|||||||
if($this->loadLevel($default) === false){
|
if($this->loadLevel($default) === false){
|
||||||
$seed = $this->getConfigInt("level-seed", time());
|
$seed = $this->getConfigInt("level-seed", time());
|
||||||
$this->generateLevel($default, $seed === 0 ? time() : $seed);
|
$this->generateLevel($default, $seed === 0 ? time() : $seed);
|
||||||
$this->loadLevel($default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setDefaultLevel($this->getLevel($default));
|
$this->setDefaultLevel($this->getLevelByName($default));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1564,6 +1600,7 @@ class Server{
|
|||||||
foreach($this->getLevels() as $level){
|
foreach($this->getLevels() as $level){
|
||||||
$this->unloadLevel($level, true);
|
$this->unloadLevel($level, true);
|
||||||
}
|
}
|
||||||
|
$this->generationManager->shutdown();
|
||||||
|
|
||||||
HandlerList::unregisterAll();
|
HandlerList::unregisterAll();
|
||||||
$this->scheduler->cancelAllTasks();
|
$this->scheduler->cancelAllTasks();
|
||||||
@ -1629,6 +1666,7 @@ class Server{
|
|||||||
$lastLoop = 0;
|
$lastLoop = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->generationManager->handlePackets();
|
||||||
|
|
||||||
if(($ticks = $this->tick()) !== true){
|
if(($ticks = $this->tick()) !== true){
|
||||||
++$lastLoop;
|
++$lastLoop;
|
||||||
@ -1717,7 +1755,7 @@ class Server{
|
|||||||
$dump .= "server.properties: " . var_export($p, true) . "\r\n\r\n\r\n";
|
$dump .= "server.properties: " . var_export($p, true) . "\r\n\r\n\r\n";
|
||||||
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
||||||
$dump .= "Loaded plugins:\r\n";
|
$dump .= "Loaded plugins:\r\n";
|
||||||
foreach(PluginManager::getPlugins() as $p){
|
foreach($this->getPluginManager()->getPlugins() as $p){
|
||||||
$d = $p->getDescription();
|
$d = $p->getDescription();
|
||||||
$dump .= $d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . "\r\n";
|
$dump .= $d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . "\r\n";
|
||||||
}
|
}
|
||||||
@ -1751,6 +1789,7 @@ class Server{
|
|||||||
$lastLoop = 0;
|
$lastLoop = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->generationManager->handlePackets();
|
||||||
|
|
||||||
if(($ticks = $this->tick()) !== true){
|
if(($ticks = $this->tick()) !== true){
|
||||||
++$lastLoop;
|
++$lastLoop;
|
||||||
|
@ -43,12 +43,12 @@ use pocketmine\nbt\tag\Byte;
|
|||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Float;
|
use pocketmine\nbt\tag\Float;
|
||||||
use pocketmine\nbt\tag\Short;
|
use pocketmine\nbt\tag\Short;
|
||||||
|
use pocketmine\Network;
|
||||||
use pocketmine\network\protocol\MoveEntityPacket_PosRot;
|
use pocketmine\network\protocol\MoveEntityPacket_PosRot;
|
||||||
use pocketmine\network\protocol\MovePlayerPacket;
|
use pocketmine\network\protocol\MovePlayerPacket;
|
||||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||||
use pocketmine\network\protocol\SetTimePacket;
|
use pocketmine\network\protocol\SetTimePacket;
|
||||||
use pocketmine\Network;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\plugin\Plugin;
|
use pocketmine\plugin\Plugin;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
@ -29,10 +29,10 @@ 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\Network;
|
||||||
use pocketmine\network\protocol\AddPlayerPacket;
|
use pocketmine\network\protocol\AddPlayerPacket;
|
||||||
use pocketmine\network\protocol\RemovePlayerPacket;
|
use pocketmine\network\protocol\RemovePlayerPacket;
|
||||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||||
use pocketmine\Network;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Human extends Creature implements ProjectileSource, InventoryHolder{
|
class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||||
|
@ -25,7 +25,6 @@ use pocketmine\entity\Entity;
|
|||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
use pocketmine\Event;
|
use pocketmine\Event;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
|
|
||||||
class EntityTeleportEvent extends EntityEvent implements Cancellable{
|
class EntityTeleportEvent extends EntityEvent implements Cancellable{
|
||||||
public static $handlerList = null;
|
public static $handlerList = null;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\event\player;
|
namespace pocketmine\event\player;
|
||||||
|
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
use pocketmine\item\Item;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\event\player;
|
namespace pocketmine\event\player;
|
||||||
|
|
||||||
use pocketmine\event\Cancellable;
|
|
||||||
use pocketmine\Event;
|
use pocketmine\Event;
|
||||||
|
use pocketmine\event\Cancellable;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\event\server;
|
namespace pocketmine\event\server;
|
||||||
|
|
||||||
use pocketmine\event;
|
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
|
use pocketmine\event;
|
||||||
use pocketmine\network\protocol\DataPacket;
|
use pocketmine\network\protocol\DataPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\event\server;
|
namespace pocketmine\event\server;
|
||||||
|
|
||||||
use pocketmine\event;
|
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
|
use pocketmine\event;
|
||||||
use pocketmine\network\protocol\DataPacket;
|
use pocketmine\network\protocol\DataPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ class Painting extends Item{
|
|||||||
|
|
||||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||||
if($target->isTransparent === false and $face > 1 and $block->isSolid === false){
|
if($target->isTransparent === false and $face > 1 and $block->isSolid === false){
|
||||||
$server = Server::getInstance();
|
|
||||||
$faces = array(
|
$faces = array(
|
||||||
2 => 1,
|
2 => 1,
|
||||||
3 => 3,
|
3 => 3,
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,77 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* ____ _ _ __ __ _ __ __ ____
|
|
||||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
|
||||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
|
||||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
|
||||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* @author PocketMine Team
|
|
||||||
* @link http://www.pocketmine.net/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace pocketmine\level;
|
|
||||||
|
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\level\generator\Generator;
|
|
||||||
use pocketmine\Server;
|
|
||||||
use pocketmine\utils\Binary;
|
|
||||||
use pocketmine\utils\Random;
|
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class WorldGenerator{
|
|
||||||
private $seed, $level, $path, $random, $generator, $server;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Server $server
|
|
||||||
* @param Generator $generator
|
|
||||||
* @param string $name
|
|
||||||
* @param int $seed
|
|
||||||
*/
|
|
||||||
public function __construct(Server $server, Generator $generator, $name, $seed = null){
|
|
||||||
$this->seed = $seed !== null ? (int) $seed : Binary::readInt(Utils::getRandomBytes(4, false));
|
|
||||||
$this->random = new Random($this->seed);
|
|
||||||
$this->server = $server;
|
|
||||||
$this->path = $this->server->getDataPath() . "worlds/" . $name . "/";
|
|
||||||
$this->generator = $generator;
|
|
||||||
$level = new LevelFormat($this->path . "level.pmf", array(
|
|
||||||
"name" => $name,
|
|
||||||
"seed" => $this->seed,
|
|
||||||
"time" => 0,
|
|
||||||
"spawnX" => 128,
|
|
||||||
"spawnY" => 128,
|
|
||||||
"spawnZ" => 128,
|
|
||||||
"height" => 8,
|
|
||||||
"generator" => $this->generator->getName(),
|
|
||||||
"generatorSettings" => $this->generator->getSettings(),
|
|
||||||
"extra" => ""
|
|
||||||
));
|
|
||||||
$this->level = new Level($this->server, $level, $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generate(){
|
|
||||||
$this->generator->init($this->level, $this->random);
|
|
||||||
|
|
||||||
for($Z = 6; $Z <= 10; ++$Z){
|
|
||||||
for($X = 6; $X <= 10; ++$X){
|
|
||||||
$this->level->level->loadChunk($X, $Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->level->setSpawn($this->generator->getSpawn());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function close(){
|
|
||||||
$this->level->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -151,13 +151,24 @@ interface Chunk{
|
|||||||
*/
|
*/
|
||||||
public function getChunkSnapshot($includeMaxBlockY = true, $includeBiome = false, $includeBiomeTemp = false);
|
public function getChunkSnapshot($includeMaxBlockY = true, $includeBiome = false, $includeBiomeTemp = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Entity $entity
|
||||||
|
*/
|
||||||
public function addEntity(Entity $entity);
|
public function addEntity(Entity $entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Entity $entity
|
||||||
|
*/
|
||||||
public function removeEntity(Entity $entity);
|
public function removeEntity(Entity $entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tile $tile
|
||||||
|
*/
|
||||||
public function addTile(Tile $tile);
|
public function addTile(Tile $tile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tile $tile
|
||||||
|
*/
|
||||||
public function removeTile(Tile $tile);
|
public function removeTile(Tile $tile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,6 +45,29 @@ interface LevelProvider{
|
|||||||
*/
|
*/
|
||||||
public static function isValid($path);
|
public static function isValid($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the needed files in the path given
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param string $name
|
||||||
|
* @param int $seed
|
||||||
|
* @param string $generator
|
||||||
|
* @param array[] $options
|
||||||
|
*/
|
||||||
|
public static function generate($path, $name, $seed, $generator, array $options = []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the generator name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getGenerator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getGeneratorOptions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Chunk object
|
* Gets the Chunk object
|
||||||
* This method must be implemented by all the level formats.
|
* This method must be implemented by all the level formats.
|
||||||
@ -92,6 +115,14 @@ interface LevelProvider{
|
|||||||
*/
|
*/
|
||||||
public function isChunkGenerated($X, $Z);
|
public function isChunkGenerated($X, $Z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $X
|
||||||
|
* @param int $Z
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isChunkPopulated($X, $Z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $X
|
* @param int $X
|
||||||
* @param int $Z
|
* @param int $Z
|
||||||
@ -100,6 +131,15 @@ interface LevelProvider{
|
|||||||
*/
|
*/
|
||||||
public function isChunkLoaded($X, $Z);
|
public function isChunkLoaded($X, $Z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $chunkX
|
||||||
|
* @param int $chunkZ
|
||||||
|
* @param SimpleChunk $chunk
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function setChunk($chunkX, $chunkZ, SimpleChunk $chunk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -115,6 +155,16 @@ interface LevelProvider{
|
|||||||
*/
|
*/
|
||||||
public function setTime($value);
|
public function setTime($value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSeed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $value
|
||||||
|
*/
|
||||||
|
public function setSeed($value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Vector3
|
* @return Vector3
|
||||||
*/
|
*/
|
||||||
@ -135,4 +185,6 @@ interface LevelProvider{
|
|||||||
*/
|
*/
|
||||||
public function getLevel();
|
public function getLevel();
|
||||||
|
|
||||||
|
public function close();
|
||||||
|
|
||||||
}
|
}
|
59
src/pocketmine/level/format/LevelProviderManager.php
Normal file
59
src/pocketmine/level/format/LevelProviderManager.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?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\format;
|
||||||
|
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
|
abstract class LevelProviderManager{
|
||||||
|
protected static $providers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Server $server
|
||||||
|
* @param string $class
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function addProvider(Server $server, $class){
|
||||||
|
if(!is_subclass_of($class, "pocketmine\\level\\format\\LevelProvider")){
|
||||||
|
throw new \Exception("Class is not a subclass of LevelProvider");
|
||||||
|
}
|
||||||
|
self::$providers[strtolower($class)] = $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a LevelProvider class for this path, or null
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getProvider($path){
|
||||||
|
foreach(self::$providers as $provider){
|
||||||
|
/** @var $provider LevelProvider */
|
||||||
|
if($provider::isValid($path)){
|
||||||
|
return $provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -125,9 +125,9 @@ class SimpleChunk{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $x 0-15
|
* @param int $x 0-15
|
||||||
* @param int $y 0-127
|
* @param int $y 0-127
|
||||||
* @param int $z 0-15
|
* @param int $z 0-15
|
||||||
* @param int $blockId 0-255
|
* @param int $blockId 0-255
|
||||||
*/
|
*/
|
||||||
public function setBlockId($x, $y, $z, $blockId){
|
public function setBlockId($x, $y, $z, $blockId){
|
||||||
@ -151,9 +151,9 @@ class SimpleChunk{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $x 0-15
|
* @param int $x 0-15
|
||||||
* @param int $y 0-127
|
* @param int $y 0-127
|
||||||
* @param int $z 0-15
|
* @param int $z 0-15
|
||||||
* @param int $data 0-15
|
* @param int $data 0-15
|
||||||
*/
|
*/
|
||||||
public function setBlockData($x, $y, $z, $data){
|
public function setBlockData($x, $y, $z, $data){
|
||||||
@ -236,6 +236,7 @@ class SimpleChunk{
|
|||||||
$offset += 2048;
|
$offset += 2048;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SimpleChunk($chunkX, $chunkZ, $flags, $ids, $meta);
|
return new SimpleChunk($chunkX, $chunkZ, $flags, $ids, $meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,21 @@
|
|||||||
namespace pocketmine\level\format\anvil;
|
namespace pocketmine\level\format\anvil;
|
||||||
|
|
||||||
use pocketmine\level\format\generic\BaseLevelProvider;
|
use pocketmine\level\format\generic\BaseLevelProvider;
|
||||||
|
use pocketmine\level\format\SimpleChunk;
|
||||||
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\nbt\NBT;
|
||||||
|
use pocketmine\nbt\tag\Byte;
|
||||||
|
use pocketmine\nbt\tag\ByteArray;
|
||||||
|
use pocketmine\nbt\tag\Compound;
|
||||||
|
use pocketmine\nbt\tag\Int;
|
||||||
|
use pocketmine\nbt\tag\Long;
|
||||||
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Anvil extends BaseLevelProvider{
|
class Anvil extends BaseLevelProvider{
|
||||||
|
|
||||||
/** @var RegionLoader */
|
/** @var RegionLoader[] */
|
||||||
protected $regions = [];
|
protected $regions = [];
|
||||||
|
|
||||||
/** @var Chunk[] */
|
/** @var Chunk[] */
|
||||||
@ -38,6 +47,37 @@ class Anvil extends BaseLevelProvider{
|
|||||||
return file_exists(realpath($path) . "level.dat") and file_exists(realpath($path) . "region/");
|
return file_exists(realpath($path) . "level.dat") and file_exists(realpath($path) . "region/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function generate($path, $name, $seed, $generator, array $options = []){
|
||||||
|
@mkdir($path, 0777, true);
|
||||||
|
@mkdir($path . "/region", 0777);
|
||||||
|
//TODO, add extra details
|
||||||
|
$levelData = new Compound("Data", [
|
||||||
|
"hardcore" => new Byte("hardcore", 0),
|
||||||
|
"initialized" => new Byte("initialized", 1),
|
||||||
|
"GameType" => new Int("GameType", 0),
|
||||||
|
"generatorVersion" => new Int("generatorVersion", 1), //2 in MCPE
|
||||||
|
"SpawnX" => new Int("SpawnX", 128),
|
||||||
|
"SpawnY" => new Int("SpawnY", 70),
|
||||||
|
"SpawnZ" => new Int("SpawnZ", 128),
|
||||||
|
"version" => new Int("version", 19133),
|
||||||
|
"DayTime" => new Int("DayTime", 0),
|
||||||
|
"LastPlayed" => new Long("LastPlayed", microtime(true) * 1000),
|
||||||
|
"RandomSeed" => new Long("RandomSeed", $seed),
|
||||||
|
"SizeOnDisk" => new Long("SizeOnDisk", 0),
|
||||||
|
"Time" => new Long("Time", 0),
|
||||||
|
"generatorName" => new String("generatorName", Generator::getGeneratorName($generator)),
|
||||||
|
"generatorOptions" => new String("generatorOptions", isset($options["preset"]) ? $options["preset"] : ""),
|
||||||
|
"LevelName" => new String("LevelName", $name),
|
||||||
|
"GameRules" => new Compound("GameRules", [])
|
||||||
|
]);
|
||||||
|
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||||
|
$nbt->setData(new Compound(null, [
|
||||||
|
"Data" => $levelData
|
||||||
|
]));
|
||||||
|
$buffer = $nbt->writeCompressed();
|
||||||
|
@file_put_contents($path . "level.dat", $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
public static function getRegionIndex($chunkX, $chunkZ, &$x, &$z){
|
public static function getRegionIndex($chunkX, $chunkZ, &$x, &$z){
|
||||||
$x = $chunkX >> 5;
|
$x = $chunkX >> 5;
|
||||||
$z = $chunkZ >> 5;
|
$z = $chunkZ >> 5;
|
||||||
@ -47,6 +87,14 @@ class Anvil extends BaseLevelProvider{
|
|||||||
$this->chunks = [];
|
$this->chunks = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getGenerator(){
|
||||||
|
return $this->levelData["generatorName"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGeneratorOptions(){
|
||||||
|
return ["preset" => $this->levelData["generatorOptions"]];
|
||||||
|
}
|
||||||
|
|
||||||
public function getLoadedChunks(){
|
public function getLoadedChunks(){
|
||||||
return $this->chunks;
|
return $this->chunks;
|
||||||
}
|
}
|
||||||
@ -88,12 +136,14 @@ class Anvil extends BaseLevelProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
unset($this->chunks[Level::chunkHash($x, $z)]);
|
unset($this->chunks[Level::chunkHash($x, $z)]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveChunk($x, $z){
|
public function saveChunk($x, $z){
|
||||||
if($this->isChunkLoaded($x, $z)){
|
if($this->isChunkLoaded($x, $z)){
|
||||||
$this->getRegion($x >> 5, $z >> 5)->writeChunk($this->getChunk($x, $z));
|
$this->getRegion($x >> 5, $z >> 5)->writeChunk($this->getChunk($x, $z));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,10 +157,18 @@ class Anvil extends BaseLevelProvider{
|
|||||||
* @return RegionLoader
|
* @return RegionLoader
|
||||||
*/
|
*/
|
||||||
protected function getRegion($x, $z){
|
protected function getRegion($x, $z){
|
||||||
$index = $x.":".$z;
|
$index = $x . ":" . $z;
|
||||||
|
|
||||||
return isset($this->regions[$index]) ? $this->regions[$index] : null;
|
return isset($this->regions[$index]) ? $this->regions[$index] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $chunkX
|
||||||
|
* @param int $chunkZ
|
||||||
|
* @param bool $create
|
||||||
|
*
|
||||||
|
* @return Chunk
|
||||||
|
*/
|
||||||
public function getChunk($chunkX, $chunkZ, $create = false){
|
public function getChunk($chunkX, $chunkZ, $create = false){
|
||||||
$index = Level::chunkHash($chunkX, $chunkZ);
|
$index = Level::chunkHash($chunkX, $chunkZ);
|
||||||
if(isset($this->chunks[$index])){
|
if(isset($this->chunks[$index])){
|
||||||
@ -120,18 +178,55 @@ class Anvil extends BaseLevelProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->loadChunk($chunkX, $chunkZ);
|
$this->loadChunk($chunkX, $chunkZ);
|
||||||
|
|
||||||
return $this->getChunk($chunkX, $chunkZ, false);
|
return $this->getChunk($chunkX, $chunkZ, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setChunk($chunkX, $chunkZ, SimpleChunk $chunk){
|
||||||
|
if($chunk->isGenerated() === false){
|
||||||
|
$this->unloadChunk($chunkX, $chunkZ, false);
|
||||||
|
$region = $this->getRegion($chunkX >> 4, $chunkZ >> 4);
|
||||||
|
$region->removeChunk($chunkX - $region->getX() * 32, $chunkZ - $region->getZ() * 32);
|
||||||
|
$this->loadChunk($chunkX, $chunkZ);
|
||||||
|
}else{
|
||||||
|
$newChunk = $this->getChunk($chunkX, $chunkZ, true);
|
||||||
|
for($y = 0; $y < 8; ++$y){
|
||||||
|
$section = new ChunkSection(new Compound(null, [
|
||||||
|
"Y" => new Byte("Y", $y),
|
||||||
|
"Blocks" => new ByteArray("Blocks", $chunk->getSectionIds($y)),
|
||||||
|
"Data" => new ByteArray("Data", $chunk->getSectionData($y)),
|
||||||
|
"BlockLight" => new ByteArray("BlockLight", str_repeat("\xff", 2048)), //TODO
|
||||||
|
"SkyLight" => new ByteArray("SkyLight", str_repeat("\x00", 2048)) //TODO
|
||||||
|
]));
|
||||||
|
$newChunk->setSection($y, $section);
|
||||||
|
}
|
||||||
|
if($chunk->isPopulated()){
|
||||||
|
$newChunk->setPopulated(1);
|
||||||
|
}
|
||||||
|
$this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $newChunk;
|
||||||
|
$this->saveChunk($chunkX, $chunkZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function isChunkGenerated($chunkX, $chunkZ){
|
public function isChunkGenerated($chunkX, $chunkZ){
|
||||||
if(($region = $this->getRegion($chunkX >> 5, $chunkZ >> 5)) instanceof RegionLoader){
|
if(($region = $this->getRegion($chunkX >> 5, $chunkZ >> 5)) instanceof RegionLoader){
|
||||||
return $region->chunkExists($chunkX - $region->getX() * 32, $chunkZ - $region->getZ() * 32);
|
return $region->chunkExists($chunkX - $region->getX() * 32, $chunkZ - $region->getZ() * 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isChunkPopulated($chunkX, $chunkZ){
|
||||||
|
$chunk = $this->getChunk($chunkX, $chunkZ);
|
||||||
|
if($chunk instanceof Chunk){
|
||||||
|
return $chunk->isPopulated();
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadRegion($x, $z){
|
protected function loadRegion($x, $z){
|
||||||
$index = $x.":".$z;
|
$index = $x . ":" . $z;
|
||||||
if(isset($this->regions[$index])){
|
if(isset($this->regions[$index])){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -140,4 +235,13 @@ class Anvil extends BaseLevelProvider{
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function close(){
|
||||||
|
$this->unloadChunks();
|
||||||
|
foreach($this->regions as $index => $region){
|
||||||
|
$region->doSlowCleanUp();
|
||||||
|
$region->close();
|
||||||
|
unset($this->regions[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -24,8 +24,8 @@ namespace pocketmine\level\format\anvil;
|
|||||||
use pocketmine\level\format\generic\BaseChunk;
|
use pocketmine\level\format\generic\BaseChunk;
|
||||||
use pocketmine\level\format\generic\EmptyChunkSection;
|
use pocketmine\level\format\generic\EmptyChunkSection;
|
||||||
use pocketmine\level\format\LevelProvider;
|
use pocketmine\level\format\LevelProvider;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
|
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;
|
||||||
|
|
||||||
@ -68,11 +68,33 @@ class Chunk extends BaseChunk{
|
|||||||
$sections = [];
|
$sections = [];
|
||||||
foreach($this->nbt->Sections as $section){
|
foreach($this->nbt->Sections as $section){
|
||||||
if($section instanceof Compound){
|
if($section instanceof Compound){
|
||||||
$sections[(int) $section["Y"]] = new ChunkSection($section);
|
$y = (int) $section["Y"];
|
||||||
|
if($y < 8){
|
||||||
|
$sections[$y] = new ChunkSection($section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for($y = 0; $y < 8; ++$y){
|
||||||
|
if(!isset($sections[$y])){
|
||||||
|
$sections[$y] = new EmptyChunkSection($y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $sections, $this->nbt["Entities"], $this->nbt["TileEntities"]);
|
parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $sections, $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isPopulated(){
|
||||||
|
return $this->nbt["TerrainPopulated"] > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $value
|
||||||
|
*/
|
||||||
|
public function setPopulated($value = 1){
|
||||||
|
$this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChunkSnapshot($includeMaxBlockY = true, $includeBiome = false, $includeBiomeTemp = false){
|
public function getChunkSnapshot($includeMaxBlockY = true, $includeBiome = false, $includeBiomeTemp = false){
|
||||||
@ -103,7 +125,7 @@ class Chunk extends BaseChunk{
|
|||||||
//TODO: maxBlockY, biomeMap, biomeTemp
|
//TODO: maxBlockY, biomeMap, biomeTemp
|
||||||
|
|
||||||
//TODO: time
|
//TODO: time
|
||||||
return new ChunkSnapshot($this->getX(), $this->getZ(), $this->getLevel()->getName(), 0/*$this->getLevel()->getTime()*/, $blockId, $blockData, $blockSkyLight, $blockLight, $emptySections, null, null, null, null);
|
return new ChunkSnapshot($this->getX(), $this->getZ(), $this->getLevel()->getName(), 0 /*$this->getLevel()->getTime()*/, $blockId, $blockData, $blockSkyLight, $blockLight, $emptySections, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,8 +27,8 @@ class ChunkSnapshot extends BaseChunkSnapshot{
|
|||||||
|
|
||||||
public function getBlockId($x, $y, $z){
|
public function getBlockId($x, $y, $z){
|
||||||
return ord($this->blockId{
|
return ord($this->blockId{
|
||||||
(($y >> 4) << 12) //get section index
|
(($y >> 4) << 12) //get section index
|
||||||
+ ($y << 8) + ($z << 4) + $x //get block index in section
|
+ ($y << 8) + ($z << 4) + $x //get block index in section
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,9 @@ class RegionLoader{
|
|||||||
|
|
||||||
if($length <= 0){ //Not yet generated
|
if($length <= 0){ //Not yet generated
|
||||||
$this->generateChunk($x, $z);
|
$this->generateChunk($x, $z);
|
||||||
|
fseek($this->filePointer, $this->locationTable[$index][0] << 12);
|
||||||
|
$length = Binary::readInt(fread($this->filePointer, 4));
|
||||||
|
$compression = ord(fgetc($this->filePointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($length > ($this->locationTable[$index][1] << 12)){ //Invalid chunk, bigger than defined number of sectors
|
if($length > ($this->locationTable[$index][1] << 12)){ //Invalid chunk, bigger than defined number of sectors
|
||||||
@ -133,7 +136,7 @@ class RegionLoader{
|
|||||||
public function generateChunk($x, $z){
|
public function generateChunk($x, $z){
|
||||||
$nbt = new Compound("Level", []);
|
$nbt = new Compound("Level", []);
|
||||||
$nbt->xPos = new Int("xPos", ($this->getX() * 32) + $x);
|
$nbt->xPos = new Int("xPos", ($this->getX() * 32) + $x);
|
||||||
$nbt->zPos = new Int("xPos", ($this->getZ() * 32) + $z);
|
$nbt->zPos = new Int("zPos", ($this->getZ() * 32) + $z);
|
||||||
$nbt->LastUpdate = new Long("LastUpdate", 0);
|
$nbt->LastUpdate = new Long("LastUpdate", 0);
|
||||||
$nbt->LightPopulated = new Byte("LightPopulated", 0);
|
$nbt->LightPopulated = new Byte("LightPopulated", 0);
|
||||||
$nbt->TerrainPopulated = new Byte("TerrainPopulated", 0);
|
$nbt->TerrainPopulated = new Byte("TerrainPopulated", 0);
|
||||||
@ -170,6 +173,12 @@ class RegionLoader{
|
|||||||
fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $sectors << 12, "\x00", STR_PAD_RIGHT));
|
fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $sectors << 12, "\x00", STR_PAD_RIGHT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeChunk($x, $z){
|
||||||
|
$index = self::getChunkOffset($x, $z);
|
||||||
|
$this->locationTable[$index][0] = 0;
|
||||||
|
$this->locationTable[$index][1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public function writeChunk(Chunk $chunk){
|
public function writeChunk(Chunk $chunk){
|
||||||
$nbt = $chunk->getNBT();
|
$nbt = $chunk->getNBT();
|
||||||
$nbt->Sections = new Enum("Sections", []);
|
$nbt->Sections = new Enum("Sections", []);
|
||||||
@ -215,6 +224,11 @@ class RegionLoader{
|
|||||||
return $x + ($z << 5);
|
return $x + ($z << 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function close(){
|
||||||
|
flock($this->filePointer, LOCK_UN);
|
||||||
|
fclose($this->filePointer);
|
||||||
|
}
|
||||||
|
|
||||||
public function doSlowCleanUp(){
|
public function doSlowCleanUp(){
|
||||||
for($i = 0; $i < 1024; ++$i){
|
for($i = 0; $i < 1024; ++$i){
|
||||||
if($this->locationTable[$i][0] === 0 or $this->locationTable[$i][1] === 0){
|
if($this->locationTable[$i][0] === 0 or $this->locationTable[$i][1] === 0){
|
||||||
|
@ -26,7 +26,6 @@ use pocketmine\entity\Entity;
|
|||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\format\ChunkSection;
|
use pocketmine\level\format\ChunkSection;
|
||||||
use pocketmine\level\format\LevelProvider;
|
use pocketmine\level\format\LevelProvider;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\String;
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\tile\Chest;
|
use pocketmine\tile\Chest;
|
||||||
@ -58,6 +57,8 @@ abstract class BaseChunk implements Chunk{
|
|||||||
* @param ChunkSection[] $sections
|
* @param ChunkSection[] $sections
|
||||||
* @param Compound[] $entities
|
* @param Compound[] $entities
|
||||||
* @param Compound[] $tiles
|
* @param Compound[] $tiles
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function __construct(LevelProvider $level, $x, $z, array $sections, array $entities = [], array $tiles = []){
|
protected function __construct(LevelProvider $level, $x, $z, array $sections, array $entities = [], array $tiles = []){
|
||||||
$this->level = new \WeakRef($level);
|
$this->level = new \WeakRef($level);
|
||||||
@ -68,14 +69,11 @@ abstract class BaseChunk implements Chunk{
|
|||||||
$this->sections[$Y] = $section;
|
$this->sections[$Y] = $section;
|
||||||
}else{
|
}else{
|
||||||
trigger_error("Received invalid ChunkSection instance", E_USER_ERROR);
|
trigger_error("Received invalid ChunkSection instance", E_USER_ERROR);
|
||||||
|
throw new \Exception("Received invalid ChunkSection instance");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($section >= self::SECTION_COUNT){
|
if($Y >= self::SECTION_COUNT){
|
||||||
trigger_error("Invalid amount of chunks", E_USER_WARNING);
|
throw new \Exception("Invalid amount of chunks");
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace pocketmine\level\format\generic;
|
namespace pocketmine\level\format\generic;
|
||||||
|
|
||||||
use pocketmine\level\format\LevelProvider;
|
use pocketmine\level\format\LevelProvider;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
@ -73,14 +74,22 @@ abstract class BaseLevelProvider implements LevelProvider{
|
|||||||
$this->levelData->Time = new Int("Time", (int) $value);
|
$this->levelData->Time = new Int("Time", (int) $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSeed(){
|
||||||
|
return $this->levelData["RandomSeed"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSeed($value){
|
||||||
|
$this->levelData->RandomSeed = new Int("RandomSeed", (int) $value);
|
||||||
|
}
|
||||||
|
|
||||||
public function getSpawn(){
|
public function getSpawn(){
|
||||||
return new Vector3($this->levelData["SpawnX"], $this->levelData["SpawnY"], $this->levelData["SpawnZ"]);
|
return new Vector3($this->levelData["SpawnX"], $this->levelData["SpawnY"], $this->levelData["SpawnZ"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSpawn(Vector3 $pos){
|
public function setSpawn(Vector3 $pos){
|
||||||
$this->levelData->SpawnX = new Int("SpawnX", $pos->x);
|
$this->levelData->SpawnX = new Int("SpawnX", (int) $pos->x);
|
||||||
$this->levelData->SpawnY = new Int("SpawnY", $pos->y);
|
$this->levelData->SpawnY = new Int("SpawnY", (int) $pos->y);
|
||||||
$this->levelData->SpawnZ = new Int("SpawnZ", $pos->z);
|
$this->levelData->SpawnZ = new Int("SpawnZ", (int) $pos->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,6 +27,17 @@ use pocketmine\level\format\ChunkSection;
|
|||||||
* Stub used to detect empty chunks
|
* Stub used to detect empty chunks
|
||||||
*/
|
*/
|
||||||
class EmptyChunkSection implements ChunkSection{
|
class EmptyChunkSection implements ChunkSection{
|
||||||
|
|
||||||
|
private $y;
|
||||||
|
|
||||||
|
public function __construct($y){
|
||||||
|
$this->y = $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getY(){
|
||||||
|
return $this->y;
|
||||||
|
}
|
||||||
|
|
||||||
final public function getBlockId($x, $y, $z){
|
final public function getBlockId($x, $y, $z){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -39,6 +50,15 @@ class EmptyChunkSection implements ChunkSection{
|
|||||||
return "\x00\x00\x00\x00\x00\x00\x00\x00";
|
return "\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final public function getBlock($x, $y, $z, &$id = null, &$meta = null){
|
||||||
|
$id = 0;
|
||||||
|
$meta = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setBlock($x, $y, $z, $id = null, $meta = null){
|
||||||
|
throw new \Exception("Tried to modify an empty Chunk");
|
||||||
|
}
|
||||||
|
|
||||||
public function getIdArray(){
|
public function getIdArray(){
|
||||||
return str_repeat("\x00", 4096);
|
return str_repeat("\x00", 4096);
|
||||||
}
|
}
|
||||||
@ -56,7 +76,7 @@ class EmptyChunkSection implements ChunkSection{
|
|||||||
}
|
}
|
||||||
|
|
||||||
final public function setBlockId($x, $y, $z, $id){
|
final public function setBlockId($x, $y, $z, $id){
|
||||||
|
throw new \Exception("Tried to modify an empty Chunk");
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getBlockData($x, $y, $z){
|
final public function getBlockData($x, $y, $z){
|
||||||
@ -64,7 +84,7 @@ class EmptyChunkSection implements ChunkSection{
|
|||||||
}
|
}
|
||||||
|
|
||||||
final public function setBlockData($x, $y, $z, $data){
|
final public function setBlockData($x, $y, $z, $data){
|
||||||
|
throw new \Exception("Tried to modify an empty Chunk");
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getBlockLight($x, $y, $z){
|
final public function getBlockLight($x, $y, $z){
|
||||||
@ -72,7 +92,7 @@ class EmptyChunkSection implements ChunkSection{
|
|||||||
}
|
}
|
||||||
|
|
||||||
final public function setBlockLight($x, $y, $z, $level){
|
final public function setBlockLight($x, $y, $z, $level){
|
||||||
|
throw new \Exception("Tried to modify an empty Chunk");
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getBlockSkyLight($x, $y, $z){
|
final public function getBlockSkyLight($x, $y, $z){
|
||||||
@ -80,6 +100,6 @@ class EmptyChunkSection implements ChunkSection{
|
|||||||
}
|
}
|
||||||
|
|
||||||
final public function setBlockSkyLight($x, $y, $z, $level){
|
final public function setBlockSkyLight($x, $y, $z, $level){
|
||||||
|
throw new \Exception("Tried to modify an empty Chunk");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
namespace pocketmine\level\generator;
|
namespace pocketmine\level\generator;
|
||||||
|
|
||||||
use pocketmine\level\generator\populator\Populator;
|
|
||||||
use pocketmine\block\CoalOre;
|
use pocketmine\block\CoalOre;
|
||||||
use pocketmine\block\DiamondOre;
|
use pocketmine\block\DiamondOre;
|
||||||
use pocketmine\block\Dirt;
|
use pocketmine\block\Dirt;
|
||||||
@ -33,7 +32,7 @@ use pocketmine\block\RedstoneOre;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\format\SimpleChunk;
|
use pocketmine\level\format\SimpleChunk;
|
||||||
use pocketmine\level\generator\populator\Ore;
|
use pocketmine\level\generator\populator\Ore;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\generator\populator\Populator;
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ class Flat extends Generator{
|
|||||||
$b = Item::fromString($b);
|
$b = Item::fromString($b);
|
||||||
$cnt = $matches[2][$i] === "" ? 1 : intval($matches[2][$i]);
|
$cnt = $matches[2][$i] === "" ? 1 : intval($matches[2][$i]);
|
||||||
for($cY = $y, $y += $cnt; $cY < $y; ++$cY){
|
for($cY = $y, $y += $cnt; $cY < $y; ++$cY){
|
||||||
$this->structure[$cY] = [$b->getID(),$b->getDamage()];
|
$this->structure[$cY] = [$b->getID(), $b->getDamage()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ namespace pocketmine\level\generator;
|
|||||||
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\format\SimpleChunk;
|
use pocketmine\level\format\SimpleChunk;
|
||||||
use pocketmine\level\generator\Generator;
|
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
@ -77,6 +76,7 @@ class GenerationChunkManager implements ChunkManager{
|
|||||||
*/
|
*/
|
||||||
public function getChunk($chunkX, $chunkZ){
|
public function getChunk($chunkX, $chunkZ){
|
||||||
$index = Level::chunkHash($chunkX, $chunkZ);
|
$index = Level::chunkHash($chunkX, $chunkZ);
|
||||||
|
|
||||||
return !isset($this->chunks[$index]) ? $this->requestChunk($chunkX, $chunkZ) : $this->chunks[$index];
|
return !isset($this->chunks[$index]) ? $this->requestChunk($chunkX, $chunkZ) : $this->chunks[$index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +112,7 @@ class GenerationChunkManager implements ChunkManager{
|
|||||||
protected function requestChunk($chunkX, $chunkZ){
|
protected function requestChunk($chunkX, $chunkZ){
|
||||||
$chunk = $this->manager->requestChunk($this->levelID, $chunkX, $chunkZ);
|
$chunk = $this->manager->requestChunk($this->levelID, $chunkX, $chunkZ);
|
||||||
$this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk;
|
$this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk;
|
||||||
|
|
||||||
return $chunk;
|
return $chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,6 @@ class GenerationManager{
|
|||||||
const PACKET_SHUTDOWN = 0xff;
|
const PACKET_SHUTDOWN = 0xff;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected $socket;
|
protected $socket;
|
||||||
/** @var \Logger */
|
/** @var \Logger */
|
||||||
protected $logger;
|
protected $logger;
|
||||||
@ -138,6 +137,9 @@ class GenerationManager{
|
|||||||
protected function generateChunk($levelID, $chunkX, $chunkZ){
|
protected function generateChunk($levelID, $chunkX, $chunkZ){
|
||||||
if(isset($this->levels[$levelID])){
|
if(isset($this->levels[$levelID])){
|
||||||
$this->levels[$levelID]->populateChunk($chunkX, $chunkZ); //Request population directly
|
$this->levels[$levelID]->populateChunk($chunkX, $chunkZ); //Request population directly
|
||||||
|
if(isset($this->levels[$levelID])){
|
||||||
|
$this->sendChunk($levelID, $this->levels[$levelID]->getChunk($chunkX, $chunkZ));
|
||||||
|
}
|
||||||
//TODO: wait for queue generation (to wait for extra chunk changes)
|
//TODO: wait for queue generation (to wait for extra chunk changes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +173,7 @@ class GenerationManager{
|
|||||||
*/
|
*/
|
||||||
public function requestChunk($levelID, $chunkX, $chunkZ){
|
public function requestChunk($levelID, $chunkX, $chunkZ){
|
||||||
$this->needsChunk = [$levelID, $chunkX, $chunkZ];
|
$this->needsChunk = [$levelID, $chunkX, $chunkZ];
|
||||||
$binary = chr(self::PACKET_REQUEST_CHUNK . Binary::writeInt($levelID) . Binary::writeInt($chunkX) . Binary::writeInt($chunkZ));
|
$binary = chr(self::PACKET_REQUEST_CHUNK) . Binary::writeInt($levelID) . Binary::writeInt($chunkX) . Binary::writeInt($chunkZ);
|
||||||
@socket_write($this->socket, Binary::writeInt(strlen($binary)) . $binary);
|
@socket_write($this->socket, Binary::writeInt(strlen($binary)) . $binary);
|
||||||
do{
|
do{
|
||||||
$this->readPacket();
|
$this->readPacket();
|
||||||
@ -187,14 +189,14 @@ class GenerationManager{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function sendChunk($levelID, SimpleChunk $chunk){
|
public function sendChunk($levelID, SimpleChunk $chunk){
|
||||||
$binary = chr(self::PACKET_SEND_CHUNK . Binary::writeInt($levelID) . $chunk->toBinary());
|
$binary = chr(self::PACKET_SEND_CHUNK) . Binary::writeInt($levelID) . $chunk->toBinary();
|
||||||
@socket_write($this->socket, Binary::writeInt(strlen($binary)) . $binary);
|
@socket_write($this->socket, Binary::writeInt(strlen($binary)) . $binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function readPacket(){
|
protected function readPacket(){
|
||||||
$len = socket_read($this->socket, 4);
|
$len = @socket_read($this->socket, 4);
|
||||||
if($len === false or $len === ""){
|
if($len === false or $len === ""){
|
||||||
usleep(5000);
|
$this->shutdown = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$packet = socket_read($this->socket, Binary::readInt($len));
|
$packet = socket_read($this->socket, Binary::readInt($len));
|
||||||
|
140
src/pocketmine/level/generator/GenerationRequestManager.php
Normal file
140
src/pocketmine/level/generator/GenerationRequestManager.php
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<?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\level\format\SimpleChunk;
|
||||||
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\Server;
|
||||||
|
use pocketmine\utils\Binary;
|
||||||
|
|
||||||
|
class GenerationRequestManager{
|
||||||
|
|
||||||
|
protected $socket;
|
||||||
|
/** @var Server */
|
||||||
|
protected $server;
|
||||||
|
/** @var GenerationThread */
|
||||||
|
protected $generationThread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Server $server
|
||||||
|
*/
|
||||||
|
public function __construct(Server $server){
|
||||||
|
$this->server = $server;
|
||||||
|
$this->generationThread = new GenerationThread($server->getLogger(), $server->getLoader());
|
||||||
|
$this->socket = $this->generationThread->getExternalSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Level $level
|
||||||
|
* @param string $generator
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function openLevel(Level $level, $generator, array $options = []){
|
||||||
|
$buffer = chr(GenerationManager::PACKET_OPEN_LEVEL) . Binary::writeInt($level->getID()) . Binary::writeInt($level->getSeed()) .
|
||||||
|
Binary::writeShort(strlen($generator)) . $generator . serialize($options);
|
||||||
|
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Level $level
|
||||||
|
*/
|
||||||
|
public function closeLevel(Level $level){
|
||||||
|
$buffer = chr(GenerationManager::PACKET_CLOSE_LEVEL) . Binary::writeInt($level->getID());
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addNamespace($namespace, $path){
|
||||||
|
$buffer = chr(GenerationManager::PACKET_ADD_NAMESPACE) . Binary::writeShort(strlen($namespace)) . $namespace . $path;
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function socketRead($len){
|
||||||
|
$buffer = "";
|
||||||
|
while(strlen($buffer) < $len){
|
||||||
|
$buffer .= @socket_read($this->socket, $len - strlen($buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sendChunk($levelID, SimpleChunk $chunk){
|
||||||
|
$binary = chr(GenerationManager::PACKET_SEND_CHUNK) . Binary::writeInt($levelID) . $chunk->toBinary();
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($binary)) . $binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function requestChunk(Level $level, $chunkX, $chunkZ){
|
||||||
|
$buffer = chr(GenerationManager::PACKET_REQUEST_CHUNK) . Binary::writeInt($level->getID()) . Binary::writeInt($chunkX) . Binary::writeInt($chunkZ);
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleRequest($levelID, $chunkX, $chunkZ){
|
||||||
|
if(($level = $this->server->getLevel($levelID)) instanceof Level){
|
||||||
|
$this->sendChunk($levelID, $level->getChunk($chunkX, $chunkZ, false));
|
||||||
|
}else{
|
||||||
|
$buffer = chr(GenerationManager::PACKET_CLOSE_LEVEL) . Binary::writeInt($levelID);
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function receiveChunk($levelID, SimpleChunk $chunk){
|
||||||
|
if(($level = $this->server->getLevel($levelID)) instanceof Level){
|
||||||
|
$level->setChunk($chunk->getX(), $chunk->getZ(), $chunk);
|
||||||
|
}else{
|
||||||
|
$buffer = chr(GenerationManager::PACKET_CLOSE_LEVEL) . Binary::writeInt($levelID);
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handlePackets(){
|
||||||
|
if(($len = @socket_read($this->socket, 4)) !== false){
|
||||||
|
if(strlen($len) < 4){
|
||||||
|
$len .= $this->socketRead(4 - strlen($len));
|
||||||
|
}
|
||||||
|
$packet = $this->socketRead(Binary::readInt($len));
|
||||||
|
$pid = ord($packet{0});
|
||||||
|
$offset = 1;
|
||||||
|
|
||||||
|
if($pid === GenerationManager::PACKET_REQUEST_CHUNK){
|
||||||
|
$levelID = Binary::readInt(substr($packet, $offset, 4));
|
||||||
|
$offset += 4;
|
||||||
|
$chunkX = Binary::readInt(substr($packet, $offset, 4));
|
||||||
|
$offset += 4;
|
||||||
|
$chunkZ = Binary::readInt(substr($packet, $offset, 4));
|
||||||
|
$this->handleRequest($levelID, $chunkX, $chunkZ);
|
||||||
|
}elseif($pid === GenerationManager::PACKET_SEND_CHUNK){
|
||||||
|
$levelID = Binary::readInt(substr($packet, $offset, 4));
|
||||||
|
$offset += 4;
|
||||||
|
$chunk = SimpleChunk::fromBinary(substr($packet, $offset));
|
||||||
|
$this->receiveChunk($levelID, $chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shutdown(){
|
||||||
|
$buffer = chr(GenerationManager::PACKET_SHUTDOWN);
|
||||||
|
@socket_write($this->socket, Binary::writeInt(strlen($buffer)) . $buffer);
|
||||||
|
$this->generationThread->join();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -50,6 +50,7 @@ class GenerationThread extends \Thread{
|
|||||||
|
|
||||||
public function __construct(\ThreadedLogger $logger, \SplAutoloader $loader){
|
public function __construct(\ThreadedLogger $logger, \SplAutoloader $loader){
|
||||||
$this->loader = $loader;
|
$this->loader = $loader;
|
||||||
|
$this->logger = $logger;
|
||||||
$loadPaths = [];
|
$loadPaths = [];
|
||||||
$this->addDependency($loadPaths, new \ReflectionClass($this->logger));
|
$this->addDependency($loadPaths, new \ReflectionClass($this->logger));
|
||||||
$this->addDependency($loadPaths, new \ReflectionClass($this->loader));
|
$this->addDependency($loadPaths, new \ReflectionClass($this->loader));
|
||||||
@ -57,7 +58,7 @@ class GenerationThread extends \Thread{
|
|||||||
|
|
||||||
$sockets = [];
|
$sockets = [];
|
||||||
if(!socket_create_pair((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? AF_INET : AF_UNIX), SOCK_STREAM, 0, $sockets)){
|
if(!socket_create_pair((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? AF_INET : AF_UNIX), SOCK_STREAM, 0, $sockets)){
|
||||||
throw new \Exception("Could not create IPC sockets. Reason: ".socket_strerror(socket_last_error()));
|
throw new \Exception("Could not create IPC sockets. Reason: " . socket_strerror(socket_last_error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->internalSocket = $sockets[0];
|
$this->internalSocket = $sockets[0];
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
namespace pocketmine\level\generator;
|
namespace pocketmine\level\generator;
|
||||||
|
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
abstract class Generator{
|
abstract class Generator{
|
||||||
@ -48,6 +47,16 @@ abstract class Generator{
|
|||||||
return "pocketmine\\level\\generator\\Normal";
|
return "pocketmine\\level\\generator\\Normal";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getGeneratorName($class){
|
||||||
|
foreach(Generator::$list as $name => $c){
|
||||||
|
if($c === $class){
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
public abstract function __construct(array $settings = []);
|
public abstract function __construct(array $settings = []);
|
||||||
|
|
||||||
public abstract function init(GenerationChunkManager $level, Random $random);
|
public abstract function init(GenerationChunkManager $level, Random $random);
|
||||||
|
@ -32,12 +32,11 @@ use pocketmine\block\RedstoneOre;
|
|||||||
use pocketmine\level\generator\noise\Simplex;
|
use pocketmine\level\generator\noise\Simplex;
|
||||||
use pocketmine\level\generator\object\OreType;
|
use pocketmine\level\generator\object\OreType;
|
||||||
use pocketmine\level\generator\populator\Ore;
|
use pocketmine\level\generator\populator\Ore;
|
||||||
|
use pocketmine\level\generator\populator\Populator;
|
||||||
use pocketmine\level\generator\populator\TallGrass;
|
use pocketmine\level\generator\populator\TallGrass;
|
||||||
use pocketmine\level\generator\populator\Tree;
|
use pocketmine\level\generator\populator\Tree;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
use pocketmine\level\generator\populator\Populator;
|
|
||||||
|
|
||||||
class Normal extends Generator{
|
class Normal extends Generator{
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
namespace pocketmine\level\generator\object;
|
namespace pocketmine\level\generator\object;
|
||||||
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
|
|
||||||
class BigTree extends Tree{
|
class BigTree extends Tree{
|
||||||
private $trunkHeightMultiplier = 0.618;
|
private $trunkHeightMultiplier = 0.618;
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
namespace pocketmine\level\generator\object;
|
namespace pocketmine\level\generator\object;
|
||||||
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\math\VectorMath;
|
use pocketmine\math\VectorMath;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
|
@ -21,13 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\level\generator\object;
|
namespace pocketmine\level\generator\object;
|
||||||
|
|
||||||
use pocketmine\block\Dirt;
|
|
||||||
use pocketmine\block\Leaves;
|
|
||||||
use pocketmine\block\Wood;
|
|
||||||
use pocketmine\item\Block;
|
use pocketmine\item\Block;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class PineTree extends Tree{
|
class PineTree extends Tree{
|
||||||
|
@ -23,7 +23,6 @@ namespace pocketmine\level\generator\object;
|
|||||||
|
|
||||||
use pocketmine\block\Block;
|
use pocketmine\block\Block;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
|
@ -21,13 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\level\generator\object;
|
namespace pocketmine\level\generator\object;
|
||||||
|
|
||||||
use pocketmine\block\Dirt;
|
|
||||||
use pocketmine\block\Leaves;
|
|
||||||
use pocketmine\block\Wood;
|
|
||||||
use pocketmine\item\Block;
|
use pocketmine\item\Block;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class SmallTree extends Tree{
|
class SmallTree extends Tree{
|
||||||
|
@ -21,13 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\level\generator\object;
|
namespace pocketmine\level\generator\object;
|
||||||
|
|
||||||
use pocketmine\block\Dirt;
|
|
||||||
use pocketmine\block\Leaves;
|
|
||||||
use pocketmine\block\Wood;
|
|
||||||
use pocketmine\item\Block;
|
use pocketmine\item\Block;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class SpruceTree extends Tree{
|
class SpruceTree extends Tree{
|
||||||
|
@ -23,7 +23,6 @@ namespace pocketmine\level\generator\object;
|
|||||||
|
|
||||||
use pocketmine\block\Block;
|
use pocketmine\block\Block;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
|
@ -23,8 +23,6 @@ namespace pocketmine\level\generator\object;
|
|||||||
|
|
||||||
use pocketmine\block\Sapling;
|
use pocketmine\block\Sapling;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class Tree{
|
class Tree{
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\level\generator\populator;
|
namespace pocketmine\level\generator\populator;
|
||||||
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class Mineshaft extends Populator{
|
class Mineshaft extends Populator{
|
||||||
|
@ -23,8 +23,6 @@ namespace pocketmine\level\generator\populator;
|
|||||||
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\generator\object\Ore as ObjectOre;
|
use pocketmine\level\generator\object\Ore as ObjectOre;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class Ore extends Populator{
|
class Ore extends Populator{
|
||||||
|
@ -23,8 +23,6 @@ namespace pocketmine\level\generator\populator;
|
|||||||
|
|
||||||
use pocketmine\block\Water;
|
use pocketmine\block\Water;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class Pond extends Populator{
|
class Pond extends Populator{
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
namespace pocketmine\level\generator\populator;
|
namespace pocketmine\level\generator\populator;
|
||||||
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
abstract class Populator{
|
abstract class Populator{
|
||||||
|
@ -22,10 +22,7 @@
|
|||||||
namespace pocketmine\level\generator\populator;
|
namespace pocketmine\level\generator\populator;
|
||||||
|
|
||||||
use pocketmine\block\Block;
|
use pocketmine\block\Block;
|
||||||
use pocketmine\block\TallGrass as BlockTallGrass;
|
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class TallGrass extends Populator{
|
class TallGrass extends Populator{
|
||||||
|
@ -25,8 +25,6 @@ use pocketmine\block\Block;
|
|||||||
use pocketmine\block\Sapling;
|
use pocketmine\block\Sapling;
|
||||||
use pocketmine\level\ChunkManager;
|
use pocketmine\level\ChunkManager;
|
||||||
use pocketmine\level\generator\object\Tree as ObjectTree;
|
use pocketmine\level\generator\object\Tree as ObjectTree;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class Tree extends Populator{
|
class Tree extends Populator{
|
||||||
|
@ -35,6 +35,16 @@ class Enum extends NamedTag implements \ArrayAccess{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function &getValue(){
|
||||||
|
$value = [];
|
||||||
|
foreach($this as $k => $v){
|
||||||
|
if($v instanceof Tag){
|
||||||
|
$value[$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
public function offsetExists($offset){
|
public function offsetExists($offset){
|
||||||
return isset($this->{$offset});
|
return isset($this->{$offset});
|
||||||
}
|
}
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* ____ _ _ __ __ _ __ __ ____
|
|
||||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
|
||||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
|
||||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
|
||||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* @author PocketMine Team
|
|
||||||
* @link http://www.pocketmine.net/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace pocketmine\network\protocol;
|
|
||||||
|
|
||||||
|
|
||||||
class DisconnectPacket extends DataPacket{
|
|
||||||
public function pid(){
|
|
||||||
return Info::DISCONNECT_PACKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function decode(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(){
|
|
||||||
$this->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -21,8 +21,7 @@
|
|||||||
|
|
||||||
namespace pocketmine\network\query;
|
namespace pocketmine\network\query;
|
||||||
|
|
||||||
use pocketmine\network\Packet;
|
se pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Binary;
|
|
||||||
|
|
||||||
class QueryPacket extends Packet{
|
class QueryPacket extends Packet{
|
||||||
const HANDSHAKE = 9;
|
const HANDSHAKE = 9;
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\plugin;
|
namespace pocketmine\plugin;
|
||||||
|
|
||||||
use \Logger;
|
use Logger;
|
||||||
use \LogLevel;
|
use LogLevel;
|
||||||
use pocketmine\utils\MainLogger;
|
use pocketmine\utils\MainLogger;
|
||||||
|
|
||||||
class PluginLogger implements Logger{
|
class PluginLogger implements Logger{
|
||||||
|
@ -26,7 +26,6 @@ use pocketmine\inventory\DoubleChestInventory;
|
|||||||
use pocketmine\inventory\InventoryHolder;
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Byte;
|
use pocketmine\nbt\tag\Byte;
|
||||||
|
@ -27,7 +27,6 @@ use pocketmine\inventory\FurnaceRecipe;
|
|||||||
use pocketmine\inventory\InventoryHolder;
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Byte;
|
use pocketmine\nbt\tag\Byte;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\tile;
|
namespace pocketmine\tile;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Int;
|
use pocketmine\nbt\tag\Int;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\tile;
|
namespace pocketmine\tile;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
namespace pocketmine\tile;
|
namespace pocketmine\tile;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
|
|
||||||
@ -58,11 +57,6 @@ abstract class Tile extends Position{
|
|||||||
protected $lastUpdate;
|
protected $lastUpdate;
|
||||||
protected $server;
|
protected $server;
|
||||||
|
|
||||||
public function getID(){
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct(Chunk $chunk, Compound $nbt){
|
public function __construct(Chunk $chunk, Compound $nbt){
|
||||||
$this->server = $chunk->getLevel()->getLevel()->getServer();
|
$this->server = $chunk->getLevel()->getLevel()->getServer();
|
||||||
$this->chunk = $chunk;
|
$this->chunk = $chunk;
|
||||||
@ -80,6 +74,10 @@ abstract class Tile extends Position{
|
|||||||
$this->getLevel()->addTile($this);
|
$this->getLevel()->addTile($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getID(){
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
public function saveNBT(){
|
public function saveNBT(){
|
||||||
$this->namedtag["x"] = $this->x;
|
$this->namedtag["x"] = $this->x;
|
||||||
$this->namedtag["y"] = $this->y;
|
$this->namedtag["y"] = $this->y;
|
||||||
@ -94,6 +92,10 @@ abstract class Tile extends Position{
|
|||||||
Tile::$needUpdate[$this->id] = $this;
|
Tile::$needUpdate[$this->id] = $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __destruct(){
|
||||||
|
$this->close();
|
||||||
|
}
|
||||||
|
|
||||||
public function close(){
|
public function close(){
|
||||||
if($this->closed === false){
|
if($this->closed === false){
|
||||||
$this->closed = true;
|
$this->closed = true;
|
||||||
@ -103,10 +105,6 @@ abstract class Tile extends Position{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct(){
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName(){
|
public function getName(){
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace pocketmine\utils;
|
namespace pocketmine\utils;
|
||||||
use \LogLevel;
|
|
||||||
|
use LogLevel;
|
||||||
|
|
||||||
class MainLogger extends \ThreadedLogger{
|
class MainLogger extends \ThreadedLogger{
|
||||||
protected $logFile;
|
protected $logFile;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user