mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-06 20:32:56 +02:00
Merge pull request #15916 from luiscuenca/WLAsyncThunder
BUGZ-989: Get recent builds asynchronously while the windows launcher is showing the splash screen
This commit is contained in:
commit
8ad1202bcb
5 changed files with 135 additions and 84 deletions
|
@ -672,7 +672,7 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
|
|||
theApp._manager.addToLog(_T("Start splash screen"));
|
||||
setDrawDialog(DrawStep::DrawLogo);
|
||||
}
|
||||
} else if (_splashStep > 100) {
|
||||
} else if (_splashStep > 100 && !theApp._manager.needsToWait()) {
|
||||
_showSplash = false;
|
||||
if (theApp._manager.shouldShutDown()) {
|
||||
if (_applicationWND != NULL) {
|
||||
|
|
|
@ -24,35 +24,7 @@ LauncherManager::~LauncherManager() {
|
|||
void LauncherManager::init() {
|
||||
initLog();
|
||||
addToLog(_T("Getting most recent build"));
|
||||
CString response;
|
||||
LauncherUtils::ResponseError error = getMostRecentBuild(_latestApplicationURL, _latestVersion, response);
|
||||
if (error == LauncherUtils::ResponseError::NoError) {
|
||||
addToLog(_T("Latest version: ") + _latestVersion);
|
||||
CString currentVersion;
|
||||
if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) {
|
||||
addToLog(_T("Installed version: ") + currentVersion);
|
||||
if (_latestVersion.Compare(currentVersion) == 0) {
|
||||
addToLog(_T("Already running most recent build. Launching interface.exe"));
|
||||
_shouldLaunch = TRUE;
|
||||
_shouldShutdown = TRUE;
|
||||
} else {
|
||||
addToLog(_T("New build found. Updating"));
|
||||
_shouldUpdate = TRUE;
|
||||
}
|
||||
} else if (_loggedIn) {
|
||||
addToLog(_T("Interface not found but logged in. Reinstalling"));
|
||||
_shouldUpdate = TRUE;
|
||||
} else {
|
||||
_shouldInstall = TRUE;
|
||||
}
|
||||
} else {
|
||||
_hasFailed = true;
|
||||
CString msg;
|
||||
msg.Format(_T("Getting most recent build has failed with error: %d"), error);
|
||||
addToLog(msg);
|
||||
msg.Format(_T("Response: %s"), response);
|
||||
addToLog(msg);
|
||||
}
|
||||
getMostRecentBuild(_latestApplicationURL, _latestVersion);
|
||||
}
|
||||
|
||||
BOOL LauncherManager::initLog() {
|
||||
|
@ -387,39 +359,71 @@ LauncherUtils::ResponseError LauncherManager::readOrganizationJSON(const CString
|
|||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherManager::getMostRecentBuild(CString& urlOut, CString& versionOut,
|
||||
CString& response) {
|
||||
void LauncherManager::getMostRecentBuild(CString& urlOut, CString& versionOut) {
|
||||
CString contentTypeJson = L"content-type:application/json";
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher",
|
||||
L"thunder.highfidelity.com",
|
||||
L"/builds/api/tags/latest?format=json",
|
||||
contentTypeJson, CStringA(),
|
||||
response, false);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
int count = json["count"].isInt() ? json["count"].asInt() : 0;
|
||||
if (count > 0 && json["results"].isArray()) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (json["results"][i].isObject()) {
|
||||
Json::Value result = json["results"][i];
|
||||
if (result["latest_version"].isInt()) {
|
||||
std::string version = std::to_string(result["latest_version"].asInt());
|
||||
versionOut = CString(version.c_str());
|
||||
}
|
||||
if (result["installers"].isObject() &&
|
||||
result["installers"]["windows"].isObject() &&
|
||||
result["installers"]["windows"]["zip_url"].isString()) {
|
||||
urlOut = result["installers"]["windows"]["zip_url"].asCString();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
std::function<void(CString, int)> httpCallback = [&](CString response, int err) {
|
||||
LauncherUtils::ResponseError error = LauncherUtils::ResponseError(err);
|
||||
if (error == LauncherUtils::ResponseError::NoError) {
|
||||
Json::Value json;
|
||||
error = LauncherUtils::ResponseError::ParsingJSON;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
int count = json["count"].isInt() ? json["count"].asInt() : 0;
|
||||
if (count > 0 && json["results"].isArray()) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (json["results"][i].isObject()) {
|
||||
Json::Value result = json["results"][i];
|
||||
if (result["latest_version"].isInt()) {
|
||||
std::string version = std::to_string(result["latest_version"].asInt());
|
||||
versionOut = CString(version.c_str());
|
||||
}
|
||||
if (result["installers"].isObject() &&
|
||||
result["installers"]["windows"].isObject() &&
|
||||
result["installers"]["windows"]["zip_url"].isString()) {
|
||||
urlOut = result["installers"]["windows"]["zip_url"].asCString();
|
||||
error = LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onMostRecentBuildReceived(response, error);
|
||||
}
|
||||
};
|
||||
LauncherUtils::httpCallOnThread(L"HQ Launcher",
|
||||
L"thunder.highfidelity.com",
|
||||
L"/builds/api/tags/latest?format=json",
|
||||
contentTypeJson, CStringA(), false, httpCallback);
|
||||
}
|
||||
|
||||
void LauncherManager::onMostRecentBuildReceived(const CString& response, LauncherUtils::ResponseError error) {
|
||||
if (error == LauncherUtils::ResponseError::NoError) {
|
||||
addToLog(_T("Latest version: ") + _latestVersion);
|
||||
CString currentVersion;
|
||||
if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) {
|
||||
addToLog(_T("Installed version: ") + currentVersion);
|
||||
if (_latestVersion.Compare(currentVersion) == 0) {
|
||||
addToLog(_T("Already running most recent build. Launching interface.exe"));
|
||||
_shouldLaunch = TRUE;
|
||||
_shouldShutdown = TRUE;
|
||||
} else {
|
||||
addToLog(_T("New build found. Updating"));
|
||||
_shouldUpdate = TRUE;
|
||||
}
|
||||
} else if (_loggedIn) {
|
||||
addToLog(_T("Interface not found but logged in. Reinstalling"));
|
||||
_shouldUpdate = TRUE;
|
||||
} else {
|
||||
_shouldInstall = TRUE;
|
||||
}
|
||||
_shouldWait = FALSE;
|
||||
} else {
|
||||
_hasFailed = true;
|
||||
CString msg;
|
||||
msg.Format(_T("Getting most recent build has failed with error: %d"), error);
|
||||
addToLog(msg);
|
||||
msg.Format(_T("Response: %s"), response);
|
||||
addToLog(msg);
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherManager::getAccessTokenForCredentials(const CString& username,
|
||||
|
@ -603,12 +607,10 @@ BOOL LauncherManager::downloadFile(ProcessType type, const CString& url, CString
|
|||
std::function<void(int, bool)> onDownloadFinished = [&](int type, bool error) {
|
||||
if (!error) {
|
||||
onFileDownloaded((ProcessType)type);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (type == ProcessType::DownloadApplication) {
|
||||
addToLog(_T("Error downloading content."));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
addToLog(_T("Error downloading application."));
|
||||
}
|
||||
_hasFailed = true;
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
BOOL isApplicationInstalled(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn);
|
||||
LauncherUtils::ResponseError getAccessTokenForCredentials(const CString& username, const CString& password);
|
||||
LauncherUtils::ResponseError getMostRecentBuild(CString& urlOut, CString& versionOut, CString& response);
|
||||
void getMostRecentBuild(CString& urlOut, CString& versionOut);
|
||||
LauncherUtils::ResponseError readOrganizationJSON(const CString& hash);
|
||||
LauncherUtils::ResponseError readConfigJSON(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn);
|
||||
|
@ -90,12 +90,13 @@ public:
|
|||
BOOL needsUpdate() { return _shouldUpdate; }
|
||||
BOOL needsUninstall() { return _shouldUninstall; }
|
||||
BOOL needsInstall() { return _shouldInstall; }
|
||||
BOOL needsToWait() { return _shouldWait; }
|
||||
void setDisplayName(const CString& displayName) { _displayName = displayName; }
|
||||
bool isLoggedIn() { return _loggedIn; }
|
||||
bool hasFailed() { return _hasFailed; }
|
||||
void setFailed(bool hasFailed) { _hasFailed = hasFailed; }
|
||||
const CString& getLatestInterfaceURL() const { return _latestApplicationURL; }
|
||||
void uninstall() { _shouldUninstall = true; };
|
||||
void uninstall() { _shouldUninstall = true; _shouldWait = false; };
|
||||
|
||||
BOOL downloadFile(ProcessType type, const CString& url, CString& localPath);
|
||||
BOOL downloadContent();
|
||||
|
@ -110,6 +111,7 @@ public:
|
|||
|
||||
private:
|
||||
ProcessType _currentProcess { ProcessType::DownloadApplication };
|
||||
void onMostRecentBuildReceived(const CString& response, LauncherUtils::ResponseError error);
|
||||
CString _latestApplicationURL;
|
||||
CString _latestVersion;
|
||||
CString _contentURL;
|
||||
|
@ -126,6 +128,7 @@ private:
|
|||
BOOL _shouldInstall { FALSE };
|
||||
BOOL _shouldShutdown { FALSE };
|
||||
BOOL _shouldLaunch { FALSE };
|
||||
BOOL _shouldWait { TRUE };
|
||||
float _progress { 0.0f };
|
||||
CStdioFile _logFile;
|
||||
};
|
||||
|
|
|
@ -470,9 +470,9 @@ BOOL LauncherUtils::hMac256(const CString& cmessage, const char* keystr, CString
|
|||
|
||||
DWORD WINAPI LauncherUtils::unzipThread(LPVOID lpParameter) {
|
||||
UnzipThreadData& data = *((UnzipThreadData*)lpParameter);
|
||||
uint64_t size = LauncherUtils::extractZip(data._zipFile, data._path, std::vector<std::string>(), data.progressCallback);
|
||||
uint64_t size = LauncherUtils::extractZip(data._zipFile, data._path, std::vector<std::string>(), data._progressCallback);
|
||||
int mb_size = (int)(size * 0.001f);
|
||||
data.callback(data._type, mb_size);
|
||||
data._callback(data._type, mb_size);
|
||||
delete &data;
|
||||
return 0;
|
||||
}
|
||||
|
@ -480,17 +480,26 @@ DWORD WINAPI LauncherUtils::unzipThread(LPVOID lpParameter) {
|
|||
DWORD WINAPI LauncherUtils::downloadThread(LPVOID lpParameter) {
|
||||
DownloadThreadData& data = *((DownloadThreadData*)lpParameter);
|
||||
ProgressCallback progressCallback;
|
||||
progressCallback.setProgressCallback(data.progressCallback);
|
||||
progressCallback.setProgressCallback(data._progressCallback);
|
||||
auto hr = URLDownloadToFile(0, data._url, data._file, 0,
|
||||
static_cast<LPBINDSTATUSCALLBACK>(&progressCallback));
|
||||
data.callback(data._type, hr != S_OK);
|
||||
data._callback(data._type, hr != S_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI LauncherUtils::deleteDirectoryThread(LPVOID lpParameter) {
|
||||
DeleteThreadData& data = *((DeleteThreadData*)lpParameter);
|
||||
BOOL success = LauncherUtils::deleteFileOrDirectory(data._dirPath);
|
||||
data.callback(!success);
|
||||
data._callback(!success);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI LauncherUtils::httpThread(LPVOID lpParameter) {
|
||||
HttpThreadData& data = *((HttpThreadData*)lpParameter);
|
||||
CString response;
|
||||
auto error = LauncherUtils::makeHTTPCall(data._callerName, data._mainUrl, data._dirUrl,
|
||||
data._contentType, data._postData, response, data._isPost);
|
||||
data._callback(response, error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -543,6 +552,26 @@ BOOL LauncherUtils::deleteDirectoryOnThread(const CString& dirPath, std::functio
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::httpCallOnThread(const CString& callerName, const CString& mainUrl, const CString& dirUrl,
|
||||
const CString& contentType, CStringA& postData, bool isPost,
|
||||
std::function<void(CString, int)> callback) {
|
||||
DWORD myThreadID;
|
||||
HttpThreadData* httpThreadData = new HttpThreadData();
|
||||
httpThreadData->_callerName = callerName;
|
||||
httpThreadData->_mainUrl = mainUrl;
|
||||
httpThreadData->_dirUrl = dirUrl;
|
||||
httpThreadData->_contentType = contentType;
|
||||
httpThreadData->_postData = postData;
|
||||
httpThreadData->_isPost = isPost;
|
||||
httpThreadData->setCallback(callback);
|
||||
HANDLE myHandle = CreateThread(0, 0, httpThread, httpThreadData, 0, &myThreadID);
|
||||
if (myHandle) {
|
||||
CloseHandle(myHandle);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HWND LauncherUtils::executeOnForeground(const CString& path, const CString& params) {
|
||||
SHELLEXECUTEINFO info;
|
||||
info.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
|
|
|
@ -55,15 +55,15 @@ public:
|
|||
ULONG ulStatusCode, LPCWSTR szStatusText) {
|
||||
float progress = (float)ulProgress / ulProgressMax;
|
||||
if (!isnan(progress)) {
|
||||
onProgressCallback(progress);
|
||||
_onProgressCallback(progress);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
void setProgressCallback(std::function<void(float)> fn) {
|
||||
onProgressCallback = std::bind(fn, std::placeholders::_1);
|
||||
_onProgressCallback = std::bind(fn, std::placeholders::_1);
|
||||
}
|
||||
private:
|
||||
std::function<void(float)> onProgressCallback;
|
||||
std::function<void(float)> _onProgressCallback;
|
||||
};
|
||||
|
||||
enum ResponseError {
|
||||
|
@ -82,14 +82,14 @@ public:
|
|||
int _type;
|
||||
CString _url;
|
||||
CString _file;
|
||||
std::function<void(int, bool)> callback;
|
||||
std::function<void(float)> progressCallback;
|
||||
std::function<void(int, bool)> _callback;
|
||||
std::function<void(float)> _progressCallback;
|
||||
// function(type, errorType)
|
||||
void setCallback(std::function<void(int, bool)> fn) {
|
||||
callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
_callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
}
|
||||
void setProgressCallback(std::function<void(float)> fn) {
|
||||
progressCallback = std::bind(fn, std::placeholders::_1);
|
||||
_progressCallback = std::bind(fn, std::placeholders::_1);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -98,23 +98,36 @@ public:
|
|||
std::string _zipFile;
|
||||
std::string _path;
|
||||
// function(type, size)
|
||||
std::function<void(int, int)> callback;
|
||||
std::function<void(float)> progressCallback;
|
||||
std::function<void(int, int)> _callback;
|
||||
std::function<void(float)> _progressCallback;
|
||||
void setCallback(std::function<void(int, int)> fn) {
|
||||
callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
_callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
}
|
||||
void setProgressCallback(std::function<void(float)> fn) {
|
||||
progressCallback = std::bind(fn, std::placeholders::_1);
|
||||
_progressCallback = std::bind(fn, std::placeholders::_1);
|
||||
}
|
||||
};
|
||||
|
||||
struct DeleteThreadData {
|
||||
CString _dirPath;
|
||||
std::function<void(bool)> callback;
|
||||
std::function<void(float)> progressCallback;
|
||||
void setCallback(std::function<void(bool)> fn) { callback = std::bind(fn, std::placeholders::_1); }
|
||||
std::function<void(bool)> _callback;
|
||||
std::function<void(float)> _progressCallback;
|
||||
void setCallback(std::function<void(bool)> fn) { _callback = std::bind(fn, std::placeholders::_1); }
|
||||
void setProgressCallback(std::function<void(float)> fn) {
|
||||
progressCallback = std::bind(fn, std::placeholders::_1);
|
||||
_progressCallback = std::bind(fn, std::placeholders::_1);
|
||||
}
|
||||
};
|
||||
|
||||
struct HttpThreadData {
|
||||
CString _callerName;
|
||||
CString _mainUrl;
|
||||
CString _dirUrl;
|
||||
CString _contentType;
|
||||
CStringA _postData;
|
||||
bool _isPost { false };
|
||||
std::function<void(CString, int)> _callback;
|
||||
void setCallback(std::function<void(CString, int)> fn) {
|
||||
_callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -150,6 +163,9 @@ public:
|
|||
std::function<void(int, bool)> callback,
|
||||
std::function<void(float)> progressCallback);
|
||||
static BOOL deleteDirectoryOnThread(const CString& dirPath, std::function<void(bool)> callback);
|
||||
static BOOL httpCallOnThread(const CString& callerName, const CString& mainUrl, const CString& dirUrl,
|
||||
const CString& contentType, CStringA& postData, bool isPost,
|
||||
std::function<void(CString, int)> callback);
|
||||
|
||||
static CString urlEncodeString(const CString& url);
|
||||
static HWND executeOnForeground(const CString& path, const CString& params);
|
||||
|
@ -159,4 +175,5 @@ private:
|
|||
static DWORD WINAPI unzipThread(LPVOID lpParameter);
|
||||
static DWORD WINAPI downloadThread(LPVOID lpParameter);
|
||||
static DWORD WINAPI deleteDirectoryThread(LPVOID lpParameter);
|
||||
};
|
||||
static DWORD WINAPI httpThread(LPVOID lpParameter);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue