diff --git a/modules/core/main_window.ts b/modules/core/main_window.ts index 1c2eda1..80bc040 100644 --- a/modules/core/main_window.ts +++ b/modules/core/main_window.ts @@ -112,7 +112,7 @@ function handle_uo_load_error(message: string) { type: "error", buttons: ["exit"], title: "A critical error happened while loading TeaClient!", - message: message + message: (message || "no error").toString() }).then(unreference_app); loader.ui.cancel(); } diff --git a/modules/core/ui-loader/loader.ts b/modules/core/ui-loader/loader.ts index 3aa1dc5..fd60607 100644 --- a/modules/core/ui-loader/loader.ts +++ b/modules/core/ui-loader/loader.ts @@ -166,15 +166,15 @@ async function client_shipped_ui() : Promise { channel: entry["channel"], versions_hash: entry["git-ref"], version: entry["version"], - timestamp: entry["timestamp"], + timestamp: parseInt(entry["timestamp"]) * 1000, /* server provices that stuff in seconds */ min_client_version: entry["required_client"] }); } @@ -256,7 +256,7 @@ async function download_ui_pack(version: local_ui_cache.UIPackInfo) : Promise { + gunzip.on('error', event => { + reject(event); + }); + extract.on('finish', resolve); extract.on('error', event => { if(!event) return; reject(event); }); + + fpipe.pipe(gunzip).pipe(extract); }); - fpipe.pipe(gunzip).pipe(extract); try { await finish_promise; } catch(error) { @@ -449,10 +454,12 @@ async function load_cached_or_remote_ui_pack(channel: string, stats_update: (mes } const required_version = parse_version(e.pack_info.min_client_version); - return client_version.newer_than(required_version) || client_version.equals(required_version); + return client_version.in_dev() || client_version.newer_than(required_version) || client_version.equals(required_version); }); - if(process_args.has_flag(Arguments.UPDATER_UI_NO_CACHE)) + if(process_args.has_flag(Arguments.UPDATER_UI_NO_CACHE)) { + console.log("Ignoring local UI cache"); available_versions = []; + } let remote_version_dropped = false; /* remote version gathering */ @@ -472,9 +479,9 @@ async function load_cached_or_remote_ui_pack(channel: string, stats_update: (mes if(!remote_version && available_versions.length === 0) throw "no UI pack available for channel " + channel; - let newest_local_version = available_versions.map(e => e.download_timestamp).reduce((a, b) => Math.max(a, b), bundles_ui ? bundles_ui.download_timestamp : 0); + let newest_local_version = available_versions.map(e => e.pack_info.timestamp).reduce((a, b) => Math.max(a, b), bundles_ui ? bundles_ui.download_timestamp : 0); const required_version = parse_version(remote_version.min_client_version); - if(required_version.newer_than(client_version)) { + if(required_version.newer_than(client_version) && !is_debug) { const result = await electron.dialog.showMessageBox({ type: "question", message: @@ -482,12 +489,14 @@ async function load_cached_or_remote_ui_pack(channel: string, stats_update: (mes "Newer UI packs (>= " + remote_version.version + ", " + remote_version.versions_hash + ") require client " + remote_version.min_client_version + "\n" + "Do you want to update your client?", title: "Client outdated!", - buttons: ["yes", available_versions.length === 0 ? "close client" : "ignore and use last possible"] + buttons: ["Update client", available_versions.length === 0 ? "Close client" : "Ignore and use last possible"] } as MessageBoxOptions); if(result.response == 0) { - await execute_graphical(channel, true); - throw "client outdated"; + if(!await execute_graphical(channel, true)) + throw "Client outdated an no suitable UI pack versions found"; + else + return; } else { if(available_versions.length === 0) { electron.app.exit(1); @@ -500,7 +509,9 @@ async function load_cached_or_remote_ui_pack(channel: string, stats_update: (mes } else { /* update is possible because the timestamp is newer than out latest local version */ try { - stats_update("Download new UI pack", .55); + console.log("Downloading UI pack version (%d) %s. Forced: %s. Newest local version: %d", remote_version.timestamp, + remote_version.versions_hash, ignore_new_version_timestamp ? "true" : "false", newest_local_version); + stats_update("Downloading new UI pack", .55); available_versions.push(await download_ui_pack(remote_version)); } catch (error) { console.error("Failed to download new UI pack: %o", error); @@ -513,22 +524,24 @@ async function load_cached_or_remote_ui_pack(channel: string, stats_update: (mes /* Only invalidate the version if any other succeeded to load. Else we might fucked up (no permission to write etc) */ let invalidate_versions: local_ui_cache.CachedUIPack[] = []; + const do_invalidate_versions = async () => { + if(invalidate_versions.length > 0) { + for(const version of invalidate_versions) { + version.invalid_reason = "failed to unpack"; + version.status = "invalid"; + } + await local_ui_cache.save(); + } + }; + while(available_versions.length > 0) { const pack = available_versions.pop(); - console.log("Trying to load UI pack from %s (%s). Downloaded at %s", moment(pack.pack_info.timestamp).format("llll"), moment(pack.pack_info.versions_hash).format("llll"), moment(pack.download_timestamp).format("llll")) + console.log("Trying to load UI pack from %s (%s). Downloaded at %s", moment(pack.pack_info.timestamp).format("llll"), pack.pack_info.versions_hash, moment(pack.download_timestamp).format("llll")); try { const target = await unpack_local_ui_pack(pack); stats_update("UI pack loaded", 1); - - if(invalidate_versions.length > 0) { - for(const version of invalidate_versions) { - version.invalid_reason = "failed to unpack"; - version.status = "invalid"; - } - await local_ui_cache.save(); - } - + await do_invalidate_versions(); return path.join(target, "index.html"); } catch (error) { invalidate_versions.push(pack); @@ -539,6 +552,8 @@ async function load_cached_or_remote_ui_pack(channel: string, stats_update: (mes if(remote_version_dropped) { /* try again, but this time enforce a remote download */ await load_cached_or_remote_ui_pack(channel, stats_update, true); + await do_invalidate_versions(); /* new UI pack seems to be successfully loaded */ + return; /* if not succeeded an exception will be thrown */ } throw "Failed to load any UI pack (local and remote)\nView the console for more details.\n"; diff --git a/modules/core/ui-loader/local_ui_cache.ts b/modules/core/ui-loader/local_ui_cache.ts index e4f3fbc..16b42cb 100644 --- a/modules/core/ui-loader/local_ui_cache.ts +++ b/modules/core/ui-loader/local_ui_cache.ts @@ -79,10 +79,11 @@ let ui_cache_: CacheFile = { }; async function load_() : Promise { const file = path.join(cache_path(), "data.json"); - if(!(await util.promisify(fs.exists)(file))) - return ui_cache_; try { + if(!(await fs.pathExists(file))) + return ui_cache_; + const data = await fs.readJSON(file) as CacheFile; if(!data) throw "invalid data object"; @@ -123,7 +124,7 @@ export function unload() { export async function save() { const file = path.join(cache_path(), "data.json"); try { - if(!(await util.promisify(fs.exists)(path.dirname(file)))) + if(!(await fs.pathExists(path.dirname(file)))) await fs.mkdirs(path.dirname(file)); await fs.writeJson(file, ui_cache_); } catch (error) {