diff --git a/src/API/TileEntityAPI.php b/src/API/TileEntityAPI.php new file mode 100644 index 000000000..51d82d998 --- /dev/null +++ b/src/API/TileEntityAPI.php @@ -0,0 +1,93 @@ +server = $server; + } + + public function get($eid){ + if(isset($this->server->tileEntities[$eid])){ + return $this->server->tileEntities[$eid]; + } + return false; + } + + public function init(){ + + } + + public function getAll(){ + return $this->server->tileEntities; + } + + public function add($class, $x, $y, $z, $data = array()){ + $id = $this->tCnt++; + $this->server->tileEntities[$id] = new TileEntity($this->server, $id, $class, $x, $y, $z, $data); + return $this->server->tileEntities[$id]; + } + + public function spawnTo($id, $player){ + $t = $this->get($id); + if($t === false){ + return false; + } + $t->spawn($player); + } + + public function spawnToAll($id){ + $t = $this->get($id); + if($t === false){ + return false; + } + foreach($this->server->api->player->getAll() as $player){ + if($player->eid !== false){ + $t->spawn($player); + } + } + } + + public function spawnAll($player){ + foreach($this->getAll() as $t){ + $t->spawn($player); + } + } + + public function remove($id){ + if(isset($this->server->tileEntities[$id])){ + $t = $this->server->tileEntities[$eid]; + $this->server->tileEntities[$id] = null; + unset($this->server->tileEntities[$id]); + $t->closed = true; + $t->close(); + $this->server->query("DELETE FROM tileentities WHERE ID = ".$id.";"); + $t = null; + unset($t); + } + } +} \ No newline at end of file diff --git a/src/classes/Player.php b/src/classes/Player.php index afea1de5b..169129d3c 100644 --- a/src/classes/Player.php +++ b/src/classes/Player.php @@ -386,7 +386,7 @@ class Player{ break; } $this->loggedIn = true; - $this->username = str_replace(array("\x00", "/", " ", "\r", "\n"), array("", "-", "_", "", ""), $data["username"]); + $this->username = str_replace(array("\x00", "/", " ", "\r", "\n", '"', "'"), array("", "-", "_", "", "", "", ""), $data["username"]); if($this->username == ""){ $this->close("bad username", false); break; @@ -499,6 +499,8 @@ class Player{ } break; case MC_REQUEST_CHUNK: + $x = $data["x"] * 16; + $z = $data["z"] * 16; $this->actionQueue(' $max = max(1, floor(($this->MTU - 16 - 255) / 192)); $chunk = $this->server->api->level->getOrderedChunk('.$data["x"].', '.$data["z"].', $max); @@ -509,6 +511,12 @@ class Player{ "data" => $d, ), true); } + $tiles = $this->server->query("SELECT * FROM tileentities WHERE x >= '.$x.' AND x < '.($x + 16).' AND z >= '.$z.' AND z < '.($z + 16).';"); + if($tiles !== false and $tiles !== true){ + while(($tile = $tiles->fetchArray(SQLITE3_ASSOC)) !== false){ + $this->server->api->tileentity->spawnTo($tile["ID"], "'.$this->username.'"); + } + } '); console("[INTERNAL] Chunk X ".$data["x"]." Z ".$data["z"]." requested", true, true, 3); break; diff --git a/src/classes/PocketMinecraftServer.php b/src/classes/PocketMinecraftServer.php index e2487ddf1..d3bc63c7a 100644 --- a/src/classes/PocketMinecraftServer.php +++ b/src/classes/PocketMinecraftServer.php @@ -26,6 +26,7 @@ the Free Software Foundation, either version 3 of the License, or */ class PocketMinecraftServer{ + public $tCnt; var $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $spawn, $entities, $mapDir, $mapName, $map, $levelData, $tileEntities; private $database, $interface, $evCnt, $handCnt, $events, $handlers, $serverType, $lastTick, $ticker; @@ -45,7 +46,8 @@ class PocketMinecraftServer{ console("[INFO] Loading database..."); $this->startDatabase(); $this->doTick = false; - $this->api = false; + $this->api = false; + $this->tCnt = 1; $this->mapDir = false; $this->mapName = false; $this->events = array(); @@ -57,12 +59,12 @@ class PocketMinecraftServer{ $this->tileEntities = array(); $this->entities = array(); $this->custom = array(); - $this->evCnt = 0; - $this->handCnt = 0; + $this->evCnt = 1; + $this->handCnt = 1; $this->eidCnt = 1; $this->maxClients = 20; $this->schedule = array(); - $this->scheduleCnt = 0; + $this->scheduleCnt = 1; $this->description = ""; $this->whitelist = false; $this->clients = array(); @@ -113,7 +115,7 @@ class PocketMinecraftServer{ //$this->query("PRAGMA secure_delete = OFF;"); $this->query("CREATE TABLE players (clientID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE);"); $this->query("CREATE TABLE entities (EID INTEGER PRIMARY KEY, type NUMERIC, class NUMERIC, name TEXT, x NUMERIC, y NUMERIC, z NUMERIC, yaw NUMERIC, pitch NUMERIC, health NUMERIC);"); - $this->query("CREATE TABLE metadata (EID INTEGER PRIMARY KEY, name TEXT, value TEXT);"); + $this->query("CREATE TABLE tileentities (ID INTEGER PRIMARY KEY, class NUMERIC, x NUMERIC, y NUMERIC, z NUMERIC);"); $this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);"); $this->query("CREATE TABLE events (ID INTEGER PRIMARY KEY, name TEXT);"); $this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);"); @@ -327,7 +329,21 @@ class PocketMinecraftServer{ } } } - console("[DEBUG] Loaded ".count($this->entities)." Entities", true, true, 2); + $tiles = unserialize(file_get_contents($this->mapDir."tileEntities.dat")); + foreach($tiles as $tile){ + if(!isset($tile["id"])){ + break; + } + $class = false; + switch($tile["id"]){ + case "Sign": + $class = TILE_SIGN; + break; + } + if($class !== false){ + $t = $this->api->tileentity->add($class, $tile["x"], $tile["y"], $tile["z"], $tile); + } + } $this->action(1000000 * 60 * 15, '$this->api->chat->broadcast("Forcing save...");$this->save();'); } } diff --git a/src/classes/world/TileEntity.php b/src/classes/world/TileEntity.php index 6086062d6..10af394f2 100644 --- a/src/classes/world/TileEntity.php +++ b/src/classes/world/TileEntity.php @@ -25,12 +25,93 @@ the Free Software Foundation, either version 3 of the License, or */ -class TileEntity extends stdClass{ - private $server; - function __construct(PocketMinecraftServer $server){ +define("TILE_SIGN", 0); + +class TileEntity extends stdClass{ + public $name; + public $id; + public $x; + public $y; + public $z; + public $data; + public $class; + public $attach; + public $metadata; + public $closed; + private $server; + function __construct(PocketMinecraftServer $server, $id, $class, $x, $y, $z, $data = array()){ + $this->server = $server; + $this->class = (int) $class; + $this->data = $data; + $this->closed = false; + $this->name = ""; + $this->id = (int) $id; + $this->x = (int) $x; + $this->y = (int) $y; + $this->z = (int) $z; + $this->server->query("INSERT OR REPLACE INTO tileentities (ID, class, x, y, z) VALUES (".$this->id.", ".$this->class.", ".$this->x.", ".$this->y.", ".$this->z.");"); + $update = false; + switch($this->class){ + case TILE_SIGN: + break; + } + if($update === true){ + $this->server->schedule(40, array($this, "update"), array(), true); + } + } + + public function update(){ + if($this->closed === true){ + return false; + } + } + + public function spawn($player){ + if(!($player instanceof Player)){ + $player = $this->server->api->player->get($player); + } + switch($this->class){ + case TILE_SIGN: + $player->dataPacket(MC_SIGN_UPDATE, array( + "x" => $this->x, + "y" => $this->y, + "z" => $this->z, + "line0" => $this->data["Text1"], + "line1" => $this->data["Text2"], + "line2" => $this->data["Text3"], + "line3" => $this->data["Text4"], + ), true); + break; + } + } + + public function close(){ + if($this->closed === false){ + $this->closed = true; + $this->server->api->entity->remove($this->eid); + } + } + + public function __destruct(){ + $this->close(); + } + + public function getName(){ + return $this->name; + } + + public function setName($name){ + $this->name = $name; + $this->server->query("UPDATE entities SET name = '".str_replace("'", "", $this->name)."' WHERE EID = ".$this->eid.";"); + } + + + public function setPosition($x, $y, $z){ + $this->x = (int) $x; + $this->y = (int) $y; + $this->z = (int) $z; + $this->server->query("UPDATE entities SET x = ".$this->x.", y = ".$this->y.", z = ".$this->z." WHERE EID = ".$this->eid.";"); } } - -?> \ No newline at end of file