39    public const GROUP_MINECRAFT = 
"Minecraft";
 
   43    private static bool $initialized = 
false;
 
   54    public static TimingsHandler $playerNetworkSendCompressSessionBuffer;
 
   88    public static array $entityTypeTimingMap = [];
 
   90    public static array $tileEntityTypeTimingMap = [];
 
   92    public static array $packetReceiveTimingMap = [];
 
   95    private static array $packetDecodeTimingMap = [];
 
   97    private static array $packetHandleTimingMap = [];
 
  100    private static array $packetEncodeTimingMap = [];
 
  103    public static array $packetSendTimingMap = [];
 
  105    public static array $pluginTaskTimingMap = [];
 
  111    private static array $commandTimingMap = [];
 
  118    private static array $events = [];
 
  120    private static array $eventHandlers = [];
 
  127    private static array $asyncTaskProgressUpdate = [];
 
  130    private static array $asyncTaskCompletion = [];
 
  132    private static array $asyncTaskError = [];
 
  136    private static array $asyncTaskRun = [];
 
  138    public static function init() : void{
 
  139        if(self::$initialized){
 
  142        self::$initialized = 
true;
 
  145        self::$serverTick = 
new TimingsHandler(
"Server Tick Update Cycle", self::$fullTick);
 
  146        self::$serverInterrupts = 
new TimingsHandler(
"Server Mid-Tick Processing", self::$fullTick);
 
  148        self::$garbageCollector = 
new TimingsHandler(
"Garbage Collector", self::$memoryManager);
 
  153        self::$playerNetworkSend = 
new TimingsHandler(
"Player Network Send", self::$connection);
 
  154        self::$playerNetworkSendCompress = 
new TimingsHandler(
"Player Network Send - Compression", self::$playerNetworkSend);
 
  155        self::$playerNetworkSendCompressBroadcast = 
new TimingsHandler(
"Player Network Send - Compression (Broadcast)", self::$playerNetworkSendCompress);
 
  156        self::$playerNetworkSendCompressSessionBuffer = 
new TimingsHandler(
"Player Network Send - Compression (Session Buffer)", self::$playerNetworkSendCompress);
 
  157        self::$playerNetworkSendEncrypt = 
new TimingsHandler(
"Player Network Send - Encryption", self::$playerNetworkSend);
 
  158        self::$playerNetworkSendInventorySync = 
new TimingsHandler(
"Player Network Send - Inventory Sync", self::$playerNetworkSend);
 
  159        self::$playerNetworkSendPreSpawnGameData = 
new TimingsHandler(
"Player Network Send - Pre-Spawn Game Data", self::$playerNetworkSend);
 
  161        self::$playerNetworkReceive = 
new TimingsHandler(
"Player Network Receive", self::$connection);
 
  162        self::$playerNetworkReceiveDecompress = 
new TimingsHandler(
"Player Network Receive - Decompression", self::$playerNetworkReceive);
 
  163        self::$playerNetworkReceiveDecrypt = 
new TimingsHandler(
"Player Network Receive - Decryption", self::$playerNetworkReceive);
 
  165        self::$broadcastPackets = 
new TimingsHandler(
"Broadcast Packets", self::$playerNetworkSend);
 
  168        self::$playerChunkOrder = 
new TimingsHandler(
"Player Order Chunks");
 
  169        self::$playerChunkSend = 
new TimingsHandler(
"Player Network Send - Chunks", self::$playerNetworkSend);
 
  172        self::$permissibleCalculation = 
new TimingsHandler(
"Permissible Calculation");
 
  173        self::$permissibleCalculationDiff = 
new TimingsHandler(
"Permissible Calculation - Diff", self::$permissibleCalculation);
 
  174        self::$permissibleCalculationCallback = 
new TimingsHandler(
"Permissible Calculation - Callbacks", self::$permissibleCalculation);
 
  176        self::$syncPlayerDataLoad = 
new TimingsHandler(
"Player Data Load");
 
  177        self::$syncPlayerDataSave = 
new TimingsHandler(
"Player Data Save");
 
  180        self::$entityMoveCollision = 
new TimingsHandler(
"Entity Movement - Collision Checks", self::$entityMove);
 
  182        self::$projectileMove = 
new TimingsHandler(
"Projectile Movement", self::$entityMove);
 
  183        self::$projectileMoveRayTrace = 
new TimingsHandler(
"Projectile Movement - Ray Tracing", self::$projectileMove);
 
  185        self::$playerCheckNearEntities = 
new TimingsHandler(
"checkNearEntities");
 
  187        self::$livingEntityBaseTick = 
new TimingsHandler(
"Entity Base Tick - Living");
 
  188        self::$itemEntityBaseTick = 
new TimingsHandler(
"Entity Base Tick - ItemEntity");
 
  190        self::$schedulerSync = 
new TimingsHandler(
"Scheduler - Sync Tasks");
 
  192        self::$schedulerAsync = 
new TimingsHandler(
"Scheduler - Async Tasks");
 
  193        self::$asyncTaskProgressUpdateParent = 
new TimingsHandler(
"Async Tasks - Progress Updates", self::$schedulerAsync);
 
  194        self::$asyncTaskCompletionParent = 
new TimingsHandler(
"Async Tasks - Completion Handlers", self::$schedulerAsync);
 
  195        self::$asyncTaskErrorParent = 
new TimingsHandler(
"Async Tasks - Error Handlers", self::$schedulerAsync);
 
  197        self::$asyncTaskWorkers = 
new TimingsHandler(
"Async Task Workers");
 
  200        self::$craftingDataCacheRebuild = 
new TimingsHandler(
"Build CraftingDataPacket Cache");
 
  210        $name = 
"Task: " . $task->getTaskName();
 
  213            $name .= 
"(interval:" . $period . 
")";
 
  218        if(!isset(self::$pluginTaskTimingMap[$name])){
 
  219            self::$pluginTaskTimingMap[$name] = 
new TimingsHandler($name, self::$schedulerSync, $task->getOwnerName());
 
  222        return self::$pluginTaskTimingMap[$name];
 
 
  228    private static function shortenCoreClassName(
string $class, 
string $prefix) : string{
 
  229        if(str_starts_with($class, $prefix)){
 
  230            return (
new \ReflectionClass($class))->getShortName();
 
  235    public static function getEntityTimings(Entity $entity) : TimingsHandler{
 
  237        if(!isset(self::$entityTypeTimingMap[$entity::class])){
 
  238            if($entity instanceof Player){
 
  241                $displayName = $entity::class !== Player::class ? 
"Player (" . $entity::class . 
")" : 
"Player";
 
  243                $displayName = self::shortenCoreClassName($entity::class, 
"pocketmine\\entity\\");
 
  245            self::$entityTypeTimingMap[$entity::class] = 
new TimingsHandler(
"Entity Tick - " . $displayName);
 
  248        return self::$entityTypeTimingMap[$entity::class];
 
  251    public static function getTileEntityTimings(Tile $tile) : TimingsHandler{
 
  253        if(!isset(self::$tileEntityTypeTimingMap[$tile::class])){
 
  254            self::$tileEntityTypeTimingMap[$tile::class] = 
new TimingsHandler(
 
  255                "Block Entity Tick - " . self::shortenCoreClassName($tile::class, 
"pocketmine\\block\\tile\\")
 
  259        return self::$tileEntityTypeTimingMap[$tile::class];
 
  262    public static function getReceiveDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{
 
  264        if(!isset(self::$packetReceiveTimingMap[$pk::class])){
 
  265            self::$packetReceiveTimingMap[$pk::class] = 
new TimingsHandler(
"Receive - " . $pk->getName(), self::$playerNetworkReceive);
 
  268        return self::$packetReceiveTimingMap[$pk::class];
 
  271    public static function getDecodeDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{
 
  272        return self::$packetDecodeTimingMap[$pk::class] ??= new TimingsHandler(
 
  273            "Decode - " . $pk->getName(),
 
  274            self::getReceiveDataPacketTimings($pk)
 
  278    public static function getHandleDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{
 
  279        return self::$packetHandleTimingMap[$pk::class] ??= new TimingsHandler(
 
  280            "Handler - " . $pk->getName(),
 
  281            self::getReceiveDataPacketTimings($pk)
 
  285    public static function getEncodeDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
 
  286        return self::$packetEncodeTimingMap[$pk::class] ??= new TimingsHandler(
 
  287            "Encode - " . $pk->getName(),
 
  288            self::getSendDataPacketTimings($pk)
 
  292    public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
 
  294        if(!isset(self::$packetSendTimingMap[$pk::class])){
 
  295            self::$packetSendTimingMap[$pk::class] = 
new TimingsHandler(
"Send - " . $pk->getName(), self::$playerNetworkSend);
 
  298        return self::$packetSendTimingMap[$pk::class];
 
  301    public static function getCommandDispatchTimings(
string $commandName) : TimingsHandler{
 
  304        return self::$commandTimingMap[$commandName] ??= 
new TimingsHandler(
"Command - " . $commandName);
 
  307    public static function getEventTimings(Event $event) : TimingsHandler{
 
  308        $eventClass = get_class($event);
 
  309        if(!isset(self::$events[$eventClass])){
 
  310            self::$events[$eventClass] = 
new TimingsHandler(self::shortenCoreClassName($eventClass, 
"pocketmine\\event\\"), group: 
"Events");
 
  313        return self::$events[$eventClass];
 
  320        if(!isset(self::$eventHandlers[$event][$handlerName])){
 
  321            self::$eventHandlers[$event][$handlerName] = 
new TimingsHandler($handlerName . 
"(" . self::shortenCoreClassName($event, 
"pocketmine\\event\\") . 
")", group: $group);
 
  324        return self::$eventHandlers[$event][$handlerName];
 
 
  327    public static function getAsyncTaskProgressUpdateTimings(AsyncTask $task, 
string $group = self::GROUP_MINECRAFT) : 
TimingsHandler{
 
  328        $taskClass = $task::class;
 
  329        if(!isset(self::$asyncTaskProgressUpdate[$taskClass])){
 
  332                "AsyncTask - " . self::shortenCoreClassName($taskClass, 
"pocketmine\\") . 
" - Progress Updates",
 
  333                self::$asyncTaskProgressUpdateParent,
 
  338        return self::$asyncTaskProgressUpdate[$taskClass];
 
  341    public static function getAsyncTaskCompletionTimings(AsyncTask $task, 
string $group = self::GROUP_MINECRAFT) : TimingsHandler{
 
  342        $taskClass = $task::class;
 
  343        if(!isset(self::$asyncTaskCompletion[$taskClass])){
 
  345            self::$asyncTaskCompletion[$taskClass] = 
new TimingsHandler(
 
  346                "AsyncTask - " . self::shortenCoreClassName($taskClass, 
"pocketmine\\") . 
" - Completion Handler",
 
  347                self::$asyncTaskCompletionParent,
 
  352        return self::$asyncTaskCompletion[$taskClass];
 
  359        $taskClass = $task::class;
 
  360        if(!isset(self::$asyncTaskError[$taskClass])){
 
  363                "AsyncTask - " . self::shortenCoreClassName($taskClass, 
"pocketmine\\") . 
" - Error Handler",
 
  364                self::$asyncTaskErrorParent,
 
  369        return self::$asyncTaskError[$taskClass];
 
 
  372    public static function getAsyncTaskRunTimings(AsyncTask $task, 
string $group = self::GROUP_MINECRAFT) : 
TimingsHandler{
 
  373        $taskClass = $task::class;
 
  374        if(!isset(self::$asyncTaskRun[$taskClass])){
 
  377                "AsyncTask - " . self::shortenCoreClassName($taskClass, 
"pocketmine\\") . 
" - Run",
 
  378                self::$asyncTaskWorkers,
 
  383        return self::$asyncTaskRun[$taskClass];