diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c428929f9..34fd4fc14 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -594,6 +594,12 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade Level::getXZ($index, $X, $Z); $this->unloadChunk($X, $Z, $oldLevel); } + + $this->usedChunks = []; + $pk = new SetTimePacket(); + $pk->time = $this->level->getTime(); + $pk->started = $this->level->stopTime == false; + $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); } } @@ -1717,6 +1723,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($this->server->getAutoSave()){ $this->server->saveOfflinePlayerData($this->username, $nbt, true); } + parent::__construct($this->level->getChunk($nbt["Pos"][0] >> 4, $nbt["Pos"][2] >> 4, true), $nbt); $this->loggedIn = true; @@ -1797,9 +1804,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade }else{ $pk = new ContainerSetContentPacket(); $pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE; - foreach(Item::getCreativeItems() as $item){ - $pk->slots[] = clone $item; - } + $pk->slots = Item::getCreativeItems(); $this->dataPacket($pk->setChannel(Network::CHANNEL_PRIORITY)); } @@ -3158,6 +3163,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if(!$this->justCreated){ $newChunk = $this->level->getChunkPlayers($this->x >> 4, $this->z >> 4); + unset($newChunk[$this->getLoaderId()]); + /** @var Player[] $reload */ $reload = []; foreach($this->hasSpawned as $player){ @@ -3169,9 +3176,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } } - //TODO HACK: Minecraft: PE does not like moving a player from old chunks. - //Player entities get stuck in unloaded chunks and the client does not accept position updates. - $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET, Network::CHANNEL_MOVEMENT, $reload); + if($this->chunk !== null and $this->spawned){ + //TODO HACK: Minecraft: PE does not like moving a player from old chunks. + //Player entities get stuck in unloaded chunks and the client does not accept position updates. + $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET, Network::CHANNEL_MOVEMENT, $reload); + } foreach($newChunk as $player){ $this->spawnTo($player); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 4695121ac..3be454089 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1021,13 +1021,6 @@ abstract class Entity extends Location implements Metadatable{ $this->setLevel($targetLevel); $this->level->addEntity($this); - if($this instanceof Player){ - $this->usedChunks = []; - $pk = new SetTimePacket(); - $pk->time = $this->level->getTime(); - $pk->started = $this->level->stopTime == false; - $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); - } $this->chunk = null; return true; diff --git a/src/pocketmine/level/format/mcregion/RegionLoader.php b/src/pocketmine/level/format/mcregion/RegionLoader.php index dff542aaa..94099853e 100644 --- a/src/pocketmine/level/format/mcregion/RegionLoader.php +++ b/src/pocketmine/level/format/mcregion/RegionLoader.php @@ -59,7 +59,9 @@ class RegionLoader{ $this->levelProvider = $level; $this->filePath = $this->levelProvider->getPath() . "region/r.$regionX.$regionZ.mcr"; $exists = file_exists($this->filePath); - touch($this->filePath); + if(!$exists){ + touch($this->filePath); + } $this->filePointer = fopen($this->filePath, "r+b"); stream_set_read_buffer($this->filePointer, 1024 * 16); //16KB stream_set_write_buffer($this->filePointer, 1024 * 16); //16KB @@ -263,10 +265,11 @@ class RegionLoader{ protected function loadLocationTable(){ fseek($this->filePointer, 0); $this->lastSector = 1; - $table = fread($this->filePointer, 4 * 1024 * 2); //1024 records * 4 bytes * 2 times + + $data = unpack("N*", fread($this->filePointer, 4 * 1024 * 2)); //1024 records * 4 bytes * 2 times for($i = 0; $i < 1024; ++$i){ - $index = unpack("N", substr($table, $i << 2, 4))[1]; - $this->locationTable[$i] = [$index >> 8, $index & 0xff, unpack("N", substr($table, 4096 + ($i << 2), 4))[1]]; + $index = $data[$i + 1]; + $this->locationTable[$i] = [$index >> 8, $index & 0xff, $data[1024 + $i + 1]]; if(($this->locationTable[$i][0] + $this->locationTable[$i][1] - 1) > $this->lastSector){ $this->lastSector = $this->locationTable[$i][0] + $this->locationTable[$i][1] - 1; }