mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-12-24 10:38:14 +03:00
API improvements
- added `Archive.closeStreams()` method to close all the unpacking streams - added `Downloader.closeStreams()` method to close all the downloading streams - added the same methods to the streams itself - fixed launch button events execution - added prefix creation during the game installation/updagin if it is not created - added some hack to the `Process.running()` method to show that the process is not running if it is a zombie
This commit is contained in:
parent
e8c721dc93
commit
68d766da58
8 changed files with 145 additions and 33 deletions
|
@ -27,7 +27,7 @@
|
|||
"maximize": false,
|
||||
"hidden": true,
|
||||
"resizable": false,
|
||||
"exitProcessOnClose": true
|
||||
"exitProcessOnClose": false
|
||||
},
|
||||
"browser": {},
|
||||
"cloud": {}
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
import '../i18n';
|
||||
import App from '../index.svelte';
|
||||
import Archive from '../ts/core/Archive';
|
||||
import Downloader from '../ts/core/Downloader';
|
||||
|
||||
declare const Neutralino;
|
||||
|
||||
Neutralino.init();
|
||||
|
||||
Neutralino.events.on('ready', () => import('../defaultSettings'));
|
||||
|
||||
Neutralino.events.on('windowClose', () => {
|
||||
Downloader.closeStreams(true);
|
||||
Archive.closeStreams(true);
|
||||
|
||||
Neutralino.app.exit();
|
||||
});
|
||||
|
||||
const app = new App({
|
||||
target: document.getElementById('app')!
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ export default class Launcher
|
|||
this.progressBar = new ProgressBar(this);
|
||||
|
||||
// Progress bar test
|
||||
this.progressBar.init({
|
||||
/*this.progressBar.init({
|
||||
label: 'Abobus',
|
||||
showSpeed: true,
|
||||
showEta: true,
|
||||
|
@ -42,7 +42,7 @@ export default class Launcher
|
|||
}
|
||||
};
|
||||
|
||||
t(0);
|
||||
t(0);*/
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,16 @@ declare const NL_CWD;
|
|||
|
||||
class Stream
|
||||
{
|
||||
protected _id: number = -1;
|
||||
|
||||
/**
|
||||
* ID of the archive unpacker process
|
||||
*/
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interval in ms between progress event calls
|
||||
*/
|
||||
|
@ -67,6 +77,8 @@ class Stream
|
|||
|
||||
Neutralino.os.execCommand(command, {
|
||||
background: true
|
||||
}).then((result) => {
|
||||
this._id = result.pid;
|
||||
});
|
||||
|
||||
const updateProgress = async () => {
|
||||
|
@ -156,10 +168,20 @@ class Stream
|
|||
if (this.throwedError)
|
||||
callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close unpacking stream
|
||||
*/
|
||||
public close(forced: boolean = false)
|
||||
{
|
||||
Neutralino.os.execCommand(`kill ${forced ? '-9' : '-15'} ${this._id}`);
|
||||
}
|
||||
}
|
||||
|
||||
export default class Archive
|
||||
{
|
||||
protected static streams: Stream[] = [];
|
||||
|
||||
/**
|
||||
* Get type of archive
|
||||
*
|
||||
|
@ -259,7 +281,23 @@ export default class Archive
|
|||
*/
|
||||
public static unpack(path: string, unpackDir: string|null = null): Promise<Stream>
|
||||
{
|
||||
return new Promise((resolve) => resolve(new Stream(path, unpackDir)));
|
||||
return new Promise((resolve) => {
|
||||
const stream = new Stream(path, unpackDir);
|
||||
|
||||
this.streams.push(stream);
|
||||
|
||||
resolve(stream);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Close every open archive unpacking stream
|
||||
*/
|
||||
public static closeStreams(forced: boolean = false)
|
||||
{
|
||||
this.streams.forEach((stream) => {
|
||||
stream.close(forced);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,16 @@ declare const Neutralino;
|
|||
|
||||
class Stream
|
||||
{
|
||||
protected _id: number = -1;
|
||||
|
||||
/**
|
||||
* ID of the curl process
|
||||
*/
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interval in ms between progress event calls
|
||||
*/
|
||||
|
@ -31,12 +41,14 @@ class Stream
|
|||
|
||||
Neutralino.os.execCommand(`curl -s -L -N -o "${output}" "${uri}"`, {
|
||||
background: true
|
||||
}).then((result) => {
|
||||
this._id = result.pid;
|
||||
});
|
||||
|
||||
const updateProgress = () => {
|
||||
Neutralino.filesystem.getStats(output).then((stats) => {
|
||||
if (this.onProgress)
|
||||
this.onProgress(stats.size, this.total, this.previous - stats.size);
|
||||
this.onProgress(stats.size, this.total, stats.size - this.previous);
|
||||
|
||||
this.previous = stats.size;
|
||||
|
||||
|
@ -94,10 +106,20 @@ class Stream
|
|||
if (this.finished)
|
||||
callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close downloading stream
|
||||
*/
|
||||
public close(forced: boolean = false)
|
||||
{
|
||||
Neutralino.os.execCommand(`kill ${forced ? '-9' : '-15'} ${this._id}`);
|
||||
}
|
||||
}
|
||||
|
||||
export default class Downloader
|
||||
{
|
||||
protected static streams: Stream[] = [];
|
||||
|
||||
/**
|
||||
* Download file
|
||||
*
|
||||
|
@ -110,11 +132,28 @@ export default class Downloader
|
|||
{
|
||||
return new Promise(async (resolve) => {
|
||||
fetch(uri).then((response) => {
|
||||
resolve(new Stream(uri, output ?? this.fileFromUri(uri), response.length!));
|
||||
const stream = new Stream(uri, output ?? this.fileFromUri(uri), response.length!);
|
||||
|
||||
this.streams.push(stream);
|
||||
|
||||
resolve(stream);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Close every open downloading stream
|
||||
*/
|
||||
public static closeStreams(forced: boolean = false)
|
||||
{
|
||||
this.streams.forEach((stream) => {
|
||||
stream.close(forced);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file name from the URI
|
||||
*/
|
||||
public static fileFromUri(uri: string): string
|
||||
{
|
||||
const file = uri.split('/').pop()!.split('#')[0].split('?')[0];
|
||||
|
|
|
@ -8,12 +8,12 @@ export default class State
|
|||
|
||||
public launchButton: HTMLElement;
|
||||
|
||||
protected _state: LauncherState = 'game-launch-available';
|
||||
protected _state: LauncherState = 'game-installation-available';
|
||||
|
||||
protected events = {
|
||||
'game-launch-available': import('./states/Launch'),
|
||||
|
||||
'game-install-available': import('./states/Install'),
|
||||
'game-installation-available': import('./states/Install'),
|
||||
'game-update-available': import('./states/Install')
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@ export default class State
|
|||
|
||||
this.launchButton.onclick = () => {
|
||||
if (this.events[this._state])
|
||||
this.events[this._state].then((event) => event.default());
|
||||
this.events[this._state].then((event) => event.default(this.launcher));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +1,64 @@
|
|||
import type Launcher from '../../Launcher';
|
||||
|
||||
import Game from '../../Game';
|
||||
import constants from '../../Constants';
|
||||
import Runners from '../../core/Runners';
|
||||
|
||||
declare const Neutralino;
|
||||
|
||||
export default (launcher: Launcher): Promise<void> => {
|
||||
return new Promise(async (resolve) => {
|
||||
Game.update(await Game.current).then((stream) => {
|
||||
launcher.progressBar?.init({
|
||||
label: 'Downloading game...',
|
||||
showSpeed: true,
|
||||
showEta: true,
|
||||
showPercents: true,
|
||||
showTotals: true
|
||||
const prefixDir = await constants.paths.prefix.current;
|
||||
|
||||
Neutralino.filesystem.getStats(prefixDir)
|
||||
.then(() => updateGame())
|
||||
.catch(() => {
|
||||
Runners.createPrefix(prefixDir).then((result) => {
|
||||
if (result === true)
|
||||
updateGame();
|
||||
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
console.error('There\'s no wine version installed to use to create the prefix');
|
||||
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
stream?.downloadStart(() => launcher.progressBar?.show());
|
||||
|
||||
stream?.downloadProgress((current: number, total: number, difference: number) => {
|
||||
launcher.progressBar?.update(current, total, difference);
|
||||
});
|
||||
|
||||
stream?.unpackStart(() => {
|
||||
const updateGame = async () => {
|
||||
Game.update(await Game.current).then((stream) => {
|
||||
launcher.progressBar?.init({
|
||||
label: 'Unpacking game...',
|
||||
label: 'Downloading game...',
|
||||
showSpeed: true,
|
||||
showEta: true,
|
||||
showPercents: true,
|
||||
showTotals: true
|
||||
});
|
||||
});
|
||||
|
||||
stream?.unpackProgress((current: number, total: number, difference: number) => {
|
||||
launcher.progressBar?.update(current, total, difference);
|
||||
});
|
||||
stream?.downloadStart(() => launcher.progressBar?.show());
|
||||
|
||||
stream?.unpackFinish(() => resolve());
|
||||
});
|
||||
stream?.downloadProgress((current: number, total: number, difference: number) => {
|
||||
launcher.progressBar?.update(current, total, difference);
|
||||
});
|
||||
|
||||
stream?.unpackStart(() => {
|
||||
launcher.progressBar?.init({
|
||||
label: 'Unpacking game...',
|
||||
showSpeed: true,
|
||||
showEta: true,
|
||||
showPercents: true,
|
||||
showTotals: true
|
||||
});
|
||||
});
|
||||
|
||||
stream?.unpackProgress((current: number, total: number, difference: number) => {
|
||||
launcher.progressBar?.update(current, total, difference);
|
||||
});
|
||||
|
||||
stream?.unpackFinish(() => resolve());
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
|
|
|
@ -106,8 +106,8 @@ class Process
|
|||
public running(): Promise<boolean>
|
||||
{
|
||||
return new Promise((resolve) => {
|
||||
Neutralino.os.execCommand(`ps -p ${this.id}`).then((output) => {
|
||||
resolve(output.stdOut.includes(this.id));
|
||||
Neutralino.os.execCommand(`ps -p ${this.id} -S`).then((output) => {
|
||||
resolve(output.stdOut.includes(this.id) && !output.stdOut.includes('Z '));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue