From 9f1dadb662d4757262e5377245ed6fd70bdc1037 Mon Sep 17 00:00:00 2001 From: Pompurin404 Date: Fri, 2 Aug 2024 23:12:38 +0800 Subject: [PATCH] change profile --- src/main/config/profile.ts | 24 +++++++++++------ src/main/core/manager.ts | 23 ++++++++++++++-- src/main/resolve/init.ts | 8 ++++++ src/main/utils/cmds.ts | 2 ++ src/main/utils/dirs.ts | 4 +++ .../src/components/profiles/profile-item.tsx | 3 ++- src/renderer/src/hooks/use-profile.tsx | 15 ++++++++--- src/renderer/src/pages/profiles.tsx | 6 +++-- src/renderer/src/utils/ipc.ts | 26 +++++++++++-------- 9 files changed, 84 insertions(+), 27 deletions(-) diff --git a/src/main/config/profile.ts b/src/main/config/profile.ts index 9311f86f..131daa7b 100644 --- a/src/main/config/profile.ts +++ b/src/main/config/profile.ts @@ -22,21 +22,29 @@ export function getProfileItem(id: string | undefined): IProfileItem { return items?.find((item) => item.id === id) || { id: 'default', type: 'local', name: '空白订阅' } } +export async function changeCurrentProfile(id: string): Promise { + const oldId = getProfileConfig().current + profileConfig.current = id + getCurrentProfile(true) + try { + restartCore() + } catch (e) { + profileConfig.current = oldId + getCurrentProfile(true) + } finally { + window?.webContents.send('profileConfigUpdated') + fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig)) + } +} + export async function addProfileItem(item: Partial): Promise { const newItem = await createProfile(item) - profileConfig.items = getProfileConfig().items.filter((item) => item.id !== newItem.id) profileConfig.items.push(newItem) - let changeProfile = false if (!getProfileConfig().current) { - profileConfig.current = newItem.id - changeProfile = true + changeCurrentProfile(newItem.id) } fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig)) window?.webContents.send('profileConfigUpdated') - if (changeProfile) { - getCurrentProfile(true) - restartCore() - } } export function removeProfileItem(id: string): void { diff --git a/src/main/core/manager.ts b/src/main/core/manager.ts index cf13510a..01db7110 100644 --- a/src/main/core/manager.ts +++ b/src/main/core/manager.ts @@ -1,13 +1,21 @@ import { ChildProcess, execSync, spawn } from 'child_process' -import { logPath, mihomoCorePath, mihomoWorkDir } from '../utils/dirs' +import { + logPath, + mihomoCorePath, + mihomoTestDir, + mihomoWorkConfigPath, + mihomoWorkDir +} from '../utils/dirs' import { generateProfile } from '../resolve/factory' import { getAppConfig } from '../config' import fs from 'fs' + let child: ChildProcess -export async function startCore(): Promise { +export function startCore(): void { const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo') generateProfile() + checkProfile() stopCore() if (process.platform !== 'win32') { execSync(`chmod +x ${corePath}`) @@ -41,3 +49,14 @@ export function stopCore(): void { export function restartCore(): void { startCore() } + +// mihomo -t -d path return status code +export function checkProfile(): void { + const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo') + generateProfile() + if (process.platform !== 'win32') { + execSync(`chmod +x ${corePath}`) + } + + execSync(`${corePath} -t -f ${mihomoWorkConfigPath()} -d ${mihomoTestDir()}`) +} diff --git a/src/main/resolve/init.ts b/src/main/resolve/init.ts index d77dc57b..536af21e 100644 --- a/src/main/resolve/init.ts +++ b/src/main/resolve/init.ts @@ -3,6 +3,7 @@ import { controledMihomoConfigPath, dataDir, logDir, + mihomoTestDir, mihomoWorkDir, profileConfigPath, profilePath, @@ -35,6 +36,9 @@ function initDirs(): void { if (!fs.existsSync(logDir())) { fs.mkdirSync(logDir()) } + if (!fs.existsSync(mihomoTestDir())) { + fs.mkdirSync(mihomoTestDir()) + } } function initConfig(): void { @@ -56,10 +60,14 @@ function initFiles(): void { const fileList = ['Country.mmdb', 'geoip.dat', 'geosite.dat'] for (const file of fileList) { const targetPath = path.join(mihomoWorkDir(), file) + const testTargrtPath = path.join(mihomoTestDir(), file) const sourcePath = path.join(resourcesFilesDir(), file) if (!fs.existsSync(targetPath) && fs.existsSync(sourcePath)) { fs.copyFileSync(sourcePath, targetPath) } + if (!fs.existsSync(testTargrtPath) && fs.existsSync(sourcePath)) { + fs.copyFileSync(sourcePath, testTargrtPath) + } } } diff --git a/src/main/utils/cmds.ts b/src/main/utils/cmds.ts index c7291739..bf03acf7 100644 --- a/src/main/utils/cmds.ts +++ b/src/main/utils/cmds.ts @@ -22,6 +22,7 @@ import { } from '../config' import { restartCore } from '../core/manager' import { triggerSysProxy } from '../resolve/sysproxy' +import { changeCurrentProfile } from '../config/profile' export function registerIpcMainHandlers(): void { ipcMain.handle('mihomoVersion', mihomoVersion) @@ -41,6 +42,7 @@ export function registerIpcMainHandlers(): void { ipcMain.handle('getProfileConfig', (_e, force) => getProfileConfig(force)) ipcMain.handle('getCurrentProfileItem', getCurrentProfileItem) ipcMain.handle('getProfileItem', (_e, id) => getProfileItem(id)) + ipcMain.handle('changeCurrentProfile', (_e, id) => changeCurrentProfile(id)) ipcMain.handle('addProfileItem', (_e, item) => addProfileItem(item)) ipcMain.handle('removeProfileItem', (_e, id) => removeProfileItem(id)) ipcMain.handle('restartCore', () => restartCore()) diff --git a/src/main/utils/dirs.ts b/src/main/utils/dirs.ts index 236224b9..9a870fa8 100644 --- a/src/main/utils/dirs.ts +++ b/src/main/utils/dirs.ts @@ -49,6 +49,10 @@ export function mihomoWorkDir(): string { return path.join(dataDir, 'work') } +export function mihomoTestDir(): string { + return path.join(dataDir, 'test') +} + export function mihomoWorkConfigPath(): string { return path.join(mihomoWorkDir(), 'config.yaml') } diff --git a/src/renderer/src/components/profiles/profile-item.tsx b/src/renderer/src/components/profiles/profile-item.tsx index 0dab6389..347077a5 100644 --- a/src/renderer/src/components/profiles/profile-item.tsx +++ b/src/renderer/src/components/profiles/profile-item.tsx @@ -6,7 +6,7 @@ import { IoMdRefresh } from 'react-icons/io' interface Props { info: IProfileItem isCurrent: boolean - onClick: () => void + onClick: () => Promise } const ProfileItem: React.FC = (props) => { @@ -14,6 +14,7 @@ const ProfileItem: React.FC = (props) => { const extra = info?.extra const usage = (extra?.upload ?? 0) + (extra?.download ?? 0) const total = extra?.total ?? 0 + return ( diff --git a/src/renderer/src/hooks/use-profile.tsx b/src/renderer/src/hooks/use-profile.tsx index 111fe846..3bdadc34 100644 --- a/src/renderer/src/hooks/use-profile.tsx +++ b/src/renderer/src/hooks/use-profile.tsx @@ -2,7 +2,8 @@ import useSWR from 'swr' import { getProfileConfig, addProfileItem as add, - removeProfileItem as remove + removeProfileItem as remove, + changeCurrentProfile as change } from '@renderer/utils/ipc' import { useEffect } from 'react' @@ -10,7 +11,8 @@ interface RetuenType { profileConfig: IProfileConfig | undefined mutateProfileConfig: () => void addProfileItem: (item: Partial) => Promise - removeProfileItem: (id: string) => void + removeProfileItem: (id: string) => Promise + changeCurrentProfile: (id: string) => Promise } export const useProfileConfig = (): RetuenType => { @@ -27,6 +29,12 @@ export const useProfileConfig = (): RetuenType => { await remove(id) mutateProfileConfig() } + + const changeCurrentProfile = async (id: string): Promise => { + await change(id) + mutateProfileConfig() + } + useEffect(() => { window.electron.ipcRenderer.on('profileConfigUpdated', () => { mutateProfileConfig() @@ -40,6 +48,7 @@ export const useProfileConfig = (): RetuenType => { profileConfig, mutateProfileConfig, addProfileItem, - removeProfileItem + removeProfileItem, + changeCurrentProfile } } diff --git a/src/renderer/src/pages/profiles.tsx b/src/renderer/src/pages/profiles.tsx index 1b56756a..f5822620 100644 --- a/src/renderer/src/pages/profiles.tsx +++ b/src/renderer/src/pages/profiles.tsx @@ -6,7 +6,7 @@ import { useState } from 'react' import { MdContentPaste } from 'react-icons/md' const Profiles: React.FC = () => { - const { profileConfig, addProfileItem } = useProfileConfig() + const { profileConfig, addProfileItem, changeCurrentProfile } = useProfileConfig() const { current, items } = profileConfig || {} const [importing, setImporting] = useState(false) const [url, setUrl] = useState('') @@ -56,7 +56,9 @@ const Profiles: React.FC = () => { key={item.id} isCurrent={item.id === current} info={item} - onClick={() => {}} + onClick={async () => { + await changeCurrentProfile(item.id) + }} /> ))} diff --git a/src/renderer/src/utils/ipc.ts b/src/renderer/src/utils/ipc.ts index ac5daa61..d4235f41 100644 --- a/src/renderer/src/utils/ipc.ts +++ b/src/renderer/src/utils/ipc.ts @@ -14,15 +14,15 @@ export async function mihomoRules(): Promise { return await window.electron.ipcRenderer.invoke('mihomoRules') } export async function startMihomoLogs(): Promise { - await window.electron.ipcRenderer.invoke('startMihomoLogs') + return await window.electron.ipcRenderer.invoke('startMihomoLogs') } export async function stopMihomoLogs(): Promise { - await window.electron.ipcRenderer.invoke('stopMihomoLogs') + return await window.electron.ipcRenderer.invoke('stopMihomoLogs') } export async function patchMihomoConfig(patch: Partial): Promise { - await window.electron.ipcRenderer.invoke('patchMihomoConfig', patch) + return await window.electron.ipcRenderer.invoke('patchMihomoConfig', patch) } export async function checkAutoRun(): Promise { @@ -30,11 +30,11 @@ export async function checkAutoRun(): Promise { } export async function enableAutoRun(): Promise { - await window.electron.ipcRenderer.invoke('enableAutoRun') + return await window.electron.ipcRenderer.invoke('enableAutoRun') } export async function disableAutoRun(): Promise { - await window.electron.ipcRenderer.invoke('disableAutoRun') + return await window.electron.ipcRenderer.invoke('disableAutoRun') } export async function getAppConfig(force = false): Promise { @@ -42,7 +42,7 @@ export async function getAppConfig(force = false): Promise { } export async function setAppConfig(patch: Partial): Promise { - await window.electron.ipcRenderer.invoke('setAppConfig', patch) + return await window.electron.ipcRenderer.invoke('setAppConfig', patch) } export async function getControledMihomoConfig(force = false): Promise> { @@ -50,7 +50,7 @@ export async function getControledMihomoConfig(force = false): Promise): Promise { - await window.electron.ipcRenderer.invoke('setControledMihomoConfig', patch) + return await window.electron.ipcRenderer.invoke('setControledMihomoConfig', patch) } export async function getProfileConfig(force = false): Promise { @@ -65,18 +65,22 @@ export async function getProfileItem(id: string | undefined): Promise { + return await window.electron.ipcRenderer.invoke('changeCurrentProfile', id) +} + export async function addProfileItem(item: Partial): Promise { - await window.electron.ipcRenderer.invoke('addProfileItem', item) + return await window.electron.ipcRenderer.invoke('addProfileItem', item) } export async function removeProfileItem(id: string): Promise { - await window.electron.ipcRenderer.invoke('removeProfileItem', id) + return await window.electron.ipcRenderer.invoke('removeProfileItem', id) } export async function restartCore(): Promise { - await window.electron.ipcRenderer.invoke('restartCore') + return await window.electron.ipcRenderer.invoke('restartCore') } export async function triggerSysProxy(enable: boolean): Promise { - await window.electron.ipcRenderer.invoke('triggerSysProxy', enable) + return await window.electron.ipcRenderer.invoke('triggerSysProxy', enable) }