Chunk parsing...

This commit is contained in:
Shoghi Cervantes Pueyo 2012-12-08 23:51:39 +01:00
parent cef574015f
commit cf3aa79c54
7 changed files with 127 additions and 7 deletions

View File

@ -32,9 +32,10 @@ class ChunkParser{
private $raw = b"";
var $sectorLenght = 4096; //16 * 16 * 16
var $chunkLenght = 86016; //21 * $sectorLenght
var $map;
function __construct(){
$map = array();
}
public function loadFile($file){
@ -67,8 +68,68 @@ class ChunkParser{
return substr($this->raw, $this->getOffset($X, $Z) + $add, $this->chunkLenght - $add);
}
public function getColumn($X, $Z){
public function parseChunk($X, $Z){
$X = (int) $X;
$Z = (int) $Z;
$offset = $this->getOffset($X, $Z);
$len = Utils::readLInt(substr($this->raw, $offset, 4));
$offset += 4;
$chunk = array(
0 => array(), //Block
1 => array(), //Data
2 => array(), //SkyLight
3 => array(), //BlockLight
);
foreach($chunk as $section => &$data){
$l = $section === 0 ? 128:64;
for($i = 0; $i < 256; ++$i){
$data[] = substr($this->raw, $offset, $l);
$offset += $l;
}
}
return $chunk;
}
public function getRawColumn($offset, $l){
$data = "";
if($l === 128){
$data = substr($this->raw, $offset, $l);
}elseif($l === 64){
for($i = 0; $i < $l; ++$i){
$d = ord($this->raw{$offset + $i});
$data .= chr($d >> 4);
$data .= chr($d & 0x0F);
}
}
return $data;
}
public function parseColumn($offset, $l){
$data = array();
if($l === 128){
for($i = 0; $i < $l; ++$i){
$data[] = ord($this->raw{$offset + $i});
}
}elseif($l === 64){
for($i = 0; $i < $l; ++$i){
$d = ord($this->raw{$offset + $i});
$data[] = $d >> 4;
$data[] = $d & 0x0F;
}
}
return $data;
}
public function loadMap(){
console("[DEBUG] Loading chunks...", true, true, 2);
for($x = 0; $x < 16; ++$x){
$this->map[$x] = array();
for($z = 0; $z < 16; ++$z){
$this->map[$x][$z] = $this->parseChunk($x, $z);
console("[INTERNAL] Chunk X ".$x." Z ".$z." loaded", true, true, 3);
}
}
console("[DEBUG] Chunks loaded!", true, true, 2);
}
public function getBlock($x, $y, $z){
@ -77,8 +138,14 @@ class ChunkParser{
$z = (int) $z;
$X = $x >> 4;
$Z = $z >> 4;
$block = $this->getOffset($X, $Z) + 4 + (($x << 6) + $y + ($z << 10));
$meta = $this->getOffset($X, $Z) + 4 + (($x << 6) + $y + ($z << 10));
$aX = $x - ($X << 4);
$aZ = $z - ($Z << 4);
$index = $aZ + ($aX << 4);
console("[DEBUG] $x $y $z | $X $Z $index", true, true, 2);
var_dump($this->map[$X][$Z][0][$index]);
$block = ord($this->map[$X][$Z][0][$index]{$y});
//$meta = $this->getOffset($X, $Z) + 4 + (($x << 6) + $y + ($z << 10));
return array($block, 0);
}
}

View File

@ -207,6 +207,25 @@ class CustomPacketHandler{
));
}
break;
case MC_ADD_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["type"] = ord($this->get(1));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["type"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::hexToStr("000000020000ffd30000");//Utils::writeInt(0);
/*$this->raw .= Utils::writeShort(0);
$this->raw .= Utils::writeShort(0);
$this->raw .= Utils::writeShort(0);*/
}
break;
case MC_REMOVE_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
@ -286,6 +305,21 @@ class CustomPacketHandler{
$this->raw .= Utils::writeFloat($this->data["pitch"]);
}
break;
case MC_PLACE_BLOCK:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["y"] = ord($this->get(1));
$this->data["face"] = Utils::readByte($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= chr($this->data["y"]);
$this->raw .= chr($this->data["face"]);
}
break;
case MC_REMOVE_BLOCK:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
@ -348,6 +382,16 @@ class CustomPacketHandler{
$this->raw .= Utils::writeShort($this->data["meta"]);
}
break;
case MC_SET_ENTITY_DATA:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeMetadata(array(
));
}
break;
case MC_SET_HEALTH: //SetHealth
if($this->c === false){
$this->data["health"] = ord($this->get(1));

View File

@ -174,7 +174,7 @@ class PocketMinecraftServer{
console("[ERROR] Couldn't load the map \"".$this->level["LevelName"]."\"!", true, true, 0);
$this->map = false;
}else{
$this->map->loadMap();
}
console("[INFO] Loading entities...");
$entities = unserialize(file_get_contents($this->mapDir."entities.dat"));

View File

@ -325,12 +325,12 @@ class Session{
array(
"id" => MC_ADD_ITEM_ENTITY,
"eid" => $entity->eid,
"type" => $entity->type,
"x" => $entity->position["x"],
"y" => $entity->position["y"],
"z" => $entity->position["z"],
"block" => 10,
"meta" => 0,
"stack" => 1,
),
));
++$this->counter[0];

View File

@ -46,6 +46,7 @@ define("MC_START_GAME", 0x87);
define("MC_ADD_PLAYER", 0x89);
define("MC_ADD_ENTITY", 0x8c);
define("MC_REMOVE_ENTITY", 0x8d);
define("MC_ADD_ITEM_ENTITY", 0x8e);

View File

@ -46,6 +46,7 @@ $dataName = array(
MC_ADD_PLAYER => "AddPlayer",
MC_ADD_ENTITY => "AddEntity",
MC_REMOVE_ENTITY => "RemoveEntity",
MC_ADD_ITEM_ENTITY => "AddItemEntity",
@ -55,6 +56,7 @@ $dataName = array(
MC_MOVE_PLAYER => "MovePlayer",
MC_PLACE_BLOCK => "PlaceBlock",
MC_REMOVE_BLOCK => "RemoveBlock",
MC_UPDATE_BLOCK => "UpdateBlock",
MC_REQUEST_CHUNK => "RequestChunk",
MC_CHUNK_DATA => "ChunkData",

View File

@ -224,7 +224,7 @@ function serverCommands(){
$config["gamemode"] = (int) $s;
$server->gamemode = $config["gamemode"];
console("[INFO] Gamemode changed to ".$server->gamemode);
loadConfig();
loadConfig(true);
break;
case "say":
$s = implode(" ", $params);
@ -339,6 +339,12 @@ function serverCommands(){
));
}
break;
case "block":
foreach($server->clients as $client){
$b = $server->map->getBlock($client->entity->position["x"], $client->entity->position["y"] - 2, $client->entity->position["z"]);
console("[INFO] EID ".$client->eid." is over block ".$b[0].":".$b[1]);
}
break;
case "list":
console("[INFO] Player list:");
foreach($server->clients as $c){