Improved the clients UI loader

This commit is contained in:
WolverinDEV 2020-04-02 11:13:44 +02:00
parent fbbbbcd7ef
commit 865f4e27a0
3 changed files with 44 additions and 28 deletions

View File

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

View File

@ -166,15 +166,15 @@ async function client_shipped_ui() : Promise<local_ui_cache.CachedUIPack | undef
} = await fs.readJson(path.join(base_path, "default_ui_info.json")) as any;
return {
download_timestamp: info.timestamp,
download_timestamp: info.timestamp * 1000,
status: "valid",
invalid_reason: undefined,
local_checksum: "none",
local_file_path: path.join(path.join(path.dirname(app_path), "ui"), info.filename),
pack_info: {
channel: info.channel,
min_client_version: "0.0.0", //TODO: Just take the current client version
timestamp: info.timestamp,
min_client_version: info.required_client,
timestamp: info.timestamp * 1000,
version: info.version,
versions_hash: info.git_hash
}
@ -224,7 +224,7 @@ async function query_ui_pack_versions() : Promise<local_ui_cache.UIPackInfo[]> {
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<lo
"type": "ui-download",
"git-ref": version.versions_hash,
"version": version.version,
"timestamp": version.timestamp,
"timestamp": Math.floor(version.timestamp / 1000), /* remote server has only the timestamp in seconds*/
"channel": version.channel
}), {
timeout: TIMEOUT
@ -342,14 +342,19 @@ async function unpack_local_ui_pack(version: local_ui_cache.CachedUIPack) : Prom
});
const finish_promise = new Promise((resolve, reject) => {
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";

View File

@ -79,10 +79,11 @@ let ui_cache_: CacheFile = {
};
async function load_() : Promise<CacheFile> {
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) {