Skip to content

Commit

Permalink
Feature - Generate File System
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomhuel committed Jul 15, 2024
1 parent 4cf09f6 commit 421d6cf
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 46 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ out
.DS_Store
*.log*
pnpm-lock.yaml
package-lock.json
package-lock.json
data
8 changes: 1 addition & 7 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
{
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
Expand Down
7 changes: 4 additions & 3 deletions electron-builder.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
appId: com.electron.app
productName: tao-mod-manager
appId: com.github.taomodmanager
productName: 'Tao Mod Manager'
directories:
buildResources: build
files:
Expand All @@ -12,7 +12,8 @@ files:
asarUnpack:
- resources/**
win:
executableName: tao-mod-manager
executableName: 'Tao Mod Manager'
requestedExecutionLevel: "requireAdministrator"
nsis:
artifactName: ${name}-${version}-setup.${ext}
shortcutName: ${productName}
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "An Electron application with Svelte and TypeScript",
"main": "./out/main/index.js",
"author": "example.com",
"author": "LukaLaKuka",
"homepage": "https://electron-vite.org",
"scripts": {
"format": "prettier --plugin prettier-plugin-svelte --write .",
Expand All @@ -22,7 +22,9 @@
},
"dependencies": {
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^3.0.0"
"@electron-toolkit/utils": "^3.0.0",
"@tomhuel/jsonhandler": "^1.0.1",
"decompress": "^4.2.1"
},
"devDependencies": {
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
Expand Down
Binary file added resources/3dmigoto.zip
Binary file not shown.
6 changes: 4 additions & 2 deletions src/main/app/mods/descompress.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export function descompress(args: any) {
console.log(args);
import { APPDIR } from "../..";

export async function descompress(_: any) {
return APPDIR;
}
30 changes: 30 additions & 0 deletions src/main/app/modules/fs/findFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fs from 'node:fs';
import path from 'node:path';
import { APPDIR } from '../../..';

export async function findFile(filename: string, extensions: string[], rootPath: string | undefined = undefined): Promise<string | undefined> {
rootPath = rootPath ?? APPDIR;

let files = fs.readdirSync(rootPath);

for (const file of files) {
if (file === 'app.asar') continue;
let filepath = path.join(rootPath, file);
let fileStat = fs.statSync(filepath);
if (fileStat.isDirectory()) {
let found = findFile(filename, extensions, filepath);
if (found) return found;
}

if (fileStat.isFile()) {
if (file === filename) return filepath;
let found = extensions.find((ext) => {
if (ext.startsWith('.')) ext = ext.substring(1);
return file === `${filename}.${ext}`;
});
if (found) return filepath;
}
}

return undefined;
}
12 changes: 12 additions & 0 deletions src/main/app/modules/fs/mkdir.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import fs from 'node:fs';

export async function createAppDir(dir: string, _: Electron.App) {
try {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
} catch (e: any) {
console.error(e.message);
//app.exit();
}
}
31 changes: 31 additions & 0 deletions src/main/app/modules/zip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import decompress from 'decompress'
import { decompressedFile } from '../../interaces/decompressedFile'
import fs from 'node:fs'
import path from 'node:path'

export async function decompressZip(zipFile: string, output: string) {
try {
let files: decompressedFile[] = await decompress(zipFile);
files.forEach(async (file: decompressedFile) => {
let outputPath = path.join(output, file.path);

if (file.type === 'directory') {
fs.mkdirSync(outputPath, { recursive: true });
fs.chmodSync(outputPath, file.mode);
}

let parentDir = path.dirname(outputPath);
if (!fs.existsSync(parentDir)) fs.mkdirSync(parentDir);

if (file.type === 'file') {
await fs.writeFileSync(outputPath, file.data);
await fs.chmodSync(outputPath, file.mode);
await fs.utimesSync(outputPath, new Date(), file.mtime);
}
});
return true;
} catch (e) {
console.error(e);
return false;
}
}
20 changes: 20 additions & 0 deletions src/main/app/setup/setupDirs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import path from "node:path";
import { CONFIGDIR, DATADIR, MODSDIR, MODSDIRWRAPPER, ZIPPATH } from "../..";
import fs from 'node:fs';
import { decompressZip } from "../modules/zip";
import { createAppDir } from "../modules/fs/mkdir";

export async function setupProject(app: Electron.App) {
[CONFIGDIR, MODSDIRWRAPPER, DATADIR].forEach(async (dir) => {
await createAppDir(dir, app);
});

if (!fs.existsSync(path.join(MODSDIR, 'loader.exe'))) {
let zipPath = await ZIPPATH();
if (zipPath) {
await decompressZip(zipPath, MODSDIR);
} else {
alert(`Error decompressing Loader`);
}
}
}
6 changes: 4 additions & 2 deletions src/main/eventHandler/eventHandler.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { ipcMain } from "electron";
import { descompress } from "../app/mods/descompress";
import { APPDIR } from "..";

/**
* Event Handler (IPC events emitted by front)
* @param app Electron's Application
*/
export default function handleEvent() {

ipcMain.handle('hello', async (_, __) => {
console.log('Hello from back');
return __dirname;
return APPDIR;
});

ipcMain.handle('descompress', async (_, args) => {
descompress(args);
return (await descompress(args));
});
}
33 changes: 27 additions & 6 deletions src/main/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { app, shell, BrowserWindow } from 'electron'
import { join } from 'path'
import path, { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import handleEvent from './eventHandler/eventHandler'
import { setupProject } from './app/setup/setupDirs'
import { findFile } from './app/modules/fs/findFile'

function createWindow(): void {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
height: 670,
minWidth: 505,
show: false,
autoHideMenuBar: true,
icon,
Expand All @@ -18,8 +21,9 @@ function createWindow(): void {
}
})

mainWindow.on('ready-to-show', () => {
mainWindow.show()
mainWindow.on('ready-to-show', async () => {
mainWindow.show();
await bootstrap();
})

mainWindow.webContents.setWindowOpenHandler((details) => {
Expand Down Expand Up @@ -68,7 +72,24 @@ app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
});

const APPDIR = path.join(app.getPath('appData'), app.getName());

export { APPDIR };

console.log(APPDIR)
export const DATADIR = path.join(APPDIR, 'data');
export const MODSDIRWRAPPER = path.join(DATADIR, 'mods');
export const MODSDIR = path.join(MODSDIRWRAPPER, 'Mods');
export const DISABLEDMODSDIR = path.join(MODSDIRWRAPPER, 'DisabledMods');
export const CONFIGDIR = path.join(DATADIR, 'config');
export const ZIPNAME = '3dmigoto';
export const ZIPPATH = async (): Promise<string | undefined> => {
// Find 3dmigoto.zip
return (await findFile(ZIPNAME, ['zip'], 'resources'));
}

// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
const bootstrap = async () => {
await setupProject(app)
};
7 changes: 7 additions & 0 deletions src/main/interaces/decompressedFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface decompressedFile {
mode: number;
mtime: Date;
path: string;
type: 'file' | 'directory';
data: Buffer;
}
27 changes: 13 additions & 14 deletions src/renderer/index.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Tao Mod Manager</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
/>
</head>

<body class="bg-dark">
<div id="app"></div>
<script type="module" src="./src/main.ts"></script>
</body>
</html>
<head>
<meta charset="UTF-8" />
<title>Tao Mod Manager</title>
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:" />
</head>

<body class="bg-dark">
<div id="app"></div>
<script type="module" src="./src/main.ts"></script>
</body>

</html>
20 changes: 14 additions & 6 deletions src/renderer/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
<script>
import Navbar from './components/navbar/Navbar.svelte'
import Modcard from './components/card/modcard.svelte'
import SettingsModal from './components/modal/settings/settingsModal.svelte'
import Import from './icons/import.svelte'
import Modcard from './components/card/modcard.svelte';
import SettingsModal from './components/modal/settings/settingsModal.svelte';
// Lógica
const getMods = () => {
return Array(10)
}
import Import from './icons/import.svelte';
const importCompress = (e) => {
console.log(e.target.files[0])
}
let mods = Array(10)
let mods = getMods()
</script>

<div class="h-screen">
<Navbar />
<main class="px-6 py-5 overflow-y-scroll">
<div class="flex justify-between text-light-blue mb-8">
<Import />
<label for="import-input" class="cursor-pointer">
<Import />
<input type="file" accept=".zip,.rar" on:change={importCompress} id="import-input" hidden />
</label>
<SettingsModal genshinPath="C:/Program_x86/App/Genshin/Executable/Path" />
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:gap-x-20 gap-8">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import Play from "../../../icons/play.svelte";
</script>

<button class="bg-primary flex justify-between items-center gap-1 text-light ps-3 pe-5 py-2 rounded-button my-3 transition-all duration-500 hover:bg-primary-darker" on:click={async () => {
console.log(await window.electron.hello('hello'));
}}>
<button class="bg-primary flex justify-between items-center gap-1 text-light ps-3 pe-5 py-2 rounded-button my-3 transition-all duration-500 hover:bg-primary-darker">
<Play className="w-9" />
<span class="font-yeon text-3xl min-h-full">Play</span>
</button>

0 comments on commit 421d6cf

Please sign in to comment.