Merge branch 'next-minor' into next-major

This commit is contained in:
Dylan K. Taylor 2023-02-21 15:41:57 +00:00
commit 50b8d39aba
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
10 changed files with 213 additions and 126 deletions

@ -1 +1 @@
Subproject commit fb297eb511862ef3d4ca0aff5256a8caf5513cb4 Subproject commit b2207cf70d3fc5b81f50a655aba4730fcf40a37c

View File

@ -12,3 +12,11 @@ Released 17th February 2023.
## General ## General
- Added support for Minecraft: Bedrock Edition 1.19.62. - Added support for Minecraft: Bedrock Edition 1.19.62.
- Removed support for older versions. - Removed support for older versions.
# 4.15.1
Released 21st February 2023.
## Fixes
- Fixed dropped items not despawning when in non-ticking chunks.
- Fixed dropped items not despawning if an infinite pickup delay is set.
- Fixed infinite despawn delay (never despawn) being ignored for dropped items.

View File

@ -37,7 +37,7 @@
"pocketmine/bedrock-block-upgrade-schema": "^1.0.0", "pocketmine/bedrock-block-upgrade-schema": "^1.0.0",
"pocketmine/bedrock-data": "dev-modern-world-support@dev", "pocketmine/bedrock-data": "dev-modern-world-support@dev",
"pocketmine/bedrock-item-upgrade-schema": "^1.0.0", "pocketmine/bedrock-item-upgrade-schema": "^1.0.0",
"pocketmine/bedrock-protocol": "~19.2.0+bedrock-1.19.62", "pocketmine/bedrock-protocol": "~19.3.0+bedrock-1.19.62",
"pocketmine/binaryutils": "^0.2.1", "pocketmine/binaryutils": "^0.2.1",
"pocketmine/callback-validator": "^1.0.2", "pocketmine/callback-validator": "^1.0.2",
"pocketmine/classloader": "^0.3.0", "pocketmine/classloader": "^0.3.0",
@ -55,7 +55,7 @@
"symfony/filesystem": "^5.4" "symfony/filesystem": "^5.4"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "1.9.17", "phpstan/phpstan": "1.9.18",
"phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0", "phpstan/phpstan-strict-rules": "^1.2.0",
"phpunit/phpunit": "^9.2" "phpunit/phpunit": "^9.2"

26
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "3f98a352bac38a5e4cac66484ea8f8c7", "content-hash": "ea992cf9b9be39c9d5251b7769f9d044",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -328,16 +328,16 @@
}, },
{ {
"name": "pocketmine/bedrock-protocol", "name": "pocketmine/bedrock-protocol",
"version": "19.2.0+bedrock-1.19.62", "version": "19.3.0+bedrock-1.19.62",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git", "url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "a156db582d0b1a6c20c9d9cc9b1df7ef907efd0b" "reference": "a5bf4753c7f30f781c4541918e238f5bb637e7ad"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/a156db582d0b1a6c20c9d9cc9b1df7ef907efd0b", "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/a5bf4753c7f30f781c4541918e238f5bb637e7ad",
"reference": "a156db582d0b1a6c20c9d9cc9b1df7ef907efd0b", "reference": "a5bf4753c7f30f781c4541918e238f5bb637e7ad",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -369,9 +369,9 @@
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
"support": { "support": {
"issues": "https://github.com/pmmp/BedrockProtocol/issues", "issues": "https://github.com/pmmp/BedrockProtocol/issues",
"source": "https://github.com/pmmp/BedrockProtocol/tree/19.2.0+bedrock-1.19.62" "source": "https://github.com/pmmp/BedrockProtocol/tree/19.3.0+bedrock-1.19.62"
}, },
"time": "2023-02-17T16:32:49+00:00" "time": "2023-02-19T16:11:03+00:00"
}, },
{ {
"name": "pocketmine/binaryutils", "name": "pocketmine/binaryutils",
@ -1775,16 +1775,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.9.17", "version": "1.9.18",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2" "reference": "f2d5cf71be91172a57c649770b73c20ebcffb0bf"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/204e459e7822f2c586463029f5ecec31bb45a1f2", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f2d5cf71be91172a57c649770b73c20ebcffb0bf",
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2", "reference": "f2d5cf71be91172a57c649770b73c20ebcffb0bf",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1814,7 +1814,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan/issues", "issues": "https://github.com/phpstan/phpstan/issues",
"source": "https://github.com/phpstan/phpstan/tree/1.9.17" "source": "https://github.com/phpstan/phpstan/tree/1.9.18"
}, },
"funding": [ "funding": [
{ {
@ -1830,7 +1830,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-02-08T12:25:00+00:00" "time": "2023-02-17T15:01:27+00:00"
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",

View File

@ -774,6 +774,15 @@ abstract class Entity{
$this->server->broadcastPackets($this->hasSpawned, [SetActorMotionPacket::create($this->id, $this->getMotion())]); $this->server->broadcastPackets($this->hasSpawned, [SetActorMotionPacket::create($this->id, $this->getMotion())]);
} }
public function getGravity() : float{
return $this->gravity;
}
public function setGravity(float $gravity) : void{
Utils::checkFloatNotInfOrNaN("gravity", $gravity);
$this->gravity = $gravity;
}
public function hasGravity() : bool{ public function hasGravity() : bool{
return $this->gravityEnabled; return $this->gravityEnabled;
} }

View File

@ -106,33 +106,42 @@ class ItemEntity extends Entity{
$hasUpdate = parent::entityBaseTick($tickDiff); $hasUpdate = parent::entityBaseTick($tickDiff);
if(!$this->isFlaggedForDespawn() && $this->pickupDelay !== self::NEVER_DESPAWN){ //Infinite delay if($this->isFlaggedForDespawn()){
return $hasUpdate;
}
if($this->pickupDelay !== self::NEVER_DESPAWN && $this->pickupDelay > 0){ //Infinite delay
$hasUpdate = true;
$this->pickupDelay -= $tickDiff; $this->pickupDelay -= $tickDiff;
if($this->pickupDelay < 0){ if($this->pickupDelay < 0){
$this->pickupDelay = 0; $this->pickupDelay = 0;
} }
if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){ }
$mergeable = [$this]; //in case the merge target ends up not being this
$mergeTarget = $this;
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){
if(!$entity instanceof ItemEntity || $entity->isFlaggedForDespawn()){
continue;
}
if($entity->isMergeable($this)){ if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){
$mergeable[] = $entity; $mergeable = [$this]; //in case the merge target ends up not being this
if($entity->item->getCount() > $mergeTarget->item->getCount()){ $mergeTarget = $this;
$mergeTarget = $entity; foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){
} if(!$entity instanceof ItemEntity || $entity->isFlaggedForDespawn()){
} continue;
} }
foreach($mergeable as $itemEntity){
if($itemEntity !== $mergeTarget){ if($entity->isMergeable($this)){
$itemEntity->tryMergeInto($mergeTarget); $mergeable[] = $entity;
if($entity->item->getCount() > $mergeTarget->item->getCount()){
$mergeTarget = $entity;
} }
} }
} }
foreach($mergeable as $itemEntity){
if($itemEntity !== $mergeTarget){
$itemEntity->tryMergeInto($mergeTarget);
}
}
}
if(!$this->isFlaggedForDespawn() && $this->despawnDelay !== self::NEVER_DESPAWN){
$hasUpdate = true;
$this->despawnDelay -= $tickDiff; $this->despawnDelay -= $tickDiff;
if($this->despawnDelay <= 0){ if($this->despawnDelay <= 0){
$ev = new ItemDespawnEvent($this); $ev = new ItemDespawnEvent($this);
@ -141,7 +150,6 @@ class ItemEntity extends Entity{
$this->despawnDelay = self::DEFAULT_DESPAWN_DELAY; $this->despawnDelay = self::DEFAULT_DESPAWN_DELAY;
}else{ }else{
$this->flagForDespawn(); $this->flagForDespawn();
$hasUpdate = true;
} }
} }
} }

View File

@ -34,6 +34,7 @@ use pocketmine\network\mcpe\protocol\types\ChunkPosition;
use pocketmine\network\mcpe\serializer\ChunkSerializer; use pocketmine\network\mcpe\serializer\ChunkSerializer;
use pocketmine\scheduler\AsyncTask; use pocketmine\scheduler\AsyncTask;
use pocketmine\thread\NonThreadSafeValue; use pocketmine\thread\NonThreadSafeValue;
use pocketmine\utils\BinaryStream;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\format\io\FastChunkSerializer;
@ -68,7 +69,10 @@ class ChunkRequestTask extends AsyncTask{
$subCount = ChunkSerializer::getSubChunkCount($chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk);
$encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); $encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary());
$payload = ChunkSerializer::serializeFullChunk($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); $payload = ChunkSerializer::serializeFullChunk($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles);
$this->setResult($this->compressor->deserialize()->compress(PacketBatch::fromPackets($encoderContext, LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $subCount, false, null, $payload))->getBuffer()));
$stream = new BinaryStream();
PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $subCount, false, null, $payload)]);
$this->setResult($this->compressor->deserialize()->compress($stream->getBuffer()));
} }
public function onError() : void{ public function onError() : void{

View File

@ -120,6 +120,7 @@ use pocketmine\player\XboxLivePlayerInfo;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\timings\Timings; use pocketmine\timings\Timings;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\BinaryStream;
use pocketmine\utils\ObjectSet; use pocketmine\utils\ObjectSet;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
@ -177,7 +178,7 @@ class NetworkSession{
private ?EncryptionContext $cipher = null; private ?EncryptionContext $cipher = null;
/** @var Packet[] */ /** @var ClientboundPacket[] */
private array $sendBuffer = []; private array $sendBuffer = [];
/** /**
@ -265,6 +266,23 @@ class NetworkSession{
); );
} }
/**
* @param ClientboundPacket[] $packets
*/
public static function encodePacketBatchTimed(BinaryStream $stream, PacketSerializerContext $context, array $packets) : void{
PacketBatch::encodeRaw($stream, array_map(function(ClientboundPacket $packet) use ($context) : string{
$timings = Timings::getEncodeDataPacketTimings($packet);
$timings->startTiming();
try{
$stream = PacketSerializer::encoder($context);
$packet->encode($stream);
return $stream->getBuffer();
}finally{
$timings->stopTiming();
}
}, $packets));
}
private function onPlayerCreated(Player $player) : void{ private function onPlayerCreated(Player $player) : void{
if(!$this->isConnected()){ if(!$this->isConnected()){
//the remote player might have disconnected before spawn terrain generation was finished //the remote player might have disconnected before spawn terrain generation was finished
@ -360,56 +378,67 @@ class NetworkSession{
return; return;
} }
if($this->incomingPacketBatchBudget <= 0){ Timings::$playerNetworkReceive->startTiming();
$this->updatePacketBudget();
if($this->incomingPacketBatchBudget <= 0){
throw new PacketHandlingException("Receiving packets too fast");
}
}
$this->incomingPacketBatchBudget--;
if($this->cipher !== null){
Timings::$playerNetworkReceiveDecrypt->startTiming();
try{
$payload = $this->cipher->decrypt($payload);
}catch(DecryptionException $e){
$this->logger->debug("Encrypted packet: " . base64_encode($payload));
throw PacketHandlingException::wrap($e, "Packet decryption error");
}finally{
Timings::$playerNetworkReceiveDecrypt->stopTiming();
}
}
if($this->enableCompression){
Timings::$playerNetworkReceiveDecompress->startTiming();
try{
$decompressed = $this->compressor->decompress($payload);
}catch(DecompressionException $e){
$this->logger->debug("Failed to decompress packet: " . base64_encode($payload));
throw PacketHandlingException::wrap($e, "Compressed packet batch decode error");
}finally{
Timings::$playerNetworkReceiveDecompress->stopTiming();
}
}else{
$decompressed = $payload;
}
try{ try{
foreach((new PacketBatch($decompressed))->getPackets($this->packetPool, $this->packetSerializerContext, 1300) as [$packet, $buffer]){ if($this->incomingPacketBatchBudget <= 0){
if($packet === null){ $this->updatePacketBudget();
$this->logger->debug("Unknown packet: " . base64_encode($buffer)); if($this->incomingPacketBatchBudget <= 0){
throw new PacketHandlingException("Unknown packet received"); throw new PacketHandlingException("Receiving packets too fast");
}
try{
$this->handleDataPacket($packet, $buffer);
}catch(PacketHandlingException $e){
$this->logger->debug($packet->getName() . ": " . base64_encode($buffer));
throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName());
} }
} }
}catch(PacketDecodeException $e){ $this->incomingPacketBatchBudget--;
$this->logger->logException($e);
throw PacketHandlingException::wrap($e, "Packet batch decode error"); if($this->cipher !== null){
Timings::$playerNetworkReceiveDecrypt->startTiming();
try{
$payload = $this->cipher->decrypt($payload);
}catch(DecryptionException $e){
$this->logger->debug("Encrypted packet: " . base64_encode($payload));
throw PacketHandlingException::wrap($e, "Packet decryption error");
}finally{
Timings::$playerNetworkReceiveDecrypt->stopTiming();
}
}
if($this->enableCompression){
Timings::$playerNetworkReceiveDecompress->startTiming();
try{
$decompressed = $this->compressor->decompress($payload);
}catch(DecompressionException $e){
$this->logger->debug("Failed to decompress packet: " . base64_encode($payload));
throw PacketHandlingException::wrap($e, "Compressed packet batch decode error");
}finally{
Timings::$playerNetworkReceiveDecompress->stopTiming();
}
}else{
$decompressed = $payload;
}
try{
$stream = new BinaryStream($decompressed);
$count = 0;
foreach(PacketBatch::decodeRaw($stream) as $buffer){
if(++$count > 1300){
throw new PacketHandlingException("Too many packets in batch");
}
$packet = $this->packetPool->getPacket($buffer);
if($packet === null){
$this->logger->debug("Unknown packet: " . base64_encode($buffer));
throw new PacketHandlingException("Unknown packet received");
}
try{
$this->handleDataPacket($packet, $buffer);
}catch(PacketHandlingException $e){
$this->logger->debug($packet->getName() . ": " . base64_encode($buffer));
throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName());
}
}
}catch(PacketDecodeException $e){
$this->logger->logException($e);
throw PacketHandlingException::wrap($e, "Packet batch decode error");
}
}finally{
Timings::$playerNetworkReceive->stopTiming();
} }
} }
@ -500,22 +529,29 @@ class NetworkSession{
private function flushSendBuffer(bool $immediate = false) : void{ private function flushSendBuffer(bool $immediate = false) : void{
if(count($this->sendBuffer) > 0){ if(count($this->sendBuffer) > 0){
$syncMode = null; //automatic Timings::$playerNetworkSend->startTiming();
if($immediate){ try{
$syncMode = true; $syncMode = null; //automatic
}elseif($this->forceAsyncCompression){ if($immediate){
$syncMode = false; $syncMode = true;
} }elseif($this->forceAsyncCompression){
$syncMode = false;
}
$batch = PacketBatch::fromPackets($this->packetSerializerContext, ...$this->sendBuffer); $stream = new BinaryStream();
if($this->enableCompression){ self::encodePacketBatchTimed($stream, $this->packetSerializerContext, $this->sendBuffer);
$promise = $this->server->prepareBatch($batch, $this->compressor, $syncMode);
}else{ if($this->enableCompression){
$promise = new CompressBatchPromise(); $promise = $this->server->prepareBatch(new PacketBatch($stream->getBuffer()), $this->compressor, $syncMode);
$promise->resolve($batch->getBuffer()); }else{
$promise = new CompressBatchPromise();
$promise->resolve($stream->getBuffer());
}
$this->sendBuffer = [];
$this->queueCompressedNoBufferFlush($promise, $immediate);
}finally{
Timings::$playerNetworkSend->stopTiming();
} }
$this->sendBuffer = [];
$this->queueCompressedNoBufferFlush($promise, $immediate);
} }
} }
@ -528,35 +564,45 @@ class NetworkSession{
} }
public function queueCompressed(CompressBatchPromise $payload, bool $immediate = false) : void{ public function queueCompressed(CompressBatchPromise $payload, bool $immediate = false) : void{
$this->flushSendBuffer($immediate); //Maintain ordering if possible Timings::$playerNetworkSend->startTiming();
$this->queueCompressedNoBufferFlush($payload, $immediate); try{
$this->flushSendBuffer($immediate); //Maintain ordering if possible
$this->queueCompressedNoBufferFlush($payload, $immediate);
}finally{
Timings::$playerNetworkSend->stopTiming();
}
} }
private function queueCompressedNoBufferFlush(CompressBatchPromise $payload, bool $immediate = false) : void{ private function queueCompressedNoBufferFlush(CompressBatchPromise $payload, bool $immediate = false) : void{
if($immediate){ Timings::$playerNetworkSend->startTiming();
//Skips all queues try{
$this->sendEncoded($payload->getResult(), true); if($immediate){
}else{ //Skips all queues
$this->compressedQueue->enqueue($payload); $this->sendEncoded($payload->getResult(), true);
$payload->onResolve(function(CompressBatchPromise $payload) : void{ }else{
if($this->connected && $this->compressedQueue->bottom() === $payload){ $this->compressedQueue->enqueue($payload);
$this->compressedQueue->dequeue(); //result unused $payload->onResolve(function(CompressBatchPromise $payload) : void{
$this->sendEncoded($payload->getResult()); if($this->connected && $this->compressedQueue->bottom() === $payload){
$this->compressedQueue->dequeue(); //result unused
$this->sendEncoded($payload->getResult());
while(!$this->compressedQueue->isEmpty()){ while(!$this->compressedQueue->isEmpty()){
/** @var CompressBatchPromise $current */ /** @var CompressBatchPromise $current */
$current = $this->compressedQueue->bottom(); $current = $this->compressedQueue->bottom();
if($current->hasResult()){ if($current->hasResult()){
$this->compressedQueue->dequeue(); $this->compressedQueue->dequeue();
$this->sendEncoded($current->getResult()); $this->sendEncoded($current->getResult());
}else{ }else{
//can't send any more queued until this one is ready //can't send any more queued until this one is ready
break; break;
}
} }
} }
} });
}); }
}finally{
Timings::$playerNetworkSend->stopTiming();
} }
} }

View File

@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe;
use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\BinaryStream;
use function spl_object_id; use function spl_object_id;
final class StandardPacketBroadcaster implements PacketBroadcaster{ final class StandardPacketBroadcaster implements PacketBroadcaster{
@ -38,7 +39,9 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{
$serializerContext = $recipient->getPacketSerializerContext(); $serializerContext = $recipient->getPacketSerializerContext();
$bufferId = spl_object_id($serializerContext); $bufferId = spl_object_id($serializerContext);
if(!isset($buffers[$bufferId])){ if(!isset($buffers[$bufferId])){
$buffers[$bufferId] = PacketBatch::fromPackets($serializerContext, ...$packets); $stream = new BinaryStream();
NetworkSession::encodePacketBatchTimed($stream, $serializerContext, $packets);
$buffers[$bufferId] = $stream->getBuffer();
} }
//TODO: different compressors might be compatible, it might not be necessary to split them up by object //TODO: different compressors might be compatible, it might not be necessary to split them up by object
@ -52,14 +55,14 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{
$buffer = $buffers[$bufferId]; $buffer = $buffers[$bufferId];
foreach($compressorMap as $compressorId => $compressorTargets){ foreach($compressorMap as $compressorId => $compressorTargets){
$compressor = $compressors[$compressorId]; $compressor = $compressors[$compressorId];
if(!$compressor->willCompress($buffer->getBuffer())){ if(!$compressor->willCompress($buffer)){
foreach($compressorTargets as $target){ foreach($compressorTargets as $target){
foreach($packets as $pk){ foreach($packets as $pk){
$target->addToSendBuffer($pk); $target->addToSendBuffer($pk);
} }
} }
}else{ }else{
$promise = $this->server->prepareBatch($buffer, $compressor); $promise = $this->server->prepareBatch(new PacketBatch($buffer), $compressor);
foreach($compressorTargets as $target){ foreach($compressorTargets as $target){
$target->queueCompressed($promise); $target->queueCompressed($promise);
} }

View File

@ -89,6 +89,9 @@ abstract class Timings{
/** @var TimingsHandler[] */ /** @var TimingsHandler[] */
private static array $packetHandleTimingMap = []; private static array $packetHandleTimingMap = [];
/** @var TimingsHandler[] */
private static array $packetEncodeTimingMap = [];
/** @var TimingsHandler[] */ /** @var TimingsHandler[] */
public static array $packetSendTimingMap = []; public static array $packetSendTimingMap = [];
/** @var TimingsHandler[] */ /** @var TimingsHandler[] */
@ -202,8 +205,7 @@ abstract class Timings{
self::init(); self::init();
$pid = $pk->pid(); $pid = $pk->pid();
if(!isset(self::$packetReceiveTimingMap[$pid])){ if(!isset(self::$packetReceiveTimingMap[$pid])){
$pkName = (new \ReflectionClass($pk))->getShortName(); self::$packetReceiveTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "receivePacket - " . $pk->getName() . " [0x" . dechex($pid) . "]", self::$playerNetworkReceive);
self::$packetReceiveTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "receivePacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkReceive);
} }
return self::$packetReceiveTimingMap[$pid]; return self::$packetReceiveTimingMap[$pid];
@ -225,12 +227,19 @@ abstract class Timings{
); );
} }
public static function getEncodeDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
$pid = $pk->pid();
return self::$packetEncodeTimingMap[$pid] ??= new TimingsHandler(
self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Encode - " . $pk->getName() . " [0x" . dechex($pid) . "]",
self::getSendDataPacketTimings($pk)
);
}
public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{ public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
self::init(); self::init();
$pid = $pk->pid(); $pid = $pk->pid();
if(!isset(self::$packetSendTimingMap[$pid])){ if(!isset(self::$packetSendTimingMap[$pid])){
$pkName = (new \ReflectionClass($pk))->getShortName(); self::$packetSendTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "sendPacket - " . $pk->getName() . " [0x" . dechex($pid) . "]", self::$playerNetworkSend);
self::$packetSendTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "sendPacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkSend);
} }
return self::$packetSendTimingMap[$pid]; return self::$packetSendTimingMap[$pid];