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

View File

@ -1,12 +1,13 @@
import { getControledMihomoConfig } from './controledMihomo' import { getControledMihomoConfig } from './controledMihomo'
import { profileConfigPath, profilePath } from '../utils/dirs' import { mihomoProfileWorkDir, profileConfigPath, profilePath } from '../utils/dirs'
import { addProfileUpdater } from '../core/profileUpdater' 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 { restartCore } from '../core/manager'
import { getAppConfig } from './app' import { getAppConfig } from './app'
import { existsSync } from 'fs' import { existsSync } from 'fs'
import axios, { AxiosResponse } from 'axios' import axios, { AxiosResponse } from 'axios'
import yaml from 'yaml' import yaml from 'yaml'
import path from 'path'
import { defaultProfile } from '../utils/template' import { defaultProfile } from '../utils/template'
import { subStorePort } from '../resolve/server' import { subStorePort } from '../resolve/server'
@ -92,6 +93,21 @@ export async function removeProfileItem(id: string): Promise<void> {
if (shouldRestart) { if (shouldRestart) {
await restartCore() 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> { export async function getCurrentProfileItem(): Promise<IProfileItem> {

View File

@ -7,12 +7,18 @@ import {
getOverrideItem, getOverrideItem,
getOverrideConfig getOverrideConfig
} from '../config' } from '../config'
import { mihomoWorkConfigPath, overridePath } from '../utils/dirs' import {
mihomoProfileWorkDir,
mihomoWorkConfigPath,
overridePath,
resourcesFilesDir
} from '../utils/dirs'
import yaml from 'yaml' import yaml from 'yaml'
import { writeFile } from 'fs/promises' import { link, mkdir, writeFile } from 'fs/promises'
import { deepMerge } from '../utils/merge' import { deepMerge } from '../utils/merge'
import vm from 'vm' import vm from 'vm'
import { writeFileSync } from 'fs' import { existsSync, writeFileSync } from 'fs'
import path from 'path'
let runtimeConfigStr: string let runtimeConfigStr: string
let runtimeConfig: IMihomoConfig let runtimeConfig: IMihomoConfig
@ -26,7 +32,23 @@ export async function generateProfile(): Promise<void> {
profile['log-level'] = 'info' profile['log-level'] = 'info'
runtimeConfig = profile runtimeConfig = profile
runtimeConfigStr = yaml.stringify(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( async function overrideProfile(

View File

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

View File

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