mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-21 10:26:38 +00:00
Map importing, entity loading and more
This commit is contained in:
parent
92469a426f
commit
02b2e980eb
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
data/*
|
data/players/*
|
||||||
|
data/maps/*
|
||||||
*.log
|
*.log
|
||||||
*.bat
|
*.bat
|
||||||
server.properties
|
server.properties
|
||||||
|
27
classes/ChunkParser.class.php
Normal file
27
classes/ChunkParser.class.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
-
|
||||||
|
/ \
|
||||||
|
/ \
|
||||||
|
/ POCKET \
|
||||||
|
/ MINECRAFT PHP \
|
||||||
|
|\ @shoghicp /|
|
||||||
|
|. \ / .|
|
||||||
|
| .. \ / .. |
|
||||||
|
| .. | .. |
|
||||||
|
| .. | .. |
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
155
classes/MapInterface.class.php
Normal file
155
classes/MapInterface.class.php
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
-
|
||||||
|
/ \
|
||||||
|
/ \
|
||||||
|
/ POCKET \
|
||||||
|
/ MINECRAFT PHP \
|
||||||
|
|\ @shoghicp /|
|
||||||
|
|. \ / .|
|
||||||
|
| .. \ / .. |
|
||||||
|
| .. | .. |
|
||||||
|
| .. | .. |
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MapInterface{
|
||||||
|
protected $map, $floor, $column, $biome, $material, $biomes;
|
||||||
|
|
||||||
|
function __construct($client){
|
||||||
|
$this->client = $client;
|
||||||
|
$this->map = $this->client->mapParser;
|
||||||
|
$this->floor = method_exists($this->map, "getFloor");
|
||||||
|
$this->column = method_exists($this->map, "getColumn");
|
||||||
|
//$this->biome = method_exists($this->map, "getBiome");
|
||||||
|
//include("misc/materials.php");
|
||||||
|
//$this->material = $material;
|
||||||
|
//include("misc/biomes.php");
|
||||||
|
//$this->biomes = $biomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBiome($x, $z){
|
||||||
|
$x = (int) $x;
|
||||||
|
$z = (int) $z;
|
||||||
|
if($this->biome === true){
|
||||||
|
return $this->map->getBiome($x, $z);
|
||||||
|
}else{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public function getBiomeName($x, $z){
|
||||||
|
$biome = $this->getBiome($x, $z);
|
||||||
|
return isset($this->biomes[$biome]) ? $this->biomes[$biome]:"Unknown";
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public function getBlockName($x, $y, $z){
|
||||||
|
$block = $this->getBlock($x, $y, $z);
|
||||||
|
return isset($this->material[$block[0]]) ? $this->material[$block[0]]:"Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFloor($x, $z, $startY = -1){
|
||||||
|
$x = (int) $x;
|
||||||
|
$z = (int) $z;
|
||||||
|
if($this->floor === true){
|
||||||
|
$map = $this->map->getFloor($x, $z, $startY);
|
||||||
|
return $map;
|
||||||
|
}else{
|
||||||
|
$startY = ((int) $startY) > -1 ? ((int) $startY):HEIGHT_LIMIT - 1;
|
||||||
|
for($y = $startY; $y > 0; --$y){
|
||||||
|
$block = $this->getBlock($x, $y, $z);
|
||||||
|
if(!isset($this->material["nosolid"][$block[0]])){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array($y, $block[0], $block[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changeBlock($x, $y, $z, $block, $metadata = 0){
|
||||||
|
$x = (int) $x;
|
||||||
|
$y = (int) $y;
|
||||||
|
$z = (int) $z;
|
||||||
|
return $this->map->changeBlock($x, $y, $z, $block, $metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBlock($x, $y, $z){
|
||||||
|
$x = (int) $x;
|
||||||
|
$y = (int) $y;
|
||||||
|
$z = (int) $z;
|
||||||
|
return $this->map->getBlock($x, $y, $z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getColumn($x, $z){
|
||||||
|
$x = (int) $x;
|
||||||
|
$z = (int) $z;
|
||||||
|
if($this->column === true){
|
||||||
|
return $this->map->getColumn($x, $z);
|
||||||
|
}else{
|
||||||
|
$zone = $this->getZone($x,0,$z,$x,HEIGHT_LIMIT,$z);
|
||||||
|
$data = array();
|
||||||
|
foreach($zone as $x => $a){
|
||||||
|
foreach($a as $y => $b){
|
||||||
|
foreach($b as $z => $block){
|
||||||
|
$data[$y] = $block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEllipse($x, $y, $z, $rX = 4, $rZ = 4, $rY = 4){
|
||||||
|
$x = (int) $x;
|
||||||
|
$y = (int) $y;
|
||||||
|
$z = (int) $z;
|
||||||
|
$rY = abs((int) $rX);
|
||||||
|
$rY = abs((int) $rZ);
|
||||||
|
$rY = abs((int) $rY);
|
||||||
|
return $this->getZone($x-$rX,max(0,$y-$rY),$z-$rZ,$x+$rX,$y+$rY,$z+$rZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSphere($x, $y, $z, $r=4){
|
||||||
|
$x = (int) $x;
|
||||||
|
$y = (int) $y;
|
||||||
|
$z = (int) $z;
|
||||||
|
$r = abs((int) $r);
|
||||||
|
return $this->getZone($x-$r,max(0,$y-$r),$z-$r,$x+$r,$y+$r,$z+$r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getZone($x1, $y1, $z1, $x2, $y2, $z2){
|
||||||
|
$x1 = (int) $x1;
|
||||||
|
$y1 = (int) $y1;
|
||||||
|
$z1 = (int) $z1;
|
||||||
|
$x2 = (int) $x2;
|
||||||
|
$y2 = (int) $y2;
|
||||||
|
$z2 = (int) $z2;
|
||||||
|
if($x1>$x2 or $y1>$y2 or $z1>$z2){
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$blocks = array();
|
||||||
|
for($x=$x1;$x<=$x2;++$x){
|
||||||
|
$blocks[$x] = array();
|
||||||
|
for($z=$z1;$z<=$z2;++$z){
|
||||||
|
$blocks[$x][$z] = array();
|
||||||
|
for($y=$y1;$y<=$y2;++$y){
|
||||||
|
$blocks[$x][$z][$y] = $this->getBlock($x,$y,$z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -55,7 +55,7 @@ class MinecraftInterface{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function writeDump($pid, $raw, $data, $origin = "client", $ip = "", $port = 0){
|
protected function writeDump($pid, $raw, $data, $origin = "client", $ip = "", $port = 0){
|
||||||
if(LOG === true and DEBUG >= 2){
|
if(LOG === true and DEBUG >= 3){
|
||||||
$p = "[".(microtime(true) - $this->start)."] [".((($origin === "client" and $this->client === true) or ($origin === "server" and $this->client === false)) ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: ".(isset($data["id"]) ? "MC Packet ".$this->dataName[$pid]:$this->name[$pid])." (0x".Utils::strTohex(chr($pid)).") [length ".strlen($raw)."]".PHP_EOL;
|
$p = "[".(microtime(true) - $this->start)."] [".((($origin === "client" and $this->client === true) or ($origin === "server" and $this->client === false)) ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: ".(isset($data["id"]) ? "MC Packet ".$this->dataName[$pid]:$this->name[$pid])." (0x".Utils::strTohex(chr($pid)).") [length ".strlen($raw)."]".PHP_EOL;
|
||||||
$p .= Utils::hexdump($raw);
|
$p .= Utils::hexdump($raw);
|
||||||
if(is_array($data)){
|
if(is_array($data)){
|
||||||
|
102
classes/NBT.class.php
Normal file
102
classes/NBT.class.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class for reading in NBT-format files.
|
||||||
|
*
|
||||||
|
* @author Justin Martin <frozenfire@thefrozenfire.com>
|
||||||
|
* @version 1.0
|
||||||
|
* MODIFIED BY @shoghicp
|
||||||
|
*
|
||||||
|
* Dependencies:
|
||||||
|
* PHP 4.3+ (5.3+ recommended)
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NBT {
|
||||||
|
public $root = array();
|
||||||
|
|
||||||
|
const TAG_END = 0;
|
||||||
|
const TAG_BYTE = 1;
|
||||||
|
const TAG_SHORT = 2;
|
||||||
|
const TAG_INT = 3;
|
||||||
|
const TAG_LONG = 4;
|
||||||
|
const TAG_FLOAT = 5;
|
||||||
|
const TAG_DOUBLE = 6;
|
||||||
|
const TAG_BYTE_ARRAY = 7;
|
||||||
|
const TAG_STRING = 8;
|
||||||
|
const TAG_LIST = 9;
|
||||||
|
const TAG_COMPOUND = 10;
|
||||||
|
|
||||||
|
public function loadFile($filename) {
|
||||||
|
if(is_file($filename)) {
|
||||||
|
$fp = fopen($filename, "rb");
|
||||||
|
}else{
|
||||||
|
trigger_error("First parameter must be a filename", E_USER_WARNING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch(basename($filename, ".dat")){
|
||||||
|
case "level":
|
||||||
|
$version = Utils::readInt(strrev(fread($fp, 4)));
|
||||||
|
$lenght = Utils::readInt(strrev(fread($fp, 4)));
|
||||||
|
break;
|
||||||
|
case "entities":
|
||||||
|
fread($fp, 12);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->traverseTag($fp, $this->root);
|
||||||
|
return end($this->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function traverseTag($fp, &$tree) {
|
||||||
|
if(feof($fp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$tagType = $this->readType($fp, self::TAG_BYTE); // Read type byte.
|
||||||
|
if($tagType == self::TAG_END) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$tagName = $this->readType($fp, self::TAG_STRING);
|
||||||
|
$tagData = $this->readType($fp, $tagType);
|
||||||
|
$tree[] = array("type"=>$tagType, "name"=>$tagName, "value"=>$tagData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readType($fp, $tagType) {
|
||||||
|
switch($tagType) {
|
||||||
|
case self::TAG_BYTE: // Signed byte (8 bit)
|
||||||
|
return Utils::readByte(fread($fp, 1));
|
||||||
|
case self::TAG_SHORT: // Signed short (16 bit, big endian)
|
||||||
|
return Utils::readShort(strrev(fread($fp, 2)));
|
||||||
|
case self::TAG_INT: // Signed integer (32 bit, big endian)
|
||||||
|
return Utils::readInt(strrev(fread($fp, 4)));
|
||||||
|
case self::TAG_LONG: // Signed long (64 bit, big endian)
|
||||||
|
return Utils::readLong(strrev(fread($fp, 8)));
|
||||||
|
case self::TAG_FLOAT: // Floating point value (32 bit, big endian, IEEE 754-2008)
|
||||||
|
return Utils::readFloat(strrev(fread($fp, 4)));
|
||||||
|
case self::TAG_DOUBLE: // Double value (64 bit, big endian, IEEE 754-2008)
|
||||||
|
return Utils::readDouble(strrev(fread($fp, 8)));
|
||||||
|
case self::TAG_BYTE_ARRAY: // Byte array
|
||||||
|
$arrayLength = $this->readType($fp, self::TAG_INT);
|
||||||
|
$array = array();
|
||||||
|
for($i = 0; $i < $arrayLength; $i++) $array[] = $this->readType($fp, self::TAG_BYTE);
|
||||||
|
return $array;
|
||||||
|
case self::TAG_STRING: // String
|
||||||
|
if(!$stringLength = $this->readType($fp, self::TAG_SHORT)) return "";
|
||||||
|
$string = fread($fp, $stringLength); // Read in number of bytes specified by string length, and decode from utf8.
|
||||||
|
return $string;
|
||||||
|
case self::TAG_LIST: // List
|
||||||
|
$tagID = $this->readType($fp, self::TAG_BYTE);
|
||||||
|
$listLength = $this->readType($fp, self::TAG_INT);
|
||||||
|
$list = array("type"=>$tagID, "value"=>array());
|
||||||
|
for($i = 0; $i < $listLength; $i++) {
|
||||||
|
if(feof($fp)) break;
|
||||||
|
$list["value"][] = $this->readType($fp, $tagID);
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
case self::TAG_COMPOUND: // Compound
|
||||||
|
$tree = array();
|
||||||
|
while($this->traverseTag($fp, $tree));
|
||||||
|
return $tree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -28,7 +28,7 @@ the Free Software Foundation, either version 3 of the License, or
|
|||||||
require_once("classes/Session.class.php");
|
require_once("classes/Session.class.php");
|
||||||
|
|
||||||
class PocketMinecraftServer{
|
class PocketMinecraftServer{
|
||||||
var $seed, $protocol, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities;
|
var $seed, $protocol, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities, $mapDir, $mapParser, $map, $level, $tileEntities;
|
||||||
private $database, $interface, $cnt, $events, $version, $serverType, $lastTick;
|
private $database, $interface, $cnt, $events, $version, $serverType, $lastTick;
|
||||||
function __construct($name, $gamemode = 1, $seed = false, $protocol = CURRENT_PROTOCOL, $port = 19132, $serverID = false, $version = CURRENT_VERSION){
|
function __construct($name, $gamemode = 1, $seed = false, $protocol = CURRENT_PROTOCOL, $port = 19132, $serverID = false, $version = CURRENT_VERSION){
|
||||||
$this->port = (int) $port;
|
$this->port = (int) $port;
|
||||||
@ -38,6 +38,12 @@ class PocketMinecraftServer{
|
|||||||
$this->gamemode = (int) $gamemode;
|
$this->gamemode = (int) $gamemode;
|
||||||
$this->version = (int) $version;
|
$this->version = (int) $version;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
$this->mapDir = false;
|
||||||
|
$this->mapParser = false;
|
||||||
|
$this->map = false;
|
||||||
|
$this->level = false;
|
||||||
|
$this->tileEntities = array();
|
||||||
|
$this->entities = array();
|
||||||
$this->custom = array();
|
$this->custom = array();
|
||||||
$this->cnt = 1;
|
$this->cnt = 1;
|
||||||
$this->eidCnt = 1;
|
$this->eidCnt = 1;
|
||||||
@ -61,11 +67,8 @@ class PocketMinecraftServer{
|
|||||||
console("[INFO] Server Name: ".$this->name);
|
console("[INFO] Server Name: ".$this->name);
|
||||||
console("[INFO] Server GUID: ".$this->serverID);
|
console("[INFO] Server GUID: ".$this->serverID);
|
||||||
console("[INFO] Protocol Version: ".$this->protocol);
|
console("[INFO] Protocol Version: ".$this->protocol);
|
||||||
console("[INFO] Seed: ".$this->seed);
|
|
||||||
console("[INFO] Gamemode: ".($this->gamemode === 0 ? "survival":"creative"));
|
|
||||||
console("[INFO] Max Clients: ".$this->maxClients);
|
console("[INFO] Max Clients: ".$this->maxClients);
|
||||||
$this->stop = false;
|
$this->stop = false;
|
||||||
console("[INFO] Server started!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loadEvents(){
|
public function loadEvents(){
|
||||||
@ -157,12 +160,31 @@ class PocketMinecraftServer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loadMap(){
|
||||||
|
$this->level = unserialize(file_get_contents($this->mapDir."level.dat"));
|
||||||
|
console("[INFO] Map: ".$this->level["LevelName"]);
|
||||||
|
$this->seed = $this->level["RandomSeed"];
|
||||||
|
console("[INFO] Seed: ".$this->seed);
|
||||||
|
console("[INFO] Gamemode: ".($this->gamemode === 0 ? "survival":"creative"));
|
||||||
|
console("[DEBUG] Loading entities...");
|
||||||
|
$entities = unserialize(file_get_contents($this->mapDir."entities.dat"));
|
||||||
|
foreach($entities as $entity){
|
||||||
|
$this->entities[$this->eidCnt] = new Entity($this->eidCnt, ENTITY_MOB, $entity["id"], $this);
|
||||||
|
$this->entities[$this->eidCnt]->setPosition($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2], $entity["Rotation"][0], $entity["Rotation"][1]);
|
||||||
|
$this->entities[$this->eidCnt]->setHealth($entity["Health"]);
|
||||||
|
++$this->eidCnt;
|
||||||
|
}
|
||||||
|
console("[DEBUG] Loaded ".count($this->entities)." Entities", true, true, 2);
|
||||||
|
}
|
||||||
|
|
||||||
public function start(){
|
public function start(){
|
||||||
declare(ticks=15);
|
declare(ticks=15);
|
||||||
register_tick_function(array($this, "tick"));
|
register_tick_function(array($this, "tick"));
|
||||||
$this->event("onTick", "tickerFunction", true);
|
$this->event("onTick", "tickerFunction", true);
|
||||||
$this->event("onReceivedPacket", "packetHandler", true);
|
$this->event("onReceivedPacket", "packetHandler", true);
|
||||||
register_shutdown_function(array($this, "close"));
|
register_shutdown_function(array($this, "close"));
|
||||||
|
$this->loadMap();
|
||||||
|
console("[INFO] Server started!");
|
||||||
$this->process();
|
$this->process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ if(!defined("HEX2BIN")){
|
|||||||
define("BIG_ENDIAN", 0x00);
|
define("BIG_ENDIAN", 0x00);
|
||||||
define("LITTLE_ENDIAN", 0x01);
|
define("LITTLE_ENDIAN", 0x01);
|
||||||
define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? BIG_ENDIAN:LITTLE_ENDIAN));
|
define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? BIG_ENDIAN:LITTLE_ENDIAN));
|
||||||
console("[DEBUG] Endianness: ".(ENDIANNESS === LITTLE_ENDIAN ? "Little Endian":"Big Endian"), true, true, 2);
|
|
||||||
|
|
||||||
class Utils{
|
class Utils{
|
||||||
|
|
||||||
|
@ -3,14 +3,15 @@ server-name=PHP Server
|
|||||||
description= This is a Work in Progress custom server.
|
description= This is a Work in Progress custom server.
|
||||||
motd=Welcome to PHP Server
|
motd=Welcome to PHP Server
|
||||||
port=19132
|
port=19132
|
||||||
gamemode=1
|
|
||||||
protocol=CURRENT
|
protocol=CURRENT
|
||||||
seed=false
|
|
||||||
server-id=false
|
|
||||||
server-type=normal
|
|
||||||
max-players=20
|
|
||||||
time-per-second=10
|
|
||||||
white-list=false
|
white-list=false
|
||||||
debug=1
|
debug=1
|
||||||
|
max-players=20
|
||||||
|
server-type=normal
|
||||||
|
time-per-second=10
|
||||||
|
gamemode=1
|
||||||
|
seed=false
|
||||||
|
level-name=false
|
||||||
|
server-id=false
|
||||||
spawn=128.5;100;128.5
|
spawn=128.5;100;128.5
|
||||||
regenerate-config=true
|
regenerate-config=true
|
@ -71,6 +71,9 @@ require_once("classes/Utils.class.php");
|
|||||||
require_once("classes/UDPSocket.class.php");
|
require_once("classes/UDPSocket.class.php");
|
||||||
require_once("classes/Packet.class.php");
|
require_once("classes/Packet.class.php");
|
||||||
require_once("classes/Entity.class.php");
|
require_once("classes/Entity.class.php");
|
||||||
|
require_once("classes/MapInterface.class.php");
|
||||||
|
require_once("classes/ChunkParser.class.php");
|
||||||
|
require_once("classes/NBT.class.php");
|
||||||
require_once("classes/SerializedPacketHandler.class.php");
|
require_once("classes/SerializedPacketHandler.class.php");
|
||||||
require_once("classes/CustomPacketHandler.class.php");
|
require_once("classes/CustomPacketHandler.class.php");
|
||||||
require_once("classes/MinecraftInterface.class.php");
|
require_once("classes/MinecraftInterface.class.php");
|
||||||
|
@ -26,6 +26,31 @@ the Free Software Foundation, either version 3 of the License, or
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
function parseNBTData($data){
|
||||||
|
$x = array();
|
||||||
|
if(isset($data["value"])){
|
||||||
|
return parseNBTData($data["value"]);
|
||||||
|
}
|
||||||
|
foreach($data as $d){
|
||||||
|
if(!isset($d["value"]) and is_array($d) and count($d) == 1){
|
||||||
|
return parseNBTData(array_pop($d));
|
||||||
|
}elseif(!isset($d["value"]) and is_array($d)){
|
||||||
|
$x[] = parseNBTData($d);
|
||||||
|
}elseif(is_array($d["value"]) and isset($d["name"])){
|
||||||
|
$x[$d["name"]] = parseNBTData($d["value"]);
|
||||||
|
}elseif(is_array($d["value"]) and $d["type"] == 10){
|
||||||
|
return parseNBTData($d["value"]);
|
||||||
|
}elseif($d["name"] != ""){
|
||||||
|
$x[$d["name"]] = $d["value"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(count($x) == 0){
|
||||||
|
$x = $data;
|
||||||
|
}
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function arg($name, $default){
|
function arg($name, $default){
|
||||||
global $arguments, $argv;
|
global $arguments, $argv;
|
||||||
if(!isset($arguments)){
|
if(!isset($arguments)){
|
||||||
|
2
data/How To Import Maps.txt
Normal file
2
data/How To Import Maps.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
To import a Pocket Edition Map, drop to the folder "maps"
|
||||||
|
the chunk.dat, level.dat and entities.dat from the savegame file.
|
50
server.php
50
server.php
@ -29,23 +29,25 @@ require_once("common/dependencies.php");
|
|||||||
require_once("classes/PocketMinecraftServer.class.php");
|
require_once("classes/PocketMinecraftServer.class.php");
|
||||||
file_put_contents("packets.log", "");
|
file_put_contents("packets.log", "");
|
||||||
|
|
||||||
|
|
||||||
if(!file_exists(FILE_PATH."white-list.txt")){
|
if(!file_exists(FILE_PATH."white-list.txt")){
|
||||||
console("[WARNING] No white-list.txt found, creating blank file");
|
console("[NOTICE] No white-list.txt found, creating blank file");
|
||||||
file_put_contents(FILE_PATH."white-list.txt", "");
|
file_put_contents(FILE_PATH."white-list.txt", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!file_exists(FILE_PATH."banned-ips.txt")){
|
if(!file_exists(FILE_PATH."banned-ips.txt")){
|
||||||
console("[WARNING] No banned-ips.txt found, creating blank file");
|
console("[NOTICE] No banned-ips.txt found, creating blank file");
|
||||||
file_put_contents(FILE_PATH."banned-ips.txt", "");
|
file_put_contents(FILE_PATH."banned-ips.txt", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!file_exists(FILE_PATH."server.properties")){
|
if(!file_exists(FILE_PATH."server.properties")){
|
||||||
console("[WARNING] No server.properties found, using default settings");
|
console("[NOTICE] No server.properties found, using default settings");
|
||||||
copy(FILE_PATH."common/default.properties", FILE_PATH."server.properties");
|
copy(FILE_PATH."common/default.properties", FILE_PATH."server.properties");
|
||||||
}
|
}
|
||||||
|
|
||||||
@mkdir(FILE_PATH."data/entities/", 0777, true);
|
@mkdir(FILE_PATH."data/players/", 0777, true);
|
||||||
@mkdir(FILE_PATH."data/players/", 0777);
|
@mkdir(FILE_PATH."data/maps/", 0777);
|
||||||
|
|
||||||
|
|
||||||
$prop = file_get_contents(FILE_PATH."server.properties");
|
$prop = file_get_contents(FILE_PATH."server.properties");
|
||||||
$prop = explode("\n", str_replace("\r", "", $prop));
|
$prop = explode("\n", str_replace("\r", "", $prop));
|
||||||
@ -75,6 +77,10 @@ foreach($prop as $line){
|
|||||||
$v = trim($v);
|
$v = trim($v);
|
||||||
$v = $v == "false" ? false:(preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v);
|
$v = $v == "false" ? false:(preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v);
|
||||||
break;
|
break;
|
||||||
|
case "level-name":
|
||||||
|
$v = trim($v);
|
||||||
|
$v = $v == "false" ? false:$v;
|
||||||
|
break;
|
||||||
case "spawn":
|
case "spawn":
|
||||||
$v = explode(";", $v);
|
$v = explode(";", $v);
|
||||||
$v = array("x" => floatval($v[0]), "y" => floatval($v[1]), "z" => floatval($v[2]));
|
$v = array("x" => floatval($v[0]), "y" => floatval($v[1]), "z" => floatval($v[2]));
|
||||||
@ -89,6 +95,39 @@ foreach($prop as $line){
|
|||||||
define("DEBUG", $config["debug"]);
|
define("DEBUG", $config["debug"]);
|
||||||
|
|
||||||
$server = new PocketMinecraftServer($config["server-name"], $config["gamemode"], $config["seed"], $config["protocol"], $config["port"], $config["server-id"]);
|
$server = new PocketMinecraftServer($config["server-name"], $config["gamemode"], $config["seed"], $config["protocol"], $config["port"], $config["server-id"]);
|
||||||
|
|
||||||
|
if(file_exists(FILE_PATH."data/maps/level.dat")){
|
||||||
|
console("[NOTICE] Detected unimported map data. Importing...");
|
||||||
|
$nbt = new NBT();
|
||||||
|
$level = parseNBTData($nbt->loadFile(FILE_PATH."data/maps/level.dat"));
|
||||||
|
console("[DEBUG] Importing map \"".$level["LevelName"]."\" gamemode ".$level["GameType"]." with seed ".$level["RandomSeed"], true, true, 2);
|
||||||
|
unset($level["Player"]);
|
||||||
|
$lvName = $level["LevelName"]."/";
|
||||||
|
@mkdir(FILE_PATH."data/maps/".$lvName, 0777);
|
||||||
|
file_put_contents(FILE_PATH."data/maps/".$lvName."level.dat", serialize($level));
|
||||||
|
$entities = parseNBTData($nbt->loadFile(FILE_PATH."data/maps/entities.dat"));
|
||||||
|
file_put_contents(FILE_PATH."data/maps/".$lvName."entities.dat", serialize($entities["Entities"]));
|
||||||
|
if(!isset($entities["TileEntities"])){
|
||||||
|
$entities["TileEntities"] = array();
|
||||||
|
}
|
||||||
|
file_put_contents(FILE_PATH."data/maps/".$lvName."tileEntities.dat", serialize($entities["TileEntities"]));
|
||||||
|
console("[DEBUG] Imported ".count($entities["Entities"])." Entities and ".count($entities["TileEntities"])." TileEntities", true, true, 2);
|
||||||
|
rename(FILE_PATH."data/maps/chunks.dat", FILE_PATH."data/maps/".$lvName."chunks.dat");
|
||||||
|
unlink(FILE_PATH."data/maps/level.dat");
|
||||||
|
@unlink(FILE_PATH."data/maps/level.dat_old");
|
||||||
|
unlink(FILE_PATH."data/maps/entities.dat");
|
||||||
|
if($config["level-name"] === false){
|
||||||
|
console("[INFO] Setting default level to \"".$level["LevelName"]."\"");
|
||||||
|
$config["level-name"] = $level["LevelName"];
|
||||||
|
$config["gamemode"] = $level["GameType"];
|
||||||
|
$server->gamemode = $config["gamemode"];
|
||||||
|
$server->seed = $level["RandomSeed"];
|
||||||
|
$config["spawn"] = array("x" => $level["SpawnX"], "y" => $level["SpawnY"], "z" => $level["SpawnZ"]);
|
||||||
|
$config["regenerate-config"] = true;
|
||||||
|
}
|
||||||
|
console("[INFO] Map \"".$level["LevelName"]."\" importing done!");
|
||||||
|
unset($level, $entities, $nbt);
|
||||||
|
}
|
||||||
$server->setType($config["server-type"]);
|
$server->setType($config["server-type"]);
|
||||||
$server->timePerSecond = $config["time-per-second"];
|
$server->timePerSecond = $config["time-per-second"];
|
||||||
$server->maxClients = $config["max-players"];
|
$server->maxClients = $config["max-players"];
|
||||||
@ -96,6 +135,7 @@ $server->description = $config["description"];
|
|||||||
$server->motd = $config["motd"];
|
$server->motd = $config["motd"];
|
||||||
$server->spawn = $config["spawn"];
|
$server->spawn = $config["spawn"];
|
||||||
$server->whitelist = $config["white-list"];
|
$server->whitelist = $config["white-list"];
|
||||||
|
$server->mapDir = FILE_PATH."data/maps/".$config["level-name"]."/";
|
||||||
$server->reloadConfig();
|
$server->reloadConfig();
|
||||||
|
|
||||||
if($config["regenerate-config"] == true){
|
if($config["regenerate-config"] == true){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user