mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-12-24 18:48:14 +03:00
Several changes
- updated requirements: added `webkit2gtk` and `curl` - added `Configs` class - updated `Constants` - removed process existing checking from `Downloader.ts`
This commit is contained in:
parent
761268b667
commit
a1d1d9a3ca
8 changed files with 174 additions and 77 deletions
|
@ -48,9 +48,11 @@ To work this launcher requires
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
| webkit2gtk | To run Neutralino apps |
|
||||||
| unzip | To unpack zip archives (DXVKs / wines) |
|
| unzip | To unpack zip archives (DXVKs / wines) |
|
||||||
| tar | To unpack tar archives (DXVKs / wines) |
|
| tar | To unpack tar archives (DXVKs / wines) |
|
||||||
| git | To check for new versions of the launcher |
|
| 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 |
|
| xdelta3 | To apply the patch to the game |
|
||||||
| cabextract | To install fonts to the wine prefix |
|
| cabextract | To install fonts to the wine prefix |
|
||||||
|
|
||||||
|
@ -59,13 +61,13 @@ To work this launcher requires
|
||||||
### apt-get
|
### apt-get
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt-get install unzip tar git xdelta3 cabextract
|
sudo apt-get install webkit2gtk unzip tar git curl xdelta3 cabextract
|
||||||
```
|
```
|
||||||
|
|
||||||
### pacman
|
### pacman
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -Syu unzip tar git xdelta3 cabextract
|
sudo pacman -Syu webkit2gtk unzip tar git curl xdelta3 cabextract
|
||||||
```
|
```
|
||||||
|
|
||||||
# Additional requirements
|
# Additional requirements
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Window from '../ts/neutralino/Window';
|
||||||
|
|
||||||
import Downloader from '../ts/Downloader';
|
import Downloader from '../ts/Downloader';
|
||||||
import Archive from '../ts/Archive';
|
import Archive from '../ts/Archive';
|
||||||
|
import Configs from '../ts/Configs';
|
||||||
|
|
||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
@ -25,7 +26,7 @@ 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').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) => {
|
stream.progress((current: number, total: number) => {
|
||||||
document.getElementById('progress').innerHTML = `${Math.round(current / total * 100)}%`;
|
document.getElementById('progress').innerHTML = `${Math.round(current / total * 100)}%`;
|
||||||
});
|
});
|
||||||
|
|
112
src/ts/Configs.ts
Normal file
112
src/ts/Configs.ts
Normal file
|
@ -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<undefined|..>
|
||||||
|
*/
|
||||||
|
public static get(name: string = ''): Promise<undefined|scalar|scalar[]>
|
||||||
|
{
|
||||||
|
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<void> indicates when the settings was updated
|
||||||
|
*/
|
||||||
|
public static set(name: string, value: scalar|scalar[]): Promise<void>
|
||||||
|
{
|
||||||
|
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<void>
|
||||||
|
{
|
||||||
|
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({}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
class Dirs
|
class Paths
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Directory where the launcher's executable stored
|
* Directory where the launcher's executable stored
|
||||||
|
@ -11,7 +11,7 @@ class Dirs
|
||||||
/**
|
/**
|
||||||
* Shaders directory
|
* Shaders directory
|
||||||
*
|
*
|
||||||
* Default is [constants.dirs.app]/public/shaders
|
* Default is [constants.paths.app]/public/shaders
|
||||||
*
|
*
|
||||||
* @returns string
|
* @returns string
|
||||||
*/
|
*/
|
||||||
|
@ -54,6 +54,18 @@ class Dirs
|
||||||
return new Promise(async (resolve) => resolve(`${await this.launcher}/dxvks`));
|
return new Promise(async (resolve) => resolve(`${await this.launcher}/dxvks`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config file
|
||||||
|
*
|
||||||
|
* Default is ~/.local/share/anime-game-launcher/config.json
|
||||||
|
*
|
||||||
|
* @returns Promise<string>
|
||||||
|
*/
|
||||||
|
public static get config(): Promise<string>
|
||||||
|
{
|
||||||
|
return new Promise(async (resolve) => resolve(`${await this.launcher}/config.json`));
|
||||||
|
}
|
||||||
|
|
||||||
/*public static readonly prefix = new class
|
/*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
|
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 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=`;
|
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 runnersUri: string = `${this.uri.launcher}/raw/main/runners.json`;
|
||||||
public static readonly dxvksUri: string = `${this.uri.launcher}/raw/main/dxvks.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
|
/*public static get gameDir(): string
|
||||||
{
|
{
|
||||||
return path.join(this.prefixDir.get(), 'drive_c', 'Program Files', this.placeholders.uppercase.full);
|
return path.join(this.prefixDir.get(), 'drive_c', 'Program Files', this.placeholders.uppercase.full);
|
||||||
|
|
0
src/ts/DXVK.ts
Normal file
0
src/ts/DXVK.ts
Normal file
|
@ -20,41 +20,35 @@ class Stream
|
||||||
this.total = total;
|
this.total = total;
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
Neutralino.os.execCommand('pidof curl').then((stats) => {
|
Neutralino.os.execCommand(`curl -s -L -N -o "${output}" "${uri}"`, {
|
||||||
if (stats.stdOut == '')
|
background: true
|
||||||
{
|
|
||||||
// @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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type {
|
import type {
|
||||||
Runner,
|
Runner,
|
||||||
RunnersFamily
|
RunnerFamily
|
||||||
} from './types/Runners';
|
} from './types/Runners';
|
||||||
|
|
||||||
import constants from './Constants';
|
import constants from './Constants';
|
||||||
|
@ -15,9 +15,9 @@ class Runners
|
||||||
public static get(): Promise<Runner[]>
|
public static get(): Promise<Runner[]>
|
||||||
{
|
{
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
constants.dirs.runners.then(async (runnersDir: string) => {
|
constants.paths.runners.then(async (runnersDir: string) => {
|
||||||
// @ts-expect-error
|
// @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
|
// @ts-expect-error
|
||||||
const installed: { entry: string, type: string }[] = await Neutralino.filesystem.readDirectory(runnersDir);
|
const installed: { entry: string, type: string }[] = await Neutralino.filesystem.readDirectory(runnersDir);
|
||||||
|
@ -25,7 +25,7 @@ class Runners
|
||||||
let runners = [];
|
let runners = [];
|
||||||
|
|
||||||
list.forEach((family) => {
|
list.forEach((family) => {
|
||||||
let newFamily: RunnersFamily = {
|
let newFamily: RunnerFamily = {
|
||||||
title: family.title,
|
title: family.title,
|
||||||
runners: []
|
runners: []
|
||||||
};
|
};
|
||||||
|
@ -63,5 +63,5 @@ export default Runners;
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
Runner,
|
Runner,
|
||||||
RunnersFamily
|
RunnerFamily
|
||||||
};
|
};
|
||||||
|
|
16
src/ts/types/Runners.d.ts
vendored
16
src/ts/types/Runners.d.ts
vendored
|
@ -1,16 +1,16 @@
|
||||||
type Runner = {
|
type Runner = {
|
||||||
/**
|
/**
|
||||||
* i.e. proton-ge
|
* e.g. proton-ge
|
||||||
*/
|
*/
|
||||||
family: string;
|
family: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i.e. Proton-6.20-GE-1
|
* e.g. Proton-6.20-GE-1
|
||||||
*/
|
*/
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i.e. Proton 6.20 GE 1
|
* e.g. Proton 6.20 GE 1
|
||||||
*/
|
*/
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
@ -18,17 +18,17 @@ type Runner = {
|
||||||
|
|
||||||
files: {
|
files: {
|
||||||
/**
|
/**
|
||||||
* i.e. bin/wine64
|
* e.g. bin/wine64
|
||||||
*/
|
*/
|
||||||
wine: string;
|
wine: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i.e. bin/wineserver
|
* e.g. bin/wineserver
|
||||||
*/
|
*/
|
||||||
wineserver: string;
|
wineserver: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i.e. lib64/wine/x86_64-windows/winecfg.exe
|
* e.g. lib64/wine/x86_64-windows/winecfg.exe
|
||||||
*/
|
*/
|
||||||
winecfg: string;
|
winecfg: string;
|
||||||
};
|
};
|
||||||
|
@ -37,12 +37,12 @@ type Runner = {
|
||||||
installed: boolean;
|
installed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type RunnersFamily = {
|
type RunnerFamily = {
|
||||||
title: string;
|
title: string;
|
||||||
runners: Runner[];
|
runners: Runner[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
Runner,
|
Runner,
|
||||||
RunnersFamily
|
RunnerFamily
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue