mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 21:20:29 +08:00
260 lines
6.9 KiB
TypeScript
260 lines
6.9 KiB
TypeScript
import {
|
|
appConfigPath,
|
|
controledMihomoConfigPath,
|
|
dataDir,
|
|
logDir,
|
|
mihomoTestDir,
|
|
mihomoWorkDir,
|
|
overrideConfigPath,
|
|
overrideDir,
|
|
profileConfigPath,
|
|
profilePath,
|
|
profilesDir,
|
|
resourcesFilesDir,
|
|
subStoreDir,
|
|
themesDir
|
|
} from './dirs'
|
|
import {
|
|
defaultConfig,
|
|
defaultControledMihomoConfig,
|
|
defaultOverrideConfig,
|
|
defaultProfile,
|
|
defaultProfileConfig
|
|
} from './template'
|
|
import yaml from 'yaml'
|
|
import { mkdir, writeFile,rm, readdir, cp } from 'fs/promises'
|
|
import { existsSync } from 'fs'
|
|
import path from 'path'
|
|
import {
|
|
startPacServer,
|
|
startSubStoreBackendServer,
|
|
startSubStoreFrontendServer
|
|
} from '../resolve/server'
|
|
import { triggerSysProxy } from '../sys/sysproxy'
|
|
import {
|
|
getAppConfig,
|
|
getControledMihomoConfig,
|
|
patchAppConfig,
|
|
patchControledMihomoConfig
|
|
} from '../config'
|
|
import { app } from 'electron'
|
|
import { startSSIDCheck } from '../sys/ssid'
|
|
|
|
async function initDirs(): Promise<void> {
|
|
if (!existsSync(dataDir())) {
|
|
await mkdir(dataDir())
|
|
}
|
|
if (!existsSync(themesDir())) {
|
|
await mkdir(themesDir())
|
|
}
|
|
if (!existsSync(profilesDir())) {
|
|
await mkdir(profilesDir())
|
|
}
|
|
if (!existsSync(overrideDir())) {
|
|
await mkdir(overrideDir())
|
|
}
|
|
if (!existsSync(mihomoWorkDir())) {
|
|
await mkdir(mihomoWorkDir())
|
|
}
|
|
if (!existsSync(logDir())) {
|
|
await mkdir(logDir())
|
|
}
|
|
if (!existsSync(mihomoTestDir())) {
|
|
await mkdir(mihomoTestDir())
|
|
}
|
|
if (!existsSync(subStoreDir())) {
|
|
await mkdir(subStoreDir())
|
|
}
|
|
}
|
|
|
|
async function initConfig(): Promise<void> {
|
|
if (!existsSync(appConfigPath())) {
|
|
await writeFile(appConfigPath(), yaml.stringify(defaultConfig))
|
|
}
|
|
if (!existsSync(profileConfigPath())) {
|
|
await writeFile(profileConfigPath(), yaml.stringify(defaultProfileConfig))
|
|
}
|
|
if (!existsSync(overrideConfigPath())) {
|
|
await writeFile(overrideConfigPath(), yaml.stringify(defaultOverrideConfig))
|
|
}
|
|
if (!existsSync(profilePath('default'))) {
|
|
await writeFile(profilePath('default'), yaml.stringify(defaultProfile))
|
|
}
|
|
if (!existsSync(controledMihomoConfigPath())) {
|
|
await writeFile(controledMihomoConfigPath(), yaml.stringify(defaultControledMihomoConfig))
|
|
}
|
|
}
|
|
|
|
async function initFiles(): Promise<void> {
|
|
const copy = async (file: string): Promise<void> => {
|
|
const targetPath = path.join(mihomoWorkDir(), file)
|
|
const testTargetPath = path.join(mihomoTestDir(), file)
|
|
const sourcePath = path.join(resourcesFilesDir(), file)
|
|
if (!existsSync(targetPath) && existsSync(sourcePath)) {
|
|
await cp(sourcePath, targetPath, { recursive: true })
|
|
}
|
|
if (!existsSync(testTargetPath) && existsSync(sourcePath)) {
|
|
await cp(sourcePath, testTargetPath, { recursive: true })
|
|
}
|
|
}
|
|
await Promise.all([
|
|
copy('country.mmdb'),
|
|
copy('geoip.metadb'),
|
|
copy('geoip.dat'),
|
|
copy('geosite.dat'),
|
|
copy('ASN.mmdb'),
|
|
copy('sub-store.bundle.js'),
|
|
copy('sub-store-frontend')
|
|
])
|
|
}
|
|
|
|
async function cleanup(): Promise<void> {
|
|
// update cache
|
|
const files = await readdir(dataDir())
|
|
for (const file of files) {
|
|
if (file.endsWith('.exe') || file.endsWith('.pkg') || file.endsWith('.7z')) {
|
|
try {
|
|
await rm(path.join(dataDir(), file))
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
}
|
|
// logs
|
|
const { maxLogDays = 7 } = await getAppConfig()
|
|
const logs = await readdir(logDir())
|
|
for (const log of logs) {
|
|
const date = new Date(log.split('.')[0])
|
|
const diff = Date.now() - date.getTime()
|
|
if (diff > maxLogDays * 24 * 60 * 60 * 1000) {
|
|
try {
|
|
await rm(path.join(logDir(), log))
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function migration(): Promise<void> {
|
|
const {
|
|
siderOrder = [
|
|
'sysproxy',
|
|
'tun',
|
|
'profile',
|
|
'proxy',
|
|
'rule',
|
|
'resource',
|
|
'override',
|
|
'connection',
|
|
'mihomo',
|
|
'dns',
|
|
'sniff',
|
|
'log',
|
|
'substore'
|
|
],
|
|
appTheme = 'system',
|
|
envType = [process.platform === 'win32' ? 'powershell' : 'bash'],
|
|
useSubStore = true,
|
|
showFloatingWindow = false,
|
|
disableTray = false,
|
|
encryptedPassword
|
|
} = await getAppConfig()
|
|
const {
|
|
'external-controller-pipe': externalControllerPipe,
|
|
'external-controller-unix': externalControllerUnix,
|
|
'external-controller': externalController,
|
|
'skip-auth-prefixes': skipAuthPrefixes,
|
|
authentication,
|
|
'bind-address': bindAddress,
|
|
'lan-allowed-ips': lanAllowedIps,
|
|
'lan-disallowed-ips': lanDisallowedIps
|
|
} = await getControledMihomoConfig()
|
|
// add substore sider card
|
|
if (useSubStore && !siderOrder.includes('substore')) {
|
|
await patchAppConfig({ siderOrder: [...siderOrder, 'substore'] })
|
|
}
|
|
// add default skip auth prefix
|
|
if (!skipAuthPrefixes) {
|
|
await patchControledMihomoConfig({ 'skip-auth-prefixes': ['127.0.0.1/32'] })
|
|
}
|
|
// add default authentication
|
|
if (!authentication) {
|
|
await patchControledMihomoConfig({ authentication: [] })
|
|
}
|
|
// add default bind address
|
|
if (!bindAddress) {
|
|
await patchControledMihomoConfig({ 'bind-address': '*' })
|
|
}
|
|
// add default lan allowed ips
|
|
if (!lanAllowedIps) {
|
|
await patchControledMihomoConfig({ 'lan-allowed-ips': ['0.0.0.0/0', '::/0'] })
|
|
}
|
|
// add default lan disallowed ips
|
|
if (!lanDisallowedIps) {
|
|
await patchControledMihomoConfig({ 'lan-disallowed-ips': [] })
|
|
}
|
|
// remove custom app theme
|
|
if (!['system', 'light', 'dark'].includes(appTheme)) {
|
|
await patchAppConfig({ appTheme: 'system' })
|
|
}
|
|
// change env type
|
|
if (typeof envType === 'string') {
|
|
await patchAppConfig({ envType: [envType] })
|
|
}
|
|
// use unix socket
|
|
if (externalControllerUnix) {
|
|
await patchControledMihomoConfig({ 'external-controller-unix': undefined })
|
|
}
|
|
// use named pipe
|
|
if (externalControllerPipe) {
|
|
await patchControledMihomoConfig({
|
|
'external-controller-pipe': undefined
|
|
})
|
|
}
|
|
if (externalController === undefined) {
|
|
await patchControledMihomoConfig({ 'external-controller': '' })
|
|
}
|
|
if (!showFloatingWindow && disableTray) {
|
|
await patchAppConfig({ disableTray: false })
|
|
}
|
|
// remove password
|
|
if (encryptedPassword) {
|
|
await patchAppConfig({ encryptedPassword: undefined })
|
|
}
|
|
}
|
|
|
|
function initDeeplink(): void {
|
|
if (process.defaultApp) {
|
|
if (process.argv.length >= 2) {
|
|
app.setAsDefaultProtocolClient('clash', process.execPath, [path.resolve(process.argv[1])])
|
|
app.setAsDefaultProtocolClient('mihomo', process.execPath, [path.resolve(process.argv[1])])
|
|
}
|
|
} else {
|
|
app.setAsDefaultProtocolClient('clash')
|
|
app.setAsDefaultProtocolClient('mihomo')
|
|
}
|
|
}
|
|
|
|
export async function init(): Promise<void> {
|
|
await initDirs()
|
|
await initConfig()
|
|
await migration()
|
|
await initFiles()
|
|
await cleanup()
|
|
await startSubStoreFrontendServer()
|
|
await startSubStoreBackendServer()
|
|
const { sysProxy } = await getAppConfig()
|
|
try {
|
|
if (sysProxy.enable) {
|
|
await startPacServer()
|
|
}
|
|
await triggerSysProxy(sysProxy.enable)
|
|
} catch {
|
|
// ignore
|
|
}
|
|
await startSSIDCheck()
|
|
|
|
initDeeplink()
|
|
}
|