mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
StandardPacketBroadcaster now splits broadcasts by session-specific PacketSerializerContext
in the normal case, all sessions will share the same PacketSerializerContext and Compressor, so this code will be the same as before However, for the multi-protocol hackers out there, this should reduce the maintenance burden (@Driesboy) since now only the PacketSerializerContext needs to be maintained. I recommend a separate PacketSerializerContext for each protocol (perhaps put the protocol version in the serializer context too, if you need it for some reason).
This commit is contained in:
parent
b3720b3f17
commit
eb40b741ae
@ -447,6 +447,8 @@ class NetworkSession{
|
||||
}
|
||||
}
|
||||
|
||||
public function getPacketSerializerContext() : PacketSerializerContext{ return $this->packetSerializerContext; }
|
||||
|
||||
public function getBroadcaster() : PacketBroadcaster{ return $this->broadcaster; }
|
||||
|
||||
public function getCompressor() : Compressor{
|
||||
|
@ -23,10 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use pocketmine\network\mcpe\compression\Compressor;
|
||||
use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\Server;
|
||||
use function spl_object_id;
|
||||
|
||||
@ -40,35 +37,40 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{
|
||||
}
|
||||
|
||||
public function broadcastPackets(array $recipients, array $packets) : void{
|
||||
//TODO: we should be using session-specific serializer contexts for this
|
||||
$stream = PacketBatch::fromPackets(new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()), ...$packets);
|
||||
|
||||
/** @var Compressor[] $compressors */
|
||||
$buffers = [];
|
||||
$compressors = [];
|
||||
/** @var NetworkSession[][] $compressorTargets */
|
||||
$compressorTargets = [];
|
||||
$targetMap = [];
|
||||
foreach($recipients as $recipient){
|
||||
$compressor = $recipient->getCompressor();
|
||||
$compressorId = spl_object_id($compressor);
|
||||
$serializerContext = $recipient->getPacketSerializerContext();
|
||||
$bufferId = spl_object_id($serializerContext);
|
||||
if(!isset($buffers[$bufferId])){
|
||||
$buffers[$bufferId] = PacketBatch::fromPackets($serializerContext, ...$packets);
|
||||
}
|
||||
|
||||
//TODO: different compressors might be compatible, it might not be necessary to split them up by object
|
||||
$compressors[$compressorId] = $compressor;
|
||||
$compressorTargets[$compressorId][] = $recipient;
|
||||
$compressor = $recipient->getCompressor();
|
||||
$compressors[spl_object_id($compressor)] = $compressor;
|
||||
|
||||
$targetMap[$bufferId][spl_object_id($compressor)][] = $recipient;
|
||||
}
|
||||
|
||||
foreach($compressors as $compressorId => $compressor){
|
||||
if(!$compressor->willCompress($stream->getBuffer())){
|
||||
foreach($compressorTargets[$compressorId] as $target){
|
||||
foreach($packets as $pk){
|
||||
$target->addToSendBuffer($pk);
|
||||
foreach($targetMap as $bufferId => $compressorMap){
|
||||
$buffer = $buffers[$bufferId];
|
||||
foreach($compressorMap as $compressorId => $compressorTargets){
|
||||
$compressor = $compressors[$compressorId];
|
||||
if(!$compressor->willCompress($buffer->getBuffer())){
|
||||
foreach($compressorTargets as $target){
|
||||
foreach($packets as $pk){
|
||||
$target->addToSendBuffer($pk);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$promise = $this->server->prepareBatch($buffer, $compressor);
|
||||
foreach($compressorTargets as $target){
|
||||
$target->queueCompressed($promise);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$promise = $this->server->prepareBatch($stream, $compressor);
|
||||
foreach($compressorTargets[$compressorId] as $target){
|
||||
$target->queueCompressed($promise);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user