InGamePacketHandler: don't resync blocks if the client predicted an interact fail

if the prediction was a fail, we can assume that the client didn't do anything visual on its end,
which avoids the need to resend blocks.
This fixes block lag when towering as discussed in #6803.

The more general issue in #6803 remains unresolved (that the server's block resyncing may overwrite
additional client side predictions if it places a block before the server's resync for the initial
placement arrives), but that's more complicated to fix and I'm not convinced on the correct method
to resolve it yet.

In any case, this change nets a decent improvement for everyone, regardless.
This commit is contained in:
Dylan K. Taylor
2025-09-15 19:36:29 +01:00
parent e7ad3c25fa
commit b237cacfc9

View File

@@ -89,6 +89,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction;
use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\PredictedResult;
use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\ItemStackRequest; use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\ItemStackRequest;
use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse; use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse;
@@ -498,11 +499,13 @@ class InGamePacketHandler extends PacketHandler{
$blockPos = $data->getBlockPosition(); $blockPos = $data->getBlockPosition();
$vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ()); $vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ());
$this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos); $this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos);
if($data->getClientInteractPrediction() === PredictedResult::SUCCESS){
//always sync this in case plugins caused a different result than the client expected //always sync this in case plugins caused a different result than the client expected
//we *could* try to enhance detection of plugin-altered behaviour, but this would require propagating //we *could* try to enhance detection of plugin-altered behaviour, but this would require propagating
//more information up the stack. For now I think this is good enough. //more information up the stack. For now I think this is good enough.
//if only the client would tell us what blocks it thinks changed... //if only the client would tell us what blocks it thinks changed...
$this->syncBlocksNearby($vBlockPos, $data->getFace()); $this->syncBlocksNearby($vBlockPos, $data->getFace());
}
return true; return true;
case UseItemTransactionData::ACTION_CLICK_AIR: case UseItemTransactionData::ACTION_CLICK_AIR:
if($this->player->isUsingItem()){ if($this->player->isUsingItem()){