mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 02:42:58 +00:00
Merge branch 'stable' into minor-next
This commit is contained in:
@ -341,7 +341,7 @@ JIT_WARNING
|
||||
|
||||
if(ThreadManager::getInstance()->stopAll() > 0){
|
||||
$logger->debug("Some threads could not be stopped, performing a force-kill");
|
||||
Process::kill(Process::pid(), true);
|
||||
Process::kill(Process::pid());
|
||||
}
|
||||
}while(false);
|
||||
|
||||
|
@ -1427,7 +1427,7 @@ class Server{
|
||||
|
||||
private function forceShutdownExit() : void{
|
||||
$this->forceShutdown();
|
||||
Process::kill(Process::pid(), true);
|
||||
Process::kill(Process::pid());
|
||||
}
|
||||
|
||||
public function forceShutdown() : void{
|
||||
@ -1495,7 +1495,7 @@ class Server{
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->logException($e);
|
||||
$this->logger->emergency("Crashed while crashing, killing process");
|
||||
@Process::kill(Process::pid(), true);
|
||||
@Process::kill(Process::pid());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1649,7 +1649,7 @@ class Server{
|
||||
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
|
||||
sleep($spacing);
|
||||
}
|
||||
@Process::kill(Process::pid(), true);
|
||||
@Process::kill(Process::pid());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockBurnEvent;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
@ -58,12 +59,16 @@ class Fire extends BaseFire{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->equals(SupportType::FULL());
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(SoulFire::canBeSupportedBy($down)){
|
||||
$world->setBlock($this->position, VanillaBlocks::SOUL_FIRE());
|
||||
}elseif($down->isTransparent() && !$this->hasAdjacentFlammableBlocks()){
|
||||
}elseif(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->hasAdjacentFlammableBlocks()){
|
||||
$world->setBlock($this->position, VanillaBlocks::AIR());
|
||||
}else{
|
||||
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));
|
||||
|
@ -48,12 +48,7 @@ class FrostedIce extends Ice{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->checkAdjacentBlocks(2)){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40));
|
||||
}
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40));
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\ShulkerBox as TileShulkerBox;
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -110,4 +111,8 @@ class ShulkerBox extends Opaque{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class KillCommand extends VanillaCommand{
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000));
|
||||
$player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, $player->getHealth()));
|
||||
if($player === $sender){
|
||||
$sender->sendMessage(KnownTranslationFactory::commands_kill_successful($sender->getName()));
|
||||
}else{
|
||||
|
@ -94,4 +94,4 @@ while(!feof($socket)){
|
||||
//For simplicity's sake, we don't bother with a graceful shutdown here.
|
||||
//The parent process would normally forcibly terminate the child process anyway, so we only reach this point if the
|
||||
//parent process was terminated forcibly and didn't clean up after itself.
|
||||
Process::kill(Process::pid(), false);
|
||||
Process::kill(Process::pid());
|
||||
|
@ -520,7 +520,9 @@ abstract class Living extends Entity{
|
||||
$source->cancel();
|
||||
}
|
||||
|
||||
$this->applyDamageModifiers($source);
|
||||
if($source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE){
|
||||
$this->applyDamageModifiers($source);
|
||||
}
|
||||
|
||||
if($source instanceof EntityDamageByEntityEvent && (
|
||||
$source->getCause() === EntityDamageEvent::CAUSE_BLOCK_EXPLOSION ||
|
||||
|
@ -139,6 +139,6 @@ final class StandardEntityEventBroadcaster implements EntityEventBroadcaster{
|
||||
}
|
||||
|
||||
public function onEmote(array $recipients, Human $from, string $emoteId) : void{
|
||||
$this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER));
|
||||
$this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER | EmotePacket::FLAG_MUTE_ANNOUNCEMENT));
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use const M_SQRT2;
|
||||
final class ChunkSelector{
|
||||
|
||||
/**
|
||||
* @preturn \Generator|int[]
|
||||
* @return \Generator|int[]
|
||||
* @phpstan-return \Generator<int, int, void, void>
|
||||
*/
|
||||
public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{
|
||||
|
@ -125,7 +125,10 @@ final class Process{
|
||||
return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread
|
||||
}
|
||||
|
||||
public static function kill(int $pid, bool $subprocesses) : void{
|
||||
/**
|
||||
* @param bool $subprocesses @deprecated
|
||||
*/
|
||||
public static function kill(int $pid, bool $subprocesses = false) : void{
|
||||
$logger = \GlobalLogger::get();
|
||||
if($logger instanceof MainLogger){
|
||||
$logger->syncFlushBuffer();
|
||||
|
@ -42,7 +42,7 @@ class ServerKiller extends Thread{
|
||||
});
|
||||
if(time() - $start >= $this->time){
|
||||
echo "\nTook too long to stop, server was killed forcefully!\n";
|
||||
@Process::kill(Process::pid(), true);
|
||||
@Process::kill(Process::pid());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\block\Block;
|
||||
use pocketmine\data\bedrock\BiomeIds;
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use pocketmine\nbt\LittleEndianNbtSerializer;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\NbtDataException;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\TreeRoot;
|
||||
@ -155,7 +156,33 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$nbt = new LittleEndianNbtSerializer();
|
||||
$palette = [];
|
||||
|
||||
$paletteSize = $bitsPerBlock === 0 ? 1 : $stream->getLInt();
|
||||
if($bitsPerBlock === 0){
|
||||
$paletteSize = 1;
|
||||
/*
|
||||
* Due to code copy-paste in a public plugin, some PM4 worlds have 0 bpb palettes with a length prefix.
|
||||
* This is invalid and does not happen in vanilla.
|
||||
* These palettes were accepted by PM4 despite being invalid, but PM5 considered them corrupt, causing loss
|
||||
* of data. Since many users were affected by this, a workaround is therefore necessary to allow PM5 to read
|
||||
* these worlds without data loss.
|
||||
*
|
||||
* References:
|
||||
* - https://github.com/Refaltor77/CustomItemAPI/issues/68
|
||||
* - https://github.com/pmmp/PocketMine-MP/issues/5911
|
||||
*/
|
||||
$offset = $stream->getOffset();
|
||||
$byte1 = $stream->getByte();
|
||||
$stream->setOffset($offset); //reset offset
|
||||
|
||||
if($byte1 !== NBT::TAG_Compound){ //normally the first byte would be the NBT of the blockstate
|
||||
$susLength = $stream->getLInt();
|
||||
if($susLength !== 1){ //make sure the data isn't complete garbage
|
||||
throw new CorruptedChunkException("CustomItemAPI borked 0 bpb palette should always have a length of 1");
|
||||
}
|
||||
$logger->error("Unexpected palette size for 0 bpb palette");
|
||||
}
|
||||
}else{
|
||||
$paletteSize = $stream->getLInt();
|
||||
}
|
||||
|
||||
for($i = 0; $i < $paletteSize; ++$i){
|
||||
try{
|
||||
@ -276,6 +303,10 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$previous = $decoded;
|
||||
if($nextIndex <= Chunk::MAX_SUBCHUNK_INDEX){ //older versions wrote additional superfluous biome palettes
|
||||
$result[$nextIndex++] = $decoded;
|
||||
}elseif($stream->feof()){
|
||||
//not enough padding biome arrays for the given version - this is non-critical since we discard the excess anyway, but this should be logged
|
||||
$logger->error("Wrong number of 3D biome palettes for this chunk version: expected $expectedCount, but got " . ($i + 1) . " - this is not a problem, but may indicate a corrupted chunk");
|
||||
break;
|
||||
}
|
||||
}catch(BinaryDataException $e){
|
||||
throw new CorruptedChunkException("Failed to deserialize biome palette $i: " . $e->getMessage(), 0, $e);
|
||||
|
Reference in New Issue
Block a user