diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c5b238b89..537478b9d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -642,11 +642,15 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->usedChunks[Level::chunkHash($x, $z)] = true; $this->chunkLoadCount++; - $pk = new FullChunkDataPacket(); - $pk->chunkX = $x; - $pk->chunkZ = $z; - $pk->data = $payload; - $this->batchDataPacket($pk->setChannel($this->spawned ? Network::CHANNEL_WORLD_CHUNKS : Network::CHANNEL_PRIORITY)); + if($payload instanceof DataPacket){ + $this->dataPacket($payload); + }else{ + $pk = new FullChunkDataPacket(); + $pk->chunkX = $x; + $pk->chunkZ = $z; + $pk->data = $payload; + $this->batchDataPacket($pk->setChannel($this->spawned ? Network::CHANNEL_WORLD_CHUNKS : Network::CHANNEL_PRIORITY)); + } if($this->spawned){ foreach($this->level->getChunkEntities($x, $z) as $entity){ @@ -1333,10 +1337,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->move($dx, $dy, $dz); - if($newPos !== null){ - - } - $diffX = $this->x - $newPos->x; $diffY = $this->y - $newPos->y; $diffZ = $this->z - $newPos->z; @@ -1355,7 +1355,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidMove", [$this->getName()])); } } - }elseif($diff > 0){ + } + + if($diff > 0){ $this->x = $newPos->x; $this->y = $newPos->y; $this->z = $newPos->z; @@ -3376,4 +3378,27 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return $this->isConnected(); } + /** + * @param $chunkX + * @param $chunkZ + * @param $payload + * + * @return DataPacket + */ + public static function getChunkCacheFromData($chunkX, $chunkZ, $payload){ + $pk = new FullChunkDataPacket(); + $pk->chunkX = $chunkX; + $pk->chunkZ = $chunkZ; + $pk->data = $payload; + $pk->encode(); + + $batch = new BatchPacket(); + $batch->payload = zlib_encode($pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel); + + $batch->setChannel(Network::CHANNEL_WORLD_CHUNKS); + $batch->encode(); + $batch->isEncoded = true; + return $batch; + } + } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f18461169..bbe1fed29 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -206,7 +206,7 @@ class Server{ private $network; private $networkCompressionAsync = true; - private $networkCompressionLevel = 7; + public $networkCompressionLevel = 7; private $autoTickRate = true; private $autoTickRateLimit = 20; diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index ce8b30803..1b03c64ac 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -22,6 +22,7 @@ namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Vector3; class Fence extends Transparent{ @@ -52,28 +53,28 @@ class Fence extends Transparent{ protected function recalculateBoundingBox(){ - $flag = $this->canConnect($this->getSide(2)); - $flag1 = $this->canConnect($this->getSide(3)); - $flag2 = $this->canConnect($this->getSide(4)); - $flag3 = $this->canConnect($this->getSide(5)); + $north = $this->canConnect($this->getSide(Vector3::SIDE_NORTH)); + $south = $this->canConnect($this->getSide(Vector3::SIDE_SOUTH)); + $west = $this->canConnect($this->getSide(Vector3::SIDE_WEST)); + $east = $this->canConnect($this->getSide(Vector3::SIDE_EAST)); - $f = $flag2 ? 0 : 0.375; - $f1 = $flag3 ? 1 : 0.625; - $f2 = $flag ? 0 : 0.375; - $f3 = $flag1 ? 1 : 0.625; + $n = $north ? 0 : 0.375; + $s = $south ? 1 : 0.625; + $w = $west ? 0 : 0.375; + $e = $east ? 1 : 0.625; return new AxisAlignedBB( - $this->x + $f, + $this->x + $w, $this->y, - $this->z + $f2, - $this->x + $f1, + $this->z + $n, + $this->x + $e, $this->y + 1.5, - $this->z + $f3 + $this->z + $s ); } public function canConnect(Block $block){ - return (!($block instanceof Fence) and !($block instanceof FenceGate)) ? $block->isSolid() : true; + return ($block instanceof Fence or $block instanceof FenceGate) ? true : $block->isSolid() and !$block->isTransparent(); } } diff --git a/src/pocketmine/event/player/PlayerQuitEvent.php b/src/pocketmine/event/player/PlayerQuitEvent.php index 87fc08336..b8c4f63f4 100644 --- a/src/pocketmine/event/player/PlayerQuitEvent.php +++ b/src/pocketmine/event/player/PlayerQuitEvent.php @@ -48,7 +48,7 @@ class PlayerQuitEvent extends PlayerEvent{ } public function getAutoSave(){ - + return $this->autoSave; } public function setAutoSave($value = true){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 3caf4ae15..6c63103c0 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -88,6 +88,7 @@ use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\String; use pocketmine\network\Network; +use pocketmine\network\protocol\DataPacket; use pocketmine\network\protocol\LevelEventPacket; use pocketmine\network\protocol\SetTimePacket; use pocketmine\network\protocol\UpdateBlockPacket; @@ -144,6 +145,7 @@ class Level implements ChunkManager, Metadatable{ private $blockCache = []; + /** @var DataPacket[] */ private $chunkCache = []; private $cacheChunks = false; @@ -788,11 +790,11 @@ class Level implements ChunkManager, Metadatable{ $this->chunkCache = []; $this->blockCache = []; }else{ - if(count($this->chunkCache) > 1024){ + if(count($this->chunkCache) > 768){ $this->chunkCache = []; } - if(count($this->blockCache) > 65535){ + if(count($this->blockCache) > 2048){ $this->chunkCache = []; } @@ -2180,6 +2182,19 @@ class Level implements ChunkManager, Metadatable{ $this->chunkSendQueue[$index][$player->getLoaderId()] = $player; } + private function sendChunkFromCache($x, $z){ + if(isset($this->chunkSendTasks[$index = Level::chunkHash($x, $z)])){ + foreach($this->chunkSendQueue[$index] as $player){ + /** @var Player $player */ + if($player->isConnected() and isset($player->usedChunks[$index])){ + $player->sendChunk($x, $z, $this->chunkCache[$index]); + } + } + unset($this->chunkSendQueue[$index]); + unset($this->chunkSendTasks[$index]); + } + } + private function processChunkRequest(){ if(count($this->chunkSendQueue) > 0){ $this->timings->syncChunkSendTimer->startTiming(); @@ -2193,7 +2208,7 @@ class Level implements ChunkManager, Metadatable{ Level::getXZ($index, $x, $z); $this->chunkSendTasks[$index] = true; if(isset($this->chunkCache[$index])){ - $this->chunkRequestCallback($x, $z, $this->chunkCache[$index]); + $this->sendChunkFromCache($x, $z); continue; } $this->timings->syncChunkSendPrepareTimer->startTiming(); @@ -2214,7 +2229,10 @@ class Level implements ChunkManager, Metadatable{ $index = Level::chunkHash($x, $z); if(!isset($this->chunkCache[$index]) and $this->cacheChunks and $this->server->getMemoryManager()->canUseChunkCache()){ - $this->chunkCache[$index] = $payload; + $this->chunkCache[$index] = Player::getChunkCacheFromData($x, $z, $payload); + $this->sendChunkFromCache($x, $z); + $this->timings->syncChunkSendTimer->stopTiming(); + return; } if(isset($this->chunkSendTasks[$index])){