diff --git a/src/Player.php b/src/Player.php index e58d744e96..eaf3ee5c17 100644 --- a/src/Player.php +++ b/src/Player.php @@ -39,7 +39,7 @@ class Player{ private $clientID; private $ip; private $port; - private $counter = array(0, 0, 0); + private $counter = array(0, 0, 0, 0, 0); private $username; private $iusername; private $eid = false; @@ -65,6 +65,7 @@ class Player{ private $freedChunks = true; public $itemEnforcement; public $lastCorrect; + private $bigCnt; public function __get($name){ if(isset($this->{$name})){ @@ -74,6 +75,7 @@ class Player{ } public function __construct($clientID, $ip, $port, $MTU){ + $this->bigCnt = 0; $this->MTU = $MTU; $this->server = ServerAPI::request(); $this->lastBreak = microtime(true); @@ -163,18 +165,10 @@ class Player{ $x = $X << 4; $z = $Z << 4; $y = $Y << 4; - $MTU = $this->MTU - 16; $this->level->useChunk($X, $Z, $this); - $chunk = $this->level->getOrderedMiniChunk($X, $Z, $Y, $MTU); - foreach($chunk as $d){ - $this->dataPacket(MC_CHUNK_DATA, array( - "x" => $X, - "z" => $Z, - "data" => $d, - )); - } + $this->directBigRawPacket(MC_CHUNK_DATA, Utils::writeInt($X) . Utils::writeInt($Z) . $this->level->getOrderedMiniChunk($X, $Z, $Y)); - $tiles = $this->server->query("SELECT ID FROM tileentities WHERE spawnable = 1 AND x >= ".($x - 1)." AND x < ".($x + 17)." AND z >= ".($z - 1)." AND z < ".($z + 17)." AND y >= ".($y - 1)." AND y < ".($y + 17).";"); + $tiles = $this->server->query("SELECT ID FROM tileentities WHERE spawnable = 1 AND level = '".$this->level->getName()."' AND x >= ".($x - 1)." AND x < ".($x + 17)." AND z >= ".($z - 1)." AND z < ".($z + 17)." AND y >= ".($y - 1)." AND y < ".($y + 17).";"); if($tiles !== false and $tiles !== true){ while(($tile = $tiles->fetchArray(SQLITE3_ASSOC)) !== false){ $this->server->api->tileentity->spawnTo($tile["ID"], $this); @@ -1368,6 +1362,40 @@ class Player{ $this->nextBuffer = microtime(true) + 0.1; } + public function directBigRawPacket($id, $buffer){ + if($this->connected === false){ + return false; + } + $data = array( + "id" => false, + "sendtime" => microtime(true), + "raw" => "", + ); + $size = $this->MTU - 32; + $buffer = str_split(chr($id).$buffer, $size); + $h = strrev(Utils::writeTriad($this->counter[4]++))."\x00".Utils::writeInt(count($buffer)).Utils::writeShort($this->bigCnt); + $this->counter[4] %= 0x1000000; + $this->bigCnt = ($this->bigCnt + 1) % 0x10000; + foreach($buffer as $i => $buf){ + $data["raw"] = Utils::writeShort(strlen($buf) << 3).strrev(Utils::writeTriad($this->counter[3]++)).$h.Utils::writeInt($i).$buf; + $this->counter[3] %= 0x1000000; + $count = $this->counter[0]++; + if(count($this->recovery) >= 1024){ + reset($this->recovery); + $k = key($this->recovery); + $this->recovery[$k] = null; + unset($this->recovery[$k]); + end($this->recovery); + } + $this->recovery[$count] = $data; + $this->send(0x80, array( + $count, + 0x70, + $data, + )); + } + } + public function directDataPacket($id, $data = array(), $count = false){ if($this->connected === false){ return false; @@ -1375,8 +1403,7 @@ class Player{ $data["id"] = $id; $data["sendtime"] = microtime(true); if($count === false){ - $count = $this->counter[0]; - ++$this->counter[0]; + $count = $this->counter[0]++; if(count($this->recovery) >= 1024){ reset($this->recovery); $k = key($this->recovery); diff --git a/src/material/block/liquid/StillWater.php b/src/material/block/liquid/StillWater.php index 3bcf5e9153..fbbc5f9077 100644 --- a/src/material/block/liquid/StillWater.php +++ b/src/material/block/liquid/StillWater.php @@ -25,9 +25,14 @@ the Free Software Foundation, either version 3 of the License, or */ -class StillWaterBlock extends LiquidBlock{ + +/***REM_START***/ +require_once("Water.php"); +/***REM_END***/ + +class StillWaterBlock extends WaterBlock{ public function __construct($meta = 0){ - parent::__construct(STILL_WATER, $meta, "Still Water"); + LiquidBlock::__construct(STILL_WATER, $meta, "Still Water"); } } \ No newline at end of file diff --git a/src/material/block/liquid/Water.php b/src/material/block/liquid/Water.php index 980fceb6bc..23c04bac8b 100644 --- a/src/material/block/liquid/Water.php +++ b/src/material/block/liquid/Water.php @@ -30,4 +30,26 @@ class WaterBlock extends LiquidBlock{ parent::__construct(WATER, $meta, "Water"); } + public function onUpdate($type){ + return false; + $level = $this->meta & 0x03; + if($type !== BLOCK_UPDATE_NORMAL or $level === 0){ + return false; + } + + $falling = $this->meta >> 3; + $down = $this->getSide(0); + if($down->isFlowable){ + $this->level->setBlock($down, new WaterBlock(9), true); //1001 + return; + }elseif($down instanceof WaterBlock and $down->getMetadata() === 9){ + $level = 1; + } + + $up = $this->getSide(1); + if($up instanceof WaterBlock){ + + } + } + } \ No newline at end of file diff --git a/src/network/Packet.php b/src/network/Packet.php index 21166ff45d..8b24f2a76c 100644 --- a/src/network/Packet.php +++ b/src/network/Packet.php @@ -102,7 +102,7 @@ class Packet{ case 0x40: $reply = new CustomPacketHandler($this->data[2]["id"], "", $this->data[2], true); $this->addRaw(Utils::writeShort((strlen($reply->raw) + 1) << 3)); - $this->addRaw(Utils::writeTriad(strrev($this->data[2]["count"]))); + $this->addRaw(strrev(Utils::writeTriad($this->data[2]["count"]))); $this->addRaw(chr($this->data[2]["id"])); $this->addRaw($reply->raw); break; @@ -117,6 +117,11 @@ class Packet{ $this->addRaw($this->data[2]["raw"]); } break; + default: + if($this->data[2]["id"] === false){ + $this->addRaw($this->data[2]["raw"]); + } + break; } break; case "magic": @@ -251,6 +256,8 @@ class Packet{ $offset += 2; $splitIndex = Utils::readInt(substr($raw, $offset, 4)); $offset += 4; + //error! no split packets allowed! + break; }else{ $splitCount = 0; $splitID = 0; diff --git a/src/world/Level.php b/src/world/Level.php index a053c8c60e..76ce12b871 100644 --- a/src/world/Level.php +++ b/src/world/Level.php @@ -215,23 +215,15 @@ class Level{ return $this->level->unloadChunk($X, $Z); } - public function getOrderedMiniChunk($X, $Z, $Y, $MTU){ + public function getOrderedMiniChunk($X, $Z, $Y){ $raw = $this->level->getMiniChunk($X, $Z, $Y); - $ordered = array(); - $i = 0; - $ordered[$i] = ""; - $cnt = 0; + $ordered = ""; $flag = chr(1 << $Y); for($j = 0; $j < 256; ++$j){ - if((strlen($ordered[$i]) + 16 + 8 + 1) > $MTU){ - ++$i; - $ordered[$i] = str_repeat("\x00", $cnt); - } $index = $j << 5; - $ordered[$i] .= $flag; - $ordered[$i] .= substr($raw, $index, 16); - $ordered[$i] .= substr($raw, $index + 16, 8); - ++$cnt; + $ordered .= $flag; + $ordered .= substr($raw, $index, 16); + $ordered .= substr($raw, $index + 16, 8); } return $ordered; }