mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-28 12:22:37 +00:00
Compare commits
63 Commits
v0.9.7
...
3971468034
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3971468034 | ||
|
|
75a7b1c84c | ||
|
|
4ee3e11950 | ||
|
|
68f2f3bb56 | ||
|
|
79b2e31096 | ||
|
|
d5e6159fbd | ||
|
|
eec5113947 | ||
|
|
695f5eb6d7 | ||
|
|
a0ad2b46e0 | ||
|
|
2b0011a127 | ||
|
|
f69597efb7 | ||
|
|
ffbd262aae | ||
|
|
3ea867e4b8 | ||
|
|
090c2def1d | ||
|
|
e88f8fd485 | ||
|
|
292850818a | ||
|
|
92f66bf5b5 | ||
|
|
b39de30db9 | ||
|
|
223d75a10a | ||
|
|
691193731f | ||
|
|
05959b09b4 | ||
|
|
3f5ed82672 | ||
|
|
05910ac5dd | ||
|
|
1d56f44696 | ||
|
|
c207bfc1f0 | ||
|
|
3a8762c307 | ||
|
|
bc7e2c2e94 | ||
|
|
ad47d18a23 | ||
|
|
79a7e888b1 | ||
|
|
a1f919eafb | ||
|
|
644b9040b9 | ||
|
|
3f2281e284 | ||
|
|
0c11565cc9 | ||
|
|
6974910734 | ||
|
|
0c8574755a | ||
|
|
b9ad0c2ee2 | ||
|
|
04ac98725c | ||
|
|
6af2c56fc8 | ||
|
|
fb6a830d7b | ||
|
|
b82d49200d | ||
|
|
40ba3fd970 | ||
|
|
1f57413025 | ||
|
|
b228255d3b | ||
|
|
55e765e7f9 | ||
|
|
535d1d01e1 | ||
|
|
7fdba81f2c | ||
|
|
6c38710312 | ||
|
|
eeffa0f544 | ||
|
|
73da1a87ad | ||
|
|
670544cfb1 | ||
|
|
4864a6b13c | ||
|
|
cb15d568c0 | ||
|
|
0f2cefd537 | ||
|
|
9e66b07251 | ||
|
|
624f5cd120 | ||
|
|
c711f1ad05 | ||
|
|
88635b6ed8 | ||
|
|
0cb4053f8d | ||
|
|
fb2aca3237 | ||
|
|
37c4e13071 | ||
|
|
623ffbb23f | ||
|
|
be2de49360 | ||
|
|
eef5328506 |
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@@ -1,11 +1,11 @@
|
||||
name: Publish Docker Image
|
||||
on:
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
tags:
|
||||
- '**'
|
||||
|
||||
concurrency:
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -3,3 +3,9 @@ subconverter.exe
|
||||
cmake-build-debug
|
||||
.idea
|
||||
base/cache
|
||||
scripts/quickjspp
|
||||
scripts/yaml-cpp
|
||||
.DS_Store
|
||||
src/.DS_Store
|
||||
|
||||
build
|
||||
@@ -4,6 +4,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/")
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition")
|
||||
endif()
|
||||
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE Release)
|
||||
ENDIF()
|
||||
|
||||
@@ -6,7 +6,7 @@ original git: https://github.com/asdlokj1qpi23/subconverter
|
||||
|
||||
[](https://github.com/asdlokj1qpi233/subconverter/actions)
|
||||
[](https://github.com/asdlokj1qpi23/subconverter/tags)
|
||||
[](https://github.com/asdlokj1qpi23/subconverter/releases)
|
||||
[](https://github.com/asdlokj1qpi233/subconverter/releases)
|
||||
[](https://github.com/tindy2013/subconverter/blob/master/LICENSE)
|
||||
|
||||
[Docker README](https://github.com/asdlokj1qpi23/subconverter/blob/master/README-docker.md)
|
||||
|
||||
@@ -5,7 +5,7 @@ socks-port: {{ default(global.clash.socks_port, "7891") }}
|
||||
allow-lan: {{ default(global.clash.allow_lan, "true") }}
|
||||
mode: Rule
|
||||
log-level: {{ default(global.clash.log_level, "info") }}
|
||||
external-controller: :9090
|
||||
external-controller: {{ default(global.clash.external_controller, "127.0.0.1:9090") }}
|
||||
{% if default(request.clash.dns, "") == "1" %}
|
||||
dns:
|
||||
enable: true
|
||||
@@ -378,7 +378,16 @@ enhanced-mode-by-rule = true
|
||||
"rules": [],
|
||||
"auto_detect_interface": true
|
||||
},
|
||||
"experimental": {}
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"store_fakeip": true
|
||||
},
|
||||
"clash_api": {
|
||||
"external_controller": "{{ default(global.clash.external_controller, "127.0.0.1:9090") }}",
|
||||
"external_ui": "dashboard"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
|
||||
@@ -100,5 +100,14 @@
|
||||
"rules": [],
|
||||
"auto_detect_interface": true
|
||||
},
|
||||
"experimental": {}
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"store_fakeip": true
|
||||
},
|
||||
"clash_api": {
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"external_ui": "dashboard"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,13 +109,14 @@ filter_deprecated_nodes=false
|
||||
append_sub_userinfo=true
|
||||
clash_use_new_field_name=true
|
||||
|
||||
;Generate style of the proxies section of Clash subscriptions.
|
||||
;Generate style of the proxies and proxy groups section of Clash subscriptions.
|
||||
;Supported styles: block, flow, compact
|
||||
;Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
|
||||
; key: value - {name: name2, key: value}
|
||||
; - name: name2
|
||||
; key: value
|
||||
clash_proxies_style=flow
|
||||
clash_proxy_groups_style=block
|
||||
|
||||
;add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
|
||||
singbox_add_clash_modes=true
|
||||
@@ -232,6 +233,7 @@ clash.http_port=7890
|
||||
clash.socks_port=7891
|
||||
clash.allow_lan=true
|
||||
clash.log_level=info
|
||||
clash.external_controller=127.0.0.1:9090
|
||||
singbox.allow_lan=true
|
||||
singbox.mixed_port=2080
|
||||
|
||||
|
||||
@@ -117,9 +117,9 @@ match = '^Smart Access expire: (\d+)/(\d+)/(\d+)$'
|
||||
replace = '$1:$2:$3:0:0:0'
|
||||
|
||||
[node_pref]
|
||||
#udp_flag = true
|
||||
#udp_flag = false
|
||||
#tcp_fast_open_flag = false
|
||||
#skip_cert_verify_flag = true
|
||||
#skip_cert_verify_flag = false
|
||||
#tls13_flag = false
|
||||
|
||||
sort_flag = false
|
||||
@@ -135,13 +135,14 @@ filter_deprecated_nodes = false
|
||||
append_sub_userinfo = true
|
||||
clash_use_new_field_name = true
|
||||
|
||||
# Generate style of the proxies section of Clash subscriptions.
|
||||
# Generate style of the proxies and proxy groups section of Clash subscriptions.
|
||||
# Supported styles: block, flow, compact
|
||||
# Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
|
||||
# key: value - {name: name2, key: value}
|
||||
# - name: name2
|
||||
# key: value
|
||||
clash_proxies_style = "flow"
|
||||
clash_proxy_groups_style = "block"
|
||||
|
||||
# add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
|
||||
singbox_add_clash_modes = true
|
||||
@@ -243,6 +244,10 @@ value = "true"
|
||||
key = "clash.log_level"
|
||||
value = "info"
|
||||
|
||||
[[template.globals]]
|
||||
key = "clash.external_controller"
|
||||
value = "127.0.0.1:9090"
|
||||
|
||||
[[template.globals]]
|
||||
key = "singbox.allow_lan"
|
||||
value = "true"
|
||||
|
||||
@@ -50,6 +50,7 @@ node_pref:
|
||||
append_sub_userinfo: true
|
||||
clash_use_new_field_name: true
|
||||
clash_proxies_style: flow
|
||||
clash_proxy_groups_style: block
|
||||
singbox_add_clash_modes: true
|
||||
rename_node:
|
||||
# - {match: "\\(?((x|X)?(\\d+)(\\.?\\d+)?)((\\s?倍率?)|(x|X))\\)?", replace: "$1x"}
|
||||
@@ -108,9 +109,10 @@ template:
|
||||
- {key: clash.socks_port, value: 7891}
|
||||
- {key: clash.allow_lan, value: true}
|
||||
- {key: clash.log_level, value: info}
|
||||
- {key: clash.external_controller, value: '127.0.0.1:9090'}
|
||||
- {key: singbox.allow_lan, value: true}
|
||||
- {key: singbox.mixed_port, value: 2080}
|
||||
|
||||
|
||||
aliases:
|
||||
- {uri: /v, target: /version}
|
||||
- {uri: /clash, target: "/sub?target=clash"}
|
||||
|
||||
@@ -3,15 +3,15 @@ match = "(?i:Bandwidth|expire|流量|时间|应急|过期)"
|
||||
emoji = "🏳️🌈"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bHK[G]?\\b|Hong.*?Kong|\\bHKT\\b|\\bHKBN\\b|\\bHGC\\b|\\bWTT\\b|\\bCMI\\b|[^-]港)"
|
||||
match = "(?i:\\bHK[G]?\\d*\\b|Hong.*?Kong|\\bHKT\\b|\\bHKBN\\b|\\bHGC\\b|\\bWTT\\b|\\bCMI\\b|[^-]港)"
|
||||
emoji = "🇭🇰"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bTW[N]?\\b|Taiwan|新北|彰化|\\bCHT\\b|台湾|[^-]台|\\bHINET\\b)"
|
||||
match = "(?i:\\bTW[N]?\\d*\\b|Taiwan|新北|彰化|\\bCHT\\b|台湾|[^-]台|\\bHINET\\b)"
|
||||
emoji = "🇨🇳"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bSG[P]?\\b|Singapore|新加坡|狮城|[^-]新)"
|
||||
match = "(?i:\\bSG[P]?\\d*\\b|Singapore|新加坡|狮城|[^-]新)"
|
||||
emoji = "🇸🇬"
|
||||
|
||||
[[emoji]]
|
||||
@@ -19,15 +19,15 @@ match = "(尼日利亚|Nigeria)"
|
||||
emoji = "🇳🇬"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bJP[N]?\\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日)"
|
||||
match = "(?i:\\bJP[N]?\\d*\\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日)"
|
||||
emoji = "🇯🇵"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bK[O]?R\\b|Korea|首尔|韩|韓)"
|
||||
match = "(?i:(?<!North\\s)(\\bK[O]?R\\d*\\b|Korea|首尔|韩|韓))"
|
||||
emoji = "🇰🇷"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bUS[A]?\\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥)"
|
||||
match = "(?i:\\bUS[A]?\\d*\\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥)"
|
||||
emoji = "🇺🇸"
|
||||
|
||||
[[emoji]]
|
||||
@@ -42,6 +42,10 @@ emoji = "🇦🇪"
|
||||
match = "(阿尔巴尼亚|Albania)"
|
||||
emoji = "🇦🇱"
|
||||
|
||||
[[emoji]]
|
||||
match = "(南极|Antarctica)"
|
||||
emoji = "🇦🇶"
|
||||
|
||||
[[emoji]]
|
||||
match = "(Argentina|阿根廷)"
|
||||
emoji = "🇦🇷"
|
||||
@@ -51,7 +55,7 @@ match = "(Austria|Vienna|奥地利|维也纳)"
|
||||
emoji = "🇦🇹"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bAU[S]?\\b|Australia|Sydney|澳大利亚|澳洲|悉尼)"
|
||||
match = "(?i:\\bAU[S]?\\d*\\b|Australia|Sydney|澳大利亚|澳洲|悉尼)"
|
||||
emoji = "🇦🇺"
|
||||
|
||||
[[emoji]]
|
||||
@@ -75,7 +79,7 @@ match = "(Brazil|Paulo|巴西|圣保罗)"
|
||||
emoji = "🇧🇷"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bCA[N]?\\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶)"
|
||||
match = "(?i:\\bCA[N]?\\d*\\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶)"
|
||||
emoji = "🇨🇦"
|
||||
|
||||
[[emoji]]
|
||||
@@ -103,7 +107,7 @@ match = "(Czech|捷克)"
|
||||
emoji = "🇨🇿"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bDE[U]?\\b|Germany|法兰克福|德(国|意志)|中德|^德$)"
|
||||
match = "(?i:\\bDE[U]?\\d*\\b|Germany|法兰克福|德(国|意志)|中德|^德$)"
|
||||
emoji = "🇩🇪"
|
||||
|
||||
[[emoji]]
|
||||
@@ -119,7 +123,7 @@ match = "(埃及|Egypt)"
|
||||
emoji = "🇪🇬"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bES[P]?\\b|Spain|西班牙)"
|
||||
match = "(?i:\\bES[P]?\\d*\\b|Spain|西班牙)"
|
||||
emoji = "🇪🇸"
|
||||
|
||||
[[emoji]]
|
||||
@@ -131,11 +135,11 @@ match = "(Finland|Helsinki|芬兰|赫尔辛基)"
|
||||
emoji = "🇫🇮"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bFR[A]?\\b|France|Paris|法国|巴黎)"
|
||||
match = "(?i:\\bFR[A]?\\d*\\b|France|Paris|法国|巴黎)"
|
||||
emoji = "🇫🇷"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bUK\\b|\\bGB[R]?\\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦)"
|
||||
match = "(?i:\\bUK\\d*\\b|\\bGB[R]?\\d*\\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦)"
|
||||
emoji = "🇬🇧"
|
||||
|
||||
[[emoji]]
|
||||
@@ -171,7 +175,7 @@ match = "(马恩岛|Mann)"
|
||||
emoji = "🇮🇲"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bIN[D]?\\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德)"
|
||||
match = "(?i:\\bIN[D]?\\d*\\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德)"
|
||||
emoji = "🇮🇳"
|
||||
|
||||
[[emoji]]
|
||||
@@ -179,11 +183,11 @@ match = "(伊朗|Iran)"
|
||||
emoji = "🇮🇷"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bIS[L]?\\b|Iceland|冰岛)"
|
||||
match = "(?i:\\bIS[L]?\\d*\\b|Iceland|冰岛)"
|
||||
emoji = "🇮🇸"
|
||||
|
||||
[[emoji]]
|
||||
match = "(Italy|Milan|意大利|米兰)"
|
||||
match = "(Italy|Italia|Milan|意大利|米兰)"
|
||||
emoji = "🇮🇹"
|
||||
|
||||
[[emoji]]
|
||||
@@ -202,7 +206,6 @@ emoji = "🇰🇬"
|
||||
match = "(柬埔寨|Cambodia)"
|
||||
emoji = "🇰🇭"
|
||||
|
||||
|
||||
[[emoji]]
|
||||
match = "(North.*?Korea|朝鲜)"
|
||||
emoji = "🇰🇵"
|
||||
@@ -231,6 +234,10 @@ emoji = "🇲🇩"
|
||||
match = "(北马其顿|Macedonia)"
|
||||
emoji = "🇲🇰"
|
||||
|
||||
[[emoji]]
|
||||
match = "(缅甸|Myanmar)"
|
||||
emoji = "🇲🇲"
|
||||
|
||||
[[emoji]]
|
||||
match = "(蒙古|Монголулс|Mongolia)"
|
||||
emoji = "🇲🇳"
|
||||
@@ -248,7 +255,7 @@ match = "(Malaysia|马来|MY)"
|
||||
emoji = "🇲🇾"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bNL[D]?\\b|Netherlands|荷兰|阿姆斯特丹)"
|
||||
match = "(?i:\\bNL[D]?\\d*\\b|Netherlands|荷兰|阿姆斯特丹)"
|
||||
emoji = "🇳🇱"
|
||||
|
||||
[[emoji]]
|
||||
@@ -260,7 +267,7 @@ match = "(新西兰|纽西兰|New Zealand)"
|
||||
emoji = "🇳🇿"
|
||||
|
||||
[[emoji]]
|
||||
match = "(Philippines|菲律宾)"
|
||||
match = "(?i:\\bP[O]?H\\d*\\b|Philippines|菲律宾)"
|
||||
emoji = "🇵🇭"
|
||||
|
||||
[[emoji]]
|
||||
@@ -292,7 +299,7 @@ match = "(塞尔维亚|Serbia)"
|
||||
emoji = "🇷🇸"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bRU[S]?\\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄)"
|
||||
match = "(?i:\\bRU[S]?\\d*\\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄)"
|
||||
emoji = "🇷🇺"
|
||||
|
||||
[[emoji]]
|
||||
@@ -320,7 +327,7 @@ match = "(突尼斯|Tunisia)"
|
||||
emoji = "🇹🇳"
|
||||
|
||||
[[emoji]]
|
||||
match = "(Turkey|土耳其|伊斯坦布尔)"
|
||||
match = "(Turkey|Türkiye|土耳其|伊斯坦布尔)"
|
||||
emoji = "🇹🇷"
|
||||
|
||||
[[emoji]]
|
||||
@@ -364,4 +371,4 @@ emoji = "🇧🇩"
|
||||
|
||||
[[emoji]]
|
||||
match = "(?i:\\bC[H]?N\\b|China|back|回国|中国[^-]|江苏[^-]|北京[^-]|上海[^-]|广州[^-]|深圳[^-]|杭州[^-]|常州[^-]|徐州[^-]|青岛[^-]|宁波[^-]|镇江[^-]|成都[^-]|河北[^-]|山西[^-]|辽宁[^-]|吉林[^-]|黑龙江[^-]|江苏[^-]|浙江[^-]|安徽[^-]|福建[^-]|江西[^-]|山东[^-]|河南[^-]|湖北[^-]|湖南[^-]|广东[^-]|海南[^-]|四川[^-]|贵州[^-]|云南[^-]|陕西[^-]|甘肃[^-]|青海[^-]|内蒙古[^-]|广西[^-]|西藏[^-]|宁夏[^-]|新疆[^-])"
|
||||
emoji = "🇨🇳"
|
||||
emoji = "🇨🇳"
|
||||
@@ -1,38 +1,39 @@
|
||||
(?i:Bandwidth|expire|流量|时间|应急|过期),🏳️🌈
|
||||
(?i:\bHK[G]?\b|Hong.*?Kong|\bHKT\b|\bHKBN\b|\bHGC\b|\bWTT\b|\bCMI\b|[^-]港),🇭🇰
|
||||
(?i:\bTW[N]?\b|Taiwan|新北|彰化|\bCHT\b|台湾|[^-]台|\bHINET\b),🇨🇳
|
||||
(?i:\bSG[P]?\b|Singapore|新加坡|狮城|[^-]新),🇸🇬
|
||||
(?i:\bHK[G]?\d*\b|Hong.*?Kong|\bHKT\b|\bHKBN\b|\bHGC\b|\bWTT\b|\bCMI\b|[^-]港),🇭🇰
|
||||
(?i:\bTW[N]?\d*\b|Taiwan|新北|彰化|\bCHT\b|台湾|[^-]台|\bHINET\b),🇨🇳
|
||||
(?i:\bSG[P]?\d*\b|Singapore|新加坡|狮城|[^-]新),🇸🇬
|
||||
(尼日利亚|Nigeria),🇳🇬
|
||||
(?i:\bJP[N]?\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
|
||||
(?i:\bK[O]?R\b|Korea|首尔|韩|韓),🇰🇷
|
||||
(?i:\bUS[A]?\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
|
||||
(?i:\bJP[N]?\d*\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
|
||||
(?i:(?<!North\s)(\bK[O]?R\d*\b|Korea|首尔|韩|韓)),🇰🇷
|
||||
(?i:\bUS[A]?\d*\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
|
||||
(Ascension|阿森松),🇦🇨
|
||||
(?i:\bUAE\b|Dubai|阿联酋|迪拜),🇦🇪
|
||||
(阿尔巴尼亚|Albania),🇦🇱
|
||||
(南极|Antarctica),🇦🇶
|
||||
(Argentina|阿根廷),🇦🇷
|
||||
(Austria|Vienna|奥地利|维也纳),🇦🇹
|
||||
(?i:\bAU[S]?\b|Australia|Sydney|澳大利亚|澳洲|悉尼),🇦🇺
|
||||
(?i:\bAU[S]?\d*\b|Australia|Sydney|澳大利亚|澳洲|悉尼),🇦🇺
|
||||
(阿塞拜疆|Azerbaijan),🇦🇿
|
||||
(波黑共和国|波士尼亚与赫塞哥维纳|Bosnia|Herzegovina),🇧🇦
|
||||
(Belgium|比利时),🇧🇪
|
||||
(保加利亚|Bulgaria),🇧🇬
|
||||
(Brazil|Paulo|巴西|圣保罗),🇧🇷
|
||||
(?i:\bCA[N]?\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶),🇨🇦
|
||||
(?i:\bCA[N]?\d*\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶),🇨🇦
|
||||
(Switzerland|Zurich|瑞士|苏黎世),🇨🇭
|
||||
(智利|Chile),🇨🇱
|
||||
(Colombia|哥伦比亚),🇨🇴
|
||||
(Costa Rica|哥斯达黎加),🇨🇷
|
||||
(塞浦路斯|Cyprus),🇨🇾
|
||||
(Czech|捷克),🇨🇿
|
||||
(?i:\bDE[U]?\b|Germany|法兰克福|德(国|意志)|中德|^德$),🇩🇪
|
||||
(?i:\bDE[U]?\d*\b|Germany|法兰克福|德(国|意志)|中德|^德$),🇩🇪
|
||||
(?i:\bD[N]?K\b|Denmark|丹麦),🇩🇰
|
||||
(爱沙尼亚|Estonia),🇪🇪
|
||||
(埃及|Egypt),🇪🇬
|
||||
(?i:\bES[P]?\b|Spain|西班牙),🇪🇸
|
||||
(?i:\bES[P]?\d*\b|Spain|西班牙),🇪🇸
|
||||
(Europe|欧洲),🇪🇺
|
||||
(Finland|Helsinki|芬兰|赫尔辛基),🇫🇮
|
||||
(?i:\bFR[A]?\b|France|Paris|法国|巴黎),🇫🇷
|
||||
(?i:\bUK\b|\bGB[R]?\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦),🇬🇧
|
||||
(?i:\bFR[A]?\d*\b|France|Paris|法国|巴黎),🇫🇷
|
||||
(?i:\bUK\d*\b|\bGB[R]?\d*\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦),🇬🇧
|
||||
(希腊|Greece),🇬🇷
|
||||
(格鲁吉亚|Georgia),🇬🇪
|
||||
(克罗地亚|Croatia),🇭🇷
|
||||
@@ -41,10 +42,10 @@
|
||||
(Ireland|Dublin|爱尔兰|都柏林),🇮🇪
|
||||
(Israel|以色列),🇮🇱
|
||||
(马恩岛|Mann),🇮🇲
|
||||
(?i:\bIN[D]?\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德),🇮🇳
|
||||
(?i:\bIN[D]?\d*\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德),🇮🇳
|
||||
(伊朗|Iran),🇮🇷
|
||||
(?i:\bIS[L]?\b|Iceland|冰岛),🇮🇸
|
||||
(Italy|Milan|意大利|米兰),🇮🇹
|
||||
(?i:\bIS[L]?\d*\b|Iceland|冰岛),🇮🇸
|
||||
(Italy|Italia|Milan|意大利|米兰),🇮🇹
|
||||
(约旦|Jordan),🇯🇴
|
||||
(肯尼亚|Kenya),🇰🇪
|
||||
(吉尔吉斯斯坦|Kyrgyzstan),🇰🇬
|
||||
@@ -56,14 +57,15 @@
|
||||
(拉脱维亚|Latvia),🇱🇻
|
||||
(Moldova|摩尔多瓦),🇲🇩
|
||||
(北马其顿|Macedonia),🇲🇰
|
||||
(缅甸|Myanmar),🇲🇲
|
||||
(蒙古|Монголулс|Mongolia),🇲🇳
|
||||
(Macao|澳门|\bCTM\b),🇲🇴
|
||||
(墨西哥|Mexico),🇲🇽
|
||||
(Malaysia|马来|MY),🇲🇾
|
||||
(?i:\bNL[D]?\b|Netherlands|荷兰|阿姆斯特丹),🇳🇱
|
||||
(?i:\bNL[D]?\d*\b|Netherlands|荷兰|阿姆斯特丹),🇳🇱
|
||||
(挪威|Norway),🇳🇴
|
||||
(新西兰|纽西兰|New Zealand),🇳🇿
|
||||
(Philippines|菲律宾),🇵🇭
|
||||
(?i:\bP[O]?H\d*\b|Philippines|菲律宾),🇵🇭
|
||||
(Pakistan|巴基斯坦),🇵🇰
|
||||
(?i:\bP[O]?L\b|Poland|波兰),🇵🇱
|
||||
(巴拿马|Panama),🇵🇦
|
||||
@@ -71,15 +73,16 @@
|
||||
(葡萄牙|Portugal),🇵🇹
|
||||
(Romania|罗马尼亚),🇷🇴
|
||||
(塞尔维亚|Serbia),🇷🇸
|
||||
(?i:\bRU[S]?\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄),🇷🇺
|
||||
(?i:\bRU[S]?\d*\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄),🇷🇺
|
||||
(Arabia|沙特),🇸🇦
|
||||
(Sweden|瑞典),🇸🇪
|
||||
(斯洛文尼亚|Slovenia),🇸🇮
|
||||
(斯洛伐克|Slovensko),🇸🇰
|
||||
(Thailand|泰国|曼谷),🇹🇭
|
||||
(突尼斯|Tunisia),🇹🇳
|
||||
(Turkey|土耳其|伊斯坦布尔),🇹🇷
|
||||
(Turkey|Türkiye|土耳其|伊斯坦布尔),🇹🇷
|
||||
(乌拉圭|Uruguay),🇺🇾
|
||||
(梵蒂冈|Vatican),🇻🇦
|
||||
(Vietnam|越南),🇻🇳
|
||||
(Africa|南非),🇿🇦
|
||||
(Ukraine|UA|乌克兰),🇺🇦
|
||||
|
||||
@@ -30,7 +30,7 @@ RUN set -xe && \
|
||||
install -d /usr/include/date/ && \
|
||||
install -m644 libcron/externals/date/include/date/* /usr/include/date/ && \
|
||||
cd .. && \
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1 && \
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v4.3.0" --depth=1 && \
|
||||
cd toml11 && \
|
||||
cmake -DCMAKE_CXX_STANDARD=11 . && \
|
||||
make install -j $THREADS && \
|
||||
@@ -53,6 +53,10 @@ RUN apk add --no-cache --virtual subconverter-deps pcre2 libcurl yaml-cpp
|
||||
COPY --from=builder /subconverter/subconverter /usr/bin/
|
||||
COPY --from=builder /subconverter/base /base/
|
||||
|
||||
ENV TZ=Africa/Abidjan
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime
|
||||
RUN echo $TZ > /etc/timezone
|
||||
|
||||
# set entry
|
||||
WORKDIR /base
|
||||
CMD subconverter
|
||||
|
||||
@@ -4,7 +4,7 @@ set -xe
|
||||
apk add gcc g++ build-base linux-headers cmake make autoconf automake libtool python2 python3
|
||||
apk add mbedtls-dev mbedtls-static zlib-dev rapidjson-dev zlib-static pcre2-dev
|
||||
|
||||
git clone https://github.com/curl/curl --depth=1 --branch curl-8_4_0
|
||||
git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0
|
||||
cd curl
|
||||
cmake -DCURL_USE_MBEDTLS=ON -DHTTP_ONLY=ON -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_USE_LIBSSH2=OFF -DBUILD_CURL_EXE=OFF . > /dev/null
|
||||
make install -j2 > /dev/null
|
||||
@@ -34,7 +34,7 @@ cmake -DCMAKE_BUILD_TYPE=Release .
|
||||
make libcron install -j3
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v4.3.0" --depth=1
|
||||
cd toml11
|
||||
cmake -DCMAKE_CXX_STANDARD=11 .
|
||||
make install -j4
|
||||
|
||||
@@ -41,7 +41,7 @@ sudo install -d /usr/local/include/date/
|
||||
sudo install -m644 libcron/externals/date/include/date/* /usr/local/include/date/
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v4.3.0" --depth=1
|
||||
cd toml11
|
||||
cmake -DCMAKE_CXX_STANDARD=11 .
|
||||
sudo make install -j6 > /dev/null
|
||||
@@ -63,4 +63,4 @@ chmod +r ./*
|
||||
cd ..
|
||||
mv base subconverter
|
||||
|
||||
set +xe
|
||||
set +xe
|
||||
|
||||
@@ -1,33 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -xe
|
||||
|
||||
# 获取系统架构
|
||||
ARCH=$(uname -m)
|
||||
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
TOOLCHAIN="mingw-w64-x86_64"
|
||||
else
|
||||
TOOLCHAIN="mingw-w64-i686"
|
||||
fi
|
||||
|
||||
pacman -S --needed --noconfirm base-devel ${TOOLCHAIN}-toolchain ${TOOLCHAIN}-cmake ${TOOLCHAIN}-nghttp2 ${TOOLCHAIN}-openssl
|
||||
|
||||
git clone https://github.com/curl/curl --depth=1 --branch curl-8_8_0
|
||||
git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0
|
||||
cd curl
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCURL_USE_LIBSSH2=OFF \
|
||||
-DHTTP_ONLY=ON \
|
||||
-DCURL_USE_SCHANNEL=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DBUILD_CURL_EXE=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" \
|
||||
-G "Unix Makefiles" \
|
||||
-DHAVE_LIBIDN2=OFF \
|
||||
-DCURL_USE_LIBPSL=OFF \
|
||||
-DCURL_STATICLIB=ON \
|
||||
-DCURL_DISABLE_SOCKETPAIR=ON \
|
||||
-DCURL_DISABLE_NONBLOCKING=ON .
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCURL_USE_LIBSSH2=OFF -DHTTP_ONLY=ON -DCURL_USE_SCHANNEL=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DHAVE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF .
|
||||
make install -j4
|
||||
cd ..
|
||||
|
||||
@@ -40,8 +16,26 @@ cd ..
|
||||
git clone https://github.com/ftk/quickjspp --depth=1
|
||||
cd quickjspp
|
||||
patch quickjs/quickjs-libc.c -i ../scripts/patches/0001-quickjs-libc-add-realpath-for-Windows.patch
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .
|
||||
cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_FLAGS="-D__MINGW_FENV_DEFINED" .
|
||||
make quickjs -j4
|
||||
# 如果是 32 位编译,则处理 libquickjs.a,去掉重复定义的符号
|
||||
# 注意:此处通过检测目标架构环境变量,你也可以根据实际情况加个判断
|
||||
echo "处理 32 位 libquickjs.a,去除重复定义的符号..."
|
||||
mkdir -p tmp_lib
|
||||
cd tmp_lib
|
||||
# 解包静态库
|
||||
ar x ../quickjs/libquickjs.a
|
||||
# 对每个目标文件,删除这几个符号
|
||||
for obj in *.o; do
|
||||
objcopy --strip-symbol=__mingw_fe_pc53_env --strip-symbol=__mingw_fe_pc64_env --strip-symbol=__mingw_fe_dfl_env "$obj"
|
||||
done
|
||||
# 重新打包为新的静态库
|
||||
ar rcs ../quickjs/libquickjs_fixed.a *.o
|
||||
cd ..
|
||||
# 用处理后的库覆盖原库(或直接安装新库)
|
||||
mv quickjs/libquickjs_fixed.a quickjs/libquickjs.a
|
||||
install -d "$MINGW_PREFIX/lib/quickjs/"
|
||||
install -m644 quickjs/libquickjs.a "$MINGW_PREFIX/lib/quickjs/"
|
||||
install -d "$MINGW_PREFIX/include/quickjs"
|
||||
@@ -62,7 +56,7 @@ cmake -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD
|
||||
make install -j4
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1
|
||||
git clone https://github.com/ToruNiina/toml11 --branch "v4.3.0" --depth=1
|
||||
cd toml11
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=11 .
|
||||
make install -j4
|
||||
@@ -78,4 +72,4 @@ make -j4
|
||||
rm subconverter.exe
|
||||
# shellcheck disable=SC2046
|
||||
g++ $(find CMakeFiles/subconverter.dir/src -name "*.obj") curl/lib/libcurl.a -o base/subconverter.exe -static -lbcrypt -lpcre2-8 -l:quickjs/libquickjs.a -llibcron -lyaml-cpp -liphlpapi -lcrypt32 -lws2_32 -lwsock32 -lz -s
|
||||
mv base subconverter
|
||||
mv base subconverter
|
||||
@@ -1,23 +1,23 @@
|
||||
[ACL4SSR]
|
||||
name=ACL4SSR
|
||||
url=https://github.com/ACL4SSR/ACL4SSR
|
||||
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
|
||||
branch=master
|
||||
match=Clash/*.list|Clash/Ruleset/**
|
||||
|
||||
[ACL4SSR_config]
|
||||
name=ACL4SSR
|
||||
url=https://github.com/ACL4SSR/ACL4SSR
|
||||
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
|
||||
branch=master
|
||||
match=Clash/config/**
|
||||
dest=base/config/
|
||||
keep_tree=false
|
||||
|
||||
[DivineEngine]
|
||||
url=https://github.com/asdlokj1qpi233/Profiles.git
|
||||
checkout=f6302d855192bd8d0be08319dff3e58ae7c2bd4e
|
||||
match=Surge/Ruleset/**
|
||||
|
||||
[NobyDa]
|
||||
url=https://github.com/NobyDa/Script
|
||||
checkout=ae4c12f23de8078e02c373c9969b19af28257fcb
|
||||
branch=master
|
||||
match=Surge/*.list
|
||||
|
||||
[lhie1]
|
||||
url=https://github.com/dler-io/Rules
|
||||
branch=main
|
||||
match=Surge/Surge 3/Provider/**
|
||||
|
||||
@@ -22,10 +22,13 @@ def open_repo(path: str):
|
||||
return None
|
||||
|
||||
|
||||
def update_rules(repo_path, save_path, commit, matches, keep_tree):
|
||||
def update_rules(repo_path: str, save_path: str, matches: list[str], keep_tree: bool):
|
||||
os.makedirs(save_path, exist_ok=True)
|
||||
for pattern in matches:
|
||||
files = glob.glob(os.path.join(repo_path, pattern), recursive=True)
|
||||
if len(files) == 0:
|
||||
logging.warn(f"no files found for pattern {pattern}")
|
||||
continue
|
||||
for file in files:
|
||||
if os.path.isdir(file):
|
||||
continue
|
||||
@@ -51,12 +54,13 @@ def main():
|
||||
for section in config.sections():
|
||||
repo = config.get(section, "name", fallback=section)
|
||||
url = config.get(section, "url")
|
||||
commit = config.get(section, "checkout")
|
||||
commit = config.get(section, "commit", fallback=None)
|
||||
branch = config.get(section, "branch", fallback=None)
|
||||
matches = config.get(section, "match").split("|")
|
||||
save_path = config.get(section, "dest", fallback=f"base/rules/{repo}")
|
||||
keep_tree = config.getboolean(section, "keep_tree", fallback=True)
|
||||
|
||||
logging.info(f"reading files from url {url} with commit {commit} and matches {matches}, save to {save_path} keep_tree {keep_tree}")
|
||||
logging.info(f"reading files from url {url}, matches {matches}, save to {save_path} keep_tree {keep_tree}")
|
||||
|
||||
repo_path = os.path.join("./tmp/repo/", repo)
|
||||
|
||||
@@ -67,8 +71,21 @@ def main():
|
||||
else:
|
||||
logging.info(f"repo {repo_path} exists")
|
||||
|
||||
r.git.checkout(commit)
|
||||
update_rules(repo_path, save_path, commit, matches, keep_tree)
|
||||
try:
|
||||
if commit is not None:
|
||||
logging.info(f"checking out to commit {commit}")
|
||||
r.git.checkout(commit)
|
||||
elif branch is not None:
|
||||
logging.info(f"checking out to branch {branch}")
|
||||
r.git.checkout(branch)
|
||||
else:
|
||||
logging.info(f"checking out to default branch")
|
||||
r.active_branch.checkout()
|
||||
except Exception as e:
|
||||
logging.error(f"checkout failed {e}")
|
||||
continue
|
||||
|
||||
update_rules(repo_path, save_path, matches, keep_tree)
|
||||
|
||||
shutil.rmtree("./tmp", ignore_errors=True)
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace toml
|
||||
static ProxyGroupConfig from_toml(const value& v)
|
||||
{
|
||||
ProxyGroupConfig conf;
|
||||
conf.Name = toml::find<String>(v, "name");
|
||||
String type = toml::find<String>(v, "type");
|
||||
String strategy = toml::find_or<String>(v, "strategy", "");
|
||||
conf.Name = find<String>(v, "name");
|
||||
String type = find<String>(v, "type");
|
||||
String strategy = find_or<String>(v, "strategy", "");
|
||||
switch(hash_(type))
|
||||
{
|
||||
case "select"_hash:
|
||||
@@ -27,18 +27,18 @@ namespace toml
|
||||
break;
|
||||
case "url-test"_hash:
|
||||
conf.Type = ProxyGroupType::URLTest;
|
||||
conf.Url = toml::find<String>(v, "url");
|
||||
conf.Interval = toml::find<Integer>(v, "interval");
|
||||
conf.Tolerance = toml::find_or<Integer>(v, "tolerance", 0);
|
||||
conf.Url = find<String>(v, "url");
|
||||
conf.Interval = find<Integer>(v, "interval");
|
||||
conf.Tolerance = find_or<Integer>(v, "tolerance", 0);
|
||||
if(v.contains("lazy"))
|
||||
conf.Lazy = toml::find_or<bool>(v, "lazy", false);
|
||||
conf.Lazy = find_or<bool>(v, "lazy", false);
|
||||
if(v.contains("evaluate-before-use"))
|
||||
conf.EvaluateBeforeUse = toml::find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
|
||||
conf.EvaluateBeforeUse = find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
|
||||
break;
|
||||
case "load-balance"_hash:
|
||||
conf.Type = ProxyGroupType::LoadBalance;
|
||||
conf.Url = toml::find<String>(v, "url");
|
||||
conf.Interval = toml::find<Integer>(v, "interval");
|
||||
conf.Url = find<String>(v, "url");
|
||||
conf.Interval = find<Integer>(v, "interval");
|
||||
switch(hash_(strategy))
|
||||
{
|
||||
case "consistent-hashing"_hash:
|
||||
@@ -49,14 +49,14 @@ namespace toml
|
||||
break;
|
||||
}
|
||||
if(v.contains("persistent"))
|
||||
conf.Persistent = toml::find_or(v, "persistent", conf.Persistent.get());
|
||||
conf.Persistent = find_or(v, "persistent", conf.Persistent.get());
|
||||
break;
|
||||
case "fallback"_hash:
|
||||
conf.Type = ProxyGroupType::Fallback;
|
||||
conf.Url = toml::find<String>(v, "url");
|
||||
conf.Interval = toml::find<Integer>(v, "interval");
|
||||
conf.Url = find<String>(v, "url");
|
||||
conf.Interval = find<Integer>(v, "interval");
|
||||
if(v.contains("evaluate-before-use"))
|
||||
conf.EvaluateBeforeUse = toml::find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
|
||||
conf.EvaluateBeforeUse = find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
|
||||
break;
|
||||
case "relay"_hash:
|
||||
conf.Type = ProxyGroupType::Relay;
|
||||
@@ -64,16 +64,26 @@ namespace toml
|
||||
case "ssid"_hash:
|
||||
conf.Type = ProxyGroupType::SSID;
|
||||
break;
|
||||
case "smart"_hash:
|
||||
conf.Type = ProxyGroupType::Smart;
|
||||
conf.Url = find<String>(v, "url");
|
||||
conf.Interval = find<Integer>(v, "interval");
|
||||
conf.Tolerance = find_or<Integer>(v, "tolerance", 0);
|
||||
if(v.contains("lazy"))
|
||||
conf.Lazy = find_or<bool>(v, "lazy", false);
|
||||
if(v.contains("evaluate-before-use"))
|
||||
conf.EvaluateBeforeUse = find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
|
||||
break;
|
||||
default:
|
||||
throw toml::syntax_error("Proxy Group has incorrect type, should be one of following:\n select, url-test, load-balance, fallback, relay, ssid", v.at("type").location());
|
||||
throw serialization_error(format_error("Proxy Group has unsupported type!", v.at("type").location(), "should be one of following: select, url-test, load-balance, fallback, relay, ssid"), v.at("type").location());
|
||||
}
|
||||
conf.Timeout = toml::find_or(v, "timeout", 5);
|
||||
conf.Proxies = toml::find_or<StrArray>(v, "rule", {});
|
||||
conf.UsingProvider = toml::find_or<StrArray>(v, "use", {});
|
||||
conf.Timeout = find_or(v, "timeout", 5);
|
||||
conf.Proxies = find_or<StrArray>(v, "rule", {});
|
||||
conf.UsingProvider = find_or<StrArray>(v, "use", {});
|
||||
if(conf.Proxies.empty() && conf.UsingProvider.empty())
|
||||
throw toml::syntax_error("Proxy Group must contains at least one of proxy match rule or provider", v.location());
|
||||
throw serialization_error(format_error("Proxy Group must contains at least one of proxy match rule or provider!", v.location(), "here"), v.location());
|
||||
if(v.contains("disable-udp"))
|
||||
conf.DisableUdp = toml::find_or(v, "disable-udp", conf.DisableUdp.get());
|
||||
conf.DisableUdp = find_or(v, "disable-udp", conf.DisableUdp.get());
|
||||
return conf;
|
||||
}
|
||||
};
|
||||
@@ -84,8 +94,8 @@ namespace toml
|
||||
static RulesetConfig from_toml(const value& v)
|
||||
{
|
||||
RulesetConfig conf;
|
||||
conf.Group = toml::find<String>(v, "group");
|
||||
String type = toml::find_or<String>(v, "type", "surge-ruleset");
|
||||
conf.Group = find<String>(v, "group");
|
||||
String type = find_or<String>(v, "type", "surge-ruleset");
|
||||
switch(hash_(type))
|
||||
{
|
||||
/*
|
||||
@@ -122,10 +132,10 @@ namespace toml
|
||||
conf.Url = type + ":";
|
||||
break;
|
||||
default:
|
||||
throw toml::syntax_error("Ruleset has incorrect type, should be one of following:\n surge-ruleset, quantumultx, clash-domain, clash-ipcidr, clash-classic", v.at("type").location());
|
||||
throw serialization_error(format_error("Ruleset has unsupported type!", v.at("type").location(), "should be one of following: surge-ruleset, quantumultx, clash-domain, clash-ipcidr, clash-classic"), v.at("type").location());
|
||||
}
|
||||
conf.Url += toml::find<String>(v, "ruleset");
|
||||
conf.Interval = toml::find_or<Integer>(v, "interval", 86400);
|
||||
conf.Url += find<String>(v, "ruleset");
|
||||
conf.Interval = find_or<Integer>(v, "interval", 86400);
|
||||
return conf;
|
||||
}
|
||||
};
|
||||
@@ -138,14 +148,14 @@ namespace toml
|
||||
RegexMatchConfig conf;
|
||||
if(v.contains("script"))
|
||||
{
|
||||
conf.Script = toml::find<String>(v, "script");
|
||||
conf.Script = find<String>(v, "script");
|
||||
return conf;
|
||||
}
|
||||
conf.Match = toml::find<String>(v, "match");
|
||||
conf.Match = find<String>(v, "match");
|
||||
if(v.contains("emoji"))
|
||||
conf.Replace = toml::find<String>(v, "emoji");
|
||||
conf.Replace = find<String>(v, "emoji");
|
||||
else
|
||||
conf.Replace = toml::find<String>(v, "replace");
|
||||
conf.Replace = find<String>(v, "replace");
|
||||
return conf;
|
||||
}
|
||||
};
|
||||
@@ -156,10 +166,10 @@ namespace toml
|
||||
static CronTaskConfig from_toml(const value& v)
|
||||
{
|
||||
CronTaskConfig conf;
|
||||
conf.Name = toml::find<String>(v, "name");
|
||||
conf.CronExp = toml::find<String>(v, "cronexp");
|
||||
conf.Path = toml::find<String>(v, "path");
|
||||
conf.Timeout = toml::find_or<Integer>(v, "timeout", 0);
|
||||
conf.Name = find<String>(v, "name");
|
||||
conf.CronExp = find<String>(v, "cronexp");
|
||||
conf.Path = find<String>(v, "path");
|
||||
conf.Timeout = find_or<Integer>(v, "timeout", 0);
|
||||
return conf;
|
||||
}
|
||||
};
|
||||
@@ -220,6 +230,9 @@ namespace INIBinding
|
||||
case "ssid"_hash:
|
||||
conf.Type = ProxyGroupType::SSID;
|
||||
break;
|
||||
case "smart"_hash:
|
||||
conf.Type = ProxyGroupType::Smart;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
|
||||
#include "def.h"
|
||||
|
||||
enum ProxyGroupType
|
||||
enum class ProxyGroupType
|
||||
{
|
||||
Select,
|
||||
URLTest,
|
||||
Fallback,
|
||||
LoadBalance,
|
||||
Relay,
|
||||
SSID
|
||||
SSID,
|
||||
Smart
|
||||
};
|
||||
|
||||
enum BalanceStrategy
|
||||
enum class BalanceStrategy
|
||||
{
|
||||
ConsistentHashing,
|
||||
RoundRobin
|
||||
@@ -45,6 +46,7 @@ struct ProxyGroupConfig
|
||||
case ProxyGroupType::Fallback: return "fallback";
|
||||
case ProxyGroupType::Relay: return "relay";
|
||||
case ProxyGroupType::SSID: return "ssid";
|
||||
case ProxyGroupType::Smart: return "smart";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "def.h"
|
||||
|
||||
enum RulesetType
|
||||
enum class RulesetType
|
||||
{
|
||||
SurgeRuleset,
|
||||
QuantumultX,
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
/// rule type lists
|
||||
#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL"
|
||||
string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME"};
|
||||
// 新增meta路由规则
|
||||
//string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME"};
|
||||
string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME", "DOMAIN-REGEX", "GEOSITE", "IP-SUFFIX", "IP-ASN", "SRC-GEOIP", "SRC-IP-ASN", "SRC-IP-SUFFIX", "IN-PORT", "IN-TYPE", "IN-USER", "IN-NAME", "PROCESS-PATH-REGEX", "PROCESS-PATH", "PROCESS-NAME-REGEX", "UID", "NETWORK", "DSCP", "SUB-RULE", "RULE-SET", "AND", "OR", "NOT"};
|
||||
string_array Surge2RuleTypes = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
|
||||
string_array SurgeRuleTypes = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
|
||||
string_array QuanXRuleTypes = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"};
|
||||
@@ -248,8 +250,26 @@ std::string rulesetToClashStr(YAML::Node &base_rule, std::vector<RulesetContent>
|
||||
strLine.erase(strLine.find("//"));
|
||||
strLine = trimWhitespace(strLine);
|
||||
}
|
||||
strLine = transformRuleToCommon(temp, strLine, rule_group);
|
||||
output_content += " - " + strLine + "\n";
|
||||
|
||||
//AND & OR & NOT
|
||||
if(startsWith(strLine, "AND") || startsWith(strLine, "OR") || startsWith(strLine, "NOT"))
|
||||
{
|
||||
output_content += " - " + strLine + "," + rule_group + "\n";
|
||||
}
|
||||
//SUB-RULE & RULE-SET
|
||||
else if (startsWith(strLine, "SUB-RULE") || startsWith(strLine, "RULE-SET"))
|
||||
{
|
||||
output_content += " - " + strLine + "\n";
|
||||
}
|
||||
else
|
||||
//OTHER
|
||||
{
|
||||
strLine = transformRuleToCommon(temp, strLine, rule_group);
|
||||
output_content += " - " + strLine + "\n";
|
||||
}
|
||||
|
||||
//strLine = transformRuleToCommon(temp, strLine, rule_group);
|
||||
//output_content += " - " + strLine + "\n";
|
||||
total_rules++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,18 @@
|
||||
|
||||
extern string_array ss_ciphers, ssr_ciphers;
|
||||
|
||||
const string_array clashr_protocols = {"origin", "auth_sha1_v4", "auth_aes128_md5", "auth_aes128_sha1", "auth_chain_a",
|
||||
"auth_chain_b"};
|
||||
const string_array clashr_obfs = {"plain", "http_simple", "http_post", "random_head", "tls1.2_ticket_auth",
|
||||
"tls1.2_ticket_fastauth"};
|
||||
const string_array clash_ssr_ciphers = {"rc4-md5", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb",
|
||||
"aes-192-cfb", "aes-256-cfb", "chacha20-ietf", "xchacha20", "none"};
|
||||
const string_array clashr_protocols = {
|
||||
"origin", "auth_sha1_v4", "auth_aes128_md5", "auth_aes128_sha1", "auth_chain_a",
|
||||
"auth_chain_b"
|
||||
};
|
||||
const string_array clashr_obfs = {
|
||||
"plain", "http_simple", "http_post", "random_head", "tls1.2_ticket_auth",
|
||||
"tls1.2_ticket_fastauth"
|
||||
};
|
||||
const string_array clash_ssr_ciphers = {
|
||||
"rc4-md5", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb",
|
||||
"aes-192-cfb", "aes-256-cfb", "chacha20-ietf", "xchacha20", "none"
|
||||
};
|
||||
|
||||
std::string
|
||||
vmessLinkConstruct(const std::string &remarks, const std::string &add, const std::string &port, const std::string &type,
|
||||
@@ -70,7 +76,8 @@ bool matchRange(const std::string &range, int target) {
|
||||
bool match = false;
|
||||
std::string range_begin_str, range_end_str;
|
||||
int range_begin, range_end;
|
||||
static const std::string reg_num = "-?\\d+", reg_range = "(\\d+)-(\\d+)", reg_not = "\\!-?(\\d+)", reg_not_range = "\\!(\\d+)-(\\d+)", reg_less = "(\\d+)-", reg_more = "(\\d+)\\+";
|
||||
static const std::string reg_num = "-?\\d+", reg_range = "(\\d+)-(\\d+)", reg_not = "\\!-?(\\d+)", reg_not_range =
|
||||
"\\!(\\d+)-(\\d+)", reg_less = "(\\d+)-", reg_more = "(\\d+)\\+";
|
||||
for (std::string &x: vArray) {
|
||||
if (regMatch(x, reg_num)) {
|
||||
if (to_int(x, INT_MAX) == target)
|
||||
@@ -105,20 +112,24 @@ bool matchRange(const std::string &range, int target) {
|
||||
|
||||
bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &node) {
|
||||
std::string target, ret_real_rule;
|
||||
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)";
|
||||
static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex = R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)";
|
||||
static const std::map<ProxyType, const char *> types = {{ProxyType::Shadowsocks, "SS"},
|
||||
{ProxyType::ShadowsocksR, "SSR"},
|
||||
{ProxyType::VMess, "VMESS"},
|
||||
{ProxyType::Trojan, "TROJAN"},
|
||||
{ProxyType::Snell, "SNELL"},
|
||||
{ProxyType::HTTP, "HTTP"},
|
||||
{ProxyType::HTTPS, "HTTPS"},
|
||||
{ProxyType::SOCKS5, "SOCKS5"},
|
||||
{ProxyType::WireGuard, "WIREGUARD"},
|
||||
{ProxyType::VLESS, "VLESS"},
|
||||
{ProxyType::Hysteria, "HYSTERIA"},
|
||||
{ProxyType::Hysteria2, "HYSTERIA2"}};
|
||||
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex =
|
||||
R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)";
|
||||
static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex =
|
||||
R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)";
|
||||
static const std::map<ProxyType, const char *> types = {
|
||||
{ProxyType::Shadowsocks, "SS"},
|
||||
{ProxyType::ShadowsocksR, "SSR"},
|
||||
{ProxyType::VMess, "VMESS"},
|
||||
{ProxyType::Trojan, "TROJAN"},
|
||||
{ProxyType::Snell, "SNELL"},
|
||||
{ProxyType::HTTP, "HTTP"},
|
||||
{ProxyType::HTTPS, "HTTPS"},
|
||||
{ProxyType::SOCKS5, "SOCKS5"},
|
||||
{ProxyType::WireGuard, "WIREGUARD"},
|
||||
{ProxyType::VLESS, "VLESS"},
|
||||
{ProxyType::Hysteria, "HYSTERIA"},
|
||||
{ProxyType::Hysteria2, "HYSTERIA2"}
|
||||
};
|
||||
if (startsWith(rule, "!!GROUP=")) {
|
||||
regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule);
|
||||
real_rule = ret_real_rule;
|
||||
@@ -149,7 +160,7 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &
|
||||
|
||||
void processRemark(std::string &remark, const string_array &remarks_list, bool proc_comma = true) {
|
||||
// Replace every '=' with '-' in the remark string to avoid parse errors from the clients.
|
||||
// Surge is tested to yield an error when handling '=' in the remark string,
|
||||
// Surge is tested to yield an error when handling '=' in the remark string,
|
||||
// not sure if other clients have the same problem.
|
||||
std::replace(remark.begin(), remark.end(), '=', '-');
|
||||
|
||||
@@ -184,8 +195,7 @@ groupGenerate(const std::string &rule, std::vector<Proxy> &nodelist, string_arra
|
||||
auto filter = (std::function<std::string(const std::vector<Proxy> &)>) ctx.eval("filter");
|
||||
std::string result_list = filter(nodelist);
|
||||
filtered_nodelist = split(regTrim(result_list), "\n");
|
||||
}
|
||||
catch (qjs::exception) {
|
||||
} catch (qjs::exception) {
|
||||
script_print_stack(ctx);
|
||||
}
|
||||
}, global.scriptCleanContext);
|
||||
@@ -207,16 +217,28 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
std::vector<Proxy> nodelist;
|
||||
string_array remarks_list;
|
||||
/// proxies style
|
||||
bool block = false, compact = false;
|
||||
|
||||
bool proxy_block = false, proxy_compact = false, group_block = false, group_compact = false;
|
||||
switch (hash_(ext.clash_proxies_style)) {
|
||||
case "block"_hash:
|
||||
block = true;
|
||||
proxy_block = true;
|
||||
break;
|
||||
default:
|
||||
case "flow"_hash:
|
||||
break;
|
||||
case "compact"_hash:
|
||||
compact = true;
|
||||
proxy_compact = true;
|
||||
break;
|
||||
}
|
||||
switch (hash_(ext.clash_proxy_groups_style)) {
|
||||
case "block"_hash:
|
||||
group_block = true;
|
||||
break;
|
||||
default:
|
||||
case "flow"_hash:
|
||||
break;
|
||||
case "compact"_hash:
|
||||
group_compact = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -333,8 +355,9 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
case ProxyType::ShadowsocksR:
|
||||
//ignoring all nodes with unsupported obfs, protocols and encryption
|
||||
if (ext.filter_deprecated) {
|
||||
if (!clashR && std::find(clash_ssr_ciphers.cbegin(), clash_ssr_ciphers.cend(), x.EncryptMethod) ==
|
||||
clash_ssr_ciphers.cend())
|
||||
if (!clashR &&
|
||||
std::find(clash_ssr_ciphers.cbegin(), clash_ssr_ciphers.cend(), x.EncryptMethod) ==
|
||||
clash_ssr_ciphers.cend())
|
||||
continue;
|
||||
if (std::find(clashr_protocols.cbegin(), clashr_protocols.cend(), x.Protocol) ==
|
||||
clashr_protocols.cend())
|
||||
@@ -541,7 +564,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
singleproxy["tfo"] = tfo.get();
|
||||
if (xudp && udp)
|
||||
singleproxy["xudp"] = true;
|
||||
if(!x.PacketEncoding.empty()){
|
||||
if (!x.PacketEncoding.empty()) {
|
||||
singleproxy["packet-encoding"] = x.PacketEncoding;
|
||||
}
|
||||
if (!x.Flow.empty())
|
||||
@@ -614,7 +637,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
// sees in https://dreamacro.github.io/clash/configuration/outbound.html#snell
|
||||
if (udp && x.Type != ProxyType::Snell && x.Type != ProxyType::TUIC)
|
||||
singleproxy["udp"] = true;
|
||||
if (block)
|
||||
if(proxy_block)
|
||||
singleproxy.SetStyle(YAML::EmitterStyle::Block);
|
||||
else
|
||||
singleproxy.SetStyle(YAML::EmitterStyle::Flow);
|
||||
@@ -623,7 +646,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
nodelist.emplace_back(x);
|
||||
}
|
||||
|
||||
if (compact)
|
||||
if(proxy_compact)
|
||||
proxies.SetStyle(YAML::EmitterStyle::Flow);
|
||||
|
||||
if (ext.nodelist) {
|
||||
@@ -639,68 +662,84 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
yamlnode["Proxy"] = proxies;
|
||||
|
||||
|
||||
for (const ProxyGroupConfig &x: extra_proxy_group) {
|
||||
for(const ProxyGroupConfig &x : extra_proxy_group)
|
||||
{
|
||||
YAML::Node singlegroup;
|
||||
string_array filtered_nodelist;
|
||||
|
||||
singlegroup["name"] = x.Name;
|
||||
singlegroup["type"] = x.TypeStr();
|
||||
if (x.Type == ProxyGroupType::Smart)
|
||||
singlegroup["type"] = "url-test";
|
||||
else
|
||||
singlegroup["type"] = x.TypeStr();
|
||||
|
||||
switch (x.Type) {
|
||||
case ProxyGroupType::Select:
|
||||
case ProxyGroupType::Relay:
|
||||
break;
|
||||
case ProxyGroupType::LoadBalance:
|
||||
singlegroup["strategy"] = x.StrategyStr();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::URLTest:
|
||||
if (!x.Lazy.is_undef())
|
||||
singlegroup["lazy"] = x.Lazy.get();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Fallback:
|
||||
singlegroup["url"] = x.Url;
|
||||
if (x.Interval > 0)
|
||||
singlegroup["interval"] = x.Interval;
|
||||
if (x.Tolerance > 0)
|
||||
singlegroup["tolerance"] = x.Tolerance;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
switch(x.Type)
|
||||
{
|
||||
case ProxyGroupType::Select:
|
||||
case ProxyGroupType::Relay:
|
||||
break;
|
||||
case ProxyGroupType::LoadBalance:
|
||||
singlegroup["strategy"] = x.StrategyStr();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Smart:
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::URLTest:
|
||||
if(!x.Lazy.is_undef())
|
||||
singlegroup["lazy"] = x.Lazy.get();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Fallback:
|
||||
singlegroup["url"] = x.Url;
|
||||
if(x.Interval > 0)
|
||||
singlegroup["interval"] = x.Interval;
|
||||
if(x.Tolerance > 0)
|
||||
singlegroup["tolerance"] = x.Tolerance;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (!x.DisableUdp.is_undef())
|
||||
if(!x.DisableUdp.is_undef())
|
||||
singlegroup["disable-udp"] = x.DisableUdp.get();
|
||||
|
||||
for (const auto &y: x.Proxies)
|
||||
for(const auto& y : x.Proxies)
|
||||
groupGenerate(y, nodelist, filtered_nodelist, true, ext);
|
||||
|
||||
if (!x.UsingProvider.empty())
|
||||
if(!x.UsingProvider.empty())
|
||||
singlegroup["use"] = x.UsingProvider;
|
||||
else {
|
||||
if (filtered_nodelist.empty())
|
||||
else
|
||||
{
|
||||
if(filtered_nodelist.empty())
|
||||
filtered_nodelist.emplace_back("DIRECT");
|
||||
}
|
||||
if (!filtered_nodelist.empty())
|
||||
if(!filtered_nodelist.empty())
|
||||
singlegroup["proxies"] = filtered_nodelist;
|
||||
//singlegroup.SetStyle(YAML::EmitterStyle::Flow);
|
||||
if(group_block)
|
||||
singlegroup.SetStyle(YAML::EmitterStyle::Block);
|
||||
else
|
||||
singlegroup.SetStyle(YAML::EmitterStyle::Flow);
|
||||
|
||||
bool replace_flag = false;
|
||||
for (auto &&original_group: original_groups) {
|
||||
if (original_group["name"].as<std::string>() == x.Name) {
|
||||
for(auto && original_group : original_groups)
|
||||
{
|
||||
if(original_group["name"].as<std::string>() == x.Name)
|
||||
{
|
||||
original_group.reset(singlegroup);
|
||||
replace_flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!replace_flag)
|
||||
if(!replace_flag)
|
||||
original_groups.push_back(singlegroup);
|
||||
}
|
||||
if(group_compact)
|
||||
original_groups.SetStyle(YAML::EmitterStyle::Flow);
|
||||
|
||||
if (ext.clash_new_field_name)
|
||||
if(ext.clash_new_field_name)
|
||||
yamlnode["proxy-groups"] = original_groups;
|
||||
else
|
||||
yamlnode["Proxy Group"] = original_groups;
|
||||
}
|
||||
|
||||
|
||||
void formatterShortId(std::string &input) {
|
||||
std::string target = "short-id:";
|
||||
size_t startPos = input.find(target);
|
||||
@@ -726,18 +765,17 @@ void formatterShortId(std::string &input) {
|
||||
// 继续查找下一个实例
|
||||
startPos = input.find(target, startPos + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string proxyToClash(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
const ProxyGroupConfigs &extra_proxy_group,
|
||||
bool clashR, extra_settings &ext) {
|
||||
YAML::Node yamlnode;
|
||||
|
||||
try {
|
||||
yamlnode = YAML::Load(base_conf);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
} catch (std::exception &e) {
|
||||
writeLog(0, std::string("Clash base loader failed with error: ") + e.what(), LOG_LEVEL_ERROR);
|
||||
return "";
|
||||
}
|
||||
@@ -805,7 +843,8 @@ std::string generatePeer(Proxy &node, bool client_id_as_reserved = false) {
|
||||
}
|
||||
|
||||
std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
const ProxyGroupConfigs &extra_proxy_group,
|
||||
int surge_ver, extra_settings &ext) {
|
||||
INIReader ini;
|
||||
std::string output_nodelist;
|
||||
@@ -840,8 +879,11 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
|
||||
processRemark(x.Remark, remarks_list);
|
||||
|
||||
std::string &hostname = x.Hostname, &sni = x.ServerName, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &edge = x.Edge, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption;
|
||||
std::string port = std::to_string(x.Port);
|
||||
std::string &hostname = x.Hostname, &sni = x.ServerName, &username = x.Username, &password = x.Password, &method
|
||||
= x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &edge = x.Edge, &
|
||||
path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.
|
||||
OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption, &underlying_proxy = x.UnderlyingProxy;
|
||||
std::string port = std::to_string(x.Port);;
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
|
||||
tribool udp = ext.udp, tfo = ext.tfo, scv = ext.skip_cert_verify, tls13 = ext.tls13;
|
||||
@@ -856,7 +898,8 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
switch (x.Type) {
|
||||
case ProxyType::Shadowsocks:
|
||||
if (surge_ver >= 3 || surge_ver == -3) {
|
||||
proxy = "ss, " + hostname + ", " + port + ", encrypt-method=" + method + ", password=" + password;
|
||||
proxy = "ss, " + hostname + ", " + port + ", encrypt-method=" + method + ", password=" +
|
||||
password;
|
||||
} else {
|
||||
proxy = "custom, " + hostname + ", " + port + ", " + method + ", " + password +
|
||||
", https://github.com/pobizhe/SSEncrypt/raw/master/SSEncrypt.module";
|
||||
@@ -905,8 +948,10 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
if (ext.surge_ssr_path.empty() || surge_ver < 2)
|
||||
continue;
|
||||
proxy = "external, exec=\"" + ext.surge_ssr_path + "\", args=\"";
|
||||
args = {"-l", std::to_string(local_port), "-s", hostname, "-p", port, "-m", method, "-k", password,
|
||||
"-o", obfs, "-O", protocol};
|
||||
args = {
|
||||
"-l", std::to_string(local_port), "-s", hostname, "-p", port, "-m", method, "-k", password,
|
||||
"-o", obfs, "-O", protocol
|
||||
};
|
||||
if (!obfsparam.empty()) {
|
||||
args.emplace_back("-g");
|
||||
args.emplace_back(std::move(obfsparam));
|
||||
@@ -975,11 +1020,18 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
proxy += ", version=" + std::to_string(x.SnellVersion);
|
||||
break;
|
||||
case ProxyType::Hysteria2:
|
||||
if (surge_ver < 4 && surge_ver != -3)
|
||||
if (surge_ver < 4)
|
||||
continue;
|
||||
proxy = "hysteria2, " + hostname + ", " + port + ", password=" + password;
|
||||
proxy = "hysteria, " + hostname + ", " + port + ", password=" + password;
|
||||
if (x.DownSpeed)
|
||||
proxy += ", download-bandwidth=" + x.DownSpeed;
|
||||
|
||||
if (!scv.is_undef())
|
||||
proxy += ", skip-cert-verify=" + scv.get_str();
|
||||
proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false");
|
||||
if (!x.Fingerprint.empty())
|
||||
proxy += ",server-cert-fingerprint-sha256=" + x.Fingerprint;
|
||||
if (!x.SNI.empty())
|
||||
proxy += ",sni=" + x.SNI;
|
||||
break;
|
||||
case ProxyType::WireGuard:
|
||||
if (surge_ver < 4 && surge_ver != -3)
|
||||
@@ -1011,7 +1063,8 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
proxy += ", tfo=" + tfo.get_str();
|
||||
if (!udp.is_undef())
|
||||
proxy += ", udp-relay=" + udp.get_str();
|
||||
|
||||
if (underlying_proxy != "")
|
||||
proxy += ", underlying-proxy=" + underlying_proxy;
|
||||
if (ext.nodelist)
|
||||
output_nodelist += x.Remark + " = " + proxy + "\n";
|
||||
else {
|
||||
@@ -1032,6 +1085,7 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
|
||||
switch (x.Type) {
|
||||
case ProxyGroupType::Select:
|
||||
case ProxyGroupType::Smart:
|
||||
case ProxyGroupType::URLTest:
|
||||
case ProxyGroupType::Fallback:
|
||||
break;
|
||||
@@ -1084,7 +1138,8 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
}
|
||||
|
||||
if (ext.enable_rule_generator)
|
||||
rulesetToSurge(ini, ruleset_content_array, surge_ver, ext.overwrite_original_rules, ext.managed_config_prefix);
|
||||
rulesetToSurge(ini, ruleset_content_array, surge_ver, ext.overwrite_original_rules,
|
||||
ext.managed_config_prefix);
|
||||
|
||||
return ini.to_string();
|
||||
}
|
||||
@@ -1096,7 +1151,12 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
||||
|
||||
for (Proxy &x: nodes) {
|
||||
std::string remark = x.Remark;
|
||||
std::string &hostname = x.Hostname, &sni = x.ServerName, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &faketype = x.FakeType;
|
||||
std::string &hostname = x.Hostname, &sni = x.ServerName, &password = x.Password, &method = x.EncryptMethod, &
|
||||
plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.
|
||||
ProtocolParam,
|
||||
&obfs = x.OBFS, &obfsparam = x.OBFSParam, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.
|
||||
Host, &
|
||||
path = x.Path, &faketype = x.FakeType;
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
std::string port = std::to_string(x.Port);
|
||||
std::string aid = std::to_string(x.AlterId);
|
||||
@@ -1113,23 +1173,28 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
||||
if (std::find(ssr_ciphers.begin(), ssr_ciphers.end(), method) != ssr_ciphers.end() &&
|
||||
plugin.empty())
|
||||
proxyStr = "ssr://" + urlSafeBase64Encode(
|
||||
hostname + ":" + port + ":origin:" + method + ":plain:" + urlSafeBase64Encode(password) \
|
||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(remark));
|
||||
hostname + ":" + port + ":origin:" + method + ":plain:" +
|
||||
urlSafeBase64Encode(password)
|
||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(
|
||||
remark));
|
||||
} else
|
||||
continue;
|
||||
break;
|
||||
case ProxyType::ShadowsocksR:
|
||||
if (ssr) {
|
||||
proxyStr = "ssr://" + urlSafeBase64Encode(
|
||||
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
||||
urlSafeBase64Encode(password) \
|
||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(remark) \
|
||||
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" + urlSafeBase64Encode(protoparam));
|
||||
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
||||
urlSafeBase64Encode(password)
|
||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(
|
||||
remark)
|
||||
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" +
|
||||
urlSafeBase64Encode(protoparam));
|
||||
} else if (ss) {
|
||||
if (std::find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() &&
|
||||
protocol == "origin" && obfs == "plain")
|
||||
proxyStr =
|
||||
"ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" + port +
|
||||
"ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" +
|
||||
port +
|
||||
"#" + urlEncode(remark);
|
||||
} else
|
||||
continue;
|
||||
@@ -1138,8 +1203,8 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
||||
if (!vmess)
|
||||
continue;
|
||||
proxyStr = "vmess://" + base64Encode(
|
||||
vmessLinkConstruct(remark, hostname, port, faketype, id, aid, transproto, path, host,
|
||||
tlssecure ? "tls" : ""));
|
||||
vmessLinkConstruct(remark, hostname, port, faketype, id, aid, transproto, path, host,
|
||||
tlssecure ? "tls" : ""));
|
||||
break;
|
||||
case ProxyType::Trojan:
|
||||
if (!trojan)
|
||||
@@ -1181,7 +1246,8 @@ std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra
|
||||
base_conf = "{}";
|
||||
rapidjson::ParseResult result = base.Parse(base_conf.data());
|
||||
if (!result)
|
||||
writeLog(0, std::string("SIP008 base loader failed with error: ") + rapidjson::GetParseError_En(result.Code()) +
|
||||
writeLog(0, std::string("SIP008 base loader failed with error: ") +
|
||||
rapidjson::GetParseError_En(result.Code()) +
|
||||
" (" + std::to_string(result.Offset()) + ")", LOG_LEVEL_ERROR);
|
||||
|
||||
rapidjson::Value proxies(rapidjson::kArrayType);
|
||||
@@ -1210,20 +1276,21 @@ std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra
|
||||
}
|
||||
rapidjson::Value proxy(rapidjson::kObjectType);
|
||||
proxy.CopyFrom(base, alloc)
|
||||
| AddMemberOrReplace("remarks", rapidjson::Value(remark.c_str(), remark.size()), alloc)
|
||||
| AddMemberOrReplace("server", rapidjson::Value(hostname.c_str(), hostname.size()), alloc)
|
||||
| AddMemberOrReplace("server_port", rapidjson::Value(x.Port), alloc)
|
||||
| AddMemberOrReplace("method", rapidjson::Value(method.c_str(), method.size()), alloc)
|
||||
| AddMemberOrReplace("password", rapidjson::Value(password.c_str(), password.size()), alloc)
|
||||
| AddMemberOrReplace("plugin", rapidjson::Value(plugin.c_str(), plugin.size()), alloc)
|
||||
| AddMemberOrReplace("plugin_opts", rapidjson::Value(pluginopts.c_str(), pluginopts.size()), alloc);
|
||||
| AddMemberOrReplace("remarks", rapidjson::Value(remark.c_str(), remark.size()), alloc)
|
||||
| AddMemberOrReplace("server", rapidjson::Value(hostname.c_str(), hostname.size()), alloc)
|
||||
| AddMemberOrReplace("server_port", rapidjson::Value(x.Port), alloc)
|
||||
| AddMemberOrReplace("method", rapidjson::Value(method.c_str(), method.size()), alloc)
|
||||
| AddMemberOrReplace("password", rapidjson::Value(password.c_str(), password.size()), alloc)
|
||||
| AddMemberOrReplace("plugin", rapidjson::Value(plugin.c_str(), plugin.size()), alloc)
|
||||
| AddMemberOrReplace("plugin_opts", rapidjson::Value(pluginopts.c_str(), pluginopts.size()), alloc);
|
||||
proxies.PushBack(proxy, alloc);
|
||||
}
|
||||
return proxies | SerializeObject();
|
||||
}
|
||||
|
||||
std::string
|
||||
proxyToQuan(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector<RulesetContent> &ruleset_content_array,
|
||||
proxyToQuan(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
|
||||
INIReader ini;
|
||||
ini.store_any_line = true;
|
||||
@@ -1261,7 +1328,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
|
||||
processRemark(x.Remark, remarks_list);
|
||||
|
||||
std::string &hostname = x.Hostname, &method = x.EncryptMethod, &password = x.Password, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &edge = x.Edge, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption, &username = x.Username;
|
||||
std::string &hostname = x.Hostname, &method = x.EncryptMethod, &password = x.Password, &id = x.UserId, &
|
||||
transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &edge = x.Edge, &protocol = x.
|
||||
Protocol,
|
||||
&protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts
|
||||
= x.
|
||||
PluginOption, &username = x.Username;
|
||||
std::string port = std::to_string(x.Port);
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
tribool scv;
|
||||
@@ -1274,7 +1346,8 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
if (method == "auto")
|
||||
method = "chacha20-ietf-poly1305";
|
||||
proxyStr =
|
||||
x.Remark + " = vmess, " + hostname + ", " + port + ", " + method + ", \"" + id + "\", group=" +
|
||||
x.Remark + " = vmess, " + hostname + ", " + port + ", " + method + ", \"" + id +
|
||||
"\", group=" +
|
||||
x.Group;
|
||||
if (tlssecure) {
|
||||
proxyStr += ", over-tls=true, tls-host=" + host;
|
||||
@@ -1294,10 +1367,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
case ProxyType::ShadowsocksR:
|
||||
if (ext.nodelist) {
|
||||
proxyStr = "ssr://" + urlSafeBase64Encode(
|
||||
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
||||
urlSafeBase64Encode(password) \
|
||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(x.Remark) \
|
||||
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" + urlSafeBase64Encode(protoparam));
|
||||
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
||||
urlSafeBase64Encode(password)
|
||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(
|
||||
x.Remark)
|
||||
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" +
|
||||
urlSafeBase64Encode(protoparam));
|
||||
} else {
|
||||
proxyStr = x.Remark + " = shadowsocksr, " + hostname + ", " + port + ", " + method + ", \"" +
|
||||
password + "\", group=" + x.Group + ", protocol=" + protocol + ", obfs=" + obfs;
|
||||
@@ -1316,7 +1391,8 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
proxyStr += "&group=" + urlSafeBase64Encode(x.Group) + "#" + urlEncode(x.Remark);
|
||||
} else {
|
||||
proxyStr =
|
||||
x.Remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" + password +
|
||||
x.Remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" +
|
||||
password +
|
||||
"\", group=" + x.Group;
|
||||
if (plugin == "obfs-local" && !pluginopts.empty()) {
|
||||
proxyStr += ", " + replaceAllDistinct(pluginopts, ";", ", ");
|
||||
@@ -1325,11 +1401,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
break;
|
||||
case ProxyType::HTTP:
|
||||
case ProxyType::HTTPS:
|
||||
proxyStr = x.Remark + " = http, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port +
|
||||
", group=" + x.Group;
|
||||
proxyStr =
|
||||
x.Remark + " = http, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port +
|
||||
", group=" + x.Group;
|
||||
if (!username.empty() && !password.empty())
|
||||
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username +
|
||||
", upstream-proxy-password=" + password;
|
||||
", upstream-proxy-password=" + password;
|
||||
else
|
||||
proxyStr += ", upstream-proxy-auth=false";
|
||||
|
||||
@@ -1345,11 +1422,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
proxyStr = "http://" + urlSafeBase64Encode(proxyStr);
|
||||
break;
|
||||
case ProxyType::SOCKS5:
|
||||
proxyStr = x.Remark + " = socks, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port +
|
||||
proxyStr = x.Remark + " = socks, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" +
|
||||
port +
|
||||
", group=" + x.Group;
|
||||
if (!username.empty() && !password.empty())
|
||||
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username +
|
||||
", upstream-proxy-password=" + password;
|
||||
", upstream-proxy-password=" + password;
|
||||
else
|
||||
proxyStr += ", upstream-proxy-auth=false";
|
||||
|
||||
@@ -1439,7 +1517,8 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
||||
}
|
||||
|
||||
std::string proxyToQuanX(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
const ProxyGroupConfigs &extra_proxy_group,
|
||||
extra_settings &ext) {
|
||||
INIReader ini;
|
||||
ini.store_any_line = true;
|
||||
@@ -1485,7 +1564,10 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
||||
|
||||
processRemark(x.Remark, remarks_list);
|
||||
|
||||
std::string &hostname = x.Hostname, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &password = x.Password, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &username = x.Username;
|
||||
std::string &hostname = x.Hostname, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol,
|
||||
&host = x.Host, &path = x.Path, &password = x.Password, &plugin = x.Plugin, &pluginopts = x.PluginOption
|
||||
, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &
|
||||
username = x.Username;
|
||||
std::string port = std::to_string(x.Port);
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
|
||||
@@ -1536,7 +1618,8 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
||||
proxyStr += ", obfs=over-tls, obfs-host=" + host;
|
||||
break;
|
||||
case ProxyType::Shadowsocks:
|
||||
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
|
||||
proxyStr =
|
||||
"shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
|
||||
if (!plugin.empty()) {
|
||||
switch (hash_(plugin)) {
|
||||
case "simple-obfs"_hash:
|
||||
@@ -1568,8 +1651,9 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
||||
|
||||
break;
|
||||
case ProxyType::ShadowsocksR:
|
||||
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password +
|
||||
", ssr-protocol=" + protocol;
|
||||
proxyStr =
|
||||
"shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password +
|
||||
", ssr-protocol=" + protocol;
|
||||
if (!protoparam.empty())
|
||||
proxyStr += ", ssr-protocol-param=" + protoparam;
|
||||
proxyStr += ", obfs=" + obfs;
|
||||
@@ -1578,8 +1662,9 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
||||
break;
|
||||
case ProxyType::HTTP:
|
||||
case ProxyType::HTTPS:
|
||||
proxyStr = "http = " + hostname + ":" + port + ", username=" + (username.empty() ? "none" : username) +
|
||||
", password=" + (password.empty() ? "none" : password);
|
||||
proxyStr =
|
||||
"http = " + hostname + ":" + port + ", username=" + (username.empty() ? "none" : username) +
|
||||
", password=" + (password.empty() ? "none" : password);
|
||||
if (tlssecure) {
|
||||
proxyStr += ", over-tls=true";
|
||||
if (!tls13.is_undef())
|
||||
@@ -1693,7 +1778,7 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
||||
std::string proxies = join(filtered_nodelist, ", ");
|
||||
|
||||
std::string singlegroup = type + "=" + x.Name + ", " + proxies;
|
||||
if (type != "static") {
|
||||
if (x.Type != ProxyGroupType::Select && x.Type != ProxyGroupType::SSID) {
|
||||
singlegroup += ", check-interval=" + std::to_string(x.Interval);
|
||||
if (x.Tolerance > 0)
|
||||
singlegroup += ", tolerance=" + std::to_string(x.Tolerance);
|
||||
@@ -1724,9 +1809,10 @@ std::string proxyToSSD(std::vector<Proxy> &nodes, std::string &group, std::strin
|
||||
writer.String("password");
|
||||
if (!userinfo.empty()) {
|
||||
std::string data = replaceAllDistinct(userinfo, "; ", "&");
|
||||
std::string upload = getUrlArg(data, "upload"), download = getUrlArg(data, "download"), total = getUrlArg(data,
|
||||
"total"), expiry = getUrlArg(
|
||||
data, "expire");
|
||||
std::string upload = getUrlArg(data, "upload"), download = getUrlArg(data, "download"), total = getUrlArg(
|
||||
data,
|
||||
"total"), expiry = getUrlArg(
|
||||
data, "expire");
|
||||
double used = (to_number(upload, 0.0) + to_number(download, 0.0)) / std::pow(1024, 3) * 1.0, tot =
|
||||
to_number(total, 0.0) / std::pow(1024, 3) * 1.0;
|
||||
writer.Key("traffic_used");
|
||||
@@ -1746,7 +1832,8 @@ std::string proxyToSSD(std::vector<Proxy> &nodes, std::string &group, std::strin
|
||||
writer.StartArray();
|
||||
|
||||
for (Proxy &x: nodes) {
|
||||
std::string &hostname = x.Hostname, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &obfs = x.OBFS;
|
||||
std::string &hostname = x.Hostname, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &
|
||||
pluginopts = x.PluginOption, &protocol = x.Protocol, &obfs = x.OBFS;
|
||||
|
||||
switch (x.Type) {
|
||||
case ProxyType::Shadowsocks:
|
||||
@@ -1848,7 +1935,8 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
|
||||
case ProxyType::Shadowsocks:
|
||||
if (!x.Plugin.empty())
|
||||
continue;
|
||||
proxy = x.Remark + ", ss, ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" +
|
||||
proxy = x.Remark + ", ss, ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname +
|
||||
":" +
|
||||
port;
|
||||
break;
|
||||
case ProxyType::VMess:
|
||||
@@ -1883,11 +1971,13 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
|
||||
proxy += "&sockopt.tcpfastopen=" + tfo.get_str();
|
||||
break;
|
||||
case ProxyType::SOCKS5:
|
||||
proxy = x.Remark + ", builtin, socks, address=" + hostname + ", port=" + port + ", user=" + username +
|
||||
proxy = x.Remark + ", builtin, socks, address=" + hostname + ", port=" + port + ", user=" +
|
||||
username +
|
||||
", pass=" + password;
|
||||
break;
|
||||
case ProxyType::HTTP:
|
||||
proxy = x.Remark + ", builtin, http, address=" + hostname + ", port=" + port + ", user=" + username +
|
||||
proxy = x.Remark + ", builtin, http, address=" + hostname + ", port=" + port + ", user=" +
|
||||
username +
|
||||
", pass=" + password;
|
||||
break;
|
||||
default:
|
||||
@@ -1952,7 +2042,8 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
|
||||
}
|
||||
|
||||
std::string
|
||||
proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector<RulesetContent> &ruleset_content_array,
|
||||
proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
|
||||
INIReader ini;
|
||||
std::string output_nodelist;
|
||||
@@ -1977,7 +2068,10 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
|
||||
}
|
||||
processRemark(x.Remark, remarks_list);
|
||||
|
||||
std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam;
|
||||
std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &
|
||||
plugin = x.Plugin, &pluginopts = x.PluginOption, &id = x.UserId, &transproto = x.TransferProtocol, &host
|
||||
= x.Host, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &
|
||||
obfsparam = x.OBFSParam;
|
||||
std::string port = std::to_string(x.Port), aid = std::to_string(x.AlterId);
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
|
||||
@@ -1992,7 +2086,8 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
|
||||
if (plugin == "simple-obfs" || plugin == "obfs-local") {
|
||||
if (!pluginopts.empty())
|
||||
proxy += "," +
|
||||
replaceAllDistinct(replaceAllDistinct(pluginopts, ";obfs-host=", ","), "obfs=", "");
|
||||
replaceAllDistinct(replaceAllDistinct(pluginopts, ";obfs-host=", ","), "obfs=",
|
||||
"");
|
||||
} else if (!plugin.empty())
|
||||
continue;
|
||||
break;
|
||||
@@ -2177,7 +2272,8 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
|
||||
if (x.Type != ProxyGroupType::Select) {
|
||||
group += ",url=" + x.Url + ",interval=" + std::to_string(x.Interval);
|
||||
if (x.Type == ProxyGroupType::LoadBalance) {
|
||||
group += ",algorithm=" + std::string(x.Strategy == BalanceStrategy::RoundRobin ? "round-robin" : "pcc");
|
||||
group += ",algorithm=" +
|
||||
std::string(x.Strategy == BalanceStrategy::RoundRobin ? "round-robin" : "pcc");
|
||||
if (x.Timeout > 0)
|
||||
group += ",max-timeout=" + std::to_string(x.Timeout);
|
||||
}
|
||||
@@ -2294,7 +2390,8 @@ bool isNumeric(const std::string &str) {
|
||||
}
|
||||
|
||||
void
|
||||
proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector<RulesetContent> &ruleset_content_array,
|
||||
proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
|
||||
using namespace rapidjson_ext;
|
||||
rapidjson::Document::AllocatorType &allocator = json.GetAllocator();
|
||||
@@ -2342,16 +2439,16 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
}
|
||||
break;
|
||||
}
|
||||
// case ProxyType::ShadowsocksR: {
|
||||
// addSingBoxCommonMembers(proxy, x, "shadowsocksr", allocator);
|
||||
// proxy.AddMember("method", rapidjson::StringRef(x.EncryptMethod.c_str()), allocator);
|
||||
// proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
||||
// proxy.AddMember("protocol", rapidjson::StringRef(x.Protocol.c_str()), allocator);
|
||||
// proxy.AddMember("protocol_param", rapidjson::StringRef(x.ProtocolParam.c_str()), allocator);
|
||||
// proxy.AddMember("obfs", rapidjson::StringRef(x.OBFS.c_str()), allocator);
|
||||
// proxy.AddMember("obfs_param", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
|
||||
// break;
|
||||
// }
|
||||
// case ProxyType::ShadowsocksR: {
|
||||
// addSingBoxCommonMembers(proxy, x, "shadowsocksr", allocator);
|
||||
// proxy.AddMember("method", rapidjson::StringRef(x.EncryptMethod.c_str()), allocator);
|
||||
// proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
||||
// proxy.AddMember("protocol", rapidjson::StringRef(x.Protocol.c_str()), allocator);
|
||||
// proxy.AddMember("protocol_param", rapidjson::StringRef(x.ProtocolParam.c_str()), allocator);
|
||||
// proxy.AddMember("obfs", rapidjson::StringRef(x.OBFS.c_str()), allocator);
|
||||
// proxy.AddMember("obfs_param", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
|
||||
// break;
|
||||
// }
|
||||
case ProxyType::VMess: {
|
||||
addSingBoxCommonMembers(proxy, x, "vmess", allocator);
|
||||
proxy.AddMember("uuid", rapidjson::StringRef(x.UserId.c_str()), allocator);
|
||||
@@ -2370,7 +2467,7 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
proxy.AddMember("packet_encoding", rapidjson::StringRef("xudp"), allocator);
|
||||
if (!x.Flow.empty())
|
||||
proxy.AddMember("flow", rapidjson::StringRef(x.Flow.c_str()), allocator);
|
||||
if(!x.PacketEncoding.empty()){
|
||||
if (!x.PacketEncoding.empty()) {
|
||||
proxy.AddMember("packet_encoding", rapidjson::StringRef(x.PacketEncoding.c_str()), allocator);
|
||||
}
|
||||
rapidjson::Value vlesstransport(rapidjson::kObjectType);
|
||||
@@ -2431,8 +2528,8 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
proxy.AddMember("inet4_bind_address", rapidjson::StringRef(x.SelfIP.c_str()), allocator);
|
||||
rapidjson::Value addresses(rapidjson::kArrayType);
|
||||
addresses.PushBack(rapidjson::StringRef(x.SelfIP.append("/32").c_str()), allocator);
|
||||
// if (!x.SelfIPv6.empty())
|
||||
// addresses.PushBack(rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
||||
// if (!x.SelfIPv6.empty())
|
||||
// addresses.PushBack(rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
||||
proxy.AddMember("local_address", addresses, allocator);
|
||||
if (!x.SelfIPv6.empty())
|
||||
proxy.AddMember("inet6_bind_address", rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
||||
@@ -2520,7 +2617,6 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
addSingBoxCommonMembers(proxy, x, "hysteria2", allocator);
|
||||
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
||||
if (!x.TLSSecure) {
|
||||
|
||||
rapidjson::Value tls(rapidjson::kObjectType);
|
||||
tls.AddMember("enabled", true, allocator);
|
||||
if (!x.ServerName.empty())
|
||||
@@ -2560,7 +2656,6 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
obfs.AddMember("password", rapidjson::StringRef(x.OBFSPassword.c_str()), allocator);
|
||||
}
|
||||
proxy.AddMember("obfs", obfs, allocator);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2586,7 +2681,8 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
proxy.AddMember("tls", tls, allocator);
|
||||
}
|
||||
if (!x.CongestionControl.empty()) {
|
||||
proxy.AddMember("congestion_control", rapidjson::StringRef(x.CongestionControl.c_str()), allocator);
|
||||
proxy.AddMember("congestion_control", rapidjson::StringRef(x.CongestionControl.c_str()),
|
||||
allocator);
|
||||
}
|
||||
if (!x.UdpRelayMode.empty()) {
|
||||
proxy.AddMember("udp_relay_mode", rapidjson::StringRef(x.UdpRelayMode.c_str()), allocator);
|
||||
@@ -2623,7 +2719,7 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
||||
if (!x.PublicKey.empty()) {
|
||||
reality.AddMember("public_key", rapidjson::StringRef(x.PublicKey.c_str()), allocator);
|
||||
}
|
||||
// auto shortIds = stringArrayToJsonArray(x.ShortId, ",", allocator);
|
||||
// auto shortIds = stringArrayToJsonArray(x.ShortId, ",", allocator);
|
||||
if (!x.ShortId.empty()) {
|
||||
reality.AddMember("short_id", rapidjson::StringRef(x.ShortId.c_str()), allocator);
|
||||
} else {
|
||||
|
||||
@@ -40,6 +40,7 @@ struct extra_settings
|
||||
bool clash_classical_ruleset = false;
|
||||
std::string sort_script;
|
||||
std::string clash_proxies_style = "flow";
|
||||
std::string clash_proxy_groups_style = "flow";
|
||||
bool authorized = false;
|
||||
|
||||
extra_settings() = default;
|
||||
|
||||
@@ -357,10 +357,10 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
if(x.rule_type == RULESET_CLASH_IPCIDR || x.rule_type == RULESET_CLASH_DOMAIN || x.rule_type == RULESET_CLASH_CLASSICAL)
|
||||
{
|
||||
//rule_name = std::to_string(hash_(rule_group + rule_path));
|
||||
rule_name = old_rule_name = findFileName(rule_path);
|
||||
rule_name = old_rule_name = urlDecode(findFileName(rule_path));
|
||||
int idx = 2;
|
||||
while(std::find(groups.begin(), groups.end(), rule_name) != groups.end())
|
||||
rule_name = old_rule_name + "_" + std::to_string(idx++);
|
||||
rule_name = old_rule_name + " " + std::to_string(idx++);
|
||||
names[rule_name] = rule_group;
|
||||
urls[rule_name] = "*" + rule_path;
|
||||
rule_type[rule_name] = x.rule_type;
|
||||
@@ -386,10 +386,10 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
if(fileExist(rule_path, true) || isLink(rule_path))
|
||||
{
|
||||
//rule_name = std::to_string(hash_(rule_group + rule_path));
|
||||
rule_name = old_rule_name = findFileName(rule_path);
|
||||
rule_name = old_rule_name = urlDecode(findFileName(rule_path));
|
||||
int idx = 2;
|
||||
while(std::find(groups.begin(), groups.end(), rule_name) != groups.end())
|
||||
rule_name = old_rule_name + "_" + std::to_string(idx++);
|
||||
rule_name = old_rule_name + " " + std::to_string(idx++);
|
||||
names[rule_name] = rule_group;
|
||||
urls[rule_name] = rule_path_typed;
|
||||
rule_type[rule_name] = x.rule_type;
|
||||
@@ -436,9 +436,9 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
if(vArray.size() < 2)
|
||||
continue;
|
||||
if(keywords.find(rule_name) == keywords.end())
|
||||
keywords[rule_name] = "\"" + vArray[1] + "\"";
|
||||
keywords[rule_name] = "\"" + trim(vArray[1]) + "\"";
|
||||
else
|
||||
keywords[rule_name] += ",\"" + vArray[1] + "\"";
|
||||
keywords[rule_name] += ",\"" + trim(vArray[1]) + "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -449,7 +449,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
}
|
||||
else
|
||||
{
|
||||
strLine = vArray[0] + "," + vArray[1] + "," + rule_group;
|
||||
strLine = vArray[0] + "," + trim(vArray[1]) + "," + rule_group;
|
||||
if(vArray.size() > 2)
|
||||
strLine += "," + vArray[2];
|
||||
}
|
||||
@@ -466,14 +466,16 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
}
|
||||
}
|
||||
if(has_domain[rule_name] && !script)
|
||||
rules.emplace_back("RULE-SET," + rule_name + "_domain," + rule_group);
|
||||
rules.emplace_back("RULE-SET," + rule_name + " (Domain)," + rule_group);
|
||||
if(has_ipcidr[rule_name] && !script)
|
||||
{
|
||||
if(has_no_resolve)
|
||||
rules.emplace_back("RULE-SET," + rule_name + "_ipcidr," + rule_group + ",no-resolve");
|
||||
rules.emplace_back("RULE-SET," + rule_name + " (IP-CIDR)," + rule_group + ",no-resolve");
|
||||
else
|
||||
rules.emplace_back("RULE-SET," + rule_name + "_ipcidr," + rule_group);
|
||||
rules.emplace_back("RULE-SET," + rule_name + " (IP-CIDR)," + rule_group);
|
||||
}
|
||||
if(!has_domain[rule_name] && !has_ipcidr[rule_name] && !script)
|
||||
rules.emplace_back("RULE-SET," + rule_name + "," + rule_group);
|
||||
if(std::find(groups.begin(), groups.end(), rule_name) == groups.end())
|
||||
groups.emplace_back(rule_name);
|
||||
}
|
||||
@@ -488,14 +490,14 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
{
|
||||
std::string yaml_key = x;
|
||||
if(rule_type[x] != RULESET_CLASH_DOMAIN)
|
||||
yaml_key += "_domain";
|
||||
yaml_key += " (Domain)";
|
||||
base_rule["rule-providers"][yaml_key]["type"] = "http";
|
||||
base_rule["rule-providers"][yaml_key]["behavior"] = "domain";
|
||||
if(url[0] == '*')
|
||||
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
||||
else
|
||||
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=3&url=" + urlSafeBase64Encode(url);
|
||||
base_rule["rule-providers"][yaml_key]["path"] = "./providers/rule-provider_" + yaml_key + ".yaml";
|
||||
base_rule["rule-providers"][yaml_key]["path"] = "./providers/" + std::to_string(hash_(url)) + "_domain.yaml";
|
||||
if(interval)
|
||||
base_rule["rule-providers"][yaml_key]["interval"] = interval;
|
||||
}
|
||||
@@ -503,14 +505,14 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
{
|
||||
std::string yaml_key = x;
|
||||
if(rule_type[x] != RULESET_CLASH_IPCIDR)
|
||||
yaml_key += "_ipcidr";
|
||||
yaml_key += " (IP-CIDR)";
|
||||
base_rule["rule-providers"][yaml_key]["type"] = "http";
|
||||
base_rule["rule-providers"][yaml_key]["behavior"] = "ipcidr";
|
||||
if(url[0] == '*')
|
||||
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
||||
else
|
||||
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=4&url=" + urlSafeBase64Encode(url);
|
||||
base_rule["rule-providers"][yaml_key]["path"] = "./providers/rule-provider_" + yaml_key + ".yaml";
|
||||
base_rule["rule-providers"][yaml_key]["path"] = "./providers/" + std::to_string(hash_(url)) + "_ipcidr.yaml";
|
||||
if(interval)
|
||||
base_rule["rule-providers"][yaml_key]["interval"] = interval;
|
||||
}
|
||||
@@ -523,7 +525,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
||||
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
||||
else
|
||||
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=6&url=" + urlSafeBase64Encode(url);
|
||||
base_rule["rule-providers"][yaml_key]["path"] = "./providers/rule-provider_" + yaml_key + ".yaml";
|
||||
base_rule["rule-providers"][yaml_key]["path"] = "./providers/" + std::to_string(hash_(url)) + ".yaml";
|
||||
if(interval)
|
||||
base_rule["rule-providers"][yaml_key]["interval"] = interval;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -564,14 +564,14 @@ void readYAMLConf(YAML::Node &node)
|
||||
writeLog(0, "Load preference settings in YAML format completed.", LOG_LEVEL_INFO);
|
||||
}
|
||||
|
||||
//template <class T, class... U>
|
||||
//void find_if_exist(const toml::value &v, const toml::key &k, T& target, U&&... args)
|
||||
//{
|
||||
// if(v.contains(k)) target = toml::find<T>(v, k);
|
||||
// if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
||||
//}
|
||||
template <class T, class... U>
|
||||
void find_if_exist(const toml::value &v, const toml::value::key_type &k, T& target, U&&... args)
|
||||
{
|
||||
if(v.contains(k)) target = toml::find<T>(v, k);
|
||||
if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
||||
}
|
||||
|
||||
void operate_toml_kv_table(const std::vector<toml::table> &arr, const toml::key &key_name, const toml::key &value_name, std::function<void (const toml::value&, const toml::value&)> binary_op)
|
||||
void operate_toml_kv_table(const std::vector<toml::table> &arr, const toml::value::key_type &key_name, const toml::value::key_type &value_name, std::function<void (const toml::value&, const toml::value&)> binary_op)
|
||||
{
|
||||
for(const toml::table &table : arr)
|
||||
{
|
||||
@@ -800,7 +800,7 @@ void readConf()
|
||||
return readYAMLConf(yaml);
|
||||
}
|
||||
toml::value conf = parseToml(prefdata, global.prefPath);
|
||||
if(!conf.is_uninitialized() && toml::find_or<int>(conf, "version", 0))
|
||||
if(!conf.is_empty() && toml::find_or<int>(conf, "version", 0))
|
||||
return readTOMLConf(conf);
|
||||
}
|
||||
catch (YAML::Exception &e)
|
||||
@@ -1209,7 +1209,7 @@ int loadExternalConfig(std::string &path, ExternalConfig &ext)
|
||||
if(yaml.size() && yaml["custom"].IsDefined())
|
||||
return loadExternalYAML(yaml, ext);
|
||||
toml::value conf = parseToml(base_content, path);
|
||||
if(!conf.is_uninitialized() && toml::find_or<int>(conf, "version", 0))
|
||||
if(!conf.is_empty() && toml::find_or<int>(conf, "version", 0))
|
||||
return loadExternalTOML(conf, ext);
|
||||
}
|
||||
catch (YAML::Exception &e)
|
||||
|
||||
@@ -49,7 +49,7 @@ struct Settings
|
||||
tribool UDPFlag, TFOFlag, skipCertVerify, TLS13Flag, enableInsert;
|
||||
bool enableSort = false, updateStrict = false;
|
||||
bool clashUseNewField = false, singBoxAddClashModes = true;
|
||||
std::string clashProxiesStyle = "flow";
|
||||
std::string clashProxiesStyle = "flow", clashProxyGroupsStyle = "block";
|
||||
std::string proxyConfig, proxyRuleset, proxySubscription;
|
||||
int updateInterval = 0;
|
||||
std::string sortScript, filterScript;
|
||||
@@ -101,12 +101,12 @@ extern Settings global;
|
||||
|
||||
int importItems(string_array &target, bool scope_limit = true);
|
||||
int loadExternalConfig(std::string &path, ExternalConfig &ext);
|
||||
template <class T, class... U>
|
||||
void find_if_exist(const toml::value &v, const toml::key &k, T& target, U&&... args)
|
||||
{
|
||||
if(v.contains(k)) target = toml::find<T>(v, k);
|
||||
if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
||||
}
|
||||
//template <class T, class... U>
|
||||
//void find_if_exist(const toml::value &v, const toml::key &k, T& target, U&&... args)
|
||||
//{
|
||||
// if(v.contains(k)) target = toml::find<T>(v, k);
|
||||
// if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
||||
//}
|
||||
template <class... Args>
|
||||
void parseGroupTimes(const std::string &src, Args... args)
|
||||
{
|
||||
|
||||
@@ -87,11 +87,13 @@ static int logger(CURL *handle, curl_infotype type, char *data, size_t size, voi
|
||||
switch(type)
|
||||
{
|
||||
case CURLINFO_TEXT:
|
||||
prefix = "CURL_INFO";
|
||||
prefix = "CURL_INFO: ";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
prefix = "CURL_HEADER: < ";
|
||||
break;
|
||||
case CURLINFO_HEADER_OUT:
|
||||
prefix = "CURL_HEADER";
|
||||
prefix = "CURL_HEADER: > ";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
case CURLINFO_DATA_OUT:
|
||||
@@ -105,7 +107,6 @@ static int logger(CURL *handle, curl_infotype type, char *data, size_t size, voi
|
||||
for(auto &x : lines)
|
||||
{
|
||||
std::string log_content = prefix;
|
||||
log_content += ": ";
|
||||
log_content += x;
|
||||
writeLog(0, log_content, LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
@@ -113,7 +114,6 @@ static int logger(CURL *handle, curl_infotype type, char *data, size_t size, voi
|
||||
else
|
||||
{
|
||||
std::string log_content = prefix;
|
||||
log_content += ": ";
|
||||
log_content += trimWhitespace(content);
|
||||
writeLog(0, log_content, LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
@@ -172,7 +172,8 @@ static int curlGet(const FetchArgument &argument, FetchResult &result)
|
||||
{
|
||||
for(auto &x : *argument.request_headers)
|
||||
{
|
||||
header_list = curl_slist_append(header_list, (x.first + ": " + x.second).data());
|
||||
auto header = x.first + ": " + x.second;
|
||||
header_list = curl_slist_append(header_list, header.data());
|
||||
}
|
||||
if(!argument.request_headers->contains("User-Agent"))
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent_str);
|
||||
@@ -233,7 +234,7 @@ static int curlGet(const FetchArgument &argument, FetchResult &result)
|
||||
while(true)
|
||||
{
|
||||
retVal = curl_easy_perform(curl_handle);
|
||||
if(retVal == CURLE_OK || max_fails <= fail_count)
|
||||
if(retVal == CURLE_OK || max_fails <= fail_count || global.APIMode)
|
||||
break;
|
||||
else
|
||||
fail_count++;
|
||||
|
||||
@@ -233,10 +233,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
std::string type = getUrlArg(request.argument, "type");
|
||||
if(type == "form")
|
||||
fileWrite(global.prefPath, getFormData(request.postdata), true);
|
||||
else if(type == "direct")
|
||||
if(type == "form" || type == "direct")
|
||||
{
|
||||
fileWrite(global.prefPath, request.postdata, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.status_code = 501;
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
using String = std::string;
|
||||
using StringArray = std::vector<String>;
|
||||
|
||||
enum class ProxyType {
|
||||
enum class ProxyType
|
||||
{
|
||||
Unknown,
|
||||
Shadowsocks,
|
||||
ShadowsocksR,
|
||||
@@ -126,10 +127,14 @@ struct Proxy {
|
||||
String Flow;
|
||||
bool FlowShow = false;
|
||||
tribool DisableSni;
|
||||
uint32_t UpSpeed;
|
||||
uint32_t DownSpeed;
|
||||
String SNI;
|
||||
tribool ReduceRtt;
|
||||
String UdpRelayMode = "native";
|
||||
uint16_t RequestTimeout = 15000;
|
||||
String token;
|
||||
String UnderlyingProxy;
|
||||
std::vector<String> AlpnList;
|
||||
String PacketEncoding;
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ std::string modSSMD5 = "f7653207090ce3389115e9c88541afe0";
|
||||
|
||||
void commonConstruct(Proxy &node, ProxyType type, const std::string &group, const std::string &remarks,
|
||||
const std::string &server, const std::string &port, const tribool &udp, const tribool &tfo,
|
||||
const tribool &scv, const tribool &tls13) {
|
||||
const tribool &scv, const tribool &tls13,const std::string& underlying_proxy) {
|
||||
node.Type = type;
|
||||
node.Group = group;
|
||||
node.Remark = remarks;
|
||||
@@ -46,6 +46,7 @@ void commonConstruct(Proxy &node, ProxyType type, const std::string &group, cons
|
||||
node.TCPFastOpen = tfo;
|
||||
node.AllowInsecure = scv;
|
||||
node.TLS13 = tls13;
|
||||
node.UnderlyingProxy = underlying_proxy;
|
||||
}
|
||||
|
||||
void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
||||
@@ -53,8 +54,8 @@ void vmessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
const std::string &net, const std::string &cipher, const std::string &path, const std::string &host,
|
||||
const std::string &edge, const std::string &tls, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList, tribool udp, tribool tfo,
|
||||
tribool scv, tribool tls13) {
|
||||
commonConstruct(node, ProxyType::VMess, group, remarks, add, port, udp, tfo, scv, tls13);
|
||||
tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::VMess, group, remarks, add, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
|
||||
node.AlterId = to_int(aid);
|
||||
node.EncryptMethod = cipher;
|
||||
@@ -76,8 +77,8 @@ void vmessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &protocol, const std::string &method,
|
||||
const std::string &obfs, const std::string &password, const std::string &obfsparam,
|
||||
const std::string &protoparam, tribool udp, tribool tfo, tribool scv) {
|
||||
commonConstruct(node, ProxyType::ShadowsocksR, group, remarks, server, port, udp, tfo, scv, tribool());
|
||||
const std::string &protoparam, tribool udp, tribool tfo, tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::ShadowsocksR, group, remarks, server, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
node.Password = password;
|
||||
node.EncryptMethod = method;
|
||||
node.Protocol = protocol;
|
||||
@@ -89,8 +90,8 @@ void ssrConstruct(Proxy &node, const std::string &group, const std::string &rema
|
||||
void ssConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &password, const std::string &method,
|
||||
const std::string &plugin, const std::string &pluginopts, tribool udp, tribool tfo, tribool scv,
|
||||
tribool tls13) {
|
||||
commonConstruct(node, ProxyType::Shadowsocks, group, remarks, server, port, udp, tfo, scv, tls13);
|
||||
tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Shadowsocks, group, remarks, server, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
node.Password = password;
|
||||
node.EncryptMethod = method;
|
||||
node.Plugin = plugin;
|
||||
@@ -99,17 +100,17 @@ void ssConstruct(Proxy &node, const std::string &group, const std::string &remar
|
||||
|
||||
void socksConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &username, const std::string &password, tribool udp,
|
||||
tribool tfo, tribool scv) {
|
||||
commonConstruct(node, ProxyType::SOCKS5, group, remarks, server, port, udp, tfo, scv, tribool());
|
||||
tribool tfo, tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::SOCKS5, group, remarks, server, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
node.Username = username;
|
||||
node.Password = password;
|
||||
}
|
||||
|
||||
void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &username, const std::string &password, bool tls,
|
||||
tribool tfo, tribool scv, tribool tls13) {
|
||||
tribool tfo, tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, tls ? ProxyType::HTTPS : ProxyType::HTTP, group, remarks, server, port, tribool(), tfo, scv,
|
||||
tls13);
|
||||
tls13,underlying_proxy);
|
||||
node.Username = username;
|
||||
node.Password = password;
|
||||
node.TLSSecure = tls;
|
||||
@@ -121,8 +122,8 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
|
||||
const std::vector<std::string> &alpnList,
|
||||
bool tlssecure,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv, tribool tls13) {
|
||||
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13);
|
||||
tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
node.Password = password;
|
||||
node.Host = host;
|
||||
node.TLSSecure = tlssecure;
|
||||
@@ -135,8 +136,8 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
|
||||
|
||||
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &password, const std::string &obfs,
|
||||
const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv) {
|
||||
commonConstruct(node, ProxyType::Snell, group, remarks, server, port, udp, tfo, scv, tribool());
|
||||
const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Snell, group, remarks, server, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
node.Password = password;
|
||||
node.OBFS = obfs;
|
||||
node.Host = host;
|
||||
@@ -147,8 +148,8 @@ void wireguardConstruct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &port, const std::string &selfIp, const std::string &selfIpv6,
|
||||
const std::string &privKey, const std::string &pubKey, const std::string &psk,
|
||||
const string_array &dns, const std::string &mtu, const std::string &keepalive,
|
||||
const std::string &testUrl, const std::string &clientId, const tribool &udp) {
|
||||
commonConstruct(node, ProxyType::WireGuard, group, remarks, server, port, udp, tribool(), tribool(), tribool());
|
||||
const std::string &testUrl, const std::string &clientId, const tribool &udp,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::WireGuard, group, remarks, server, port, udp, tribool(), tribool(), tribool(),underlying_proxy);
|
||||
node.SelfIP = selfIp;
|
||||
node.SelfIPv6 = selfIpv6;
|
||||
node.PrivateKey = privKey;
|
||||
@@ -168,8 +169,8 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &obfsParam, const std::string &insecure, const std::string &ports,
|
||||
const std::string &sni, tribool udp,
|
||||
tribool tfo, tribool scv,
|
||||
tribool tls13) {
|
||||
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13);
|
||||
tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
node.Auth = auth;
|
||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||
node.UpMbps = up;
|
||||
@@ -191,8 +192,8 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
const std::string &pbk, const std::string &sid, const std::string &fp, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList,const std::string &packet_encoding,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv, tribool tls13) {
|
||||
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13);
|
||||
tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
|
||||
node.AlterId = to_int(aid);
|
||||
node.EncryptMethod = cipher;
|
||||
@@ -231,8 +232,8 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &obfsParam, const std::string &obfsPassword, const std::string &sni,
|
||||
const std::string &publicKey, const std::string &ports,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv) {
|
||||
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool());
|
||||
tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
node.Password = password;
|
||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||
node.UpMbps = up;
|
||||
@@ -251,8 +252,8 @@ void tuicConstruct(Proxy &node, const std::string &group, const std::string &rem
|
||||
const std::string &sni, const std::string &uuid, const std::string &udpRelayMode,
|
||||
const std::string &token,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv, tribool reduceRtt, tribool disableSni, uint16_t request_timeout) {
|
||||
commonConstruct(node, ProxyType::TUIC, group, remarks, add, port, udp, tfo, scv, tribool());
|
||||
tribool scv, tribool reduceRtt, tribool disableSni, uint16_t request_timeout,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::TUIC, group, remarks, add, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
node.Password = password;
|
||||
node.Alpn = alpn;
|
||||
node.ServerName = sni;
|
||||
@@ -1309,7 +1310,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
singleproxy["ipv6"] >>= ipv6;
|
||||
|
||||
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
||||
dns_server, mtu, "0", "", "", udp);
|
||||
dns_server, mtu, "0", "", "", udp,"");
|
||||
break;
|
||||
case "vless"_hash:
|
||||
group = XRAY_DEFAULT_GROUP;
|
||||
@@ -1582,7 +1583,7 @@ void explodeStdVless(std::string vless, Proxy &node) {
|
||||
remarks = urlDecode(vless.substr(pos + 1));
|
||||
vless.erase(pos);
|
||||
}
|
||||
const std::string stdvless_matcher = R"(^([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})@\[?([\d\-a-zA-Z:.]+)\]?:(\d+)(?:\/?\?(.*))?$)";
|
||||
const std::string stdvless_matcher = R"(^([\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12})@\[?([\d\-a-zA-Z:.]+)\]?:(\d+)(?:\/?\?(.*))?$)";
|
||||
if (regGetMatch(vless, stdvless_matcher, 5, 0, &id, &add, &port, &addition))
|
||||
return;
|
||||
|
||||
@@ -2160,7 +2161,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
|
||||
wireguardConstruct(node, WG_DEFAULT_GROUP, remarks, "", "0", ip, ipv6, private_key, "", "", dns_servers,
|
||||
mtu, keepalive, test_url, "", udp);
|
||||
mtu, keepalive, test_url, "", udp,"");
|
||||
parsePeers(node, peer);
|
||||
break;
|
||||
default:
|
||||
@@ -2823,7 +2824,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
password = GetMember(singboxNode, "pre_shared_key");
|
||||
dns_server = {"8.8.8.8"};
|
||||
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
||||
dns_server, mtu, "0", "", "", udp);
|
||||
dns_server, mtu, "0", "", "", udp,"");
|
||||
break;
|
||||
case "socks"_hash:
|
||||
group = SOCKS_DEFAULT_GROUP;
|
||||
|
||||
@@ -25,7 +25,7 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &down, const std::string &alpn, const std::string &obfsParam,
|
||||
const std::string &insecure, const std::string &ports, const std::string &sni,
|
||||
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||
tribool tls13 = tribool());
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
||||
const std::string &port, const std::string &password, const std::string &host,
|
||||
@@ -33,7 +33,7 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &obfsParam, const std::string &obfsPassword, const std::string &sni,
|
||||
const std::string &publicKey, const std::string &ports,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv);
|
||||
tribool scv,const std::string& underlying_proxy="");
|
||||
|
||||
void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
||||
const std::string &port, const std::string &type, const std::string &id, const std::string &aid,
|
||||
@@ -42,45 +42,45 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
const std::string &pkd, const std::string &sid, const std::string &fp, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList,const std::string &packet_encoding,
|
||||
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||
tribool tls13 = tribool());
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
||||
const std::string &port, const std::string &type, const std::string &id, const std::string &aid,
|
||||
const std::string &net, const std::string &cipher, const std::string &path, const std::string &host,
|
||||
const std::string &edge, const std::string &tls, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList, tribool udp = tribool(),
|
||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &protocol, const std::string &method,
|
||||
const std::string &obfs, const std::string &password, const std::string &obfsparam,
|
||||
const std::string &protoparam, tribool udp = tribool(), tribool tfo = tribool(),
|
||||
tribool scv = tribool());
|
||||
tribool scv = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void ssConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &password, const std::string &method,
|
||||
const std::string &plugin, const std::string &pluginopts, tribool udp = tribool(),
|
||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void socksConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &username, const std::string &password,
|
||||
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &username, const std::string &password, bool tls,
|
||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &password, const std::string &network,
|
||||
const std::string &host, const std::string &path, const std::string &fp, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList,
|
||||
bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||
tribool tls13 = tribool());
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
||||
const std::string &port, const std::string &password, const std::string &obfs,
|
||||
const std::string &host, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(),
|
||||
tribool scv = tribool());
|
||||
tribool scv = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void tuicConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
||||
const std::string &port, const std::string &password, const std::string &congestion_control,
|
||||
@@ -89,7 +89,7 @@ void tuicConstruct(Proxy &node, const std::string &group, const std::string &rem
|
||||
const std::string &token,
|
||||
tribool udp = tribool(), tribool tfo = tribool(),
|
||||
tribool scv = tribool(), tribool reduceRtt = tribool(), tribool disableSni = tribool(),
|
||||
uint16_t request_timeout = 15000);
|
||||
uint16_t request_timeout = 15000,const std::string& underlying_proxy="");
|
||||
|
||||
void explodeVmess(std::string vmess, Proxy &node);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <quickjspp.hpp>
|
||||
#include <utility>
|
||||
#include <quickjs/quickjs-libc.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -226,7 +227,7 @@ public:
|
||||
qjs_fetch_Headers headers;
|
||||
std::string cookies;
|
||||
std::string postdata;
|
||||
explicit qjs_fetch_Request(const std::string &url) : url(url) {}
|
||||
explicit qjs_fetch_Request(std::string url) : url(std::move(url)) {}
|
||||
};
|
||||
|
||||
class qjs_fetch_Response
|
||||
@@ -389,7 +390,7 @@ void script_runtime_init(qjs::Runtime &runtime)
|
||||
js_std_init_handlers(runtime.rt);
|
||||
}
|
||||
|
||||
int ShowMsgbox(const std::string &title, std::string content, uint16_t type = 0)
|
||||
int ShowMsgbox(const std::string &title, const std::string &content, uint16_t type = 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(!type)
|
||||
@@ -424,7 +425,7 @@ struct Lambda {
|
||||
|
||||
uint32_t currentTime()
|
||||
{
|
||||
return time(NULL);
|
||||
return time(nullptr);
|
||||
}
|
||||
|
||||
int script_context_init(qjs::Context &context)
|
||||
@@ -525,7 +526,7 @@ int script_context_init(qjs::Context &context)
|
||||
)", "<import>", JS_EVAL_TYPE_MODULE);
|
||||
return 0;
|
||||
}
|
||||
catch(qjs::exception)
|
||||
catch(qjs::exception&)
|
||||
{
|
||||
script_print_stack(context);
|
||||
return 1;
|
||||
|
||||
@@ -47,16 +47,23 @@ static httplib::Server::Handler makeHandler(const responseRoute &rr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
req.headers[h.first] = h.second;
|
||||
req.headers.emplace(h.first.data(), h.second.data());
|
||||
}
|
||||
req.argument = request.params;
|
||||
if (request.get_header_value("Content-Type") == "application/x-www-form-urlencoded")
|
||||
if (request.method == "POST" || request.method == "PUT" || request.method == "PATCH")
|
||||
{
|
||||
req.postdata = urlDecode(request.body);
|
||||
}
|
||||
else
|
||||
{
|
||||
req.postdata = request.body;
|
||||
if (request.is_multipart_form_data() && !request.files.empty())
|
||||
{
|
||||
req.postdata = request.files.begin()->second.content;
|
||||
}
|
||||
else if (request.get_header_value("Content-Type") == "application/x-www-form-urlencoded")
|
||||
{
|
||||
req.postdata = urlDecode(request.body);
|
||||
}
|
||||
else
|
||||
{
|
||||
req.postdata = request.body;
|
||||
}
|
||||
}
|
||||
auto result = rr.rc(req, resp);
|
||||
response.status = resp.status_code;
|
||||
@@ -163,6 +170,7 @@ int WebServer::start_web_server_multi(listener_args *args)
|
||||
{
|
||||
res.set_header("Access-Control-Allow-Headers", req.get_header_value("Access-Control-Request-Headers"));
|
||||
}
|
||||
res.set_header("Access-Control-Allow-Origin", "*");
|
||||
return httplib::Server::HandlerResponse::Unhandled;
|
||||
});
|
||||
for (auto &x : redirect_map)
|
||||
@@ -187,7 +195,7 @@ int WebServer::start_web_server_multi(listener_args *args)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::rethrow_exception(e);
|
||||
if (e) std::rethrow_exception(e);
|
||||
}
|
||||
catch (const httplib::Error &err)
|
||||
{
|
||||
@@ -212,6 +220,9 @@ int WebServer::start_web_server_multi(listener_args *args)
|
||||
{
|
||||
server.set_mount_point("/", serve_file_root);
|
||||
}
|
||||
server.new_task_queue = [args] {
|
||||
return new httplib::ThreadPool(args->max_workers);
|
||||
};
|
||||
server.bind_to_port(args->listen_address, args->port, 0);
|
||||
|
||||
std::thread thread([&]()
|
||||
|
||||
@@ -26,7 +26,8 @@ std::string getTime(int type)
|
||||
format = "%Y%m%d-%H%M%S";
|
||||
break;
|
||||
case 2:
|
||||
format = "%Y/%m/%d %a %H:%M:%S." + std::string(cMillis);
|
||||
format = "%Y/%m/%d %a %H:%M:%S.";
|
||||
format += cMillis;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
|
||||
@@ -5,9 +5,16 @@
|
||||
#include <map>
|
||||
#include <string.h>
|
||||
|
||||
struct strICaseComp {
|
||||
bool operator()(const std::string &lhs, const std::string &rhs) const {
|
||||
return strcasecmp(lhs.c_str(), rhs.c_str()) > 0;
|
||||
struct strICaseComp
|
||||
{
|
||||
bool operator() (const std::string &lhs, const std::string &rhs) const
|
||||
{
|
||||
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
|
||||
rhs.end(),
|
||||
[](unsigned char c1, unsigned char c2)
|
||||
{
|
||||
return ::tolower(c1) < ::tolower(c2);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,88 +3,38 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <random>
|
||||
|
||||
#include "string.h"
|
||||
#include "map_extra.h"
|
||||
|
||||
std::vector<std::string> split(const std::string &s, const std::string &separator)
|
||||
{
|
||||
string_size bpos = 0, epos = s.find(separator);
|
||||
std::vector<std::string> result;
|
||||
string_size i = 0;
|
||||
|
||||
while(i != s.size())
|
||||
while(bpos < s.size())
|
||||
{
|
||||
int flag = 0;
|
||||
while(i != s.size() && flag == 0)
|
||||
{
|
||||
flag = 1;
|
||||
for(char x : separator)
|
||||
if(s[i] == x)
|
||||
{
|
||||
++i;
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flag = 0;
|
||||
string_size j = i;
|
||||
while(j != s.size() && flag == 0)
|
||||
{
|
||||
for(char x : separator)
|
||||
if(s[j] == x)
|
||||
{
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
if(flag == 0)
|
||||
++j;
|
||||
}
|
||||
if(i != j)
|
||||
{
|
||||
result.push_back(s.substr(i, j-i));
|
||||
i = j;
|
||||
}
|
||||
if(epos == std::string::npos)
|
||||
epos = s.size();
|
||||
result.push_back(s.substr(bpos, epos - bpos));
|
||||
bpos = epos + separator.size();
|
||||
epos = s.find(separator, bpos);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void split(std::vector<std::string_view> &result, std::string_view s, char separator)
|
||||
{
|
||||
string_size i = 0;
|
||||
|
||||
while (i != s.size())
|
||||
string_size bpos = 0, epos = s.find(separator);
|
||||
while(bpos < s.size())
|
||||
{
|
||||
int flag = 0;
|
||||
while(i != s.size() && flag == 0)
|
||||
{
|
||||
flag = 1;
|
||||
if(s[i] == separator)
|
||||
{
|
||||
++i;
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flag = 0;
|
||||
string_size j = i;
|
||||
while(j != s.size() && flag == 0)
|
||||
{
|
||||
if(s[j] == separator)
|
||||
{
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
if (i != j)
|
||||
{
|
||||
result.push_back(s.substr(i, j-i));
|
||||
i = j;
|
||||
}
|
||||
if(epos == std::string_view::npos)
|
||||
epos = s.size();
|
||||
result.push_back(s.substr(bpos, epos - bpos));
|
||||
bpos = epos + 1;
|
||||
epos = s.find(separator, bpos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +91,7 @@ std::string toUpper(const std::string &str)
|
||||
void processEscapeChar(std::string &str)
|
||||
{
|
||||
string_size pos = str.find('\\');
|
||||
while(pos != str.npos)
|
||||
while(pos != std::string::npos)
|
||||
{
|
||||
if(pos == str.size())
|
||||
break;
|
||||
@@ -191,7 +141,7 @@ void processEscapeCharReverse(std::string &str)
|
||||
|
||||
int parseCommaKeyValue(const std::string &input, const std::string &separator, string_pair_array &result)
|
||||
{
|
||||
string_size bpos = 0, epos = input.find(',');
|
||||
string_size bpos = 0, epos = input.find(separator);
|
||||
std::string kv;
|
||||
while(bpos < input.size())
|
||||
{
|
||||
@@ -200,9 +150,9 @@ int parseCommaKeyValue(const std::string &input, const std::string &separator, s
|
||||
else if(epos && input[epos - 1] == '\\')
|
||||
{
|
||||
kv += input.substr(bpos, epos - bpos - 1);
|
||||
kv += ',';
|
||||
kv += separator;
|
||||
bpos = epos + 1;
|
||||
epos = input.find(',', bpos);
|
||||
epos = input.find(separator, bpos);
|
||||
continue;
|
||||
}
|
||||
kv += input.substr(bpos, epos - bpos);
|
||||
@@ -213,9 +163,9 @@ int parseCommaKeyValue(const std::string &input, const std::string &separator, s
|
||||
result.emplace_back(kv.substr(0, eqpos), kv.substr(eqpos + 1));
|
||||
kv.clear();
|
||||
bpos = epos + 1;
|
||||
epos = input.find(',', bpos);
|
||||
epos = input.find(separator, bpos);
|
||||
}
|
||||
if(kv.size())
|
||||
if(!kv.empty())
|
||||
{
|
||||
string_size eqpos = kv.find('=');
|
||||
if(eqpos == std::string::npos)
|
||||
@@ -328,12 +278,12 @@ std::string getUrlArg(const std::string &url, const std::string &request)
|
||||
while(pos)
|
||||
{
|
||||
pos = url.rfind(pattern, pos);
|
||||
if(pos != url.npos)
|
||||
if(pos != std::string::npos)
|
||||
{
|
||||
if(pos == 0 || url[pos - 1] == '&' || url[pos - 1] == '?')
|
||||
{
|
||||
pos += pattern.size();
|
||||
return url.substr(pos, url.find("&", pos) - pos);
|
||||
return url.substr(pos, url.find('&', pos) - pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -410,23 +360,24 @@ bool isStrUTF8(const std::string &data)
|
||||
std::string randomStr(int len)
|
||||
{
|
||||
std::string retData;
|
||||
srand(time(NULL));
|
||||
int cnt = 0;
|
||||
while(cnt < len)
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> dis(0, 61);
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
switch((rand() % 3))
|
||||
int r = dis(gen);
|
||||
if (r < 26)
|
||||
{
|
||||
case 1:
|
||||
retData += ('A' + rand() % 26);
|
||||
break;
|
||||
case 2:
|
||||
retData += ('a' + rand() % 26);
|
||||
break;
|
||||
default:
|
||||
retData += ('0' + rand() % 10);
|
||||
break;
|
||||
retData.push_back('a' + r);
|
||||
}
|
||||
else if (r < 52)
|
||||
{
|
||||
retData.push_back('A' + r - 26);
|
||||
}
|
||||
else
|
||||
{
|
||||
retData.push_back('0' + r - 52);
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
return retData;
|
||||
}
|
||||
@@ -451,7 +402,7 @@ int to_int(const std::string &str, int def_value)
|
||||
|
||||
std::string join(const string_array &arr, const std::string &delimiter)
|
||||
{
|
||||
if(arr.size() == 0)
|
||||
if(arr.empty())
|
||||
return "";
|
||||
if(arr.size() == 1)
|
||||
return arr[0];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef VERSION_H_INCLUDED
|
||||
#define VERSION_H_INCLUDED
|
||||
|
||||
#define VERSION "v0.9.7"
|
||||
#define VERSION "v0.9.8"
|
||||
|
||||
#endif // VERSION_H_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user