API improvements

- changed dxvk fields
- added abstract `Installer` class to simplify `Stream` classes
- added `DXVK` class
- updated comments
This commit is contained in:
Observer KRypt0n_ 2021-12-21 23:28:46 +02:00
parent bde04d7a9a
commit 748b197984
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
11 changed files with 283 additions and 203 deletions

View file

@ -2,56 +2,56 @@
{ {
"version": "1.9.2", "version": "1.9.2",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9.2/dxvk-1.9.2.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9.2/dxvk-1.9.2.tar.gz",
"recommendable": true "recommended": true
}, },
{ {
"version": "1.9.1", "version": "1.9.1",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9.1/dxvk-1.9.1.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9.1/dxvk-1.9.1.tar.gz",
"recommendable": true "recommended": true
}, },
{ {
"version": "1.9", "version": "1.9",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9/dxvk-1.9.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9/dxvk-1.9.tar.gz",
"recommendable": true "recommended": true
}, },
{ {
"version": "1.8.1", "version": "1.8.1",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.8.1/dxvk-1.8.1.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.8.1/dxvk-1.8.1.tar.gz",
"recommendable": true "recommended": true
}, },
{ {
"version": "1.8", "version": "1.8",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.8/dxvk-1.8.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.8/dxvk-1.8.tar.gz",
"recommendable": true "recommended": true
}, },
{ {
"version": "1.7.3", "version": "1.7.3",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.3/dxvk-1.7.3.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.3/dxvk-1.7.3.tar.gz",
"recommendable": false "recommended": false
}, },
{ {
"version": "1.7.2", "version": "1.7.2",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.2/dxvk-1.7.2.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.2/dxvk-1.7.2.tar.gz",
"recommendable": false "recommended": false
}, },
{ {
"version": "1.7.1", "version": "1.7.1",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.1/dxvk-1.7.1.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.1/dxvk-1.7.1.tar.gz",
"recommendable": false "recommended": false
}, },
{ {
"version": "1.7", "version": "1.7",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7/dxvk-1.7.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7/dxvk-1.7.tar.gz",
"recommendable": false "recommended": false
}, },
{ {
"version": "1.6.1", "version": "1.6.1",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.6.1/dxvk-1.6.1.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.6.1/dxvk-1.6.1.tar.gz",
"recommendable": false "recommended": false
}, },
{ {
"version": "1.6", "version": "1.6",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.6/dxvk-1.6.tar.gz", "uri": "https://github.com/doitsujin/dxvk/releases/download/v1.6/dxvk-1.6.tar.gz",
"recommendable": false "recommended": false
} }
] ]

View file

@ -6,6 +6,7 @@ import Downloader from '../ts/Downloader';
import Archive from '../ts/Archive'; import Archive from '../ts/Archive';
import Configs from '../ts/Configs'; import Configs from '../ts/Configs';
import Runners from '../ts/Runners'; import Runners from '../ts/Runners';
import DXVK from '../ts/DXVK';
const app = Vue.createApp({ const app = Vue.createApp({
data: () => ({ data: () => ({
@ -41,16 +42,6 @@ const app = Vue.createApp({
stream.finish(() => console.log('finished')); 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', '123.zip').then((stream) => {
stream.progress((current: number, total: number) => {
document.getElementById('progress').innerHTML = `${Math.round(current / total * 100)}%`;
});
stream.finish(() => {
console.log('finished');
});
});*/
} }
}); });

165
src/ts/AbstractInstaller.ts Normal file
View file

@ -0,0 +1,165 @@
import Constants from './Constants';
import Downloader from './Downloader';
import Archive from './Archive';
export default abstract class Installer
{
/**
* The interval in ms between progress event calls
*/
public downloadProgressInterval: number = 200;
/**
* The interval in ms between progress event calls
*/
public unpackProgressInterval: number = 500;
protected onDownloadStart?: () => void;
protected onUnpackStart?: () => void;
protected onDownloadProgress?: (current: number, total: number, difference: number) => void;
protected onUnpackProgress?: (current: number, total: number, difference: number) => void;
protected onDownloadFinish?: () => void;
protected onUnpackFinish?: () => void;
protected downloadStarted: boolean = false;
protected unpackStarted: boolean = false;
protected downloadFinished: boolean = false;
protected unpackFinished: boolean = false;
public constructor(uri: string, unpackDir: string|Promise<string>)
{
Constants.paths.launcher.then((launcherDir) => {
const archivePath = `${launcherDir}/${Downloader.fileFromUri(uri)}`;
// Download archive
Downloader.download(uri, archivePath).then((stream) => {
stream.progressInterval = this.downloadProgressInterval;
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;
if (this.onUnpackFinish)
this.onUnpackFinish();
});
});
};
if (typeof unpackDir === 'string')
unpackArchive(unpackDir);
else unpackDir.then((unpackDir) => unpackArchive(unpackDir));
});
});
});
}
/**
* Specify event that will be called after downloading will begin
*
* @param callback
*/
public downloadStart(callback: () => void)
{
this.onDownloadStart = callback;
if (this.downloadStarted)
callback();
}
/**
* Specify event that will be called after unpacking will begin
*
* @param callback
*/
public unpackStart(callback: () => void)
{
this.onUnpackStart = callback;
if (this.unpackStarted)
callback();
}
/**
* Specify event that will be called every [this.downloadProgressInterval] ms during downloading
*
* @param callback
*/
public downloadProgress(callback: (current: number, total: number, difference: number) => void)
{
this.onDownloadProgress = callback;
}
/**
* Specify event that will be called every [this.unpackProgressInterval] ms during unpacking
*
* @param callback
*/
public unpackProgress(callback: (current: number, total: number, difference: number) => void)
{
this.onUnpackProgress = callback;
}
/**
* Specify event that will be called after downloading will be finished
*
* @param callback
*/
public downloadFinish(callback: () => void)
{
this.onDownloadFinish = callback;
if (this.downloadFinished)
callback();
}
/**
* Specify event that will be called after unpacking will be finished
*
* @param callback
*/
public unpackFinish(callback: () => void)
{
this.onUnpackFinish = callback;
if (this.unpackFinished)
callback();
}
}

View file

@ -164,7 +164,7 @@ export default class Archive
* Get type of archive * Get type of archive
* *
* @param path path to archive * @param path path to archive
* @returns ArchiveType|null * @returns supported archive type or null
*/ */
public static getType(path: string): ArchiveType|null public static getType(path: string): ArchiveType|null
{ {
@ -181,7 +181,7 @@ export default class Archive
* Get archive info * Get archive info
* *
* @param path path to archive * @param path path to archive
* @returns Promise<ArchiveInfo|null> * @returns null if the archive has unsupported type. Otherwise - archive info
*/ */
public static getInfo(path: string): Promise<ArchiveInfo|null> public static getInfo(path: string): Promise<ArchiveInfo|null>
{ {

View file

@ -1,4 +1,5 @@
import Constants from './Constants'; import Constants from './Constants';
declare const Neutralino; declare const Neutralino;
declare const NL_CWD; declare const NL_CWD;
@ -12,7 +13,7 @@ export default class Configs
* Get config value * Get config value
* *
* @param name config name, e.g. "lang.launcher" * @param name config name, e.g. "lang.launcher"
* @returns Promise<undefined|..> * @returns undefined if config is not exists. Otherwise - config value
*/ */
public static get(name: string = ''): Promise<undefined|scalar|scalar[]> public static get(name: string = ''): Promise<undefined|scalar|scalar[]>
{ {
@ -67,6 +68,7 @@ export default class Configs
* Set default values * Set default values
* *
* @param configs object of default values * @param configs object of default values
* @returns Promise<void> indicates when the default settings was applied
*/ */
public static defaults(configs: scalar): Promise<void> public static defaults(configs: scalar): Promise<void>
{ {

View file

@ -1,30 +1,24 @@
declare const Neutralino; declare const Neutralino;
declare const NL_PATH;
class Paths class Paths
{ {
/** /**
* Directory where the launcher's executable stored * Directory where the launcher's executable stored
*
* @returns string
*/ */
// @ts-expect-error
public static readonly app: string = NL_PATH; public static readonly app: string = NL_PATH;
/** /**
* Shaders directory * Shaders directory
* *
* Default is [constants.paths.app]/public/shaders * @defaultValue "[Constants.paths.app]/public/shaders"
*
* @returns string
*/ */
public static readonly shaders: string = `${this.app}/public/shaders`; public static readonly shaders: string = `${this.app}/public/shaders`;
/** /**
* Launcher data directory * Launcher data directory
* *
* Default is ~/.local/share/anime-game-launcher * @defaultValue "~/.local/share/anime-game-launcher"
*
* @returns Promise<string>
*/ */
public static get launcher(): Promise<string> public static get launcher(): Promise<string>
{ {
@ -34,9 +28,7 @@ class Paths
/** /**
* Runners directory * Runners directory
* *
* Default is ~/.local/share/anime-game-launcher/runners * @defaultValue "~/.local/share/anime-game-launcher/runners"
*
* @returns Promise<string>
*/ */
public static get runners(): Promise<string> public static get runners(): Promise<string>
{ {
@ -46,9 +38,7 @@ class Paths
/** /**
* DXVKs directory * DXVKs directory
* *
* Default is ~/.local/share/anime-game-launcher/dxvks * @defaultValue "~/.local/share/anime-game-launcher/dxvks"
*
* @returns Promise<string>
*/ */
public static get dxvks(): Promise<string> public static get dxvks(): Promise<string>
{ {
@ -58,9 +48,7 @@ class Paths
/** /**
* Config file * Config file
* *
* Default is ~/.local/share/anime-game-launcher/config.json * @defaultValue "~/.local/share/anime-game-launcher/config.json"
*
* @returns Promise<string>
*/ */
public static get config(): Promise<string> public static get config(): Promise<string>
{ {

View file

@ -0,0 +1,78 @@
import type { DXVK as TDXVK } from './types/DXVK';
import Constants from './Constants';
import AbstractInstaller from './AbstractInstaller';
declare const Neutralino;
class Stream extends AbstractInstaller
{
public constructor(dxvk: TDXVK)
{
super(dxvk.uri, Constants.paths.dxvks);
}
}
export default class DXVK
{
/**
* Get DXVKs list
*/
public static get(): Promise<TDXVK[]>
{
return new Promise((resolve) => {
Constants.paths.dxvks.then(async (dxvksDir: string) => {
let list: TDXVK[] = JSON.parse(await Neutralino.filesystem.readFile(`${Constants.paths.app}/public/dxvks.json`));
const installed: { entry: string, type: string }[] = await Neutralino.filesystem.readDirectory(dxvksDir);
let dxvks: TDXVK[] = [];
list.forEach((dxvk) => {
let inst = false;
for (let dir of installed)
inst ||= dir.entry == `dxvk-${dxvk.version}`;
dxvks.push({
...dxvk,
installed: inst
});
});
resolve(dxvks);
});
});
}
/**
* Download DXVK to the [Constants.paths.dxvks] directory
*
* @param dxvk DXVK object or version
* @returns null if the DXVK with specified version is not exists. Otherwise - installation stream
*/
public static download(dxvk: TDXVK|TDXVK['version']): Promise<null|Stream>
{
return new Promise(async (resolve) => {
// If we provided dxvk property as a version of the DXVK
// then we should find this DXVK and call this method from it
if (typeof dxvk == 'string')
{
let foundDXVK = null;
(await this.get()).forEach((currDxvk) => {
if (currDxvk.version == dxvk)
foundDXVK = currDxvk;
});
resolve(foundDXVK === null ? null : new Stream(foundDXVK));
}
// Otherwise we can use dxvk.uri and so on to download DXVK
else resolve(new Stream(dxvk));
});
}
}
export type { TDXVK };

View file

@ -103,7 +103,7 @@ export default class Downloader
* @param uri * @param uri
* @param output * @param output
* *
* @returns Promise<Stream> * @returns downloading stream
*/ */
public static async download(uri: string, output: string|null = null): Promise<Stream> public static async download(uri: string, output: string|null = null): Promise<Stream>
{ {

View file

@ -3,166 +3,16 @@ import {
RunnerFamily RunnerFamily
} from './types/Runners'; } from './types/Runners';
import Constants from './Constants';
import AbstractInstaller from './AbstractInstaller';
declare const Neutralino; declare const Neutralino;
import Constants from './Constants'; class Stream extends AbstractInstaller
import Downloader from './Downloader';
import Archive from './Archive';
class Stream
{ {
/**
* The interval in ms between progress event calls
*/
public downloadProgressInterval: number = 200;
/**
* The interval in ms between progress event calls
*/
public unpackProgressInterval: number = 500;
protected onDownloadStart?: () => void;
protected onUnpackStart?: () => void;
protected onDownloadProgress?: (current: number, total: number, difference: number) => void;
protected onUnpackProgress?: (current: number, total: number, difference: number) => void;
protected onDownloadFinish?: () => void;
protected onUnpackFinish?: () => void;
protected downloadStarted: boolean = false;
protected unpackStarted: boolean = false;
protected downloadFinished: boolean = false;
protected unpackFinished: boolean = false;
public constructor(runner: Runner) public constructor(runner: Runner)
{ {
Constants.paths.launcher.then((launcherDir) => { super(runner.uri, Constants.paths.runners);
const archivePath = `${launcherDir}/${Downloader.fileFromUri(runner.uri)}`;
// Download archive
Downloader.download(runner.uri, archivePath).then((stream) => {
stream.progressInterval = this.downloadProgressInterval;
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
Constants.paths.runners.then((runners) => {
Archive.unpack(archivePath, runners).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;
if (this.onUnpackFinish)
this.onUnpackFinish();
});
});
});
});
});
});
}
/**
* Specify event that will be called after the runner will begin downloading
*
* @param callback
*/
public downloadStart(callback: () => void)
{
this.onDownloadStart = callback;
if (this.downloadStarted)
callback();
}
/**
* Specify event that will be called after the runner will begin unpacking
*
* @param callback
*/
public unpackStart(callback: () => void)
{
this.onUnpackStart = callback;
if (this.unpackStarted)
callback();
}
/**
* Specify event that will be called every [this.downloadProgressInterval] ms during the runner downloading
*
* @param callback
*/
public downloadProgress(callback: (current: number, total: number, difference: number) => void)
{
this.onDownloadProgress = callback;
}
/**
* Specify event that will be called every [this.unpackProgressInterval] ms during the runner unpacking
*
* @param callback
*/
public unpackProgress(callback: (current: number, total: number, difference: number) => void)
{
this.onUnpackProgress = callback;
}
/**
* Specify event that will be called after the runner will be downloaded
*
* @param callback
*/
public downloadFinish(callback: () => void)
{
this.onDownloadFinish = callback;
if (this.downloadFinished)
callback();
}
/**
* Specify event that will be called after the runner will be unpacked
*
* @param callback
*/
public unpackFinish(callback: () => void)
{
this.onUnpackFinish = callback;
if (this.unpackFinished)
callback();
} }
} }
@ -170,8 +20,6 @@ class Runners
{ {
/** /**
* Get runners list * Get runners list
*
* @returns Promise<Runner[]>
*/ */
public static get(): Promise<RunnerFamily[]> public static get(): Promise<RunnerFamily[]>
{ {
@ -213,8 +61,8 @@ class Runners
/** /**
* Download runner to the [Constants.paths.runners] directory * Download runner to the [Constants.paths.runners] directory
* *
* @param runner Runner object or name * @param runner runner object or name
* @returns Promise<null|Stream> * @returns null if the runner with specified name is not exists. Otherwise - installation stream
*/ */
public static download(runner: Runner|Runner['name']): Promise<null|Stream> public static download(runner: Runner|Runner['name']): Promise<null|Stream>
{ {

8
src/ts/types/DXVK.d.ts vendored Normal file
View file

@ -0,0 +1,8 @@
type DXVK = {
version: string;
uri: string;
recommended: boolean;
installed: boolean;
};
export type { DXVK };

View file

@ -2,7 +2,7 @@ type Runner = {
/** /**
* e.g. proton-ge * e.g. proton-ge
*/ */
family: string; family: string;
/** /**
* e.g. Proton-6.20-GE-1 * e.g. Proton-6.20-GE-1