Skip to content

Commit

Permalink
Implement TypeConvertor chunk packet buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
dries-c committed Jul 19, 2023
1 parent fb57181 commit 3a8a0f4
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 18 deletions.
3 changes: 1 addition & 2 deletions src/block/Bell.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,7 @@ public function ring(int $faceHit) : void{
$world->addSound($this->position, new BellRingSound());
$tile = $world->getTile($this->position);
if($tile instanceof TileBell){
$players = $world->getViewersForPosition($this->position);
TypeConverter::broadcastByTypeConverter($players, fn($typeConverter) : array => [$tile->createFakeUpdatePacket($faceHit, $typeConverter)]);
$world->broadcastPacketToViewersByTypeConverter($this->position, fn($typeConverter) : array => [$tile->createFakeUpdatePacket($faceHit, $typeConverter)]);
}
}

Expand Down
80 changes: 64 additions & 16 deletions src/world/World.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
*/
namespace pocketmine\world;

use DaveRandom\CallbackValidator\BuiltInTypes;
use DaveRandom\CallbackValidator\CallbackType;
use DaveRandom\CallbackValidator\ParameterType;
use DaveRandom\CallbackValidator\ReturnType;
use pocketmine\block\Air;
use pocketmine\block\Block;
use pocketmine\block\BlockTypeIds;
Expand Down Expand Up @@ -83,6 +87,7 @@
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Limits;
use pocketmine\utils\ReversePriorityQueue;
use pocketmine\utils\Utils;
use pocketmine\world\biome\Biome;
use pocketmine\world\biome\BiomeRegistry;
use pocketmine\world\format\Chunk;
Expand Down Expand Up @@ -253,8 +258,8 @@ class World implements ChunkManager{
private array $playerChunkListeners = [];

/**
* @var ClientboundPacket[][]
* @phpstan-var array<ChunkPosHash, list<ClientboundPacket>>
* @var ClientboundPacket[][] chunkHash => [spl_object_id => ClientboundPacket[]]
* @phpstan-var array<ChunkPosHash, array<?int, list<ClientboundPacket>>>
*/
private array $packetBuffersByChunk = [];

Expand Down Expand Up @@ -701,10 +706,16 @@ public function addSound(Vector3 $pos, Sound $sound, ?array $players = null) : v

$players = $ev->getRecipients();
if($sound instanceof BlockSound){
TypeConverter::broadcastByTypeConverter($players, function(TypeConverter $typeConverter) use ($sound, $pos) : array{
$closure = function(TypeConverter $typeConverter) use ($sound, $pos) : array{
$sound->setBlockTranslator($typeConverter->getBlockTranslator());
return $sound->encode($pos);
});
};

if($players === $this->getViewersForPosition($pos)){
$this->broadcastPacketToViewersByTypeConverter($pos, $closure);
}else{
TypeConverter::broadcastByTypeConverter($this->filterViewersForPosition($pos, $players), $closure);
}
}else{
$pk = $sound->encode($pos);

Expand Down Expand Up @@ -735,15 +746,21 @@ public function addParticle(Vector3 $pos, Particle $particle, ?array $players =

$players = $ev->getRecipients();
if($particle instanceof BlockParticle || $particle instanceof ItemParticle){
TypeConverter::broadcastByTypeConverter($players, function(TypeConverter $typeConverter) use ($particle, $pos) : array{
$closure = function(TypeConverter $typeConverter) use ($particle, $pos) : array{
if($particle instanceof ItemParticle){
$particle->setItemTranslator($typeConverter->getItemTranslator());
}else{
$particle->setBlockTranslator($typeConverter->getBlockTranslator());
}

return $particle->encode($pos);
});
};

if($players === $this->getViewersForPosition($pos)){
$this->broadcastPacketToViewersByTypeConverter($pos, $closure);
}else{
TypeConverter::broadcastByTypeConverter($this->filterViewersForPosition($pos, $players), $closure);
}
}else{
$pk = $particle->encode($pos);

Expand Down Expand Up @@ -807,11 +824,33 @@ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet
$this->broadcastPacketToPlayersUsingChunk($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE, $packet);
}

private function broadcastPacketToPlayersUsingChunk(int $chunkX, int $chunkZ, ClientboundPacket $packet) : void{
if(!isset($this->packetBuffersByChunk[$index = World::chunkHash($chunkX, $chunkZ)])){
$this->packetBuffersByChunk[$index] = [$packet];
/**
* Broadcasts packets to every player who has the target position within their view distance.
*/
public function broadcastPacketToViewersByTypeConverter(Vector3 $pos, \Closure $closure) : void{

Check failure on line 830 in src/world/World.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Method pocketmine\world\World::broadcastPacketToViewersByTypeConverter() has parameter $closure with no signature specified for Closure.

Check failure on line 830 in src/world/World.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Method pocketmine\world\World::broadcastPacketToViewersByTypeConverter() has parameter $closure with no signature specified for Closure.
Utils::validateCallableSignature(new CallbackType(
new ReturnType(BuiltInTypes::ARRAY, ReturnType::COVARIANT),
new ParameterType('typeConverter', TypeConverter::class),
), $closure);

[$typeConverters, ] = TypeConverter::sortByConverter($this->getViewersForPosition($pos));

foreach($typeConverters as $typeConverter){
/** @var ClientboundPacket[] $packets */
$packets = $closure($typeConverter);
foreach($packets as $packet){
$this->broadcastPacketToPlayersUsingChunk($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE, $packet, $typeConverter);
}
}
}

private function broadcastPacketToPlayersUsingChunk(int $chunkX, int $chunkZ, ClientboundPacket $packet, ?TypeConverter $typeConverter = null) : void{
$typeConverterId = $typeConverter === null ? null : spl_object_id($typeConverter);

if(!isset($this->packetBuffersByChunk[$index = World::chunkHash($chunkX, $chunkZ)][$typeConverterId])){
$this->packetBuffersByChunk[$index][$typeConverterId] = [$packet];

Check failure on line 851 in src/world/World.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Property pocketmine\world\World::$packetBuffersByChunk (array<int, array<int, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>) does not accept array<int, array<int|string, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>.

Check failure on line 851 in src/world/World.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Property pocketmine\world\World::$packetBuffersByChunk (array<int, array<int, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>) does not accept array<int, array<int|string, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>.
}else{
$this->packetBuffersByChunk[$index][] = $packet;
$this->packetBuffersByChunk[$index][$typeConverterId][] = $packet;

Check failure on line 853 in src/world/World.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Property pocketmine\world\World::$packetBuffersByChunk (array<int, array<int, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>) does not accept array<int, array<int|string, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>.

Check failure on line 853 in src/world/World.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Property pocketmine\world\World::$packetBuffersByChunk (array<int, array<int, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>) does not accept array<int, array<int|string, array<int, pocketmine\network\mcpe\protocol\ClientboundPacket>>>.
}
}

Expand Down Expand Up @@ -1033,9 +1072,12 @@ protected function actuallyDoTick(int $currentTick) : void{
$p->onChunkChanged($chunkX, $chunkZ, $chunk);
}
}else{
TypeConverter::broadcastByTypeConverter($this->getChunkPlayers($chunkX, $chunkZ), function(TypeConverter $typeConverter) use ($blocks) : array{
return $this->createBlockUpdatePackets($typeConverter, $blocks);
});
[$typeConverters, ] = TypeConverter::sortByConverter($this->getChunkPlayers($chunkX, $chunkZ));
foreach($typeConverters as $typeConverter){
foreach($this->createBlockUpdatePackets($typeConverter, $blocks) as $packet){
$this->broadcastPacketToPlayersUsingChunk($chunkX, $chunkZ, $packet);
}
}
}
}
}
Expand All @@ -1050,9 +1092,15 @@ protected function actuallyDoTick(int $currentTick) : void{

foreach($this->packetBuffersByChunk as $index => $entries){
World::getXZ($index, $chunkX, $chunkZ);
$chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ);
if(count($chunkPlayers) > 0){
NetworkBroadcastUtils::broadcastPackets($chunkPlayers, $entries);
$universalPackets = $entries[null] ?? [];
[$typeConverters, $converterRecipients] = TypeConverter::sortByConverter($this->getChunkPlayers($chunkX, $chunkZ));

foreach($typeConverters as $key => $typeConverter){
$packets = ($entries[$key] ?? []) + $universalPackets;

if(count($packets) > 0){
NetworkBroadcastUtils::broadcastPackets($converterRecipients[$key], $packets);
}
}
}

Expand Down

0 comments on commit 3a8a0f4

Please sign in to comment.