diff --git a/src/Server.php b/src/Server.php index 8728ce87bc8..7e3058e82c3 100644 --- a/src/Server.php +++ b/src/Server.php @@ -304,8 +304,6 @@ class Server{ */ private array $broadcastSubscribers = []; - /** @var array */ - private array $packetSerializerContexts = []; /** @var array */ private array $packetBroadcasters = []; /** @var array */ @@ -606,8 +604,7 @@ public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bo $playerPromiseResolver->reject(); }; - $promise = Promise::all($promises->toArray()); - $promise->onCompletion(function () use ($playerPos, $world, $createPlayer, $playerCreationRejected) : void{ + $playerCreationSucceeded = function () use ($playerPos, $world, $createPlayer, $playerCreationRejected) : void{ if($playerPos === null){ //new player or no valid position due to world not being loaded $world->requestSafeSpawn()->onCompletion( function(Position $spawn) use ($createPlayer, $world) : void{ @@ -620,9 +617,18 @@ function() use ($playerCreationRejected) : void{ }else{ //returning player with a valid position - safe spawn not required $createPlayer($playerPos); } - }, function () use ($playerCreationRejected) : void{ - $playerCreationRejected("Failed to create player"); - }); + }; + + if(count($prs = $promises->toArray()) > 0){ + /** @phpstan-var non-empty-array> $prs */ + $promise = Promise::all($prs); + + $promise->onCompletion($playerCreationSucceeded, function () use ($playerCreationRejected) : void{ + $playerCreationRejected("Failed to create player"); + }); + }else{ + $playerCreationSucceeded(); + } return $playerPromiseResolver->getPromise(); } @@ -1255,7 +1261,7 @@ private function startupPrepareNetworkInterfaces() : bool{ $useQuery = $this->configGroup->getConfigBool(ServerProperties::ENABLE_QUERY, true); $typeConverter = TypeConverter::getInstance(); - $packetBroadcaster = $this->getPacketBroadcaster($typeConverter); + $packetBroadcaster = $this->getPacketBroadcaster(ProtocolInfo::CURRENT_PROTOCOL); $entityEventBroadcaster = $this->getEntityEventBroadcaster($packetBroadcaster, $typeConverter); if( @@ -1914,12 +1920,11 @@ private function tick() : void{ $this->nextTick += self::TARGET_SECONDS_PER_TICK; } } - public function getPacketSerializerContext(TypeConverter $typeConverter) : PacketSerializerContext{ - return $this->packetSerializerContexts[spl_object_id($typeConverter)] ??= new PacketSerializerContext($typeConverter->getItemTypeDictionary(), $typeConverter->getProtocolId()); - } - public function getPacketBroadcaster(PacketSerializerContext $packetSerializerContext) : PacketBroadcaster{ - return $this->packetBroadcasters[spl_object_id($packetSerializerContext)] ??= new StandardPacketBroadcaster($this, $packetSerializerContext); + + public function getPacketBroadcaster(int $protocolId) : PacketBroadcaster{ + return $this->packetBroadcasters[$protocolId] ??= new StandardPacketBroadcaster($this, $protocolId); } + public function getEntityEventBroadcaster(PacketBroadcaster $packetBroadcaster, TypeConverter $typeConverter) : EntityEventBroadcaster{ return $this->entityEventBroadcasters[spl_object_id($packetBroadcaster) . ':' . spl_object_id($typeConverter)] ??= new StandardEntityEventBroadcaster($packetBroadcaster, $typeConverter); } diff --git a/src/network/mcpe/CachedChunk.php b/src/network/mcpe/CachedChunk.php index e6e4a02169b..38a838cfbc5 100644 --- a/src/network/mcpe/CachedChunk.php +++ b/src/network/mcpe/CachedChunk.php @@ -28,7 +28,6 @@ use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\types\ChunkPosition; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\utils\BinaryStream; @@ -85,14 +84,14 @@ public function getHashMap() : array{ /** * @phpstan-param DimensionIds::* $dimensionId */ - public function compressPackets(int $chunkX, int $chunkZ, int $dimensionId, string $chunkData, Compressor $compressor, PacketSerializerContext $encoderContext, int $protocolId) : void{ + public function compressPackets(int $chunkX, int $chunkZ, int $dimensionId, string $chunkData, Compressor $compressor, int $protocolId) : void{ $protocolAddition = $protocolId >= ProtocolInfo::PROTOCOL_1_20_60 ? chr($compressor->getNetworkId()) : ''; $stream = new BinaryStream(); - PacketBatch::encodePackets($stream, $encoderContext, [$this->createPacket($chunkX, $chunkZ, $dimensionId, $chunkData)]); + PacketBatch::encodePackets($stream, $protocolId, [$this->createPacket($chunkX, $chunkZ, $dimensionId, $chunkData)]); $this->packet = $protocolAddition . $compressor->compress($stream->getBuffer()); $stream = new BinaryStream(); - PacketBatch::encodePackets($stream, $encoderContext, [$this->createCachablePacket($chunkX, $chunkZ, $dimensionId, $chunkData)]); + PacketBatch::encodePackets($stream, $protocolId, [$this->createCachablePacket($chunkX, $chunkZ, $dimensionId, $chunkData)]); $this->cachablePacket = $protocolAddition . $compressor->compress($stream->getBuffer()); } diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 87b98f698a6..81be59f74c2 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -26,10 +26,6 @@ use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; -use pocketmine\network\mcpe\protocol\LevelChunkPacket; -use pocketmine\network\mcpe\protocol\serializer\PacketBatch; -use pocketmine\network\mcpe\protocol\types\ChunkPosition; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\serializer\ChunkSerializer; use pocketmine\scheduler\AsyncTask; diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 6135167d284..0a9a35c8e7a 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -436,8 +436,8 @@ private function itemStackExtraDataEqual(ItemStack $left, ItemStack $right) : bo } $typeConverter = $this->session->getTypeConverter(); - $leftExtraData = $typeConverter->deserializeItemStackExtraData($left->getRawExtraData(), $left->getId()); - $rightExtraData = $typeConverter->deserializeItemStackExtraData($right->getRawExtraData(), $right->getId()); + $leftExtraData = $typeConverter->deserializeItemStackExtraData($this->session->getProtocolId(), $left->getRawExtraData(), $left->getId()); + $rightExtraData = $typeConverter->deserializeItemStackExtraData($this->session->getProtocolId(), $right->getRawExtraData(), $right->getId()); $leftNbt = $leftExtraData->getNbt(); $rightNbt = $rightExtraData->getNbt(); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index c8097289eab..20debf6a306 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -364,8 +364,7 @@ public function setProtocolId(int $protocolId) : void{ $this->protocolId = $protocolId; $this->typeConverter = TypeConverter::getInstance($protocolId); - $this->packetSerializerContext = $this->server->getPacketSerializerContext($this->typeConverter); - $this->broadcaster = $this->server->getPacketBroadcaster($this->packetSerializerContext); + $this->broadcaster = $this->server->getPacketBroadcaster($protocolId); $this->entityEventBroadcaster = $this->server->getEntityEventBroadcaster($this->broadcaster, $this->typeConverter); } diff --git a/src/network/mcpe/StandardPacketBroadcaster.php b/src/network/mcpe/StandardPacketBroadcaster.php index 4a0ca6cd06a..276751e2b38 100644 --- a/src/network/mcpe/StandardPacketBroadcaster.php +++ b/src/network/mcpe/StandardPacketBroadcaster.php @@ -36,7 +36,8 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{ public function __construct( - private Server $server + private Server $server, + private int $protocolId ){} public function broadcastPackets(array $recipients, array $packets) : void{ @@ -66,7 +67,7 @@ public function broadcastPackets(array $recipients, array $packets) : void{ $totalLength = 0; $packetBuffers = []; foreach($packets as $packet){ - $buffer = NetworkSession::encodePacketTimed(PacketSerializer::encoder(), $packet); + $buffer = NetworkSession::encodePacketTimed(PacketSerializer::encoder($this->protocolId), $packet); //varint length prefix + packet buffer $totalLength += (((int) log(strlen($buffer), 128)) + 1) + strlen($buffer); $packetBuffers[] = $buffer; @@ -82,7 +83,7 @@ public function broadcastPackets(array $recipients, array $packets) : void{ PacketBatch::encodeRaw($stream, $packetBuffers); $batchBuffer = $stream->getBuffer(); - $batch = $this->server->prepareBatch($batchBuffer, $this->protocolContext, $compressor, timings: Timings::$playerNetworkSendCompressBroadcast); + $batch = $this->server->prepareBatch($batchBuffer, $this->protocolId, $compressor, timings: Timings::$playerNetworkSendCompressBroadcast); foreach($compressorTargets as $target){ $target->queueCompressed($batch); } diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index aaa5c4542ae..3291194013b 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -34,8 +34,8 @@ use pocketmine\crafting\TagWildcardRecipeIngredient; use pocketmine\data\bedrock\item\BlockItemIdMap; use pocketmine\data\bedrock\item\downgrade\ItemIdMetaDowngrader; -use pocketmine\event\server\TypeConverterConstructEvent; use pocketmine\data\bedrock\item\ItemTypeNames; +use pocketmine\event\server\TypeConverterConstructEvent; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use pocketmine\nbt\NbtException; diff --git a/tools/generate-bedrock-data-from-packets.php b/tools/generate-bedrock-data-from-packets.php index ca15bd8bec0..13d43f8d790 100644 --- a/tools/generate-bedrock-data-from-packets.php +++ b/tools/generate-bedrock-data-from-packets.php @@ -49,6 +49,7 @@ use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\network\mcpe\protocol\CreativeContentPacket; use pocketmine\network\mcpe\protocol\PacketPool; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\StartGamePacket; @@ -173,7 +174,7 @@ private function itemStackToJson(ItemStack $itemStack) : ItemStackData{ $rawExtraData = $itemStack->getRawExtraData(); if($rawExtraData !== ""){ - $decoder = PacketSerializer::decoder($rawExtraData, 0); + $decoder = PacketSerializer::decoder(ProtocolInfo::CURRENT_PROTOCOL, $rawExtraData, 0); $extraData = $itemStringId === ItemTypeNames::SHIELD ? ItemStackExtraDataShield::read($decoder) : ItemStackExtraData::read($decoder); $nbt = $extraData->getNbt(); if($nbt !== null && count($nbt) > 0){ @@ -577,7 +578,7 @@ function main(array $argv) : int{ fwrite(STDERR, "Unknown packet on line " . ($lineNum + 1) . ": " . $parts[1]); continue; } - $serializer = PacketSerializer::decoder($raw, 0); + $serializer = PacketSerializer::decoder(ProtocolInfo::CURRENT_PROTOCOL, $raw, 0); $pk->decode($serializer); $pk->handle($handler);