mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 17:29:44 +00:00
New batched UpdateBlockPacket, added Level->sendBlocks()
This commit is contained in:
parent
93a50d08e7
commit
d2bf92c3ed
@ -105,7 +105,6 @@ use pocketmine\network\protocol\SetSpawnPositionPacket;
|
|||||||
use pocketmine\network\protocol\SetTimePacket;
|
use pocketmine\network\protocol\SetTimePacket;
|
||||||
use pocketmine\network\protocol\StartGamePacket;
|
use pocketmine\network\protocol\StartGamePacket;
|
||||||
use pocketmine\network\protocol\TakeItemEntityPacket;
|
use pocketmine\network\protocol\TakeItemEntityPacket;
|
||||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
|
||||||
use pocketmine\network\SourceInterface;
|
use pocketmine\network\SourceInterface;
|
||||||
use pocketmine\permission\PermissibleBase;
|
use pocketmine\permission\PermissibleBase;
|
||||||
use pocketmine\permission\PermissionAttachment;
|
use pocketmine\permission\PermissionAttachment;
|
||||||
@ -1715,21 +1714,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$target = $this->level->getBlock($blockVector);
|
$target = $this->level->getBlock($blockVector);
|
||||||
$block = $target->getSide($packet->face);
|
$block = $target->getSide($packet->face);
|
||||||
|
|
||||||
$pk = new UpdateBlockPacket();
|
$this->level->sendBlocks([$this], [$target, $block]);
|
||||||
$pk->x = $target->x;
|
|
||||||
$pk->y = $target->y;
|
|
||||||
$pk->z = $target->z;
|
|
||||||
$pk->block = $target->getId();
|
|
||||||
$pk->meta = $target->getDamage();
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
|
|
||||||
$pk = new UpdateBlockPacket();
|
|
||||||
$pk->x = $block->x;
|
|
||||||
$pk->y = $block->y;
|
|
||||||
$pk->z = $block->z;
|
|
||||||
$pk->block = $block->getId();
|
|
||||||
$pk->meta = $block->getDamage();
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
break;
|
break;
|
||||||
}elseif($packet->face === 0xff){
|
}elseif($packet->face === 0xff){
|
||||||
if($this->isCreative()){
|
if($this->isCreative()){
|
||||||
@ -1906,13 +1891,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$target = $this->level->getBlock($vector);
|
$target = $this->level->getBlock($vector);
|
||||||
$tile = $this->level->getTile($vector);
|
$tile = $this->level->getTile($vector);
|
||||||
|
|
||||||
$pk = new UpdateBlockPacket();
|
$this->level->sendBlocks([$this], [$target]);
|
||||||
$pk->x = $target->x;
|
|
||||||
$pk->y = $target->y;
|
|
||||||
$pk->z = $target->z;
|
|
||||||
$pk->block = $target->getId();
|
|
||||||
$pk->meta = $target->getDamage();
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
|
|
||||||
if($tile instanceof Spawnable){
|
if($tile instanceof Spawnable){
|
||||||
$tile->spawnTo($this);
|
$tile->spawnTo($this);
|
||||||
|
@ -163,7 +163,6 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
/** @var Block[][] */
|
/** @var Block[][] */
|
||||||
protected $changedBlocks = [];
|
protected $changedBlocks = [];
|
||||||
protected $changedCount = [];
|
|
||||||
|
|
||||||
/** @var ReversePriorityQueue */
|
/** @var ReversePriorityQueue */
|
||||||
private $updateQueue;
|
private $updateQueue;
|
||||||
@ -583,52 +582,22 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->tickChunks();
|
$this->tickChunks();
|
||||||
$this->timings->doTickTiles->stopTiming();
|
$this->timings->doTickTiles->stopTiming();
|
||||||
|
|
||||||
if(count($this->changedCount) > 0){
|
if(count($this->changedBlocks) > 0){
|
||||||
if(count($this->players) > 0){
|
if(count($this->players) > 0){
|
||||||
foreach($this->changedCount as $index => $mini){
|
foreach($this->changedBlocks as $index => $blocks){
|
||||||
for($Y = 0; $Y < 8; ++$Y){
|
if(count($blocks) > 512){
|
||||||
if(($mini & (1 << $Y)) === 0){
|
Level::getXZ($index, $X, $Z);
|
||||||
continue;
|
foreach($this->getUsingChunk($X, $Z) as $p){
|
||||||
}
|
$p->unloadChunk($X, $Z);
|
||||||
if(count($this->changedBlocks[$index][$Y]) < 256){
|
|
||||||
continue;
|
|
||||||
}else{
|
|
||||||
$X = null;
|
|
||||||
$Z = null;
|
|
||||||
Level::getXZ($index, $X, $Z);
|
|
||||||
foreach($this->getUsingChunk($X, $Z) as $p){
|
|
||||||
$p->unloadChunk($X, $Z);
|
|
||||||
}
|
|
||||||
unset($this->changedBlocks[$index][$Y]);
|
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
$this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), $blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->changedCount = [];
|
|
||||||
if(count($this->changedBlocks) > 0){
|
|
||||||
foreach($this->changedBlocks as $index => $mini){
|
|
||||||
foreach($mini as $blocks){
|
|
||||||
/** @var Block $b */
|
|
||||||
foreach($blocks as $b){
|
|
||||||
if(!($b instanceof Block)){
|
|
||||||
$b = $this->getBlock($b);
|
|
||||||
}
|
|
||||||
$pk = new UpdateBlockPacket();
|
|
||||||
$pk->x = $b->x;
|
|
||||||
$pk->y = $b->y;
|
|
||||||
$pk->z = $b->z;
|
|
||||||
$pk->block = $b->getId();
|
|
||||||
$pk->meta = $b->getDamage();
|
|
||||||
Server::broadcastPacket($this->getUsingChunk($b->x >> 4, $b->z >> 4), $pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->changedBlocks = [];
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
$this->changedCount = [];
|
|
||||||
$this->changedBlocks = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->changedBlocks = [];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->processChunkRequest();
|
$this->processChunkRequest();
|
||||||
@ -638,6 +607,23 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->timings->doTick->stopTiming();
|
$this->timings->doTick->stopTiming();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player[] $target
|
||||||
|
* @param Block[] $blocks
|
||||||
|
* @param int $flags
|
||||||
|
*/
|
||||||
|
public function sendBlocks(array $target, array $blocks, $flags = UpdateBlockPacket::FLAG_NONE){
|
||||||
|
$pk = new UpdateBlockPacket();
|
||||||
|
foreach($blocks as $b){
|
||||||
|
if($b === null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk->records[] = [$b->x, $b->z, $b->y, $b->getId(), $b->getDamage(), $flags];
|
||||||
|
}
|
||||||
|
Server::broadcastPacket($target, $pk);
|
||||||
|
}
|
||||||
|
|
||||||
public function clearCache(){
|
public function clearCache(){
|
||||||
$this->blockCache = [];
|
$this->blockCache = [];
|
||||||
}
|
}
|
||||||
@ -1146,7 +1132,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
*
|
*
|
||||||
* @param Vector3 $pos
|
* @param Vector3 $pos
|
||||||
* @param Block $block
|
* @param Block $block
|
||||||
* @param bool $direct
|
* @param bool $direct @deprecated
|
||||||
* @param bool $update
|
* @param bool $update
|
||||||
*
|
*
|
||||||
* @return bool Whether the block has been updated or not
|
* @return bool Whether the block has been updated or not
|
||||||
@ -1169,14 +1155,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($direct === true){
|
if($direct === true){
|
||||||
$pk = new UpdateBlockPacket();
|
$this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY);
|
||||||
$pk->x = $pos->x;
|
|
||||||
$pk->y = $pos->y;
|
|
||||||
$pk->z = $pos->z;
|
|
||||||
$pk->block = $block->getId();
|
|
||||||
$pk->meta = $block->getDamage();
|
|
||||||
|
|
||||||
Server::broadcastPacket($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), $pk);
|
|
||||||
}else{
|
}else{
|
||||||
if(!($pos instanceof Position)){
|
if(!($pos instanceof Position)){
|
||||||
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
|
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
|
||||||
@ -1184,14 +1163,9 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$block->position($pos);
|
$block->position($pos);
|
||||||
if(!isset($this->changedBlocks[$index])){
|
if(!isset($this->changedBlocks[$index])){
|
||||||
$this->changedBlocks[$index] = [];
|
$this->changedBlocks[$index] = [];
|
||||||
$this->changedCount[$index] = 0;
|
|
||||||
}
|
}
|
||||||
$Y = $pos->y >> 4;
|
|
||||||
if(!isset($this->changedBlocks[$index][$Y])){
|
$this->changedBlocks[$index][Level::blockHash($block->x, $block->y, $block->z)] = clone $block;
|
||||||
$this->changedBlocks[$index][$Y] = [];
|
|
||||||
$this->changedCount[$index] |= 1 << $Y;
|
|
||||||
}
|
|
||||||
$this->changedBlocks[$index][$Y][Level::blockHash($block->x, $block->y, $block->z)] = clone $block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($update === true){
|
if($update === true){
|
||||||
@ -1663,13 +1637,8 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
if(!isset($this->changedBlocks[$index = Level::chunkHash($x >> 4, $z >> 4)])){
|
if(!isset($this->changedBlocks[$index = Level::chunkHash($x >> 4, $z >> 4)])){
|
||||||
$this->changedBlocks[$index] = [];
|
$this->changedBlocks[$index] = [];
|
||||||
$this->changedCount[$index] = 0;
|
|
||||||
}
|
}
|
||||||
if(!isset($this->changedBlocks[$index][$Y = $y >> 4])){
|
$this->changedBlocks[$index][Level::blockHash($x, $y, $z)] = new Vector3($x, $y, $z);
|
||||||
$this->changedBlocks[$index][$Y] = [];
|
|
||||||
$this->changedCount[$index] |= 1 << $Y;
|
|
||||||
}
|
|
||||||
$this->changedBlocks[$index][$Y][Level::blockHash($x, $y, $z)] = new Vector3($x, $y, $z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1699,13 +1668,8 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
if(!isset($this->changedBlocks[$index = Level::chunkHash($x >> 4, $z >> 4)])){
|
if(!isset($this->changedBlocks[$index = Level::chunkHash($x >> 4, $z >> 4)])){
|
||||||
$this->changedBlocks[$index] = [];
|
$this->changedBlocks[$index] = [];
|
||||||
$this->changedCount[$index] = 0;
|
|
||||||
}
|
}
|
||||||
if(!isset($this->changedBlocks[$index][$Y = $y >> 4])){
|
$this->changedBlocks[$index][Level::blockHash($x, $y, $z)] = new Vector3($x, $y, $z);
|
||||||
$this->changedBlocks[$index][$Y] = [];
|
|
||||||
$this->changedCount[$index] |= 1 << $Y;
|
|
||||||
}
|
|
||||||
$this->changedBlocks[$index][$Y][Level::blockHash($x, $y, $z)] = new Vector3($x, $y, $z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,11 +28,15 @@ class UpdateBlockPacket extends DataPacket{
|
|||||||
public static $pool = [];
|
public static $pool = [];
|
||||||
public static $next = 0;
|
public static $next = 0;
|
||||||
|
|
||||||
public $x;
|
const FLAG_NONE = 0b0;
|
||||||
public $z;
|
const FLAG_NEIGHBORS = 0b1;
|
||||||
public $y;
|
const FLAG_NOGRAPHIC = 0b100;
|
||||||
public $block;
|
const FLAG_PRIORITY = 0b1000;
|
||||||
public $meta;
|
|
||||||
|
const FLAG_ALL = self::FLAG_NEIGHBORS;
|
||||||
|
const FLAG_ALL_PRIORITY = self::FLAG_NEIGHBORS | self::FLAG_PRIORITY;
|
||||||
|
|
||||||
|
public $records = []; //x, z, y, blockId, blockData, flags
|
||||||
|
|
||||||
public function pid(){
|
public function pid(){
|
||||||
return Info::UPDATE_BLOCK_PACKET;
|
return Info::UPDATE_BLOCK_PACKET;
|
||||||
@ -44,11 +48,14 @@ class UpdateBlockPacket extends DataPacket{
|
|||||||
|
|
||||||
public function encode(){
|
public function encode(){
|
||||||
$this->reset();
|
$this->reset();
|
||||||
$this->putInt($this->x);
|
$this->putInt(count($this->records));
|
||||||
$this->putInt($this->z);
|
foreach($this->records as $r){
|
||||||
$this->putByte($this->y);
|
$this->putInt($r[0]);
|
||||||
$this->putByte($this->block);
|
$this->putInt($r[1]);
|
||||||
$this->putByte($this->meta);
|
$this->putByte($r[2]);
|
||||||
|
$this->putByte($r[3]);
|
||||||
|
$this->putByte(($r[5] << 4) | $r[4]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user