From 2a4dcc03e3ecd19a760d0936635ef1a1e15a94d7 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Wed, 29 Dec 2021 19:32:09 +0200 Subject: [PATCH] API improvements - now pre-downloaded game will be automatically unpacked --- src/ts/Game.ts | 25 ++++++-- src/ts/Voice.ts | 41 +++++++++---- src/ts/core/AbstractInstaller.ts | 101 ++++++++++++++++++------------- 3 files changed, 108 insertions(+), 59 deletions(-) diff --git a/src/ts/Game.ts b/src/ts/Game.ts index 04477ae..5d5d4b0 100644 --- a/src/ts/Game.ts +++ b/src/ts/Game.ts @@ -18,9 +18,9 @@ declare const Neutralino; class Stream extends AbstractInstaller { - public constructor(uri: string) + public constructor(uri: string, predownloaded: boolean = false) { - super(uri, constants.paths.gameDir); + super(uri, constants.paths.gameDir, predownloaded); } } @@ -170,9 +170,24 @@ export default class Game }); return new Promise((resolve, reject) => { - (version === null ? this.latest : this.getDiff(version)) - .then((data: Latest|Diff|null) => resolve(data === null ? null : new Stream(data.path))) - .catch((error) => reject(error)); + this.isUpdatePredownloaded().then(async (predownloaded) => { + if (predownloaded) + { + Debug.log({ + function: 'Game.update', + message: 'Update is already pre-downloaded. Unpacking started' + }); + + resolve(new Stream(`${await constants.paths.launcherDir}/game-predownloaded.zip`, true)); + } + + else + { + (version === null ? this.latest : this.getDiff(version)) + .then((data: Latest|Diff|null) => resolve(data === null ? null : new Stream(data.path))) + .catch((error) => reject(error)); + } + }); }); } diff --git a/src/ts/Voice.ts b/src/ts/Voice.ts index 9f40304..2373168 100644 --- a/src/ts/Voice.ts +++ b/src/ts/Voice.ts @@ -12,9 +12,9 @@ declare const Neutralino; class Stream extends AbstractInstaller { - public constructor(uri: string) + public constructor(uri: string, predownloaded: boolean = false) { - super(uri, constants.paths.gameDir); + super(uri, constants.paths.gameDir, predownloaded); } } @@ -129,19 +129,34 @@ export default class Voice }); return new Promise((resolve, reject) => { - (version === null ? this.latest : this.getDiff(version)) - .then((data: VoicePack[]|null) => { - if (data === null) - resolve(null); + this.isUpdatePredownloaded(lang).then(async (predownloaded) => { + if (predownloaded) + { + Debug.log({ + function: 'Voice.update', + message: 'Voice package update is already pre-downloaded. Unpacking started' + }); - else - { - const voice = data.filter(voice => voice.language === lang); + resolve(new Stream(`${await constants.paths.launcherDir}/voice-${lang}-predownloaded.zip`, true)); + } - resolve(voice.length === 1 ? new Stream(voice[0].path) : null); - } - }) - .catch((error) => reject(error)); + else + { + (version === null ? this.latest : this.getDiff(version)) + .then((data: VoicePack[]|null) => { + if (data === null) + resolve(null); + + else + { + const voice = data.filter(voice => voice.language === lang); + + resolve(voice.length === 1 ? new Stream(voice[0].path) : null); + } + }) + .catch((error) => reject(error)); + } + }); }); } diff --git a/src/ts/core/AbstractInstaller.ts b/src/ts/core/AbstractInstaller.ts index ddbf409..fb096da 100644 --- a/src/ts/core/AbstractInstaller.ts +++ b/src/ts/core/AbstractInstaller.ts @@ -32,81 +32,100 @@ export default abstract class Installer protected downloadFinished: boolean = false; protected unpackFinished: boolean = false; - public constructor(uri: string, unpackDir: string|Promise) + /** + * @param uri URI to the archive we need to download + * @param unpackDir path to unpack this archive to + * + * @param alreadyDownloaded specifies whether the archive was already downloaded + * If true, then URI will be used as a path to the archive. Otherwise stream will download it + */ + public constructor(uri: string, unpackDir: string|Promise, alreadyDownloaded: boolean = false) { + const shouldResolve = typeof unpackDir !== 'string'; + const debugThread = new DebugThread('AbstractInstaller', { message: { 'uri': uri, - 'unpack dir': typeof unpackDir === 'string' ? unpackDir : '' + 'unpack dir': shouldResolve ? '' : unpackDir, + 'already downloaded': alreadyDownloaded ? 'true' : 'false' } }); constants.paths.launcherDir.then((launcherDir) => { - const archivePath = `${launcherDir}/${Downloader.fileFromUri(uri)}`; + const archivePath = alreadyDownloaded ? uri : `${launcherDir}/${Downloader.fileFromUri(uri)}`; - // Download archive - Downloader.download(uri, archivePath).then((stream) => { - stream.progressInterval = this.downloadProgressInterval; + // And then unpack it + const unpackArchive = () => { + Promise.resolve(unpackDir) + .then((unpackDir) => { + if (shouldResolve) + debugThread.log(`Resolved unpack dir: ${unpackDir}`); - stream.start(() => { - this.downloadStarted = true; - - if (this.onDownloadStart) - this.onDownloadStart(); - }); - - stream.progress((current, total, difference) => { - if (this.onDownloadProgress) - this.onDownloadProgress(current, total, difference); - }); - - stream.finish(() => { - this.downloadFinished = true; - - if (this.onDownloadFinish) - this.onDownloadFinish(); - - // And then unpack it - const unpackArchive = (unpackDir: string) => { Archive.unpack(archivePath, unpackDir).then((stream) => { stream.progressInterval = this.unpackProgressInterval; - + stream.start(() => { this.unpackStarted = true; if (this.onUnpackStart) this.onUnpackStart(); }); - + stream.progress((current, total, difference) => { if (this.onUnpackProgress) this.onUnpackProgress(current, total, difference); }); - + stream.finish(() => { this.unpackFinished = true; - + Neutralino.filesystem.removeFile(archivePath); - + debugThread.log('Installation finished'); - + if (this.onUnpackFinish) this.onUnpackFinish(); }); }); - }; + }); + }; - const shouldResolve = typeof unpackDir !== 'string'; + // Download archive + if (!alreadyDownloaded) + { + Downloader.download(uri, archivePath).then((stream) => { + stream.progressInterval = this.downloadProgressInterval; - Promise.resolve(unpackDir) - .then((unpackDir) => { - if (shouldResolve) - debugThread.log(`Resolved unpack dir: ${unpackDir}`); + stream.start(() => { + this.downloadStarted = true; - unpackArchive(unpackDir); - }); + if (this.onDownloadStart) + this.onDownloadStart(); + }); + + stream.progress((current, total, difference) => { + if (this.onDownloadProgress) + this.onDownloadProgress(current, total, difference); + }); + + stream.finish(() => { + this.downloadFinished = true; + + if (this.onDownloadFinish) + this.onDownloadFinish(); + + Promise.resolve(unpackDir) + .then((unpackDir) => { + if (shouldResolve) + debugThread.log(`Resolved unpack dir: ${unpackDir}`); + + unpackArchive(); + }); + }); }); - }); + } + + else unpackArchive(); }); }