Merge branch 'minor-next' into major-next

This commit is contained in:
Dylan K. Taylor
2023-05-17 15:45:03 +01:00
20 changed files with 150 additions and 204 deletions

View File

@@ -50,7 +50,7 @@ namespace pocketmine {
require_once __DIR__ . '/VersionInfo.php';
const MIN_PHP_VERSION = "8.0.0";
const MIN_PHP_VERSION = "8.1.0";
/**
* @param string $message
@@ -265,9 +265,6 @@ JIT_WARNING
exit(1);
}
}
if(extension_loaded('parallel')){
\parallel\bootstrap(\pocketmine\COMPOSER_AUTOLOADER_PATH);
}
ErrorToExceptionHandler::set();

View File

@@ -205,6 +205,8 @@ class Server{
private const TICKS_PER_TPS_OVERLOAD_WARNING = 5 * self::TARGET_TICKS_PER_SECOND;
private const TICKS_PER_STATS_REPORT = 300 * self::TARGET_TICKS_PER_SECOND;
private const DEFAULT_ASYNC_COMPRESSION_THRESHOLD = 10_000;
private static ?Server $instance = null;
private TimeTrackingSleeperHandler $tickSleeper;
@@ -263,6 +265,7 @@ class Server{
private Network $network;
private bool $networkCompressionAsync = true;
private int $networkCompressionAsyncThreshold = self::DEFAULT_ASYNC_COMPRESSION_THRESHOLD;
private Language $language;
private bool $forceLanguage = false;
@@ -901,6 +904,10 @@ class Server{
ZlibCompressor::setInstance(new ZlibCompressor($netCompressionLevel, $netCompressionThreshold, ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE));
$this->networkCompressionAsync = $this->configGroup->getPropertyBool("network.async-compression", true);
$this->networkCompressionAsyncThreshold = max(
$this->configGroup->getPropertyInt("network.async-compression-threshold", self::DEFAULT_ASYNC_COMPRESSION_THRESHOLD),
$netCompressionThreshold ?? self::DEFAULT_ASYNC_COMPRESSION_THRESHOLD
);
EncryptionContext::$ENABLED = $this->configGroup->getPropertyBool("network.enable-encryption", true);
@@ -1359,7 +1366,7 @@ class Server{
}
$promise = new CompressBatchPromise();
if(!$sync){
if(!$sync && strlen($buffer) >= $this->networkCompressionAsyncThreshold){
$task = new CompressBatchTask($buffer, $promise, $compressor);
$this->asyncPool->submitTask($task);
}else{

View File

@@ -106,7 +106,6 @@ use pocketmine\utils\BinaryDataException;
use pocketmine\utils\BinaryStream;
use pocketmine\utils\ObjectSet;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use pocketmine\world\Position;
use function array_map;
use function array_values;
@@ -1049,8 +1048,6 @@ class NetworkSession{
* @phpstan-param \Closure() : void $onCompletion
*/
public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{
Utils::validateCallableSignature(function() : void{}, $onCompletion);
$world = $this->player->getLocation()->getWorld();
ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve(

View File

@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\compression;
use pocketmine\utils\Utils;
use function array_push;
class CompressBatchPromise{
@@ -42,9 +41,6 @@ class CompressBatchPromise{
*/
public function onResolve(\Closure ...$callbacks) : void{
$this->checkCancelled();
foreach($callbacks as $callback){
Utils::validateCallableSignature(function(CompressBatchPromise $promise) : void{}, $callback);
}
if($this->result !== null){
foreach($callbacks as $callback){
$callback($this);

View File

@@ -1192,7 +1192,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* TODO: make this a dynamic ability instead of being hardcoded
*/
public function hasFiniteResources() : bool{
return $this->gamemode->equals(GameMode::SURVIVAL()) || $this->gamemode->equals(GameMode::ADVENTURE());
return !$this->gamemode->equals(GameMode::CREATIVE());
}
public function isFireProof() : bool{
@@ -1685,7 +1685,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$ev = new PlayerBlockPickEvent($this, $block, $item);
$existingSlot = $this->inventory->first($item);
if($existingSlot === -1 && ($this->hasFiniteResources() || $this->isSpectator())){
if($existingSlot === -1 && $this->hasFiniteResources()){
$ev->cancel();
}
$ev->call();

View File

@@ -242,7 +242,6 @@ class AsyncPool{
while(!$queue->isEmpty()){
/** @var AsyncTask $task */
$task = $queue->bottom();
$task->checkProgressUpdates();
if($task->isFinished()){ //make sure the task actually executed before trying to collect
$queue->dequeue();
@@ -263,6 +262,7 @@ class AsyncPool{
$task->onCompletion();
}
}else{
$task->checkProgressUpdates();
$more = true;
break; //current task is still running, skip to next worker
}

View File

@@ -59,10 +59,6 @@ abstract class Timings{
public static TimingsHandler $connection;
public static TimingsHandler $scheduler;
public static TimingsHandler $serverCommand;
public static TimingsHandler $worldLoad;
public static TimingsHandler $worldSave;
public static TimingsHandler $population;
public static TimingsHandler $generationCallback;
public static TimingsHandler $permissibleCalculation;
public static TimingsHandler $permissibleCalculationDiff;
public static TimingsHandler $permissibleCalculationCallback;
@@ -71,8 +67,6 @@ abstract class Timings{
public static TimingsHandler $projectileMove;
public static TimingsHandler $projectileMoveRayTrace;
public static TimingsHandler $playerCheckNearEntities;
public static TimingsHandler $tickEntity;
public static TimingsHandler $tickTileEntity;
public static TimingsHandler $entityBaseTick;
public static TimingsHandler $livingEntityBaseTick;
public static TimingsHandler $itemEntityBaseTick;
@@ -155,10 +149,6 @@ abstract class Timings{
self::$playerChunkSend = new TimingsHandler("Player Network Send - Chunks", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN);
self::$scheduler = new TimingsHandler("Scheduler");
self::$serverCommand = new TimingsHandler("Server Command");
self::$worldLoad = new TimingsHandler("World Load");
self::$worldSave = new TimingsHandler("World Save");
self::$population = new TimingsHandler("World Population");
self::$generationCallback = new TimingsHandler("World Generation Callback");
self::$permissibleCalculation = new TimingsHandler("Permissible Calculation");
self::$permissibleCalculationDiff = new TimingsHandler("Permissible Calculation - Diff", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN);
self::$permissibleCalculationCallback = new TimingsHandler("Permissible Calculation - Callbacks", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN);
@@ -173,9 +163,6 @@ abstract class Timings{
self::$projectileMoveRayTrace = new TimingsHandler("Projectile Movement - Ray Tracing", self::$projectileMove, group: self::GROUP_BREAKDOWN);
self::$playerCheckNearEntities = new TimingsHandler("checkNearEntities", group: self::GROUP_BREAKDOWN);
self::$tickEntity = new TimingsHandler("Entity Tick", group: self::GROUP_BREAKDOWN);
self::$tickTileEntity = new TimingsHandler("Block Entity Tick", group: self::GROUP_BREAKDOWN);
self::$entityBaseTick = new TimingsHandler("Entity Base Tick", group: self::GROUP_BREAKDOWN);
self::$livingEntityBaseTick = new TimingsHandler("Entity Base Tick - Living", group: self::GROUP_BREAKDOWN);
self::$itemEntityBaseTick = new TimingsHandler("Entity Base Tick - ItemEntity", group: self::GROUP_BREAKDOWN);
@@ -226,7 +213,7 @@ abstract class Timings{
}else{
$displayName = self::shortenCoreClassName($entity::class, "pocketmine\\entity\\");
}
self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName, self::$tickEntity, group: self::GROUP_BREAKDOWN);
self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName, group: self::GROUP_BREAKDOWN);
}
return self::$entityTypeTimingMap[$entity::class];
@@ -237,7 +224,6 @@ abstract class Timings{
if(!isset(self::$tileEntityTypeTimingMap[$tile::class])){
self::$tileEntityTypeTimingMap[$tile::class] = new TimingsHandler(
"Block Entity Tick - " . self::shortenCoreClassName($tile::class, "pocketmine\\block\\tile\\"),
self::$tickTileEntity,
group: self::GROUP_BREAKDOWN
);
}

View File

@@ -30,7 +30,7 @@ use function implode;
use function spl_object_id;
class TimingsHandler{
private const FORMAT_VERSION = 1;
private const FORMAT_VERSION = 2; //peak timings fix
private static bool $enabled = false;
private static int $timingStart = 0;

View File

@@ -66,9 +66,6 @@ final class TimingsRecord{
if($record->curTickTotal > Server::TARGET_NANOSECONDS_PER_TICK){
$record->violations += (int) floor($record->curTickTotal / Server::TARGET_NANOSECONDS_PER_TICK);
}
if($record->curTickTotal > $record->peakTime){
$record->peakTime = $record->curTickTotal;
}
$record->curTickTotal = 0;
$record->curCount = 0;
$record->ticksActive++;
@@ -126,7 +123,7 @@ final class TimingsRecord{
public function getTicksActive() : int{ return $this->ticksActive; }
public function getPeakTime() : float{ return $this->peakTime; }
public function getPeakTime() : int{ return $this->peakTime; }
public function startTiming(int $now) : void{
$this->start = $now;
@@ -152,6 +149,9 @@ final class TimingsRecord{
++$this->curCount;
++$this->count;
$this->start = 0;
if($diff > $this->peakTime){
$this->peakTime = $diff;
}
}
public static function getCurrentRecord() : ?self{

View File

@@ -79,7 +79,6 @@ use pocketmine\promise\PromiseResolver;
use pocketmine\scheduler\AsyncPool;
use pocketmine\Server;
use pocketmine\ServerConfigGroup;
use pocketmine\timings\Timings;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Limits;
use pocketmine\utils\ReversePriorityQueue;
@@ -980,7 +979,6 @@ class World implements ChunkManager{
$this->timings->entityTick->startTiming();
//Update entities that need update
Timings::$tickEntity->startTiming();
foreach($this->updateEntities as $id => $entity){
if($entity->isClosed() || $entity->isFlaggedForDespawn() || !$entity->onUpdate($currentTick)){
unset($this->updateEntities[$id]);
@@ -989,7 +987,6 @@ class World implements ChunkManager{
$entity->close();
}
}
Timings::$tickEntity->stopTiming();
$this->timings->entityTick->stopTiming();
$this->timings->randomChunkUpdates->startTiming();
@@ -1385,10 +1382,15 @@ class World implements ChunkManager{
(new WorldSaveEvent($this))->call();
$timings = $this->timings->syncDataSave;
$timings->startTiming();
$this->provider->getWorldData()->setTime($this->time);
$this->saveChunks();
$this->provider->getWorldData()->save();
$timings->stopTiming();
return true;
}
@@ -3191,7 +3193,8 @@ class World implements ChunkManager{
private function internalOrderChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader, ?PromiseResolver $resolver) : Promise{
$chunkHash = World::chunkHash($chunkX, $chunkZ);
Timings::$population->startTiming();
$timings = $this->timings->chunkPopulationOrder;
$timings->startTiming();
try{
for($xx = -1; $xx <= 1; ++$xx){
@@ -3248,7 +3251,7 @@ class World implements ChunkManager{
return $resolver->getPromise();
}finally{
Timings::$population->stopTiming();
$timings->stopTiming();
}
}
@@ -3257,7 +3260,8 @@ class World implements ChunkManager{
* @phpstan-param array<int, Chunk> $adjacentChunks
*/
private function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{
Timings::$generationCallback->startTiming();
$timings = $this->timings->chunkPopulationCompletion;
$timings->startTiming();
$dirtyChunks = 0;
for($xx = -1; $xx <= 1; ++$xx){
@@ -3326,7 +3330,7 @@ class World implements ChunkManager{
$this->drainPopulationRequestQueue();
}
Timings::$generationCallback->stopTiming();
$timings->stopTiming();
}
public function doChunkGarbageCollection() : void{

View File

@@ -30,7 +30,6 @@ use pocketmine\event\world\WorldUnloadEvent;
use pocketmine\lang\KnownTranslationFactory;
use pocketmine\player\ChunkSelector;
use pocketmine\Server;
use pocketmine\timings\Timings;
use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\exception\CorruptedWorldException;
use pocketmine\world\format\io\exception\UnsupportedWorldFormatException;
@@ -393,7 +392,6 @@ class WorldManager{
}
private function doAutoSave() : void{
Timings::$worldSave->startTiming();
foreach($this->worlds as $world){
foreach($world->getPlayers() as $player){
if($player->spawned){
@@ -402,6 +400,5 @@ class WorldManager{
}
$world->save(false);
}
Timings::$worldSave->stopTiming();
}
}

View File

@@ -38,6 +38,7 @@ class WorldTimings{
public TimingsHandler $randomChunkUpdatesChunkSelection;
public TimingsHandler $doChunkGC;
public TimingsHandler $entityTick;
public TimingsHandler $tileTick;
public TimingsHandler $doTick;
public TimingsHandler $syncChunkSend;
@@ -48,33 +49,54 @@ class WorldTimings{
public TimingsHandler $syncChunkLoadFixInvalidBlocks;
public TimingsHandler $syncChunkLoadEntities;
public TimingsHandler $syncChunkLoadTileEntities;
public TimingsHandler $syncDataSave;
public TimingsHandler $syncChunkSave;
public TimingsHandler $chunkPopulationOrder;
public TimingsHandler $chunkPopulationCompletion;
/**
* @var TimingsHandler[]
* @phpstan-var array<string, TimingsHandler>
*/
private static array $aggregators = [];
private static function newTimer(string $worldName, string $timerName) : TimingsHandler{
$aggregator = self::$aggregators[$timerName] ??= new TimingsHandler("Worlds - $timerName"); //displayed in Minecraft primary table
return new TimingsHandler("$worldName - $timerName", $aggregator, Timings::GROUP_BREAKDOWN);
}
public function __construct(World $world){
$name = $world->getFolderName() . " - ";
$name = $world->getFolderName();
$this->setBlock = new TimingsHandler($name . "setBlock", group: Timings::GROUP_BREAKDOWN);
$this->doBlockLightUpdates = new TimingsHandler($name . "Block Light Updates", group: Timings::GROUP_BREAKDOWN);
$this->doBlockSkyLightUpdates = new TimingsHandler($name . "Sky Light Updates", group: Timings::GROUP_BREAKDOWN);
$this->setBlock = self::newTimer($name, "Set Blocks");
$this->doBlockLightUpdates = self::newTimer($name, "Block Light Updates");
$this->doBlockSkyLightUpdates = self::newTimer($name, "Sky Light Updates");
$this->doChunkUnload = new TimingsHandler($name . "Unload Chunks", group: Timings::GROUP_BREAKDOWN);
$this->scheduledBlockUpdates = new TimingsHandler($name . "Scheduled Block Updates", group: Timings::GROUP_BREAKDOWN);
$this->randomChunkUpdates = new TimingsHandler($name . "Random Chunk Updates", group: Timings::GROUP_BREAKDOWN);
$this->randomChunkUpdatesChunkSelection = new TimingsHandler($name . "Random Chunk Updates - Chunk Selection", group: Timings::GROUP_BREAKDOWN);
$this->doChunkGC = new TimingsHandler($name . "Garbage Collection", group: Timings::GROUP_BREAKDOWN);
$this->entityTick = new TimingsHandler($name . "Tick Entities", group: Timings::GROUP_BREAKDOWN);
$this->doChunkUnload = self::newTimer($name, "Unload Chunks");
$this->scheduledBlockUpdates = self::newTimer($name, "Scheduled Block Updates");
$this->randomChunkUpdates = self::newTimer($name, "Random Chunk Updates");
$this->randomChunkUpdatesChunkSelection = self::newTimer($name, "Random Chunk Updates - Chunk Selection");
$this->doChunkGC = self::newTimer($name, "Garbage Collection");
$this->entityTick = self::newTimer($name, "Entity Tick");
$this->tileTick = self::newTimer($name, "Block Entity Tick");
$this->doTick = self::newTimer($name, "World Tick");
Timings::init(); //make sure the timers we want are available
$this->syncChunkSend = new TimingsHandler($name . "Player Send Chunks", Timings::$playerChunkSend, group: Timings::GROUP_BREAKDOWN);
$this->syncChunkSendPrepare = new TimingsHandler($name . "Player Send Chunk Prepare", Timings::$playerChunkSend, group: Timings::GROUP_BREAKDOWN);
$this->syncChunkSend = self::newTimer($name, "Player Send Chunks");
$this->syncChunkSendPrepare = self::newTimer($name, "Player Send Chunk Prepare");
$this->syncChunkLoad = new TimingsHandler($name . "Chunk Load", Timings::$worldLoad, group: Timings::GROUP_BREAKDOWN);
$this->syncChunkLoadData = new TimingsHandler($name . "Chunk Load - Data", group: Timings::GROUP_BREAKDOWN);
$this->syncChunkLoadFixInvalidBlocks = new TimingsHandler($name . "Chunk Load - Fix Invalid Blocks", group: Timings::GROUP_BREAKDOWN);
$this->syncChunkLoadEntities = new TimingsHandler($name . "Chunk Load - Entities", group: Timings::GROUP_BREAKDOWN);
$this->syncChunkLoadTileEntities = new TimingsHandler($name . "Chunk Load - TileEntities", group: Timings::GROUP_BREAKDOWN);
$this->syncChunkSave = new TimingsHandler($name . "Chunk Save", Timings::$worldSave, group: Timings::GROUP_BREAKDOWN);
$this->syncChunkLoad = self::newTimer($name, "Chunk Load");
$this->syncChunkLoadData = self::newTimer($name, "Chunk Load - Data");
$this->syncChunkLoadFixInvalidBlocks = self::newTimer($name, "Chunk Load - Fix Invalid Blocks");
$this->syncChunkLoadEntities = self::newTimer($name, "Chunk Load - Entities");
$this->syncChunkLoadTileEntities = self::newTimer($name, "Chunk Load - Block Entities");
$this->doTick = new TimingsHandler($name . "World Tick");
$this->syncDataSave = self::newTimer($name, "Data Save");
$this->syncChunkSave = self::newTimer($name, "Chunk Save");
$this->chunkPopulationOrder = self::newTimer($name, "Chunk Population - Order");
$this->chunkPopulationCompletion = self::newTimer($name, "Chunk Population - Completion");
}
}