mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2025-03-20 07:00:00 +03:00
Project library updates
- changed ts files structure - archives unpacking files downloading functions were moved to Tools class
This commit is contained in:
parent
cf45b490d6
commit
6fc0def0b6
8 changed files with 161 additions and 182 deletions
|
@ -5,10 +5,11 @@ const { exec } = require('child_process');
|
|||
const { ipcRenderer } = require('electron');
|
||||
|
||||
import $ from 'cash-dom';
|
||||
import { i18n } from './i18n';
|
||||
import { i18n } from './lib/i18n';
|
||||
|
||||
import { Genshinlib } from './Genshinlib';
|
||||
import { LauncherUI } from './LauncherUI';
|
||||
import { Genshinlib } from './lib/Genshinlib';
|
||||
import { LauncherUI } from './lib/LauncherUI';
|
||||
import { Tools } from './lib/Tools';
|
||||
|
||||
if (!fs.existsSync(Genshinlib.prefixDir))
|
||||
fs.mkdirSync(Genshinlib.prefixDir, { recursive: true });
|
||||
|
@ -116,14 +117,14 @@ $(() => {
|
|||
console.log(`%c> Downloading voice data...`, 'font-size: 16px');
|
||||
|
||||
// For some reason this keeps breaking and locking up most of the time.
|
||||
Genshinlib.downloadFile(voicePack.path, path.join(Genshinlib.launcherDir, voicePack.name), (current: number, total: number, difference: number) => {
|
||||
Tools.downloadFile(voicePack.path, path.join(Genshinlib.launcherDir, voicePack.name), (current: number, total: number, difference: number) => {
|
||||
LauncherUI.updateProgressBar(i18n.translate('Downloading'), current, total, difference);
|
||||
}).then(() => {
|
||||
console.log(`%c> Unpacking voice data...`, 'font-size: 16px');
|
||||
|
||||
LauncherUI.initProgressBar();
|
||||
|
||||
Genshinlib.unzip(path.join(Genshinlib.launcherDir, voicePack.name), Genshinlib.gameDir, (current: number, total: number, difference: number) => {
|
||||
Tools.unzip(path.join(Genshinlib.launcherDir, voicePack.name), Genshinlib.gameDir, (current: number, total: number, difference: number) => {
|
||||
LauncherUI.updateProgressBar(i18n.translate('Unpack'), current, total, difference);
|
||||
}).then(() => {
|
||||
fs.unlinkSync(path.join(Genshinlib.launcherDir, voicePack.name));
|
||||
|
@ -325,7 +326,7 @@ $(() => {
|
|||
|
||||
LauncherUI.initProgressBar();
|
||||
|
||||
Genshinlib.downloadFile(diff.path, path.join(Genshinlib.launcherDir, diff.name), (current: number, total: number, difference: number) => {
|
||||
Tools.downloadFile(diff.path, path.join(Genshinlib.launcherDir, diff.name), (current: number, total: number, difference: number) => {
|
||||
LauncherUI.updateProgressBar(i18n.translate('Downloading'), current, total, difference);
|
||||
}).then(() => {
|
||||
/**
|
||||
|
@ -339,7 +340,7 @@ $(() => {
|
|||
|
||||
LauncherUI.initProgressBar();
|
||||
|
||||
Genshinlib.unzip(path.join(Genshinlib.launcherDir, diff.name), Genshinlib.gameDir, (current: number, total: number, difference: number) => {
|
||||
Tools.unzip(path.join(Genshinlib.launcherDir, diff.name), Genshinlib.gameDir, (current: number, total: number, difference: number) => {
|
||||
LauncherUI.updateProgressBar(i18n.translate('Unpack'), current, total, difference);
|
||||
}).then(() => {
|
||||
/**
|
||||
|
@ -362,7 +363,7 @@ $(() => {
|
|||
|
||||
LauncherUI.initProgressBar();
|
||||
|
||||
Genshinlib.downloadFile(voicePack.path, path.join(Genshinlib.launcherDir, voicePack.name), (current: number, total: number, difference: number) => {
|
||||
Tools.downloadFile(voicePack.path, path.join(Genshinlib.launcherDir, voicePack.name), (current: number, total: number, difference: number) => {
|
||||
LauncherUI.updateProgressBar(i18n.translate('Downloading'), current, total, difference);
|
||||
}).then(() => {
|
||||
/**
|
||||
|
@ -373,7 +374,7 @@ $(() => {
|
|||
|
||||
LauncherUI.initProgressBar();
|
||||
|
||||
Genshinlib.unzip(path.join(Genshinlib.launcherDir, voicePack.name), Genshinlib.gameDir, (current: number, total: number, difference: number) => {
|
||||
Tools.unzip(path.join(Genshinlib.launcherDir, voicePack.name), Genshinlib.gameDir, (current: number, total: number, difference: number) => {
|
||||
LauncherUI.updateProgressBar(i18n.translate('Unpack'), current, total, difference);
|
||||
}).then(() => {
|
||||
fs.unlinkSync(path.join(Genshinlib.launcherDir, voicePack.name));
|
||||
|
|
0
src/ts/GIJSON.d.ts → src/ts/lib/GIJSON.d.ts
vendored
0
src/ts/GIJSON.d.ts → src/ts/lib/GIJSON.d.ts
vendored
|
@ -1,4 +1,5 @@
|
|||
import GIJSON from './GIJSON';
|
||||
import { Tools } from './Tools';
|
||||
|
||||
const https = require('follow-redirects').https;
|
||||
|
||||
|
@ -48,7 +49,7 @@ type Config = {
|
|||
|
||||
export class Genshinlib
|
||||
{
|
||||
public static readonly patchDir: string = path.join(path.dirname(__dirname), 'patch');
|
||||
public static readonly patchDir: string = path.join(path.dirname(__dirname), '..', 'patch');
|
||||
public static readonly patchJson: string = path.join(this.patchDir, 'patch.json');
|
||||
public static readonly patchSh = path.join(this.patchDir, 'patch.sh');
|
||||
public static readonly patchAntiCrashSh = path.join(this.patchDir, 'patch_anti_logincrash.sh');
|
||||
|
@ -177,7 +178,7 @@ export class Genshinlib
|
|||
|
||||
else
|
||||
{
|
||||
await this.downloadFile(resdone.data.adv.background, path.join(this.launcherDir, this.getConfig().background.file), (current: number, total: number, difference: number) => null).then(() => {
|
||||
await Tools.downloadFile(resdone.data.adv.background, path.join(this.launcherDir, this.getConfig().background.file), (current: number, total: number, difference: number) => null).then(() => {
|
||||
!prevBackground ?
|
||||
console.log('No old background found') :
|
||||
fs.unlinkSync(path.join(this.launcherDir, prevBackground));
|
||||
|
@ -228,131 +229,6 @@ export class Genshinlib
|
|||
});
|
||||
}
|
||||
|
||||
public static async downloadFile (uri: string, savePath: string, progress: (current: number, total: number, difference: number) => void): Promise<void|Error>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get(uri, (response: any) => {
|
||||
let length = parseInt(response.headers['content-length'], 10),
|
||||
total = 0;
|
||||
|
||||
response.on('data', (chunk: any) => {
|
||||
total += chunk.length;
|
||||
|
||||
progress(total, length, chunk.length);
|
||||
|
||||
fs.appendFileSync(savePath, chunk);
|
||||
});
|
||||
|
||||
response.on('end', () => resolve());
|
||||
}).on('error', (err: Error) => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
public static async unzip (zipPath: string, unpackedPath: string, progress: (current: number, total: number, difference: number) => void): Promise<void|Error>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
let listenerProcess = spawn('unzip', ['-v', zipPath]),
|
||||
filesList = '';
|
||||
|
||||
listenerProcess.stdout.on('data', (data: string) => filesList += data);
|
||||
|
||||
listenerProcess.on('close', () => {
|
||||
let files = filesList.split(/\r\n|\r|\n/).slice(3, -3).map(line => {
|
||||
line = line.trim();
|
||||
|
||||
if (line.slice(-1) == '/')
|
||||
line = line.slice(0, -1);
|
||||
|
||||
let matches = /^(\d+) [a-zA-Z\:]+[ ]+(\d+)[ ]+[0-9\-]+% [0-9\-]+ [0-9\:]+ [a-f0-9]{8} (.+)/.exec(line);
|
||||
|
||||
if (matches)
|
||||
return {
|
||||
path: matches[3],
|
||||
compressedSize: parseInt(matches[2]),
|
||||
uncompressedSize: parseInt(matches[1])
|
||||
};
|
||||
});
|
||||
|
||||
let total = fs.statSync(zipPath)['size'], current = 0;
|
||||
let unpackerProcess = spawn('unzip', ['-o', zipPath, '-d', unpackedPath]);
|
||||
|
||||
unpackerProcess.stdout.on('data', (data: string) => {
|
||||
data.toString().split(/\r\n|\r|\n/).forEach(line => {
|
||||
let items = line.split(': ');
|
||||
|
||||
if (items[1] !== undefined)
|
||||
{
|
||||
items[1] = path.relative(unpackedPath, items[1].trim());
|
||||
|
||||
files.forEach(file => {
|
||||
if (file?.path == items[1])
|
||||
{
|
||||
current += file.compressedSize;
|
||||
|
||||
progress(current, total, file.compressedSize);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
unpackerProcess.on('close', () => resolve());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static async untar (tarPath: string, unpackedPath: string, progress: (current: number, total: number, difference: number) => void): Promise<void|Error>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
let listenerProcess = spawn('tar', ['-tvf', tarPath]),
|
||||
filesList = '', total = 0;
|
||||
|
||||
listenerProcess.stdout.on('data', (data: string) => filesList += data);
|
||||
|
||||
listenerProcess.on('close', () => {
|
||||
let files = filesList.split(/\r\n|\r|\n/).slice(3, -3).map(line => {
|
||||
line = line.trim();
|
||||
|
||||
if (line.slice(-1) == '/')
|
||||
line = line.slice(0, -1);
|
||||
|
||||
let matches = /^[dwxr\-]+ [\w/]+[ ]+(\d+) [0-9\-]+ [0-9\:]+ (.+)/.exec(line);
|
||||
|
||||
// TODO: compressedSize?
|
||||
if (matches)
|
||||
{
|
||||
total += parseInt(matches[1]);
|
||||
|
||||
return {
|
||||
path: matches[2],
|
||||
uncompressedSize: parseInt(matches[1])
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
let current = 0;
|
||||
let unpackerProcess = spawn('tar', ['-xvf', tarPath, '-C', unpackedPath]);
|
||||
|
||||
unpackerProcess.stdout.on('data', (data: string) => {
|
||||
data.toString().split(/\r\n|\r|\n/).forEach(line => {
|
||||
line = line.trim();
|
||||
|
||||
files.forEach(file => {
|
||||
if (file?.path == line)
|
||||
{
|
||||
current += file.uncompressedSize; // compressedSize
|
||||
|
||||
progress(current, total, file.uncompressedSize); // compressedSize
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
unpackerProcess.on('close', () => resolve());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// WINEPREFIX='/home/observer/genshin-impact-launcher/wineprefix' winetricks corefonts usetakefocus=n
|
||||
public static async installPrefix (prefixpath: string, progress: (output: string, current: number, total: number) => void): Promise<void>
|
||||
{
|
||||
|
@ -421,8 +297,8 @@ export class Genshinlib
|
|||
|
||||
public static patchGame (version: string, onFinish: () => void, onData: (data: string) => void)
|
||||
{
|
||||
this.downloadFile(this.patchUri, path.join(this.launcherDir, 'krock.zip'), (current: number, total: number, difference: number) => null).then(() => {
|
||||
this.unzip(path.join(this.launcherDir, 'krock.zip'), this.launcherDir, (current: number, total: number, difference: number) => null).then(() => {
|
||||
Tools.downloadFile(this.patchUri, path.join(this.launcherDir, 'krock.zip'), (current: number, total: number, difference: number) => null).then(() => {
|
||||
Tools.unzip(path.join(this.launcherDir, 'krock.zip'), this.launcherDir, (current: number, total: number, difference: number) => null).then(() => {
|
||||
// Delete zip file and assign patch directory.
|
||||
fs.unlinkSync(path.join(this.launcherDir, 'krock.zip'));
|
||||
|
||||
|
@ -476,38 +352,4 @@ export class Genshinlib
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*public static applyPatch (onFinish: () => void, onData: (data: string) => void)
|
||||
{
|
||||
let patcherProcess = spawn('bash', [Genshinlib.patchSh], {
|
||||
cwd: Genshinlib.gameDir,
|
||||
env: {
|
||||
...process.env,
|
||||
WINEPREFIX: Genshinlib.prefixDir
|
||||
}
|
||||
});
|
||||
|
||||
patcherProcess.stdout.on('data', (data: string) => onData(data));
|
||||
|
||||
patcherProcess.on('close', () => {
|
||||
let patcherAntiCrashProcess = spawn('bash', [Genshinlib.patchAntiCrashSh], {
|
||||
cwd: Genshinlib.gameDir,
|
||||
env: {
|
||||
...process.env,
|
||||
WINEPREFIX: Genshinlib.prefixDir
|
||||
}
|
||||
});
|
||||
|
||||
patcherAntiCrashProcess.stdout.on('data', (data: string) => onData(data));
|
||||
|
||||
patcherAntiCrashProcess.on('close', () => {
|
||||
Genshinlib.setConfig({
|
||||
...Genshinlib.getConfig(),
|
||||
patch: Genshinlib.getPatchInfo()
|
||||
});
|
||||
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}*/
|
||||
}
|
133
src/ts/lib/Tools.ts
Normal file
133
src/ts/lib/Tools.ts
Normal file
|
@ -0,0 +1,133 @@
|
|||
const https = require('follow-redirects').https;
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
export class Tools
|
||||
{
|
||||
public static async downloadFile (uri: string, savePath: string, progress: (current: number, total: number, difference: number) => void): Promise<void|Error>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get(uri, (response: any) => {
|
||||
let length = parseInt(response.headers['content-length'], 10),
|
||||
total = 0;
|
||||
|
||||
response.on('data', (chunk: any) => {
|
||||
total += chunk.length;
|
||||
|
||||
progress(total, length, chunk.length);
|
||||
|
||||
fs.appendFileSync(savePath, chunk);
|
||||
});
|
||||
|
||||
response.on('end', () => resolve());
|
||||
}).on('error', (err: Error) => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
public static async unzip (zipPath: string, unpackedPath: string, progress: (current: number, total: number, difference: number) => void): Promise<void|Error>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
let listenerProcess = spawn('unzip', ['-v', zipPath]),
|
||||
filesList = '';
|
||||
|
||||
listenerProcess.stdout.on('data', (data: string) => filesList += data);
|
||||
|
||||
listenerProcess.on('close', () => {
|
||||
let files = filesList.split(/\r\n|\r|\n/).slice(3, -3).map(line => {
|
||||
line = line.trim();
|
||||
|
||||
if (line.slice(-1) == '/')
|
||||
line = line.slice(0, -1);
|
||||
|
||||
let matches = /^(\d+) [a-zA-Z\:]+[ ]+(\d+)[ ]+[0-9\-]+% [0-9\-]+ [0-9\:]+ [a-f0-9]{8} (.+)/.exec(line);
|
||||
|
||||
if (matches)
|
||||
return {
|
||||
path: matches[3],
|
||||
compressedSize: parseInt(matches[2]),
|
||||
uncompressedSize: parseInt(matches[1])
|
||||
};
|
||||
});
|
||||
|
||||
let total = fs.statSync(zipPath)['size'], current = 0;
|
||||
let unpackerProcess = spawn('unzip', ['-o', zipPath, '-d', unpackedPath]);
|
||||
|
||||
unpackerProcess.stdout.on('data', (data: string) => {
|
||||
data.toString().split(/\r\n|\r|\n/).forEach(line => {
|
||||
let items = line.split(': ');
|
||||
|
||||
if (items[1] !== undefined)
|
||||
{
|
||||
items[1] = path.relative(unpackedPath, items[1].trim());
|
||||
|
||||
files.forEach(file => {
|
||||
if (file?.path == items[1])
|
||||
{
|
||||
current += file.compressedSize;
|
||||
|
||||
progress(current, total, file.compressedSize);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
unpackerProcess.on('close', () => resolve());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static async untar (tarPath: string, unpackedPath: string, progress: (current: number, total: number, difference: number) => void): Promise<void|Error>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
let listenerProcess = spawn('tar', ['-tvf', tarPath]),
|
||||
filesList = '', total = 0;
|
||||
|
||||
listenerProcess.stdout.on('data', (data: string) => filesList += data);
|
||||
|
||||
listenerProcess.on('close', () => {
|
||||
let files = filesList.split(/\r\n|\r|\n/).slice(3, -3).map(line => {
|
||||
line = line.trim();
|
||||
|
||||
if (line.slice(-1) == '/')
|
||||
line = line.slice(0, -1);
|
||||
|
||||
let matches = /^[dwxr\-]+ [\w/]+[ ]+(\d+) [0-9\-]+ [0-9\:]+ (.+)/.exec(line);
|
||||
|
||||
// TODO: compressedSize?
|
||||
if (matches)
|
||||
{
|
||||
total += parseInt(matches[1]);
|
||||
|
||||
return {
|
||||
path: matches[2],
|
||||
uncompressedSize: parseInt(matches[1])
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
let current = 0;
|
||||
let unpackerProcess = spawn('tar', ['-xvf', tarPath, '-C', unpackedPath]);
|
||||
|
||||
unpackerProcess.stdout.on('data', (data: string) => {
|
||||
data.toString().split(/\r\n|\r|\n/).forEach(line => {
|
||||
line = line.trim();
|
||||
|
||||
files.forEach(file => {
|
||||
if (file?.path == line)
|
||||
{
|
||||
current += file.uncompressedSize; // compressedSize
|
||||
|
||||
progress(current, total, file.uncompressedSize); // compressedSize
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
unpackerProcess.on('close', () => resolve());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@ const fs = require('fs');
|
|||
|
||||
export class i18n
|
||||
{
|
||||
public static readonly localesDir = path.join(path.dirname(__dirname), '..', 'locales');
|
||||
|
||||
public static loadedLanguage: any;
|
||||
|
||||
public static translate (phrase: string)
|
||||
|
@ -36,8 +38,8 @@ export class i18n
|
|||
break;
|
||||
}
|
||||
|
||||
i18n.loadedLanguage = JSON.parse(fs.readFileSync(path.join(path.dirname(__dirname), 'locales',
|
||||
fs.existsSync(path.join(path.dirname(__dirname), 'locales', lang + '.json')) ?
|
||||
i18n.loadedLanguage = JSON.parse(fs.readFileSync(path.join(this.localesDir,
|
||||
fs.existsSync(path.join(this.localesDir, lang + '.json')) ?
|
||||
lang + '.json' : 'en.json'
|
||||
)));
|
||||
}
|
|
@ -4,9 +4,10 @@ const { ipcRenderer } = require('electron');
|
|||
const { exec } = require('child_process');
|
||||
|
||||
import $ from 'cash-dom';
|
||||
import { i18n } from './i18n';
|
||||
import { Genshinlib } from './Genshinlib';
|
||||
import { LauncherUI } from './LauncherUI';
|
||||
import { i18n } from './lib/i18n';
|
||||
import { Genshinlib } from './lib/Genshinlib';
|
||||
import { LauncherUI } from './lib/LauncherUI';
|
||||
import { Tools } from './lib/Tools';
|
||||
|
||||
$(() => {
|
||||
|
||||
|
@ -117,11 +118,11 @@ $(() => {
|
|||
|
||||
let div = item.find('div');
|
||||
|
||||
Genshinlib.downloadFile(runner.uri, path.join(Genshinlib.launcherDir, runner.name), (current: number, total: number, difference: number) => {
|
||||
Tools.downloadFile(runner.uri, path.join(Genshinlib.launcherDir, runner.name), (current: number, total: number, difference: number) => {
|
||||
div.text(`${ Math.round(current / total * 100) }%`);
|
||||
}).then(() => {
|
||||
let unpacker = runner.archive === 'tar' ?
|
||||
Genshinlib.untar : Genshinlib.unzip;
|
||||
Tools.untar : Tools.unzip;
|
||||
|
||||
unpacker(
|
||||
path.join(Genshinlib.launcherDir, runner.name),
|
||||
|
@ -188,10 +189,10 @@ $(() => {
|
|||
|
||||
let div = item.find('div');
|
||||
|
||||
Genshinlib.downloadFile(dxvk.uri, path.join(Genshinlib.launcherDir, 'dxvk-' + dxvk.version), (current: number, total: number, difference: number) => {
|
||||
Tools.downloadFile(dxvk.uri, path.join(Genshinlib.launcherDir, 'dxvk-' + dxvk.version), (current: number, total: number, difference: number) => {
|
||||
div.text(`${ Math.round(current / total * 100) }%`);
|
||||
}).then(() => {
|
||||
Genshinlib.untar(
|
||||
Tools.untar(
|
||||
path.join(Genshinlib.launcherDir, 'dxvk-' + dxvk.version),
|
||||
Genshinlib.dxvksDir,
|
||||
(current: number, total: number, difference: number) => {
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"removeComments": true,
|
||||
"outDir": "public/js"
|
||||
},
|
||||
"include": ["src/ts/*"],
|
||||
"include": ["src/ts/*", "src/ts/lib/*"],
|
||||
"exclude": ["node_modules", "**/*.spec.ts"]
|
||||
}
|
Loading…
Add table
Reference in a new issue