mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 17:29:44 +00:00
Moved Level methods to Server
This commit is contained in:
parent
5865f17c75
commit
502c27273d
@ -276,7 +276,7 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->server->removeOp($this->getName());
|
$this->server->removeOp($this->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->perm->recalculatePermissions();
|
$this->recalculatePermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,7 +316,17 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function recalculatePermissions(){
|
public function recalculatePermissions(){
|
||||||
|
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||||
|
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||||
|
|
||||||
$this->perm->recalculatePermissions();
|
$this->perm->recalculatePermissions();
|
||||||
|
|
||||||
|
if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){
|
||||||
|
$this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||||
|
}
|
||||||
|
if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){
|
||||||
|
$this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,10 +354,10 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->CID = $ip . ":" . $port;
|
$this->CID = $ip . ":" . $port;
|
||||||
$this->ip = $ip;
|
$this->ip = $ip;
|
||||||
$this->port = $port;
|
$this->port = $port;
|
||||||
$this->spawnPosition = Level::getDefault()->getSafeSpawn();
|
$this->spawnPosition = $this->server->getDefaultLevel()->getSafeSpawn();
|
||||||
$this->timeout = microtime(true) + 20;
|
$this->timeout = microtime(true) + 20;
|
||||||
$this->gamemode = $this->server->getGamemode();
|
$this->gamemode = $this->server->getGamemode();
|
||||||
$this->level = Level::getDefault();
|
$this->level = $this->server->getDefaultLevel();
|
||||||
$this->viewDistance = $this->server->getViewDistance();
|
$this->viewDistance = $this->server->getViewDistance();
|
||||||
$this->slot = 0;
|
$this->slot = 0;
|
||||||
$this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1);
|
$this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1);
|
||||||
@ -1285,8 +1295,13 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
|
||||||
$this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){
|
||||||
|
$this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||||
|
}
|
||||||
|
if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){
|
||||||
|
$this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
/*$u = $this->server->matchPlayer($this->username);
|
/*$u = $this->server->matchPlayer($this->username);
|
||||||
@ -1305,8 +1320,8 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$nbt["NameTag"] = $this->username;
|
$nbt["NameTag"] = $this->username;
|
||||||
}
|
}
|
||||||
$this->gamemode = $nbt["playerGameType"] & 0x03;
|
$this->gamemode = $nbt["playerGameType"] & 0x03;
|
||||||
if(($this->level = Level::get($nbt["Level"])) === false){
|
if(($this->level = $this->server->getLevel($nbt["Level"])) === null){
|
||||||
$this->level = Level::getDefault();
|
$this->level = $this->server->getDefaultLevel();
|
||||||
$nbt["Level"] = $this->level->getName();
|
$nbt["Level"] = $this->level->getName();
|
||||||
$nbt["Pos"][0] = $this->level->getSpawn()->x;
|
$nbt["Pos"][0] = $this->level->getSpawn()->x;
|
||||||
$nbt["Pos"][1] = $this->level->getSpawn()->y;
|
$nbt["Pos"][1] = $this->level->getSpawn()->y;
|
||||||
@ -1358,7 +1373,7 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->dataPacket($pk);
|
$this->dataPacket($pk);
|
||||||
|
|
||||||
|
|
||||||
if(($level = Level::get($this->namedtag["SpawnLevel"])) !== false){
|
if(($level = $this->server->getLevel($this->namedtag["SpawnLevel"])) instanceof Level){
|
||||||
$this->spawnPosition = new Position($this->namedtag["SpawnX"], $this->namedtag["SpawnY"], $this->namedtag["SpawnZ"], $level);
|
$this->spawnPosition = new Position($this->namedtag["SpawnX"], $this->namedtag["SpawnY"], $this->namedtag["SpawnZ"], $level);
|
||||||
|
|
||||||
$pk = new SetSpawnPositionPacket;
|
$pk = new SetSpawnPositionPacket;
|
||||||
@ -2287,7 +2302,6 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
if(isset($ev) and $this->username != "" and $this->spawned !== false and $ev->getQuitMessage() != ""){
|
if(isset($ev) and $this->username != "" and $this->spawned !== false and $ev->getQuitMessage() != ""){
|
||||||
$this->server->broadcastMessage($ev->getQuitMessage());
|
$this->server->broadcastMessage($ev->getQuitMessage());
|
||||||
}
|
}
|
||||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
|
||||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||||
$this->spawned = false;
|
$this->spawned = false;
|
||||||
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
|
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
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;
|
||||||
@ -37,8 +39,12 @@ use pocketmine\event\server\PacketReceiveEvent;
|
|||||||
use pocketmine\event\server\PacketSendEvent;
|
use pocketmine\event\server\PacketSendEvent;
|
||||||
use pocketmine\event\server\ServerCommandEvent;
|
use pocketmine\event\server\ServerCommandEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\level\generator\Flat;
|
||||||
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\WorldGenerator;
|
||||||
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;
|
||||||
@ -61,16 +67,21 @@ use pocketmine\permission\DefaultPermissions;
|
|||||||
use pocketmine\plugin\Plugin;
|
use pocketmine\plugin\Plugin;
|
||||||
use pocketmine\plugin\PluginLoadOrder;
|
use pocketmine\plugin\PluginLoadOrder;
|
||||||
use pocketmine\plugin\PluginManager;
|
use pocketmine\plugin\PluginManager;
|
||||||
|
use pocketmine\pmf\LevelFormat;
|
||||||
use pocketmine\recipes\Crafting;
|
use pocketmine\recipes\Crafting;
|
||||||
use pocketmine\scheduler\CallbackTask;
|
use pocketmine\scheduler\CallbackTask;
|
||||||
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\Config;
|
use pocketmine\utils\Config;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
use pocketmine\utils\VersionString;
|
use pocketmine\utils\VersionString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that manages everything
|
||||||
|
*/
|
||||||
class Server{
|
class Server{
|
||||||
const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin";
|
const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin";
|
||||||
const BROADCAST_CHANNEL_USERS = "pocketmine.broadcast.user";
|
const BROADCAST_CHANNEL_USERS = "pocketmine.broadcast.user";
|
||||||
@ -141,6 +152,12 @@ class Server{
|
|||||||
/** @var Player[] */
|
/** @var Player[] */
|
||||||
private $players = array();
|
private $players = array();
|
||||||
|
|
||||||
|
/** @var Level[] */
|
||||||
|
private $levels = array();
|
||||||
|
|
||||||
|
/** @var Level */
|
||||||
|
private $levelDefault = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -477,7 +494,7 @@ class Server{
|
|||||||
$name = strtolower($name);
|
$name = strtolower($name);
|
||||||
$path = $this->getDataPath() . "players/";
|
$path = $this->getDataPath() . "players/";
|
||||||
if(!file_exists($path . "$name.dat")){
|
if(!file_exists($path . "$name.dat")){
|
||||||
$spawn = Level::getDefault()->getSafeSpawn();
|
$spawn = $this->getDefaultLevel()->getSafeSpawn();
|
||||||
$nbt = new Compound(false, array(
|
$nbt = new Compound(false, array(
|
||||||
new Long("firstPlayed", floor(microtime(true) * 1000)),
|
new Long("firstPlayed", floor(microtime(true) * 1000)),
|
||||||
new Long("lastPlayed", floor(microtime(true) * 1000)),
|
new Long("lastPlayed", floor(microtime(true) * 1000)),
|
||||||
@ -486,8 +503,8 @@ class Server{
|
|||||||
new Double(1, $spawn->y),
|
new Double(1, $spawn->y),
|
||||||
new Double(2, $spawn->z)
|
new Double(2, $spawn->z)
|
||||||
)),
|
)),
|
||||||
new String("Level", Level::getDefault()->getName()),
|
new String("Level", $this->getDefaultLevel()->getName()),
|
||||||
new String("SpawnLevel", Level::getDefault()->getName()),
|
new String("SpawnLevel", $this->getDefaultLevel()->getName()),
|
||||||
new Int("SpawnX", (int) $spawn->x),
|
new Int("SpawnX", (int) $spawn->x),
|
||||||
new Int("SpawnY", (int) $spawn->y),
|
new Int("SpawnY", (int) $spawn->y),
|
||||||
new Int("SpawnZ", (int) $spawn->z),
|
new Int("SpawnZ", (int) $spawn->z),
|
||||||
@ -659,6 +676,257 @@ class Server{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function saveLevels(){
|
||||||
|
foreach($this->getLevels() as $level){
|
||||||
|
$level->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Level[]
|
||||||
|
*/
|
||||||
|
public function getLevels(){
|
||||||
|
return $this->levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Level
|
||||||
|
*/
|
||||||
|
public function getDefaultLevel(){
|
||||||
|
return $this->levelDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default level to a different level
|
||||||
|
* This won't change the level-name property,
|
||||||
|
* it only affects the server on runtime
|
||||||
|
*
|
||||||
|
* @param Level $level
|
||||||
|
*/
|
||||||
|
public function setDefaultLevel($level){
|
||||||
|
if($level === null or ($this->isLevelLoaded($level->getName()) and $level !== $this->levelDefault)){
|
||||||
|
$this->levelDefault = $level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isLevelLoaded($name){
|
||||||
|
return isset($this->levels[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return Level
|
||||||
|
*/
|
||||||
|
public function getLevel($name){
|
||||||
|
if(isset($this->levels[$name])){
|
||||||
|
return $this->levels[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Level $level
|
||||||
|
* @param bool $forceUnload
|
||||||
|
*/
|
||||||
|
public function unloadLevel(Level $level, $forceUnload = false){
|
||||||
|
if((!$level->isLoaded() or $level->unload($forceUnload) === true) and $this->isLevelLoaded($level->getName())){
|
||||||
|
unset($this->levels[$level->getName()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a level from the data directory
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function loadLevel($name){
|
||||||
|
if(trim($name) === ""){
|
||||||
|
trigger_error("Invalid empty level name", E_USER_WARNING);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if($this->isLevelLoaded($name)){
|
||||||
|
return true;
|
||||||
|
}elseif(!$this->isLevelGenerated($name)){
|
||||||
|
console("[NOTICE] Level \"" . $name . "\" not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||||
|
console("[INFO] Preparing level \"" . $name . "\"");
|
||||||
|
$level = new LevelFormat($path . "level.pmf");
|
||||||
|
if(!$level->isLoaded){
|
||||||
|
console("[ERROR] Could not load level \"" . $name . "\"");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//$entities = new Config($path."entities.yml", Config::YAML);
|
||||||
|
if(file_exists($path . "tileEntities.yml")){
|
||||||
|
@rename($path . "tileEntities.yml", $path . "tiles.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = new Level($this, $level, $name);
|
||||||
|
$this->levels[$level->getName()] = $level;
|
||||||
|
/*foreach($entities->getAll() as $entity){
|
||||||
|
if(!isset($entity["id"])){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if($entity["id"] === 64){ //Item Drop
|
||||||
|
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_ITEM, $entity["Item"]["id"], array(
|
||||||
|
"meta" => $entity["Item"]["Damage"],
|
||||||
|
"stack" => $entity["Item"]["Count"],
|
||||||
|
"x" => $entity["Pos"][0],
|
||||||
|
"y" => $entity["Pos"][1],
|
||||||
|
"z" => $entity["Pos"][2],
|
||||||
|
"yaw" => $entity["Rotation"][0],
|
||||||
|
"pitch" => $entity["Rotation"][1],
|
||||||
|
));
|
||||||
|
}elseif($entity["id"] === FALLING_SAND){
|
||||||
|
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_FALLING, $entity["id"], $entity);
|
||||||
|
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
|
||||||
|
$e->setHealth($entity["Health"]);
|
||||||
|
}elseif($entity["id"] === OBJECT_PAINTING or $entity["id"] === OBJECT_ARROW){ //Painting
|
||||||
|
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_OBJECT, $entity["id"], $entity);
|
||||||
|
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
|
||||||
|
$e->setHealth(1);
|
||||||
|
}else{
|
||||||
|
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_MOB, $entity["id"], $entity);
|
||||||
|
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
|
||||||
|
$e->setHealth($entity["Health"]);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if(file_exists($path . "tiles.yml")){
|
||||||
|
$tiles = new Config($path . "tiles.yml", Config::YAML);
|
||||||
|
foreach($tiles->getAll() as $tile){
|
||||||
|
if(!isset($tile["id"])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$level->loadChunk($tile["x"] >> 4, $tile["z"] >> 4);
|
||||||
|
|
||||||
|
$nbt = new Compound(false, array());
|
||||||
|
foreach($tile as $index => $data){
|
||||||
|
switch($index){
|
||||||
|
case "Items":
|
||||||
|
$tag = new Enum("Items", array());
|
||||||
|
$tag->setTagType(NBT::TAG_Compound);
|
||||||
|
foreach($data as $slot => $fields){
|
||||||
|
$tag[(int) $slot] = new Compound(false, array(
|
||||||
|
"Count" => new Byte("Count", $fields["Count"]),
|
||||||
|
"Slot" => new Short("Slot", $fields["Slot"]),
|
||||||
|
"Damage" => new Short("Damage", $fields["Damage"]),
|
||||||
|
"id" => new String("id", $fields["id"])
|
||||||
|
));
|
||||||
|
}
|
||||||
|
$nbt["Items"] = $tag;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "id":
|
||||||
|
case "Text1":
|
||||||
|
case "Text2":
|
||||||
|
case "Text3":
|
||||||
|
case "Text4":
|
||||||
|
$nbt[$index] = new String($index, $data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "x":
|
||||||
|
case "y":
|
||||||
|
case "z":
|
||||||
|
case "pairx":
|
||||||
|
case "pairz":
|
||||||
|
$nbt[$index] = new Int($index, $data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "BurnTime":
|
||||||
|
case "CookTime":
|
||||||
|
case "MaxTime":
|
||||||
|
$nbt[$index] = new Short($index, $data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch($tile["id"]){
|
||||||
|
case Tile::FURNACE:
|
||||||
|
new Furnace($level, $nbt);
|
||||||
|
break;
|
||||||
|
case Tile::CHEST:
|
||||||
|
new Chest($level, $nbt);
|
||||||
|
break;
|
||||||
|
case Tile::SIGN:
|
||||||
|
new Sign($level, $nbt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlink($path . "tiles.yml");
|
||||||
|
$level->save(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a new level if it does not exists
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param int $seed
|
||||||
|
* @param string $generator Class name that extends pocketmine\level\generator\Generator
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function generateLevel($name, $seed = null, $generator = null, array $options = array()){
|
||||||
|
if(trim($name) === "" or $this->isLevelGenerated($name)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($generator !== false and class_exists($generator) and is_subclass_of($generator, "pocketmine\\level\\generator\\Generator")){
|
||||||
|
$generator = new $generator($options);
|
||||||
|
}else{
|
||||||
|
if(strtoupper($this->getLevelType()) == "FLAT"){
|
||||||
|
$generator = new Flat($options);
|
||||||
|
$options["preset"] = $this->getConfigString("generator-settings", "");
|
||||||
|
}else{
|
||||||
|
$generator = new Normal($options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$gen = new WorldGenerator($this, $generator, $name, $seed === null ? Utils::readInt(Utils::getRandomBytes(4, false)) : (int) $seed);
|
||||||
|
$gen->generate();
|
||||||
|
$gen->close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isLevelGenerated($name){
|
||||||
|
if(trim($name) === ""){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||||
|
if($this->getLevel($name) === false and !file_exists($path . "level.pmf")){
|
||||||
|
if(file_exists($path)){
|
||||||
|
$level = new LevelImport($path);
|
||||||
|
if($level->import() === false){ //Try importing a world
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $variable
|
* @param string $variable
|
||||||
* @param string $defaultValue
|
* @param string $defaultValue
|
||||||
@ -968,7 +1236,22 @@ class Server{
|
|||||||
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");
|
||||||
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "default");
|
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "default");
|
||||||
Level::init();
|
|
||||||
|
if($this->getDefaultLevel() === null){
|
||||||
|
$default = $this->getConfigString("level-name", "world");
|
||||||
|
if(trim($default) == ""){
|
||||||
|
trigger_error("level-name cannot be null", E_USER_WARNING);
|
||||||
|
$default = "world";
|
||||||
|
$this->setConfigString("level-name", "world");
|
||||||
|
}
|
||||||
|
if($this->loadLevel($default) === false){
|
||||||
|
$this->generateLevel($default, $this->getConfigInt("level-seed", time()));
|
||||||
|
$this->loadLevel($default);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setDefaultLevel($this->getLevel($default));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$this->properties->save();
|
$this->properties->save();
|
||||||
//TODO
|
//TODO
|
||||||
@ -1118,8 +1401,8 @@ class Server{
|
|||||||
$player->kick("server stop");
|
$player->kick("server stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Level::getAll() as $level){
|
foreach($this->getLevels() as $level){
|
||||||
$level->unload(true);
|
$this->unloadLevel($level, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandlerList::unregisterAll();
|
HandlerList::unregisterAll();
|
||||||
@ -1268,14 +1551,14 @@ class Server{
|
|||||||
//TODO: Add level blocks
|
//TODO: Add level blocks
|
||||||
|
|
||||||
//Do level ticks
|
//Do level ticks
|
||||||
foreach(Level::getAll() as $level){
|
foreach($this->getLevels() as $level){
|
||||||
$level->doTick();
|
$level->doTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function doAutoSave(){
|
public function doAutoSave(){
|
||||||
$this->broadcast(TextFormat::GRAY . "Saving...", self::BROADCAST_CHANNEL_ADMINISTRATIVE);
|
$this->broadcast(TextFormat::GRAY . "Saving...", self::BROADCAST_CHANNEL_ADMINISTRATIVE);
|
||||||
Level::saveAll();
|
$this->saveLevels();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendUsage(){
|
public function sendUsage(){
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
namespace pocketmine\command\defaults;
|
namespace pocketmine\command\defaults;
|
||||||
|
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class SeedCommand extends VanillaCommand{
|
class SeedCommand extends VanillaCommand{
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class SeedCommand extends VanillaCommand{
|
|||||||
if($sender instanceof Player){
|
if($sender instanceof Player){
|
||||||
$seed = $sender->getLevel()->getSeed();
|
$seed = $sender->getLevel()->getSeed();
|
||||||
}else{
|
}else{
|
||||||
$seed = Level::getDefault()->getSeed();
|
$seed = Server::getInstance()->getDefaultLevel()->getSeed();
|
||||||
}
|
}
|
||||||
$sender->sendMessage("Seed: " . $seed);
|
$sender->sendMessage("Seed: " . $seed);
|
||||||
|
|
||||||
|
@ -31,16 +31,12 @@ use pocketmine\event\block\BlockBreakEvent;
|
|||||||
use pocketmine\event\block\BlockPlaceEvent;
|
use pocketmine\event\block\BlockPlaceEvent;
|
||||||
use pocketmine\event\player\PlayerInteractEvent;
|
use pocketmine\event\player\PlayerInteractEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\generator\Flat;
|
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\level\generator\Normal;
|
|
||||||
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\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Enum;
|
use pocketmine\nbt\tag\Enum;
|
||||||
use pocketmine\nbt\tag\Int;
|
use pocketmine\nbt\tag\Int;
|
||||||
use pocketmine\nbt\tag\Short;
|
|
||||||
use pocketmine\nbt\tag\String;
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\network\protocol\SetTimePacket;
|
use pocketmine\network\protocol\SetTimePacket;
|
||||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||||
@ -52,9 +48,7 @@ use pocketmine\tile\Furnace;
|
|||||||
use pocketmine\tile\Sign;
|
use pocketmine\tile\Sign;
|
||||||
use pocketmine\tile\Tile;
|
use pocketmine\tile\Tile;
|
||||||
use pocketmine\utils\Cache;
|
use pocketmine\utils\Cache;
|
||||||
use pocketmine\utils\Config;
|
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main Level handling class, includes all the methods used on them.
|
* Main Level handling class, includes all the methods used on them.
|
||||||
@ -67,39 +61,19 @@ class Level{
|
|||||||
const BLOCK_UPDATE_WEAK = 4;
|
const BLOCK_UPDATE_WEAK = 4;
|
||||||
const BLOCK_UPDATE_TOUCH = 5;
|
const BLOCK_UPDATE_TOUCH = 5;
|
||||||
|
|
||||||
/**
|
/** @var Player[] */
|
||||||
* @var Level[]
|
|
||||||
*/
|
|
||||||
public static $list = array();
|
|
||||||
|
|
||||||
/** @var Level */
|
|
||||||
public static $default = null;
|
|
||||||
|
|
||||||
public static $saveEnabled = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Player[]
|
|
||||||
*/
|
|
||||||
public $players = array();
|
public $players = array();
|
||||||
|
|
||||||
/**
|
/** @var Entity[] */
|
||||||
* @var Entity[]
|
|
||||||
*/
|
|
||||||
public $entities = array();
|
public $entities = array();
|
||||||
|
|
||||||
/**
|
/** @var Entity[][] */
|
||||||
* @var Entity[][]
|
|
||||||
*/
|
|
||||||
public $chunkEntities = array();
|
public $chunkEntities = array();
|
||||||
|
|
||||||
/**
|
/** @var Tile[] */
|
||||||
* @var Tile[]
|
|
||||||
*/
|
|
||||||
public $tiles = array();
|
public $tiles = array();
|
||||||
|
|
||||||
/**
|
/** @var Tile[][] */
|
||||||
* @var Tile[][]
|
|
||||||
*/
|
|
||||||
public $chunkTiles = array();
|
public $chunkTiles = array();
|
||||||
|
|
||||||
public $nextSave;
|
public $nextSave;
|
||||||
@ -107,264 +81,27 @@ class Level{
|
|||||||
/** @var LevelFormat */
|
/** @var LevelFormat */
|
||||||
public $level;
|
public $level;
|
||||||
public $stopTime;
|
public $stopTime;
|
||||||
private $time, $startCheck, $startTime;
|
private $time;
|
||||||
|
private $startCheck;
|
||||||
|
private $startTime;
|
||||||
/** @var Server */
|
/** @var Server */
|
||||||
private $server;
|
private $server;
|
||||||
private $name, $usedChunks, $changedBlocks, $changedCount, $generator;
|
private $name;
|
||||||
|
private $usedChunks;
|
||||||
|
private $changedBlocks;
|
||||||
|
private $changedCount;
|
||||||
|
/** @var Generator */
|
||||||
|
private $generator;
|
||||||
|
|
||||||
public static function init(){
|
private $autoSave = true;
|
||||||
if(self::$default === null){
|
|
||||||
$default = Server::getInstance()->getConfigString("level-name", null);
|
|
||||||
if($default == ""){
|
|
||||||
trigger_error("level-name cannot be null", E_USER_ERROR);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(self::loadLevel($default) === false){
|
|
||||||
self::generateLevel($default, 0); //TODO: Server->getSeed();
|
|
||||||
self::loadLevel($default);
|
|
||||||
}
|
|
||||||
self::$default = self::get($default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves all the levels
|
* @param Server $server
|
||||||
*
|
* @param LevelFormat $level
|
||||||
* @return void
|
* @param string $name
|
||||||
*/
|
*/
|
||||||
public static function saveAll(){
|
public function __construct(Server $server, LevelFormat $level, $name){
|
||||||
foreach(self::$list as $level){
|
$this->server = $server;
|
||||||
$level->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of all the loaded Levels
|
|
||||||
*
|
|
||||||
* @return Level[]
|
|
||||||
*/
|
|
||||||
public static function getAll(){
|
|
||||||
return self::$list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default Level on the Server
|
|
||||||
*
|
|
||||||
* @return Level
|
|
||||||
*/
|
|
||||||
public static function getDefault(){
|
|
||||||
return self::$default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a loaded Level
|
|
||||||
*
|
|
||||||
* @param $name string Level name
|
|
||||||
*
|
|
||||||
* @return bool|Level
|
|
||||||
*/
|
|
||||||
public static function get($name){
|
|
||||||
if($name !== "" and isset(self::$list[$name])){
|
|
||||||
return self::$list[$name];
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a level from the data directory
|
|
||||||
*
|
|
||||||
* @param $name
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function loadLevel($name){
|
|
||||||
if(self::get($name) !== false){
|
|
||||||
return true;
|
|
||||||
}elseif(self::levelExists($name) === false){
|
|
||||||
console("[NOTICE] Level \"" . $name . "\" not found");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$path = \pocketmine\DATA . "worlds/" . $name . "/";
|
|
||||||
console("[INFO] Preparing level \"" . $name . "\"");
|
|
||||||
$level = new LevelFormat($path . "level.pmf");
|
|
||||||
if(!$level->isLoaded){
|
|
||||||
console("[ERROR] Could not load level \"" . $name . "\"");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//$entities = new Config($path."entities.yml", Config::YAML);
|
|
||||||
if(file_exists($path . "tileEntities.yml")){
|
|
||||||
@rename($path . "tileEntities.yml", $path . "tiles.yml");
|
|
||||||
}
|
|
||||||
$blockUpdates = new Config($path . "bupdates.yml", Config::YAML);
|
|
||||||
$level = new Level($level, $name);
|
|
||||||
/*foreach($entities->getAll() as $entity){
|
|
||||||
if(!isset($entity["id"])){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if($entity["id"] === 64){ //Item Drop
|
|
||||||
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_ITEM, $entity["Item"]["id"], array(
|
|
||||||
"meta" => $entity["Item"]["Damage"],
|
|
||||||
"stack" => $entity["Item"]["Count"],
|
|
||||||
"x" => $entity["Pos"][0],
|
|
||||||
"y" => $entity["Pos"][1],
|
|
||||||
"z" => $entity["Pos"][2],
|
|
||||||
"yaw" => $entity["Rotation"][0],
|
|
||||||
"pitch" => $entity["Rotation"][1],
|
|
||||||
));
|
|
||||||
}elseif($entity["id"] === FALLING_SAND){
|
|
||||||
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_FALLING, $entity["id"], $entity);
|
|
||||||
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
|
|
||||||
$e->setHealth($entity["Health"]);
|
|
||||||
}elseif($entity["id"] === OBJECT_PAINTING or $entity["id"] === OBJECT_ARROW){ //Painting
|
|
||||||
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_OBJECT, $entity["id"], $entity);
|
|
||||||
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
|
|
||||||
$e->setHealth(1);
|
|
||||||
}else{
|
|
||||||
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_MOB, $entity["id"], $entity);
|
|
||||||
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
|
|
||||||
$e->setHealth($entity["Health"]);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if(file_exists($path . "tiles.yml")){
|
|
||||||
$tiles = new Config($path . "tiles.yml", Config::YAML);
|
|
||||||
foreach($tiles->getAll() as $tile){
|
|
||||||
if(!isset($tile["id"])){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$level->loadChunk($tile["x"] >> 4, $tile["z"] >> 4);
|
|
||||||
|
|
||||||
$nbt = new Compound(false, array());
|
|
||||||
foreach($tile as $index => $data){
|
|
||||||
switch($index){
|
|
||||||
case "Items":
|
|
||||||
$tag = new Enum("Items", array());
|
|
||||||
$tag->setTagType(NBT::TAG_Compound);
|
|
||||||
foreach($data as $slot => $fields){
|
|
||||||
$tag[(int) $slot] = new Compound(false, array(
|
|
||||||
"Count" => new Byte("Count", $fields["Count"]),
|
|
||||||
"Slot" => new Short("Slot", $fields["Slot"]),
|
|
||||||
"Damage" => new Short("Damage", $fields["Damage"]),
|
|
||||||
"id" => new String("id", $fields["id"])
|
|
||||||
));
|
|
||||||
}
|
|
||||||
$nbt["Items"] = $tag;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "id":
|
|
||||||
case "Text1":
|
|
||||||
case "Text2":
|
|
||||||
case "Text3":
|
|
||||||
case "Text4":
|
|
||||||
$nbt[$index] = new String($index, $data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "x":
|
|
||||||
case "y":
|
|
||||||
case "z":
|
|
||||||
case "pairx":
|
|
||||||
case "pairz":
|
|
||||||
$nbt[$index] = new Int($index, $data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "BurnTime":
|
|
||||||
case "CookTime":
|
|
||||||
case "MaxTime":
|
|
||||||
$nbt[$index] = new Short($index, $data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch($tile["id"]){
|
|
||||||
case Tile::FURNACE:
|
|
||||||
new Furnace($level, $nbt);
|
|
||||||
break;
|
|
||||||
case Tile::CHEST:
|
|
||||||
new Chest($level, $nbt);
|
|
||||||
break;
|
|
||||||
case Tile::SIGN:
|
|
||||||
new Sign($level, $nbt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unlink($path . "tiles.yml");
|
|
||||||
$level->save(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
/*foreach($blockUpdates->getAll() as $bupdate){
|
|
||||||
Server::getInstance()->api->block->scheduleBlockUpdate(new Position((int) $bupdate["x"], (int) $bupdate["y"], (int) $bupdate["z"], $level), (float) $bupdate["delay"], (int) $bupdate["type"]);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a new level
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param bool $seed
|
|
||||||
* @param bool $generator
|
|
||||||
* @param bool|array $options
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function generateLevel($name, $seed = false, $generator = false, $options = false){
|
|
||||||
if($name == "" or self::levelExists($name)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$options = array();
|
|
||||||
if($options === false and trim(Server::getInstance()->getConfigString("generator-settings", "")) !== ""){
|
|
||||||
$options["preset"] = Server::getInstance()->getConfigString("generator-settings", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if($generator !== false and class_exists($generator)){
|
|
||||||
$generator = new $generator($options);
|
|
||||||
}else{
|
|
||||||
if(strtoupper(Server::getInstance()->getLevelType()) == "FLAT"){
|
|
||||||
$generator = new Flat($options);
|
|
||||||
}else{
|
|
||||||
$generator = new Normal($options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$gen = new WorldGenerator($generator, $name, $seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)) : (int) $seed);
|
|
||||||
$gen->generate();
|
|
||||||
$gen->close();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches if a level exists on file
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function levelExists($name){
|
|
||||||
if($name === ""){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$path = \pocketmine\DATA . "worlds/" . $name . "/";
|
|
||||||
if(self::get($name) === false and !file_exists($path . "level.pmf")){
|
|
||||||
if(file_exists($path)){
|
|
||||||
$level = new LevelImport($path);
|
|
||||||
if($level->import() === false){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct(LevelFormat $level, $name){
|
|
||||||
$this->server = Server::getInstance();
|
|
||||||
$this->level = $level;
|
$this->level = $level;
|
||||||
$this->level->level = $this;
|
$this->level->level = $this;
|
||||||
$this->startTime = $this->time = (int) $this->level->getData("time");
|
$this->startTime = $this->time = (int) $this->level->getData("time");
|
||||||
@ -378,7 +115,20 @@ class Level{
|
|||||||
$gen = Generator::getGenerator($this->level->levelData["generator"]);
|
$gen = Generator::getGenerator($this->level->levelData["generator"]);
|
||||||
$this->generator = new $gen((array) $this->level->levelData["generatorSettings"]);
|
$this->generator = new $gen((array) $this->level->levelData["generatorSettings"]);
|
||||||
$this->generator->init($this, new Random($this->level->levelData["seed"]));
|
$this->generator->init($this, new Random($this->level->levelData["seed"]));
|
||||||
self::$list[$name] = $this;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getAutoSave(){
|
||||||
|
return $this->autoSave === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
|
public function setAutoSave($value){
|
||||||
|
$this->autoSave = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(){
|
public function close(){
|
||||||
@ -394,22 +144,23 @@ class Level{
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function unload($force = false){
|
public function unload($force = false){
|
||||||
if($this === self::getDefault() and $force !== true){
|
if($this === $this->server->getDefaultLevel() and $force !== true){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
console("[INFO] Unloading level \"" . $this->getName() . "\"");
|
console("[INFO] Unloading level \"" . $this->getName() . "\"");
|
||||||
$this->nextSave = PHP_INT_MAX;
|
$this->nextSave = PHP_INT_MAX;
|
||||||
$this->save();
|
$this->save();
|
||||||
|
$defaultLevel = $this->server->getDefaultLevel();
|
||||||
foreach($this->getPlayers() as $player){
|
foreach($this->getPlayers() as $player){
|
||||||
if($this === self::getDefault()){
|
if($this === $defaultLevel or $defaultLevel === null){
|
||||||
$player->close($player->getName() . " has left the game", "forced level unload");
|
$player->close($player->getName() . " has left the game", "forced default level unload");
|
||||||
}else{
|
}elseif($defaultLevel instanceof Level){
|
||||||
$player->teleport(Level::getDefault()->getSafeSpawn());
|
$player->teleport($this->server->getDefaultLevel()->getSafeSpawn());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->close();
|
$this->close();
|
||||||
if($this === self::getDefault()){
|
if($this === $defaultLevel){
|
||||||
self::$default = null;
|
$this->server->setDefaultLevel(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -581,7 +332,7 @@ class Level{
|
|||||||
unset($this->usedChunks[$i]);
|
unset($this->usedChunks[$i]);
|
||||||
LevelFormat::getXZ($i, $X, $Z);
|
LevelFormat::getXZ($i, $X, $Z);
|
||||||
if(!$this->isSpawnChunk($X, $Z)){
|
if(!$this->isSpawnChunk($X, $Z)){
|
||||||
$this->level->unloadChunk($X, $Z, self::$saveEnabled);
|
$this->level->unloadChunk($X, $Z, $this->getAutoSave());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,14 +368,23 @@ class Level{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct(){
|
public function __destruct(){
|
||||||
unset(self::$list[$this->getName()]);
|
|
||||||
if(isset($this->level)){
|
if(isset($this->level)){
|
||||||
$this->save(false, false);
|
$this->save(false, false);
|
||||||
$this->level->closeLevel();
|
$this->level->closeLevel();
|
||||||
unset($this->level);
|
if($this->isLoaded()){
|
||||||
|
unset($this->level);
|
||||||
|
$this->server->unloadLevel($this, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isLoaded(){
|
||||||
|
return $this->level instanceof LevelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $force
|
* @param bool $force
|
||||||
* @param bool $extra
|
* @param bool $extra
|
||||||
@ -635,10 +395,10 @@ class Level{
|
|||||||
if(!isset($this->level)){
|
if(!isset($this->level)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//TODO: save enabled/disabled
|
|
||||||
/*if(self::$saveEnabled === false and $force === false){
|
if($this->getAutoSave() === false and $force === false){
|
||||||
return;
|
return;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
if($extra !== false){
|
if($extra !== false){
|
||||||
$this->doSaveRoundExtra();
|
$this->doSaveRoundExtra();
|
||||||
@ -648,6 +408,8 @@ class Level{
|
|||||||
$this->level->doSaveRound($force);
|
$this->level->doSaveRound($force);
|
||||||
$this->level->saveData();
|
$this->level->saveData();
|
||||||
$this->nextSave = microtime(true) + 45;
|
$this->nextSave = microtime(true) + 45;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doSaveRoundExtra(){
|
protected function doSaveRoundExtra(){
|
||||||
@ -884,7 +646,7 @@ class Level{
|
|||||||
if($player instanceof Player){
|
if($player instanceof Player){
|
||||||
$this->server->getPluginManager()->callEvent($ev = new PlayerInteractEvent($player, $item, $target, $face));
|
$this->server->getPluginManager()->callEvent($ev = new PlayerInteractEvent($player, $item, $target, $face));
|
||||||
if(!$ev->isCancelled()){
|
if(!$ev->isCancelled()){
|
||||||
$target->onUpdate(Level::BLOCK_UPDATE_TOUCH);
|
$target->onUpdate(self::BLOCK_UPDATE_TOUCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,7 +926,7 @@ class Level{
|
|||||||
unset($this->chunkTiles[$index]);
|
unset($this->chunkTiles[$index]);
|
||||||
Cache::remove("world:{$this->name}:$X:$Z");
|
Cache::remove("world:{$this->name}:$X:$Z");
|
||||||
|
|
||||||
return $this->level->unloadChunk($X, $Z, self::$saveEnabled);
|
return $this->level->unloadChunk($X, $Z, $this->getAutoSave());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,18 +23,24 @@ namespace pocketmine\level;
|
|||||||
|
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\pmf\LevelFormat;
|
use pocketmine\pmf\LevelFormat;
|
||||||
use pocketmine\utils\Config;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
|
|
||||||
class WorldGenerator{
|
class WorldGenerator{
|
||||||
private $seed, $level, $path, $random, $generator, $height;
|
private $seed, $level, $path, $random, $generator, $server;
|
||||||
|
|
||||||
public function __construct(Generator $generator, $name, $seed = false, $height = 8){
|
/**
|
||||||
$this->seed = $seed !== false ? (int) $seed : Utils::readInt(Utils::getRandomBytes(4, false));
|
* @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 : Utils::readInt(Utils::getRandomBytes(4, false));
|
||||||
$this->random = new Random($this->seed);
|
$this->random = new Random($this->seed);
|
||||||
$this->height = (int) $height;
|
$this->server = $server;
|
||||||
$this->path = \pocketmine\DATA . "worlds/" . $name . "/";
|
$this->path = $this->server->getDataPath() . "worlds/" . $name . "/";
|
||||||
$this->generator = $generator;
|
$this->generator = $generator;
|
||||||
$level = new LevelFormat($this->path . "level.pmf", array(
|
$level = new LevelFormat($this->path . "level.pmf", array(
|
||||||
"name" => $name,
|
"name" => $name,
|
||||||
@ -43,13 +49,12 @@ class WorldGenerator{
|
|||||||
"spawnX" => 128,
|
"spawnX" => 128,
|
||||||
"spawnY" => 128,
|
"spawnY" => 128,
|
||||||
"spawnZ" => 128,
|
"spawnZ" => 128,
|
||||||
"height" => $this->height,
|
"height" => 8,
|
||||||
"generator" => $this->generator->getName(),
|
"generator" => $this->generator->getName(),
|
||||||
"generatorSettings" => $this->generator->getSettings(),
|
"generatorSettings" => $this->generator->getSettings(),
|
||||||
"extra" => ""
|
"extra" => ""
|
||||||
));
|
));
|
||||||
$blockUpdates = new Config($this->path . "bupdates.yml", Config::YAML);
|
$this->level = new Level($this->server, $level, $name);
|
||||||
$this->level = new Level($level, $name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generate(){
|
public function generate(){
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
namespace pocketmine\network\query;
|
namespace pocketmine\network\query;
|
||||||
|
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
|
|
||||||
@ -73,7 +72,7 @@ class QueryHandler{
|
|||||||
"version" => $this->server->getVersion(),
|
"version" => $this->server->getVersion(),
|
||||||
"server_engine" => $this->server->getName() . " " . $this->server->getPocketMineVersion(),
|
"server_engine" => $this->server->getName() . " " . $this->server->getPocketMineVersion(),
|
||||||
"plugins" => $plist,
|
"plugins" => $plist,
|
||||||
"map" => Level::getDefault()->getName(),
|
"map" => $this->server->getDefaultLevel()->getName(),
|
||||||
"numplayers" => count($this->server->getOnlinePlayers()),
|
"numplayers" => count($this->server->getOnlinePlayers()),
|
||||||
"maxplayers" => $this->server->getMaxPlayers(),
|
"maxplayers" => $this->server->getMaxPlayers(),
|
||||||
"whitelist" => $this->server->hasWhitelist() === true ? "on" : "off",
|
"whitelist" => $this->server->hasWhitelist() === true ? "on" : "off",
|
||||||
@ -131,7 +130,7 @@ class QueryHandler{
|
|||||||
}
|
}
|
||||||
$pk->payload = $this->longData;
|
$pk->payload = $this->longData;
|
||||||
}else{
|
}else{
|
||||||
$pk->payload = $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . Level::getDefault()->getName() . "\x00" . count($this->server->getOnlinePlayers()) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Utils::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00";
|
$pk->payload = $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . $this->server->getDefaultLevel()->getName() . "\x00" . count($this->server->getOnlinePlayers()) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Utils::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00";
|
||||||
}
|
}
|
||||||
$pk->encode();
|
$pk->encode();
|
||||||
$this->server->sendPacket($pk);
|
$this->server->sendPacket($pk);
|
||||||
|
@ -27,10 +27,7 @@ namespace pocketmine\utils;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Utils
|
|
||||||
* Big collection of functions
|
* Big collection of functions
|
||||||
*
|
|
||||||
* @package PocketMine\Utils
|
|
||||||
*/
|
*/
|
||||||
class Utils{
|
class Utils{
|
||||||
const BIG_ENDIAN = 0x00;
|
const BIG_ENDIAN = 0x00;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user