mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-30 23:29:54 +00:00
Merge remote-tracking branch 'origin/stable' into minor-next
This commit is contained in:
commit
71b78b02d3
@ -115,6 +115,8 @@ abstract class Entity{
|
|||||||
/** @var Block[]|null */
|
/** @var Block[]|null */
|
||||||
protected $blocksAround;
|
protected $blocksAround;
|
||||||
|
|
||||||
|
private bool $checkBlockIntersectionsNextTick = true;
|
||||||
|
|
||||||
/** @var Location */
|
/** @var Location */
|
||||||
protected $location;
|
protected $location;
|
||||||
/** @var Location */
|
/** @var Location */
|
||||||
@ -649,7 +651,10 @@ abstract class Entity{
|
|||||||
|
|
||||||
$hasUpdate = false;
|
$hasUpdate = false;
|
||||||
|
|
||||||
$this->checkBlockIntersections();
|
if($this->checkBlockIntersectionsNextTick){
|
||||||
|
$this->checkBlockIntersections();
|
||||||
|
}
|
||||||
|
$this->checkBlockIntersectionsNextTick = true;
|
||||||
|
|
||||||
if($this->location->y <= World::Y_MIN - 16 && $this->isAlive()){
|
if($this->location->y <= World::Y_MIN - 16 && $this->isAlive()){
|
||||||
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10);
|
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10);
|
||||||
@ -1308,6 +1313,7 @@ abstract class Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function checkBlockIntersections() : void{
|
protected function checkBlockIntersections() : void{
|
||||||
|
$this->checkBlockIntersectionsNextTick = false;
|
||||||
$vectors = [];
|
$vectors = [];
|
||||||
|
|
||||||
foreach($this->getBlocksAroundWithEntityInsideActions() as $block){
|
foreach($this->getBlocksAroundWithEntityInsideActions() as $block){
|
||||||
@ -1319,10 +1325,12 @@ abstract class Entity{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$vector = Vector3::sum(...$vectors);
|
if(count($vectors) > 0){
|
||||||
if($vector->lengthSquared() > 0){
|
$vector = Vector3::sum(...$vectors);
|
||||||
$d = 0.014;
|
if($vector->lengthSquared() > 0){
|
||||||
$this->motion = $this->motion->addVector($vector->normalize()->multiply($d));
|
$d = 0.014;
|
||||||
|
$this->motion = $this->motion->addVector($vector->normalize()->multiply($d));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +57,11 @@ class RegisteredListener{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->timings->startTiming();
|
$this->timings->startTiming();
|
||||||
($this->handler)($event);
|
try{
|
||||||
$this->timings->stopTiming();
|
($this->handler)($event);
|
||||||
|
}finally{
|
||||||
|
$this->timings->stopTiming();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isHandlingCancelled() : bool{
|
public function isHandlingCancelled() : bool{
|
||||||
|
@ -353,30 +353,35 @@ class Item implements \JsonSerializable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function serializeCompoundTag(CompoundTag $tag) : void{
|
protected function serializeCompoundTag(CompoundTag $tag) : void{
|
||||||
$display = $tag->getCompoundTag(self::TAG_DISPLAY) ?? new CompoundTag();
|
$display = $tag->getCompoundTag(self::TAG_DISPLAY);
|
||||||
|
|
||||||
$this->hasCustomName() ?
|
if($this->customName !== ""){
|
||||||
$display->setString(self::TAG_DISPLAY_NAME, $this->getCustomName()) :
|
$display ??= new CompoundTag();
|
||||||
$display->removeTag(self::TAG_DISPLAY_NAME);
|
$display->setString(self::TAG_DISPLAY_NAME, $this->customName);
|
||||||
|
}else{
|
||||||
|
$display?->removeTag(self::TAG_DISPLAY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
if(count($this->lore) > 0){
|
if(count($this->lore) > 0){
|
||||||
$loreTag = new ListTag();
|
$loreTag = new ListTag();
|
||||||
foreach($this->lore as $line){
|
foreach($this->lore as $line){
|
||||||
$loreTag->push(new StringTag($line));
|
$loreTag->push(new StringTag($line));
|
||||||
}
|
}
|
||||||
|
$display ??= new CompoundTag();
|
||||||
$display->setTag(self::TAG_DISPLAY_LORE, $loreTag);
|
$display->setTag(self::TAG_DISPLAY_LORE, $loreTag);
|
||||||
}else{
|
}else{
|
||||||
$display->removeTag(self::TAG_DISPLAY_LORE);
|
$display?->removeTag(self::TAG_DISPLAY_LORE);
|
||||||
}
|
}
|
||||||
$display->count() > 0 ?
|
$display !== null && $display->count() > 0 ?
|
||||||
$tag->setTag(self::TAG_DISPLAY, $display) :
|
$tag->setTag(self::TAG_DISPLAY, $display) :
|
||||||
$tag->removeTag(self::TAG_DISPLAY);
|
$tag->removeTag(self::TAG_DISPLAY);
|
||||||
|
|
||||||
if($this->hasEnchantments()){
|
if(count($this->enchantments) > 0){
|
||||||
$ench = new ListTag();
|
$ench = new ListTag();
|
||||||
foreach($this->getEnchantments() as $enchantmentInstance){
|
$enchantmentIdMap = EnchantmentIdMap::getInstance();
|
||||||
|
foreach($this->enchantments as $enchantmentInstance){
|
||||||
$ench->push(CompoundTag::create()
|
$ench->push(CompoundTag::create()
|
||||||
->setShort(self::TAG_ENCH_ID, EnchantmentIdMap::getInstance()->toId($enchantmentInstance->getType()))
|
->setShort(self::TAG_ENCH_ID, $enchantmentIdMap->toId($enchantmentInstance->getType()))
|
||||||
->setShort(self::TAG_ENCH_LVL, $enchantmentInstance->getLevel())
|
->setShort(self::TAG_ENCH_LVL, $enchantmentInstance->getLevel())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -385,8 +390,8 @@ class Item implements \JsonSerializable{
|
|||||||
$tag->removeTag(self::TAG_ENCH);
|
$tag->removeTag(self::TAG_ENCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
($blockData = $this->getCustomBlockData()) !== null ?
|
$this->blockEntityTag !== null ?
|
||||||
$tag->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $blockData) :
|
$tag->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $this->blockEntityTag) :
|
||||||
$tag->removeTag(self::TAG_BLOCK_ENTITY_TAG);
|
$tag->removeTag(self::TAG_BLOCK_ENTITY_TAG);
|
||||||
|
|
||||||
if(count($this->canPlaceOn) > 0){
|
if(count($this->canPlaceOn) > 0){
|
||||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace pocketmine\network\mcpe\convert;
|
namespace pocketmine\network\mcpe\convert;
|
||||||
|
|
||||||
|
use pocketmine\block\Block;
|
||||||
use pocketmine\block\BlockLegacyIds;
|
use pocketmine\block\BlockLegacyIds;
|
||||||
use pocketmine\item\Durable;
|
use pocketmine\item\Durable;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
@ -135,14 +136,16 @@ class TypeConverter{
|
|||||||
if($itemStack->isNull()){
|
if($itemStack->isNull()){
|
||||||
return ItemStack::null();
|
return ItemStack::null();
|
||||||
}
|
}
|
||||||
$nbt = null;
|
$nbt = $itemStack->getNamedTag();
|
||||||
if($itemStack->hasNamedTag()){
|
if($nbt->count() === 0){
|
||||||
$nbt = clone $itemStack->getNamedTag();
|
$nbt = null;
|
||||||
|
}else{
|
||||||
|
$nbt = clone $nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
$isBlockItem = $itemStack->getId() < 256;
|
$internalId = $itemStack->getId();
|
||||||
|
$internalMeta = $itemStack->getMeta();
|
||||||
$idMeta = ItemTranslator::getInstance()->toNetworkIdQuiet($itemStack->getId(), $itemStack->getMeta());
|
$idMeta = ItemTranslator::getInstance()->toNetworkIdQuiet($internalId, $internalMeta);
|
||||||
if($idMeta === null){
|
if($idMeta === null){
|
||||||
//Display unmapped items as INFO_UPDATE, but stick something in their NBT to make sure they don't stack with
|
//Display unmapped items as INFO_UPDATE, but stick something in their NBT to make sure they don't stack with
|
||||||
//other unmapped items.
|
//other unmapped items.
|
||||||
@ -150,8 +153,8 @@ class TypeConverter{
|
|||||||
if($nbt === null){
|
if($nbt === null){
|
||||||
$nbt = new CompoundTag();
|
$nbt = new CompoundTag();
|
||||||
}
|
}
|
||||||
$nbt->setInt(self::PM_ID_TAG, $itemStack->getId());
|
$nbt->setInt(self::PM_ID_TAG, $internalId);
|
||||||
$nbt->setInt(self::PM_META_TAG, $itemStack->getMeta());
|
$nbt->setInt(self::PM_META_TAG, $internalMeta);
|
||||||
}else{
|
}else{
|
||||||
[$id, $meta] = $idMeta;
|
[$id, $meta] = $idMeta;
|
||||||
|
|
||||||
@ -166,23 +169,15 @@ class TypeConverter{
|
|||||||
}
|
}
|
||||||
$nbt->setInt(self::DAMAGE_TAG, $itemStack->getDamage());
|
$nbt->setInt(self::DAMAGE_TAG, $itemStack->getDamage());
|
||||||
$meta = 0;
|
$meta = 0;
|
||||||
}elseif($isBlockItem && $itemStack->getMeta() !== 0){
|
|
||||||
//TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the
|
|
||||||
//client sends it back to us, because as of 1.16.220, blockitems quietly discard their metadata
|
|
||||||
//client-side. Aside from being very annoying, this also breaks various server-side behaviours.
|
|
||||||
if($nbt === null){
|
|
||||||
$nbt = new CompoundTag();
|
|
||||||
}
|
|
||||||
$nbt->setInt(self::PM_META_TAG, $itemStack->getMeta());
|
|
||||||
$meta = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$blockRuntimeId = 0;
|
$blockRuntimeId = 0;
|
||||||
if($isBlockItem){
|
if($internalId < 256){
|
||||||
$block = $itemStack->getBlock();
|
$block = $itemStack->getBlock();
|
||||||
if($block->getId() !== BlockLegacyIds::AIR){
|
if($block->getId() !== BlockLegacyIds::AIR){
|
||||||
$blockRuntimeId = RuntimeBlockMapping::getInstance()->toRuntimeId($block->getFullId());
|
$blockRuntimeId = RuntimeBlockMapping::getInstance()->toRuntimeId($block->getFullId());
|
||||||
|
$meta = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +203,11 @@ class TypeConverter{
|
|||||||
$compound = $itemStack->getNbt();
|
$compound = $itemStack->getNbt();
|
||||||
|
|
||||||
[$id, $meta] = ItemTranslator::getInstance()->fromNetworkId($itemStack->getId(), $itemStack->getMeta());
|
[$id, $meta] = ItemTranslator::getInstance()->fromNetworkId($itemStack->getId(), $itemStack->getMeta());
|
||||||
|
if($itemStack->getBlockRuntimeId() !== 0){
|
||||||
|
//blockitem meta is zeroed out by the client, so we have to infer it from the block runtime ID
|
||||||
|
$blockFullId = RuntimeBlockMapping::getInstance()->fromRuntimeId($itemStack->getBlockRuntimeId());
|
||||||
|
$meta = $blockFullId & Block::INTERNAL_METADATA_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
if($compound !== null){
|
if($compound !== null){
|
||||||
$compound = clone $compound;
|
$compound = clone $compound;
|
||||||
@ -222,12 +222,6 @@ class TypeConverter{
|
|||||||
$compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION);
|
$compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION);
|
||||||
$compound->setTag(self::DAMAGE_TAG, $conflicted);
|
$compound->setTag(self::DAMAGE_TAG, $conflicted);
|
||||||
}
|
}
|
||||||
}elseif(($metaTag = $compound->getTag(self::PM_META_TAG)) instanceof IntTag){
|
|
||||||
//TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the
|
|
||||||
//client sends it back to us, because as of 1.16.220, blockitems quietly discard their metadata
|
|
||||||
//client-side. Aside from being very annoying, this also breaks various server-side behaviours.
|
|
||||||
$meta = $metaTag->getValue();
|
|
||||||
$compound->removeTag(self::PM_META_TAG);
|
|
||||||
}
|
}
|
||||||
if($compound->count() === 0){
|
if($compound->count() === 0){
|
||||||
$compound = null;
|
$compound = null;
|
||||||
|
@ -53,6 +53,7 @@ use function implode;
|
|||||||
use function mt_rand;
|
use function mt_rand;
|
||||||
use function random_bytes;
|
use function random_bytes;
|
||||||
use function rtrim;
|
use function rtrim;
|
||||||
|
use function str_split;
|
||||||
use function substr;
|
use function substr;
|
||||||
use const PHP_INT_MAX;
|
use const PHP_INT_MAX;
|
||||||
|
|
||||||
@ -196,7 +197,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
|||||||
try{
|
try{
|
||||||
$session->handleEncoded($buf);
|
$session->handleEncoded($buf);
|
||||||
}catch(PacketHandlingException $e){
|
}catch(PacketHandlingException $e){
|
||||||
$errorId = bin2hex(random_bytes(6));
|
$errorId = implode("-", str_split(bin2hex(random_bytes(6)), 4));
|
||||||
|
|
||||||
$logger = $session->getLogger();
|
$logger = $session->getLogger();
|
||||||
$logger->error("Bad packet (error ID $errorId): " . $e->getMessage());
|
$logger->error("Bad packet (error ID $errorId): " . $e->getMessage());
|
||||||
|
@ -24,12 +24,10 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\tools\simulate_chunk_selector;
|
namespace pocketmine\tools\simulate_chunk_selector;
|
||||||
|
|
||||||
use pocketmine\player\ChunkSelector;
|
use pocketmine\player\ChunkSelector;
|
||||||
use pocketmine\utils\AssumptionFailedError;
|
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
use pocketmine\world\format\Chunk;
|
use pocketmine\world\format\Chunk;
|
||||||
use pocketmine\world\World;
|
use pocketmine\world\World;
|
||||||
use Symfony\Component\Filesystem\Path;
|
use Symfony\Component\Filesystem\Path;
|
||||||
use function assert;
|
|
||||||
use function count;
|
use function count;
|
||||||
use function dirname;
|
use function dirname;
|
||||||
use function fwrite;
|
use function fwrite;
|
||||||
@ -128,7 +126,12 @@ if(count(getopt("", ["help"])) !== 0){
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Utils::stringifyKeys(getopt("", ["radius:", "baseX:", "baseZ:", "scale:", "chunksPerStep:"])) as $name => $value){
|
$opts = getopt("", ["radius:", "baseX:", "baseZ:", "scale:", "chunksPerStep:", "output:"]);
|
||||||
|
foreach(["radius", "baseX", "baseZ", "scale", "chunksPerStep"] as $name){
|
||||||
|
$value = $opts[$name] ?? null;
|
||||||
|
if($value === null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(!is_string($value) || (string) ((int) $value) !== $value){
|
if(!is_string($value) || (string) ((int) $value) !== $value){
|
||||||
fwrite(STDERR, "Value for --$name must be an integer\n");
|
fwrite(STDERR, "Value for --$name must be an integer\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -139,8 +142,7 @@ foreach(Utils::stringifyKeys(getopt("", ["radius:", "baseX:", "baseZ:", "scale:"
|
|||||||
"baseX" => ($baseX = $value),
|
"baseX" => ($baseX = $value),
|
||||||
"baseZ" => ($baseZ = $value),
|
"baseZ" => ($baseZ = $value),
|
||||||
"scale" => ($scale = $value),
|
"scale" => ($scale = $value),
|
||||||
"chunksPerStep" => ($nChunksPerStep = $value),
|
"chunksPerStep" => ($nChunksPerStep = $value)
|
||||||
default => throw new AssumptionFailedError("getopt() returned unknown option")
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if($radius === null){
|
if($radius === null){
|
||||||
@ -149,10 +151,10 @@ if($radius === null){
|
|||||||
}
|
}
|
||||||
|
|
||||||
$outputDirectory = null;
|
$outputDirectory = null;
|
||||||
foreach(Utils::stringifyKeys(getopt("", ["output:"])) as $name => $value){
|
if(isset($opts["output"])){
|
||||||
assert($name === "output");
|
$value = $opts["output"];
|
||||||
if(!is_string($value)){
|
if(!is_string($value)){
|
||||||
fwrite(STDERR, "Value for --$name must be a string\n");
|
fwrite(STDERR, "Value for --output be a string\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(!@mkdir($value) && !is_dir($value)){
|
if(!@mkdir($value) && !is_dir($value)){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user