diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 3f2b7232b..99d03d807 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -229,13 +229,13 @@ class CrashDump{ } private function generalData(){ - $version = new VersionString(); + $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); $this->data["general"] = []; $this->data["general"]["name"] = $this->server->getName(); - $this->data["general"]["version"] = $version->get(false); + $this->data["general"]["version"] = $version->getFullVersion(false); $this->data["general"]["build"] = $version->getBuild(); $this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL; - $this->data["general"]["api"] = \pocketmine\API_VERSION; + $this->data["general"]["api"] = \pocketmine\BASE_VERSION; $this->data["general"]["git"] = \pocketmine\GIT_COMMIT; $this->data["general"]["raklib"] = RakLib::VERSION; $this->data["general"]["uname"] = php_uname("a"); @@ -243,7 +243,7 @@ class CrashDump{ $this->data["general"]["zend"] = zend_version(); $this->data["general"]["php_os"] = PHP_OS; $this->data["general"]["os"] = Utils::getOS(); - $this->addLine($this->server->getName() . " version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "; API " . API_VERSION . "]"); + $this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]"); $this->addLine("Git commit: " . GIT_COMMIT); $this->addLine("uname -a: " . php_uname("a")); $this->addLine("PHP Version: " . phpversion()); diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 6468c4b04..ec11fa1ea 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -33,12 +33,13 @@ namespace pocketmine { use pocketmine\utils\Terminal; use pocketmine\utils\Timezone; use pocketmine\utils\Utils; + use pocketmine\utils\VersionString; use pocketmine\wizard\SetupWizard; const NAME = "PocketMine-MP"; - const VERSION = "1.7dev"; - const API_VERSION = "3.0.0"; + const BASE_VERSION = "3.0.0"; const IS_DEVELOPMENT_BUILD = true; + const BUILD_NUMBER = 0; const MIN_PHP_VERSION = "7.2.0"; @@ -205,6 +206,9 @@ namespace pocketmine { $logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance."); } + $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + define('pocketmine\VERSION', $version->getFullVersion(true)); + $gitHash = str_repeat("00", 20); if(\Phar::running(true) === ""){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 5770a8355..ab736182f 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -320,7 +320,7 @@ class Server{ * @return string */ public function getApiVersion() : string{ - return \pocketmine\API_VERSION; + return \pocketmine\BASE_VERSION; } /** @@ -1438,12 +1438,10 @@ class Server{ $this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR; $this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR; - $version = new VersionString($this->getPocketMineVersion()); - $this->logger->info("Loading pocketmine.yml..."); if(!file_exists($this->dataPath . "pocketmine.yml")){ $content = file_get_contents(\pocketmine\RESOURCE_PATH . "pocketmine.yml"); - if($version->isDev()){ + if(\pocketmine\IS_DEVELOPMENT_BUILD){ $content = str_replace("preferred-channel: stable", "preferred-channel: beta", $content); } @file_put_contents($this->dataPath . "pocketmine.yml", $content); @@ -1611,8 +1609,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [ $this->getName(), - ($version->isDev() ? TextFormat::YELLOW : "") . $version->get(true) . TextFormat::RESET, - $this->getApiVersion() + (\pocketmine\IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET ])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); diff --git a/src/pocketmine/command/defaults/VersionCommand.php b/src/pocketmine/command/defaults/VersionCommand.php index 741777936..c6328ba85 100644 --- a/src/pocketmine/command/defaults/VersionCommand.php +++ b/src/pocketmine/command/defaults/VersionCommand.php @@ -50,7 +50,6 @@ class VersionCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer("pocketmine.server.info.extended", [ $sender->getServer()->getName(), $sender->getServer()->getPocketMineVersion(), - $sender->getServer()->getApiVersion(), $sender->getServer()->getVersion(), ProtocolInfo::CURRENT_PROTOCOL ])); diff --git a/src/pocketmine/lang/locale b/src/pocketmine/lang/locale index 5e6ccee0c..ac510ed32 160000 --- a/src/pocketmine/lang/locale +++ b/src/pocketmine/lang/locale @@ -1 +1 @@ -Subproject commit 5e6ccee0c1962c8b28491212c3a947fb2036e4a4 +Subproject commit ac510ed32673d019d9bffede266d15ee9e287bae diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index a60f9c0be..087b7f8a6 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -35,10 +35,10 @@ class AutoUpdater{ protected $server; /** @var string */ protected $endpoint; - /** @var bool */ - protected $hasUpdate = false; /** @var array|null */ protected $updateInfo = null; + /** @var VersionString|null */ + protected $newVersion; /** * @param Server $server @@ -67,10 +67,9 @@ class AutoUpdater{ $this->showConsoleUpdate(); } }elseif($this->server->getProperty("auto-updater.preferred-channel", true)){ - $version = new VersionString(); - if(!$version->isDev() and $this->getChannel() !== "stable"){ + if(!\pocketmine\IS_DEVELOPMENT_BUILD and $this->getChannel() !== "stable"){ $this->showChannelSuggestionStable(); - }elseif($version->isDev() and $this->getChannel() === "stable"){ + }elseif(\pocketmine\IS_DEVELOPMENT_BUILD and $this->getChannel() === "stable"){ $this->showChannelSuggestionBeta(); } } @@ -82,17 +81,15 @@ class AutoUpdater{ * @return bool */ public function hasUpdate() : bool{ - return $this->hasUpdate; + return $this->newVersion !== null; } /** * Posts a warning to the console to tell the user there is an update available */ public function showConsoleUpdate(){ - $newVersion = new VersionString($this->updateInfo["version"]); - $messages = [ - "Your version of " . $this->server->getName() . " is out of date. Version " . $newVersion->get(false) . " (build #" . $this->updateInfo["build"] . ") was released on " . date("D M j h:i:s Y", $this->updateInfo["date"]) + "Your version of " . $this->server->getName() . " is out of date. Version " . $this->newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo["date"]) ]; if($this->updateInfo["details_url"] !== null){ $messages[] = "Details: " . $this->updateInfo["details_url"]; @@ -159,15 +156,18 @@ class AutoUpdater{ if($this->updateInfo === null){ return; } - $currentVersion = new VersionString($this->server->getPocketMineVersion()); - $newVersion = new VersionString($this->updateInfo["version"]); - - if($currentVersion->compare($newVersion) > 0 and ($currentVersion->get() !== $newVersion->get() or $currentVersion->getBuild() > 0)){ - $this->hasUpdate = true; - }else{ - $this->hasUpdate = false; + $currentVersion = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + try{ + $newVersion = new VersionString($this->updateInfo["base_version"], $this->updateInfo["is_dev"], $this->updateInfo["build"]); + }catch(\InvalidArgumentException $e){ + //Invalid version returned from API, assume there's no update + $this->server->getLogger()->debug("[AutoUpdater] Assuming no update because \"" . $e->getMessage() . "\""); + return; } + if($currentVersion->compare($newVersion) > 0 and ($currentVersion->getFullVersion() !== $newVersion->getFullVersion() or $currentVersion->getBuild() > 0)){ + $this->newVersion = $newVersion; + } } /** diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/pocketmine/updater/UpdateCheckTask.php index 69c46270d..a4fc4100e 100644 --- a/src/pocketmine/updater/UpdateCheckTask.php +++ b/src/pocketmine/updater/UpdateCheckTask.php @@ -52,8 +52,8 @@ class UpdateCheckTask extends AsyncTask{ $response = json_decode($response, true); if(is_array($response)){ if( - isset($response["version"]) and - isset($response["api_version"]) and + isset($response["base_version"]) and + isset($response["is_dev"]) and isset($response["build"]) and isset($response["date"]) and isset($response["download_url"]) diff --git a/src/pocketmine/utils/VersionString.php b/src/pocketmine/utils/VersionString.php index 65f9ae4ad..4c512f47d 100644 --- a/src/pocketmine/utils/VersionString.php +++ b/src/pocketmine/utils/VersionString.php @@ -28,47 +28,62 @@ namespace pocketmine\utils; * Manages PocketMine-MP version strings, and compares them */ class VersionString{ - /** @var int */ - private $generation; + /** @var string */ + private $baseVersion; + /** @var string */ + private $suffix; + /** @var int */ private $major; /** @var int */ private $minor; + /** @var int */ + private $patch; + /** @var int */ private $build; /** @var bool */ private $development = false; /** - * VersionString constructor. - * - * @param int|string $version + * @param string $baseVersion + * @param bool $isDevBuild + * @param int $buildNumber */ - public function __construct($version = \pocketmine\VERSION){ - if(is_int($version)){ - $this->minor = $version & 0x1F; - $this->major = ($version >> 5) & 0x0F; - $this->generation = ($version >> 9) & 0x0F; - }else{ - $version = preg_split("/([A-Za-z]*)[ _\\-]?([0-9]*)\\.([0-9]*)\\.{0,1}([0-9]*)(dev|)(-[\\0-9]{1,}|)/", $version, -1, PREG_SPLIT_DELIM_CAPTURE); - $this->generation = (int) ($version[2] ?? 0); //0-15 - $this->major = (int) ($version[3] ?? 0); //0-15 - $this->minor = (int) ($version[4] ?? 0); //0-31 - $this->development = $version[5] === "dev"; - if($version[6] !== ""){ - $this->build = (int) substr($version[6], 1); - }else{ - $this->build = 0; - } + public function __construct(string $baseVersion, bool $isDevBuild = false, int $buildNumber = 0){ + $this->baseVersion = $baseVersion; + $this->development = $isDevBuild; + $this->build = $buildNumber; + + preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)(?:-(.*))?$/', $this->baseVersion, $matches); + if(count($matches) < 4){ + throw new \InvalidArgumentException("Invalid base version \"$baseVersion\", should contain at least 3 version digits"); } + + $this->major = (int) $matches[1]; + $this->minor = (int) $matches[2]; + $this->patch = (int) $matches[3]; + $this->suffix = $matches[4] ?? ""; } public function getNumber() : int{ - return (($this->generation << 9) + ($this->major << 5) + $this->minor); + return (($this->major << 9) + ($this->minor << 5) + $this->patch); } - public function getGeneration() : int{ - return $this->generation; + public function getBaseVersion() : string{ + return $this->baseVersion; + } + + public function getFullVersion(bool $build = false) : string{ + $retval = $this->baseVersion; + if($this->development){ + $retval .= "+dev"; + if($build and $this->build > 0){ + $retval .= "." . $this->build; + } + } + + return $retval; } public function getMajor() : int{ @@ -79,8 +94,12 @@ class VersionString{ return $this->minor; } - public function getRelease() : string{ - return $this->generation . "." . $this->major . "." . $this->minor; + public function getPatch() : int{ + return $this->patch; + } + + public function getSuffix() : string{ + return $this->suffix; } public function getBuild() : int{ @@ -91,24 +110,17 @@ class VersionString{ return $this->development; } - public function get(bool $build = false) : string{ - return $this->getRelease() . ($this->development ? "dev" : "") . (($this->build > 0 and $build) ? "-" . $this->build : ""); - } - public function __toString() : string{ - return $this->get(); + return $this->getFullVersion(); } /** - * @param VersionString|int|string $target - * @param bool $diff + * @param VersionString $target + * @param bool $diff * * @return int */ - public function compare($target, bool $diff = false) : int{ - if(!($target instanceof VersionString)){ - $target = new VersionString($target); - } + public function compare(VersionString $target, bool $diff = false) : int{ $number = $this->getNumber(); $tNumber = $target->getNumber(); if($diff){