3
0
Fork 0
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:
dante ruiz 2019-09-19 09:41:01 -07:00
parent 7d6404b40b
commit 09b9b1e10c
7 changed files with 175 additions and 3 deletions

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);

View file

@ -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");

View file

@ -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 };

View file

@ -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];
}

View file

@ -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);