Project library updates

- changed ts files structure
- archives unpacking files downloading functions were moved to Tools class
This commit is contained in:
Observer KRypt0n_ 2021-10-24 09:19:20 +02:00
parent cf45b490d6
commit 6fc0def0b6
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
8 changed files with 161 additions and 182 deletions

View file

@ -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));

View file

@ -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
View 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());
});
});
}
}

View file

@ -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'
)));
}

View file

@ -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) => {

View file

@ -9,6 +9,6 @@
"removeComments": true,
"outDir": "public/js"
},
"include": ["src/ts/*"],
"include": ["src/ts/*", "src/ts/lib/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}