mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 14:01:56 +08:00
167 lines
5.7 KiB
TypeScript
167 lines
5.7 KiB
TypeScript
import { observable, action, runInAction } from 'mobx'
|
|
import * as yaml from 'yaml'
|
|
import * as Models from '@models'
|
|
import { jsBridge } from '@lib/jsBridge'
|
|
import * as API from '@lib/request'
|
|
import { getLocalStorageItem, partition } from '@lib/helper'
|
|
|
|
export class ConfigStore {
|
|
|
|
@observable
|
|
config: Models.Config = {
|
|
proxy: [],
|
|
proxyGroup: [],
|
|
rules: []
|
|
}
|
|
|
|
@observable
|
|
data: Models.Data = {
|
|
general: {},
|
|
proxy: [],
|
|
proxyGroup: [],
|
|
rules: []
|
|
}
|
|
|
|
@action
|
|
async fetchData () {
|
|
const [{ data: general }, rawProxies, rules] = await Promise.all([API.getConfig(), API.getProxies(), API.getRules()])
|
|
|
|
runInAction(() => {
|
|
this.data.general = {
|
|
port: general.port,
|
|
socksPort: general['socket-port'],
|
|
redirPort: general['redir-port'],
|
|
mode: general.mode,
|
|
logLevel: general['log-level']
|
|
}
|
|
|
|
const policyGroup = new Set(['Selector', 'URLTest', 'Fallback'])
|
|
const unUsedProxy = new Set(['DIRECT', 'REJECT', 'GLOBAL'])
|
|
const proxies = Object.keys(rawProxies.data.proxies)
|
|
.filter(key => !unUsedProxy.has(key))
|
|
.map(key => ({ ...rawProxies.data.proxies[key], name: key }))
|
|
const [proxy, groups] = partition(proxies, proxy => !policyGroup.has(proxy.type))
|
|
this.data.proxy = proxy as API.Proxy[]
|
|
this.data.proxyGroup = groups as API.Group[]
|
|
|
|
this.data.rules = rules.data.rules
|
|
})
|
|
}
|
|
|
|
@action
|
|
async fetchAndParseConfig () {
|
|
const rawConfig = await jsBridge.readConfigString()
|
|
|
|
runInAction(() => {
|
|
// emit error when config is empty
|
|
// because read config might be error
|
|
if (!rawConfig) {
|
|
return
|
|
}
|
|
|
|
// otherwise parse ini
|
|
const config = yaml.parse(rawConfig)
|
|
const externalController = config['external-controller'] as string || ''
|
|
const host = externalController.split(':')
|
|
|
|
const proxies = config.Proxy as any[] || []
|
|
const proxy: Models.Proxy[] = proxies
|
|
.filter(p => ['vmess', 'ss', 'socks5'].includes(p.type))
|
|
|
|
const proxyGroups = config['Proxy Group'] as any[] || []
|
|
const proxyGroup: Models.ProxyGroup[] = proxyGroups
|
|
.filter(p => ['url-test', 'select', 'fallback'].includes(p.type))
|
|
const rules = config['Rule'] as any[] || []
|
|
const rule: Models.Rule[] = rules.map(r => r.split(',')).filter(r => r.length >= 3).map(r => ({
|
|
type: Models.RuleType[r[0] as string],
|
|
payload: r[1],
|
|
proxy: r[2]
|
|
}))
|
|
this.config = {
|
|
general: {
|
|
port: config.port || 0,
|
|
socksPort: config['socks-port'] || 0,
|
|
redirPort: config['redir-port'] || 0,
|
|
allowLan: config['allow-lan'] || false,
|
|
externalControllerAddr: host[0] || '',
|
|
externalControllerPort: host[1] || '',
|
|
secret: config.secret || '',
|
|
logLevel: config['log-level'] || 'info',
|
|
mode: config.mode || 'Rule'
|
|
},
|
|
proxy,
|
|
proxyGroup,
|
|
rules: rule || []
|
|
}
|
|
})
|
|
}
|
|
|
|
@action
|
|
async fetchConfig () {
|
|
const { data: config } = await API.getConfig()
|
|
this.config = {
|
|
general: {
|
|
port: config.port,
|
|
socksPort: config['socket-port'],
|
|
redirPort: config['redir-port'],
|
|
allowLan: config['allow-lan'],
|
|
mode: config.mode,
|
|
externalControllerAddr: getLocalStorageItem('externalControllerAddr', '127.0.0.1'),
|
|
externalControllerPort: getLocalStorageItem('externalControllerPort', '8080'),
|
|
secret: getLocalStorageItem('secret', '')
|
|
}
|
|
}
|
|
}
|
|
|
|
@action
|
|
async updateConfig () {
|
|
const { general, proxy, proxyGroup, rules } = this.config
|
|
const externalController = `${general.externalControllerAddr}:${general.externalControllerPort}`
|
|
const Rule = rules.map(r => [r.type, r.payload, r.proxy].join(','))
|
|
const config = {
|
|
'external-controller': externalController,
|
|
port: general.port,
|
|
'socks-port': general.socksPort,
|
|
'redir-port': general.redirPort,
|
|
'allow-lan': general.allowLan,
|
|
secret: general.secret,
|
|
'log-level': general.logLevel,
|
|
mode: general.mode,
|
|
Proxy: proxy,
|
|
'Proxy Group': proxyGroup,
|
|
Rule
|
|
}
|
|
const data = yaml.stringify(config)
|
|
// console.log(data)
|
|
jsBridge.writeConfigWithString(data)
|
|
}
|
|
|
|
@action
|
|
async modifyProxyByIndexAndSave (index: number, config: Models.Proxy) {
|
|
const { proxy } = this.config
|
|
const fomatedConfig: Models.Proxy = {}
|
|
const { type } = config
|
|
let configList: string[] = []
|
|
|
|
switch (type) {
|
|
case 'ss':
|
|
configList = Models.SsProxyConfigList
|
|
break
|
|
case 'vmess':
|
|
configList = Models.VmessProxyConfigList
|
|
break
|
|
case 'socks5':
|
|
configList = Models.Socks5ProxyConfigList
|
|
break
|
|
}
|
|
|
|
for (const configKey of configList) {
|
|
fomatedConfig[configKey] = config[configKey]
|
|
}
|
|
|
|
proxy[index] = fomatedConfig
|
|
await this.updateConfig()
|
|
await this.fetchAndParseConfig()
|
|
}
|
|
}
|