mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 16:51:42 +00:00
Chunk unloading
This commit is contained in:
parent
3f532d419c
commit
244fde8143
@ -716,7 +716,6 @@ class BlockAPI{
|
||||
|
||||
public function blockUpdateAround(Position $pos, $type = BLOCK_UPDATE_NORMAL){
|
||||
if(!($pos instanceof Block)){
|
||||
$pos = $pos->floor();
|
||||
$block = $pos->level->getBlock($pos);
|
||||
}else{
|
||||
$block = $pos;
|
||||
@ -731,7 +730,6 @@ class BlockAPI{
|
||||
|
||||
public function blockUpdate(Position $pos, $type = BLOCK_UPDATE_NORMAL){
|
||||
if(!($pos instanceof Block)){
|
||||
$pos = $pos->floor();
|
||||
$block = $pos->level->getBlock($pos);
|
||||
}else{
|
||||
$block = $pos;
|
||||
@ -748,7 +746,7 @@ class BlockAPI{
|
||||
if($delay < 0){
|
||||
return false;
|
||||
}
|
||||
$pos = $pos->floor();
|
||||
|
||||
$index = $pos->x.".".$pos->y.".".$pos->z.".".$pos->level->getName();
|
||||
$delay = microtime(true) + $delay * 0.05;
|
||||
if(!isset($this->scheduledUpdates[$index])){
|
||||
|
@ -62,6 +62,7 @@ class Player{
|
||||
private $chunksOrder = array();
|
||||
private $lag = array(0, 0);
|
||||
private $spawnPosition;
|
||||
private $freedChunks = true;
|
||||
public $itemEnforcement;
|
||||
public $lastCorrect;
|
||||
|
||||
@ -118,7 +119,7 @@ class Player{
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
for($y = 0; $y < 8; ++$y){
|
||||
$d = $x.":".$y.":".$z;
|
||||
if(!isset($this->chunksLoaded[$d])){
|
||||
if(!isset($this->chunksLoaded[$d])){
|
||||
$this->chunksOrder[$d] = $v->distance(new Vector3($x + 0.5, $y / 4, $z + 0.5));
|
||||
}
|
||||
}
|
||||
@ -134,9 +135,19 @@ class Player{
|
||||
$c = key($this->chunksOrder);
|
||||
$d = $this->chunksOrder[$c];
|
||||
if($c === null or $d > $this->server->api->getProperty("view-distance")){
|
||||
if($this->freedChunks === false){
|
||||
foreach($this->chunksOrder as $c => $d){
|
||||
$id = explode(":", $c);
|
||||
$X = $id[0];
|
||||
$Z = $id[2];
|
||||
$this->level->freeChunk($X, $Z, $this);
|
||||
}
|
||||
$this->freedChunks = true;
|
||||
}
|
||||
$this->server->schedule(50, array($this, "getNextChunk"));
|
||||
return false;
|
||||
}
|
||||
$this->freedChunks = false;
|
||||
array_shift($this->chunksOrder);
|
||||
$this->chunksLoaded[$c] = true;
|
||||
$id = explode(":", $c);
|
||||
@ -147,6 +158,7 @@ class Player{
|
||||
$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(
|
||||
@ -233,6 +245,7 @@ class Player{
|
||||
$this->eventHandler(new Container("You have been kicked. Reason: ".$reason), "server.chat");
|
||||
$this->directDataPacket(MC_DISCONNECT);
|
||||
$this->sendBuffer();
|
||||
$this->level->freeAllChunks($this);
|
||||
$this->buffer = null;
|
||||
unset($this->buffer);
|
||||
$this->recovery = null;
|
||||
@ -589,7 +602,7 @@ class Player{
|
||||
$this->entity->setPosition($pos, $yaw, $pitch);
|
||||
$this->entity->resetSpeed();
|
||||
$this->entity->updateLast();
|
||||
$this->entity->calculateVelocity();
|
||||
$this->entity->calculateVelocity();
|
||||
if($pos instanceof Position and $pos->level !== $this->level){
|
||||
foreach($this->server->api->entity->getAll($this->level) as $e){
|
||||
if($e !== $this->entity){
|
||||
@ -603,6 +616,7 @@ class Player{
|
||||
));
|
||||
}
|
||||
}
|
||||
$this->level->freeAllChunks($this);
|
||||
$this->level = $pos->level;
|
||||
$this->chunksLoaded = array();
|
||||
$this->server->api->entity->spawnToAll($this->level, $this->eid);
|
||||
|
@ -39,6 +39,24 @@ class Level{
|
||||
$this->server->schedule(15, array($this, "checkThings"), array(), true);
|
||||
$this->server->event("server.close", array($this, "save"));
|
||||
$this->name = $name;
|
||||
$this->usedChunks = array();
|
||||
}
|
||||
|
||||
public function useChunk($X, $Z, Player $player){
|
||||
if(!isset($this->usedChunks[$X.".".$Z])){
|
||||
$this->usedChunks[$X.".".$Z] = array();
|
||||
}
|
||||
$this->usedChunks[$X.".".$Z][$player->CID] = true;
|
||||
$this->level->loadChunk($X, $Z);
|
||||
}
|
||||
|
||||
public function freeAllChunks(Player $player){
|
||||
foreach($this->usedChunks as $i => $c){
|
||||
unset($this->usedChunks[$i][$player->CID]);
|
||||
}
|
||||
}
|
||||
public function freeChunk($X, $Z, Player $player){
|
||||
unset($this->usedChunks[$X.".".$Z][$player->CID]);
|
||||
}
|
||||
|
||||
public function checkThings(){
|
||||
@ -47,6 +65,15 @@ class Level{
|
||||
if($this->server->api->dhandle("time.change", array("level" => $this, "time" => $time)) !== false){
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
foreach($this->usedChunks as $i => $c){
|
||||
if(count($c) === 0){
|
||||
unset($this->usedChunks[$i]);
|
||||
$X = explode(".", $i);
|
||||
$Z = array_pop($X);
|
||||
$this->level->unloadChunk((int) $X, (int) $Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
@ -68,10 +95,14 @@ class Level{
|
||||
return BlockAPI::get($b[0], $b[1], new Position($pos->x, $pos->y, $pos->z, $this));
|
||||
}
|
||||
|
||||
public function setBlock(Position $pos, Block $block, $update = true, $tiles = false){
|
||||
public function setBlock(Vector3 $pos, Block $block, $update = true, $tiles = false){
|
||||
if((($pos instanceof Position) and $pos->level !== $this) or $pos->x < 0 or $pos->y < 0 or $pos->z < 0){
|
||||
return false;
|
||||
}elseif($this->server->api->dhandle("block.change", array(
|
||||
}elseif(!($pos instanceof Position)){
|
||||
$pos = new Position($pos->x, $pos->y, $pos->z, $this);
|
||||
}
|
||||
|
||||
if($this->server->api->dhandle("block.change", array(
|
||||
"position" => $pos,
|
||||
"block" => $block,
|
||||
)) !== false){
|
||||
|
@ -66,7 +66,7 @@ class SmallTreeObject extends TreeObject{
|
||||
for($xx = -$xzRadius; $xx < ($xzRadius + 1); ++$xx){
|
||||
for($zz = -$xzRadius; $zz < ($xzRadius + 1); ++$zz){
|
||||
if((abs($xx) != $xzRadius or abs($zz) != $xzRadius) and $yRadius != 0){
|
||||
$level->setBlock(new Vector3($x + $xx, $y + $yy, $z + $zz), new LeavesBlck($this->type));
|
||||
$level->setBlock(new Vector3($x + $xx, $y + $yy, $z + $zz), new LeavesBlock($this->type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user