mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-12 16:59:44 +00:00
Revert "World: do not group broadcasted packets by chunk, broadcast directly instead"
This reverts commit b172c93e45e60ee3dbfd8a2efbede60b894673a3. I made a significant mistake with this change: the scaling factor of batch-by-chunk is O(nSendBytes), while the scaling factor of sending directly to players is O(nSendBytes * nActivePlayers). It seems like the real problem is that this system isn't getting enough usage. While it does reduce compression efficiency in some cases, it falls back to letting the sessions do individual compression when the amount of data is less than 256 bytes anyway (compression-threshold in pocketmine.yml). My motivation for scrapping this system was to reduce the broadcast system's complexity to make it easier to thread the living shit out of compression, but it seems like this change was a step in the wrong direction for performance. A few steps can be taken to improve the usefulness of this system (and also improve output bandwidth): - Make general entity updates use this system. Movement and velocity already kinda used this system, but crucially, players did not, because we couldn't prevent the player from receiving its own movement updates if we did that, which caused all kinds of problems. - Therefore, we need to reintroduce static "self" entity IDs, like we had in the shoghi days when entity ID 0 referred to the "self" player. - However, since entity ID 0 has a variety of interesting bugs since it usually refers to "no entity" in MCPE, it would be better to use 1 (or 2, like MiNET does). - The fixed ID used should be close to zero to maximize varint encoding efficiency. - We assumed that changes to player's position and velocity would be ignored by the client. This assumption depends on the client and could be broken at any time, so it's best not to rely on it. - Make block updates use this system (when chunk updates are not sent). Currently, block updates use a separate mechanism which creates a second batch for every active chunk, which wastes CPU, and decreases bandwidth efficiency on multiple fronts (reduced compression efficiency, more cross-thread interactions, more bytes wasted on RakNet packet headers).
This commit is contained in:
parent
2e3940e8f5
commit
bd3bf3d0ce
@ -172,6 +172,9 @@ class World implements ChunkManager{
|
||||
/** @var Player[][] */
|
||||
private $playerChunkListeners = [];
|
||||
|
||||
/** @var ClientboundPacket[][] */
|
||||
private $chunkPackets = [];
|
||||
|
||||
/** @var float[] */
|
||||
private $unloadQueue = [];
|
||||
|
||||
@ -522,7 +525,11 @@ class World implements ChunkManager{
|
||||
* Broadcasts a packet to every player who has the target position within their view distance.
|
||||
*/
|
||||
public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{
|
||||
$this->server->broadcastPackets($this->getChunkPlayers($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4), [$packet]);
|
||||
if(!isset($this->chunkPackets[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){
|
||||
$this->chunkPackets[$index] = [$packet];
|
||||
}else{
|
||||
$this->chunkPackets[$index][] = $packet;
|
||||
}
|
||||
}
|
||||
|
||||
public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{
|
||||
@ -768,6 +775,16 @@ class World implements ChunkManager{
|
||||
if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){
|
||||
$this->checkSleep();
|
||||
}
|
||||
|
||||
foreach($this->chunkPackets as $index => $entries){
|
||||
World::getXZ($index, $chunkX, $chunkZ);
|
||||
$chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ);
|
||||
if(count($chunkPlayers) > 0){
|
||||
$this->server->broadcastPackets($chunkPlayers, $entries);
|
||||
}
|
||||
}
|
||||
|
||||
$this->chunkPackets = [];
|
||||
}
|
||||
|
||||
public function checkSleep() : void{
|
||||
|
Loading…
x
Reference in New Issue
Block a user