From a1d1d9a3ca4713ff64737135946c3820d1b4f851 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Tue, 21 Dec 2021 18:58:33 +0200 Subject: [PATCH] Several changes - updated requirements: added `webkit2gtk` and `curl` - added `Configs` class - updated `Constants` - removed process existing checking from `Downloader.ts` --- README.md | 6 +- src/pages/index.ts | 3 +- src/ts/Configs.ts | 112 ++++++++++++++++++++++++++++++++++++++ src/ts/Constants.ts | 42 +++++--------- src/ts/DXVK.ts | 0 src/ts/Downloader.ts | 62 ++++++++++----------- src/ts/Runners.ts | 10 ++-- src/ts/types/Runners.d.ts | 16 +++--- 8 files changed, 174 insertions(+), 77 deletions(-) create mode 100644 src/ts/Configs.ts create mode 100644 src/ts/DXVK.ts diff --git a/README.md b/README.md index 35b3fcf..e4a0620 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,11 @@ To work this launcher requires | Name | Description | | --- | --- | +| webkit2gtk | To run Neutralino apps | | unzip | To unpack zip archives (DXVKs / wines) | | tar | To unpack tar archives (DXVKs / wines) | | git | To check for new versions of the launcher | +| curl | To download archives with game, voice data, runners and so on | | xdelta3 | To apply the patch to the game | | cabextract | To install fonts to the wine prefix | @@ -59,13 +61,13 @@ To work this launcher requires ### apt-get ```sh -sudo apt-get install unzip tar git xdelta3 cabextract +sudo apt-get install webkit2gtk unzip tar git curl xdelta3 cabextract ``` ### pacman ```sh -sudo pacman -Syu unzip tar git xdelta3 cabextract +sudo pacman -Syu webkit2gtk unzip tar git curl xdelta3 cabextract ``` # Additional requirements diff --git a/src/pages/index.ts b/src/pages/index.ts index af30128..8389c22 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -4,6 +4,7 @@ import Window from '../ts/neutralino/Window'; import Downloader from '../ts/Downloader'; import Archive from '../ts/Archive'; +import Configs from '../ts/Configs'; const app = Vue.createApp({ data: () => ({ @@ -25,7 +26,7 @@ const app = Vue.createApp({ stream.finish(() => console.log('finished')); });*/ - /*Downloader.download('https://autopatchhk.yuanshen.com/client_app/download/pc_zip/20211117173404_G0gLRnxvOd4PvSu9/Audio_English(US)_2.3.0.zip').then((stream) => { + /*Downloader.download('https://autopatchhk.yuanshen.com/client_app/download/pc_zip/20211117173404_G0gLRnxvOd4PvSu9/Audio_English(US)_2.3.0.zip', '123.zip').then((stream) => { stream.progress((current: number, total: number) => { document.getElementById('progress').innerHTML = `${Math.round(current / total * 100)}%`; }); diff --git a/src/ts/Configs.ts b/src/ts/Configs.ts new file mode 100644 index 0000000..39bb82a --- /dev/null +++ b/src/ts/Configs.ts @@ -0,0 +1,112 @@ +import Constants from './Constants'; + +// Ok yea, null and object aren't scalars +// but I don't care +type scalar = null | string | number | object; + +export default class Configs +{ + /** + * Get config value + * + * @param name config name, e.g. "lang.launcher" + * @returns Promise + */ + public static get(name: string = ''): Promise + { + return new Promise(async (resolve) => { + // @ts-expect-error + Neutralino.filesystem.readFile(await Constants.paths.config).then((config) => { + config = JSON.parse(config); + + if (name !== '') + { + name.split('.').forEach((value) => { + config = config[value]; + }); + } + + resolve(config); + }).catch(() => resolve(undefined)); + }); + } + + /** + * Set config value + * + * @param name config name, e.g. "lang.launcher" + * @param value config value, e.g. "en-us" + * @returns Promise indicates when the settings was updated + */ + public static set(name: string, value: scalar|scalar[]): Promise + { + const getUpdatedArray = (path: string[], array: scalar|scalar[], value: scalar|scalar[]): scalar|scalar[] => { + array[path[0]] = path.length > 1 ? + getUpdatedArray(path.slice(1), array[path[0]] ?? {}, value) : value; + + return array; + }; + + return new Promise(async (resolve) => { + // @ts-expect-error + Neutralino.filesystem.readFile(await Constants.paths.config).then(async (config) => { + config = JSON.stringify(getUpdatedArray(name.split('.'), JSON.parse(config), value), null, 4); + + // @ts-expect-error + Neutralino.filesystem.writeFile(await Constants.paths.config, config) + .then(() => resolve()); + }).catch(async () => { + let config = JSON.stringify(getUpdatedArray(name.split('.'), {}, value), null, 4); + + // @ts-expect-error + Neutralino.filesystem.writeFile(await Constants.paths.config, config) + .then(() => resolve()); + }); + }); + } + + /** + * Set default values + * + * @param configs object of default values + */ + public static defaults(configs: scalar): Promise + { + return new Promise(async (resolve) => { + const setDefaults = async (current: scalar) => { + const updateDefaults = (current: scalar, defaults: scalar) => { + Object.keys(defaults).forEach((key) => { + // If the field exists in defaults and don't exists in current + if (current[key] === undefined) + current[key] = defaults[key]; + + // If default is scalar and current object + else if (typeof current[key] == 'object' && typeof defaults[key] != 'object') + current[key] = defaults[key]; + + // If default is object and current scalar + else if (typeof current[key] != 'object' && typeof defaults[key] == 'object') + current[key] = defaults[key]; + + // If both of default and current are objects + else if (typeof current[key] == 'object' && typeof defaults[key] == 'object') + current[key] = updateDefaults(current[key], defaults[key]); + }); + + return current; + }; + + current = JSON.stringify(updateDefaults(current, configs), null, 4); + + // @ts-expect-error + Neutralino.filesystem.writeFile(await Constants.paths.config, current) + .then(() => resolve()); + }; + + // @ts-expect-error + Neutralino.filesystem.readFile(await Constants.paths.config) + .then((config) => setDefaults(JSON.parse(config))) + .catch(() => setDefaults({})); + }); + } +} diff --git a/src/ts/Constants.ts b/src/ts/Constants.ts index fd16e11..c803bc1 100644 --- a/src/ts/Constants.ts +++ b/src/ts/Constants.ts @@ -1,4 +1,4 @@ -class Dirs +class Paths { /** * Directory where the launcher's executable stored @@ -11,7 +11,7 @@ class Dirs /** * Shaders directory * - * Default is [constants.dirs.app]/public/shaders + * Default is [constants.paths.app]/public/shaders * * @returns string */ @@ -54,6 +54,18 @@ class Dirs return new Promise(async (resolve) => resolve(`${await this.launcher}/dxvks`)); } + /** + * Config file + * + * Default is ~/.local/share/anime-game-launcher/config.json + * + * @returns Promise + */ + public static get config(): Promise + { + return new Promise(async (resolve) => resolve(`${await this.launcher}/config.json`)); + } + /*public static readonly prefix = new class { /** @@ -125,7 +137,7 @@ export default class constants new Date('January 5, 2022').getTime() // 2.4.0 half 1 release ];*/ - public static readonly dirs = Dirs; + public static readonly paths = Paths; public static readonly versionsUri: string = `${this.uri.api}/resource?key=gcStgarh&launcher_id=10`; public static readonly backgroundUri: string = `${this.uri.api}/content?filter_adv=true&launcher_id=10&key=gcStgarh&language=`; @@ -133,30 +145,6 @@ export default class constants public static readonly runnersUri: string = `${this.uri.launcher}/raw/main/runners.json`; public static readonly dxvksUri: string = `${this.uri.launcher}/raw/main/dxvks.json`; - /*public static prefixDir = new class - { - public get(): string - { - return LauncherLib.getConfig('prefix'); - } - - public getDefault(): string - { - return path.join(os.homedir(), '.local', 'share', 'anime-game-launcher', 'game'); - } - - public set(location: string) - { - if (path.relative(LauncherLib.getConfig('prefix'), location) === '') - return console.log('Can\'t set already selected prefix as new prefix'); - - const dataPath = path.join(location, 'drive_c', 'Program Files', constants.placeholders.uppercase.full, `${constants.placeholders.uppercase.first + constants.placeholders.uppercase.second}_Data`); - - LauncherLib.updateConfig('prefix', location); - LauncherLib.updateConfig('version', LauncherLib.getGameVersion(dataPath)); - } - }*/ - /*public static get gameDir(): string { return path.join(this.prefixDir.get(), 'drive_c', 'Program Files', this.placeholders.uppercase.full); diff --git a/src/ts/DXVK.ts b/src/ts/DXVK.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/ts/Downloader.ts b/src/ts/Downloader.ts index 5a37c9f..440df77 100644 --- a/src/ts/Downloader.ts +++ b/src/ts/Downloader.ts @@ -20,41 +20,35 @@ class Stream this.total = total; // @ts-expect-error - Neutralino.os.execCommand('pidof curl').then((stats) => { - if (stats.stdOut == '') - { - // @ts-expect-error - Neutralino.os.execCommand(`curl -s -L -N -o "${output}" "${uri}"`, { - background: true - }); - - const updateProgress = () => { - // @ts-expect-error - Neutralino.filesystem.getStats(output).then((stats) => { - if (this.onProgress) - this.onProgress(stats.size, this.total, this.previous - stats.size); - - this.previous = stats.size; - - if (stats.size >= this.total) - { - this.finished = true; - - if (this.onFinish) - this.onFinish(); - } - - if (!this.finished) - setTimeout(updateProgress, this.progressInterval); - }).catch(() => { - if (!this.finished) - setTimeout(updateProgress, this.progressInterval); - }); - }; - - setTimeout(updateProgress, this.progressInterval); - } + Neutralino.os.execCommand(`curl -s -L -N -o "${output}" "${uri}"`, { + background: true }); + + const updateProgress = () => { + // @ts-expect-error + Neutralino.filesystem.getStats(output).then((stats) => { + if (this.onProgress) + this.onProgress(stats.size, this.total, this.previous - stats.size); + + this.previous = stats.size; + + if (stats.size >= this.total) + { + this.finished = true; + + if (this.onFinish) + this.onFinish(); + } + + if (!this.finished) + setTimeout(updateProgress, this.progressInterval); + }).catch(() => { + if (!this.finished) + setTimeout(updateProgress, this.progressInterval); + }); + }; + + setTimeout(updateProgress, this.progressInterval); } /** diff --git a/src/ts/Runners.ts b/src/ts/Runners.ts index f3f6a5a..7cd94ec 100644 --- a/src/ts/Runners.ts +++ b/src/ts/Runners.ts @@ -1,6 +1,6 @@ import type { Runner, - RunnersFamily + RunnerFamily } from './types/Runners'; import constants from './Constants'; @@ -15,9 +15,9 @@ class Runners public static get(): Promise { return new Promise((resolve) => { - constants.dirs.runners.then(async (runnersDir: string) => { + constants.paths.runners.then(async (runnersDir: string) => { // @ts-expect-error - let list: RunnersFamily[] = JSON.parse(await Neutralino.filesystem.readFile(`${constants.dirs.app}/public/runners.json`)); + let list: RunnerFamily[] = JSON.parse(await Neutralino.filesystem.readFile(`${constants.dirs.app}/public/runners.json`)); // @ts-expect-error const installed: { entry: string, type: string }[] = await Neutralino.filesystem.readDirectory(runnersDir); @@ -25,7 +25,7 @@ class Runners let runners = []; list.forEach((family) => { - let newFamily: RunnersFamily = { + let newFamily: RunnerFamily = { title: family.title, runners: [] }; @@ -63,5 +63,5 @@ export default Runners; export type { Runner, - RunnersFamily + RunnerFamily }; diff --git a/src/ts/types/Runners.d.ts b/src/ts/types/Runners.d.ts index d8698f4..fdedddb 100644 --- a/src/ts/types/Runners.d.ts +++ b/src/ts/types/Runners.d.ts @@ -1,16 +1,16 @@ type Runner = { /** - * i.e. proton-ge + * e.g. proton-ge */ family: string; /** - * i.e. Proton-6.20-GE-1 + * e.g. Proton-6.20-GE-1 */ name: string; /** - * i.e. Proton 6.20 GE 1 + * e.g. Proton 6.20 GE 1 */ title: string; @@ -18,17 +18,17 @@ type Runner = { files: { /** - * i.e. bin/wine64 + * e.g. bin/wine64 */ wine: string; /** - * i.e. bin/wineserver + * e.g. bin/wineserver */ wineserver: string; /** - * i.e. lib64/wine/x86_64-windows/winecfg.exe + * e.g. lib64/wine/x86_64-windows/winecfg.exe */ winecfg: string; }; @@ -37,12 +37,12 @@ type Runner = { installed: boolean; }; -type RunnersFamily = { +type RunnerFamily = { title: string; runners: Runner[]; }; export type { Runner, - RunnersFamily + RunnerFamily };