diff --git a/main.js b/main.js
index afbf5a6..bae82cc 100644
--- a/main.js
+++ b/main.js
@@ -7,74 +7,89 @@ const store = new Store();
const userSavePath = app.getPath('userData')
const createWindow = () => {
- const win = new BrowserWindow({
- width: 1280,
- height: 720,
- webPreferences: {
- preload: path.join(__dirname, 'preload.js')
- }
- })
+ const win = new BrowserWindow({
+ width: 1280,
+ height: 720,
+ webPreferences: {
+ preload: path.join(__dirname, 'preload.js')
+ }
+ })
- win.loadFile('renderer/index.html')
+ win.loadFile('renderer/index.html')
}
app.whenReady().then(() => {
- createWindow()
+ createWindow()
- app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow()
- }
- })
+ app.on('activate', () => {
+ if (BrowserWindow.getAllWindows().length === 0) {
+ createWindow()
+ }
+ })
})
app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit()
- }
+ if (process.platform !== 'darwin') {
+ app.quit()
+ }
})
ipcMain.handle('save-path', (event, path) => {
- store.set('silksong-path', path);
+ store.set('silksong-path', path);
});
ipcMain.handle('load-path', () => {
- return store.get('silksong-path');
+ return store.get('silksong-path');
});
async function fileExists(filePath) {
- try {
- await fs.access(filePath);
- return true;
- } catch {
- return false;
- }
+ try {
+ await fs.access(filePath);
+ return true;
+ } catch {
+ return false;
+ }
}
ipcMain.handle('file-exists', async (_, filePath) => {
- return await fileExists(filePath);
+ return await fileExists(filePath);
});
ipcMain.handle('get-userSavePath', () => {
- return userSavePath
+ return userSavePath
});
ipcMain.handle('delete-data', async (event, path) => {
- await fs.unlink(path)
+ await fs.unlink(path)
});
ipcMain.handle('export-data', async () => {
- const dataPath = `${userSavePath}\\config.json`
+ const dataPath = `${userSavePath}\\config.json`
- const { canceled, filePath } = await dialog.showSaveDialog({
- title: 'Export Data',
- defaultPath: 'config.json',
- filters: [
- { name: 'JSON', extensions: ['json'] }
- ]
- })
+ const { canceled, filePath } = await dialog.showSaveDialog({
+ title: 'Export Data',
+ defaultPath: 'config.json',
+ filters: [
+ { name: 'JSON', extensions: ['json'] }
+ ]
+ })
- if (canceled || !filePath) return
+ if (canceled || !filePath) return
- await fs.copyFile(dataPath, filePath)
+ await fs.copyFile(dataPath, filePath)
+})
+
+ipcMain.handle('import-data', async () => {
+ const dataPath = `${userSavePath}\\config.json`
+
+ const { canceled, filePaths } = await dialog.showOpenDialog({
+ title: 'Import Data',
+ properties: ['openFile'],
+ filters: [{ name: 'JSON', extensions: ['json'] }]
+ })
+
+ if (canceled || !filePaths) return
+
+ await fs.unlink(dataPath)
+ await fs.copyFile(filePaths[0], dataPath,fs.constants.COPYFILE_EXCL)
})
\ No newline at end of file
diff --git a/preload.js b/preload.js
index 5f93cdd..39e6bc9 100644
--- a/preload.js
+++ b/preload.js
@@ -1,22 +1,20 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('versions', {
- node: () => process.versions.node,
- chrome: () => process.versions.chrome,
- electron: () => process.versions.electron
+ node: () => process.versions.node,
+ chrome: () => process.versions.chrome,
+ electron: () => process.versions.electron
});
contextBridge.exposeInMainWorld('save', {
- saveSilksongPath: (path) =>
- ipcRenderer.invoke('save-path', path),
- loadSilksongPath: () =>
- ipcRenderer.invoke('load-path')
+ saveSilksongPath: (path) => ipcRenderer.invoke('save-path', path),
+ loadSilksongPath: () => ipcRenderer.invoke('load-path')
});
contextBridge.exposeInMainWorld('files', {
- fileExists: (path) => ipcRenderer.invoke('file-exists', path),
- userSavePath: () => ipcRenderer.invoke('get-userSavePath'),
- delete: (path) => ipcRenderer.invoke('delete-data', path),
- export: () => ipcRenderer.invoke('export-data'),
- import: (data) => ipcRenderer.invoke('import-data', data)
+ fileExists: (path) => ipcRenderer.invoke('file-exists', path),
+ userSavePath: () => ipcRenderer.invoke('get-userSavePath'),
+ delete: (path) => ipcRenderer.invoke('delete-data', path),
+ export: () => ipcRenderer.invoke('export-data'),
+ import: () => ipcRenderer.invoke('import-data')
});
\ No newline at end of file
diff --git a/renderer/index.html b/renderer/index.html
index ce0f43a..756a1cd 100644
--- a/renderer/index.html
+++ b/renderer/index.html
@@ -1,102 +1,102 @@
-
- Silk Fly Launcher
-
+
+ Silk Fly Launcher
+
-
-
-
-
-
+
+
+
+
-
-
-
-
- Silk Fly Launcher
- Debugging data
-
-
-
-
- List of installed mods.
-
-
-
- Browse Nexus mods.
-
-
-
- General settings
-
-
-
-
-
- Import/Export
-
-
-
-
-
-
-
+
+
+ Silk Fly Launcher
+ Debugging data
+
+
+
+
+ List of installed mods.
+
+
+
+ Browse Nexus mods.
+
+
+
+ General settings
+
+
+
+
+
+
+ Import/Export
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/renderer/renderer.js b/renderer/renderer.js
index 23479ab..1142205 100644
--- a/renderer/renderer.js
+++ b/renderer/renderer.js
@@ -12,70 +12,76 @@ navigate("home")
let savePath
files.userSavePath().then(path => {
- savePath = `${path}\\config.json`
- files.fileExists(savePath).then(result => {
- if(!result) {
- autoDetectGamePath()
- }
- });
+ savePath = `${path}\\config.json`
+ files.fileExists(savePath).then(result => {
+ if(!result) {
+ autoDetectGamePath()
+ }
+ });
});
async function navigate(page) {
- view.replaceChildren()
- switch (page) {
- case "home":
- title.innerText = "Home";
- const HomeTemplateCopy = HomeTemplate.content.cloneNode(true)
- const versionText = HomeTemplateCopy.getElementById("version-text")
- versionText.innerText =
- `Chrome version: (v${versions.chrome()}), ` +
- `Node.js version: (v${versions.node()}), Electron version: (v${versions.electron()})`
- view.appendChild(HomeTemplateCopy)
- break;
+ view.replaceChildren()
+ switch (page) {
+ case "home":
+ title.innerText = "Home";
+ const HomeTemplateCopy = HomeTemplate.content.cloneNode(true)
+ const versionText = HomeTemplateCopy.getElementById("version-text")
+ versionText.innerText =
+ `Chrome version: (v${versions.chrome()}), ` +
+ `Node.js version: (v${versions.node()}), Electron version: (v${versions.electron()})`
+ view.appendChild(HomeTemplateCopy)
+ break;
- case "mods-installed":
- const installedModsTemplateCopy = installedModsTemplate.content.cloneNode(true)
- view.appendChild(installedModsTemplateCopy)
- break;
+ case "mods-installed":
+ const installedModsTemplateCopy = installedModsTemplate.content.cloneNode(true)
+ view.appendChild(installedModsTemplateCopy)
+ break;
- case "mods-online":
- const onlineModsTemplateCopy = onlineModsTemplate.content.cloneNode(true)
- view.appendChild(onlineModsTemplateCopy)
- break;
+ case "mods-online":
+ const onlineModsTemplateCopy = onlineModsTemplate.content.cloneNode(true)
+ view.appendChild(onlineModsTemplateCopy)
+ break;
- case "general-settings":
- const settingsTemplateCopy = settingsTemplate.content.cloneNode(true)
- const silksongPathInput = settingsTemplateCopy.getElementById("silksong-path-input")
+ case "general-settings":
+ const settingsTemplateCopy = settingsTemplate.content.cloneNode(true)
+ const silksongPathInput = settingsTemplateCopy.getElementById("silksong-path-input")
- silksongPathInput.value = await save.loadSilksongPath()
+ silksongPathInput.value = await save.loadSilksongPath()
- silksongPathInput.addEventListener('input', async function(event) {
- let silksongPath = silksongPathInput.value
- await save.saveSilksongPath(silksongPath)
- });
+ silksongPathInput.addEventListener('input', async function(event) {
+ let silksongPath = silksongPathInput.value
+ await save.saveSilksongPath(silksongPath)
+ });
- view.appendChild(settingsTemplateCopy)
- }
+ view.appendChild(settingsTemplateCopy)
+ }
}
function launch(mode) {
- alert(`Launching the game in ${mode} mode.`);
+ alert(`Launching the game in ${mode} mode.`);
}
async function autoDetectGamePath() {
- const defaultSilksongPath = "C:/Program Files (x86)/Steam/steamapps/common/Hollow Knight Silksong/Hollow Knight Silksong.exe"
- if (await files.fileExists(defaultSilksongPath)) {
- await save.saveSilksongPath(defaultSilksongPath)
- if (document.getElementById("silksong-path-input")) {
- document.getElementById("silksong-path-input").value = await save.loadSilksongPath()
+ const defaultSilksongPath = "C:/Program Files (x86)/Steam/steamapps/common/Hollow Knight Silksong/Hollow Knight Silksong.exe"
+ if (await files.fileExists(defaultSilksongPath)) {
+ await save.saveSilksongPath(defaultSilksongPath)
+ if (document.getElementById("silksong-path-input")) {
+ document.getElementById("silksong-path-input").value = await save.loadSilksongPath()
+ }
}
- }
}
async function deleteData() {
- await files.delete(savePath)
+ await files.delete(savePath)
+ document.getElementById("silksong-path-input").value = await save.loadSilksongPath()
}
async function exportData() {
- await files.export()
+ await files.export()
+}
+
+async function importData() {
+ await files.import()
+ document.getElementById("silksong-path-input").value = await save.loadSilksongPath()
}
\ No newline at end of file
diff --git a/renderer/style.css b/renderer/style.css
index 845d76c..94dcc5a 100644
--- a/renderer/style.css
+++ b/renderer/style.css
@@ -1,208 +1,208 @@
* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- font-family: "Segoe UI", sans-serif;
- cursor: url("assets/cursor.png") 0 0, auto !important;
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: "Segoe UI", sans-serif;
+ cursor: url("assets/cursor.png") 0 0, auto !important;
}
body {
- background: black;
- color: #eee;
- height: 100vh;
- overflow: hidden;
+ background: black;
+ color: #eee;
+ height: 100vh;
+ overflow: hidden;
}
.app {
- display: flex;
- height: 100vh;
+ display: flex;
+ height: 100vh;
}
.background_video {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- object-fit: cover;
- z-index: -1;
- filter: brightness(1.4);
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ z-index: -1;
+ filter: brightness(1.4);
}
.sidebar {
- width: 280px;
- background: rgba(0, 0, 0, 0.8);
- border-right: 1px solid rgba(255, 0, 0, 0.15);
- display: flex;
- flex-direction: column;
+ width: 280px;
+ background: rgba(0, 0, 0, 0.8);
+ border-right: 1px solid rgba(255, 0, 0, 0.15);
+ display: flex;
+ flex-direction: column;
}
.logo {
- height: 70px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 32px;
- cursor: pointer;
- border-bottom: 1px solid rgba(255, 72, 0, 0.2);
- transition: background 0.2s;
+ height: 70px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 32px;
+ cursor: pointer;
+ border-bottom: 1px solid rgba(255, 72, 0, 0.2);
+ transition: background 0.2s;
}
.logo:hover {
- background: rgba(255, 0, 0, 0.08);
+ background: rgba(255, 0, 0, 0.08);
}
.logo_img {
- height: 50px;
- width: auto;
+ height: 50px;
+ width: auto;
}
.nav {
- padding: 20px;
+ padding: 20px;
}
.nav-section {
- margin-bottom: 30px;
+ margin-bottom: 30px;
}
.nav-title {
- display: inline-block;
- font-size: 13px;
- text-transform: uppercase;
- letter-spacing: 1px;
- color: #fff;
- margin-bottom: 10px;
+ display: inline-block;
+ font-size: 13px;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ color: #fff;
+ margin-bottom: 10px;
- padding: 0 4px 4px;
- border-bottom: 1px solid #ff6b6b;
+ padding: 0 4px 4px;
+ border-bottom: 1px solid #ff6b6b;
}
.nav button {
- width: 100%;
- padding: 10px 14px;
- margin-bottom: 8px;
- background: transparent;
- border: 1px solid black;
- border-radius: 4px;
- color: #eee;
- cursor: pointer;
- text-align: left;
- transition: all 0.2s ease;
+ width: 100%;
+ padding: 10px 14px;
+ margin-bottom: 8px;
+ background: transparent;
+ border: 1px solid black;
+ border-radius: 4px;
+ color: #eee;
+ cursor: pointer;
+ text-align: left;
+ transition: all 0.2s ease;
}
.nav button:hover {
- background: rgba(255, 72, 0, 0.2);
- border-color: rgba(255, 25, 0, 0.3);
+ background: rgba(255, 72, 0, 0.2);
+ border-color: rgba(255, 25, 0, 0.3);
}
.content {
- flex: 1;
- padding: 40px;
+ flex: 1;
+ padding: 40px;
}
.content h1 {
- font-size: 28px;
- margin-bottom: 20px;
- color: #ffffff;
+ font-size: 28px;
+ margin-bottom: 20px;
+ color: #ffffff;
}
.content h2 {
- font-size: 24px;
- margin-bottom: 20px;
- color: #ffffff;
- padding: 0 4px 4px;
- border-bottom: 1px solid #ff6b6b;
+ font-size: 24px;
+ margin-bottom: 20px;
+ color: #ffffff;
+ padding: 0 4px 4px;
+ border-bottom: 1px solid #ff6b6b;
}
.view {
- width: 100%;
- background: rgba(0, 0, 0, 0.8);
- border-radius: 12px;
- padding: 40px;
- position: relative;
- z-index: 0;
- box-shadow: 0 0 50px rgba(0, 0, 0, 0.15);
- overflow: auto;
- height: 90%;
+ width: 100%;
+ background: rgba(0, 0, 0, 0.8);
+ border-radius: 12px;
+ padding: 40px;
+ position: relative;
+ z-index: 0;
+ box-shadow: 0 0 50px rgba(0, 0, 0, 0.15);
+ overflow: auto;
+ height: 90%;
}
.slider-container {
- margin-top: 20px;
- width: clamp(600px, 70vw, 900px);
+ margin-top: 20px;
+ width: clamp(600px, 70vw, 900px);
}
input[type="range"] {
- width: 100%;
+ width: 100%;
}
.horizontal-div {
- display: flex;
- align-items: center;
- gap: 20px;
+ display: flex;
+ align-items: center;
+ gap: 20px;
}
.silksong-path-input {
- flex: 1;
- height: 30px;
- padding: 0 12px;
- background: rgba(0, 0, 0, 0.4);
- border: 1px solid #ff6b6b;
- border-radius: 4px;
- color: #eee;
- font-size: 13px;
- outline: none;
- transition: all 0.2s ease;
+ flex: 1;
+ height: 30px;
+ padding: 0 12px;
+ background: rgba(0, 0, 0, 0.4);
+ border: 1px solid #ff6b6b;
+ border-radius: 4px;
+ color: #eee;
+ font-size: 13px;
+ outline: none;
+ transition: all 0.2s ease;
}
.silksong-path-input:hover {
- background: rgba(0, 0, 0, 0.55);
- border-color: rgba(255, 25, 0, 0.3);
+ background: rgba(0, 0, 0, 0.55);
+ border-color: rgba(255, 25, 0, 0.3);
}
.silksong-path-input:focus {
- background: rgba(0, 0, 0, 0.65);
- border-color: rgba(255, 25, 0, 0.3);
- box-shadow: 0 0 0 1px rgba(255, 25, 0, 0.2);
+ background: rgba(0, 0, 0, 0.65);
+ border-color: rgba(255, 25, 0, 0.3);
+ box-shadow: 0 0 0 1px rgba(255, 25, 0, 0.2);
}
.default-button {
- width: 120px;
- height: 40px;
- padding: 2px;
- background: rgba(0, 0, 0, 0.4);
- border: 1px solid #ff6b6b;
- border-radius: 4px;
- color: #eee;
- cursor: pointer;
- font-size: 16px;
- transition: all 0.2s ease;
- display: flex;
- justify-content: center;
- align-items: center;
+ width: 120px;
+ height: 40px;
+ padding: 2px;
+ background: rgba(0, 0, 0, 0.4);
+ border: 1px solid #ff6b6b;
+ border-radius: 4px;
+ color: #eee;
+ cursor: pointer;
+ font-size: 16px;
+ transition: all 0.2s ease;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
.default-button:hover {
- background: rgba(255, 72, 0, 0.2);
- border-color: rgba(255, 25, 0, 0.3);
+ background: rgba(255, 72, 0, 0.2);
+ border-color: rgba(255, 25, 0, 0.3);
}
.important-button {
- width: 120px;
- height: 40px;
- padding: 2px;
- background: rgba(100, 0, 0, 0.4);
- border: 1px solid rgba(200, 25, 0);
- border-radius: 4px;
- color: #eee;
- cursor: pointer;
- font-size: 16px;
- transition: all 0.2s ease;
- display: flex;
- justify-content: center;
- align-items: center;
+ width: 120px;
+ height: 40px;
+ padding: 2px;
+ background: rgba(100, 0, 0, 0.4);
+ border: 1px solid rgba(200, 25, 0);
+ border-radius: 4px;
+ color: #eee;
+ cursor: pointer;
+ font-size: 16px;
+ transition: all 0.2s ease;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
.important-button:hover {
- background: rgba(255, 0, 0, 0.4);
- border-color: rgba(255, 25, 0, 0.8);
+ background: rgba(255, 0, 0, 0.4);
+ border-color: rgba(255, 25, 0, 0.8);
}
\ No newline at end of file