From 063f44c3306bcef767f479dcd773c30a179feff4 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Pueyo Date: Thu, 13 Dec 2012 02:49:04 +0100 Subject: [PATCH] LevelAPI and pre-map r --- classes/API/LevelAPI.php | 73 +++++++++++++++++++++++++ classes/API/ServerAPI.php | 2 + classes/ChunkParser.class.php | 5 +- classes/CustomPacketHandler.class.php | 8 +-- classes/PocketMinecraftServer.class.php | 4 +- classes/Session.class.php | 43 ++++++++++----- pstruct/5.php | 2 +- pstruct/dataName.php | 2 +- 8 files changed, 115 insertions(+), 24 deletions(-) create mode 100644 classes/API/LevelAPI.php diff --git a/classes/API/LevelAPI.php b/classes/API/LevelAPI.php new file mode 100644 index 000000000..ef5edc9e4 --- /dev/null +++ b/classes/API/LevelAPI.php @@ -0,0 +1,73 @@ +server = $server; + $this->map = $this->server->map; + if($this->map !== false){ + $this->active = true; + } + } + + private function check(){ + if($this->active === false and $this->server->map === false){ + return false; + } + $this->active = true; + return true; + } + + public function getChunk($X, $Z){ + /*if($this->check() and isset($this->map->map[$X][$Z])){ + return $this->map->map[$X][$Z]; + }*/ + return false; + } + + public function getOrderedChunk($X, $Z, $columnsPerPacket = 2){ + $columnsPerPacket = max(1, (int) $columnsPerPacket); + $c = $this->getChunk($X, $Z); + if($c === false){ + return array(str_repeat("\x00", 256)); + } + $ordered = array(); + for($i = 0;$i < 0xff; ){ + $ordered[$i] = str_repeat("\x00", $i); + for($j = 0; $j < $columnsPerPacket; ++$j){ + $ordered[$i] .= "\xff"; + for($k = 0; $k < 8; ++$k){ + $ordered[$i] .= substr($c[$i][0], $k << 4, 16); //Block data + $ordered[$i] .= substr($c[$i][1], $k << 3, 8); //Meta data + } + ++$i; + } + } + return $ordered; + } +} \ No newline at end of file diff --git a/classes/API/ServerAPI.php b/classes/API/ServerAPI.php index 162b5066a..937715b08 100644 --- a/classes/API/ServerAPI.php +++ b/classes/API/ServerAPI.php @@ -80,6 +80,8 @@ class ServerAPI extends stdClass{ //Yay! I can add anything to this class in run $this->server->mapName = $this->getProperty("level-name"); $this->server->mapDir = FILE_PATH."data/maps/".$this->getProperty("level-name")."/"; $this->loadProperties(); + $this->server->loadMap(); + //Autoload all default APIs console("[INFO] Loading default APIs"); $dir = dir(FILE_PATH."classes/API/"); diff --git a/classes/ChunkParser.class.php b/classes/ChunkParser.class.php index 644db75d0..c9db0c817 100644 --- a/classes/ChunkParser.class.php +++ b/classes/ChunkParser.class.php @@ -53,8 +53,9 @@ class ChunkParser{ } private function getOffset($X, $Z){ - $info = $this->getOffsetPosition($X, $Z); - return 4096 + (($info[1] * $info[0]) << 12) + (($info[2] * $data[0]) << 16); + //$info = $this->getOffsetPosition($X, $Z); + //return 4096 + (($info[1] * $info[0]) << 12) + (($info[2] * $data[0]) << 16); + return 4096 + (($X * 21) << 12) + (($Z * 21) << 16); } public function getChunk($X, $Z, $header = true){ diff --git a/classes/CustomPacketHandler.class.php b/classes/CustomPacketHandler.class.php index 574850d08..10ca279db 100644 --- a/classes/CustomPacketHandler.class.php +++ b/classes/CustomPacketHandler.class.php @@ -121,7 +121,7 @@ class CustomPacketHandler{ $this->raw .= Utils::writeLong($this->data["session"]); } break; - case MC_CLIENT_DISCONNECT: + case MC_DISCONNECT: //null break; case 0x18: @@ -379,17 +379,17 @@ class CustomPacketHandler{ $this->data["z"] = Utils::readInt($this->get(4)); }else{ $this->raw .= Utils::writeInt($this->data["x"]); - $this->raw .= Utils::writeInt($this->data["y"]); + $this->raw .= Utils::writeInt($this->data["z"]); } break; case MC_CHUNK_DATA: if($this->c === false){ $this->data["x"] = Utils::readInt($this->get(4)); $this->data["z"] = Utils::readInt($this->get(4)); - $this->data["data"] = $this->get(256); + $this->data["data"] = $this->get(true); }else{ $this->raw .= Utils::writeInt($this->data["x"]); - $this->raw .= Utils::writeInt($this->data["y"]); + $this->raw .= Utils::writeInt($this->data["z"]); $this->raw .= $this->data["data"]; } break; diff --git a/classes/PocketMinecraftServer.class.php b/classes/PocketMinecraftServer.class.php index 57bbbdfe8..7e9f2ed17 100644 --- a/classes/PocketMinecraftServer.class.php +++ b/classes/PocketMinecraftServer.class.php @@ -196,11 +196,12 @@ class PocketMinecraftServer extends stdClass{ } } - private function loadMap(){ + public function loadMap(){ if($this->mapName !== false and trim($this->mapName) !== ""){ $this->level = unserialize(file_get_contents($this->mapDir."level.dat")); console("[INFO] Map: ".$this->level["LevelName"]); $this->time = (int) $this->level["Time"]; + $this->seed = (int) $this->level["RandomSeed"]; $this->level["Time"] = &$this->time; console("[INFO] Time: ".$this->time); console("[INFO] Seed: ".$this->seed); @@ -246,7 +247,6 @@ class PocketMinecraftServer extends stdClass{ $this->event("onTick", array($this, "tickerFunction")); $this->event("onReceivedPacket", "packetHandler", true); register_shutdown_function(array($this, "close")); - $this->loadMap(); console("[INFO] Server started!"); $this->process(); } diff --git a/classes/Session.class.php b/classes/Session.class.php index 69d639daf..4c220f73b 100644 --- a/classes/Session.class.php +++ b/classes/Session.class.php @@ -81,6 +81,14 @@ class Session{ $this->server->trigger("onChat", $this->username." left the game"); } console("[INFO] Session with ".$this->ip.":".$this->port." Client ID ".$this->clientID." closed due to ".$reason); + $this->send(0x84, array( + $this->counter[0], + 0x00, + array( + "id" => MC_DISCONNECT, + ), + )); + ++$this->counter[0]; $this->server->api->player->remove($this->CID); } @@ -247,7 +255,7 @@ class Session{ $this->send(0xc0, array(1, true, $data[0])); } switch($data["id"]){ - case MC_CLIENT_DISCONNECT: + case MC_DISCONNECT: $this->close("client disconnect"); break; case MC_CLIENT_CONNECT: @@ -367,23 +375,30 @@ class Session{ //$this->server->trigger("onChat", $this->username." joined the game"); break; case MC_MOVE_PLAYER: - $this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["yaw"], $data["pitch"]); - $this->server->trigger("onEntityMove", $this->eid); + if(is_object($this->entity)){ + $this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["yaw"], $data["pitch"]); + $this->server->trigger("onEntityMove", $this->eid); + } break; case MC_PLAYER_EQUIPMENT: console("[DEBUG] EID ".$this->eid." has now ".$data["block"].":".$data["meta"]." in their hands!", true, true, 2); break; - case MC_REQUEST_CHUNK: - $this->send(0x84, array( - $this->counter[0], - 0x00, - array( - "id" => MC_CHUNK_DATA, - "x" => $data["x"], - "z" => $data["z"], - "data" => str_repeat("\x00", 256), - ), - )); + case MC_REQUEST_CHUNK: + $chunk = $this->server->api->level->getOrderedChunk($data["x"], $data["z"]); + foreach($chunk as $d){ + $this->send(0x84, array( + $this->counter[0], + 0x00, + array( + "id" => MC_CHUNK_DATA, + "x" => $data["x"], + "z" => $data["z"], + "data" => $d, + ), + )); + } + + ++$this->counter[0]; console("[DEBUG] Chunk X ".$data["x"]." Z ".$data["z"]." requested", true, true, 2); break; diff --git a/pstruct/5.php b/pstruct/5.php index 18677d77a..be3cd7071 100644 --- a/pstruct/5.php +++ b/pstruct/5.php @@ -35,7 +35,7 @@ define("MC_SERVER_HANDSHAKE", 0x10); define("MC_CLIENT_HANDSHAKE", 0x13); -define("MC_CLIENT_DISCONNECT", 0x15); +define("MC_DISCONNECT", 0x15); define("MC_LOGIN", 0x82); define("MC_LOGIN_STATUS", 0x83); diff --git a/pstruct/dataName.php b/pstruct/dataName.php index 078b0ad80..e8ae41858 100644 --- a/pstruct/dataName.php +++ b/pstruct/dataName.php @@ -33,7 +33,7 @@ $dataName = array( MC_CLIENT_HANDSHAKE => "ClientHandshake", - MC_CLIENT_DISCONNECT => "ClientDisconnect", + MC_DISCONNECT => "Disconnect", 0x18 => "Unknown",