adjustments for singbox 1.11.0

This commit is contained in:
Alireza Ahmadi
2025-01-06 15:49:43 +01:00
parent 2d8b56208d
commit d53d9b80f5
18 changed files with 347 additions and 139 deletions
-39
View File
@@ -29,24 +29,6 @@
v-model="inbound.detour">
</v-select>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-switch v-model="inbound.sniff" color="primary" :label="$t('listen.sniffing')" hide-details></v-switch>
</v-col>
</v-row>
<v-row v-if="inbound.sniff">
<v-col cols="12" sm="6" md="4">
<v-switch v-model="inbound.sniff_override_destination" color="primary" :label="$t('listen.sniffingOverride')" hide-details></v-switch>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
:label="$t('listen.sniffingTimeout')"
hide-details
type="number"
min="50"
step="50"
:suffix="$t('date.ms')"
v-model.number="sniffTimeout"></v-text-field>
</v-col>
</v-row>
<v-row v-if="optionTCP">
<v-col cols="12" sm="6" md="4">
@@ -70,16 +52,6 @@
v-model.number="udpTimeout"></v-text-field>
</v-col>
</v-row>
<v-row v-if="optionDS">
<v-col cols="12" sm="6" md="4">
<v-select
hide-details
:label="$t('listen.domainStrategy')"
:items="['prefer_ipv4','prefer_ipv6','ipv4_only','ipv6_only']"
v-model="inbound.domain_strategy">
</v-select>
</v-col>
</v-row>
<v-card-actions class="pt-0" v-if="inbound.type != 'tun'">
<v-spacer></v-spacer>
<v-menu v-model="menu" :close-on-content-click="false" location="start">
@@ -97,9 +69,6 @@
<v-list-item>
<v-switch v-model="optionUDP" color="primary" :label="$t('listen.udpOptions')" hide-details></v-switch>
</v-list-item>
<v-list-item>
<v-switch v-model="optionDS" color="primary" :label="$t('listen.domainStrategy')" hide-details></v-switch>
</v-list-item>
</v-list>
</v-card>
</v-menu>
@@ -120,10 +89,6 @@ export default {
get() { return this.$props.inbound.udp_timeout ? parseInt(this.$props.inbound.udp_timeout.replace('m','')) : 5 },
set(newValue:number) { this.$props.inbound.udp_timeout = newValue > 0 ? newValue + 'm' : '5m' }
},
sniffTimeout: {
get() { return this.$props.inbound.sniff_timeout ? parseInt(this.$props.inbound.sniff_timeout.replace('ms','')) : 300 },
set(newValue:number) { this.$props.inbound.sniff_timeout = newValue > 0 ? newValue + 'ms' : '300ms' }
},
optionTCP: {
get(): boolean {
return this.$props.inbound.tcp_fast_open != undefined &&
@@ -147,10 +112,6 @@ export default {
optionDetour: {
get(): boolean { return this.$props.inbound.detour != undefined },
set(v:boolean) { this.$props.inbound.detour = v ? this.inTags[0]?? '' : undefined }
},
optionDS: {
get(): boolean { return this.$props.inbound.domain_strategy != undefined },
set(v:boolean) { this.$props.inbound.domain_strategy = v ? 'prefer_ipv4' : undefined }
}
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
<template>
<v-card subtitle="Direct">
<v-row>
<v-col cols="12" sm="6" md="4" v-if="direction == 'in'">
<v-col cols="12" sm="6" md="4">
<Network :data="data" />
</v-col>
<v-col cols="12" sm="6" md="4">
@@ -28,7 +28,7 @@
import Network from '@/components/Network.vue'
export default {
props: ['direction','data'],
props: ['data'],
data() {
return {}
},
-5
View File
@@ -252,11 +252,6 @@ export default {
],
fingerprints: [
{ title: "Chrome", value: "chrome" },
{ title: "Chrome PSK", value: "chrome_psk" },
{ title: "Chrome PSK Shuffle", value: "chrome_psk_shuffle" },
{ title: "Chrome Padding PSK Shuffle", value: "chrome_padding_psk_shuffle" },
{ title: "Chrome Post-Quantum", value: "chrome_pq" },
{ title: "Chrome Post-Quantum PSK", value: "chrome_pq_psk" },
{ title: "Firefox", value: "firefox" },
{ title: "Microsoft Edge", value: "edge" },
{ title: "Apple Safari", value: "safari" },
+2 -3
View File
@@ -70,15 +70,14 @@
</v-row>
<v-row>
<v-col>
<v-combobox
<v-select
v-model="clientInbounds"
:items="inboundTags"
:label="$t('client.inboundTags')"
:return-object="false"
multiple
chips
hide-details
></v-combobox>
></v-select>
</v-col>
</v-row>
</v-window-item>
+1 -1
View File
@@ -40,7 +40,7 @@
<v-window v-model="side" style="margin-top: 10px;">
<v-window-item value="s">
<Listen :inbound="inbound" :inTags="inTags" />
<Direct v-if="inbound.type == inTypes.Direct" direction="in" :data="inbound" />
<Direct v-if="inbound.type == inTypes.Direct" :data="inbound" />
<Shadowsocks v-if="inbound.type == inTypes.Shadowsocks" direction="in" :data="inbound" />
<Hysteria v-if="inbound.type == inTypes.Hysteria" direction="in" :data="inbound" />
<Hysteria2 v-if="inbound.type == inTypes.Hysteria2" direction="in" :data="inbound" />
+2 -3
View File
@@ -48,7 +48,6 @@
</v-text-field>
</v-col>
</v-row>
<Direct v-if="outbound.type == outTypes.Direct" direction="out" :data="outbound" />
<Socks v-if="outbound.type == outTypes.SOCKS" :data="outbound" />
<Http v-if="outbound.type == outTypes.HTTP" :data="outbound" />
<Shadowsocks v-if="outbound.type == outTypes.Shadowsocks" direction="out" :data="outbound" />
@@ -139,8 +138,8 @@ export default {
link: "",
loading: false,
outTypes: OutTypes,
NoDial: [OutTypes.Block, OutTypes.DNS, OutTypes.Selector, OutTypes.URLTest],
NoServer: [OutTypes.Direct, OutTypes.Block, OutTypes.DNS, OutTypes.Selector, OutTypes.URLTest, OutTypes.Tor],
NoDial: [OutTypes.Selector, OutTypes.URLTest],
NoServer: [OutTypes.Direct, OutTypes.Selector, OutTypes.URLTest, OutTypes.Tor],
}
},
methods: {
+177 -25
View File
@@ -12,7 +12,7 @@
</v-col>
<v-spacer></v-spacer>
<v-col cols="auto" v-if="logical" justify="center" align="center">
<v-btn color="primary" @click="ruleData.rules.push({})" hide-details>{{ $t('actions.add') + " " + $t('objects.rule') }}</v-btn>
<v-btn color="primary" @click="ruleData.rules.push(<rule>{})" hide-details>{{ $t('actions.add') + " " + $t('objects.rule') }}</v-btn>
</v-col>
</v-row>
<v-card style="background-color: inherit; margin-bottom: 5px;" v-for="(r, index) in ruleData.rules" v-if="ruleData.type == 'logical'">
@@ -35,12 +35,12 @@
:rsTags="rsTags" />
<v-row>
<v-col cols="12" sm="6" md="4">
<v-combobox
v-model="ruleData.outbound"
:items="outTags"
:label="$t('objects.outbound')"
<v-select
v-model="ruleData.action"
:items="actions"
:label="$t('admin.action')"
hide-details
></v-combobox>
></v-select>
</v-col>
<v-col cols="12" sm="6" md="4" v-if="logical">
<v-combobox
@@ -54,6 +54,95 @@
<v-switch color="primary" v-model="ruleData.invert" :label="$t('rule.invert')" hide-details></v-switch>
</v-col>
</v-row>
<v-card subtitle="Route" v-if="ruleData.action == 'route'">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-select
v-model="ruleData.outbound"
:items="outTags"
:label="$t('objects.outbound')"
hide-details
></v-select>
</v-col>
</v-row>
</v-card>
<v-card subtitle="Route Option" v-if="ruleData.action == 'route-options'">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="ruleData.override_address" :label="$t('types.direct.overrideAddr')" hide-details></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model.number="ruleData.override_port"
type="number"
min="0"
max="65534"
:label="$t('types.direct.overridePort')"
hide-details>
</v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-switch v-model="ruleData.udp_disable_domain_unmapping" :label="$t('rule.udpDisableDomainUnmapping')" hide-details></v-switch>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-switch v-model="ruleData.udp_connect" :label="$t('rule.udpConnect')" hide-details></v-switch>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="ruleData.udp_timeout" :label="$t('rule.udpTimeout')" hide-details></v-text-field>
</v-col>
</v-row>
</v-card>
<v-card subtitle="Reject" v-if="ruleData.action == 'reject'">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-select
v-model="ruleData.method"
:items="[{ title: 'Default', value: 'default' },{ title: 'Drop', value: 'drop'}]"
:label="$t('rule.method')"
clearable
@click:clear="delete ruleData.method"
hide-details>
</v-select>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-switch v-model="ruleData.no_drop" :label="$t('rule.noDrop')" hide-details></v-switch>
</v-col>
</v-row>
</v-card>
<v-card subtitle="Sniff" v-if="ruleData.action == 'sniff'">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-select
v-model="ruleData.sniff"
:items="sniffers"
:label="$t('rule.sniffer')"
multiple
chips
hide-details>
</v-select>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="ruleData.timeout" :label="$t('rule.timeout')" hide-details></v-text-field>
</v-col>
</v-row>
</v-card>
<v-card subtitle="Resolve" v-if="ruleData.action == 'resolve'">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-select
v-model="ruleData.strategy"
:items="strategies"
:label="$t('rule.strategy')"
clearable
@click:clear="delete ruleData.strategy"
hide-details>
</v-select>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="ruleData.server" :label="$t('basic.dns.server')" hide-details></v-text-field>
</v-col>
</v-row>
</v-card>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
@@ -78,8 +167,9 @@
</template>
<script lang="ts">
import { logicalRule, rule } from '@/types/rules'
import { logicalRule, rule, actionKeys } from '@/types/rules'
import RuleOptions from '@/components/Rule.vue'
import { title } from 'process';
export default {
props: ['visible', 'data', 'index', 'clients', 'inTags', 'outTags', 'rsTags'],
emits: ['close', 'save'],
@@ -87,13 +177,39 @@ export default {
return {
title: 'add',
loading: false,
ruleData: <logicalRule>{
ruleData: <any>{
type: 'logical',
mode: 'and',
rules: <rule[]>[{}],
invert: false,
action: 'route',
outbound: 'direct',
}
},
actions: [
{ title: 'Route', value: 'route'},
{ title: 'Route Options', value: 'route-options'},
{ title: 'Reject', value: 'reject'},
{ title: 'Hijack DNS', value: 'hijack-dns'},
{ title: 'Sniff', value: 'sniff'},
{ title: 'Resolve', value: 'resolve'}
],
sniffers: [
{ title: 'HTTP', value: 'http' },
{ title: 'TLS', value: 'tls' },
{ title: 'QUIC', value: 'quic' },
{ title: 'STUN', value: 'stun' },
{ title: 'DNS', value: 'dns' },
{ title: 'BitTorrent', value: 'bittorrent' },
{ title: 'DTLS', value: 'dtls' },
{ title: 'SSH', value: 'ssh' },
{ title: 'RDP', value: 'rdp' },
],
strategies: [
{ title: 'Prefer IPv4', value: 'prefer_ipv4' },
{ title: 'Prefer IPv6', value: 'prefer_ipv6' },
{ title: 'IPv4 Only', value: 'ipv4_only' },
{ title: 'IPv6 Only', value: 'ipv6_only' },
]
}
},
methods: {
@@ -103,13 +219,18 @@ export default {
if (newData.type) {
this.ruleData = newData
} else {
this.ruleData = <logicalRule>{
this.ruleData = {
type: 'simple',
mode: 'and',
rules: <rule[]>[{...newData}],
invert: newData.invert,
outbound: newData.outbound,
rules: <rule[]>[{}],
}
Object.keys(newData).forEach(key => {
if (actionKeys.includes(key)) {
this.ruleData[key] = newData[key]
} else {
this.ruleData.rules[0][key] = newData[key]
}
})
}
this.title = 'edit'
}
@@ -119,6 +240,7 @@ export default {
mode: 'and',
rules: <rule[]>[{}],
invert: false,
action: 'route',
outbound: this.$props.outTags[0]?? 'direct',
}
this.title = 'add'
@@ -130,11 +252,48 @@ export default {
},
saveChanges() {
this.loading = true
if (this.ruleData.type == 'simple'){
this.ruleData.rules[0].outbound = this.ruleData.outbound
this.ruleData.rules[0].invert = this.ruleData.invert
let newRule = <any>{
action: this.ruleData.action,
invert: this.ruleData.invert,
}
this.$emit('save', this.ruleData)
// Filter action data
switch (newRule.action){
case 'route':
newRule.outbound = this.ruleData.outbound
break
case 'route-options':
newRule.override_address = this.ruleData.override_address.length > 0 ? this.ruleData.override_address : undefined
newRule.override_port = this.ruleData.override_port > 0 ? this.ruleData.override_port : undefined
newRule.network_strategy = this.ruleData.network_strategy.length > 0 ? this.ruleData.network_strategy : undefined
newRule.fallback_delay = this.ruleData.fallback_delay.length > 0 ? this.ruleData.fallback_delay : undefined
newRule.udp_disable_domain_unmapping = this.ruleData.udp_disable_domain_unmapping? true : undefined
newRule.udp_connect = this.ruleData.udp_connect? true : undefined
newRule.udp_timeout = this.ruleData.udp_timeout.length > 0 ? this.ruleData.udp_timeout : undefined
break
case 'reject':
newRule.method = this.ruleData.method.length > 0 ? this.ruleData.method : undefined
newRule.no_drop = this.ruleData.no_drop? true : undefined
break
case 'sniff':
newRule.sniffer = this.ruleData.sniffer.length > 0 ? this.ruleData.sniffer : undefined
newRule.timeout = this.ruleData.timeout.length > 0 ? this.ruleData.timeout : undefined
break
case 'resolve':
newRule.strategy = this.ruleData.strategy.length > 0 ? this.ruleData.strategy : undefined
newRule.server = this.ruleData.server.length > 0 ? this.ruleData.server : undefined
break
}
// Add rules
if (this.ruleData.type == 'simple'){
newRule = { ...this.ruleData.rules[0], ...newRule }
} else {
newRule.type = 'logical'
newRule.mode = this.ruleData.mode
newRule.rules = this.ruleData.rules
}
this.$emit('save', newRule)
this.loading = false
},
deleteRule(index:number) {
@@ -145,14 +304,7 @@ export default {
logical: {
get() { return this.ruleData.type == 'logical' },
set(v:boolean) {
if (v) {
this.ruleData.type = 'logical'
this.ruleData.outbound = this.ruleData.rules[0].outbound?? this.$props.outTags[0]
delete this.ruleData.rules[0].outbound
} else {
this.ruleData.type = 'simple'
this.ruleData.rules[0].outbound = this.ruleData.outbound
}
this.ruleData.type = v? 'logical' : 'simple'
}
}
},
+8 -4
View File
@@ -88,7 +88,6 @@ export default {
tls: "TLS",
multiplex: "Multiplex",
transport: "Transport",
method: "Method",
headers: "Headers",
key: "Key",
value: "Value",
@@ -260,9 +259,6 @@ export default {
mdOption: "Multi Domain Options",
},
listen: {
sniffing: "Sniffing",
sniffingTimeout: "Sniffing Timeout",
sniffingOverride: "Override Destation",
options: "Listen Options",
tcpOptions: "TCP Options",
udpOptions: "UDP Options",
@@ -328,6 +324,14 @@ export default {
domainRules: "Domain/IP",
srcIpRules: "Source IP",
srcPortRules: "Source Port",
udpDisableDomainUnmapping: "UDP Disable Domain Unmapping",
udpConnect: "UDP Connect",
udpTimeout: "UDP Timeout",
method: "Method",
noDrop: "No Drop",
sniffer: "Sniffer",
timeout: "Timeout",
strategy: "Strategy",
},
ruleset: {
add: "Add Ruleset",
+8 -3
View File
@@ -259,9 +259,6 @@ export default {
mdOption: "گزینه‌های دامنه چندگانه",
},
listen: {
sniffing: "شنود آدرس",
sniffingTimeout: "مهلت شنود آدرس",
sniffingOverride: "جایگزینی مقصد",
options: "گزینه‌های گوش‌دادن",
tcpOptions: "گزینه‌های TCP",
udpOptions: "گزینه‌های UDP",
@@ -327,6 +324,14 @@ export default {
domainRules: "دامنه/آدرس",
srcIpRules: "آدرس مبدا",
srcPortRules: "پورت مبدا",
udpDisableDomainUnmapping: "عدم تبدیل مسیریابی دامنه",
udpConnect: "اتصال UDP",
udpTimeout: "مهلت UDP",
method: "روش",
noDrop: "عدم رهاکردن",
sniffer: "شنود کننده",
timeout: "مهلت",
strategy: "استراتژی",
},
ruleset: {
add: "ایجاد مجموعه",
+8 -4
View File
@@ -88,7 +88,6 @@ export default {
tls: "TLS",
multiplex: "Мультиплекс",
transport: "Транспорт",
method: "Метод",
headers: "Заголовки",
key: "Ключ",
value: "Значение",
@@ -260,9 +259,6 @@ export default {
mdOption: "Параметры мультидомена",
},
listen: {
sniffing: "Обнаружение",
sniffingTimeout: "Таймаут обнаружения",
sniffingOverride: "Переопределение назначения",
options: "Параметры прослушивания",
tcpOptions: "Параметры TCP",
udpOptions: "Параметры UDP",
@@ -328,6 +324,14 @@ export default {
domainRules: "Домен/IP",
srcIpRules: "Источник IP",
srcPortRules: "Источник порта",
udpDisableDomainUnmapping: "Отключить перенос доменных имен",
udpConnect: "Подключение UDP",
udpTimeout: "Таймаут UDP",
method: "Метод",
noDrop: "Не сбрасывать",
sniffer: "Обнаружение",
timeout: "Таймаут",
strategy: "Стратегия",
},
ruleset: {
add: "Добавить набор правил",
+9 -5
View File
@@ -86,7 +86,6 @@ export default {
tls: "TLS",
multiplex: "Ghép đa truyền thông ",
transport: "Giao thông",
method: "Phương pháp",
headers: "Tiêu đề",
key: "Chìa khóa",
value: "Giá trị",
@@ -249,7 +248,6 @@ export default {
in: {
addr: "Địa chỉ",
port: "Cổng",
sniffing: "Đang Sniffing",
clients: "Kích hoạt khách hàng",
ssMethod: "Phương thức",
sSide: "Phía Máy chủ",
@@ -259,9 +257,6 @@ export default {
mdOption: "Tùy chọn Nhiều Tên miền",
},
listen: {
sniffing: "Đang Sniffing",
sniffingTimeout: "Thời gian Chờ Sniffing",
sniffingOverride: "Ghi đè Đích",
options: "Tùy chọn Nghe",
tcpOptions: "Tùy chọn TCP",
udpOptions: "Tùy chọn UDP",
@@ -327,6 +322,15 @@ export default {
domainRules: "Tên miền/IP",
srcIpRules: "IP Nguồn",
srcPortRules: "Cổng Nguồn",
udpDisableDomainUnmapping: "Không màm mạng tiền lập tên miền",
udpFallbackDelay: "Thời gian Chờ Fallback",
udpConnect: "Kết nối UDP",
udpTimeout: "Thời gian Chờ UDP",
method: "Phương pháp",
noDrop: "Không Tháp",
sniffer: "Kiểm tra Sniffer",
timeout: "Thời gian Chờ Sniffing",
strategy: "Chiến lệ",
},
ruleset: {
add: "Thêm Bộ quy tắc",
+8 -5
View File
@@ -86,7 +86,6 @@ export default {
tls: "TLS",
multiplex: "多路复用",
transport: "传输",
method: "方法",
headers: "标头",
key: "键",
value: "值",
@@ -249,7 +248,6 @@ export default {
in: {
addr: "地址",
port: "端口",
sniffing: "嗅探",
clients: "启用客户端",
ssMethod: "方法",
sSide: "服务器端",
@@ -259,9 +257,6 @@ export default {
mdOption: "多域名选项",
},
listen: {
sniffing: "嗅探",
sniffingTimeout: "嗅探超时",
sniffingOverride: "覆盖目标地址",
options: "监听选项",
tcpOptions: "TCP 选项",
udpOptions: "UDP 选项",
@@ -327,6 +322,14 @@ export default {
domainRules: "域名/IP",
srcIpRules: "源 IP",
srcPortRules: "源端口",
udpDisableDomainUnmapping: "禁用域名解析映射",
udpConnect: "启用 UDP 连接",
udpTimeout: "UDP 超时",
method: "方法",
noDrop: "不丢弃",
sniffer: "嗅探",
timeout: "超时",
strategy: "策略",
},
ruleset: {
add: "添加规则集",
+8 -5
View File
@@ -87,7 +87,6 @@ export default {
tls: "TLS",
multiplex: "多路復用",
transport: "傳輸",
method: "方法",
headers: "方法",
key: "鑰匙",
value: "價值",
@@ -250,7 +249,6 @@ export default {
in: {
addr: "地址",
port: "端口",
sniffing: "嗅探",
clients: "啟用客戶端",
ssMethod: "方法",
sSide: "服務器端",
@@ -260,9 +258,6 @@ export default {
mdOption: "多域名選項",
},
listen: {
sniffing: "嗅探",
sniffingTimeout: "嗅探超時",
sniffingOverride: "覆蓋目的地",
options: "監聽選項",
tcpOptions: "TCP 選項",
udpOptions: "UDP 選項",
@@ -328,6 +323,14 @@ export default {
domainRules: "域名/IP",
srcIpRules: "源 IP",
srcPortRules: "源端口",
udpDisableDomainUnmapping: "禁用域名解析映射",
udpConnect: "啟用 UDP 連接",
udpTimeout: "UDP 超時",
method: "方法",
noDrop: "不丟弃",
sniffer: "嗅探",
timeout: "超時",
strategy: "策略",
},
ruleset: {
add: "添加規則集",
-5
View File
@@ -41,10 +41,6 @@ export interface Listen {
udp_fragment?: boolean
udp_timeout?: string
detour?: string
sniff?: boolean
sniff_override_destination?: boolean
sniff_timeout?: string
domain_strategy?: string
}
interface InboundBasics extends Listen {
@@ -180,7 +176,6 @@ export interface Tun extends InboundBasics {
udp_timeout?: string
stack?: string
auto_route?: boolean
// gso?: boolean
// strict_route?: boolean
// iproute2_table_index?: number
// iproute2_rule_index?: number
+1 -12
View File
@@ -4,7 +4,6 @@ import { Transport } from "./transport"
export const OutTypes = {
Direct: 'direct',
Block: 'block',
SOCKS: 'socks',
HTTP: 'http',
Shadowsocks: 'shadowsocks',
@@ -17,7 +16,6 @@ export const OutTypes = {
Hysteria2: 'hysteria2',
Tor: 'tor',
SSH: 'ssh',
DNS: 'dns',
Selector: 'selector',
URLTest: 'urltest',
}
@@ -54,12 +52,7 @@ export interface WgPeer {
reserved?: number[]
}
export interface Direct extends OutboundBasics, Dial {
override_address?: string
override_port?: number
}
export interface Block extends OutboundBasics {}
export interface Direct extends OutboundBasics, Dial {}
export interface SOCKS extends OutboundBasics, Dial {
server: string
@@ -209,8 +202,6 @@ export interface SSH extends OutboundBasics, Dial {
client_version?: string
}
export interface DNS extends OutboundBasics {}
export interface Selector extends OutboundBasics {
outbounds: string[]
url?: string
@@ -240,7 +231,6 @@ export type Outbound = InterfaceMap[keyof InterfaceMap]
// Create defaultValues object dynamically
const defaultValues: Record<OutType, Outbound> = {
direct: { type: OutTypes.Direct },
block: { type: OutTypes.Block },
socks: { type: OutTypes.SOCKS, version: "5" },
http: { type: OutTypes.HTTP, tls: {} },
shadowsocks: { type: OutTypes.Shadowsocks, method: 'none', multiplex: {} },
@@ -253,7 +243,6 @@ const defaultValues: Record<OutType, Outbound> = {
hysteria2: { type: OutTypes.Hysteria2, tls: { enabled: true } },
tor: { type: OutTypes.Tor, executable_path: './tor', data_directory: '$HOME/.cache/tor', torrc: { ClientOnly: 1 } },
ssh: { type: OutTypes.SSH },
dns: { type: OutTypes.DNS },
selector: { type: OutTypes.Selector },
urltest: { type: OutTypes.URLTest },
}
+35 -6
View File
@@ -1,12 +1,43 @@
export interface logicalRule {
interface generalRule {
invert: boolean
action: 'route' | 'route-options' | 'reject' | 'hijack-dns' | 'sniff' | 'resolve'
outbound?: string
override_address?: string
override_port?: number
udp_disable_domain_unmapping?: boolean
udp_connect?: boolean
udp_timeout?: string
method?: string
no_drop?: boolean
sniffer: string[]
timeout: string
strategy: string
server: string
}
export const actionKeys = [
'invert',
'action',
'outbound',
'override_address',
'override_port',
'udp_disable_domain_unmapping',
'udp_connect',
'udp_timeout',
'method',
'no_drop',
'sniffer',
'timeout',
'strategy',
'server'
]
export interface logicalRule extends generalRule {
type: 'logical' | 'simple'
mode: 'and' | 'or'
rules: rule[]
invert: boolean
outbound: string
}
export interface rule {
export interface rule extends generalRule {
inbound?: string[]
ip_version?: 4 | 6
network?: string[]
@@ -32,8 +63,6 @@ export interface rule {
clash_mode?: string
rule_set?: string[]
rule_set_ipcidr_match_source?: boolean
invert?: boolean
outbound?: string
}
export interface ruleset {
+12 -9
View File
@@ -96,16 +96,22 @@
</v-row>
</v-card-subtitle>
<v-card-text>
<v-row>
<v-col>{{ $t('admin.action') }}</v-col>
<v-col>
{{ item.action }}
</v-col>
</v-row>
<v-row>
<v-col>{{ $t('objects.outbound') }}</v-col>
<v-col>
{{ item.outbound }}
{{ item.outbound?? '-' }}
</v-col>
</v-row>
<v-row>
<v-col>{{ $t('pages.rules') }}</v-col>
<v-col>
{{ item.rules ? item.rules.length : Object.keys(item).filter(r => !["rule_set_ipcidr_match_source","invert","outbound"].includes(r)).length }}
{{ item.rules ? item.rules.length : Object.keys(item).filter(r => !actionKeys.includes(r)).length }}
</v-col>
</v-row>
<v-row>
@@ -151,7 +157,7 @@ import { computed, ref, onMounted } from 'vue'
import RuleVue from '@/layouts/modals/Rule.vue'
import RulesetVue from '@/layouts/modals/Ruleset.vue'
import { Config } from '@/types/config'
import { logicalRule, ruleset } from '@/types/rules'
import { actionKeys, ruleset } from '@/types/rules'
import { FindDiff } from '@/plugins/utils'
const oldConfig = ref({})
@@ -239,15 +245,12 @@ const closeRuleModal = () => {
ruleModal.value.visible = false
}
const saveRuleModal = (data:logicalRule) => {
// Logical or simple
const ruleData = data.type == 'logical' ? data : data.rules[0]
const saveRuleModal = (data:any) => {
// New or Edit
if (ruleModal.value.index == -1) {
rules.value.push(ruleData)
rules.value.push(data)
} else {
rules.value[ruleModal.value.index] = ruleData
rules.value[ruleModal.value.index] = data
}
ruleModal.value.visible = false
}