diff --git a/src/main/config/app.ts b/src/main/config/app.ts new file mode 100644 index 0000000..748579b --- /dev/null +++ b/src/main/config/app.ts @@ -0,0 +1,17 @@ +import { appConfigPath } from '../utils/dirs' +import yaml from 'yaml' +import fs from 'fs' + +export let appConfig: IAppConfig // config.yaml + +export function getAppConfig(force = false): IAppConfig { + if (force || !appConfig) { + appConfig = yaml.parse(fs.readFileSync(appConfigPath(), 'utf-8')) + } + return appConfig +} + +export function setAppConfig(patch: Partial): void { + appConfig = Object.assign(appConfig, patch) + fs.writeFileSync(appConfigPath(), yaml.stringify(appConfig)) +} diff --git a/src/main/config/controledMihomo.ts b/src/main/config/controledMihomo.ts new file mode 100644 index 0000000..c15de5e --- /dev/null +++ b/src/main/config/controledMihomo.ts @@ -0,0 +1,17 @@ +import { controledMihomoConfigPath } from '../utils/dirs' +import yaml from 'yaml' +import fs from 'fs' + +export let controledMihomoConfig: Partial // mihomo.yaml + +export function getControledMihomoConfig(force = false): Partial { + if (force || !controledMihomoConfig) { + controledMihomoConfig = yaml.parse(fs.readFileSync(controledMihomoConfigPath(), 'utf-8')) + } + return controledMihomoConfig +} + +export function setControledMihomoConfig(patch: Partial): void { + controledMihomoConfig = Object.assign(controledMihomoConfig, patch) + fs.writeFileSync(controledMihomoConfigPath(), yaml.stringify(controledMihomoConfig)) +} diff --git a/src/main/config/index.ts b/src/main/config/index.ts new file mode 100644 index 0000000..93e1ae9 --- /dev/null +++ b/src/main/config/index.ts @@ -0,0 +1,17 @@ +export { appConfig, getAppConfig, setAppConfig } from './app' +export { + controledMihomoConfig, + getControledMihomoConfig, + setControledMihomoConfig +} from './controledMihomo' +export { + profileConfig, + currentProfile, + getCurrentProfile, + getCurrentProfileItem, + getProfileItem, + getProfileConfig, + addProfileItem, + removeProfileItem, + createProfile +} from './profile' diff --git a/src/main/config.ts b/src/main/config/profile.ts similarity index 66% rename from src/main/config.ts rename to src/main/config/profile.ts index 8d41f57..c334eaf 100644 --- a/src/main/config.ts +++ b/src/main/config/profile.ts @@ -1,62 +1,12 @@ +import { controledMihomoConfig } from './controledMihomo' +import { profileConfigPath, profilePath } from '../utils/dirs' +import { app } from 'electron' +import axios from 'axios' import yaml from 'yaml' import fs from 'fs' -import { - defaultConfig, - defaultControledMihomoConfig, - defaultProfile, - defaultProfileConfig -} from './template' -import { appConfigPath, controledMihomoConfigPath, profileConfigPath, profilePath } from './dirs' -import axios from 'axios' -import { app } from 'electron' -export let appConfig: IAppConfig // config.yaml export let profileConfig: IProfileConfig // profile.yaml export let currentProfile: Partial // profiles/xxx.yaml -export let controledMihomoConfig: Partial // mihomo.yaml - -export function initConfig(): void { - if (!fs.existsSync(appConfigPath())) { - fs.writeFileSync(appConfigPath(), yaml.stringify(defaultConfig)) - } - if (!fs.existsSync(profileConfigPath())) { - fs.writeFileSync(profileConfigPath(), yaml.stringify(defaultProfileConfig)) - } - if (!fs.existsSync(profilePath('default'))) { - fs.writeFileSync(profilePath('default'), yaml.stringify(defaultProfile)) - } - if (!fs.existsSync(controledMihomoConfigPath())) { - fs.writeFileSync(controledMihomoConfigPath(), yaml.stringify(defaultControledMihomoConfig)) - } - getAppConfig(true) - getControledMihomoConfig(true) - getProfileConfig(true) - getCurrentProfile(true) -} - -export function getAppConfig(force = false): IAppConfig { - if (force || !appConfig) { - appConfig = yaml.parse(fs.readFileSync(appConfigPath(), 'utf-8')) - } - return appConfig -} - -export function setAppConfig(patch: Partial): void { - appConfig = Object.assign(appConfig, patch) - fs.writeFileSync(appConfigPath(), yaml.stringify(appConfig)) -} - -export function getControledMihomoConfig(force = false): Partial { - if (force || !controledMihomoConfig) { - controledMihomoConfig = yaml.parse(fs.readFileSync(controledMihomoConfigPath(), 'utf-8')) - } - return controledMihomoConfig -} - -export function setControledMihomoConfig(patch: Partial): void { - controledMihomoConfig = Object.assign(controledMihomoConfig, patch) - fs.writeFileSync(controledMihomoConfigPath(), yaml.stringify(controledMihomoConfig)) -} export function getProfileConfig(force = false): IProfileConfig { if (force || !profileConfig) { @@ -92,16 +42,6 @@ export function removeProfileItem(id: string): void { export function getCurrentProfileItem(): IProfileItem { return getProfileItem(profileConfig.current) } -export function getCurrentProfile(force = false): Partial { - if (force || !currentProfile) { - if (profileConfig.current) { - currentProfile = yaml.parse(fs.readFileSync(profilePath(profileConfig.current), 'utf-8')) - } else { - currentProfile = yaml.parse(fs.readFileSync(profilePath('default'), 'utf-8')) - } - } - return currentProfile -} export async function createProfile(item: Partial): Promise { const id = item.id || new Date().getTime().toString(16) @@ -163,3 +103,14 @@ export async function createProfile(item: Partial): Promise { + if (force || !currentProfile) { + if (profileConfig.current) { + currentProfile = yaml.parse(fs.readFileSync(profilePath(profileConfig.current), 'utf-8')) + } else { + currentProfile = yaml.parse(fs.readFileSync(profilePath('default'), 'utf-8')) + } + } + return currentProfile +} diff --git a/src/main/manager.ts b/src/main/core/manager.ts similarity index 84% rename from src/main/manager.ts rename to src/main/core/manager.ts index 7bc3760..eb1a2c3 100644 --- a/src/main/manager.ts +++ b/src/main/core/manager.ts @@ -1,7 +1,7 @@ import { ChildProcess, execSync, spawn } from 'child_process' -import { logPath, mihomoCorePath, mihomoWorkDir } from './dirs' -import { generateProfile } from './factory' -import { appConfig } from './config' +import { logPath, mihomoCorePath, mihomoWorkDir } from '../utils/dirs' +import { generateProfile } from '../resolve/factory' +import { appConfig } from '../config' import fs from 'fs' let child: ChildProcess diff --git a/src/main/mihomoApi.ts b/src/main/core/mihomoApi.ts similarity index 96% rename from src/main/mihomoApi.ts rename to src/main/core/mihomoApi.ts index e685fec..90de5e2 100644 --- a/src/main/mihomoApi.ts +++ b/src/main/core/mihomoApi.ts @@ -1,7 +1,7 @@ import axios, { AxiosInstance } from 'axios' -import { controledMihomoConfig } from './config' +import { controledMihomoConfig } from '../config' import WebSocket from 'ws' -import { window } from '.' +import { window } from '..' let axiosIns: AxiosInstance = null! let mihomoTrafficWs: WebSocket = null! diff --git a/src/main/tray.ts b/src/main/core/tray.ts similarity index 93% rename from src/main/tray.ts rename to src/main/core/tray.ts index d0dfeec..40163eb 100644 --- a/src/main/tray.ts +++ b/src/main/core/tray.ts @@ -1,11 +1,11 @@ -import { appConfig, controledMihomoConfig, setAppConfig, setControledMihomoConfig } from './config' -import icoIcon from '../../resources/icon.ico?asset' -import pngIcon from '../../resources/icon.png?asset' +import { appConfig, controledMihomoConfig, setAppConfig, setControledMihomoConfig } from '../config' +import icoIcon from '../../../resources/icon.ico?asset' +import pngIcon from '../../../resources/icon.png?asset' import { patchMihomoConfig } from './mihomoApi' -import { window } from '.' +import { window } from '..' import { app, ipcMain, Menu, shell, Tray } from 'electron' -import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from './dirs' -import { triggerSysProxy } from './sysproxy' +import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from '../utils/dirs' +import { triggerSysProxy } from '../resolve/sysproxy' let tray: Tray | null = null @@ -60,7 +60,7 @@ const buildContextMenu = (): Menu => { { type: 'checkbox', label: '系统代理', - checked: appConfig.sysProxy.enable, + checked: appConfig.sysProxy?.enable ?? false, click: (item): void => { const enable = item.checked setAppConfig({ sysProxy: { enable } }) diff --git a/src/main/index.ts b/src/main/index.ts index b1d05a6..c120608 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,13 +1,13 @@ -import { app, shell, BrowserWindow } from 'electron' -import { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' +import { registerIpcMainHandlers } from './utils/cmds' +import { app, shell, BrowserWindow } from 'electron' +import { stopCore, startCore } from './core/manager' import icon from '../../resources/icon.png?asset' -import { registerIpcMainHandlers } from './cmds' -import { initConfig, appConfig } from './config' -import { stopCore, startCore } from './manager' -import { initDirs } from './dirs' -import { mihomoTraffic } from './mihomoApi' -import { createTray } from './tray' +import { mihomoTraffic } from './core/mihomoApi' +import { createTray } from './core/tray' +import { init } from './resolve/init' +import { appConfig } from './config' +import { join } from 'path' export let window: BrowserWindow | null = null @@ -16,8 +16,7 @@ const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { app.quit() } else { - initDirs() - initConfig() + init() startCore() app.on('second-instance', () => { diff --git a/src/main/autoRun.ts b/src/main/resolve/autoRun.ts similarity index 100% rename from src/main/autoRun.ts rename to src/main/resolve/autoRun.ts diff --git a/src/main/factory.ts b/src/main/resolve/factory.ts similarity index 65% rename from src/main/factory.ts rename to src/main/resolve/factory.ts index 45db983..88c35f8 100644 --- a/src/main/factory.ts +++ b/src/main/resolve/factory.ts @@ -1,5 +1,5 @@ -import { controledMihomoConfig, currentProfile } from './config' -import { mihomoWorkConfigPath } from './dirs' +import { controledMihomoConfig, currentProfile } from '../config' +import { mihomoWorkConfigPath } from '../utils/dirs' import yaml from 'yaml' import fs from 'fs' diff --git a/src/main/resolve/init.ts b/src/main/resolve/init.ts new file mode 100644 index 0000000..65abea4 --- /dev/null +++ b/src/main/resolve/init.ts @@ -0,0 +1,77 @@ +import { + appConfigPath, + controledMihomoConfigPath, + dataDir, + logDir, + mihomoWorkDir, + profileConfigPath, + profilePath, + profilesDir, + resourcesFilesDir +} from '../utils/dirs' +import { + getAppConfig, + getControledMihomoConfig, + getCurrentProfile, + getProfileConfig +} from '../config' +import { + defaultConfig, + defaultControledMihomoConfig, + defaultProfile, + defaultProfileConfig +} from '../utils/template' +import yaml from 'yaml' +import fs from 'fs' +import path from 'path' + +function initDirs(): void { + if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir) + } + if (!fs.existsSync(profilesDir())) { + fs.mkdirSync(profilesDir()) + } + if (!fs.existsSync(mihomoWorkDir())) { + fs.mkdirSync(mihomoWorkDir()) + } + if (!fs.existsSync(logDir())) { + fs.mkdirSync(logDir()) + } +} + +function initConfig(): void { + if (!fs.existsSync(appConfigPath())) { + fs.writeFileSync(appConfigPath(), yaml.stringify(defaultConfig)) + } + if (!fs.existsSync(profileConfigPath())) { + fs.writeFileSync(profileConfigPath(), yaml.stringify(defaultProfileConfig)) + } + if (!fs.existsSync(profilePath('default'))) { + fs.writeFileSync(profilePath('default'), yaml.stringify(defaultProfile)) + } + if (!fs.existsSync(controledMihomoConfigPath())) { + fs.writeFileSync(controledMihomoConfigPath(), yaml.stringify(defaultControledMihomoConfig)) + } + getAppConfig(true) + getControledMihomoConfig(true) + getProfileConfig(true) + getCurrentProfile(true) +} + +function initFiles(): void { + const fileList = ['Country.mmdb', 'geoip.dat', 'geosite.dat'] + for (const file of fileList) { + const targetPath = path.join(profilesDir(), file) + const sourcePath = path.join(resourcesFilesDir(), file) + if (!fs.existsSync(targetPath) && fs.existsSync(sourcePath)) { + fs.copyFileSync(sourcePath, targetPath) + } + } +} + +export function init(): void { + initDirs() + initConfig() + initFiles() +} diff --git a/src/main/sysproxy.ts b/src/main/resolve/sysproxy.ts similarity index 86% rename from src/main/sysproxy.ts rename to src/main/resolve/sysproxy.ts index f37cc2c..67cd856 100644 --- a/src/main/sysproxy.ts +++ b/src/main/resolve/sysproxy.ts @@ -1,4 +1,4 @@ -import { controledMihomoConfig } from './config' +import { controledMihomoConfig } from '../config' export function triggerSysProxy(enable: boolean): void { if (enable) { diff --git a/src/main/cmds.ts b/src/main/utils/cmds.ts similarity index 87% rename from src/main/cmds.ts rename to src/main/utils/cmds.ts index ec47daf..356bf85 100644 --- a/src/main/cmds.ts +++ b/src/main/utils/cmds.ts @@ -5,8 +5,8 @@ import { mihomoRules, mihomoVersion, patchMihomoConfig -} from './mihomoApi' -import { checkAutoRun, disableAutoRun, enableAutoRun } from './autoRun' +} from '../core/mihomoApi' +import { checkAutoRun, disableAutoRun, enableAutoRun } from '../resolve/autoRun' import { getAppConfig, setAppConfig, @@ -17,9 +17,9 @@ import { getProfileItem, addProfileItem, removeProfileItem -} from './config' -import { restartCore } from './manager' -import { triggerSysProxy } from './sysproxy' +} from '../config' +import { restartCore } from '../core/manager' +import { triggerSysProxy } from '../resolve/sysproxy' export function registerIpcMainHandlers(): void { ipcMain.handle('mihomoVersion', mihomoVersion) diff --git a/src/main/dirs.ts b/src/main/utils/dirs.ts similarity index 74% rename from src/main/dirs.ts rename to src/main/utils/dirs.ts index 79fd485..236224b 100644 --- a/src/main/dirs.ts +++ b/src/main/utils/dirs.ts @@ -1,31 +1,23 @@ import { is } from '@electron-toolkit/utils' import { app } from 'electron' import path from 'path' -import fs from 'fs' export const dataDir = app.getPath('userData') -export function initDirs(): void { - if (!fs.existsSync(dataDir)) { - fs.mkdirSync(dataDir) - } - if (!fs.existsSync(profilesDir())) { - fs.mkdirSync(profilesDir()) - } - if (!fs.existsSync(mihomoWorkDir())) { - fs.mkdirSync(mihomoWorkDir()) - } - if (!fs.existsSync(logDir())) { - fs.mkdirSync(logDir()) +export function resourcesDir(): string { + if (is.dev) { + return path.join(__dirname, '../../resources') + } else { + return path.join(process.resourcesPath) } } +export function resourcesFilesDir(): string { + return path.join(resourcesDir(), 'files') +} + export function mihomoCoreDir(): string { - if (is.dev) { - return path.join(__dirname, '../../resources/sidecar') - } else { - return path.join(process.resourcesPath, 'sidecar') - } + return path.join(resourcesDir(), 'sidecar') } export function mihomoCorePath(core: string): string { diff --git a/src/main/template.ts b/src/main/utils/template.ts similarity index 100% rename from src/main/template.ts rename to src/main/utils/template.ts