diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index b04778ad0..5d206290e 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -31,63 +31,60 @@ class AutoUpdater{ /** @var Server */ protected $server; + /** @var string */ protected $endpoint; + /** @var bool */ protected $hasUpdate = false; + /** @var array|null */ protected $updateInfo = null; + /** + * @param Server $server + * @param string $endpoint + */ public function __construct(Server $server, $endpoint){ $this->server = $server; $this->endpoint = "http://$endpoint/api/"; if($server->getProperty("auto-updater.enabled", true)){ - $this->check(); - if($this->hasUpdate()){ - if($this->server->getProperty("auto-updater.on-update.warn-console", true)){ - $this->showConsoleUpdate(); - } - }elseif($this->server->getProperty("auto-updater.preferred-channel", true)){ - $version = new VersionString(); - if(!$version->isDev() and $this->getChannel() !== "stable"){ - $this->showChannelSuggestionStable(); - }elseif($version->isDev() and $this->getChannel() === "stable"){ - $this->showChannelSuggestionBeta(); - } + $this->doCheck(); + } + } + + /** + * Callback used at the end of the update checking task + * + * @param array $updateInfo + */ + public function checkUpdateCallback(array $updateInfo){ + $this->updateInfo = $updateInfo; + $this->checkUpdate(); + if($this->hasUpdate()){ + if($this->server->getProperty("auto-updater.on-update.warn-console", true)){ + $this->showConsoleUpdate(); + } + }elseif($this->server->getProperty("auto-updater.preferred-channel", true)){ + $version = new VersionString(); + if(!$version->isDev() and $this->getChannel() !== "stable"){ + $this->showChannelSuggestionStable(); + }elseif($version->isDev() and $this->getChannel() === "stable"){ + $this->showChannelSuggestionBeta(); } } } - protected function check(){ - $error = ""; - $response = Utils::getURL($this->endpoint . "?channel=" . $this->getChannel(), 4, [], $error); - if($error !== ""){ - $this->server->getLogger()->debug("[AutoUpdater] Update check failed due to \"$error\""); - return; - } - - $response = json_decode($response, true); - if(!is_array($response)){ - return; - } - - $this->updateInfo = [ - "version" => $response["version"], - "api_version" => $response["api_version"], - "build" => $response["build"], - "date" => $response["date"], - "details_url" => $response["details_url"] ?? null, - "download_url" => $response["download_url"] - ]; - - $this->checkUpdate(); - } - /** + * Returns whether there is an update available. + * * @return bool */ public function hasUpdate(){ return $this->hasUpdate; } + /** + * Posts a warning to the console to tell the user there is an update available + */ public function showConsoleUpdate(){ $logger = $this->server->getLogger(); $newVersion = new VersionString($this->updateInfo["version"]); @@ -100,6 +97,10 @@ class AutoUpdater{ $logger->warning("----- -------------------------- -----"); } + /** + * Shows a warning to a player to tell them there is an update available + * @param Player $player + */ public function showPlayerUpdate(Player $player){ $player->sendMessage(TextFormat::DARK_PURPLE . "The version of PocketMine-MP that this server is running is out of date. Please consider updating to the latest version."); $player->sendMessage(TextFormat::DARK_PURPLE . "Check the console for more details."); @@ -121,14 +122,25 @@ class AutoUpdater{ $logger->info("----- -------------------------- -----"); } + /** + * Returns the last retrieved update data. + * + * @return array|null + */ public function getUpdateInfo(){ return $this->updateInfo; } + /** + * Schedules an AsyncTask to check for an update. + */ public function doCheck(){ - $this->check(); + $this->server->getScheduler()->scheduleAsyncTask(new UpdateCheckTask($this->endpoint, $this->getChannel())); } + /** + * Checks the update information against the current server version to decide if there's an update + */ protected function checkUpdate(){ if($this->updateInfo === null){ return; @@ -144,6 +156,11 @@ class AutoUpdater{ } + /** + * Returns the channel used for update checking (stable, beta, dev) + * + * @return string + */ public function getChannel(){ $channel = strtolower($this->server->getProperty("auto-updater.preferred-channel", "stable")); if($channel !== "stable" and $channel !== "beta" and $channel !== "development"){ @@ -152,4 +169,13 @@ class AutoUpdater{ return $channel; } + + /** + * Returns the host used for update checks. + * + * @return string + */ + public function getEndpoint() : string{ + return $this->endpoint; + } } \ No newline at end of file diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/pocketmine/updater/UpdateCheckTask.php new file mode 100644 index 000000000..05923493b --- /dev/null +++ b/src/pocketmine/updater/UpdateCheckTask.php @@ -0,0 +1,82 @@ +endpoint = $endpoint; + $this->channel = $channel; + } + + public function onRun(){ + $this->error = ""; + $response = Utils::getURL($this->endpoint . "?channel=" . $this->channel, 4, [], $this->error); + if($this->error !== ""){ + return; + }else{ + $response = json_decode($response, true); + if(is_array($response)){ + $this->setResult( + [ + "version" => $response["version"], + "api_version" => $response["api_version"], + "build" => $response["build"], + "date" => $response["date"], + "details_url" => $response["details_url"] ?? null, + "download_url" => $response["download_url"] + ], + true + ); + }else{ + $this->error = "Invalid response data"; + } + } + } + + public function onCompletion(Server $server){ + if($this->error !== ""){ + $server->getLogger()->debug("[AutoUpdater] Async update check failed due to \"$this->error\""); + }else{ + $updateInfo = $this->getResult(); + if(is_array($updateInfo)){ + $server->getUpdater()->checkUpdateCallback($updateInfo); + }else{ + $server->getLogger()->debug("[AutoUpdater] Update info error"); + } + + } + } +} \ No newline at end of file