mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-16 11:42:19 +08:00
support substore
This commit is contained in:
parent
ba5380664a
commit
044b676464
|
@ -4,6 +4,4 @@
|
|||
|
||||
### New Features
|
||||
|
||||
- 优化内核管理逻辑
|
||||
- 完善错误处理
|
||||
- 支持节点搜索
|
||||
- 内置 SubStore 服务
|
||||
|
|
|
@ -271,6 +271,12 @@ const resolveRunner = () =>
|
|||
file: 'mihomo-party-run.exe',
|
||||
downloadURL: `https://github.com/pompurin404/mihomo-party-run/releases/download/${arch}/mihomo-party-run.exe`
|
||||
})
|
||||
const resolveSubstore = () =>
|
||||
resolveResource({
|
||||
file: 'sub-store.bundle.js',
|
||||
downloadURL:
|
||||
'https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store.bundle.js'
|
||||
})
|
||||
const resolveFont = async () => {
|
||||
const targetPath = path.join(cwd, 'src', 'renderer', 'src', 'assets', 'NotoColorEmoji.ttf')
|
||||
|
||||
|
@ -322,6 +328,11 @@ const tasks = [
|
|||
func: resolveRunner,
|
||||
retry: 5,
|
||||
winOnly: true
|
||||
},
|
||||
{
|
||||
name: 'substore',
|
||||
func: resolveSubstore,
|
||||
retry: 5
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ export async function webdavBackup(): Promise<boolean> {
|
|||
zip.addLocalFile(overrideConfigPath())
|
||||
zip.addLocalFolder(profilesDir(), 'profiles')
|
||||
zip.addLocalFolder(overrideDir(), 'override')
|
||||
zip.addLocalFolder(overrideDir(), 'substore')
|
||||
const date = new Date()
|
||||
const zipFileName = `${process.platform}_${dayjs(date).format('YYYY-MM-DD_HH-mm-ss')}.zip`
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { getAppConfig, getControledMihomoConfig } from '../config'
|
||||
import { Worker } from 'worker_threads'
|
||||
import { subStoreDir } from '../utils/dirs'
|
||||
import http from 'http'
|
||||
import net from 'net'
|
||||
import path from 'path'
|
||||
|
||||
export let pacPort: number
|
||||
export let subStorePort: number
|
||||
|
||||
const defaultPacScript = `
|
||||
function FindProxyForURL(url, host) {
|
||||
|
@ -47,3 +51,16 @@ export async function startPacServer(): Promise<void> {
|
|||
.listen(pacPort)
|
||||
server.unref()
|
||||
}
|
||||
|
||||
export async function startSubStoreServer(): Promise<void> {
|
||||
const { useSubStore = true } = await getAppConfig()
|
||||
if (!useSubStore) return
|
||||
if (subStorePort) return
|
||||
subStorePort = await findAvailablePort(3000)
|
||||
new Worker(path.join(subStoreDir(), 'sub-store.bundle.js'), {
|
||||
env: {
|
||||
SUB_STORE_BACKEND_API_PORT: subStorePort.toString(),
|
||||
SUB_STORE_DATA_BASE_PATH: subStoreDir()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ export function taskDir(): string {
|
|||
return dir
|
||||
}
|
||||
|
||||
export function subStoreDir(): string {
|
||||
return path.join(dataDir(), 'substore')
|
||||
}
|
||||
|
||||
export function exeDir(): string {
|
||||
return path.dirname(exePath())
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ import {
|
|||
profileConfigPath,
|
||||
profilePath,
|
||||
profilesDir,
|
||||
resourcesFilesDir
|
||||
resourcesFilesDir,
|
||||
subStoreDir
|
||||
} from './dirs'
|
||||
import {
|
||||
defaultConfig,
|
||||
|
@ -23,7 +24,7 @@ import yaml from 'yaml'
|
|||
import { mkdir, writeFile, copyFile, rm, readdir } from 'fs/promises'
|
||||
import { existsSync } from 'fs'
|
||||
import path from 'path'
|
||||
import { startPacServer } from '../resolve/server'
|
||||
import { startPacServer, startSubStoreServer } from '../resolve/server'
|
||||
import { triggerSysProxy } from '../sys/sysproxy'
|
||||
import { getAppConfig } from '../config'
|
||||
import { app } from 'electron'
|
||||
|
@ -47,6 +48,9 @@ async function initDirs(): Promise<void> {
|
|||
if (!existsSync(mihomoTestDir())) {
|
||||
await mkdir(mihomoTestDir())
|
||||
}
|
||||
if (!existsSync(subStoreDir())) {
|
||||
await mkdir(subStoreDir())
|
||||
}
|
||||
}
|
||||
|
||||
async function initConfig(): Promise<void> {
|
||||
|
@ -79,7 +83,15 @@ async function initFiles(): Promise<void> {
|
|||
await copyFile(sourcePath, testTargrtPath)
|
||||
}
|
||||
}
|
||||
const copySubStore = async (): Promise<void> => {
|
||||
const targetPath = path.join(subStoreDir(), 'sub-store.bundle.js')
|
||||
const sourcePath = path.join(resourcesFilesDir(), 'sub-store.bundle.js')
|
||||
if (existsSync(sourcePath)) {
|
||||
await copyFile(sourcePath, targetPath)
|
||||
}
|
||||
}
|
||||
await Promise.all([
|
||||
copySubStore(),
|
||||
copy('country.mmdb'),
|
||||
copy('geoip.dat'),
|
||||
copy('geosite.dat'),
|
||||
|
@ -133,6 +145,7 @@ export async function init(): Promise<void> {
|
|||
await initFiles()
|
||||
await cleanup()
|
||||
await startPacServer()
|
||||
await startSubStoreServer()
|
||||
const { sysProxy } = await getAppConfig()
|
||||
await triggerSysProxy(sysProxy.enable)
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import {
|
|||
setOverride,
|
||||
updateOverrideItem
|
||||
} from '../config'
|
||||
import { startSubStoreServer, subStorePort } from '../resolve/server'
|
||||
import { isEncryptionAvailable, manualGrantCorePermition, restartCore } from '../core/manager'
|
||||
import { triggerSysProxy } from '../sys/sysproxy'
|
||||
import { checkUpdate, downloadAndInstallUpdate } from '../resolve/autoUpdater'
|
||||
|
@ -165,6 +166,8 @@ export function registerIpcMainHandlers(): void {
|
|||
ipcMain.handle('registerShortcut', (_e, oldShortcut, newShortcut, action) =>
|
||||
ipcErrorWrapper(registerShortcut)(oldShortcut, newShortcut, action)
|
||||
)
|
||||
ipcMain.handle('startSubStoreServer', () => ipcErrorWrapper(startSubStoreServer)())
|
||||
ipcMain.handle('subStorePort', () => subStorePort)
|
||||
ipcMain.handle('setNativeTheme', (_e, theme) => {
|
||||
setNativeTheme(theme)
|
||||
})
|
||||
|
|
83
src/renderer/src/components/base/substore-icon.tsx
Normal file
83
src/renderer/src/components/base/substore-icon.tsx
Normal file
|
@ -0,0 +1,83 @@
|
|||
import React from 'react'
|
||||
|
||||
const SubStoreIcon: React.FC = (props) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
viewBox="0 0 192 192"
|
||||
width="20"
|
||||
height="20"
|
||||
{...props}
|
||||
>
|
||||
<g stroke-width="2" fill="none" stroke-linecap="butt" stroke="#ffffff" data-c-stroke="9bf6e1">
|
||||
<path d="M 68.39 29.61 L 66.04 44.57" data-c-stroke="9cf7dc" />
|
||||
<path d="M 49.10 42.15 Q 50.32 34.82 49.38 27.02" data-c-stroke="98f3ed" />
|
||||
<path
|
||||
d="M139 26.36 139.01 40.67M56.72 151.84 56.05 166.25"
|
||||
data-c-stroke="9bf6e1"
|
||||
stroke="#ffffff"
|
||||
/>
|
||||
<path d="M 139.28 166.07 L 138.77 151.74" data-c-stroke="98f3ed" />
|
||||
<path d="M 121.23 143.44 L 119.51 159.49" data-c-stroke="9cf7dc" />
|
||||
</g>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 68.39 29.61 L 66.04 44.57 Q 58.35 38.29 49.10 42.15 Q 50.32 34.82 49.38 27.02 Q 59.70 24.72 68.39 29.61 Z"
|
||||
data-c-fill="9af5e5"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 139.00 26.36 L 139.01 40.67 Q 129.55 40.19 122.90 47.18 Q 118.96 51.31 117.05 53.18 Q 116.67 53.55 116.30 53.17 L 107.39 44.27 A 0.43 0.43 0.0 0 1 107.39 43.67 Q 110.90 40.03 114.45 36.45 C 121.01 29.80 129.51 25.72 139.00 26.36 Z"
|
||||
data-c-fill="97f2ee"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 139.00 26.36 C 149.79 27.49 158.88 35.13 163.59 44.55 C 168.66 54.70 165.55 66.43 158.45 74.97 Q 155.25 78.82 149.02 85.23 Q 148.70 85.57 148.37 85.24 L 139.73 76.60 Q 139.30 76.16 139.71 75.70 Q 142.64 72.41 146.67 67.43 Q 149.30 64.19 150.73 59.99 C 153.81 50.98 148.48 42.41 139.01 40.67 L 139.00 26.36 Z"
|
||||
data-c-fill="9ef9d3"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 49.38 27.02 Q 50.32 34.82 49.10 42.15 Q 40.00 46.95 40.92 56.52 C 41.75 65.26 47.53 69.89 53.42 75.42 A 0.48 0.47 -46.3 0 1 53.43 76.10 L 44.44 85.08 Q 44.18 85.35 43.90 85.09 C 36.16 77.74 27.62 70.06 26.59 58.80 Q 25.43 46.09 34.03 36.28 Q 40.19 29.26 49.38 27.02 Z"
|
||||
data-c-fill="95f0f5"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 66.04 44.57 L 68.39 29.61 Q 75.36 34.19 80.49 39.03 Q 90.49 48.44 105.30 63.79 Q 105.67 64.17 105.29 64.55 L 96.67 73.17 Q 96.31 73.53 95.95 73.17 Q 82.37 59.67 71.05 48.70 Q 69.90 47.58 66.04 44.57 Z"
|
||||
data-c-fill="9ef9d3"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-opacity=".961"
|
||||
d="M74.45 96.86 86.25 108.66Q86.65 109.06 86.25 109.47L77.35 118.37Q77.11 118.61 76.86 118.37L55.28 96.78Q54.82 96.33 55.27 95.87 67.38 83.29 76.25 75.52 77.32 74.58 78.33 75.59L86.23 83.48Q86.55 83.81 86.23 84.14L74.45 95.91Q73.98 96.39 74.45 96.86ZM117.92 96.06 106.07 84.21Q105.67 83.81 106.07 83.4L113.56 75.91Q114.99 74.49 116.47 75.85 127.14 85.6 137.26 96.16 137.42 96.32 137.26 96.48L115.35 118.39Q115.13 118.61 114.91 118.39L106.11 109.59Q105.58 109.06 106.11 108.53L117.92 96.72A.47.47 0 0 0 117.92 96.06Z"
|
||||
data-c-fill="ffffff"
|
||||
data-o-fill=".961"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 56.72 151.84 L 56.05 166.25 C 43.95 166.03 33.55 157.74 28.69 147.07 C 23.99 136.75 27.53 125.24 34.82 116.79 Q 38.65 112.35 43.53 107.39 Q 43.98 106.93 44.43 107.38 L 53.06 116.01 Q 53.37 116.32 53.08 116.64 C 47.94 122.46 42.28 128.07 41.22 135.90 C 39.98 145.11 47.70 152.27 56.72 151.84 Z"
|
||||
data-c-fill="9ef9d3"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 139.28 166.07 L 138.77 151.74 Q 148.28 149.97 150.90 141.99 C 152.98 135.69 150.90 128.82 146.49 124.19 Q 144.17 121.74 139.51 117.31 Q 138.89 116.72 139.50 116.10 L 148.09 107.52 Q 148.46 107.14 148.85 107.50 C 154.93 113.23 158.56 116.62 162.48 122.95 C 166.31 129.12 167.21 137.50 165.26 144.01 Q 160.45 160.01 144.46 165.22 Q 142.72 165.78 139.28 166.07 Z"
|
||||
data-c-fill="95f0f5"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 121.23 143.44 L 119.51 159.49 Q 113.86 155.23 108.76 150.22 Q 97.69 139.36 87.37 128.74 Q 86.96 128.32 87.38 127.91 L 96.15 119.13 A 0.30 0.29 44.3 0 1 96.56 119.13 L 121.23 143.44 Z"
|
||||
data-c-fill="9ef9d3"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 56.05 166.25 L 56.72 151.84 Q 62.78 151.21 66.28 148.29 Q 71.06 144.32 75.45 139.32 A 0.62 0.62 0.0 0 1 76.35 139.29 L 85.16 148.10 Q 85.45 148.40 85.18 148.71 Q 79.76 155.07 74.12 159.60 Q 66.32 165.87 56.05 166.25 Z"
|
||||
data-c-fill="97f2ee"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M 121.23 143.44 C 126.74 148.19 130.95 152.38 138.77 151.74 L 139.28 166.07 Q 128.14 166.99 119.51 159.49 L 121.23 143.44 Z"
|
||||
data-c-fill="9af5e5"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SubStoreIcon
|
|
@ -10,7 +10,8 @@ import {
|
|||
disableAutoRun,
|
||||
enableAutoRun,
|
||||
relaunchApp,
|
||||
restartCore
|
||||
restartCore,
|
||||
startSubStoreServer
|
||||
} from '@renderer/utils/ipc'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import { platform } from '@renderer/utils/init'
|
||||
|
@ -26,6 +27,7 @@ const GeneralConfig: React.FC = () => {
|
|||
showTraffic = true,
|
||||
proxyInTray = true,
|
||||
useWindowFrame = false,
|
||||
useSubStore = true,
|
||||
envType = platform === 'win32' ? 'powershell' : 'bash',
|
||||
autoCheckUpdate,
|
||||
appTheme = 'system'
|
||||
|
@ -154,6 +156,20 @@ const GeneralConfig: React.FC = () => {
|
|||
</SettingItem>
|
||||
</>
|
||||
)}
|
||||
<SettingItem title="启用SubStore" divider>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={useSubStore}
|
||||
onValueChange={async (v) => {
|
||||
try {
|
||||
await patchAppConfig({ useSubStore: v })
|
||||
if (v) await startSubStoreServer()
|
||||
} catch (e) {
|
||||
alert(e)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem title="使用系统标题栏" divider>
|
||||
<Switch
|
||||
size="sm"
|
||||
|
|
|
@ -11,7 +11,8 @@ import {
|
|||
import BasePage from '@renderer/components/base/base-page'
|
||||
import ProfileItem from '@renderer/components/profiles/profile-item'
|
||||
import { useProfileConfig } from '@renderer/hooks/use-profile-config'
|
||||
import { getFilePath, readTextFile } from '@renderer/utils/ipc'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import { getFilePath, readTextFile, subStorePort } from '@renderer/utils/ipc'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { MdContentPaste } from 'react-icons/md'
|
||||
import {
|
||||
|
@ -25,6 +26,7 @@ import {
|
|||
import { SortableContext } from '@dnd-kit/sortable'
|
||||
import { FaPlus } from 'react-icons/fa6'
|
||||
import { IoMdRefresh } from 'react-icons/io'
|
||||
import SubStoreIcon from '@renderer/components/base/substore-icon'
|
||||
|
||||
const Profiles: React.FC = () => {
|
||||
const {
|
||||
|
@ -36,6 +38,8 @@ const Profiles: React.FC = () => {
|
|||
changeCurrentProfile,
|
||||
mutateProfileConfig
|
||||
} = useProfileConfig()
|
||||
const { appConfig } = useAppConfig()
|
||||
const { useSubStore = true } = appConfig || {}
|
||||
const { current, items = [] } = profileConfig || {}
|
||||
const [sortedItems, setSortedItems] = useState(items)
|
||||
const [useProxy, setUseProxy] = useState(false)
|
||||
|
@ -221,6 +225,21 @@ const Profiles: React.FC = () => {
|
|||
<DropdownItem key="new">新建</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
{useSubStore && (
|
||||
<Button
|
||||
title="SubStore"
|
||||
onPress={async () => {
|
||||
const port = await subStorePort()
|
||||
open(`https://sub-store.vercel.app/subs?api=http://127.0.0.1:${port}`)
|
||||
}}
|
||||
className="ml-2"
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color="primary"
|
||||
>
|
||||
<SubStoreIcon />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<Divider />
|
||||
</div>
|
||||
|
|
|
@ -291,6 +291,14 @@ export async function setNativeTheme(theme: 'system' | 'light' | 'dark'): Promis
|
|||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setNativeTheme', theme))
|
||||
}
|
||||
|
||||
export async function startSubStoreServer(): Promise<void> {
|
||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('startSubStoreServer'))
|
||||
}
|
||||
|
||||
export async function subStorePort(): Promise<number> {
|
||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('subStorePort'))
|
||||
}
|
||||
|
||||
export async function openFile(
|
||||
type: 'profile' | 'override',
|
||||
id: string,
|
||||
|
|
1
src/shared/types.d.ts
vendored
1
src/shared/types.d.ts
vendored
|
@ -219,6 +219,7 @@ interface IAppConfig {
|
|||
proxyCols: 'auto' | '1' | '2' | '3' | '4'
|
||||
connectionDirection: 'asc' | 'desc'
|
||||
connectionOrderBy: 'time' | 'upload' | 'download' | 'uploadSpeed' | 'downloadSpeed'
|
||||
useSubStore?: boolean
|
||||
autoSetDNS?: boolean
|
||||
originDNS?: string
|
||||
useWindowFrame: boolean
|
||||
|
|
Loading…
Reference in New Issue
Block a user