mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 05:00:30 +08:00
geo data config
This commit is contained in:
parent
afaeea2aac
commit
db6804e25a
@ -238,8 +238,8 @@ async function downloadFile(url, path) {
|
|||||||
|
|
||||||
const resolveMmdb = () =>
|
const resolveMmdb = () =>
|
||||||
resolveResource({
|
resolveResource({
|
||||||
file: 'Country.mmdb',
|
file: 'country.mmdb',
|
||||||
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb`
|
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb`
|
||||||
})
|
})
|
||||||
const resolveGeosite = () =>
|
const resolveGeosite = () =>
|
||||||
resolveResource({
|
resolveResource({
|
||||||
@ -249,7 +249,12 @@ const resolveGeosite = () =>
|
|||||||
const resolveGeoIP = () =>
|
const resolveGeoIP = () =>
|
||||||
resolveResource({
|
resolveResource({
|
||||||
file: 'geoip.dat',
|
file: 'geoip.dat',
|
||||||
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat`
|
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat`
|
||||||
|
})
|
||||||
|
const resolveASN = () =>
|
||||||
|
resolveResource({
|
||||||
|
file: 'ASN.mmdb',
|
||||||
|
downloadURL: `https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb`
|
||||||
})
|
})
|
||||||
const resolveEnableLoopback = () =>
|
const resolveEnableLoopback = () =>
|
||||||
resolveResource({
|
resolveResource({
|
||||||
@ -285,6 +290,7 @@ const tasks = [
|
|||||||
{ name: 'mmdb', func: resolveMmdb, retry: 5 },
|
{ name: 'mmdb', func: resolveMmdb, retry: 5 },
|
||||||
{ name: 'geosite', func: resolveGeosite, retry: 5 },
|
{ name: 'geosite', func: resolveGeosite, retry: 5 },
|
||||||
{ name: 'geoip', func: resolveGeoIP, retry: 5 },
|
{ name: 'geoip', func: resolveGeoIP, retry: 5 },
|
||||||
|
{ name: 'asn', func: resolveASN, retry: 5 },
|
||||||
{
|
{
|
||||||
name: 'font',
|
name: 'font',
|
||||||
func: resolveFont,
|
func: resolveFont,
|
||||||
|
|||||||
@ -85,6 +85,13 @@ export const mihomoChangeProxy = async (group: string, proxy: string): Promise<I
|
|||||||
})) as IMihomoProxy
|
})) as IMihomoProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const mihomoUpgradeGeo = async (): Promise<void> => {
|
||||||
|
const instance = await getAxios()
|
||||||
|
return instance.post('/configs/geo').catch((e) => {
|
||||||
|
return e.response.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const mihomoProxyDelay = async (proxy: string, url?: string): Promise<IMihomoDelay> => {
|
export const mihomoProxyDelay = async (proxy: string, url?: string): Promise<IMihomoDelay> => {
|
||||||
const appConfig = getAppConfig()
|
const appConfig = getAppConfig()
|
||||||
const { delayTestUrl, delayTestTimeout } = appConfig
|
const { delayTestUrl, delayTestTimeout } = appConfig
|
||||||
|
|||||||
@ -58,7 +58,7 @@ function initConfig(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initFiles(): void {
|
function initFiles(): void {
|
||||||
const fileList = ['Country.mmdb', 'geoip.dat', 'geosite.dat']
|
const fileList = ['country.mmdb', 'geoip.dat', 'geosite.dat', 'ASN.mmdb']
|
||||||
for (const file of fileList) {
|
for (const file of fileList) {
|
||||||
const targetPath = path.join(mihomoWorkDir(), file)
|
const targetPath = path.join(mihomoWorkDir(), file)
|
||||||
const testTargrtPath = path.join(mihomoTestDir(), file)
|
const testTargrtPath = path.join(mihomoTestDir(), file)
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
mihomoProxies,
|
mihomoProxies,
|
||||||
mihomoProxyDelay,
|
mihomoProxyDelay,
|
||||||
mihomoRules,
|
mihomoRules,
|
||||||
|
mihomoUpgradeGeo,
|
||||||
mihomoVersion,
|
mihomoVersion,
|
||||||
patchMihomoConfig,
|
patchMihomoConfig,
|
||||||
startMihomoConnections,
|
startMihomoConnections,
|
||||||
@ -34,6 +35,7 @@ import { triggerSysProxy } from '../resolve/sysproxy'
|
|||||||
import { checkUpdate } from '../resolve/autoUpdater'
|
import { checkUpdate } from '../resolve/autoUpdater'
|
||||||
import { exePath, mihomoCorePath, mihomoWorkConfigPath } from './dirs'
|
import { exePath, mihomoCorePath, mihomoWorkConfigPath } from './dirs'
|
||||||
import { execSync } from 'child_process'
|
import { execSync } from 'child_process'
|
||||||
|
import yaml from 'yaml'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
|
||||||
export function registerIpcMainHandlers(): void {
|
export function registerIpcMainHandlers(): void {
|
||||||
@ -43,6 +45,7 @@ export function registerIpcMainHandlers(): void {
|
|||||||
ipcMain.handle('mihomoRules', mihomoRules)
|
ipcMain.handle('mihomoRules', mihomoRules)
|
||||||
ipcMain.handle('mihomoProxies', mihomoProxies)
|
ipcMain.handle('mihomoProxies', mihomoProxies)
|
||||||
ipcMain.handle('mihomoChangeProxy', (_e, group, proxy) => mihomoChangeProxy(group, proxy))
|
ipcMain.handle('mihomoChangeProxy', (_e, group, proxy) => mihomoChangeProxy(group, proxy))
|
||||||
|
ipcMain.handle('mihomoUpgradeGeo', mihomoUpgradeGeo)
|
||||||
ipcMain.handle('mihomoProxyDelay', (_e, proxy, url) => mihomoProxyDelay(proxy, url))
|
ipcMain.handle('mihomoProxyDelay', (_e, proxy, url) => mihomoProxyDelay(proxy, url))
|
||||||
ipcMain.handle('startMihomoLogs', startMihomoLogs)
|
ipcMain.handle('startMihomoLogs', startMihomoLogs)
|
||||||
ipcMain.handle('stopMihomoLogs', stopMihomoLogs)
|
ipcMain.handle('stopMihomoLogs', stopMihomoLogs)
|
||||||
@ -71,6 +74,7 @@ export function registerIpcMainHandlers(): void {
|
|||||||
ipcMain.handle('encryptString', (_e, str) => safeStorage.encryptString(str))
|
ipcMain.handle('encryptString', (_e, str) => safeStorage.encryptString(str))
|
||||||
ipcMain.handle('getFilePath', getFilePath)
|
ipcMain.handle('getFilePath', getFilePath)
|
||||||
ipcMain.handle('readTextFile', (_e, filePath) => readTextFile(filePath))
|
ipcMain.handle('readTextFile', (_e, filePath) => readTextFile(filePath))
|
||||||
|
ipcMain.handle('getRuntimeConfigStr', getRuntimeConfigStr)
|
||||||
ipcMain.handle('getRuntimeConfig', getRuntimeConfig)
|
ipcMain.handle('getRuntimeConfig', getRuntimeConfig)
|
||||||
ipcMain.handle('checkUpdate', () => checkUpdate())
|
ipcMain.handle('checkUpdate', () => checkUpdate())
|
||||||
ipcMain.handle('getVersion', () => app.getVersion())
|
ipcMain.handle('getVersion', () => app.getVersion())
|
||||||
@ -91,10 +95,14 @@ function readTextFile(filePath: string): string {
|
|||||||
return fs.readFileSync(filePath, 'utf8')
|
return fs.readFileSync(filePath, 'utf8')
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRuntimeConfig(): string {
|
function getRuntimeConfigStr(): string {
|
||||||
return fs.readFileSync(mihomoWorkConfigPath(), 'utf8')
|
return fs.readFileSync(mihomoWorkConfigPath(), 'utf8')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRuntimeConfig(): Record<string, unknown> {
|
||||||
|
return yaml.parse(getRuntimeConfigStr())
|
||||||
|
}
|
||||||
|
|
||||||
async function setupFirewall(): Promise<void> {
|
async function setupFirewall(): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const removeCommand = `
|
const removeCommand = `
|
||||||
|
|||||||
@ -58,6 +58,15 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
'skip-domain': ['+.push.apple.com']
|
'skip-domain': ['+.push.apple.com']
|
||||||
|
},
|
||||||
|
'geo-auto-update': false,
|
||||||
|
'geo-update-interval': 24,
|
||||||
|
'geodata-mode': false,
|
||||||
|
'geox-url': {
|
||||||
|
geoip: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat',
|
||||||
|
geosite: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
|
||||||
|
mmdb: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb',
|
||||||
|
asn: 'https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,9 +15,9 @@ import SniffCard from '@renderer/components/sider/sniff-card'
|
|||||||
import OverrideCard from '@renderer/components/sider/override-card'
|
import OverrideCard from '@renderer/components/sider/override-card'
|
||||||
import ConnCard from '@renderer/components/sider/conn-card'
|
import ConnCard from '@renderer/components/sider/conn-card'
|
||||||
import LogCard from '@renderer/components/sider/log-card'
|
import LogCard from '@renderer/components/sider/log-card'
|
||||||
import MihomoCoreCard from './components/sider/mihomo-core-card.tsx'
|
import MihomoCoreCard from '@renderer/components/sider/mihomo-core-card'
|
||||||
import TestCard from './components/sider/test-card.js'
|
import ResourceCard from '@renderer/components/sider/resource-card'
|
||||||
import UpdaterButton from './components/updater/updater-button.js'
|
import UpdaterButton from '@renderer/components/updater/updater-button'
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const { setTheme } = useTheme()
|
const { setTheme } = useTheme()
|
||||||
@ -63,9 +63,24 @@ const App: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="m-2">
|
<div className="m-2">
|
||||||
<OutboundModeSwitcher />
|
<OutboundModeSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
{/* <div className="grid">
|
||||||
|
<SysproxySwitcher />
|
||||||
|
<TunSwitcher />
|
||||||
|
<ProfileCard />
|
||||||
|
<ProxyCard />
|
||||||
|
<MihomoCoreCard />
|
||||||
|
<ConnCard />
|
||||||
|
<DNSCard />
|
||||||
|
<SniffCard />
|
||||||
|
<LogCard />
|
||||||
|
<RuleCard />
|
||||||
|
<TestCard />
|
||||||
|
<OverrideCard />
|
||||||
|
</div> */}
|
||||||
<div className="flex justify-between mx-2 mb-2">
|
<div className="flex justify-between mx-2 mb-2">
|
||||||
<SysproxySwitcher />
|
<SysproxySwitcher />
|
||||||
<TunSwitcher />
|
<TunSwitcher />
|
||||||
@ -86,7 +101,7 @@ const App: React.FC = () => {
|
|||||||
<RuleCard />
|
<RuleCard />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between mx-2">
|
<div className="flex justify-between mx-2">
|
||||||
<TestCard />
|
<ResourceCard />
|
||||||
<OverrideCard />
|
<OverrideCard />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import MonacoEditor, { monaco } from 'react-monaco-editor'
|
import MonacoEditor, { monaco } from 'react-monaco-editor'
|
||||||
import { useTheme } from 'next-themes'
|
import { useTheme } from 'next-themes'
|
||||||
import { getRuntimeConfig } from '@renderer/utils/ipc'
|
import { getRuntimeConfigStr } from '@renderer/utils/ipc'
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ const ConfigViewer: React.FC<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getContent = async (): Promise<void> => {
|
const getContent = async (): Promise<void> => {
|
||||||
setCurrData(await getRuntimeConfig())
|
setCurrData(await getRuntimeConfigStr())
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -46,7 +46,7 @@ const ProfileCard: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{info?.name}
|
{info?.name}
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div className="flex">
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { TbWorldCheck } from 'react-icons/tb'
|
import { FaLayerGroup } from 'react-icons/fa6'
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
const TestCard: React.FC = () => {
|
const ResourceCard: React.FC = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const match = location.pathname.includes('/tests')
|
const match = location.pathname.includes('/resources')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
className={`w-[50%] mr-1 mb-2 ${match ? 'bg-primary' : ''}`}
|
className={`w-[50%] mr-1 mb-2 ${match ? 'bg-primary' : ''}`}
|
||||||
isPressable
|
isPressable
|
||||||
onPress={() => navigate('/tests')}
|
onPress={() => navigate('/resources')}
|
||||||
>
|
>
|
||||||
<CardBody className="pb-1 pt-0 px-0">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
@ -22,7 +22,7 @@ const TestCard: React.FC = () => {
|
|||||||
variant="flat"
|
variant="flat"
|
||||||
color="default"
|
color="default"
|
||||||
>
|
>
|
||||||
<TbWorldCheck
|
<FaLayerGroup
|
||||||
color="default"
|
color="default"
|
||||||
className={`${match ? 'text-white' : 'text-foreground'} text-[24px] font-bold`}
|
className={`${match ? 'text-white' : 'text-foreground'} text-[24px] font-bold`}
|
||||||
/>
|
/>
|
||||||
@ -31,11 +31,11 @@ const TestCard: React.FC = () => {
|
|||||||
</CardBody>
|
</CardBody>
|
||||||
<CardFooter className="pt-1">
|
<CardFooter className="pt-1">
|
||||||
<h3 className={`select-none text-md font-bold ${match ? 'text-white' : 'text-foreground'}`}>
|
<h3 className={`select-none text-md font-bold ${match ? 'text-white' : 'text-foreground'}`}>
|
||||||
测试
|
外部资源
|
||||||
</h3>
|
</h3>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TestCard
|
export default ResourceCard
|
||||||
163
src/renderer/src/pages/resources.tsx
Normal file
163
src/renderer/src/pages/resources.tsx
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
import { Button, Input, Switch, Tab, Tabs } from '@nextui-org/react'
|
||||||
|
import BasePage from '@renderer/components/base/base-page'
|
||||||
|
import SettingCard from '@renderer/components/base/base-setting-card'
|
||||||
|
import SettingItem from '@renderer/components/base/base-setting-item'
|
||||||
|
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||||
|
import { mihomoUpgradeGeo } from '@renderer/utils/ipc'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { IoMdRefresh } from 'react-icons/io'
|
||||||
|
|
||||||
|
const Resources: React.FC = () => {
|
||||||
|
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||||
|
const {
|
||||||
|
'geox-url': geoxUrl = {
|
||||||
|
geoip: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat',
|
||||||
|
geosite: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
|
||||||
|
mmdb: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb',
|
||||||
|
asn: 'https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb'
|
||||||
|
},
|
||||||
|
'geodata-mode': geoMode = false,
|
||||||
|
'geo-auto-update': geoAutoUpdate = false,
|
||||||
|
'geo-update-interval': geoUpdateInterval = 24
|
||||||
|
} = controledMihomoConfig || {}
|
||||||
|
const [geoipInput, setGeoIpInput] = useState(geoxUrl.geoip)
|
||||||
|
const [geositeInput, setGeositeInput] = useState(geoxUrl.geosite)
|
||||||
|
const [mmdbInput, setMmdbInput] = useState(geoxUrl.mmdb)
|
||||||
|
const [asnInput, setAsnInput] = useState(geoxUrl.asn)
|
||||||
|
const [updating, setUpdating] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BasePage title="外部资源">
|
||||||
|
<SettingCard>
|
||||||
|
<SettingItem title="GeoIP 数据库" divider>
|
||||||
|
<div className="flex">
|
||||||
|
{geoipInput !== geoxUrl.geoip && (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="primary"
|
||||||
|
className="mr-2"
|
||||||
|
onPress={() => {
|
||||||
|
patchControledMihomoConfig({ 'geox-url': { ...geoxUrl, geoip: geoipInput } })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Input size="sm" value={geoipInput} onValueChange={setGeoIpInput} />
|
||||||
|
</div>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem title="GeoSite 数据库" divider>
|
||||||
|
<div className="flex">
|
||||||
|
{geositeInput !== geoxUrl.geosite && (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="primary"
|
||||||
|
className="mr-2"
|
||||||
|
onPress={() => {
|
||||||
|
patchControledMihomoConfig({ 'geox-url': { ...geoxUrl, geosite: geositeInput } })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Input size="sm" value={geositeInput} onValueChange={setGeositeInput} />
|
||||||
|
</div>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem title="MMDB 数据库" divider>
|
||||||
|
<div className="flex">
|
||||||
|
{mmdbInput !== geoxUrl.mmdb && (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="primary"
|
||||||
|
className="mr-2"
|
||||||
|
onPress={() => {
|
||||||
|
patchControledMihomoConfig({ 'geox-url': { ...geoxUrl, mmdb: mmdbInput } })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Input size="sm" value={mmdbInput} onValueChange={setMmdbInput} />
|
||||||
|
</div>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem title="ASN 数据库" divider>
|
||||||
|
<div className="flex">
|
||||||
|
{asnInput !== geoxUrl.asn && (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="primary"
|
||||||
|
className="mr-2"
|
||||||
|
onPress={() => {
|
||||||
|
patchControledMihomoConfig({ 'geox-url': { ...geoxUrl, asn: asnInput } })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Input size="sm" value={asnInput} onValueChange={setAsnInput} />
|
||||||
|
</div>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem title="GeoIP 数据模式" divider>
|
||||||
|
<Tabs
|
||||||
|
size="sm"
|
||||||
|
color="primary"
|
||||||
|
selectedKey={geoMode ? 'dat' : 'db'}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
patchControledMihomoConfig({ 'geodata-mode': key === 'dat' })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tab key="db" title="db" />
|
||||||
|
<Tab key="dat" title="dat" />
|
||||||
|
</Tabs>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem
|
||||||
|
title="自动更新 Geo 数据库"
|
||||||
|
actions={
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
isIconOnly
|
||||||
|
variant="light"
|
||||||
|
onPress={() => {
|
||||||
|
setUpdating(true)
|
||||||
|
mihomoUpgradeGeo()
|
||||||
|
.catch((e) => {
|
||||||
|
new Notification('更新失败', { body: e.message })
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
new Notification('Geo 数据库更新成功')
|
||||||
|
setUpdating(false)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IoMdRefresh className={`text-lg ${updating ? 'animate-spin' : ''}`} />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
divider={geoAutoUpdate}
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
size="sm"
|
||||||
|
isSelected={geoAutoUpdate}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
patchControledMihomoConfig({ 'geo-auto-update': v })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
|
{geoAutoUpdate && (
|
||||||
|
<SettingItem title="更新间隔(小时)">
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
type="number"
|
||||||
|
className="w-[100px]"
|
||||||
|
value={geoUpdateInterval.toString()}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
patchControledMihomoConfig({ 'geo-update-interval': parseInt(v) })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
|
)}
|
||||||
|
</SettingCard>
|
||||||
|
</BasePage>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Resources
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import BasePage from '@renderer/components/base/base-page'
|
|
||||||
|
|
||||||
const Tests: React.FC = () => {
|
|
||||||
return <BasePage title="测试"></BasePage>
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Tests
|
|
||||||
@ -9,7 +9,7 @@ import Connections from '@renderer/pages/connections'
|
|||||||
import Mihomo from '@renderer/pages/mihomo'
|
import Mihomo from '@renderer/pages/mihomo'
|
||||||
import Sysproxy from '@renderer/pages/syspeoxy'
|
import Sysproxy from '@renderer/pages/syspeoxy'
|
||||||
import Tun from '@renderer/pages/tun'
|
import Tun from '@renderer/pages/tun'
|
||||||
import Tests from '@renderer/pages/tests'
|
import Resources from '@renderer/pages/resources'
|
||||||
import DNS from '@renderer/pages/dns'
|
import DNS from '@renderer/pages/dns'
|
||||||
import Sniffer from '@renderer/pages/sniffer'
|
import Sniffer from '@renderer/pages/sniffer'
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ const routes = [
|
|||||||
element: <Rules />
|
element: <Rules />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tests',
|
path: '/resources',
|
||||||
element: <Tests />
|
element: <Resources />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/dns',
|
path: '/dns',
|
||||||
|
|||||||
@ -22,6 +22,10 @@ export async function mihomoChangeProxy(group: string, proxy: string): Promise<I
|
|||||||
return await window.electron.ipcRenderer.invoke('mihomoChangeProxy', group, proxy)
|
return await window.electron.ipcRenderer.invoke('mihomoChangeProxy', group, proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function mihomoUpgradeGeo(): Promise<void> {
|
||||||
|
return await window.electron.ipcRenderer.invoke('mihomoUpgradeGeo')
|
||||||
|
}
|
||||||
|
|
||||||
export async function mihomoProxyDelay(proxy: string, url?: string): Promise<IMihomoDelay> {
|
export async function mihomoProxyDelay(proxy: string, url?: string): Promise<IMihomoDelay> {
|
||||||
const res = await window.electron.ipcRenderer.invoke('mihomoProxyDelay', proxy, url)
|
const res = await window.electron.ipcRenderer.invoke('mihomoProxyDelay', proxy, url)
|
||||||
return res
|
return res
|
||||||
@ -135,7 +139,11 @@ export async function readTextFile(filePath: string): Promise<string> {
|
|||||||
return await window.electron.ipcRenderer.invoke('readTextFile', filePath)
|
return await window.electron.ipcRenderer.invoke('readTextFile', filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRuntimeConfig(): Promise<string> {
|
export async function getRuntimeConfigStr(): Promise<string> {
|
||||||
|
return await window.electron.ipcRenderer.invoke('getRuntimeConfigStr')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getRuntimeConfig(): Promise<IMihomoConfig> {
|
||||||
return await window.electron.ipcRenderer.invoke('getRuntimeConfig')
|
return await window.electron.ipcRenderer.invoke('getRuntimeConfig')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
src/shared/types.d.ts
vendored
9
src/shared/types.d.ts
vendored
@ -246,6 +246,15 @@ interface IMihomoConfig {
|
|||||||
'proxy-groups'?: []
|
'proxy-groups'?: []
|
||||||
rules?: []
|
rules?: []
|
||||||
hosts?: { [key: string]: string | string[] }
|
hosts?: { [key: string]: string | string[] }
|
||||||
|
'geodata-mode'?: boolean
|
||||||
|
'geo-auto-update'?: boolean
|
||||||
|
'geo-update-interval'?: number
|
||||||
|
'geox-url'?: {
|
||||||
|
geoip?: string
|
||||||
|
geosite?: string
|
||||||
|
mmdb?: string
|
||||||
|
asn?: string
|
||||||
|
}
|
||||||
tun: IMihomoTunConfig
|
tun: IMihomoTunConfig
|
||||||
dns: IMihomoDNSConfig
|
dns: IMihomoDNSConfig
|
||||||
sniffer: IMihomoSnifferConfig
|
sniffer: IMihomoSnifferConfig
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user