Skip to content

Commit

Permalink
feat: Dimension changing (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benedikt05 authored May 9, 2024
1 parent ee44aa9 commit 3799ba5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 9 deletions.
17 changes: 15 additions & 2 deletions src/pocketmine/Player.php
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,17 @@ public function changeDimension(int $dimension, Vector3 $position = null, bool $
$pk->dimension = $dimension;
$pk->position = $position ?? $this;
$pk->respawn = $respawn;
//$this->sendDataPacket($pk);
$this->sendDataPacket($pk);

//send this to the client??
$pk = new PlayerActionPacket();
$pk->entityRuntimeId = $this->id;
$pk->action = PlayerActionPacket::ACTION_DIMENSION_CHANGE_ACK;
$pk->x = $pk->y = $pk->z = 0;
$pk->resultX = $pk->resultY = $pk->resultZ = 0;
$pk->face = 0;

$this->sendDataPacket($pk);
}

public function getMaxInPortalTime() : int{
Expand Down Expand Up @@ -2543,7 +2553,7 @@ protected function completeLoginSequence(){
$pk->pitch = $this->pitch;
$pk->yaw = $this->yaw;
$pk->seed = -1;
$pk->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly
$pk->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", $this->getLevel()->getDimension());
$pk->gameRules = $this->level->getGameRules()->getRules();
$pk->worldGamemode = Player::getClientFriendlyGamemode($this->server->getGamemode());
$pk->difficulty = $this->level->getDifficulty();
Expand Down Expand Up @@ -3384,6 +3394,9 @@ public function handlePlayerAction(PlayerActionPacket $packet) : bool{
case PlayerActionPacket::ACTION_STOP_ITEM_USE_ON:
//this has no obvious use and seems only used for analytics in vanilla - ignore it
break;
case PlayerActionPacket::ACTION_DIMENSION_CHANGE_ACK:
$this->sendPlayStatus(PlayStatusPacket::PLAYER_SPAWN);
break;
default:
$this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName());
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/pocketmine/level/Level.php
Original file line number Diff line number Diff line change
Expand Up @@ -2731,7 +2731,7 @@ private function processChunkRequest() : void{
}
assert($chunk->getX() === $x and $chunk->getZ() === $z, "Chunk coordinate mismatch: expected $x $z, but chunk has coordinates " . $chunk->getX() . " " . $chunk->getZ() . ", did you forget to clone a chunk before setting?");

$this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($this, $x, $z, $chunk));
$this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($this, $x, $z, $this->getDimension(), $chunk));
$this->chunkSendTasks[$index] = $task;

$this->timings->syncChunkSendPrepareTimer->stopTiming();
Expand Down
11 changes: 7 additions & 4 deletions src/pocketmine/level/format/Chunk.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\Player;
use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile;
Expand Down Expand Up @@ -867,14 +868,16 @@ public function collectGarbage() : void{
/**
* Serializes the chunk for sending to players
*/
public function networkSerialize(?string $networkSerializedTiles) : string{
public function networkSerialize(?string $networkSerializedTiles, int $dimensionId) : string{
$result = "";
$subChunkCount = $this->getSubChunkSendCount();

//TODO: HACK! fill in fake subchunks to make up for the new negative space client-side
for($y = 0; $y < 4; ++$y){
$result .= chr(8); //subchunk version 8
$result .= chr(0); //0 layers - client will treat this as all-air
if($dimensionId === DimensionIds::OVERWORLD){
for($y = 0; $y < 4; ++$y){
$result .= chr(8); //subchunk version 8
$result .= chr(0); //0 layers - client will treat this as all-air
}
}
for($y = 0; $y < $subChunkCount; ++$y){
$result .= $this->subChunks[$y]->networkSerialize();
Expand Down
6 changes: 4 additions & 2 deletions src/pocketmine/level/format/io/ChunkRequestTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ class ChunkRequestTask extends AsyncTask{
protected $chunkX;
/** @var int */
protected $chunkZ;
protected int $dimensionId;

/** @var int */
protected $compressionLevel;

public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){
public function __construct(Level $level, int $chunkX, int $chunkZ, int $dimensionId, Chunk $chunk){
$this->levelId = $level->getId();
$this->compressionLevel = $level->getServer()->networkCompressionLevel;

Expand All @@ -58,11 +59,12 @@ public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk

$this->chunkX = $chunkX;
$this->chunkZ = $chunkZ;
$this->dimensionId = $dimensionId;
}

public function onRun(){
$chunk = Chunk::fastDeserialize($this->chunk);
$pk = LevelChunkPacket::create($this->chunkX, $this->chunkZ, DimensionIds::OVERWORLD, $chunk->getSubChunkSendCount() + 4, false, null, $chunk->networkSerialize($this->tiles));
$pk = LevelChunkPacket::create($this->chunkX, $this->chunkZ, $this->dimensionId, $chunk->getSubChunkSendCount() + ($this->dimensionId === DimensionIds::OVERWORLD ? 4 : 0), false, null, $chunk->networkSerialize($this->tiles, $this->dimensionId));

$batch = new BatchPacket();
$batch->addPacket($pk);
Expand Down

0 comments on commit 3799ba5

Please sign in to comment.