mirror of
https://github.com/Gabi-Zar/Silk-Fly-Launcher.git
synced 2026-04-17 05:26:04 +02:00
Add the possibility to launch to game with or without bepinex and the ability to backup bepinex and restore this backup
This commit is contained in:
133
main.js
133
main.js
@@ -9,7 +9,18 @@ const extract = require("extract-zip");
|
|||||||
const store = new Store();
|
const store = new Store();
|
||||||
const userSavePath = app.getPath('userData')
|
const userSavePath = app.getPath('userData')
|
||||||
let silksongPath = store.get('silksong-path')
|
let silksongPath = store.get('silksong-path')
|
||||||
|
|
||||||
|
let bepinexFolderPath = `${silksongPath}/BepInEx`
|
||||||
|
let bepinexBackupPath = `${silksongPath}/BepInEx-Backup`
|
||||||
|
const bepinexFiles = [
|
||||||
|
".doorstop_version",
|
||||||
|
"changelog.txt",
|
||||||
|
"doorstop_config.ini",
|
||||||
|
"winhttp.dll"
|
||||||
|
]
|
||||||
|
|
||||||
let bepinexVersion
|
let bepinexVersion
|
||||||
|
let bepinexBackupVersion
|
||||||
|
|
||||||
const createWindow = () => {
|
const createWindow = () => {
|
||||||
const win = new BrowserWindow({
|
const win = new BrowserWindow({
|
||||||
@@ -41,6 +52,8 @@ app.on('window-all-closed', () => {
|
|||||||
|
|
||||||
ipcMain.handle('save-path', (event, path) => {
|
ipcMain.handle('save-path', (event, path) => {
|
||||||
silksongPath = path;
|
silksongPath = path;
|
||||||
|
bepinexFolderPath = `${silksongPath}/BepInEx`
|
||||||
|
bepinexBackupPath = `${silksongPath}/BepInEx-Backup`
|
||||||
store.set('silksong-path', silksongPath);
|
store.set('silksong-path', silksongPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -61,11 +74,25 @@ function saveBepinexVersion(version) {
|
|||||||
store.set('bepinex-version', version);
|
store.set('bepinex-version', version);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function saveBepinexBackupVersion(version) {
|
||||||
|
bepinexBackupVersion = version;
|
||||||
|
if (bepinexBackupVersion == undefined) {
|
||||||
|
store.delete('bepinex-backup-version');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store.set('bepinex-backup-version', version);
|
||||||
|
};
|
||||||
|
|
||||||
ipcMain.handle('load-bepinex-version', () => {
|
ipcMain.handle('load-bepinex-version', () => {
|
||||||
bepinexVersion = store.get('bepinex-version');
|
bepinexVersion = store.get('bepinex-version');
|
||||||
return bepinexVersion;
|
return bepinexVersion;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('load-bepinex-backup-version', () => {
|
||||||
|
bepinexBackupVersion = store.get('bepinex-backup-version');
|
||||||
|
return bepinexBackupVersion;
|
||||||
|
});
|
||||||
|
|
||||||
async function fileExists(filePath) {
|
async function fileExists(filePath) {
|
||||||
try {
|
try {
|
||||||
await fs.access(filePath);
|
await fs.access(filePath);
|
||||||
@@ -124,7 +151,47 @@ ipcMain.handle('open-link', async (event, link) => {
|
|||||||
await shell.openExternal(link)
|
await shell.openExternal(link)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('install-bepinex', async () => {
|
ipcMain.handle('launch-game', async (event, mode) => {
|
||||||
|
const silksongExecutablePath = `${silksongPath}/Hollow Knight Silksong.exe`
|
||||||
|
if (mode === "modded"){
|
||||||
|
if (await fileExists(bepinexFolderPath)) {
|
||||||
|
await shell.openExternal(silksongExecutablePath)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await installBepinex()
|
||||||
|
await shell.openExternal(silksongExecutablePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode === "vanilla"){
|
||||||
|
if (await fileExists(bepinexFolderPath)) {
|
||||||
|
await backupBepinex()
|
||||||
|
await shell.openExternal(silksongExecutablePath)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await shell.openExternal(silksongExecutablePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function installBepinex() {
|
||||||
|
if (await fileExists(bepinexBackupPath)) {
|
||||||
|
if (await fileExists(`${bepinexBackupPath}/BepInEx`)) {
|
||||||
|
await fs.cp(`${bepinexBackupPath}/BepInEx`, bepinexFolderPath, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of bepinexFiles) {
|
||||||
|
const filePath = `${silksongPath}/${file}`
|
||||||
|
if (await fileExists(`${bepinexBackupPath}/${file}`)) {
|
||||||
|
await fs.copyFile(`${bepinexBackupPath}/${file}`, filePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await fs.rm(bepinexBackupPath, { recursive: true })
|
||||||
|
|
||||||
|
bepinexBackupVersion = store.get('bepinex-backup-version')
|
||||||
|
saveBepinexVersion(bepinexBackupVersion)
|
||||||
|
saveBepinexBackupVersion(undefined)
|
||||||
|
}
|
||||||
|
else {
|
||||||
const GITHUB_URL = "https://api.github.com/repos/bepinex/bepinex/releases/latest"
|
const GITHUB_URL = "https://api.github.com/repos/bepinex/bepinex/releases/latest"
|
||||||
|
|
||||||
const res = await fetch(GITHUB_URL, {
|
const res = await fetch(GITHUB_URL, {
|
||||||
@@ -139,7 +206,6 @@ ipcMain.handle('install-bepinex', async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const release = await res.json();
|
const release = await res.json();
|
||||||
bepinexVersion = release.tag_name;
|
|
||||||
|
|
||||||
const asset = release.assets.find(
|
const asset = release.assets.find(
|
||||||
a => a.name.endsWith(".zip") && a.name.toLowerCase().includes("win_x64")
|
a => a.name.endsWith(".zip") && a.name.toLowerCase().includes("win_x64")
|
||||||
@@ -159,28 +225,59 @@ ipcMain.handle('install-bepinex', async () => {
|
|||||||
await extract(filePath, { dir: silksongPath})
|
await extract(filePath, { dir: silksongPath})
|
||||||
await fs.unlink(filePath)
|
await fs.unlink(filePath)
|
||||||
|
|
||||||
saveBepinexVersion(bepinexVersion)
|
saveBepinexVersion(release.tag_name)
|
||||||
})
|
}
|
||||||
|
|
||||||
ipcMain.handle('uninstall-bepinex', async () => {
|
|
||||||
const folderPath = `${silksongPath}\\BepInEx`
|
|
||||||
if (await fileExists(folderPath)) {
|
|
||||||
await fs.rm(folderPath, { recursive: true })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bepinexFiles = [
|
ipcMain.handle('install-bepinex', async () => {
|
||||||
".doorstop_version",
|
await installBepinex()
|
||||||
"changelog.txt",
|
})
|
||||||
"doorstop_config.ini",
|
|
||||||
"winhttp.dll"
|
async function uninstallBepinex() {
|
||||||
]
|
if (await fileExists(bepinexFolderPath)) {
|
||||||
|
await fs.rm(bepinexFolderPath, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
for (const file of bepinexFiles) {
|
for (const file of bepinexFiles) {
|
||||||
const filePath = `${silksongPath}\\${file}`
|
const filePath = `${silksongPath}/${file}`
|
||||||
if (await fileExists(filePath)) {
|
if (await fileExists(filePath)) {
|
||||||
await fs.unlink(filePath)
|
await fs.unlink(filePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bepinexVersion = undefined
|
saveBepinexVersion(undefined)
|
||||||
saveBepinexVersion(bepinexVersion)
|
}
|
||||||
|
|
||||||
|
ipcMain.handle('uninstall-bepinex', async () => {
|
||||||
|
await uninstallBepinex()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function backupBepinex() {
|
||||||
|
if (await fileExists(bepinexBackupPath) == false) {
|
||||||
|
await fs.mkdir(bepinexBackupPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await fileExists(bepinexFolderPath)) {
|
||||||
|
await fs.cp(bepinexFolderPath, `${bepinexBackupPath}/BepInEx`, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of bepinexFiles) {
|
||||||
|
const filePath = `${silksongPath}/${file}`
|
||||||
|
if (await fileExists(filePath)) {
|
||||||
|
await fs.copyFile(filePath, `${bepinexBackupPath}/${file}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveBepinexBackupVersion(bepinexVersion)
|
||||||
|
await uninstallBepinex()
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcMain.handle('backup-bepinex', async () => {
|
||||||
|
await backupBepinex()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('delete-bepinex-backup', async () => {
|
||||||
|
if (await fileExists(bepinexBackupPath)) {
|
||||||
|
await fs.rm(bepinexBackupPath, { recursive: true })
|
||||||
|
saveBepinexBackupVersion(undefined)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
10
preload.js
10
preload.js
@@ -16,14 +16,18 @@ contextBridge.exposeInMainWorld('files', {
|
|||||||
saveSilksongPath: (path) => ipcRenderer.invoke('save-path', path),
|
saveSilksongPath: (path) => ipcRenderer.invoke('save-path', path),
|
||||||
loadSilksongPath: () => ipcRenderer.invoke('load-path'),
|
loadSilksongPath: () => ipcRenderer.invoke('load-path'),
|
||||||
saveBepinexVersion: (version) => ipcRenderer.invoke('save-bepinex-version', version),
|
saveBepinexVersion: (version) => ipcRenderer.invoke('save-bepinex-version', version),
|
||||||
loadBepinexVersion: () => ipcRenderer.invoke('load-bepinex-version')
|
loadBepinexVersion: () => ipcRenderer.invoke('load-bepinex-version'),
|
||||||
|
loadBepinexBackupVersion: () => ipcRenderer.invoke('load-bepinex-backup-version')
|
||||||
});
|
});
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('electronAPI', {
|
contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
openExternalLink: (url) => ipcRenderer.invoke('open-link', url)
|
openExternalLink: (url) => ipcRenderer.invoke('open-link', url),
|
||||||
|
launchGame: (mode) => ipcRenderer.invoke('launch-game', mode)
|
||||||
});
|
});
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('bepinex', {
|
contextBridge.exposeInMainWorld('bepinex', {
|
||||||
install: () => ipcRenderer.invoke('install-bepinex'),
|
install: () => ipcRenderer.invoke('install-bepinex'),
|
||||||
uninstall: () => ipcRenderer.invoke('uninstall-bepinex')
|
uninstall: () => ipcRenderer.invoke('uninstall-bepinex'),
|
||||||
|
backup: () => ipcRenderer.invoke('backup-bepinex'),
|
||||||
|
deleteBackup: () => ipcRenderer.invoke('delete-bepinex-backup')
|
||||||
})
|
})
|
||||||
@@ -108,6 +108,8 @@
|
|||||||
<div class="horizontal-div">
|
<div class="horizontal-div">
|
||||||
<button class="default-button" onclick="installBepinex()">Install</button>
|
<button class="default-button" onclick="installBepinex()">Install</button>
|
||||||
<button class="important-button" onclick="uninstallBepinex()">Uninstall</button>
|
<button class="important-button" onclick="uninstallBepinex()">Uninstall</button>
|
||||||
|
<button class="default-button" onclick="backupBepinex()">Backup</button>
|
||||||
|
<button class="important-button" onclick="deleteBepinexBackup()">Delete Backup</button>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<h2>Import/Export</h2>
|
<h2>Import/Export</h2>
|
||||||
|
|||||||
@@ -77,8 +77,10 @@ async function navigate(page) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function launch(mode) {
|
async function launch(mode) {
|
||||||
alert(`Launching the game in ${mode} mode.`);
|
alert(`Launching the game in ${mode} mode.`);
|
||||||
|
await electronAPI.launchGame(mode);
|
||||||
|
setBepinexVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function autoDetectGamePath() {
|
async function autoDetectGamePath() {
|
||||||
@@ -128,12 +130,32 @@ async function uninstallBepinex() {
|
|||||||
setBepinexVersion()
|
setBepinexVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function backupBepinex() {
|
||||||
|
await bepinex.backup()
|
||||||
|
setBepinexVersion()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteBepinexBackup() {
|
||||||
|
await bepinex.deleteBackup()
|
||||||
|
setBepinexVersion()
|
||||||
|
}
|
||||||
|
|
||||||
async function setBepinexVersion() {
|
async function setBepinexVersion() {
|
||||||
const bepinexVersion = await files.loadBepinexVersion()
|
|
||||||
const bepinexVersionText = document.getElementById("bepinex-version-text")
|
const bepinexVersionText = document.getElementById("bepinex-version-text")
|
||||||
|
if (bepinexVersionText == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const bepinexVersion = await files.loadBepinexVersion()
|
||||||
|
const bepinexBackupVersion = await files.loadBepinexBackupVersion()
|
||||||
if(bepinexVersion == undefined) {
|
if(bepinexVersion == undefined) {
|
||||||
|
if(bepinexBackupVersion == undefined) {
|
||||||
bepinexVersionText.innerText = "BepInEx is not installed"
|
bepinexVersionText.innerText = "BepInEx is not installed"
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
bepinexVersionText.innerText = `BepInEx ${bepinexBackupVersion} is backuped`
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
bepinexVersionText.innerText = `BepInEx ${bepinexVersion} is installed`
|
bepinexVersionText.innerText = `BepInEx ${bepinexVersion} is installed`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user