import { exists, mkdir, readTextFile, writeFile } from '@tauri-apps/plugin-fs'; import * as path from '@tauri-apps/api/path'; import { invoke } from '@tauri-apps/api/core'; import { Crypto } from './crypto'; export class Config { private fileName: string; private config: Record = {}; private crypto: Crypto | undefined; private configFilePath: string | undefined; private encrypt: boolean; constructor(fileName: string, encrypt?: boolean) { this.fileName = fileName; this.encrypt = encrypt ?? false; } async init(): Promise { const hwid: string = (await invoke('get_hwid')) ?? 'recorderinsandybridge'; this.crypto = new Crypto(hwid); const homeDir = await path.homeDir(); const folderPath = await path.join(homeDir, '.ezpplauncher'); this.configFilePath = await path.join(folderPath, this.fileName); const createFolder = !(await exists(folderPath)); if (createFolder) await mkdir(folderPath); const configExists = await exists(this.configFilePath); if (!configExists) return true; await this.load(); return false; } private async load() { if (!this.configFilePath) throw Error('configFilePath not set'); if (this.encrypt && !this.crypto) throw Error('crypto not initialized'); const fileStream = await readTextFile(this.configFilePath); try { const decryptedJSON = JSON.parse( this.encrypt && this.crypto ? this.crypto.decrypt(fileStream) : fileStream ) as Record; this.config = decryptedJSON; } catch (err) { this.config = {}; await this.save(); } } async save() { if (!this.configFilePath) throw Error('configFilePath not set'); if (this.encrypt && !this.crypto) throw Error('crypto not initialized'); const encryptedJSON = this.encrypt && this.crypto ? this.crypto.encrypt(JSON.stringify(this.config)) : JSON.stringify(this.config); await writeFile(this.configFilePath, Buffer.from(encryptedJSON), { append: false, }); } value(key: string) { return { set: (val: T) => { this.config[key] = val; }, get: (fallback: T): T => { return (this.config[key] as T) ?? fallback; }, del: () => { delete this.config[key]; }, }; } }