mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 10:41:09 +02:00
mac auto-updater
This commit is contained in:
parent
7d6404b40b
commit
09b9b1e10c
7 changed files with 175 additions and 3 deletions
launchers/qt/src
|
@ -3,6 +3,11 @@
|
|||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
void launchClient(const QString& homePath, const QString& defaultScriptOverride, const QString& displayName,
|
||||
|
@ -45,5 +50,24 @@ void launchClient(const QString& homePath, const QString& defaultScriptOverride,
|
|||
CloseHandle(pi.hThread);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void swapLaunchers(const QString& oldLauncherPath, const QString& newLauncherPath) {
|
||||
if (!(QFileInfo::exists(oldLauncherPath) && QFileInfo::exists(newLauncherPath))) {
|
||||
qDebug() << "old launcher: " << oldLauncherPath << "new launcher: " << newLauncherPath << " file does not exist";
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
#ifdef Q_OS_MAC
|
||||
success = replaceDirectory(oldLauncherPath, newLauncherPath);
|
||||
#endif
|
||||
|
||||
if (success) {
|
||||
qDebug() << "succeessfully replaced";
|
||||
} else {
|
||||
qDebug() << "failed";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
#include <QString>
|
||||
#include <string>
|
||||
|
||||
void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptOverride,
|
||||
const QString& displayName, const QString& contentCachePath, const QString& loginResponseToken = QString());
|
||||
|
||||
|
||||
void launchAutoUpdater(const QString& autoUpdaterPath);
|
||||
void swapLaunchers(const QString& oldLauncherPath = QString(), const QString& newLauncherPath = QString());
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
bool replaceDirectory(const QString& orginalDirectory, const QString& newDirectory);
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
Launcher::Launcher(int& argc, char**argv) : QGuiApplication(argc, argv) {
|
||||
QString resourceBinaryLocation = QGuiApplication::applicationDirPath() + "/resources.rcc";
|
||||
qDebug() << "resources.rcc path: " << resourceBinaryLocation;
|
||||
QResource::registerResource(resourceBinaryLocation);
|
||||
_launcherState = std::make_shared<LauncherState>();
|
||||
//_launcherState->setUIState(LauncherState::SPLASH_SCREEN);
|
||||
|
|
|
@ -174,8 +174,24 @@ void LauncherState::receivedBuildsReply() {
|
|||
#endif
|
||||
_latestBuilds.builds.push_back(build);
|
||||
}
|
||||
|
||||
auto launcherResults = root["launcher"].toObject();
|
||||
|
||||
Build launcherBuild;
|
||||
launcherBuild.latestVersion = launcherResults["version"].toInt();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
launcherBuild.installerZipURL = launcherResults["windows"].toObject()["url"].toString();
|
||||
#elif defined(Q_OS_MACOS)
|
||||
launcherBuild.installerZipURL = launcherResults["mac"].toObject()["url"].toString();
|
||||
#else
|
||||
#error "Launcher is only supported on Windows and Mac OS"
|
||||
#endif
|
||||
_latestBuilds.launcherBuild = launcherBuild;
|
||||
}
|
||||
}
|
||||
|
||||
//downloadLauncher();
|
||||
setApplicationState(ApplicationState::WaitingForLogin);
|
||||
}
|
||||
|
||||
|
@ -290,6 +306,11 @@ void LauncherState::downloadClient() {
|
|||
}
|
||||
}
|
||||
|
||||
void LauncherState::launcherDownloadComplete() {
|
||||
_launcherZipFile.close();
|
||||
installLauncher();
|
||||
}
|
||||
|
||||
void LauncherState::clientDownloadComplete() {
|
||||
ASSERT_STATE(ApplicationState::DownloadingClient);
|
||||
|
||||
|
@ -330,6 +351,61 @@ void LauncherState::installClient() {
|
|||
//launchClient();
|
||||
}
|
||||
|
||||
void LauncherState::downloadLauncher() {
|
||||
auto request = new QNetworkRequest(QUrl(_latestBuilds.launcherBuild.installerZipURL));
|
||||
auto reply = _networkAccessManager.get(*request);
|
||||
|
||||
_launcherZipFile.setFileName(_launcherDirectory.absoluteFilePath("launcher.zip"));
|
||||
|
||||
qDebug() << "opening " << _launcherZipFile.fileName();
|
||||
|
||||
if (!_launcherZipFile.open(QIODevice::WriteOnly)) {
|
||||
setApplicationState(ApplicationState::UnexpectedError);
|
||||
return;
|
||||
}
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, &LauncherState::launcherDownloadComplete);
|
||||
connect(reply, &QNetworkReply::readyRead, this, [this, reply]() {
|
||||
char buf[4096];
|
||||
while (reply->bytesAvailable() > 0) {
|
||||
qint64 size;
|
||||
size = reply->read(buf, (qint64)sizeof(buf));
|
||||
if (size == 0) {
|
||||
break;
|
||||
}
|
||||
_launcherZipFile.write(buf, size);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LauncherState::installLauncher() {
|
||||
auto installDir = _launcherDirectory.absoluteFilePath("launcher_install");
|
||||
_launcherDirectory.mkpath("launcher_install");
|
||||
|
||||
qDebug() << "Uzipping " << _launcherZipFile.fileName() << " to " << installDir;
|
||||
|
||||
auto unzipper = new Unzipper(_launcherZipFile.fileName(), QDir(installDir));
|
||||
unzipper->setAutoDelete(true);
|
||||
connect(unzipper, &Unzipper::finished, this, [this](bool error, QString errorMessage) {
|
||||
if (error) {
|
||||
qDebug() << "Unzipper finished with error: " << errorMessage;
|
||||
} else {
|
||||
qDebug() << "Unzipper finished without error";
|
||||
|
||||
QDir installDirectory = _launcherDirectory.filePath("launcher_install");
|
||||
QString launcherPath;
|
||||
#if defined(Q_OS_WIN)
|
||||
launcherPath = installDirectory.absoluteFilePath("HQ Launcher.exe");
|
||||
#elif defined(Q_OS_MACOS)
|
||||
launcherPath = installDirectory.absoluteFilePath("HQ Launcher.app");
|
||||
#endif
|
||||
//::launchAutoUpdater(launcherPath);
|
||||
}
|
||||
});
|
||||
|
||||
QThreadPool::globalInstance()->start(unzipper);
|
||||
}
|
||||
|
||||
void LauncherState::downloadContentCache() {
|
||||
ASSERT_STATE(ApplicationState::InstallingClient);
|
||||
|
||||
|
@ -431,7 +507,6 @@ void LauncherState::launchClient() {
|
|||
defaultScriptsPath = installDirectory.filePath("interface.app/Contents/Resources/scripts/simplifiedUIBootstrapper.js");
|
||||
#endif
|
||||
|
||||
qDebug() << "------> " << defaultScriptsPath;
|
||||
QString displayName = "fixMe";
|
||||
QString contentCachePath = _launcherDirectory.filePath("cache");
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ struct LatestBuilds {
|
|||
|
||||
QString defaultTag;
|
||||
std::vector<Build> builds;
|
||||
Build launcherBuild;
|
||||
};
|
||||
|
||||
struct LoginResponse {
|
||||
|
@ -59,9 +60,11 @@ public:
|
|||
RequestingLogin,
|
||||
|
||||
DownloadingClient,
|
||||
DownloadingLauncher,
|
||||
DownloadingContentCache,
|
||||
|
||||
InstallingClient,
|
||||
InstallingLauncher,
|
||||
InstallingContentCache,
|
||||
|
||||
LaunchingHighFidelity
|
||||
|
@ -101,6 +104,10 @@ public:
|
|||
Q_INVOKABLE void login(QString username, QString password);
|
||||
Q_INVOKABLE void receivedLoginReply();
|
||||
|
||||
// Launcher
|
||||
void downloadLauncher();
|
||||
void installLauncher();
|
||||
|
||||
// Client
|
||||
void downloadClient();
|
||||
void installClient();
|
||||
|
@ -123,6 +130,7 @@ signals:
|
|||
private slots:
|
||||
void clientDownloadComplete();
|
||||
void contentCacheDownloadComplete();
|
||||
void launcherDownloadComplete();
|
||||
|
||||
private:
|
||||
bool shouldDownloadContentCache() const;
|
||||
|
@ -140,6 +148,7 @@ private:
|
|||
QString _contentCacheURL{ "https://orgs.highfidelity.com/content-cache/content_cache_small-only_data8.zip" }; // QString::null }; // If null, there is no content cache to download
|
||||
QString _loginTokenResponse;
|
||||
QFile _clientZipFile;
|
||||
QFile _launcherZipFile;
|
||||
QFile _contentZipFile;
|
||||
|
||||
float _downloadProgress { 0 };
|
||||
|
|
|
@ -40,3 +40,33 @@ void launchClient(const QString& clientPath, const QString& homePath, const QStr
|
|||
[task replaceThisProcess];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void launchAutoUpdater(const QString& autoUpdaterPath) {
|
||||
NSTask* task = [[NSTask alloc] init];
|
||||
task.launchPath = [autoUpdaterPath.toNSString() stringByAppendingString:@"/Contents/Resources/updater"];
|
||||
task.arguments = @[[[NSBundle mainBundle] bundlePath], autoUpdaterPath.toNSString()];
|
||||
[task launch];
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@interface UpdaterHelper : NSObject
|
||||
+(NSURL*) NSStringToNSURL: (NSString*) path;
|
||||
@end
|
||||
|
||||
@implementation UpdaterHelper
|
||||
+(NSURL*) NSStringToNSURL: (NSString*) path
|
||||
{
|
||||
return [NSURL URLWithString: [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]] relativeToURL: [NSURL URLWithString:@"file://"]];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
bool replaceDirectory(const QString& orginalDirectory, const QString& newDirectory) {
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
NSURL* destinationUrl = [UpdaterHelper NSStringToNSURL:newDirectory.toNSString()];
|
||||
return (bool) [fileManager replaceItemAtURL:[UpdaterHelper NSStringToNSURL:orginalDirectory.toNSString()] withItemAtURL:[UpdaterHelper NSStringToNSURL:newDirectory.toNSString()]
|
||||
backupItemName:nil options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:&destinationUrl error:nil];
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
#include "LauncherWindow.h"
|
||||
#include "Launcher.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "Helper.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
|
||||
|
@ -14,7 +16,29 @@ Q_IMPORT_PLUGIN(QtQuick2Plugin);
|
|||
Q_IMPORT_PLUGIN(QtQuickControls2Plugin);
|
||||
Q_IMPORT_PLUGIN(QtQuickTemplates2Plugin);
|
||||
|
||||
|
||||
|
||||
bool hasSuffix(const std::string path, const std::string suffix) {
|
||||
if (path.substr(path.find_last_of(".") + 1) == suffix) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// auto updater
|
||||
if (argc == 3) {
|
||||
if (hasSuffix(argv[1], "app") && hasSuffix(argv[2], "app")) {
|
||||
std::cout << "swapping launcher \n";
|
||||
swapLaunchers(argv[1], argv[2]);
|
||||
} else {
|
||||
std::cout << "not swapping launcher \n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
QString name { "High Fidelity" };
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setOrganizationName(name);
|
||||
|
|
Loading…
Reference in a new issue