setPermission(DefaultPermissionNames::COMMAND_TIMINGS); } public function execute(CommandSender $sender, string $commandLabel, array $args){ if(!$this->testPermission($sender)){ return true; } if(count($args) !== 1){ throw new InvalidCommandSyntaxException(); } $mode = strtolower($args[0]); if($mode === "on"){ if(TimingsHandler::isEnabled()){ $sender->sendMessage(KnownTranslationFactory::pocketmine_command_timings_alreadyEnabled()); return true; } TimingsHandler::setEnabled(); Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_enable()); return true; }elseif($mode === "off"){ TimingsHandler::setEnabled(false); Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_disable()); return true; } if(!TimingsHandler::isEnabled()){ $sender->sendMessage(KnownTranslationFactory::pocketmine_command_timings_timingsDisabled()); return true; } $paste = $mode === "paste"; if($mode === "reset"){ TimingsHandler::reload(); Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_reset()); }elseif($mode === "merged" or $mode === "report" or $paste){ $timings = ""; if($paste){ $fileTimings = Utils::assumeNotFalse(fopen("php://temp", "r+b"), "Opening php://temp should never fail"); }else{ $index = 0; $timingFolder = Path::join($sender->getServer()->getDataPath(), "timings"); if(!file_exists($timingFolder)){ mkdir($timingFolder, 0777); } $timings = Path::join($timingFolder, "timings.txt"); while(file_exists($timings)){ $timings = Path::join($timingFolder, "timings" . (++$index) . ".txt"); } $fileTimings = fopen($timings, "a+b"); } $lines = TimingsHandler::printTimings(); foreach($lines as $line){ fwrite($fileTimings, $line . PHP_EOL); } if($paste){ fseek($fileTimings, 0); $data = [ "browser" => $agent = $sender->getServer()->getName() . " " . $sender->getServer()->getPocketMineVersion(), "data" => $content = stream_get_contents($fileTimings) ]; fclose($fileTimings); $host = $sender->getServer()->getConfigGroup()->getPropertyString("timings.host", "timings.pmmp.io"); $sender->getServer()->getAsyncPool()->submitTask(new BulkCurlTask( [new BulkCurlTaskOperation( "https://$host?upload=true", 10, [], [ CURLOPT_HTTPHEADER => [ "User-Agent: $agent", "Content-Type: application/x-www-form-urlencoded" ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($data), CURLOPT_AUTOREFERER => false, CURLOPT_FOLLOWLOCATION => false ] )], function(array $results) use ($sender, $host) : void{ /** @phpstan-var array $results */ if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender return; } $result = $results[0]; if($result instanceof InternetException){ $sender->getServer()->getLogger()->logException($result); return; } $response = json_decode($result->getBody(), true); if(is_array($response) && isset($response["id"])){ Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsRead( "https://" . $host . "/?id=" . $response["id"])); }else{ Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_pasteError()); } } )); }else{ fclose($fileTimings); Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsWrite($timings)); } }else{ throw new InvalidCommandSyntaxException(); } return true; } }