61 public function __construct(){
64 KnownTranslationFactory::pocketmine_command_timings_description(),
65 KnownTranslationFactory::pocketmine_command_timings_usage()
67 $this->setPermission(DefaultPermissionNames::COMMAND_TIMINGS);
71 if(count($args) !== 1){
75 $mode = strtolower($args[0]);
78 if(TimingsHandler::isEnabled()){
79 $sender->sendMessage(KnownTranslationFactory::pocketmine_command_timings_alreadyEnabled());
82 TimingsHandler::setEnabled();
83 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_enable());
86 }elseif($mode ===
"off"){
87 TimingsHandler::setEnabled(
false);
88 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_disable());
92 if(!TimingsHandler::isEnabled()){
93 $sender->sendMessage(KnownTranslationFactory::pocketmine_command_timings_timingsDisabled());
98 $paste = $mode ===
"paste";
100 if($mode ===
"reset"){
101 TimingsHandler::reload();
102 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_reset());
103 }elseif($mode ===
"merged" || $mode ===
"report" || $paste){
104 $timingsPromise = TimingsHandler::requestPrintTimings();
105 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_collect());
106 $timingsPromise->onCompletion(
107 fn(array $lines) => $paste ? $this->uploadReport($lines, $sender) : $this->createReportFile($lines, $sender),
121 private function createReportFile(array $lines,
CommandSender $sender) : void{
123 $timingFolder = Path::join($sender->getServer()->getDataPath(),
"timings");
125 if(!file_exists($timingFolder)){
126 mkdir($timingFolder, 0777);
128 $timings = Path::join($timingFolder,
"timings.txt");
129 while(file_exists($timings)){
130 $timings = Path::join($timingFolder,
"timings" . (++$index) .
".txt");
134 foreach($lines as $line){
135 fwrite($fileTimings, $line . PHP_EOL);
137 fclose($fileTimings);
139 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsWrite($timings));
146 private function uploadReport(array $lines, CommandSender $sender) : void{
148 "browser" => $agent = $sender->getServer()->getName() .
" " . $sender->getServer()->getPocketMineVersion(),
149 "data" => implode(
"\n", $lines)
152 $host = $sender->getServer()->getConfigGroup()->getPropertyString(YmlServerProperties::TIMINGS_HOST,
"timings.pmmp.io");
154 $sender->getServer()->getAsyncPool()->submitTask(
new BulkCurlTask(
155 [
new BulkCurlTaskOperation(
156 "https://$host?upload=true",
160 CURLOPT_HTTPHEADER => [
161 "User-Agent: $agent",
162 "Content-Type: application/x-www-form-urlencoded"
164 CURLOPT_POST =>
true,
165 CURLOPT_POSTFIELDS => http_build_query($data),
166 CURLOPT_AUTOREFERER =>
false,
167 CURLOPT_FOLLOWLOCATION =>
false
170 function(array $results) use ($sender, $host) :
void{
172 if($sender instanceof Player && !$sender->isOnline()){
175 $result = $results[0];
176 if($result instanceof InternetException){
177 $sender->getServer()->getLogger()->logException($result);
180 $response = json_decode($result->getBody(),
true);
181 if(is_array($response) && isset($response[
"id"])){
182 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsRead(
183 "https://" . $host .
"/?id=" . $response[
"id"]));
185 $sender->getServer()->getLogger()->debug(
"Invalid response from timings server (" . $result->getCode() .
"): " . $result->getBody());
186 Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_pasteError());