Merge request !5 implementation and more

- added Lutris 6.21-5 runner
- added `recommendable` field to the runners (for future feature)
- removed PrefixSelector class which functionality now partially moved
  as an anonymous class in the `constants.prefixDir` property
- fixed temp winetricks and winecfg buttons disabling
- made `LauncherLib.getGameVersion` method to gather game version from its files
This commit is contained in:
Observer KRypt0n_ 2021-11-28 21:11:06 +02:00
parent 1cdc553c25
commit b89eccd863
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
8 changed files with 155 additions and 118 deletions

View file

@ -121,14 +121,24 @@ app.whenReady().then(() => {
mainWindow.webContents.send('change-voicepack');
});
ipcMain.on('prefix-con', async () => {
const result = await dialog.showOpenDialog({ properties: ['openDirectory'] });
if(result.filePaths.length == 0) return;
mainWindow.webContents.send('change-prefix', { 'type': 'change', 'dir': result.filePaths[0] });
ipcMain.on('prefix-select', async () => {
const result = await dialog.showOpenDialog({
properties: ['openDirectory']
});
if (result.filePaths.length > 0)
{
mainWindow.webContents.send('change-prefix', {
'type': 'change',
'dir': result.filePaths[0]
});
}
});
ipcMain.on('prefix-reset', async () => {
mainWindow.webContents.send('change-prefix', { 'type': 'reset' });
mainWindow.webContents.send('change-prefix', {
'type': 'reset'
});
});
ipcMain.on('prefix-changed', async () => {

View file

@ -54,6 +54,6 @@
"LauncherUpdateTitle": "Доступно обновление лаунчера: ",
"LauncherUpdateBody": "Вы можете скачать новую версию лаунчера с репозитория проекта: {uri.launcher}",
"TelemetryNotDisabled": "Серверы сбора телеметрии {placeholders.uppercase.company} не отключены!",
"DefPrefix": "Reset to Default",
"ChangePrefix": "Change Prefix"
"DefPrefix": "Сбросить до умолчания",
"ChangePrefix": "Изменить префикс"
}

View file

@ -2,6 +2,16 @@
{
"title": "Lutris",
"runners": [
{
"name": "Lutris 6.21-5",
"version": "6.21-5",
"uri": "https://github.com/lutris/wine/releases/download/lutris-6.21-5/wine-lutris-6.21-5-x86_64.tar.xz",
"archive": "tar",
"folder": "lutris-6.21-5-x86_64",
"makeFolder": false,
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.21-4",
"version": "6.21-4",
@ -9,7 +19,8 @@
"archive": "tar",
"folder": "lutris-6.21-4-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.21-3",
@ -18,7 +29,8 @@
"archive": "tar",
"folder": "lutris-6.21-3-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.21-2",
@ -27,7 +39,8 @@
"archive": "tar",
"folder": "lutris-6.21-2-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.21",
@ -36,7 +49,8 @@
"archive": "tar",
"folder": "lutris-6.21-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.14-4",
@ -45,7 +59,8 @@
"archive": "tar",
"folder": "lutris-6.14-4-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": true
},
{
"name": "Lutris 6.14-3",
@ -54,7 +69,8 @@
"archive": "tar",
"folder": "lutris-6.14-3-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": true
},
{
"name": "Lutris 6.14-2",
@ -63,7 +79,8 @@
"archive": "tar",
"folder": "lutris-6.14-2-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": true
},
{
"name": "Lutris 6.14",
@ -72,7 +89,8 @@
"archive": "tar",
"folder": "lutris-6.14-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": true
},
{
"name": "Lutris 6.13-3",
@ -81,7 +99,8 @@
"archive": "tar",
"folder": "lutris-6.13-3-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.13-2",
@ -90,7 +109,8 @@
"archive": "tar",
"folder": "lutris-6.13-2-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
},
{
"name": "Lutris 6.13",
@ -99,7 +119,8 @@
"archive": "tar",
"folder": "lutris-6.13-x86_64",
"makeFolder": false,
"executable": "bin/wine64"
"executable": "bin/wine64",
"recommendable": false
}
]
},
@ -113,7 +134,8 @@
"archive": "tar",
"folder": "Proton-6.21-GE-2",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.20-GE-1",
@ -122,7 +144,8 @@
"archive": "tar",
"folder": "Proton-6.20-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": true
},
{
"name": "Proton-6.19-GE-2",
@ -131,7 +154,8 @@
"archive": "tar",
"folder": "Proton-6.19-GE-2",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.19-GE-1",
@ -140,7 +164,8 @@
"archive": "tar",
"folder": "Proton-6.19-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.18-GE-2",
@ -149,7 +174,8 @@
"archive": "tar",
"folder": "Proton-6.18-GE-2",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.18-GE-1",
@ -158,7 +184,8 @@
"archive": "tar",
"folder": "Proton-6.18-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.16-GE-1",
@ -167,7 +194,8 @@
"archive": "tar",
"folder": "Proton-6.16-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.15-GE-2",
@ -176,7 +204,8 @@
"archive": "tar",
"folder": "Proton-6.15-GE-2",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.15-GE-1",
@ -185,7 +214,8 @@
"archive": "tar",
"folder": "Proton-6.15-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.14-GE-2",
@ -194,7 +224,8 @@
"archive": "tar",
"folder": "Proton-6.14-GE-2",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-6.14-GE-1",
@ -203,7 +234,8 @@
"archive": "tar",
"folder": "Proton-6.14-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": false
},
{
"name": "Proton-5.21-GE-1",
@ -212,7 +244,8 @@
"archive": "tar",
"folder": "Proton-5.21-GE-1",
"makeFolder": false,
"executable": "files/bin/wine64"
"executable": "files/bin/wine64",
"recommendable": true
}
]
}

View file

@ -13,13 +13,12 @@ import LauncherLib from './lib/LauncherLib';
import LauncherUI from './lib/LauncherUI';
import Tools from './lib/Tools';
import DiscordRPC from './lib/DiscordRPC';
import PrefixSelector from './lib/PrefixSelector';
import SwitcherooControl from './lib/SwitcherooControl';
const launcher_version = require('../../package.json').version;
if (!fs.existsSync(LauncherLib.getConfig('prefix')))
fs.mkdirSync(LauncherLib.getConfig('prefix'), { recursive: true });
if (!fs.existsSync(constants.prefixDir.get()))
fs.mkdirSync(constants.prefixDir.get(), { recursive: true });
if (!fs.existsSync(constants.runnersDir))
fs.mkdirSync(constants.runnersDir, { recursive: true });
@ -61,9 +60,21 @@ $(() => {
});
ipcRenderer.on('change-prefix', (event: void, data: any) => {
if(data.type == 'change') PrefixSelector.set(data.dir);
if(data.type == 'reset') PrefixSelector.Default();
switch (data.type)
{
case 'change':
constants.prefixDir.set(data.dir);
break;
case 'reset':
constants.prefixDir.set(constants.prefixDir.getDefault());
break;
}
LauncherUI.updateLauncherState();
ipcRenderer.send('prefix-changed');
});
@ -149,14 +160,14 @@ $(() => {
}
// Creating wine prefix
if (!LauncherLib.isPrefixInstalled(constants.prefixDir))
if (!LauncherLib.isPrefixInstalled(constants.prefixDir.get()))
{
console.log(`%c> Creating wineprefix...`, 'font-size: 16px');
$('#launch').css('display', 'none');
$('#downloader-panel').css('display', 'block');
await LauncherLib.installPrefix(constants.prefixDir, (output: string, current: number, total: number) => {
await LauncherLib.installPrefix(constants.prefixDir.get(), (output: string, current: number, total: number) => {
output = output.trim();
console.log(output);

View file

@ -227,6 +227,28 @@ export default class LauncherLib
});
}
/**
* @param dataLocation path to the [An Anime Game]_Data folder
*/
public static getGameVersion(dataLocation: string): string|null
{
const persistentPath = path.join(dataLocation, 'Persistent');
const globalGameManagersPath = path.join(dataLocation, 'globalgamemanagers');
if (fs.existsSync(persistentPath))
return fs.readFileSync(path.join(persistentPath, 'ScriptVersion'), { encoding: 'UTF-8' }).toString();
else if (fs.existsSync(globalGameManagersPath))
{
const config = fs.readFileSync(globalGameManagersPath, { encoding: 'ascii' });
const version = /([1-9]+\.[0-9]+\.[0-9]+)_[\d]+_[\d]+/.exec(config);
return version !== null ? version[1] : null;
}
else return null;
}
// WINEPREFIX='...../wineprefix' winetricks corefonts usetakefocus=n
public static async installPrefix (prefixPath: string, progress: (output: string, current: number, total: number) => void): Promise<void>
{

View file

@ -1,71 +0,0 @@
const fs = require('fs');
import LauncherLib from "./LauncherLib";
import constants from "./constants";
const path = require('path');
const os = require('os');
export default class PrefixSelector
{
protected static prefix: string = LauncherLib.getConfig('prefix');
public static set(location: string) {
if (this.prefix == location) return console.log('Can\'t set already selected prefix as new prefix');
if (fs.existsSync(path.join(location, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'Persistent'))) {
const version = fs.readFileSync(path.join(location, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'Persistent', 'ScriptVersion'), { encoding: 'UTF-8' }).toString();
LauncherLib.updateConfig('version', version);
LauncherLib.updateConfig('prefix', location);
constants.prefixDir = location;
this.prefix = location;
} else if (fs.existsSync(path.join(location, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'globalgamemanagers'))) {
const config = fs.readFileSync(path.join(location, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'globalgamemanagers'), { encoding: 'ascii' });
const version = /([1-9]+\.[0-9]+\.[0-9]+)_[\d]+_[\d]+/.exec(config)![1];
LauncherLib.updateConfig('version', version);
LauncherLib.updateConfig('prefix', location);
constants.prefixDir = location;
this.prefix = location;
} else {
console.log('Game not found.');
// Unset version if game is not found.
LauncherLib.updateConfig('version', null);
LauncherLib.updateConfig('prefix', location);
constants.prefixDir = location;
this.prefix = location;
}
}
public static Default() {
const dp = path.join(os.homedir(), '.local', 'share', 'anime-game-launcher', 'game');
if (this.prefix == dp) return console.log('Can\'t set already selected prefix as new prefix');
if (fs.existsSync(path.join(dp, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'Persistent'))) {
const version = fs.readFileSync(path.join(dp, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'Persistent', 'ScriptVersion'), { encoding: 'UTF-8' }).toString();
LauncherLib.updateConfig('version', version);
LauncherLib.updateConfig('prefix', dp);
constants.prefixDir = dp;
this.prefix = dp;
} else if (fs.existsSync(path.join(dp, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'globalgamemanagers'))) {
const config = fs.readFileSync(path.join(dp, 'drive_c', 'Program Files', 'Genshin Impact', 'GenshinImpact_Data', 'globalgamemanagers'), { encoding: 'ascii' });
const version = /([1-9]+\.[0-9]+\.[0-9]+)_[\d]+_[\d]+/.exec(config)![1];
LauncherLib.updateConfig('version', version);
LauncherLib.updateConfig('prefix', dp);
constants.prefixDir = dp;
this.prefix = dp;
} else {
console.log('Game not found.');
// Unset version if game is not found.
LauncherLib.updateConfig('version', null);
LauncherLib.updateConfig('prefix', dp);
constants.prefixDir = dp;
this.prefix = dp;
}
}
}

View file

@ -1,5 +1,7 @@
const path = require('path');
const os = require('os');
const fs = require('fs');
import LauncherLib from "./LauncherLib";
export default class constants
@ -45,10 +47,6 @@ export default class constants
public static readonly launcherDir: string = path.join(os.homedir(), '.local', 'share', 'anime-game-launcher');
public static prefixDir: string = LauncherLib.getConfig('prefix');
public static readonly gameDir: string = path.join(this.prefixDir, 'drive_c', 'Program Files', this.placeholders.uppercase.full);
public static readonly voiceDir: string = path.join(this.gameDir, `${this.placeholders.uppercase.first + this.placeholders.uppercase.second}_Data`, 'StreamingAssets', 'Audio', 'GeneratedSoundBanks', 'Windows');
public static readonly runnersDir: string = path.join(this.launcherDir, 'runners');
public static readonly dxvksDir: string = path.join(this.launcherDir, 'dxvks');
@ -59,4 +57,38 @@ export default class constants
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 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
{
return path.join(this.prefixDir.get(), 'drive_c', 'Program Files', this.placeholders.uppercase.full);
}
public static get voiceDir(): string
{
return path.join(this.gameDir, `${this.placeholders.uppercase.first + this.placeholders.uppercase.second}_Data`, 'StreamingAssets', 'Audio', 'GeneratedSoundBanks', 'Windows');
}
}

View file

@ -62,15 +62,15 @@ $(() => {
ipcRenderer.on('prefix-changed', () => {
$('#prefixloc #currentprefix').text(LauncherLib.getConfig('prefix'));
})
});
$('#prefixloc #prefixdir').on('click', () => {
ipcRenderer.send('prefix-con');
})
ipcRenderer.send('prefix-select');
});
$('#prefixloc #defprefix').on('click', () => {
ipcRenderer.send('prefix-reset');
})
});
/**
* Game voice language
@ -121,7 +121,7 @@ $(() => {
/**
* winetricks button
*/
if (!commandExists('winetricks'))
if (commandExists('winetricks'))
{
$('#general-action-buttons #winetricks').on('click', () => {
exec('winetricks', {
@ -144,7 +144,7 @@ $(() => {
/**
* winecfg button
*/
if (!commandExists('winecfg'))
if (commandExists('winecfg'))
{
$('#general-action-buttons #winecfg').on('click', () => {
exec('winecfg', {