specify work directory for each profile

This commit is contained in:
pompurin404 2024-10-12 20:06:33 +08:00
parent 484f21fac4
commit 43115d1da4
No known key found for this signature in database
5 changed files with 65 additions and 17 deletions

View File

@ -1,9 +1,7 @@
### New Features
- 支持自定义 WebDAV 备份目录名称
- 支持多个订阅切换分别保存选择的节点
### Bug Fixes
- 修复 macOS 自动更新失败的问题
- 修复订阅点击无法切换的问题
- 修复某些 Windows 管理员权限依然无法启动的问题
- 修复订阅显示样式错误

View File

@ -1,12 +1,13 @@
import { getControledMihomoConfig } from './controledMihomo'
import { profileConfigPath, profilePath } from '../utils/dirs'
import { mihomoProfileWorkDir, profileConfigPath, profilePath } from '../utils/dirs'
import { addProfileUpdater } from '../core/profileUpdater'
import { readFile, rm, writeFile } from 'fs/promises'
import { readFile, rm, unlink, writeFile } from 'fs/promises'
import { restartCore } from '../core/manager'
import { getAppConfig } from './app'
import { existsSync } from 'fs'
import axios, { AxiosResponse } from 'axios'
import yaml from 'yaml'
import path from 'path'
import { defaultProfile } from '../utils/template'
import { subStorePort } from '../resolve/server'
@ -92,6 +93,21 @@ export async function removeProfileItem(id: string): Promise<void> {
if (shouldRestart) {
await restartCore()
}
if (existsSync(mihomoProfileWorkDir(id))) {
const unln = async (file: string): Promise<void> => {
const targetPath = path.join(mihomoProfileWorkDir(id), file)
if (existsSync(targetPath)) {
await unlink(targetPath)
}
}
await Promise.all([
unln('country.mmdb'),
unln('geoip.dat'),
unln('geosite.dat'),
unln('ASN.mmdb')
])
await rm(mihomoProfileWorkDir(id), { recursive: true })
}
}
export async function getCurrentProfileItem(): Promise<IProfileItem> {

View File

@ -7,12 +7,18 @@ import {
getOverrideItem,
getOverrideConfig
} from '../config'
import { mihomoWorkConfigPath, overridePath } from '../utils/dirs'
import {
mihomoProfileWorkDir,
mihomoWorkConfigPath,
overridePath,
resourcesFilesDir
} from '../utils/dirs'
import yaml from 'yaml'
import { writeFile } from 'fs/promises'
import { link, mkdir, writeFile } from 'fs/promises'
import { deepMerge } from '../utils/merge'
import vm from 'vm'
import { writeFileSync } from 'fs'
import { existsSync, writeFileSync } from 'fs'
import path from 'path'
let runtimeConfigStr: string
let runtimeConfig: IMihomoConfig
@ -26,7 +32,23 @@ export async function generateProfile(): Promise<void> {
profile['log-level'] = 'info'
runtimeConfig = profile
runtimeConfigStr = yaml.stringify(profile)
await writeFile(mihomoWorkConfigPath(), runtimeConfigStr)
await prepareProfileWorkDir(current)
await writeFile(mihomoWorkConfigPath(current), runtimeConfigStr)
}
async function prepareProfileWorkDir(current: string | undefined): Promise<void> {
if (!existsSync(mihomoProfileWorkDir(current))) {
await mkdir(mihomoProfileWorkDir(current), { recursive: true })
}
const ln = async (file: string): Promise<void> => {
const targetPath = path.join(mihomoProfileWorkDir(current), file)
const sourcePath = path.join(resourcesFilesDir(), file)
if (!existsSync(targetPath) && existsSync(sourcePath)) {
await link(sourcePath, targetPath)
}
}
await Promise.all([ln('country.mmdb'), ln('geoip.dat'), ln('geosite.dat'), ln('ASN.mmdb')])
}
async function overrideProfile(

View File

@ -4,14 +4,15 @@ import {
logPath,
mihomoCoreDir,
mihomoCorePath,
mihomoProfileWorkDir,
mihomoTestDir,
mihomoWorkConfigPath,
mihomoWorkDir
mihomoWorkConfigPath
} from '../utils/dirs'
import { generateProfile } from './factory'
import {
getAppConfig,
getControledMihomoConfig,
getProfileConfig,
patchAppConfig,
patchControledMihomoConfig
} from '../config'
@ -75,7 +76,7 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
await rm(path.join(dataDir(), 'core.pid'))
}
}
const { current } = await getProfileConfig()
const { tun } = await getControledMihomoConfig()
const corePath = mihomoCorePath(core)
await autoGrantCorePermition(corePath)
@ -92,7 +93,7 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
}
}
child = spawn(corePath, ['-d', mihomoWorkDir(), ctlParam, mihomoIpcPath], {
child = spawn(corePath, ['-d', mihomoProfileWorkDir(current), ctlParam, mihomoIpcPath], {
detached: detached,
stdio: detached ? 'ignore' : undefined
})
@ -205,10 +206,17 @@ export async function quitWithoutCore(): Promise<void> {
async function checkProfile(): Promise<void> {
const { core = 'mihomo' } = await getAppConfig()
const { current } = await getProfileConfig()
const corePath = mihomoCorePath(core)
const execFilePromise = promisify(execFile)
try {
await execFilePromise(corePath, ['-t', '-f', mihomoWorkConfigPath(), '-d', mihomoTestDir()])
await execFilePromise(corePath, [
'-t',
'-f',
mihomoWorkConfigPath(current),
'-d',
mihomoTestDir()
])
} catch (error) {
if (error instanceof Error && 'stdout' in error) {
const { stdout } = error as { stdout: string }

View File

@ -102,12 +102,16 @@ export function mihomoWorkDir(): string {
return path.join(dataDir(), 'work')
}
export function mihomoProfileWorkDir(id: string | undefined): string {
return path.join(mihomoWorkDir(), id || 'default')
}
export function mihomoTestDir(): string {
return path.join(dataDir(), 'test')
}
export function mihomoWorkConfigPath(): string {
return path.join(mihomoWorkDir(), 'config.yaml')
export function mihomoWorkConfigPath(id: string | undefined): string {
return path.join(mihomoProfileWorkDir(id), 'config.yaml')
}
export function logDir(): string {