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",
"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",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9.1/dxvk-1.9.1.tar.gz",
"recommendable": true
"recommended": true
},
{
"version": "1.9",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.9/dxvk-1.9.tar.gz",
"recommendable": true
"recommended": true
},
{
"version": "1.8.1",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.8.1/dxvk-1.8.1.tar.gz",
"recommendable": true
"recommended": true
},
{
"version": "1.8",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.8/dxvk-1.8.tar.gz",
"recommendable": true
"recommended": true
},
{
"version": "1.7.3",
"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",
"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",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7.1/dxvk-1.7.1.tar.gz",
"recommendable": false
"recommended": false
},
{
"version": "1.7",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.7/dxvk-1.7.tar.gz",
"recommendable": false
"recommended": false
},
{
"version": "1.6.1",
"uri": "https://github.com/doitsujin/dxvk/releases/download/v1.6.1/dxvk-1.6.1.tar.gz",
"recommendable": false
"recommended": false
},
{
"version": "1.6",
"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 Configs from '../ts/Configs';
import Runners from '../ts/Runners';
import DXVK from '../ts/DXVK';
const app = Vue.createApp({
data: () => ({
@ -41,16 +42,6 @@ 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', '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
*
* @param path path to archive
* @returns ArchiveType|null
* @returns supported archive type or null
*/
public static getType(path: string): ArchiveType|null
{
@ -181,7 +181,7 @@ export default class Archive
* Get archive info
*
* @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>
{

View file

@ -1,4 +1,5 @@
import Constants from './Constants';
declare const Neutralino;
declare const NL_CWD;
@ -12,7 +13,7 @@ export default class Configs
* Get config value
*
* @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[]>
{
@ -67,6 +68,7 @@ export default class Configs
* Set 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>
{

View file

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

View file

@ -3,166 +3,16 @@ import {
RunnerFamily
} from './types/Runners';
import Constants from './Constants';
import AbstractInstaller from './AbstractInstaller';
declare const Neutralino;
import Constants from './Constants';
import Downloader from './Downloader';
import Archive from './Archive';
class Stream
class Stream extends AbstractInstaller
{
/**
* 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)
{
Constants.paths.launcher.then((launcherDir) => {
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();
super(runner.uri, Constants.paths.runners);
}
}
@ -170,8 +20,6 @@ class Runners
{
/**
* Get runners list
*
* @returns Promise<Runner[]>
*/
public static get(): Promise<RunnerFamily[]>
{
@ -213,8 +61,8 @@ class Runners
/**
* Download runner to the [Constants.paths.runners] directory
*
* @param runner Runner object or name
* @returns Promise<null|Stream>
* @param runner runner object or name
* @returns null if the runner with specified name is not exists. Otherwise - installation 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
*/
family: string;
family: string;
/**
* e.g. Proton-6.20-GE-1