New PMF level (uses NBT Entity and TileEntity)

This commit is contained in:
Shoghi Cervantes 2014-02-26 17:15:31 +01:00
parent 38c5174da7
commit 3864630bcd
9 changed files with 82 additions and 44 deletions

View File

@ -38,10 +38,10 @@ class BanAPI{
}
public function init(){
$this->whitelist = new Config(DATA_PATH."white-list.txt", Config::LIST);//Open whitelist list file
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", Config::LIST);//Open Banned IPs list file
$this->banned = new Config(DATA_PATH."banned.txt", Config::LIST);//Open Banned Usernames list file
$this->ops = new Config(DATA_PATH."ops.txt", Config::LIST);//Open list of OPs
$this->whitelist = new Config(DATA_PATH."white-list.txt", Config::ENUM);//Open whitelist list file
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", Config::ENUM);//Open Banned IPs list file
$this->banned = new Config(DATA_PATH."banned.txt", Config::ENUM);//Open Banned Usernames list file
$this->ops = new Config(DATA_PATH."ops.txt", Config::ENUM);//Open list of OPs
$this->server->api->console->register("banip", "<add|remove|list|reload> [IP|player]", array($this, "commandHandler"));
$this->server->api->console->register("ban", "<add|remove|list|reload> [username]", array($this, "commandHandler"));
$this->server->api->console->register("kick", "<player> [reason ...]", array($this, "commandHandler"));
@ -211,7 +211,7 @@ class BanAPI{
$output .= "Player \"$user\" added to white-list\n";
break;
case "reload":
$this->whitelist = new Config(DATA_PATH."white-list.txt", Config::LIST);
$this->whitelist = new Config(DATA_PATH."white-list.txt", Config::ENUM);
break;
case "list":
$output .= "White-list: ".implode(", ", $this->whitelist->getAll(true))."\n";
@ -256,7 +256,7 @@ class BanAPI{
$output .= "IP \"$ip\" added to ban list\n";
break;
case "reload":
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", Config::LIST);
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", Config::ENUM);
break;
case "list":
$output .= "IP ban list: ".implode(", ", $this->bannedIPs->getAll(true))."\n";
@ -294,7 +294,7 @@ class BanAPI{
$output .= "Player \"$user\" added to ban list\n";
break;
case "reload":
$this->banned = new Config(DATA_PATH."banned.txt", Config::LIST);
$this->banned = new Config(DATA_PATH."banned.txt", Config::ENUM);
break;
case "list":
$output .= "Ban list: ".implode(", ", $this->banned->getAll(true))."\n";

View File

@ -96,7 +96,7 @@ require_once(FILE_PATH."/src/math/Vector3.php");
require_once(FILE_PATH."/src/world/Position.php");
require_once(FILE_PATH."/src/pmf/PMF.php");
require_all(FILE_PATH . "src/");
require_all(FILE_PATH . "src/", array("entity", "Entity.php")); //REMOVE LATER!!!!
$inc = get_included_files();
$inc[] = array_shift($inc);

View File

@ -80,11 +80,11 @@ function kill($pid){
}
}
function require_all($path, &$count = 0){
function require_all($path, array $ignore = array(), &$count = 0){
$dir = dir($path."/");
$dirs = array();
while(false !== ($file = $dir->read())){
if($file !== "." and $file !== ".."){
if($file !== "." and $file !== ".." and !in_array($file, $ignore, true)){
if(!is_dir($path.$file) and strtolower(substr($file, -3)) === "php"){
require_once($path.$file);
++$count;
@ -94,7 +94,7 @@ function require_all($path, &$count = 0){
}
}
foreach($dirs as $dir){
require_all($dir, $count);
require_all($dir, $ignore, $count);
}
}
@ -134,7 +134,7 @@ function arg($name, $default = false){
}
}
function arguments ( $args ){
function arguments($args){
if(!is_array($args)){
$args = array();
}

View File

@ -57,6 +57,7 @@ class NBT{
$this->offset = 0;
$this->buffer = $buffer;
$this->data = $this->readTag();
$this->buffer = b"";
}
public function write(){
@ -221,5 +222,4 @@ class NBT{
$this->data = $data;
}
}
>>>>>>> origin/master
}

View File

@ -49,7 +49,7 @@ class NBTTag_Compound extends NamedNBTTag{
$tag = $nbt->readTag();
if($tag instanceof NamedNBTTag and $tag->getName() !== ""){
$this->value[$tag->getName()] = $tag;
}else{
}elseif(!($tag instanceof NBTTag_End)){
$this->value[] = $tag;
}
}while(!($tag instanceof NBTTag_End) and !$nbt->feof());
@ -57,7 +57,10 @@ class NBTTag_Compound extends NamedNBTTag{
public function write(NBT $nbt){
foreach($this->value as $tag){
$nbt->writeTag($tag);
if(!($tag instanceof NBTTag_End)){
$nbt->writeTag($tag);
}
}
$nbt->writeTag(new NBTTag_End);
}
}

View File

@ -20,8 +20,9 @@
*/
class PMFLevel extends PMF{
const VERSION = 0x01;
const DEFLATE_LEVEL = 9;
const VERSION = 2;
const ZLIB_LEVEL = 6;
const ZLIB_ENCODING = 15; //15 = zlib, -15 = raw deflate, 31 = gzip
public $level;
public $levelData = array();
@ -90,7 +91,7 @@ class PMFLevel extends PMF{
$this->write(Utils::writeShort(strlen($this->levelData["generator"])).$this->levelData["generator"]);
$settings = serialize($this->levelData["generatorSettings"]);
$this->write(Utils::writeShort(strlen($settings)).$settings);
$extra = gzdeflate($this->levelData["extra"], PMFLevel::DEFLATE_LEVEL);
$extra = zlib_encode($this->levelData["extra"], PMFLevel::ZLIB_ENCODING, PMFLevel::ZLIB_LEVEL);
$this->write(Utils::writeShort(strlen($extra)).$extra);
}
@ -135,11 +136,14 @@ class PMFLevel extends PMF{
$this->levelData["generatorSettings"] = unserialize($this->read(Utils::readShort($this->read(2), false)));
}
$this->levelData["extra"] = @gzinflate($this->read(Utils::readShort($this->read(2), false)));
$this->levelData["extra"] = @zlib_decode($this->read(Utils::readShort($this->read(2), false)));
if($this->levelData["version"] === 0){
$this->upgrade_From0_To1();
}
if($this->levelData["version"] === 1){
$this->upgrade_From1_To2();
}
}
private function upgrade_From0_To1(){
@ -162,12 +166,32 @@ class PMFLevel extends PMF{
gzclose($chunkOld);
@unlink($oldPath);
}
$this->levelData["version"] = 0x01;
$this->levelData["version"] = 1;
$this->levelData["generator"] = "NormalGenerator";
$this->levelData["generatorSettings"] = "";
$this->saveData();
}
private function upgrade_From1_To2(){
console("[NOTICE] Old PMF Level format version #1 detected, upgrading to version #2");
$nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new NBTTag_Compound("", array(
new NBTTag_Compound("Entities", array()),
new NBTTag_Compound("TileEntities", array())
)));
$namedtag = $nbt->write();
$namedtag = Utils::writeInt(strlen($namedtag)) . $namedtag;
foreach(glob(dirname($this->file)."/chunks/*/*.*.pmc") as $chunkFile){
$oldChunk = zlib_decode(file_get_contents($chunkFile));
$newChunk = substr($oldChunk, 0, 5);
$newChunk .= $namedtag;
$newChunk .= substr($oldChunk, 5);
file_put_contents($chunkFile, zlib_encode($newChunk, PMFLevel::ZLIB_ENCODING, PMFLevel::ZLIB_LEVEL));
}
$this->levelData["version"] = 2;
$this->saveData();
}
public static function getIndex($X, $Z){
return ($Z << 16) | ($X < 0 ? (~--$X & 0x7fff) | 0x8000 : $X & 0x7fff);
}
@ -233,29 +257,39 @@ class PMFLevel extends PMF{
return true;
}
$chunk = @gzopen($path, "rb");
$chunk = file_get_contents($path);
if($chunk === false){
return false;
}
$chunk = zlib_decode($chunk);
$offset = 0;
$this->chunkInfo[$index] = array(
0 => ord(gzread($chunk, 1)),
1 => Utils::readInt(gzread($chunk, 4)),
0 => ord($chunk{0}),
1 => Utils::readInt(substr($chunk, 1, 4)),
);
$offset += 5;
$len = Utils::readInt(substr($chunk, $offset, 4));
$offset += 4;
$nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->read(substr($chunk, $offset, $len));
$this->chunkInfo[2] = $nbt;
$offset += $len;
$this->chunks[$index] = array();
$this->chunkChange[$index] = array(-1 => false);
for($Y = 0; $Y < $this->chunkInfo[$index][0]; ++$Y){
$t = 1 << $Y;
if(($this->chunkInfo[$index][0] & $t) === $t){
// 4096 + 2048 + 2048, Block Data, Meta, Light
if(strlen($this->chunks[$index][$Y] = gzread($chunk, 8192)) < 8192){
if(strlen($this->chunks[$index][$Y] = substr($chunk, $offset, 8192)) < 8192){
console("[NOTICE] Empty corrupt chunk detected [$X,$Z,:$Y], recovering contents", true, true, 2);
$this->fillMiniChunk($X, $Z, $Y);
}
$offset += 8192;
}else{
$this->chunks[$index][$Y] = false;
}
}
@gzclose($chunk);
if($this->isGenerating === 0 and !$this->isPopulated($X, $Z)){
$this->populateChunk($X, $Z);
}
@ -561,16 +595,18 @@ class PMFLevel extends PMF{
}
$this->chunkChange[$index][$Y] = 0;
}
$chunk = @gzopen($path, "wb".PMFLevel::DEFLATE_LEVEL);
gzwrite($chunk, chr($bitmap));
gzwrite($chunk, Utils::writeInt($this->chunkInfo[$index][1]));
$chunk = b"";
$chunk .= chr($bitmap);
$chunk .= Utils::writeInt($this->chunkInfo[$index][1]);
$namedtag = $this->chunkInfo[$index][2]->write();
$chunk .= Utils::writeInt(strlen($namedtag)).$namedtag;
for($Y = 0; $Y < 8; ++$Y){
$t = 1 << $Y;
if(($bitmap & $t) === $t){
gzwrite($chunk, $this->chunks[$index][$Y]);
$chunk .= $this->chunks[$index][$Y];
}
}
gzclose($chunk);
file_put_contents($path, zlib_encode($chunk, PMFLevel::ZLIB_ENCODING, PMFLevel::ZLIB_LEVEL));
$this->chunkChange[$index][-1] = false;
$this->chunkInfo[$index][0] = $bitmap;
return true;

View File

@ -29,12 +29,13 @@
class Config{
const DETECT = -1; //Detect by file extension
const PROPERTIES = 0; // .properties
const CNF = PROPERTIES; // .cnf
const CNF = Config::PROPERTIES; // .cnf
const JSON = 1; // .js, .json
const YAML = 2; // .yml, .yaml
//const EXPORT = 3; // .export, .xport
const SERIALIZED = 4; // .sl
const LIST = 5; // .txt, .list
const ENUM = 5; // .txt, .list, .enum
const ENUMERATION = Config::ENUM;
/**
* @var array
@ -66,8 +67,9 @@ class Config{
//"xport" => Config::EXPORT,
"sl" => Config::SERIALIZED,
"serialize" => Config::SERIALIZED,
"txt" => Config::LIST,
"list" => Config::LIST,
"txt" => Config::ENUM,
"list" => Config::ENUM,
"enum" => Config::ENUM,
);
/**
@ -136,7 +138,7 @@ class Config{
case Config::SERIALIZED:
$this->config = @unserialize($content);
break;
case Config::LIST:
case Config::ENUM:
$this->parseList($content);
break;
default:
@ -182,7 +184,7 @@ class Config{
case Config::SERIALIZED:
$content = @serialize($this->config);
break;
case Config::LIST:
case Config::ENUM:
$content = implode("\r\n", array_keys($this->config));
break;
}

View File

@ -122,7 +122,7 @@ LICENSE;
if($op === ""){
echo "[!] ".$this->lang->op_warning."\n";
}else{
$ops = new Config(DATA_PATH."ops.txt", Config::LIST);
$ops = new Config(DATA_PATH."ops.txt", Config::ENUM);
$ops->set($op, true);
$ops->save();
}

View File

@ -364,16 +364,14 @@ class Tile extends Position{
new NBTTag_Int("y", (int) $this->y),
new NBTTag_Int("z", (int) $this->z),
new NBTTag_Int("pairx", (int) $this->data["pairx"]),
new NBTTag_Int("pairz", (int) $this->data["pairz"]),
new NBTTag_End
new NBTTag_Int("pairz", (int) $this->data["pairz"])
)));
}else{
$nbt->setData(new NBTTag_Compound("", array(
new NBTTag_String("id", $this->class),
new NBTTag_Int("x", (int) $this->x),
new NBTTag_Int("y", (int) $this->y),
new NBTTag_Int("z", (int) $this->z),
new NBTTag_End
new NBTTag_Int("z", (int) $this->z)
)));
}
@ -394,8 +392,7 @@ class Tile extends Position{
new NBTTag_String("id", $this->class),
new NBTTag_Int("x", (int) $this->x),
new NBTTag_Int("y", (int) $this->y),
new NBTTag_Int("z", (int) $this->z),
new NBTTag_End
new NBTTag_Int("z", (int) $this->z)
)));
$pk = new EntityDataPacket;
$pk->x = $this->x;