mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-10 15:59:39 +00:00
Player: Move rollback responsibility to network for interact/break block
Custom player implementations might not need rollbacks (f.e. Specter).
This commit is contained in:
parent
ca7c23c137
commit
51a8c2be9d
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\block\Bed;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\BlockLegacyIds;
|
||||
use pocketmine\block\UnknownBlock;
|
||||
@ -117,7 +116,6 @@ use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\World;
|
||||
use function abs;
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
use function ceil;
|
||||
use function count;
|
||||
@ -1952,7 +1950,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
*
|
||||
* @return bool if the block was successfully broken.
|
||||
* @return bool if the block was successfully broken, false if a rollback needs to take place.
|
||||
*/
|
||||
public function breakBlock(Vector3 $pos) : bool{
|
||||
$this->doCloseInventory();
|
||||
@ -1969,16 +1967,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
||||
}
|
||||
}
|
||||
|
||||
$this->inventory->sendContents($this);
|
||||
$this->inventory->sendHeldItem($this);
|
||||
|
||||
$target = $this->world->getBlock($pos);
|
||||
/** @var Block[] $blocks */
|
||||
$blocks = $target->getAllSides();
|
||||
$blocks[] = $target;
|
||||
|
||||
$this->world->sendBlocks([$this], $blocks);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2005,20 +1993,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
||||
}
|
||||
}
|
||||
|
||||
$this->inventory->sendHeldItem($this);
|
||||
|
||||
if($pos->distanceSquared($this) > 10000){
|
||||
return true;
|
||||
}
|
||||
|
||||
$target = $this->world->getBlock($pos);
|
||||
$block = $target->getSide($face);
|
||||
|
||||
/** @var Block[] $blocks */
|
||||
$blocks = array_merge($target->getAllSides(), $block->getAllSides()); //getAllSides() on each of these will include $target and $block because they are next to each other
|
||||
|
||||
$this->world->sendBlocks([$this], $blocks);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\handler;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\ItemFrame;
|
||||
use pocketmine\block\Sign;
|
||||
use pocketmine\block\utils\SignText;
|
||||
@ -78,6 +79,7 @@ use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\UseItemTransactionData;
|
||||
use pocketmine\Player;
|
||||
use function array_push;
|
||||
use function base64_encode;
|
||||
use function fmod;
|
||||
use function implode;
|
||||
@ -267,10 +269,17 @@ class SimpleSessionHandler extends SessionHandler{
|
||||
return true;
|
||||
}
|
||||
//TODO: end hack for client spam bug
|
||||
$this->player->interactBlock($data->getBlockPos(), $data->getFace(), $clickPos);
|
||||
|
||||
$blockPos = $data->getBlockPos();
|
||||
if(!$this->player->interactBlock($blockPos, $data->getFace(), $clickPos)){
|
||||
$this->onFailedBlockAction($blockPos, $data->getFace());
|
||||
}
|
||||
return true;
|
||||
case UseItemTransactionData::ACTION_BREAK_BLOCK:
|
||||
$this->player->breakBlock($data->getBlockPos());
|
||||
$blockPos = $data->getBlockPos();
|
||||
if(!$this->player->breakBlock($blockPos)){
|
||||
$this->onFailedBlockAction($blockPos, null);
|
||||
}
|
||||
return true;
|
||||
case UseItemTransactionData::ACTION_CLICK_AIR:
|
||||
$this->player->useHeldItem();
|
||||
@ -280,6 +289,30 @@ class SimpleSessionHandler extends SessionHandler{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used to execute rollbacks when an action fails on a block.
|
||||
*
|
||||
* @param Vector3 $blockPos
|
||||
* @param int|null $face
|
||||
*/
|
||||
private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{
|
||||
$this->player->getInventory()->sendHeldItem($this->player);
|
||||
if($blockPos->distanceSquared($this->player) < 10000){
|
||||
$target = $this->player->getWorld()->getBlock($blockPos);
|
||||
|
||||
$blocks = $target->getAllSides();
|
||||
if($face !== null){
|
||||
$sideBlock = $target->getSide($face);
|
||||
|
||||
/** @var Block[] $blocks */
|
||||
array_push($blocks, ...$sideBlock->getAllSides()); //getAllSides() on each of these will include $target and $sideBlock because they are next to each other
|
||||
}else{
|
||||
$blocks[] = $target;
|
||||
}
|
||||
$this->player->getWorld()->sendBlocks([$this->player], $blocks);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{
|
||||
$target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId());
|
||||
if($target === null){
|
||||
|
Loading…
x
Reference in New Issue
Block a user