/* 触发器 手动触发 */ const onRun = async () => { showUI() } /* 触发器 APP就绪后 */ const onReady = async () => { const appStore = Plugins.useAppStore() appStore.addCustomActions('profiles_header', { id: Plugin.id, component: 'Button', componentProps: { type: 'link', onClick: showUI }, componentSlots: { default: '快速配置向导' } }) } const showUI = () => { const { h, ref, watch, computed, resolveComponent } = Vue const currentStep = ref(0) const isDirectIPv6Enabled = ref(false) const isProxyIPv6Enabled = ref(false) const isAllowLanEnabled = ref(false) const lanPort = ref() const isTUNEnabled = ref(false) const isFakeIPEnabled = ref(false) const isBanQUICEnabled = ref(true) const name = ref(Plugins.sampleID()) const subsMap = ref({}) const subsRef = ref([]) const isSupportIPv6 = ref() watch(currentStep, async (step) => { if (step === 1) { isSupportIPv6.value = undefined isSupportIPv6.value = await checkIPv6Support() } }) const component = { template: `
欢迎使用快速配置向导

此向导可帮你生成一份不会出错的配置。开始前请:

  • 关闭所有代理软件(避免影响IPv6判断)
  • 开启路由器及本机的IPv6协议栈(避免影响IPv6判断)
  • 如果你禁用过Windows的智能多宿主DNS解析,请还原(避免影响TUN模式)
直连网站是否需要IPv6?
正在检测你的网络环境... 提示:你的网络环境已支持IPv6,推荐开启!访问国内网站能获得更好的效果! 提示:你的网络环境不支持IPv6,建议关闭!强行开启会导致部分网站无法访问!
代理网站是否需要IPv6?
如果你是自建用户,且节点支持IPv6,请选择需要;如果你是机场用户,节点通常不支持IPv6,请选择不需要。
是否需要代理局域网设备?
通常情况下你无需开启此项
是否需要开启TUN模式?
开启后,会新建一张虚拟网卡,所有软件的流量将通过核心进行转发

注意事项

  • Windows下启用TUN模式需要管理员权限,Linux/MacOS下需要到设置-内核页进行手动授权(每次更新核心后均需要重新手动授权)。
  • MacOS下需要前往系统网络设置,将系统DNS修改为公网IP,例如8.8.8.8,以便核心劫持DNS请求。
  • 如果遇到网络不通,请尝试更换不同的TUN堆栈模式。
是否需要开启Fake-IP模式?
开启后,部分网站的DNS查询将返回虚假的IP。(通常对需要代理的网站返回fake-ip)
是否需要禁用QUIC?
部分网站会使用QUIC协议,这通常会影响访问代理网站的速度
现在,为此配置引用一个或多个订阅?

点击下方+号,左侧填写订阅名称,右侧填写订阅链接。或者,稍后再说~

如果你打算引用多个订阅,这些订阅中可能包含相同名称的节点,造成核心启动失败。但你可以在插件中心找到解决方案。

`, setup() { const subscribeStore = Plugins.useSubscribesStore() const subs = computed(() => subscribeStore.subscribes.map((v) => ({ name: v.name, id: v.id }))) return { currentStep, isSupportIPv6, isDirectIPv6Enabled, isProxyIPv6Enabled, isAllowLanEnabled, lanPort, isTUNEnabled, isFakeIPEnabled, isBanQUICEnabled, subsMap, subsRef, subs, name, toggleSubRef(sub) { const idx = subsRef.value.indexOf(sub) if (idx === -1) { subsRef.value.push(sub) } else { subsRef.value.splice(idx, 1) } } } } } const modal = Plugins.modal( { title: Plugin.name, width: '90', height: '90', maskClosable: true, submitText: '完成', afterClose() { modal.destroy() }, async onOk() { const profilesStore = Plugins.useProfilesStore() const subscribeStore = Plugins.useSubscribesStore() // 1、导入订阅 const subIds = [] for (const [name, url] of Object.entries(subsMap.value)) { const sub = subscribeStore.getSubscribeTemplate(name, { url }) await subscribeStore.addSubscribe(sub) await Plugins.sleep(1000) subIds.push({ name, id: sub.id }) } // 2、导入配置 const profile = profilesStore.getProfileTemplate(name.value) ;[...subIds, ...subsRef.value].forEach(({ name, id }) => { if (Plugins.APP_TITLE.includes('SingBox')) { profile.outbounds[0].outbounds.push({ id: id, tag: name, type: 'Subscription' }) profile.outbounds[1].outbounds.push({ id: id, tag: name, type: 'Subscription' }) } else if (Plugins.APP_TITLE.includes('Clash')) { profile.proxyGroupsConfig[0].use.push(id) profile.proxyGroupsConfig[1].use.push(id) } }) // 3、个性化配置 personalizeProfile(profile, { isDirectIPv6Enabled: isDirectIPv6Enabled.value, isProxyIPv6Enabled: isProxyIPv6Enabled.value, isAllowLanEnabled: isAllowLanEnabled.value, lanPort: lanPort.value, isTUNEnabled: isTUNEnabled.value, isFakeIPEnabled: isFakeIPEnabled.value, isBanQUICEnabled: isBanQUICEnabled.value }) await profilesStore.addProfile(profile) Plugins.message.success('完事~') } }, { default: () => h(component), action: () => h('div', { class: 'mr-auto' }, [ h( resolveComponent('Button'), { type: 'text', disabled: currentStep.value < 1, onClick: () => (currentStep.value -= 1) }, () => '上一步' ), h( resolveComponent('Button'), { type: 'text', disabled: currentStep.value >= 7, onClick: () => (currentStep.value += 1) }, () => '下一步' ) ]) } ) modal.open() } const getRandomUA = () => { const userAgents = [ 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0', 'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10' ] return userAgents[Math.floor(Math.random() * userAgents.length)] } const checkIPv6Support = async () => { try { const { status } = await Plugins.HttpGet('https://ipv6.lookup.test-ipv6.com/ip/', { 'User-Agent': getRandomUA() }) return status === 200 } catch (error) { console.log(`[${Plugin.name}]`, '检测IPv6失败', error) return false } } const personalizeProfile = async (profile, options) => { if (Plugins.APP_TITLE.includes('SingBox')) { if (options.isDirectIPv6Enabled) { profile.dns.rules[0].strategy = 'prefer_ipv6' profile.dns.rules[3].strategy = 'prefer_ipv6' } else { profile.dns.rules[0].strategy = 'ipv4_only' profile.dns.rules[3].strategy = 'ipv4_only' profile.inbounds[1].tun.address.pop() } if (options.isProxyIPv6Enabled) { profile.dns.strategy = 'prefer_ipv6' profile.dns.rules[1].strategy = 'prefer_ipv6' profile.dns.rules[4].strategy = 'prefer_ipv6' profile.dns.rules[5].strategy = 'prefer_ipv6' } else { profile.dns.strategy = 'ipv4_only' profile.dns.rules[1].strategy = 'ipv4_only' profile.dns.rules[4].strategy = 'ipv4_only' profile.dns.rules[5].strategy = 'ipv4_only' } profile.inbounds[0].mixed.listen.listen = options.isAllowLanEnabled ? '0.0.0.0' : '127.0.0.1' if (options.lanPort) { profile.inbounds[0].mixed.listen.listen_port = Number(options.lanPort) } profile.inbounds[1].enable = options.isTUNEnabled profile.dns.rules[4].enable = options.isFakeIPEnabled profile.route.rules[6].enable = options.isBanQUICEnabled } else if (Plugins.APP_TITLE.includes('Clash')) { profile.generalConfig.ipv6 = options.isDirectIPv6Enabled || options.isProxyIPv6Enabled profile.dnsConfig.ipv6 = options.isDirectIPv6Enabled || options.isProxyIPv6Enabled if (!options.isDirectIPv6Enabled) { profile.dnsConfig['nameserver-policy']['rule-set:GEOSITE-CN'] += '&disable-ipv6=true' } if (!options.isProxyIPv6Enabled) { profile.dnsConfig['nameserver-policy']['rule-set:geolocation-!cn'] += '&disable-ipv6=true' } profile.generalConfig['allow-lan'] = options.isAllowLanEnabled if (options.lanPort) { profile.generalConfig['mixed-port'] = Number(options.lanPort) } profile.tunConfig.enable = options.isTUNEnabled if (options.isFakeIPEnabled) { profile.dnsConfig['enhanced-mode'] = 'fake-ip' profile.dnsConfig.nameserver = ['https://223.5.5.5/dns-query#' + profile.proxyGroupsConfig[2].name] profile.dnsConfig['fake-ip-filter'].push('rule-set:GEOSITE-CN') } profile.rulesConfig[1].enable = options.isBanQUICEnabled } }