@@ -174,7 +174,7 @@ class NetworkSession{
174
174
*/
175
175
private array $ sendBufferAckPromises = [];
176
176
177
- /** @phpstan-var \SplQueue<array{CompressBatchPromise|string, list<PromiseResolver<true>>}> */
177
+ /** @phpstan-var \SplQueue<array{CompressBatchPromise|string, list<PromiseResolver<true>>, bool }> */
178
178
private \SplQueue $ compressedQueue ;
179
179
private bool $ forceAsyncCompression = true ;
180
180
private bool $ enableCompression = false ; //disabled until handshake completed
@@ -235,7 +235,7 @@ public function getLogger() : \Logger{
235
235
236
236
private function onSessionStartSuccess () : void {
237
237
$ this ->logger ->debug ("Session start handshake completed, awaiting login packet " );
238
- $ this ->flushSendBuffer ( true );
238
+ $ this ->flushGamePacketQueue ( );
239
239
$ this ->enableCompression = true ;
240
240
$ this ->setHandler (new LoginPacketHandler (
241
241
$ this ->server ,
@@ -529,7 +529,7 @@ private function sendDataPacketInternal(ClientboundPacket $packet, bool $immedia
529
529
$ this ->addToSendBuffer (self ::encodePacketTimed (PacketSerializer::encoder (), $ evPacket ));
530
530
}
531
531
if ($ immediate ){
532
- $ this ->flushSendBuffer ( true );
532
+ $ this ->flushGamePacketQueue ( );
533
533
}
534
534
535
535
return true ;
@@ -577,14 +577,12 @@ public function addToSendBuffer(string $buffer) : void{
577
577
$ this ->sendBuffer [] = $ buffer ;
578
578
}
579
579
580
- private function flushSendBuffer ( bool $ immediate = false ) : void {
580
+ private function flushGamePacketQueue ( ) : void {
581
581
if (count ($ this ->sendBuffer ) > 0 ){
582
582
Timings::$ playerNetworkSend ->startTiming ();
583
583
try {
584
584
$ syncMode = null ; //automatic
585
- if ($ immediate ){
586
- $ syncMode = true ;
587
- }elseif ($ this ->forceAsyncCompression ){
585
+ if ($ this ->forceAsyncCompression ){
588
586
$ syncMode = false ;
589
587
}
590
588
@@ -599,7 +597,9 @@ private function flushSendBuffer(bool $immediate = false) : void{
599
597
$ this ->sendBuffer = [];
600
598
$ ackPromises = $ this ->sendBufferAckPromises ;
601
599
$ this ->sendBufferAckPromises = [];
602
- $ this ->queueCompressedNoBufferFlush ($ batch , $ immediate , $ ackPromises );
600
+ //these packets were already potentially buffered for up to 50ms - make sure the transport layer doesn't
601
+ //delay them any longer
602
+ $ this ->queueCompressedNoGamePacketFlush ($ batch , networkFlush: true , ackPromises: $ ackPromises );
603
603
}finally {
604
604
Timings::$ playerNetworkSend ->stopTiming ();
605
605
}
@@ -619,8 +619,10 @@ public function getTypeConverter() : TypeConverter{ return $this->typeConverter;
619
619
public function queueCompressed (CompressBatchPromise |string $ payload , bool $ immediate = false ) : void {
620
620
Timings::$ playerNetworkSend ->startTiming ();
621
621
try {
622
- $ this ->flushSendBuffer ($ immediate ); //Maintain ordering if possible
623
- $ this ->queueCompressedNoBufferFlush ($ payload , $ immediate );
622
+ //if the next packet causes a flush, avoid unnecessarily flushing twice
623
+ //however, if the next packet does *not* cause a flush, game packets should be flushed to avoid delays
624
+ $ this ->flushGamePacketQueue ();
625
+ $ this ->queueCompressedNoGamePacketFlush ($ payload , $ immediate );
624
626
}finally {
625
627
Timings::$ playerNetworkSend ->stopTiming ();
626
628
}
@@ -631,22 +633,13 @@ public function queueCompressed(CompressBatchPromise|string $payload, bool $imme
631
633
*
632
634
* @phpstan-param list<PromiseResolver<true>> $ackPromises
633
635
*/
634
- private function queueCompressedNoBufferFlush (CompressBatchPromise |string $ batch , bool $ immediate = false , array $ ackPromises = []) : void {
636
+ private function queueCompressedNoGamePacketFlush (CompressBatchPromise |string $ batch , bool $ networkFlush = false , array $ ackPromises = []) : void {
635
637
Timings::$ playerNetworkSend ->startTiming ();
636
638
try {
639
+ $ this ->compressedQueue ->enqueue ([$ batch , $ ackPromises , $ networkFlush ]);
637
640
if (is_string ($ batch )){
638
- if ($ immediate ){
639
- //Skips all queues
640
- $ this ->sendEncoded ($ batch , true , $ ackPromises );
641
- }else {
642
- $ this ->compressedQueue ->enqueue ([$ batch , $ ackPromises ]);
643
- $ this ->flushCompressedQueue ();
644
- }
645
- }elseif ($ immediate ){
646
- //Skips all queues
647
- $ this ->sendEncoded ($ batch ->getResult (), true , $ ackPromises );
641
+ $ this ->flushCompressedQueue ();
648
642
}else {
649
- $ this ->compressedQueue ->enqueue ([$ batch , $ ackPromises ]);
650
643
$ batch ->onResolve (function () : void {
651
644
if ($ this ->connected ){
652
645
$ this ->flushCompressedQueue ();
@@ -663,14 +656,14 @@ private function flushCompressedQueue() : void{
663
656
try {
664
657
while (!$ this ->compressedQueue ->isEmpty ()){
665
658
/** @var CompressBatchPromise|string $current */
666
- [$ current , $ ackPromises ] = $ this ->compressedQueue ->bottom ();
659
+ [$ current , $ ackPromises, $ networkFlush ] = $ this ->compressedQueue ->bottom ();
667
660
if (is_string ($ current )){
668
661
$ this ->compressedQueue ->dequeue ();
669
- $ this ->sendEncoded ($ current , false , $ ackPromises );
662
+ $ this ->sendEncoded ($ current , $ networkFlush , $ ackPromises );
670
663
671
664
}elseif ($ current ->hasResult ()){
672
665
$ this ->compressedQueue ->dequeue ();
673
- $ this ->sendEncoded ($ current ->getResult (), false , $ ackPromises );
666
+ $ this ->sendEncoded ($ current ->getResult (), $ networkFlush , $ ackPromises );
674
667
675
668
}else {
676
669
//can't send any more queued until this one is ready
@@ -710,7 +703,7 @@ private function tryDisconnect(\Closure $func, Translatable|string $reason) : vo
710
703
$ this ->disconnectGuard = true ;
711
704
$ func ();
712
705
$ this ->disconnectGuard = false ;
713
- $ this ->flushSendBuffer ( true );
706
+ $ this ->flushGamePacketQueue ( );
714
707
$ this ->sender ->close ("" );
715
708
foreach ($ this ->disposeHooks as $ callback ){
716
709
$ callback ();
@@ -1345,6 +1338,6 @@ public function tick() : void{
1345
1338
Timings::$ playerNetworkSendInventorySync ->stopTiming ();
1346
1339
}
1347
1340
1348
- $ this ->flushSendBuffer ();
1341
+ $ this ->flushGamePacketQueue ();
1349
1342
}
1350
1343
}
0 commit comments