mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-11 00:09: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;
|
namespace pocketmine;
|
||||||
|
|
||||||
use pocketmine\block\Bed;
|
use pocketmine\block\Bed;
|
||||||
use pocketmine\block\Block;
|
|
||||||
use pocketmine\block\BlockFactory;
|
use pocketmine\block\BlockFactory;
|
||||||
use pocketmine\block\BlockLegacyIds;
|
use pocketmine\block\BlockLegacyIds;
|
||||||
use pocketmine\block\UnknownBlock;
|
use pocketmine\block\UnknownBlock;
|
||||||
@ -117,7 +116,6 @@ use pocketmine\world\format\Chunk;
|
|||||||
use pocketmine\world\Position;
|
use pocketmine\world\Position;
|
||||||
use pocketmine\world\World;
|
use pocketmine\world\World;
|
||||||
use function abs;
|
use function abs;
|
||||||
use function array_merge;
|
|
||||||
use function assert;
|
use function assert;
|
||||||
use function ceil;
|
use function ceil;
|
||||||
use function count;
|
use function count;
|
||||||
@ -1952,7 +1950,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
*
|
*
|
||||||
* @param Vector3 $pos
|
* @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{
|
public function breakBlock(Vector3 $pos) : bool{
|
||||||
$this->doCloseInventory();
|
$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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace pocketmine\network\mcpe\handler;
|
namespace pocketmine\network\mcpe\handler;
|
||||||
|
|
||||||
|
use pocketmine\block\Block;
|
||||||
use pocketmine\block\ItemFrame;
|
use pocketmine\block\ItemFrame;
|
||||||
use pocketmine\block\Sign;
|
use pocketmine\block\Sign;
|
||||||
use pocketmine\block\utils\SignText;
|
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\UseItemOnEntityTransactionData;
|
||||||
use pocketmine\network\mcpe\protocol\types\UseItemTransactionData;
|
use pocketmine\network\mcpe\protocol\types\UseItemTransactionData;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use function array_push;
|
||||||
use function base64_encode;
|
use function base64_encode;
|
||||||
use function fmod;
|
use function fmod;
|
||||||
use function implode;
|
use function implode;
|
||||||
@ -267,10 +269,17 @@ class SimpleSessionHandler extends SessionHandler{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//TODO: end hack for client spam bug
|
//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;
|
return true;
|
||||||
case UseItemTransactionData::ACTION_BREAK_BLOCK:
|
case UseItemTransactionData::ACTION_BREAK_BLOCK:
|
||||||
$this->player->breakBlock($data->getBlockPos());
|
$blockPos = $data->getBlockPos();
|
||||||
|
if(!$this->player->breakBlock($blockPos)){
|
||||||
|
$this->onFailedBlockAction($blockPos, null);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
case UseItemTransactionData::ACTION_CLICK_AIR:
|
case UseItemTransactionData::ACTION_CLICK_AIR:
|
||||||
$this->player->useHeldItem();
|
$this->player->useHeldItem();
|
||||||
@ -280,6 +289,30 @@ class SimpleSessionHandler extends SessionHandler{
|
|||||||
return false;
|
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{
|
private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{
|
||||||
$target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId());
|
$target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId());
|
||||||
if($target === null){
|
if($target === null){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user