mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-29 21:03:00 +00:00
Compare commits
77 Commits
v0.9.6
...
b649fdc253
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b649fdc253 | ||
|
|
5759f52ebc | ||
|
|
e4b3ee816d | ||
|
|
ebf6a08449 | ||
|
|
638137e1db | ||
|
|
ea49fe862d | ||
|
|
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 | ||
|
|
33f32deb32 | ||
|
|
258a64ed4f | ||
|
|
7e16236595 | ||
|
|
644b9040b9 | ||
|
|
3f2281e284 | ||
|
|
0c11565cc9 | ||
|
|
4e6e25c710 | ||
|
|
7dec83d529 | ||
|
|
c4aa8c5b5e | ||
|
|
e22f043213 | ||
|
|
e9c39481df | ||
|
|
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
|
name: Publish Docker Image
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
tags:
|
tags:
|
||||||
- '**'
|
- '**'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-${{ github.workflow }}
|
group: ${{ github.ref }}-${{ github.workflow }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -3,3 +3,9 @@ subconverter.exe
|
|||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
.idea
|
.idea
|
||||||
base/cache
|
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/")
|
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/")
|
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/")
|
||||||
|
|
||||||
|
if (MINGW)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition")
|
||||||
|
endif()
|
||||||
|
|
||||||
IF(NOT CMAKE_BUILD_TYPE)
|
IF(NOT CMAKE_BUILD_TYPE)
|
||||||
SET(CMAKE_BUILD_TYPE Release)
|
SET(CMAKE_BUILD_TYPE Release)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
Utility to convert between various proxy subscription formats.
|
Utility to convert between various proxy subscription formats.
|
||||||
|
|
||||||
[](https://github.com/asdlokj1qpi23/subconverter/actions)
|
original git: https://github.com/asdlokj1qpi23/subconverter
|
||||||
[](https://github.com/asdlokj1qpi23/subconverter/tags)
|
|
||||||
[](https://github.com/asdlokj1qpi23/subconverter/releases)
|
[](https://github.com/asdlokj1qpi233/subconverter/actions)
|
||||||
[](https://github.com/tindy2013/subconverter/blob/master/LICENSE)
|
[](https://github.com/asdlokj1qpi23/subconverter/tags)
|
||||||
|
[](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)
|
[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") }}
|
allow-lan: {{ default(global.clash.allow_lan, "true") }}
|
||||||
mode: Rule
|
mode: Rule
|
||||||
log-level: {{ default(global.clash.log_level, "info") }}
|
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" %}
|
{% if default(request.clash.dns, "") == "1" %}
|
||||||
dns:
|
dns:
|
||||||
enable: true
|
enable: true
|
||||||
@@ -378,7 +378,16 @@ enhanced-mode-by-rule = true
|
|||||||
"rules": [],
|
"rules": [],
|
||||||
"auto_detect_interface": true
|
"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 %}
|
{% endif %}
|
||||||
|
|||||||
@@ -100,5 +100,14 @@
|
|||||||
"rules": [],
|
"rules": [],
|
||||||
"auto_detect_interface": true
|
"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
|
append_sub_userinfo=true
|
||||||
clash_use_new_field_name=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
|
;Supported styles: block, flow, compact
|
||||||
;Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
|
;Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
|
||||||
; key: value - {name: name2, key: value}
|
; key: value - {name: name2, key: value}
|
||||||
; - name: name2
|
; - name: name2
|
||||||
; key: value
|
; key: value
|
||||||
clash_proxies_style=flow
|
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
|
;add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
|
||||||
singbox_add_clash_modes=true
|
singbox_add_clash_modes=true
|
||||||
@@ -232,6 +233,7 @@ clash.http_port=7890
|
|||||||
clash.socks_port=7891
|
clash.socks_port=7891
|
||||||
clash.allow_lan=true
|
clash.allow_lan=true
|
||||||
clash.log_level=info
|
clash.log_level=info
|
||||||
|
clash.external_controller=127.0.0.1:9090
|
||||||
singbox.allow_lan=true
|
singbox.allow_lan=true
|
||||||
singbox.mixed_port=2080
|
singbox.mixed_port=2080
|
||||||
|
|
||||||
|
|||||||
@@ -117,10 +117,10 @@ match = '^Smart Access expire: (\d+)/(\d+)/(\d+)$'
|
|||||||
replace = '$1:$2:$3:0:0:0'
|
replace = '$1:$2:$3:0:0:0'
|
||||||
|
|
||||||
[node_pref]
|
[node_pref]
|
||||||
udp_flag = true
|
#udp_flag = false
|
||||||
tcp_fast_open_flag = false
|
#tcp_fast_open_flag = false
|
||||||
skip_cert_verify_flag = true
|
#skip_cert_verify_flag = false
|
||||||
tls13_flag = false
|
#tls13_flag = false
|
||||||
|
|
||||||
sort_flag = false
|
sort_flag = false
|
||||||
# Script used for sorting nodes. A "compare" function with 2 arguments which are the 2 nodes to be compared should be defined in the script. Supports inline script and script path.
|
# Script used for sorting nodes. A "compare" function with 2 arguments which are the 2 nodes to be compared should be defined in the script. Supports inline script and script path.
|
||||||
@@ -135,13 +135,14 @@ filter_deprecated_nodes = false
|
|||||||
append_sub_userinfo = true
|
append_sub_userinfo = true
|
||||||
clash_use_new_field_name = 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
|
# Supported styles: block, flow, compact
|
||||||
# Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
|
# Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
|
||||||
# key: value - {name: name2, key: value}
|
# key: value - {name: name2, key: value}
|
||||||
# - name: name2
|
# - name: name2
|
||||||
# key: value
|
# key: value
|
||||||
clash_proxies_style = "flow"
|
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
|
# add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
|
||||||
singbox_add_clash_modes = true
|
singbox_add_clash_modes = true
|
||||||
@@ -243,6 +244,10 @@ value = "true"
|
|||||||
key = "clash.log_level"
|
key = "clash.log_level"
|
||||||
value = "info"
|
value = "info"
|
||||||
|
|
||||||
|
[[template.globals]]
|
||||||
|
key = "clash.external_controller"
|
||||||
|
value = "127.0.0.1:9090"
|
||||||
|
|
||||||
[[template.globals]]
|
[[template.globals]]
|
||||||
key = "singbox.allow_lan"
|
key = "singbox.allow_lan"
|
||||||
value = "true"
|
value = "true"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ node_pref:
|
|||||||
append_sub_userinfo: true
|
append_sub_userinfo: true
|
||||||
clash_use_new_field_name: true
|
clash_use_new_field_name: true
|
||||||
clash_proxies_style: flow
|
clash_proxies_style: flow
|
||||||
|
clash_proxy_groups_style: block
|
||||||
singbox_add_clash_modes: true
|
singbox_add_clash_modes: true
|
||||||
rename_node:
|
rename_node:
|
||||||
# - {match: "\\(?((x|X)?(\\d+)(\\.?\\d+)?)((\\s?倍率?)|(x|X))\\)?", replace: "$1x"}
|
# - {match: "\\(?((x|X)?(\\d+)(\\.?\\d+)?)((\\s?倍率?)|(x|X))\\)?", replace: "$1x"}
|
||||||
@@ -108,9 +109,10 @@ template:
|
|||||||
- {key: clash.socks_port, value: 7891}
|
- {key: clash.socks_port, value: 7891}
|
||||||
- {key: clash.allow_lan, value: true}
|
- {key: clash.allow_lan, value: true}
|
||||||
- {key: clash.log_level, value: info}
|
- {key: clash.log_level, value: info}
|
||||||
|
- {key: clash.external_controller, value: '127.0.0.1:9090'}
|
||||||
- {key: singbox.allow_lan, value: true}
|
- {key: singbox.allow_lan, value: true}
|
||||||
- {key: singbox.mixed_port, value: 2080}
|
- {key: singbox.mixed_port, value: 2080}
|
||||||
|
|
||||||
aliases:
|
aliases:
|
||||||
- {uri: /v, target: /version}
|
- {uri: /v, target: /version}
|
||||||
- {uri: /clash, target: "/sub?target=clash"}
|
- {uri: /clash, target: "/sub?target=clash"}
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ match = "(?i:Bandwidth|expire|流量|时间|应急|过期)"
|
|||||||
emoji = "🏳️🌈"
|
emoji = "🏳️🌈"
|
||||||
|
|
||||||
[[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 = "🇭🇰"
|
||||||
|
|
||||||
[[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 = "🇨🇳"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bSG[P]?\\b|Singapore|新加坡|狮城|[^-]新)"
|
match = "(?i:\\bSG[P]?\\d*\\b|Singapore|新加坡|狮城|[^-]新)"
|
||||||
emoji = "🇸🇬"
|
emoji = "🇸🇬"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -19,15 +19,15 @@ match = "(尼日利亚|Nigeria)"
|
|||||||
emoji = "🇳🇬"
|
emoji = "🇳🇬"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bJP[N]?\\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日)"
|
match = "(?i:\\bJP[N]?\\d*\\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日)"
|
||||||
emoji = "🇯🇵"
|
emoji = "🇯🇵"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bK[O]?R\\b|Korea|首尔|韩|韓)"
|
match = "(?i:(?<!North\\s)(\\bK[O]?R\\d*\\b|Korea|首尔|韩|韓))"
|
||||||
emoji = "🇰🇷"
|
emoji = "🇰🇷"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bUS[A]?\\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥)"
|
match = "(?i:\\bUS[A]?\\d*\\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥)"
|
||||||
emoji = "🇺🇸"
|
emoji = "🇺🇸"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -42,6 +42,10 @@ emoji = "🇦🇪"
|
|||||||
match = "(阿尔巴尼亚|Albania)"
|
match = "(阿尔巴尼亚|Albania)"
|
||||||
emoji = "🇦🇱"
|
emoji = "🇦🇱"
|
||||||
|
|
||||||
|
[[emoji]]
|
||||||
|
match = "(南极|Antarctica)"
|
||||||
|
emoji = "🇦🇶"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(Argentina|阿根廷)"
|
match = "(Argentina|阿根廷)"
|
||||||
emoji = "🇦🇷"
|
emoji = "🇦🇷"
|
||||||
@@ -51,7 +55,7 @@ match = "(Austria|Vienna|奥地利|维也纳)"
|
|||||||
emoji = "🇦🇹"
|
emoji = "🇦🇹"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bAU[S]?\\b|Australia|Sydney|澳大利亚|澳洲|悉尼)"
|
match = "(?i:\\bAU[S]?\\d*\\b|Australia|Sydney|澳大利亚|澳洲|悉尼)"
|
||||||
emoji = "🇦🇺"
|
emoji = "🇦🇺"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -75,7 +79,7 @@ match = "(Brazil|Paulo|巴西|圣保罗)"
|
|||||||
emoji = "🇧🇷"
|
emoji = "🇧🇷"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bCA[N]?\\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶)"
|
match = "(?i:\\bCA[N]?\\d*\\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶)"
|
||||||
emoji = "🇨🇦"
|
emoji = "🇨🇦"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -103,7 +107,7 @@ match = "(Czech|捷克)"
|
|||||||
emoji = "🇨🇿"
|
emoji = "🇨🇿"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bDE[U]?\\b|Germany|法兰克福|德(国|意志)|中德|^德$)"
|
match = "(?i:\\bDE[U]?\\d*\\b|Germany|法兰克福|德(国|意志)|中德|^德$)"
|
||||||
emoji = "🇩🇪"
|
emoji = "🇩🇪"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -119,7 +123,7 @@ match = "(埃及|Egypt)"
|
|||||||
emoji = "🇪🇬"
|
emoji = "🇪🇬"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bES[P]?\\b|Spain|西班牙)"
|
match = "(?i:\\bES[P]?\\d*\\b|Spain|西班牙)"
|
||||||
emoji = "🇪🇸"
|
emoji = "🇪🇸"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -131,11 +135,11 @@ match = "(Finland|Helsinki|芬兰|赫尔辛基)"
|
|||||||
emoji = "🇫🇮"
|
emoji = "🇫🇮"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bFR[A]?\\b|France|Paris|法国|巴黎)"
|
match = "(?i:\\bFR[A]?\\d*\\b|France|Paris|法国|巴黎)"
|
||||||
emoji = "🇫🇷"
|
emoji = "🇫🇷"
|
||||||
|
|
||||||
[[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 = "🇬🇧"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -171,7 +175,7 @@ match = "(马恩岛|Mann)"
|
|||||||
emoji = "🇮🇲"
|
emoji = "🇮🇲"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bIN[D]?\\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德)"
|
match = "(?i:\\bIN[D]?\\d*\\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德)"
|
||||||
emoji = "🇮🇳"
|
emoji = "🇮🇳"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -179,11 +183,11 @@ match = "(伊朗|Iran)"
|
|||||||
emoji = "🇮🇷"
|
emoji = "🇮🇷"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bIS[L]?\\b|Iceland|冰岛)"
|
match = "(?i:\\bIS[L]?\\d*\\b|Iceland|冰岛)"
|
||||||
emoji = "🇮🇸"
|
emoji = "🇮🇸"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(Italy|Milan|意大利|米兰)"
|
match = "(Italy|Italia|Milan|意大利|米兰)"
|
||||||
emoji = "🇮🇹"
|
emoji = "🇮🇹"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -202,7 +206,6 @@ emoji = "🇰🇬"
|
|||||||
match = "(柬埔寨|Cambodia)"
|
match = "(柬埔寨|Cambodia)"
|
||||||
emoji = "🇰🇭"
|
emoji = "🇰🇭"
|
||||||
|
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(North.*?Korea|朝鲜)"
|
match = "(North.*?Korea|朝鲜)"
|
||||||
emoji = "🇰🇵"
|
emoji = "🇰🇵"
|
||||||
@@ -231,6 +234,10 @@ emoji = "🇲🇩"
|
|||||||
match = "(北马其顿|Macedonia)"
|
match = "(北马其顿|Macedonia)"
|
||||||
emoji = "🇲🇰"
|
emoji = "🇲🇰"
|
||||||
|
|
||||||
|
[[emoji]]
|
||||||
|
match = "(缅甸|Myanmar)"
|
||||||
|
emoji = "🇲🇲"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(蒙古|Монголулс|Mongolia)"
|
match = "(蒙古|Монголулс|Mongolia)"
|
||||||
emoji = "🇲🇳"
|
emoji = "🇲🇳"
|
||||||
@@ -248,7 +255,7 @@ match = "(Malaysia|马来|MY)"
|
|||||||
emoji = "🇲🇾"
|
emoji = "🇲🇾"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bNL[D]?\\b|Netherlands|荷兰|阿姆斯特丹)"
|
match = "(?i:\\bNL[D]?\\d*\\b|Netherlands|荷兰|阿姆斯特丹)"
|
||||||
emoji = "🇳🇱"
|
emoji = "🇳🇱"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -260,7 +267,7 @@ match = "(新西兰|纽西兰|New Zealand)"
|
|||||||
emoji = "🇳🇿"
|
emoji = "🇳🇿"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(Philippines|菲律宾)"
|
match = "(?i:\\bP[O]?H\\d*\\b|Philippines|菲律宾)"
|
||||||
emoji = "🇵🇭"
|
emoji = "🇵🇭"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -292,7 +299,7 @@ match = "(塞尔维亚|Serbia)"
|
|||||||
emoji = "🇷🇸"
|
emoji = "🇷🇸"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bRU[S]?\\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄)"
|
match = "(?i:\\bRU[S]?\\d*\\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄)"
|
||||||
emoji = "🇷🇺"
|
emoji = "🇷🇺"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -320,7 +327,7 @@ match = "(突尼斯|Tunisia)"
|
|||||||
emoji = "🇹🇳"
|
emoji = "🇹🇳"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(Turkey|土耳其|伊斯坦布尔)"
|
match = "(Turkey|Türkiye|土耳其|伊斯坦布尔)"
|
||||||
emoji = "🇹🇷"
|
emoji = "🇹🇷"
|
||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
@@ -364,4 +371,4 @@ emoji = "🇧🇩"
|
|||||||
|
|
||||||
[[emoji]]
|
[[emoji]]
|
||||||
match = "(?i:\\bC[H]?N\\b|China|back|回国|中国[^-]|江苏[^-]|北京[^-]|上海[^-]|广州[^-]|深圳[^-]|杭州[^-]|常州[^-]|徐州[^-]|青岛[^-]|宁波[^-]|镇江[^-]|成都[^-]|河北[^-]|山西[^-]|辽宁[^-]|吉林[^-]|黑龙江[^-]|江苏[^-]|浙江[^-]|安徽[^-]|福建[^-]|江西[^-]|山东[^-]|河南[^-]|湖北[^-]|湖南[^-]|广东[^-]|海南[^-]|四川[^-]|贵州[^-]|云南[^-]|陕西[^-]|甘肃[^-]|青海[^-]|内蒙古[^-]|广西[^-]|西藏[^-]|宁夏[^-]|新疆[^-])"
|
match = "(?i:\\bC[H]?N\\b|China|back|回国|中国[^-]|江苏[^-]|北京[^-]|上海[^-]|广州[^-]|深圳[^-]|杭州[^-]|常州[^-]|徐州[^-]|青岛[^-]|宁波[^-]|镇江[^-]|成都[^-]|河北[^-]|山西[^-]|辽宁[^-]|吉林[^-]|黑龙江[^-]|江苏[^-]|浙江[^-]|安徽[^-]|福建[^-]|江西[^-]|山东[^-]|河南[^-]|湖北[^-]|湖南[^-]|广东[^-]|海南[^-]|四川[^-]|贵州[^-]|云南[^-]|陕西[^-]|甘肃[^-]|青海[^-]|内蒙古[^-]|广西[^-]|西藏[^-]|宁夏[^-]|新疆[^-])"
|
||||||
emoji = "🇨🇳"
|
emoji = "🇨🇳"
|
||||||
@@ -1,38 +1,39 @@
|
|||||||
(?i:Bandwidth|expire|流量|时间|应急|过期),🏳️🌈
|
(?i:Bandwidth|expire|流量|时间|应急|过期),🏳️🌈
|
||||||
(?i:\bHK[G]?\b|Hong.*?Kong|\bHKT\b|\bHKBN\b|\bHGC\b|\bWTT\b|\bCMI\b|[^-]港),🇭🇰
|
(?i:\bHK[G]?\d*\b|Hong.*?Kong|\bHKT\b|\bHKBN\b|\bHGC\b|\bWTT\b|\bCMI\b|[^-]港),🇭🇰
|
||||||
(?i:\bTW[N]?\b|Taiwan|新北|彰化|\bCHT\b|台湾|[^-]台|\bHINET\b),🇨🇳
|
(?i:\bTW[N]?\d*\b|Taiwan|新北|彰化|\bCHT\b|台湾|[^-]台|\bHINET\b),🇨🇳
|
||||||
(?i:\bSG[P]?\b|Singapore|新加坡|狮城|[^-]新),🇸🇬
|
(?i:\bSG[P]?\d*\b|Singapore|新加坡|狮城|[^-]新),🇸🇬
|
||||||
(尼日利亚|Nigeria),🇳🇬
|
(尼日利亚|Nigeria),🇳🇬
|
||||||
(?i:\bJP[N]?\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
|
(?i:\bJP[N]?\d*\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
|
||||||
(?i:\bK[O]?R\b|Korea|首尔|韩|韓),🇰🇷
|
(?i:(?<!North\s)(\bK[O]?R\d*\b|Korea|首尔|韩|韓)),🇰🇷
|
||||||
(?i:\bUS[A]?\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
|
(?i:\bUS[A]?\d*\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
|
||||||
(Ascension|阿森松),🇦🇨
|
(Ascension|阿森松),🇦🇨
|
||||||
(?i:\bUAE\b|Dubai|阿联酋|迪拜),🇦🇪
|
(?i:\bUAE\b|Dubai|阿联酋|迪拜),🇦🇪
|
||||||
(阿尔巴尼亚|Albania),🇦🇱
|
(阿尔巴尼亚|Albania),🇦🇱
|
||||||
|
(南极|Antarctica),🇦🇶
|
||||||
(Argentina|阿根廷),🇦🇷
|
(Argentina|阿根廷),🇦🇷
|
||||||
(Austria|Vienna|奥地利|维也纳),🇦🇹
|
(Austria|Vienna|奥地利|维也纳),🇦🇹
|
||||||
(?i:\bAU[S]?\b|Australia|Sydney|澳大利亚|澳洲|悉尼),🇦🇺
|
(?i:\bAU[S]?\d*\b|Australia|Sydney|澳大利亚|澳洲|悉尼),🇦🇺
|
||||||
(阿塞拜疆|Azerbaijan),🇦🇿
|
(阿塞拜疆|Azerbaijan),🇦🇿
|
||||||
(波黑共和国|波士尼亚与赫塞哥维纳|Bosnia|Herzegovina),🇧🇦
|
(波黑共和国|波士尼亚与赫塞哥维纳|Bosnia|Herzegovina),🇧🇦
|
||||||
(Belgium|比利时),🇧🇪
|
(Belgium|比利时),🇧🇪
|
||||||
(保加利亚|Bulgaria),🇧🇬
|
(保加利亚|Bulgaria),🇧🇬
|
||||||
(Brazil|Paulo|巴西|圣保罗),🇧🇷
|
(Brazil|Paulo|巴西|圣保罗),🇧🇷
|
||||||
(?i:\bCA[N]?\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶),🇨🇦
|
(?i:\bCA[N]?\d*\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶),🇨🇦
|
||||||
(Switzerland|Zurich|瑞士|苏黎世),🇨🇭
|
(Switzerland|Zurich|瑞士|苏黎世),🇨🇭
|
||||||
(智利|Chile),🇨🇱
|
(智利|Chile),🇨🇱
|
||||||
(Colombia|哥伦比亚),🇨🇴
|
(Colombia|哥伦比亚),🇨🇴
|
||||||
(Costa Rica|哥斯达黎加),🇨🇷
|
(Costa Rica|哥斯达黎加),🇨🇷
|
||||||
(塞浦路斯|Cyprus),🇨🇾
|
(塞浦路斯|Cyprus),🇨🇾
|
||||||
(Czech|捷克),🇨🇿
|
(Czech|捷克),🇨🇿
|
||||||
(?i:\bDE[U]?\b|Germany|法兰克福|德(国|意志)|中德|^德$),🇩🇪
|
(?i:\bDE[U]?\d*\b|Germany|法兰克福|德(国|意志)|中德|^德$),🇩🇪
|
||||||
(?i:\bD[N]?K\b|Denmark|丹麦),🇩🇰
|
(?i:\bD[N]?K\b|Denmark|丹麦),🇩🇰
|
||||||
(爱沙尼亚|Estonia),🇪🇪
|
(爱沙尼亚|Estonia),🇪🇪
|
||||||
(埃及|Egypt),🇪🇬
|
(埃及|Egypt),🇪🇬
|
||||||
(?i:\bES[P]?\b|Spain|西班牙),🇪🇸
|
(?i:\bES[P]?\d*\b|Spain|西班牙),🇪🇸
|
||||||
(Europe|欧洲),🇪🇺
|
(Europe|欧洲),🇪🇺
|
||||||
(Finland|Helsinki|芬兰|赫尔辛基),🇫🇮
|
(Finland|Helsinki|芬兰|赫尔辛基),🇫🇮
|
||||||
(?i:\bFR[A]?\b|France|Paris|法国|巴黎),🇫🇷
|
(?i:\bFR[A]?\d*\b|France|Paris|法国|巴黎),🇫🇷
|
||||||
(?i:\bUK\b|\bGB[R]?\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦),🇬🇧
|
(?i:\bUK\d*\b|\bGB[R]?\d*\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦),🇬🇧
|
||||||
(希腊|Greece),🇬🇷
|
(希腊|Greece),🇬🇷
|
||||||
(格鲁吉亚|Georgia),🇬🇪
|
(格鲁吉亚|Georgia),🇬🇪
|
||||||
(克罗地亚|Croatia),🇭🇷
|
(克罗地亚|Croatia),🇭🇷
|
||||||
@@ -41,10 +42,10 @@
|
|||||||
(Ireland|Dublin|爱尔兰|都柏林),🇮🇪
|
(Ireland|Dublin|爱尔兰|都柏林),🇮🇪
|
||||||
(Israel|以色列),🇮🇱
|
(Israel|以色列),🇮🇱
|
||||||
(马恩岛|Mann),🇮🇲
|
(马恩岛|Mann),🇮🇲
|
||||||
(?i:\bIN[D]?\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德),🇮🇳
|
(?i:\bIN[D]?\d*\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德),🇮🇳
|
||||||
(伊朗|Iran),🇮🇷
|
(伊朗|Iran),🇮🇷
|
||||||
(?i:\bIS[L]?\b|Iceland|冰岛),🇮🇸
|
(?i:\bIS[L]?\d*\b|Iceland|冰岛),🇮🇸
|
||||||
(Italy|Milan|意大利|米兰),🇮🇹
|
(Italy|Italia|Milan|意大利|米兰),🇮🇹
|
||||||
(约旦|Jordan),🇯🇴
|
(约旦|Jordan),🇯🇴
|
||||||
(肯尼亚|Kenya),🇰🇪
|
(肯尼亚|Kenya),🇰🇪
|
||||||
(吉尔吉斯斯坦|Kyrgyzstan),🇰🇬
|
(吉尔吉斯斯坦|Kyrgyzstan),🇰🇬
|
||||||
@@ -56,14 +57,15 @@
|
|||||||
(拉脱维亚|Latvia),🇱🇻
|
(拉脱维亚|Latvia),🇱🇻
|
||||||
(Moldova|摩尔多瓦),🇲🇩
|
(Moldova|摩尔多瓦),🇲🇩
|
||||||
(北马其顿|Macedonia),🇲🇰
|
(北马其顿|Macedonia),🇲🇰
|
||||||
|
(缅甸|Myanmar),🇲🇲
|
||||||
(蒙古|Монголулс|Mongolia),🇲🇳
|
(蒙古|Монголулс|Mongolia),🇲🇳
|
||||||
(Macao|澳门|\bCTM\b),🇲🇴
|
(Macao|澳门|\bCTM\b),🇲🇴
|
||||||
(墨西哥|Mexico),🇲🇽
|
(墨西哥|Mexico),🇲🇽
|
||||||
(Malaysia|马来|MY),🇲🇾
|
(Malaysia|马来|MY),🇲🇾
|
||||||
(?i:\bNL[D]?\b|Netherlands|荷兰|阿姆斯特丹),🇳🇱
|
(?i:\bNL[D]?\d*\b|Netherlands|荷兰|阿姆斯特丹),🇳🇱
|
||||||
(挪威|Norway),🇳🇴
|
(挪威|Norway),🇳🇴
|
||||||
(新西兰|纽西兰|New Zealand),🇳🇿
|
(新西兰|纽西兰|New Zealand),🇳🇿
|
||||||
(Philippines|菲律宾),🇵🇭
|
(?i:\bP[O]?H\d*\b|Philippines|菲律宾),🇵🇭
|
||||||
(Pakistan|巴基斯坦),🇵🇰
|
(Pakistan|巴基斯坦),🇵🇰
|
||||||
(?i:\bP[O]?L\b|Poland|波兰),🇵🇱
|
(?i:\bP[O]?L\b|Poland|波兰),🇵🇱
|
||||||
(巴拿马|Panama),🇵🇦
|
(巴拿马|Panama),🇵🇦
|
||||||
@@ -71,15 +73,16 @@
|
|||||||
(葡萄牙|Portugal),🇵🇹
|
(葡萄牙|Portugal),🇵🇹
|
||||||
(Romania|罗马尼亚),🇷🇴
|
(Romania|罗马尼亚),🇷🇴
|
||||||
(塞尔维亚|Serbia),🇷🇸
|
(塞尔维亚|Serbia),🇷🇸
|
||||||
(?i:\bRU[S]?\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄),🇷🇺
|
(?i:\bRU[S]?\d*\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄),🇷🇺
|
||||||
(Arabia|沙特),🇸🇦
|
(Arabia|沙特),🇸🇦
|
||||||
(Sweden|瑞典),🇸🇪
|
(Sweden|瑞典),🇸🇪
|
||||||
(斯洛文尼亚|Slovenia),🇸🇮
|
(斯洛文尼亚|Slovenia),🇸🇮
|
||||||
(斯洛伐克|Slovensko),🇸🇰
|
(斯洛伐克|Slovensko),🇸🇰
|
||||||
(Thailand|泰国|曼谷),🇹🇭
|
(Thailand|泰国|曼谷),🇹🇭
|
||||||
(突尼斯|Tunisia),🇹🇳
|
(突尼斯|Tunisia),🇹🇳
|
||||||
(Turkey|土耳其|伊斯坦布尔),🇹🇷
|
(Turkey|Türkiye|土耳其|伊斯坦布尔),🇹🇷
|
||||||
(乌拉圭|Uruguay),🇺🇾
|
(乌拉圭|Uruguay),🇺🇾
|
||||||
|
(梵蒂冈|Vatican),🇻🇦
|
||||||
(Vietnam|越南),🇻🇳
|
(Vietnam|越南),🇻🇳
|
||||||
(Africa|南非),🇿🇦
|
(Africa|南非),🇿🇦
|
||||||
(Ukraine|UA|乌克兰),🇺🇦
|
(Ukraine|UA|乌克兰),🇺🇦
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ RUN set -xe && \
|
|||||||
install -d /usr/include/date/ && \
|
install -d /usr/include/date/ && \
|
||||||
install -m644 libcron/externals/date/include/date/* /usr/include/date/ && \
|
install -m644 libcron/externals/date/include/date/* /usr/include/date/ && \
|
||||||
cd .. && \
|
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 && \
|
cd toml11 && \
|
||||||
cmake -DCMAKE_CXX_STANDARD=11 . && \
|
cmake -DCMAKE_CXX_STANDARD=11 . && \
|
||||||
make install -j $THREADS && \
|
make install -j $THREADS && \
|
||||||
cd .. && \
|
cd .. && \
|
||||||
git clone https://github.com/asdlokj1qpi23/subconverter --depth=1 && \
|
git clone https://github.com/asdlokj1qpi233/subconverter --depth=1 && \
|
||||||
cd subconverter && \
|
cd subconverter && \
|
||||||
[ -n "$SHA" ] && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h;\
|
[ -n "$SHA" ] && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h;\
|
||||||
python3 -m ensurepip && \
|
python3 -m ensurepip && \
|
||||||
@@ -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/subconverter /usr/bin/
|
||||||
COPY --from=builder /subconverter/base /base/
|
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
|
# set entry
|
||||||
WORKDIR /base
|
WORKDIR /base
|
||||||
CMD subconverter
|
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 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
|
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
|
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
|
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
|
make install -j2 > /dev/null
|
||||||
@@ -34,7 +34,7 @@ cmake -DCMAKE_BUILD_TYPE=Release .
|
|||||||
make libcron install -j3
|
make libcron install -j3
|
||||||
cd ..
|
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
|
cd toml11
|
||||||
cmake -DCMAKE_CXX_STANDARD=11 .
|
cmake -DCMAKE_CXX_STANDARD=11 .
|
||||||
make install -j4
|
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/
|
sudo install -m644 libcron/externals/date/include/date/* /usr/local/include/date/
|
||||||
cd ..
|
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
|
cd toml11
|
||||||
cmake -DCMAKE_CXX_STANDARD=11 .
|
cmake -DCMAKE_CXX_STANDARD=11 .
|
||||||
sudo make install -j6 > /dev/null
|
sudo make install -j6 > /dev/null
|
||||||
@@ -63,4 +63,4 @@ chmod +r ./*
|
|||||||
cd ..
|
cd ..
|
||||||
mv base subconverter
|
mv base subconverter
|
||||||
|
|
||||||
set +xe
|
set +xe
|
||||||
|
|||||||
@@ -1,33 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
# 获取系统架构
|
git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0
|
||||||
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
|
|
||||||
cd curl
|
cd curl
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
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_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 .
|
|
||||||
|
|
||||||
make install -j4
|
make install -j4
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
@@ -40,8 +16,11 @@ cd ..
|
|||||||
git clone https://github.com/ftk/quickjspp --depth=1
|
git clone https://github.com/ftk/quickjspp --depth=1
|
||||||
cd quickjspp
|
cd quickjspp
|
||||||
patch quickjs/quickjs-libc.c -i ../scripts/patches/0001-quickjs-libc-add-realpath-for-Windows.patch
|
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
|
make quickjs -j4
|
||||||
|
|
||||||
install -d "$MINGW_PREFIX/lib/quickjs/"
|
install -d "$MINGW_PREFIX/lib/quickjs/"
|
||||||
install -m644 quickjs/libquickjs.a "$MINGW_PREFIX/lib/quickjs/"
|
install -m644 quickjs/libquickjs.a "$MINGW_PREFIX/lib/quickjs/"
|
||||||
install -d "$MINGW_PREFIX/include/quickjs"
|
install -d "$MINGW_PREFIX/include/quickjs"
|
||||||
@@ -62,7 +41,7 @@ cmake -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD
|
|||||||
make install -j4
|
make install -j4
|
||||||
cd ..
|
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
|
cd toml11
|
||||||
cmake -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=11 .
|
cmake -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=11 .
|
||||||
make install -j4
|
make install -j4
|
||||||
@@ -77,5 +56,5 @@ cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" .
|
|||||||
make -j4
|
make -j4
|
||||||
rm subconverter.exe
|
rm subconverter.exe
|
||||||
# shellcheck disable=SC2046
|
# 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
|
g++ $(find CMakeFiles/subconverter.dir/src -name "*.obj") curl/lib/libcurl.a -o base/subconverter.exe -static -Wl,--allow-multiple-definition -lbcrypt -lpcre2-8 -llibcron -lyaml-cpp -liphlpapi -lcrypt32 -lws2_32 -lwsock32 -lz -Lquickjspp/quickjs -lquickjs -s
|
||||||
mv base subconverter
|
mv base subconverter
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
[ACL4SSR]
|
[ACL4SSR]
|
||||||
name=ACL4SSR
|
name=ACL4SSR
|
||||||
url=https://github.com/ACL4SSR/ACL4SSR
|
url=https://github.com/ACL4SSR/ACL4SSR
|
||||||
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
|
branch=master
|
||||||
match=Clash/*.list|Clash/Ruleset/**
|
match=Clash/*.list|Clash/Ruleset/**
|
||||||
|
|
||||||
[ACL4SSR_config]
|
[ACL4SSR_config]
|
||||||
name=ACL4SSR
|
name=ACL4SSR
|
||||||
url=https://github.com/ACL4SSR/ACL4SSR
|
url=https://github.com/ACL4SSR/ACL4SSR
|
||||||
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
|
branch=master
|
||||||
match=Clash/config/**
|
match=Clash/config/**
|
||||||
dest=base/config/
|
dest=base/config/
|
||||||
keep_tree=false
|
keep_tree=false
|
||||||
|
|
||||||
[DivineEngine]
|
|
||||||
url=https://github.com/asdlokj1qpi23/DivineEngine.git
|
|
||||||
checkout=e5043a1cee1678254b424267bdcfccbcb574bad6
|
|
||||||
match=Surge/Ruleset/**
|
|
||||||
|
|
||||||
[NobyDa]
|
[NobyDa]
|
||||||
url=https://github.com/NobyDa/Script
|
url=https://github.com/NobyDa/Script
|
||||||
checkout=ae4c12f23de8078e02c373c9969b19af28257fcb
|
branch=master
|
||||||
match=Surge/*.list
|
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
|
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)
|
os.makedirs(save_path, exist_ok=True)
|
||||||
for pattern in matches:
|
for pattern in matches:
|
||||||
files = glob.glob(os.path.join(repo_path, pattern), recursive=True)
|
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:
|
for file in files:
|
||||||
if os.path.isdir(file):
|
if os.path.isdir(file):
|
||||||
continue
|
continue
|
||||||
@@ -51,12 +54,13 @@ def main():
|
|||||||
for section in config.sections():
|
for section in config.sections():
|
||||||
repo = config.get(section, "name", fallback=section)
|
repo = config.get(section, "name", fallback=section)
|
||||||
url = config.get(section, "url")
|
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("|")
|
matches = config.get(section, "match").split("|")
|
||||||
save_path = config.get(section, "dest", fallback=f"base/rules/{repo}")
|
save_path = config.get(section, "dest", fallback=f"base/rules/{repo}")
|
||||||
keep_tree = config.getboolean(section, "keep_tree", fallback=True)
|
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)
|
repo_path = os.path.join("./tmp/repo/", repo)
|
||||||
|
|
||||||
@@ -67,8 +71,21 @@ def main():
|
|||||||
else:
|
else:
|
||||||
logging.info(f"repo {repo_path} exists")
|
logging.info(f"repo {repo_path} exists")
|
||||||
|
|
||||||
r.git.checkout(commit)
|
try:
|
||||||
update_rules(repo_path, save_path, commit, matches, keep_tree)
|
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)
|
shutil.rmtree("./tmp", ignore_errors=True)
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ namespace toml
|
|||||||
static ProxyGroupConfig from_toml(const value& v)
|
static ProxyGroupConfig from_toml(const value& v)
|
||||||
{
|
{
|
||||||
ProxyGroupConfig conf;
|
ProxyGroupConfig conf;
|
||||||
conf.Name = toml::find<String>(v, "name");
|
conf.Name = find<String>(v, "name");
|
||||||
String type = toml::find<String>(v, "type");
|
String type = find<String>(v, "type");
|
||||||
String strategy = toml::find_or<String>(v, "strategy", "");
|
String strategy = find_or<String>(v, "strategy", "");
|
||||||
switch(hash_(type))
|
switch(hash_(type))
|
||||||
{
|
{
|
||||||
case "select"_hash:
|
case "select"_hash:
|
||||||
@@ -27,18 +27,18 @@ namespace toml
|
|||||||
break;
|
break;
|
||||||
case "url-test"_hash:
|
case "url-test"_hash:
|
||||||
conf.Type = ProxyGroupType::URLTest;
|
conf.Type = ProxyGroupType::URLTest;
|
||||||
conf.Url = toml::find<String>(v, "url");
|
conf.Url = find<String>(v, "url");
|
||||||
conf.Interval = toml::find<Integer>(v, "interval");
|
conf.Interval = find<Integer>(v, "interval");
|
||||||
conf.Tolerance = toml::find_or<Integer>(v, "tolerance", 0);
|
conf.Tolerance = find_or<Integer>(v, "tolerance", 0);
|
||||||
if(v.contains("lazy"))
|
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"))
|
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;
|
break;
|
||||||
case "load-balance"_hash:
|
case "load-balance"_hash:
|
||||||
conf.Type = ProxyGroupType::LoadBalance;
|
conf.Type = ProxyGroupType::LoadBalance;
|
||||||
conf.Url = toml::find<String>(v, "url");
|
conf.Url = find<String>(v, "url");
|
||||||
conf.Interval = toml::find<Integer>(v, "interval");
|
conf.Interval = find<Integer>(v, "interval");
|
||||||
switch(hash_(strategy))
|
switch(hash_(strategy))
|
||||||
{
|
{
|
||||||
case "consistent-hashing"_hash:
|
case "consistent-hashing"_hash:
|
||||||
@@ -49,14 +49,14 @@ namespace toml
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(v.contains("persistent"))
|
if(v.contains("persistent"))
|
||||||
conf.Persistent = toml::find_or(v, "persistent", conf.Persistent.get());
|
conf.Persistent = find_or(v, "persistent", conf.Persistent.get());
|
||||||
break;
|
break;
|
||||||
case "fallback"_hash:
|
case "fallback"_hash:
|
||||||
conf.Type = ProxyGroupType::Fallback;
|
conf.Type = ProxyGroupType::Fallback;
|
||||||
conf.Url = toml::find<String>(v, "url");
|
conf.Url = find<String>(v, "url");
|
||||||
conf.Interval = toml::find<Integer>(v, "interval");
|
conf.Interval = find<Integer>(v, "interval");
|
||||||
if(v.contains("evaluate-before-use"))
|
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;
|
break;
|
||||||
case "relay"_hash:
|
case "relay"_hash:
|
||||||
conf.Type = ProxyGroupType::Relay;
|
conf.Type = ProxyGroupType::Relay;
|
||||||
@@ -64,16 +64,26 @@ namespace toml
|
|||||||
case "ssid"_hash:
|
case "ssid"_hash:
|
||||||
conf.Type = ProxyGroupType::SSID;
|
conf.Type = ProxyGroupType::SSID;
|
||||||
break;
|
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:
|
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.Timeout = find_or(v, "timeout", 5);
|
||||||
conf.Proxies = toml::find_or<StrArray>(v, "rule", {});
|
conf.Proxies = find_or<StrArray>(v, "rule", {});
|
||||||
conf.UsingProvider = toml::find_or<StrArray>(v, "use", {});
|
conf.UsingProvider = find_or<StrArray>(v, "use", {});
|
||||||
if(conf.Proxies.empty() && conf.UsingProvider.empty())
|
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"))
|
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;
|
return conf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -84,8 +94,8 @@ namespace toml
|
|||||||
static RulesetConfig from_toml(const value& v)
|
static RulesetConfig from_toml(const value& v)
|
||||||
{
|
{
|
||||||
RulesetConfig conf;
|
RulesetConfig conf;
|
||||||
conf.Group = toml::find<String>(v, "group");
|
conf.Group = find<String>(v, "group");
|
||||||
String type = toml::find_or<String>(v, "type", "surge-ruleset");
|
String type = find_or<String>(v, "type", "surge-ruleset");
|
||||||
switch(hash_(type))
|
switch(hash_(type))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -122,10 +132,10 @@ namespace toml
|
|||||||
conf.Url = type + ":";
|
conf.Url = type + ":";
|
||||||
break;
|
break;
|
||||||
default:
|
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.Url += find<String>(v, "ruleset");
|
||||||
conf.Interval = toml::find_or<Integer>(v, "interval", 86400);
|
conf.Interval = find_or<Integer>(v, "interval", 86400);
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -138,14 +148,14 @@ namespace toml
|
|||||||
RegexMatchConfig conf;
|
RegexMatchConfig conf;
|
||||||
if(v.contains("script"))
|
if(v.contains("script"))
|
||||||
{
|
{
|
||||||
conf.Script = toml::find<String>(v, "script");
|
conf.Script = find<String>(v, "script");
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
conf.Match = toml::find<String>(v, "match");
|
conf.Match = find<String>(v, "match");
|
||||||
if(v.contains("emoji"))
|
if(v.contains("emoji"))
|
||||||
conf.Replace = toml::find<String>(v, "emoji");
|
conf.Replace = find<String>(v, "emoji");
|
||||||
else
|
else
|
||||||
conf.Replace = toml::find<String>(v, "replace");
|
conf.Replace = find<String>(v, "replace");
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -156,10 +166,10 @@ namespace toml
|
|||||||
static CronTaskConfig from_toml(const value& v)
|
static CronTaskConfig from_toml(const value& v)
|
||||||
{
|
{
|
||||||
CronTaskConfig conf;
|
CronTaskConfig conf;
|
||||||
conf.Name = toml::find<String>(v, "name");
|
conf.Name = find<String>(v, "name");
|
||||||
conf.CronExp = toml::find<String>(v, "cronexp");
|
conf.CronExp = find<String>(v, "cronexp");
|
||||||
conf.Path = toml::find<String>(v, "path");
|
conf.Path = find<String>(v, "path");
|
||||||
conf.Timeout = toml::find_or<Integer>(v, "timeout", 0);
|
conf.Timeout = find_or<Integer>(v, "timeout", 0);
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -220,6 +230,9 @@ namespace INIBinding
|
|||||||
case "ssid"_hash:
|
case "ssid"_hash:
|
||||||
conf.Type = ProxyGroupType::SSID;
|
conf.Type = ProxyGroupType::SSID;
|
||||||
break;
|
break;
|
||||||
|
case "smart"_hash:
|
||||||
|
conf.Type = ProxyGroupType::Smart;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,18 @@
|
|||||||
|
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
|
|
||||||
enum ProxyGroupType
|
enum class ProxyGroupType
|
||||||
{
|
{
|
||||||
Select,
|
Select,
|
||||||
URLTest,
|
URLTest,
|
||||||
Fallback,
|
Fallback,
|
||||||
LoadBalance,
|
LoadBalance,
|
||||||
Relay,
|
Relay,
|
||||||
SSID
|
SSID,
|
||||||
|
Smart
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BalanceStrategy
|
enum class BalanceStrategy
|
||||||
{
|
{
|
||||||
ConsistentHashing,
|
ConsistentHashing,
|
||||||
RoundRobin
|
RoundRobin
|
||||||
@@ -45,6 +46,7 @@ struct ProxyGroupConfig
|
|||||||
case ProxyGroupType::Fallback: return "fallback";
|
case ProxyGroupType::Fallback: return "fallback";
|
||||||
case ProxyGroupType::Relay: return "relay";
|
case ProxyGroupType::Relay: return "relay";
|
||||||
case ProxyGroupType::SSID: return "ssid";
|
case ProxyGroupType::SSID: return "ssid";
|
||||||
|
case ProxyGroupType::Smart: return "smart";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
|
|
||||||
enum RulesetType
|
enum class RulesetType
|
||||||
{
|
{
|
||||||
SurgeRuleset,
|
SurgeRuleset,
|
||||||
QuantumultX,
|
QuantumultX,
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
|
|
||||||
/// rule type lists
|
/// rule type lists
|
||||||
#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL"
|
#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 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 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"};
|
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.erase(strLine.find("//"));
|
||||||
strLine = trimWhitespace(strLine);
|
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++;
|
total_rules++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,12 +25,18 @@
|
|||||||
|
|
||||||
extern string_array ss_ciphers, ssr_ciphers;
|
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",
|
const string_array clashr_protocols = {
|
||||||
"auth_chain_b"};
|
"origin", "auth_sha1_v4", "auth_aes128_md5", "auth_aes128_sha1", "auth_chain_a",
|
||||||
const string_array clashr_obfs = {"plain", "http_simple", "http_post", "random_head", "tls1.2_ticket_auth",
|
"auth_chain_b"
|
||||||
"tls1.2_ticket_fastauth"};
|
};
|
||||||
const string_array clash_ssr_ciphers = {"rc4-md5", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb",
|
const string_array clashr_obfs = {
|
||||||
"aes-192-cfb", "aes-256-cfb", "chacha20-ietf", "xchacha20", "none"};
|
"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
|
std::string
|
||||||
vmessLinkConstruct(const std::string &remarks, const std::string &add, const std::string &port, const std::string &type,
|
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;
|
bool match = false;
|
||||||
std::string range_begin_str, range_end_str;
|
std::string range_begin_str, range_end_str;
|
||||||
int range_begin, range_end;
|
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) {
|
for (std::string &x: vArray) {
|
||||||
if (regMatch(x, reg_num)) {
|
if (regMatch(x, reg_num)) {
|
||||||
if (to_int(x, INT_MAX) == target)
|
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) {
|
bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &node) {
|
||||||
std::string target, ret_real_rule;
|
std::string target, ret_real_rule;
|
||||||
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)";
|
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex =
|
||||||
static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex = R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)";
|
R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)";
|
||||||
static const std::map<ProxyType, const char *> types = {{ProxyType::Shadowsocks, "SS"},
|
static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex =
|
||||||
{ProxyType::ShadowsocksR, "SSR"},
|
R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)";
|
||||||
{ProxyType::VMess, "VMESS"},
|
static const std::map<ProxyType, const char *> types = {
|
||||||
{ProxyType::Trojan, "TROJAN"},
|
{ProxyType::Shadowsocks, "SS"},
|
||||||
{ProxyType::Snell, "SNELL"},
|
{ProxyType::ShadowsocksR, "SSR"},
|
||||||
{ProxyType::HTTP, "HTTP"},
|
{ProxyType::VMess, "VMESS"},
|
||||||
{ProxyType::HTTPS, "HTTPS"},
|
{ProxyType::Trojan, "TROJAN"},
|
||||||
{ProxyType::SOCKS5, "SOCKS5"},
|
{ProxyType::Snell, "SNELL"},
|
||||||
{ProxyType::WireGuard, "WIREGUARD"},
|
{ProxyType::HTTP, "HTTP"},
|
||||||
{ProxyType::VLESS, "VLESS"},
|
{ProxyType::HTTPS, "HTTPS"},
|
||||||
{ProxyType::Hysteria, "HYSTERIA"},
|
{ProxyType::SOCKS5, "SOCKS5"},
|
||||||
{ProxyType::Hysteria2, "HYSTERIA2"}};
|
{ProxyType::WireGuard, "WIREGUARD"},
|
||||||
|
{ProxyType::VLESS, "VLESS"},
|
||||||
|
{ProxyType::Hysteria, "HYSTERIA"},
|
||||||
|
{ProxyType::Hysteria2, "HYSTERIA2"}
|
||||||
|
};
|
||||||
if (startsWith(rule, "!!GROUP=")) {
|
if (startsWith(rule, "!!GROUP=")) {
|
||||||
regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule);
|
regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule);
|
||||||
real_rule = 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) {
|
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.
|
// 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.
|
// not sure if other clients have the same problem.
|
||||||
std::replace(remark.begin(), remark.end(), '=', '-');
|
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");
|
auto filter = (std::function<std::string(const std::vector<Proxy> &)>) ctx.eval("filter");
|
||||||
std::string result_list = filter(nodelist);
|
std::string result_list = filter(nodelist);
|
||||||
filtered_nodelist = split(regTrim(result_list), "\n");
|
filtered_nodelist = split(regTrim(result_list), "\n");
|
||||||
}
|
} catch (qjs::exception) {
|
||||||
catch (qjs::exception) {
|
|
||||||
script_print_stack(ctx);
|
script_print_stack(ctx);
|
||||||
}
|
}
|
||||||
}, global.scriptCleanContext);
|
}, global.scriptCleanContext);
|
||||||
@@ -207,16 +217,28 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
std::vector<Proxy> nodelist;
|
std::vector<Proxy> nodelist;
|
||||||
string_array remarks_list;
|
string_array remarks_list;
|
||||||
/// proxies style
|
/// 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)) {
|
switch (hash_(ext.clash_proxies_style)) {
|
||||||
case "block"_hash:
|
case "block"_hash:
|
||||||
block = true;
|
proxy_block = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case "flow"_hash:
|
case "flow"_hash:
|
||||||
break;
|
break;
|
||||||
case "compact"_hash:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +258,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
tribool tfo = ext.tfo;
|
tribool tfo = ext.tfo;
|
||||||
udp.define(x.UDP);
|
udp.define(x.UDP);
|
||||||
xudp.define(x.XUDP);
|
xudp.define(x.XUDP);
|
||||||
scv = x.AllowInsecure;
|
scv.define(x.AllowInsecure);
|
||||||
tfo.define(x.TCPFastOpen);
|
tfo.define(x.TCPFastOpen);
|
||||||
singleproxy["name"] = x.Remark;
|
singleproxy["name"] = x.Remark;
|
||||||
singleproxy["server"] = x.Hostname;
|
singleproxy["server"] = x.Hostname;
|
||||||
@@ -277,6 +299,12 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
singleproxy["alterId"] = x.AlterId;
|
singleproxy["alterId"] = x.AlterId;
|
||||||
singleproxy["cipher"] = x.EncryptMethod;
|
singleproxy["cipher"] = x.EncryptMethod;
|
||||||
singleproxy["tls"] = x.TLSSecure;
|
singleproxy["tls"] = x.TLSSecure;
|
||||||
|
if (!x.AlpnList.empty()) {
|
||||||
|
for (auto &item: x.AlpnList) {
|
||||||
|
singleproxy["alpn"].push_back(item);
|
||||||
|
}
|
||||||
|
} else if (!x.Alpn.empty())
|
||||||
|
singleproxy["alpn"].push_back(x.Alpn);
|
||||||
if (!scv.is_undef())
|
if (!scv.is_undef())
|
||||||
singleproxy["skip-cert-verify"] = scv.get();
|
singleproxy["skip-cert-verify"] = scv.get();
|
||||||
if (!x.ServerName.empty())
|
if (!x.ServerName.empty())
|
||||||
@@ -327,8 +355,9 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
case ProxyType::ShadowsocksR:
|
case ProxyType::ShadowsocksR:
|
||||||
//ignoring all nodes with unsupported obfs, protocols and encryption
|
//ignoring all nodes with unsupported obfs, protocols and encryption
|
||||||
if (ext.filter_deprecated) {
|
if (ext.filter_deprecated) {
|
||||||
if (!clashR && std::find(clash_ssr_ciphers.cbegin(), clash_ssr_ciphers.cend(), x.EncryptMethod) ==
|
if (!clashR &&
|
||||||
clash_ssr_ciphers.cend())
|
std::find(clash_ssr_ciphers.cbegin(), clash_ssr_ciphers.cend(), x.EncryptMethod) ==
|
||||||
|
clash_ssr_ciphers.cend())
|
||||||
continue;
|
continue;
|
||||||
if (std::find(clashr_protocols.cbegin(), clashr_protocols.cend(), x.Protocol) ==
|
if (std::find(clashr_protocols.cbegin(), clashr_protocols.cend(), x.Protocol) ==
|
||||||
clashr_protocols.cend())
|
clashr_protocols.cend())
|
||||||
@@ -386,6 +415,12 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
else if (!x.Host.empty()) {
|
else if (!x.Host.empty()) {
|
||||||
singleproxy["sni"] = x.Host;
|
singleproxy["sni"] = x.Host;
|
||||||
}
|
}
|
||||||
|
if (!x.AlpnList.empty()) {
|
||||||
|
for (auto &item: x.AlpnList) {
|
||||||
|
singleproxy["alpn"].push_back(item);
|
||||||
|
}
|
||||||
|
} else if (!x.Alpn.empty())
|
||||||
|
singleproxy["alpn"].push_back(x.Alpn);
|
||||||
if (std::all_of(x.Password.begin(), x.Password.end(), ::isdigit) && !x.Password.empty()) {
|
if (std::all_of(x.Password.begin(), x.Password.end(), ::isdigit) && !x.Password.empty()) {
|
||||||
singleproxy["password"].SetTag("str");
|
singleproxy["password"].SetTag("str");
|
||||||
}
|
}
|
||||||
@@ -516,14 +551,63 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
singleproxy["congestion-controller"] = x.CongestionControl;
|
singleproxy["congestion-controller"] = x.CongestionControl;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ProxyType::AnyTLS:
|
||||||
|
singleproxy["type"] = "anytls";
|
||||||
|
if (!x.Password.empty()) {
|
||||||
|
singleproxy["password"] = x.Password;
|
||||||
|
}
|
||||||
|
if (!x.Fingerprint.empty()) {
|
||||||
|
singleproxy["client-fingerprint"] = x.Fingerprint;
|
||||||
|
}
|
||||||
|
if (!udp.is_undef()) {
|
||||||
|
singleproxy["udp"] = udp.get();
|
||||||
|
}
|
||||||
|
if (!x.ServerName.empty()) {
|
||||||
|
singleproxy["sni"] = x.SNI;
|
||||||
|
}
|
||||||
|
if (!scv.is_undef())
|
||||||
|
singleproxy["skip-cert-verify"] = scv.get();
|
||||||
|
if (!x.AlpnList.empty()) {
|
||||||
|
for (auto &item: x.AlpnList) {
|
||||||
|
singleproxy["alpn"].push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ProxyType::Mieru:
|
||||||
|
singleproxy["type"] = "mieru";
|
||||||
|
if (!x.Password.empty()) {
|
||||||
|
singleproxy["password"] = x.Password;
|
||||||
|
}
|
||||||
|
if (!x.Username.empty()) {
|
||||||
|
singleproxy["username"] = x.Username;
|
||||||
|
}
|
||||||
|
if (!x.Multiplexing.empty()) {
|
||||||
|
singleproxy["multiplexing"] = x.Multiplexing;
|
||||||
|
}
|
||||||
|
if (!x.TransferProtocol.empty()) {
|
||||||
|
singleproxy["transport"] = x.TransferProtocol;
|
||||||
|
}
|
||||||
|
if (!x.Ports.empty()) {
|
||||||
|
singleproxy["port-range"] = x.Ports;
|
||||||
|
singleproxy.remove("port");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ProxyType::VLESS:
|
case ProxyType::VLESS:
|
||||||
singleproxy["type"] = "vless";
|
singleproxy["type"] = "vless";
|
||||||
singleproxy["uuid"] = x.UserId;
|
singleproxy["uuid"] = x.UserId;
|
||||||
singleproxy["tls"] = x.TLSSecure;
|
singleproxy["tls"] = x.TLSSecure;
|
||||||
|
if (!x.AlpnList.empty()) {
|
||||||
|
for (auto &item: x.AlpnList) {
|
||||||
|
singleproxy["alpn"].push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!tfo.is_undef())
|
if (!tfo.is_undef())
|
||||||
singleproxy["tfo"] = tfo.get();
|
singleproxy["tfo"] = tfo.get();
|
||||||
if (xudp && udp)
|
if (xudp && udp)
|
||||||
singleproxy["xudp"] = true;
|
singleproxy["xudp"] = true;
|
||||||
|
if (!x.PacketEncoding.empty()) {
|
||||||
|
singleproxy["packet-encoding"] = x.PacketEncoding;
|
||||||
|
}
|
||||||
if (!x.Flow.empty())
|
if (!x.Flow.empty())
|
||||||
singleproxy["flow"] = x.Flow;
|
singleproxy["flow"] = x.Flow;
|
||||||
if (!scv.is_undef())
|
if (!scv.is_undef())
|
||||||
@@ -534,11 +618,14 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
if (!x.ServerName.empty())
|
if (!x.ServerName.empty())
|
||||||
singleproxy["servername"] = x.ServerName;
|
singleproxy["servername"] = x.ServerName;
|
||||||
if (!x.ShortId.empty()) {
|
if (!x.ShortId.empty()) {
|
||||||
singleproxy["reality-opts"]["short-id"] = x.ShortId;
|
singleproxy["reality-opts"]["short-id"] = "" + x.ShortId;
|
||||||
}
|
}
|
||||||
if (!x.PublicKey.empty() || x.Flow == "xtls-rprx-vision") {
|
if (!x.PublicKey.empty() || x.Flow == "xtls-rprx-vision") {
|
||||||
singleproxy["client-fingerprint"] = "chrome";
|
singleproxy["client-fingerprint"] = "chrome";
|
||||||
}
|
}
|
||||||
|
if (!x.Fingerprint.empty()) {
|
||||||
|
singleproxy["client-fingerprint"] = x.Fingerprint;
|
||||||
|
}
|
||||||
switch (hash_(x.TransferProtocol)) {
|
switch (hash_(x.TransferProtocol)) {
|
||||||
case "tcp"_hash:
|
case "tcp"_hash:
|
||||||
singleproxy["network"] = x.TransferProtocol;
|
singleproxy["network"] = x.TransferProtocol;
|
||||||
@@ -591,7 +678,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
// sees in https://dreamacro.github.io/clash/configuration/outbound.html#snell
|
// sees in https://dreamacro.github.io/clash/configuration/outbound.html#snell
|
||||||
if (udp && x.Type != ProxyType::Snell && x.Type != ProxyType::TUIC)
|
if (udp && x.Type != ProxyType::Snell && x.Type != ProxyType::TUIC)
|
||||||
singleproxy["udp"] = true;
|
singleproxy["udp"] = true;
|
||||||
if (block)
|
if (proxy_block)
|
||||||
singleproxy.SetStyle(YAML::EmitterStyle::Block);
|
singleproxy.SetStyle(YAML::EmitterStyle::Block);
|
||||||
else
|
else
|
||||||
singleproxy.SetStyle(YAML::EmitterStyle::Flow);
|
singleproxy.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
@@ -600,7 +687,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
nodelist.emplace_back(x);
|
nodelist.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compact)
|
if (proxy_compact)
|
||||||
proxies.SetStyle(YAML::EmitterStyle::Flow);
|
proxies.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
|
||||||
if (ext.nodelist) {
|
if (ext.nodelist) {
|
||||||
@@ -621,7 +708,10 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
string_array filtered_nodelist;
|
string_array filtered_nodelist;
|
||||||
|
|
||||||
singlegroup["name"] = x.Name;
|
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) {
|
switch (x.Type) {
|
||||||
case ProxyGroupType::Select:
|
case ProxyGroupType::Select:
|
||||||
@@ -630,6 +720,8 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
case ProxyGroupType::LoadBalance:
|
case ProxyGroupType::LoadBalance:
|
||||||
singlegroup["strategy"] = x.StrategyStr();
|
singlegroup["strategy"] = x.StrategyStr();
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
case ProxyGroupType::Smart:
|
||||||
|
[[fallthrough]];
|
||||||
case ProxyGroupType::URLTest:
|
case ProxyGroupType::URLTest:
|
||||||
if (!x.Lazy.is_undef())
|
if (!x.Lazy.is_undef())
|
||||||
singlegroup["lazy"] = x.Lazy.get();
|
singlegroup["lazy"] = x.Lazy.get();
|
||||||
@@ -658,7 +750,10 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
}
|
}
|
||||||
if (!filtered_nodelist.empty())
|
if (!filtered_nodelist.empty())
|
||||||
singlegroup["proxies"] = filtered_nodelist;
|
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;
|
bool replace_flag = false;
|
||||||
for (auto &&original_group: original_groups) {
|
for (auto &&original_group: original_groups) {
|
||||||
@@ -671,6 +766,8 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
if (!replace_flag)
|
if (!replace_flag)
|
||||||
original_groups.push_back(singlegroup);
|
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;
|
yamlnode["proxy-groups"] = original_groups;
|
||||||
@@ -678,15 +775,43 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
|||||||
yamlnode["Proxy Group"] = original_groups;
|
yamlnode["Proxy Group"] = original_groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void formatterShortId(std::string &input) {
|
||||||
|
std::string target = "short-id:";
|
||||||
|
size_t startPos = input.find(target);
|
||||||
|
|
||||||
|
while (startPos != std::string::npos) {
|
||||||
|
// 查找对应实例的结束位置
|
||||||
|
size_t endPos = input.find("}", startPos);
|
||||||
|
|
||||||
|
if (endPos != std::string::npos) {
|
||||||
|
// 提取原始id
|
||||||
|
std::string originalId = input.substr(startPos + target.length(), endPos - startPos - target.length());
|
||||||
|
|
||||||
|
// 去除原始id中的空格
|
||||||
|
originalId.erase(remove_if(originalId.begin(), originalId.end(), ::isspace), originalId.end());
|
||||||
|
|
||||||
|
// 添加引号
|
||||||
|
std::string modifiedId = " \"" + originalId + "\" ";
|
||||||
|
|
||||||
|
// 替换原始id为修改后的id
|
||||||
|
input.replace(startPos + target.length(), endPos - startPos - target.length(), modifiedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 继续查找下一个实例
|
||||||
|
startPos = input.find(target, startPos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string proxyToClash(std::vector<Proxy> &nodes, const std::string &base_conf,
|
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) {
|
bool clashR, extra_settings &ext) {
|
||||||
YAML::Node yamlnode;
|
YAML::Node yamlnode;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
yamlnode = YAML::Load(base_conf);
|
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);
|
writeLog(0, std::string("Clash base loader failed with error: ") + e.what(), LOG_LEVEL_ERROR);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -725,6 +850,7 @@ std::string proxyToClash(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
//rulesetToClash(yamlnode, ruleset_content_array, ext.overwrite_original_rules, ext.clash_new_field_name);
|
//rulesetToClash(yamlnode, ruleset_content_array, ext.overwrite_original_rules, ext.clash_new_field_name);
|
||||||
//std::string output_content = YAML::Dump(yamlnode);
|
//std::string output_content = YAML::Dump(yamlnode);
|
||||||
replaceAll(output_content, "!<str> ", "");
|
replaceAll(output_content, "!<str> ", "");
|
||||||
|
formatterShortId(output_content);
|
||||||
return output_content;
|
return output_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,7 +879,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::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) {
|
int surge_ver, extra_settings &ext) {
|
||||||
INIReader ini;
|
INIReader ini;
|
||||||
std::string output_nodelist;
|
std::string output_nodelist;
|
||||||
@@ -788,8 +915,11 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
|
|
||||||
processRemark(x.Remark, remarks_list);
|
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 &hostname = x.Hostname, &sni = x.ServerName, &username = x.Username, &password = x.Password, &method
|
||||||
std::string port = std::to_string(x.Port);
|
= 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;
|
bool &tlssecure = x.TLSSecure;
|
||||||
|
|
||||||
tribool udp = ext.udp, tfo = ext.tfo, scv = ext.skip_cert_verify, tls13 = ext.tls13;
|
tribool udp = ext.udp, tfo = ext.tfo, scv = ext.skip_cert_verify, tls13 = ext.tls13;
|
||||||
@@ -804,7 +934,8 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
switch (x.Type) {
|
switch (x.Type) {
|
||||||
case ProxyType::Shadowsocks:
|
case ProxyType::Shadowsocks:
|
||||||
if (surge_ver >= 3 || surge_ver == -3) {
|
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 {
|
} else {
|
||||||
proxy = "custom, " + hostname + ", " + port + ", " + method + ", " + password +
|
proxy = "custom, " + hostname + ", " + port + ", " + method + ", " + password +
|
||||||
", https://github.com/pobizhe/SSEncrypt/raw/master/SSEncrypt.module";
|
", https://github.com/pobizhe/SSEncrypt/raw/master/SSEncrypt.module";
|
||||||
@@ -853,8 +984,10 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
if (ext.surge_ssr_path.empty() || surge_ver < 2)
|
if (ext.surge_ssr_path.empty() || surge_ver < 2)
|
||||||
continue;
|
continue;
|
||||||
proxy = "external, exec=\"" + ext.surge_ssr_path + "\", args=\"";
|
proxy = "external, exec=\"" + ext.surge_ssr_path + "\", args=\"";
|
||||||
args = {"-l", std::to_string(local_port), "-s", hostname, "-p", port, "-m", method, "-k", password,
|
args = {
|
||||||
"-o", obfs, "-O", protocol};
|
"-l", std::to_string(local_port), "-s", hostname, "-p", port, "-m", method, "-k", password,
|
||||||
|
"-o", obfs, "-O", protocol
|
||||||
|
};
|
||||||
if (!obfsparam.empty()) {
|
if (!obfsparam.empty()) {
|
||||||
args.emplace_back("-g");
|
args.emplace_back("-g");
|
||||||
args.emplace_back(std::move(obfsparam));
|
args.emplace_back(std::move(obfsparam));
|
||||||
@@ -923,11 +1056,18 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
proxy += ", version=" + std::to_string(x.SnellVersion);
|
proxy += ", version=" + std::to_string(x.SnellVersion);
|
||||||
break;
|
break;
|
||||||
case ProxyType::Hysteria2:
|
case ProxyType::Hysteria2:
|
||||||
if (surge_ver < 4 && surge_ver != -3)
|
if (surge_ver < 4)
|
||||||
continue;
|
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())
|
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;
|
break;
|
||||||
case ProxyType::WireGuard:
|
case ProxyType::WireGuard:
|
||||||
if (surge_ver < 4 && surge_ver != -3)
|
if (surge_ver < 4 && surge_ver != -3)
|
||||||
@@ -959,7 +1099,8 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
proxy += ", tfo=" + tfo.get_str();
|
proxy += ", tfo=" + tfo.get_str();
|
||||||
if (!udp.is_undef())
|
if (!udp.is_undef())
|
||||||
proxy += ", udp-relay=" + udp.get_str();
|
proxy += ", udp-relay=" + udp.get_str();
|
||||||
|
if (underlying_proxy != "")
|
||||||
|
proxy += ", underlying-proxy=" + underlying_proxy;
|
||||||
if (ext.nodelist)
|
if (ext.nodelist)
|
||||||
output_nodelist += x.Remark + " = " + proxy + "\n";
|
output_nodelist += x.Remark + " = " + proxy + "\n";
|
||||||
else {
|
else {
|
||||||
@@ -980,6 +1121,7 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
|
|
||||||
switch (x.Type) {
|
switch (x.Type) {
|
||||||
case ProxyGroupType::Select:
|
case ProxyGroupType::Select:
|
||||||
|
case ProxyGroupType::Smart:
|
||||||
case ProxyGroupType::URLTest:
|
case ProxyGroupType::URLTest:
|
||||||
case ProxyGroupType::Fallback:
|
case ProxyGroupType::Fallback:
|
||||||
break;
|
break;
|
||||||
@@ -1032,7 +1174,8 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ext.enable_rule_generator)
|
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();
|
return ini.to_string();
|
||||||
}
|
}
|
||||||
@@ -1044,7 +1187,12 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
|||||||
|
|
||||||
for (Proxy &x: nodes) {
|
for (Proxy &x: nodes) {
|
||||||
std::string remark = x.Remark;
|
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;
|
bool &tlssecure = x.TLSSecure;
|
||||||
std::string port = std::to_string(x.Port);
|
std::string port = std::to_string(x.Port);
|
||||||
std::string aid = std::to_string(x.AlterId);
|
std::string aid = std::to_string(x.AlterId);
|
||||||
@@ -1061,23 +1209,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() &&
|
if (std::find(ssr_ciphers.begin(), ssr_ciphers.end(), method) != ssr_ciphers.end() &&
|
||||||
plugin.empty())
|
plugin.empty())
|
||||||
proxyStr = "ssr://" + urlSafeBase64Encode(
|
proxyStr = "ssr://" + urlSafeBase64Encode(
|
||||||
hostname + ":" + port + ":origin:" + method + ":plain:" + urlSafeBase64Encode(password) \
|
hostname + ":" + port + ":origin:" + method + ":plain:" +
|
||||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(remark));
|
urlSafeBase64Encode(password)
|
||||||
|
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(
|
||||||
|
remark));
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case ProxyType::ShadowsocksR:
|
case ProxyType::ShadowsocksR:
|
||||||
if (ssr) {
|
if (ssr) {
|
||||||
proxyStr = "ssr://" + urlSafeBase64Encode(
|
proxyStr = "ssr://" + urlSafeBase64Encode(
|
||||||
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
||||||
urlSafeBase64Encode(password) \
|
urlSafeBase64Encode(password)
|
||||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(remark) \
|
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(
|
||||||
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" + urlSafeBase64Encode(protoparam));
|
remark)
|
||||||
|
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" +
|
||||||
|
urlSafeBase64Encode(protoparam));
|
||||||
} else if (ss) {
|
} else if (ss) {
|
||||||
if (std::find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() &&
|
if (std::find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() &&
|
||||||
protocol == "origin" && obfs == "plain")
|
protocol == "origin" && obfs == "plain")
|
||||||
proxyStr =
|
proxyStr =
|
||||||
"ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" + port +
|
"ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" +
|
||||||
|
port +
|
||||||
"#" + urlEncode(remark);
|
"#" + urlEncode(remark);
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
@@ -1086,8 +1239,8 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
|||||||
if (!vmess)
|
if (!vmess)
|
||||||
continue;
|
continue;
|
||||||
proxyStr = "vmess://" + base64Encode(
|
proxyStr = "vmess://" + base64Encode(
|
||||||
vmessLinkConstruct(remark, hostname, port, faketype, id, aid, transproto, path, host,
|
vmessLinkConstruct(remark, hostname, port, faketype, id, aid, transproto, path, host,
|
||||||
tlssecure ? "tls" : ""));
|
tlssecure ? "tls" : ""));
|
||||||
break;
|
break;
|
||||||
case ProxyType::Trojan:
|
case ProxyType::Trojan:
|
||||||
if (!trojan)
|
if (!trojan)
|
||||||
@@ -1129,7 +1282,8 @@ std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra
|
|||||||
base_conf = "{}";
|
base_conf = "{}";
|
||||||
rapidjson::ParseResult result = base.Parse(base_conf.data());
|
rapidjson::ParseResult result = base.Parse(base_conf.data());
|
||||||
if (!result)
|
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);
|
" (" + std::to_string(result.Offset()) + ")", LOG_LEVEL_ERROR);
|
||||||
|
|
||||||
rapidjson::Value proxies(rapidjson::kArrayType);
|
rapidjson::Value proxies(rapidjson::kArrayType);
|
||||||
@@ -1158,20 +1312,21 @@ std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra
|
|||||||
}
|
}
|
||||||
rapidjson::Value proxy(rapidjson::kObjectType);
|
rapidjson::Value proxy(rapidjson::kObjectType);
|
||||||
proxy.CopyFrom(base, alloc)
|
proxy.CopyFrom(base, alloc)
|
||||||
| AddMemberOrReplace("remarks", rapidjson::Value(remark.c_str(), remark.size()), alloc)
|
| AddMemberOrReplace("remarks", rapidjson::Value(remark.c_str(), remark.size()), alloc)
|
||||||
| AddMemberOrReplace("server", rapidjson::Value(hostname.c_str(), hostname.size()), alloc)
|
| AddMemberOrReplace("server", rapidjson::Value(hostname.c_str(), hostname.size()), alloc)
|
||||||
| AddMemberOrReplace("server_port", rapidjson::Value(x.Port), alloc)
|
| AddMemberOrReplace("server_port", rapidjson::Value(x.Port), alloc)
|
||||||
| AddMemberOrReplace("method", rapidjson::Value(method.c_str(), method.size()), alloc)
|
| AddMemberOrReplace("method", rapidjson::Value(method.c_str(), method.size()), alloc)
|
||||||
| AddMemberOrReplace("password", rapidjson::Value(password.c_str(), password.size()), alloc)
|
| AddMemberOrReplace("password", rapidjson::Value(password.c_str(), password.size()), alloc)
|
||||||
| AddMemberOrReplace("plugin", rapidjson::Value(plugin.c_str(), plugin.size()), alloc)
|
| AddMemberOrReplace("plugin", rapidjson::Value(plugin.c_str(), plugin.size()), alloc)
|
||||||
| AddMemberOrReplace("plugin_opts", rapidjson::Value(pluginopts.c_str(), pluginopts.size()), alloc);
|
| AddMemberOrReplace("plugin_opts", rapidjson::Value(pluginopts.c_str(), pluginopts.size()), alloc);
|
||||||
proxies.PushBack(proxy, alloc);
|
proxies.PushBack(proxy, alloc);
|
||||||
}
|
}
|
||||||
return proxies | SerializeObject();
|
return proxies | SerializeObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
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) {
|
const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
|
||||||
INIReader ini;
|
INIReader ini;
|
||||||
ini.store_any_line = true;
|
ini.store_any_line = true;
|
||||||
@@ -1209,7 +1364,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
|||||||
|
|
||||||
processRemark(x.Remark, remarks_list);
|
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);
|
std::string port = std::to_string(x.Port);
|
||||||
bool &tlssecure = x.TLSSecure;
|
bool &tlssecure = x.TLSSecure;
|
||||||
tribool scv;
|
tribool scv;
|
||||||
@@ -1222,7 +1382,8 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
|||||||
if (method == "auto")
|
if (method == "auto")
|
||||||
method = "chacha20-ietf-poly1305";
|
method = "chacha20-ietf-poly1305";
|
||||||
proxyStr =
|
proxyStr =
|
||||||
x.Remark + " = vmess, " + hostname + ", " + port + ", " + method + ", \"" + id + "\", group=" +
|
x.Remark + " = vmess, " + hostname + ", " + port + ", " + method + ", \"" + id +
|
||||||
|
"\", group=" +
|
||||||
x.Group;
|
x.Group;
|
||||||
if (tlssecure) {
|
if (tlssecure) {
|
||||||
proxyStr += ", over-tls=true, tls-host=" + host;
|
proxyStr += ", over-tls=true, tls-host=" + host;
|
||||||
@@ -1242,10 +1403,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
|||||||
case ProxyType::ShadowsocksR:
|
case ProxyType::ShadowsocksR:
|
||||||
if (ext.nodelist) {
|
if (ext.nodelist) {
|
||||||
proxyStr = "ssr://" + urlSafeBase64Encode(
|
proxyStr = "ssr://" + urlSafeBase64Encode(
|
||||||
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
||||||
urlSafeBase64Encode(password) \
|
urlSafeBase64Encode(password)
|
||||||
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(x.Remark) \
|
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(
|
||||||
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" + urlSafeBase64Encode(protoparam));
|
x.Remark)
|
||||||
|
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" +
|
||||||
|
urlSafeBase64Encode(protoparam));
|
||||||
} else {
|
} else {
|
||||||
proxyStr = x.Remark + " = shadowsocksr, " + hostname + ", " + port + ", " + method + ", \"" +
|
proxyStr = x.Remark + " = shadowsocksr, " + hostname + ", " + port + ", " + method + ", \"" +
|
||||||
password + "\", group=" + x.Group + ", protocol=" + protocol + ", obfs=" + obfs;
|
password + "\", group=" + x.Group + ", protocol=" + protocol + ", obfs=" + obfs;
|
||||||
@@ -1264,7 +1427,8 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
|||||||
proxyStr += "&group=" + urlSafeBase64Encode(x.Group) + "#" + urlEncode(x.Remark);
|
proxyStr += "&group=" + urlSafeBase64Encode(x.Group) + "#" + urlEncode(x.Remark);
|
||||||
} else {
|
} else {
|
||||||
proxyStr =
|
proxyStr =
|
||||||
x.Remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" + password +
|
x.Remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" +
|
||||||
|
password +
|
||||||
"\", group=" + x.Group;
|
"\", group=" + x.Group;
|
||||||
if (plugin == "obfs-local" && !pluginopts.empty()) {
|
if (plugin == "obfs-local" && !pluginopts.empty()) {
|
||||||
proxyStr += ", " + replaceAllDistinct(pluginopts, ";", ", ");
|
proxyStr += ", " + replaceAllDistinct(pluginopts, ";", ", ");
|
||||||
@@ -1273,11 +1437,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
|||||||
break;
|
break;
|
||||||
case ProxyType::HTTP:
|
case ProxyType::HTTP:
|
||||||
case ProxyType::HTTPS:
|
case ProxyType::HTTPS:
|
||||||
proxyStr = x.Remark + " = http, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port +
|
proxyStr =
|
||||||
", group=" + x.Group;
|
x.Remark + " = http, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port +
|
||||||
|
", group=" + x.Group;
|
||||||
if (!username.empty() && !password.empty())
|
if (!username.empty() && !password.empty())
|
||||||
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username +
|
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username +
|
||||||
", upstream-proxy-password=" + password;
|
", upstream-proxy-password=" + password;
|
||||||
else
|
else
|
||||||
proxyStr += ", upstream-proxy-auth=false";
|
proxyStr += ", upstream-proxy-auth=false";
|
||||||
|
|
||||||
@@ -1293,11 +1458,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
|
|||||||
proxyStr = "http://" + urlSafeBase64Encode(proxyStr);
|
proxyStr = "http://" + urlSafeBase64Encode(proxyStr);
|
||||||
break;
|
break;
|
||||||
case ProxyType::SOCKS5:
|
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;
|
", group=" + x.Group;
|
||||||
if (!username.empty() && !password.empty())
|
if (!username.empty() && !password.empty())
|
||||||
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username +
|
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username +
|
||||||
", upstream-proxy-password=" + password;
|
", upstream-proxy-password=" + password;
|
||||||
else
|
else
|
||||||
proxyStr += ", upstream-proxy-auth=false";
|
proxyStr += ", upstream-proxy-auth=false";
|
||||||
|
|
||||||
@@ -1387,7 +1553,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::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) {
|
extra_settings &ext) {
|
||||||
INIReader ini;
|
INIReader ini;
|
||||||
ini.store_any_line = true;
|
ini.store_any_line = true;
|
||||||
@@ -1433,7 +1600,10 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
|||||||
|
|
||||||
processRemark(x.Remark, remarks_list);
|
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);
|
std::string port = std::to_string(x.Port);
|
||||||
bool &tlssecure = x.TLSSecure;
|
bool &tlssecure = x.TLSSecure;
|
||||||
|
|
||||||
@@ -1484,7 +1654,8 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
|||||||
proxyStr += ", obfs=over-tls, obfs-host=" + host;
|
proxyStr += ", obfs=over-tls, obfs-host=" + host;
|
||||||
break;
|
break;
|
||||||
case ProxyType::Shadowsocks:
|
case ProxyType::Shadowsocks:
|
||||||
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
|
proxyStr =
|
||||||
|
"shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
|
||||||
if (!plugin.empty()) {
|
if (!plugin.empty()) {
|
||||||
switch (hash_(plugin)) {
|
switch (hash_(plugin)) {
|
||||||
case "simple-obfs"_hash:
|
case "simple-obfs"_hash:
|
||||||
@@ -1516,8 +1687,9 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case ProxyType::ShadowsocksR:
|
case ProxyType::ShadowsocksR:
|
||||||
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password +
|
proxyStr =
|
||||||
", ssr-protocol=" + protocol;
|
"shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password +
|
||||||
|
", ssr-protocol=" + protocol;
|
||||||
if (!protoparam.empty())
|
if (!protoparam.empty())
|
||||||
proxyStr += ", ssr-protocol-param=" + protoparam;
|
proxyStr += ", ssr-protocol-param=" + protoparam;
|
||||||
proxyStr += ", obfs=" + obfs;
|
proxyStr += ", obfs=" + obfs;
|
||||||
@@ -1526,8 +1698,9 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
|||||||
break;
|
break;
|
||||||
case ProxyType::HTTP:
|
case ProxyType::HTTP:
|
||||||
case ProxyType::HTTPS:
|
case ProxyType::HTTPS:
|
||||||
proxyStr = "http = " + hostname + ":" + port + ", username=" + (username.empty() ? "none" : username) +
|
proxyStr =
|
||||||
", password=" + (password.empty() ? "none" : password);
|
"http = " + hostname + ":" + port + ", username=" + (username.empty() ? "none" : username) +
|
||||||
|
", password=" + (password.empty() ? "none" : password);
|
||||||
if (tlssecure) {
|
if (tlssecure) {
|
||||||
proxyStr += ", over-tls=true";
|
proxyStr += ", over-tls=true";
|
||||||
if (!tls13.is_undef())
|
if (!tls13.is_undef())
|
||||||
@@ -1641,7 +1814,7 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
|
|||||||
std::string proxies = join(filtered_nodelist, ", ");
|
std::string proxies = join(filtered_nodelist, ", ");
|
||||||
|
|
||||||
std::string singlegroup = type + "=" + x.Name + ", " + proxies;
|
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);
|
singlegroup += ", check-interval=" + std::to_string(x.Interval);
|
||||||
if (x.Tolerance > 0)
|
if (x.Tolerance > 0)
|
||||||
singlegroup += ", tolerance=" + std::to_string(x.Tolerance);
|
singlegroup += ", tolerance=" + std::to_string(x.Tolerance);
|
||||||
@@ -1672,9 +1845,10 @@ std::string proxyToSSD(std::vector<Proxy> &nodes, std::string &group, std::strin
|
|||||||
writer.String("password");
|
writer.String("password");
|
||||||
if (!userinfo.empty()) {
|
if (!userinfo.empty()) {
|
||||||
std::string data = replaceAllDistinct(userinfo, "; ", "&");
|
std::string data = replaceAllDistinct(userinfo, "; ", "&");
|
||||||
std::string upload = getUrlArg(data, "upload"), download = getUrlArg(data, "download"), total = getUrlArg(data,
|
std::string upload = getUrlArg(data, "upload"), download = getUrlArg(data, "download"), total = getUrlArg(
|
||||||
"total"), expiry = getUrlArg(
|
data,
|
||||||
data, "expire");
|
"total"), expiry = getUrlArg(
|
||||||
|
data, "expire");
|
||||||
double used = (to_number(upload, 0.0) + to_number(download, 0.0)) / std::pow(1024, 3) * 1.0, tot =
|
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;
|
to_number(total, 0.0) / std::pow(1024, 3) * 1.0;
|
||||||
writer.Key("traffic_used");
|
writer.Key("traffic_used");
|
||||||
@@ -1694,7 +1868,8 @@ std::string proxyToSSD(std::vector<Proxy> &nodes, std::string &group, std::strin
|
|||||||
writer.StartArray();
|
writer.StartArray();
|
||||||
|
|
||||||
for (Proxy &x: nodes) {
|
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) {
|
switch (x.Type) {
|
||||||
case ProxyType::Shadowsocks:
|
case ProxyType::Shadowsocks:
|
||||||
@@ -1796,7 +1971,8 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
|
|||||||
case ProxyType::Shadowsocks:
|
case ProxyType::Shadowsocks:
|
||||||
if (!x.Plugin.empty())
|
if (!x.Plugin.empty())
|
||||||
continue;
|
continue;
|
||||||
proxy = x.Remark + ", ss, ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" +
|
proxy = x.Remark + ", ss, ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname +
|
||||||
|
":" +
|
||||||
port;
|
port;
|
||||||
break;
|
break;
|
||||||
case ProxyType::VMess:
|
case ProxyType::VMess:
|
||||||
@@ -1831,11 +2007,13 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
|
|||||||
proxy += "&sockopt.tcpfastopen=" + tfo.get_str();
|
proxy += "&sockopt.tcpfastopen=" + tfo.get_str();
|
||||||
break;
|
break;
|
||||||
case ProxyType::SOCKS5:
|
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;
|
", pass=" + password;
|
||||||
break;
|
break;
|
||||||
case ProxyType::HTTP:
|
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;
|
", pass=" + password;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1900,7 +2078,8 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
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) {
|
const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
|
||||||
INIReader ini;
|
INIReader ini;
|
||||||
std::string output_nodelist;
|
std::string output_nodelist;
|
||||||
@@ -1925,7 +2104,10 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
|
|||||||
}
|
}
|
||||||
processRemark(x.Remark, remarks_list);
|
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);
|
std::string port = std::to_string(x.Port), aid = std::to_string(x.AlterId);
|
||||||
bool &tlssecure = x.TLSSecure;
|
bool &tlssecure = x.TLSSecure;
|
||||||
|
|
||||||
@@ -1940,7 +2122,8 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
|
|||||||
if (plugin == "simple-obfs" || plugin == "obfs-local") {
|
if (plugin == "simple-obfs" || plugin == "obfs-local") {
|
||||||
if (!pluginopts.empty())
|
if (!pluginopts.empty())
|
||||||
proxy += "," +
|
proxy += "," +
|
||||||
replaceAllDistinct(replaceAllDistinct(pluginopts, ";obfs-host=", ","), "obfs=", "");
|
replaceAllDistinct(replaceAllDistinct(pluginopts, ";obfs-host=", ","), "obfs=",
|
||||||
|
"");
|
||||||
} else if (!plugin.empty())
|
} else if (!plugin.empty())
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
@@ -2125,7 +2308,8 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
|
|||||||
if (x.Type != ProxyGroupType::Select) {
|
if (x.Type != ProxyGroupType::Select) {
|
||||||
group += ",url=" + x.Url + ",interval=" + std::to_string(x.Interval);
|
group += ",url=" + x.Url + ",interval=" + std::to_string(x.Interval);
|
||||||
if (x.Type == ProxyGroupType::LoadBalance) {
|
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)
|
if (x.Timeout > 0)
|
||||||
group += ",max-timeout=" + std::to_string(x.Timeout);
|
group += ",max-timeout=" + std::to_string(x.Timeout);
|
||||||
}
|
}
|
||||||
@@ -2224,6 +2408,14 @@ static rapidjson::Value stringArrayToJsonArray(const std::string &array, const s
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rapidjson::Value
|
||||||
|
vectorToJsonArray(const std::vector<std::string> &array, rapidjson::MemoryPoolAllocator<> &allocator) {
|
||||||
|
rapidjson::Value result(rapidjson::kArrayType);
|
||||||
|
for (const auto &x: array)
|
||||||
|
result.PushBack(rapidjson::Value(trim(x).c_str(), allocator), allocator);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool isNumeric(const std::string &str) {
|
bool isNumeric(const std::string &str) {
|
||||||
for (char c: str) {
|
for (char c: str) {
|
||||||
if (!std::isdigit(static_cast<unsigned char>(c))) {
|
if (!std::isdigit(static_cast<unsigned char>(c))) {
|
||||||
@@ -2234,7 +2426,8 @@ bool isNumeric(const std::string &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) {
|
||||||
using namespace rapidjson_ext;
|
using namespace rapidjson_ext;
|
||||||
rapidjson::Document::AllocatorType &allocator = json.GetAllocator();
|
rapidjson::Document::AllocatorType &allocator = json.GetAllocator();
|
||||||
@@ -2282,16 +2475,16 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// case ProxyType::ShadowsocksR: {
|
// case ProxyType::ShadowsocksR: {
|
||||||
// addSingBoxCommonMembers(proxy, x, "shadowsocksr", allocator);
|
// addSingBoxCommonMembers(proxy, x, "shadowsocksr", allocator);
|
||||||
// proxy.AddMember("method", rapidjson::StringRef(x.EncryptMethod.c_str()), allocator);
|
// proxy.AddMember("method", rapidjson::StringRef(x.EncryptMethod.c_str()), allocator);
|
||||||
// proxy.AddMember("password", rapidjson::StringRef(x.Password.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", rapidjson::StringRef(x.Protocol.c_str()), allocator);
|
||||||
// proxy.AddMember("protocol_param", rapidjson::StringRef(x.ProtocolParam.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", rapidjson::StringRef(x.OBFS.c_str()), allocator);
|
||||||
// proxy.AddMember("obfs_param", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
|
// proxy.AddMember("obfs_param", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
case ProxyType::VMess: {
|
case ProxyType::VMess: {
|
||||||
addSingBoxCommonMembers(proxy, x, "vmess", allocator);
|
addSingBoxCommonMembers(proxy, x, "vmess", allocator);
|
||||||
proxy.AddMember("uuid", rapidjson::StringRef(x.UserId.c_str()), allocator);
|
proxy.AddMember("uuid", rapidjson::StringRef(x.UserId.c_str()), allocator);
|
||||||
@@ -2310,6 +2503,9 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
proxy.AddMember("packet_encoding", rapidjson::StringRef("xudp"), allocator);
|
proxy.AddMember("packet_encoding", rapidjson::StringRef("xudp"), allocator);
|
||||||
if (!x.Flow.empty())
|
if (!x.Flow.empty())
|
||||||
proxy.AddMember("flow", rapidjson::StringRef(x.Flow.c_str()), allocator);
|
proxy.AddMember("flow", rapidjson::StringRef(x.Flow.c_str()), allocator);
|
||||||
|
if (!x.PacketEncoding.empty()) {
|
||||||
|
proxy.AddMember("packet_encoding", rapidjson::StringRef(x.PacketEncoding.c_str()), allocator);
|
||||||
|
}
|
||||||
rapidjson::Value vlesstransport(rapidjson::kObjectType);
|
rapidjson::Value vlesstransport(rapidjson::kObjectType);
|
||||||
rapidjson::Value vlessheaders(rapidjson::kObjectType);
|
rapidjson::Value vlessheaders(rapidjson::kObjectType);
|
||||||
switch (hash_(x.TransferProtocol)) {
|
switch (hash_(x.TransferProtocol)) {
|
||||||
@@ -2368,8 +2564,8 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
proxy.AddMember("inet4_bind_address", rapidjson::StringRef(x.SelfIP.c_str()), allocator);
|
proxy.AddMember("inet4_bind_address", rapidjson::StringRef(x.SelfIP.c_str()), allocator);
|
||||||
rapidjson::Value addresses(rapidjson::kArrayType);
|
rapidjson::Value addresses(rapidjson::kArrayType);
|
||||||
addresses.PushBack(rapidjson::StringRef(x.SelfIP.append("/32").c_str()), allocator);
|
addresses.PushBack(rapidjson::StringRef(x.SelfIP.append("/32").c_str()), allocator);
|
||||||
// if (!x.SelfIPv6.empty())
|
// if (!x.SelfIPv6.empty())
|
||||||
// addresses.PushBack(rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
// addresses.PushBack(rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
||||||
proxy.AddMember("local_address", addresses, allocator);
|
proxy.AddMember("local_address", addresses, allocator);
|
||||||
if (!x.SelfIPv6.empty())
|
if (!x.SelfIPv6.empty())
|
||||||
proxy.AddMember("inet6_bind_address", rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
proxy.AddMember("inet6_bind_address", rapidjson::StringRef(x.SelfIPv6.c_str()), allocator);
|
||||||
@@ -2457,7 +2653,6 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
addSingBoxCommonMembers(proxy, x, "hysteria2", allocator);
|
addSingBoxCommonMembers(proxy, x, "hysteria2", allocator);
|
||||||
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
||||||
if (!x.TLSSecure) {
|
if (!x.TLSSecure) {
|
||||||
|
|
||||||
rapidjson::Value tls(rapidjson::kObjectType);
|
rapidjson::Value tls(rapidjson::kObjectType);
|
||||||
tls.AddMember("enabled", true, allocator);
|
tls.AddMember("enabled", true, allocator);
|
||||||
if (!x.ServerName.empty())
|
if (!x.ServerName.empty())
|
||||||
@@ -2497,7 +2692,6 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
obfs.AddMember("password", rapidjson::StringRef(x.OBFSPassword.c_str()), allocator);
|
obfs.AddMember("password", rapidjson::StringRef(x.OBFSPassword.c_str()), allocator);
|
||||||
}
|
}
|
||||||
proxy.AddMember("obfs", obfs, allocator);
|
proxy.AddMember("obfs", obfs, allocator);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2508,28 +2702,55 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
if (!x.TLSSecure && !x.Alpn.empty()) {
|
if (!x.TLSSecure && !x.Alpn.empty()) {
|
||||||
rapidjson::Value tls(rapidjson::kObjectType);
|
rapidjson::Value tls(rapidjson::kObjectType);
|
||||||
tls.AddMember("enabled", true, allocator);
|
tls.AddMember("enabled", true, allocator);
|
||||||
|
if (!scv.is_undef()) {
|
||||||
|
tls.AddMember("insecure", buildBooleanValue(scv), allocator);
|
||||||
|
}
|
||||||
if (!x.ServerName.empty())
|
if (!x.ServerName.empty())
|
||||||
tls.AddMember("server_name", rapidjson::StringRef(x.ServerName.c_str()), allocator);
|
tls.AddMember("server_name", rapidjson::StringRef(x.ServerName.c_str()), allocator);
|
||||||
if (!x.Alpn.empty()) {
|
if (!x.Alpn.empty()) {
|
||||||
auto alpns = stringArrayToJsonArray(x.Alpn, ",", allocator);
|
auto alpns = stringArrayToJsonArray(x.Alpn, ",", allocator);
|
||||||
tls.AddMember("alpn", alpns, allocator);
|
tls.AddMember("alpn", alpns, allocator);
|
||||||
}
|
}
|
||||||
if(!x.DisableSni.is_undef()){
|
if (!x.DisableSni.is_undef()) {
|
||||||
tls.AddMember("disable_sni", buildBooleanValue(x.DisableSni), allocator);
|
tls.AddMember("disable_sni", buildBooleanValue(x.DisableSni), allocator);
|
||||||
}
|
}
|
||||||
proxy.AddMember("tls", tls, allocator);
|
proxy.AddMember("tls", tls, allocator);
|
||||||
}
|
}
|
||||||
if (!x.CongestionControl.empty()){
|
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()){
|
if (!x.UdpRelayMode.empty()) {
|
||||||
proxy.AddMember("udp_relay_mode", rapidjson::StringRef(x.UdpRelayMode.c_str()), allocator);
|
proxy.AddMember("udp_relay_mode", rapidjson::StringRef(x.UdpRelayMode.c_str()), allocator);
|
||||||
}
|
}
|
||||||
if (!x.ReduceRtt.is_undef()){
|
if (!x.ReduceRtt.is_undef()) {
|
||||||
proxy.AddMember("zero_rtt_handshake", buildBooleanValue(x.ReduceRtt), allocator);
|
proxy.AddMember("zero_rtt_handshake", buildBooleanValue(x.ReduceRtt), allocator);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ProxyType::AnyTLS: {
|
||||||
|
addSingBoxCommonMembers(proxy, x, "anytls", allocator);
|
||||||
|
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
||||||
|
rapidjson::Value tls(rapidjson::kObjectType);
|
||||||
|
tls.AddMember("enabled", true, allocator);
|
||||||
|
if (!scv.is_undef()) {
|
||||||
|
tls.AddMember("insecure", buildBooleanValue(scv), allocator);
|
||||||
|
}
|
||||||
|
if (!x.SNI.empty())
|
||||||
|
tls.AddMember("server_name", rapidjson::StringRef(x.SNI.c_str()), allocator);
|
||||||
|
if (!x.AlpnList.empty()) {
|
||||||
|
auto alpns = vectorToJsonArray(x.AlpnList, allocator);
|
||||||
|
tls.AddMember("alpn", alpns, allocator);
|
||||||
|
}
|
||||||
|
if (!x.Fingerprint.empty()) {
|
||||||
|
rapidjson::Value utls(rapidjson::kObjectType);
|
||||||
|
utls.AddMember("enabled", true, allocator);
|
||||||
|
utls.AddMember("fingerprint", rapidjson::StringRef(x.Fingerprint.c_str()), allocator);
|
||||||
|
proxy.AddMember("utls", utls, allocator);
|
||||||
|
}
|
||||||
|
proxy.AddMember("tls", tls, allocator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2538,7 +2759,10 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
tls.AddMember("enabled", true, allocator);
|
tls.AddMember("enabled", true, allocator);
|
||||||
if (!x.ServerName.empty())
|
if (!x.ServerName.empty())
|
||||||
tls.AddMember("server_name", rapidjson::StringRef(x.ServerName.c_str()), allocator);
|
tls.AddMember("server_name", rapidjson::StringRef(x.ServerName.c_str()), allocator);
|
||||||
if (!x.Alpn.empty()) {
|
if (!x.AlpnList.empty()) {
|
||||||
|
auto alpns = vectorToJsonArray(x.AlpnList, allocator);
|
||||||
|
tls.AddMember("alpn", alpns, allocator);
|
||||||
|
} else if (!x.Alpn.empty()) {
|
||||||
auto alpns = stringArrayToJsonArray(x.Alpn, ",", allocator);
|
auto alpns = stringArrayToJsonArray(x.Alpn, ",", allocator);
|
||||||
tls.AddMember("alpn", alpns, allocator);
|
tls.AddMember("alpn", alpns, allocator);
|
||||||
}
|
}
|
||||||
@@ -2554,7 +2778,7 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
|
|||||||
if (!x.PublicKey.empty()) {
|
if (!x.PublicKey.empty()) {
|
||||||
reality.AddMember("public_key", rapidjson::StringRef(x.PublicKey.c_str()), allocator);
|
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()) {
|
if (!x.ShortId.empty()) {
|
||||||
reality.AddMember("short_id", rapidjson::StringRef(x.ShortId.c_str()), allocator);
|
reality.AddMember("short_id", rapidjson::StringRef(x.ShortId.c_str()), allocator);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct extra_settings
|
|||||||
bool clash_classical_ruleset = false;
|
bool clash_classical_ruleset = false;
|
||||||
std::string sort_script;
|
std::string sort_script;
|
||||||
std::string clash_proxies_style = "flow";
|
std::string clash_proxies_style = "flow";
|
||||||
|
std::string clash_proxy_groups_style = "flow";
|
||||||
bool authorized = false;
|
bool authorized = false;
|
||||||
|
|
||||||
extra_settings() = default;
|
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)
|
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 = 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;
|
int idx = 2;
|
||||||
while(std::find(groups.begin(), groups.end(), rule_name) != groups.end())
|
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;
|
names[rule_name] = rule_group;
|
||||||
urls[rule_name] = "*" + rule_path;
|
urls[rule_name] = "*" + rule_path;
|
||||||
rule_type[rule_name] = x.rule_type;
|
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))
|
if(fileExist(rule_path, true) || isLink(rule_path))
|
||||||
{
|
{
|
||||||
//rule_name = std::to_string(hash_(rule_group + 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;
|
int idx = 2;
|
||||||
while(std::find(groups.begin(), groups.end(), rule_name) != groups.end())
|
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;
|
names[rule_name] = rule_group;
|
||||||
urls[rule_name] = rule_path_typed;
|
urls[rule_name] = rule_path_typed;
|
||||||
rule_type[rule_name] = x.rule_type;
|
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)
|
if(vArray.size() < 2)
|
||||||
continue;
|
continue;
|
||||||
if(keywords.find(rule_name) == keywords.end())
|
if(keywords.find(rule_name) == keywords.end())
|
||||||
keywords[rule_name] = "\"" + vArray[1] + "\"";
|
keywords[rule_name] = "\"" + trim(vArray[1]) + "\"";
|
||||||
else
|
else
|
||||||
keywords[rule_name] += ",\"" + vArray[1] + "\"";
|
keywords[rule_name] += ",\"" + trim(vArray[1]) + "\"";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -449,7 +449,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strLine = vArray[0] + "," + vArray[1] + "," + rule_group;
|
strLine = vArray[0] + "," + trim(vArray[1]) + "," + rule_group;
|
||||||
if(vArray.size() > 2)
|
if(vArray.size() > 2)
|
||||||
strLine += "," + vArray[2];
|
strLine += "," + vArray[2];
|
||||||
}
|
}
|
||||||
@@ -466,14 +466,16 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(has_domain[rule_name] && !script)
|
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_ipcidr[rule_name] && !script)
|
||||||
{
|
{
|
||||||
if(has_no_resolve)
|
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
|
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())
|
if(std::find(groups.begin(), groups.end(), rule_name) == groups.end())
|
||||||
groups.emplace_back(rule_name);
|
groups.emplace_back(rule_name);
|
||||||
}
|
}
|
||||||
@@ -488,14 +490,14 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
|
|||||||
{
|
{
|
||||||
std::string yaml_key = x;
|
std::string yaml_key = x;
|
||||||
if(rule_type[x] != RULESET_CLASH_DOMAIN)
|
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]["type"] = "http";
|
||||||
base_rule["rule-providers"][yaml_key]["behavior"] = "domain";
|
base_rule["rule-providers"][yaml_key]["behavior"] = "domain";
|
||||||
if(url[0] == '*')
|
if(url[0] == '*')
|
||||||
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
||||||
else
|
else
|
||||||
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=3&url=" + urlSafeBase64Encode(url);
|
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)
|
if(interval)
|
||||||
base_rule["rule-providers"][yaml_key]["interval"] = 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;
|
std::string yaml_key = x;
|
||||||
if(rule_type[x] != RULESET_CLASH_IPCIDR)
|
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]["type"] = "http";
|
||||||
base_rule["rule-providers"][yaml_key]["behavior"] = "ipcidr";
|
base_rule["rule-providers"][yaml_key]["behavior"] = "ipcidr";
|
||||||
if(url[0] == '*')
|
if(url[0] == '*')
|
||||||
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
||||||
else
|
else
|
||||||
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=4&url=" + urlSafeBase64Encode(url);
|
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)
|
if(interval)
|
||||||
base_rule["rule-providers"][yaml_key]["interval"] = 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);
|
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
|
||||||
else
|
else
|
||||||
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=6&url=" + urlSafeBase64Encode(url);
|
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)
|
if(interval)
|
||||||
base_rule["rule-providers"][yaml_key]["interval"] = 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);
|
writeLog(0, "Load preference settings in YAML format completed.", LOG_LEVEL_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
//template <class T, class... U>
|
template <class T, class... U>
|
||||||
//void find_if_exist(const toml::value &v, const toml::key &k, T& target, U&&... args)
|
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(v.contains(k)) target = toml::find<T>(v, k);
|
||||||
// if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
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)
|
for(const toml::table &table : arr)
|
||||||
{
|
{
|
||||||
@@ -800,7 +800,7 @@ void readConf()
|
|||||||
return readYAMLConf(yaml);
|
return readYAMLConf(yaml);
|
||||||
}
|
}
|
||||||
toml::value conf = parseToml(prefdata, global.prefPath);
|
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);
|
return readTOMLConf(conf);
|
||||||
}
|
}
|
||||||
catch (YAML::Exception &e)
|
catch (YAML::Exception &e)
|
||||||
@@ -1209,7 +1209,7 @@ int loadExternalConfig(std::string &path, ExternalConfig &ext)
|
|||||||
if(yaml.size() && yaml["custom"].IsDefined())
|
if(yaml.size() && yaml["custom"].IsDefined())
|
||||||
return loadExternalYAML(yaml, ext);
|
return loadExternalYAML(yaml, ext);
|
||||||
toml::value conf = parseToml(base_content, path);
|
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);
|
return loadExternalTOML(conf, ext);
|
||||||
}
|
}
|
||||||
catch (YAML::Exception &e)
|
catch (YAML::Exception &e)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ struct Settings
|
|||||||
tribool UDPFlag, TFOFlag, skipCertVerify, TLS13Flag, enableInsert;
|
tribool UDPFlag, TFOFlag, skipCertVerify, TLS13Flag, enableInsert;
|
||||||
bool enableSort = false, updateStrict = false;
|
bool enableSort = false, updateStrict = false;
|
||||||
bool clashUseNewField = false, singBoxAddClashModes = true;
|
bool clashUseNewField = false, singBoxAddClashModes = true;
|
||||||
std::string clashProxiesStyle = "flow";
|
std::string clashProxiesStyle = "flow", clashProxyGroupsStyle = "block";
|
||||||
std::string proxyConfig, proxyRuleset, proxySubscription;
|
std::string proxyConfig, proxyRuleset, proxySubscription;
|
||||||
int updateInterval = 0;
|
int updateInterval = 0;
|
||||||
std::string sortScript, filterScript;
|
std::string sortScript, filterScript;
|
||||||
@@ -101,12 +101,12 @@ extern Settings global;
|
|||||||
|
|
||||||
int importItems(string_array &target, bool scope_limit = true);
|
int importItems(string_array &target, bool scope_limit = true);
|
||||||
int loadExternalConfig(std::string &path, ExternalConfig &ext);
|
int loadExternalConfig(std::string &path, ExternalConfig &ext);
|
||||||
template <class T, class... U>
|
//template <class T, class... U>
|
||||||
void find_if_exist(const toml::value &v, const toml::key &k, T& target, U&&... args)
|
//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(v.contains(k)) target = toml::find<T>(v, k);
|
||||||
if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
// if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
|
||||||
}
|
//}
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
void parseGroupTimes(const std::string &src, Args... 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)
|
switch(type)
|
||||||
{
|
{
|
||||||
case CURLINFO_TEXT:
|
case CURLINFO_TEXT:
|
||||||
prefix = "CURL_INFO";
|
prefix = "CURL_INFO: ";
|
||||||
break;
|
break;
|
||||||
case CURLINFO_HEADER_IN:
|
case CURLINFO_HEADER_IN:
|
||||||
|
prefix = "CURL_HEADER: < ";
|
||||||
|
break;
|
||||||
case CURLINFO_HEADER_OUT:
|
case CURLINFO_HEADER_OUT:
|
||||||
prefix = "CURL_HEADER";
|
prefix = "CURL_HEADER: > ";
|
||||||
break;
|
break;
|
||||||
case CURLINFO_DATA_IN:
|
case CURLINFO_DATA_IN:
|
||||||
case CURLINFO_DATA_OUT:
|
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)
|
for(auto &x : lines)
|
||||||
{
|
{
|
||||||
std::string log_content = prefix;
|
std::string log_content = prefix;
|
||||||
log_content += ": ";
|
|
||||||
log_content += x;
|
log_content += x;
|
||||||
writeLog(0, log_content, LOG_LEVEL_VERBOSE);
|
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
|
else
|
||||||
{
|
{
|
||||||
std::string log_content = prefix;
|
std::string log_content = prefix;
|
||||||
log_content += ": ";
|
|
||||||
log_content += trimWhitespace(content);
|
log_content += trimWhitespace(content);
|
||||||
writeLog(0, log_content, LOG_LEVEL_VERBOSE);
|
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)
|
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"))
|
if(!argument.request_headers->contains("User-Agent"))
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent_str);
|
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent_str);
|
||||||
@@ -233,7 +234,7 @@ static int curlGet(const FetchArgument &argument, FetchResult &result)
|
|||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
retVal = curl_easy_perform(curl_handle);
|
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;
|
break;
|
||||||
else
|
else
|
||||||
fail_count++;
|
fail_count++;
|
||||||
|
|||||||
@@ -233,10 +233,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string type = getUrlArg(request.argument, "type");
|
std::string type = getUrlArg(request.argument, "type");
|
||||||
if(type == "form")
|
if(type == "form" || type == "direct")
|
||||||
fileWrite(global.prefPath, getFormData(request.postdata), true);
|
{
|
||||||
else if(type == "direct")
|
|
||||||
fileWrite(global.prefPath, request.postdata, true);
|
fileWrite(global.prefPath, request.postdata, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
response.status_code = 501;
|
response.status_code = 501;
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
using String = std::string;
|
using String = std::string;
|
||||||
using StringArray = std::vector<String>;
|
using StringArray = std::vector<String>;
|
||||||
|
|
||||||
enum class ProxyType {
|
enum class ProxyType
|
||||||
|
{
|
||||||
Unknown,
|
Unknown,
|
||||||
Shadowsocks,
|
Shadowsocks,
|
||||||
ShadowsocksR,
|
ShadowsocksR,
|
||||||
@@ -23,7 +24,9 @@ enum class ProxyType {
|
|||||||
VLESS,
|
VLESS,
|
||||||
Hysteria,
|
Hysteria,
|
||||||
Hysteria2,
|
Hysteria2,
|
||||||
TUIC
|
TUIC,
|
||||||
|
AnyTLS,
|
||||||
|
Mieru
|
||||||
};
|
};
|
||||||
|
|
||||||
inline String getProxyTypeName(ProxyType type) {
|
inline String getProxyTypeName(ProxyType type) {
|
||||||
@@ -54,6 +57,8 @@ inline String getProxyTypeName(ProxyType type) {
|
|||||||
return "Hysteria2";
|
return "Hysteria2";
|
||||||
case ProxyType::TUIC:
|
case ProxyType::TUIC:
|
||||||
return "Tuic";
|
return "Tuic";
|
||||||
|
case ProxyType::AnyTLS:
|
||||||
|
return "AnyTLS";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
@@ -82,7 +87,9 @@ struct Proxy {
|
|||||||
String TransferProtocol;
|
String TransferProtocol;
|
||||||
String FakeType;
|
String FakeType;
|
||||||
String AuthStr;
|
String AuthStr;
|
||||||
|
uint16_t IdleSessionCheckInterval=30;
|
||||||
|
uint16_t IdleSessionTimeout=30;
|
||||||
|
uint16_t MinIdleSession=0;
|
||||||
bool TLSSecure = false;
|
bool TLSSecure = false;
|
||||||
|
|
||||||
String Host;
|
String Host;
|
||||||
@@ -126,10 +133,17 @@ struct Proxy {
|
|||||||
String Flow;
|
String Flow;
|
||||||
bool FlowShow = false;
|
bool FlowShow = false;
|
||||||
tribool DisableSni;
|
tribool DisableSni;
|
||||||
|
uint32_t UpSpeed;
|
||||||
|
uint32_t DownSpeed;
|
||||||
|
String SNI;
|
||||||
tribool ReduceRtt;
|
tribool ReduceRtt;
|
||||||
String UdpRelayMode = "native";
|
String UdpRelayMode = "native";
|
||||||
uint16_t RequestTimeout = 15000;
|
uint16_t RequestTimeout = 15000;
|
||||||
String token;
|
String token;
|
||||||
|
String UnderlyingProxy;
|
||||||
|
std::vector<String> AlpnList;
|
||||||
|
String PacketEncoding;
|
||||||
|
String Multiplexing;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SS_DEFAULT_GROUP "SSProvider"
|
#define SS_DEFAULT_GROUP "SSProvider"
|
||||||
@@ -144,5 +158,6 @@ struct Proxy {
|
|||||||
#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider"
|
#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider"
|
||||||
#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider"
|
#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider"
|
||||||
#define TUIC_DEFAULT_GROUP "TuicProvider"
|
#define TUIC_DEFAULT_GROUP "TuicProvider"
|
||||||
|
#define ANYTLS_DEFAULT_GROUP "AnyTLSProvider"
|
||||||
|
#define MIERU_DEFAULT_GROUP "MieruProvider"
|
||||||
#endif // PROXY_H_INCLUDED
|
#endif // PROXY_H_INCLUDED
|
||||||
|
|||||||
@@ -18,16 +18,20 @@ using namespace rapidjson;
|
|||||||
using namespace rapidjson_ext;
|
using namespace rapidjson_ext;
|
||||||
using namespace YAML;
|
using namespace YAML;
|
||||||
|
|
||||||
string_array ss_ciphers = {"rc4-md5", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "aes-128-cfb", "aes-192-cfb",
|
string_array ss_ciphers = {
|
||||||
"aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "camellia-128-cfb",
|
"rc4-md5", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "aes-128-cfb", "aes-192-cfb",
|
||||||
"camellia-192-cfb", "camellia-256-cfb", "bf-cfb", "chacha20-ietf-poly1305",
|
"aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "camellia-128-cfb",
|
||||||
"xchacha20-ietf-poly1305", "salsa20", "chacha20", "chacha20-ietf", "2022-blake3-aes-128-gcm",
|
"camellia-192-cfb", "camellia-256-cfb", "bf-cfb", "chacha20-ietf-poly1305",
|
||||||
"2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "2022-blake3-chacha12-poly1305",
|
"xchacha20-ietf-poly1305", "salsa20", "chacha20", "chacha20-ietf", "2022-blake3-aes-128-gcm",
|
||||||
"2022-blake3-chacha8-poly1305"};
|
"2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "2022-blake3-chacha12-poly1305",
|
||||||
string_array ssr_ciphers = {"none", "table", "rc4", "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
"2022-blake3-chacha8-poly1305"
|
||||||
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
};
|
||||||
"camellia-192-cfb", "camellia-256-cfb", "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb",
|
string_array ssr_ciphers = {
|
||||||
"seed-cfb", "salsa20", "chacha20", "chacha20-ietf"};
|
"none", "table", "rc4", "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
||||||
|
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
||||||
|
"camellia-192-cfb", "camellia-256-cfb", "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb",
|
||||||
|
"seed-cfb", "salsa20", "chacha20", "chacha20-ietf"
|
||||||
|
};
|
||||||
|
|
||||||
std::map<std::string, std::string> parsedMD5;
|
std::map<std::string, std::string> parsedMD5;
|
||||||
std::string modSSMD5 = "f7653207090ce3389115e9c88541afe0";
|
std::string modSSMD5 = "f7653207090ce3389115e9c88541afe0";
|
||||||
@@ -36,7 +40,7 @@ std::string modSSMD5 = "f7653207090ce3389115e9c88541afe0";
|
|||||||
|
|
||||||
void commonConstruct(Proxy &node, ProxyType type, const std::string &group, const std::string &remarks,
|
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 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.Type = type;
|
||||||
node.Group = group;
|
node.Group = group;
|
||||||
node.Remark = remarks;
|
node.Remark = remarks;
|
||||||
@@ -46,14 +50,16 @@ void commonConstruct(Proxy &node, ProxyType type, const std::string &group, cons
|
|||||||
node.TCPFastOpen = tfo;
|
node.TCPFastOpen = tfo;
|
||||||
node.AllowInsecure = scv;
|
node.AllowInsecure = scv;
|
||||||
node.TLS13 = tls13;
|
node.TLS13 = tls13;
|
||||||
|
node.UnderlyingProxy = underlying_proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
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 &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 &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, tribool udp, tribool tfo,
|
const std::string &edge, const std::string &tls, const std::string &sni,
|
||||||
tribool scv, tribool tls13) {
|
const std::vector<std::string> &alpnList, tribool udp, tribool tfo,
|
||||||
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.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
|
||||||
node.AlterId = to_int(aid);
|
node.AlterId = to_int(aid);
|
||||||
node.EncryptMethod = cipher;
|
node.EncryptMethod = cipher;
|
||||||
@@ -75,8 +81,10 @@ 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,
|
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 &port, const std::string &protocol, const std::string &method,
|
||||||
const std::string &obfs, const std::string &password, const std::string &obfsparam,
|
const std::string &obfs, const std::string &password, const std::string &obfsparam,
|
||||||
const std::string &protoparam, tribool udp, tribool tfo, tribool scv) {
|
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 &underlying_proxy) {
|
||||||
|
commonConstruct(node, ProxyType::ShadowsocksR, group, remarks, server, port, udp, tfo, scv, tribool(),
|
||||||
|
underlying_proxy);
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.EncryptMethod = method;
|
node.EncryptMethod = method;
|
||||||
node.Protocol = protocol;
|
node.Protocol = protocol;
|
||||||
@@ -88,8 +96,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,
|
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 &port, const std::string &password, const std::string &method,
|
||||||
const std::string &plugin, const std::string &pluginopts, tribool udp, tribool tfo, tribool scv,
|
const std::string &plugin, const std::string &pluginopts, tribool udp, tribool tfo, tribool scv,
|
||||||
tribool tls13) {
|
tribool tls13, const std::string &underlying_proxy) {
|
||||||
commonConstruct(node, ProxyType::Shadowsocks, group, remarks, server, port, udp, tfo, scv, tls13);
|
commonConstruct(node, ProxyType::Shadowsocks, group, remarks, server, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.EncryptMethod = method;
|
node.EncryptMethod = method;
|
||||||
node.Plugin = plugin;
|
node.Plugin = plugin;
|
||||||
@@ -98,17 +106,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,
|
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,
|
const std::string &port, const std::string &username, const std::string &password, tribool udp,
|
||||||
tribool tfo, tribool scv) {
|
tribool tfo, tribool scv, const std::string &underlying_proxy) {
|
||||||
commonConstruct(node, ProxyType::SOCKS5, group, remarks, server, port, udp, tfo, scv, tribool());
|
commonConstruct(node, ProxyType::SOCKS5, group, remarks, server, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||||
node.Username = username;
|
node.Username = username;
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
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,
|
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,
|
commonConstruct(node, tls ? ProxyType::HTTPS : ProxyType::HTTP, group, remarks, server, port, tribool(), tfo, scv,
|
||||||
tls13);
|
tls13, underlying_proxy);
|
||||||
node.Username = username;
|
node.Username = username;
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.TLSSecure = tls;
|
node.TLSSecure = tls;
|
||||||
@@ -117,10 +125,11 @@ void httpConstruct(Proxy &node, const std::string &group, const std::string &rem
|
|||||||
void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
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 &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::string &host, const std::string &path, const std::string &fp, const std::string &sni,
|
||||||
|
const std::vector<std::string> &alpnList,
|
||||||
bool tlssecure,
|
bool tlssecure,
|
||||||
tribool udp, tribool tfo,
|
tribool udp, tribool tfo,
|
||||||
tribool scv, tribool tls13) {
|
tribool scv, tribool tls13, const std::string &underlying_proxy) {
|
||||||
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13);
|
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.Host = host;
|
node.Host = host;
|
||||||
node.TLSSecure = tlssecure;
|
node.TLSSecure = tlssecure;
|
||||||
@@ -128,12 +137,14 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
|
|||||||
node.Path = path;
|
node.Path = path;
|
||||||
node.Fingerprint = fp;
|
node.Fingerprint = fp;
|
||||||
node.ServerName = sni;
|
node.ServerName = sni;
|
||||||
|
node.AlpnList = alpnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
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 &port, const std::string &password, const std::string &obfs,
|
||||||
const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv) {
|
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 &underlying_proxy) {
|
||||||
|
commonConstruct(node, ProxyType::Snell, group, remarks, server, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.OBFS = obfs;
|
node.OBFS = obfs;
|
||||||
node.Host = host;
|
node.Host = host;
|
||||||
@@ -144,8 +155,10 @@ 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 &port, const std::string &selfIp, const std::string &selfIpv6,
|
||||||
const std::string &privKey, const std::string &pubKey, const std::string &psk,
|
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 string_array &dns, const std::string &mtu, const std::string &keepalive,
|
||||||
const std::string &testUrl, const std::string &clientId, const tribool &udp) {
|
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 &underlying_proxy) {
|
||||||
|
commonConstruct(node, ProxyType::WireGuard, group, remarks, server, port, udp, tribool(), tribool(), tribool(),
|
||||||
|
underlying_proxy);
|
||||||
node.SelfIP = selfIp;
|
node.SelfIP = selfIp;
|
||||||
node.SelfIPv6 = selfIpv6;
|
node.SelfIPv6 = selfIpv6;
|
||||||
node.PrivateKey = privKey;
|
node.PrivateKey = privKey;
|
||||||
@@ -165,8 +178,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 &obfsParam, const std::string &insecure, const std::string &ports,
|
||||||
const std::string &sni, tribool udp,
|
const std::string &sni, tribool udp,
|
||||||
tribool tfo, tribool scv,
|
tribool tfo, tribool scv,
|
||||||
tribool tls13) {
|
tribool tls13, const std::string &underlying_proxy) {
|
||||||
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13);
|
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||||
node.Auth = auth;
|
node.Auth = auth;
|
||||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||||
node.UpMbps = up;
|
node.UpMbps = up;
|
||||||
@@ -180,15 +193,50 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
|
|||||||
node.ServerName = sni;
|
node.ServerName = sni;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void anyTlSConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||||
|
const std::string &port, const std::string &password,
|
||||||
|
const std::string &host, const std::vector<String> &AlpnList,
|
||||||
|
const std::string &fingerprint,
|
||||||
|
const std::string &sni, tribool udp,
|
||||||
|
tribool tfo, tribool scv,
|
||||||
|
tribool tls13, const std::string &underlying_proxy, uint16_t idleSessionCheckInterval,
|
||||||
|
uint16_t idleSessionTimeout, uint16_t minIdleSession) {
|
||||||
|
commonConstruct(node, ProxyType::AnyTLS, group, remarks, host, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||||
|
node.Host = trim(host);
|
||||||
|
node.Password = password;
|
||||||
|
node.AlpnList = AlpnList;
|
||||||
|
node.SNI = sni;
|
||||||
|
node.Fingerprint = fingerprint;
|
||||||
|
node.IdleSessionCheckInterval = idleSessionCheckInterval;
|
||||||
|
node.IdleSessionTimeout = idleSessionTimeout;
|
||||||
|
node.MinIdleSession = minIdleSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mieruConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||||
|
const std::string &port, const std::string &password,
|
||||||
|
const std::string &host, const std::string &ports,
|
||||||
|
const std::string &username, const std::string &multiplexing,
|
||||||
|
const std::string &transfer_protocol, tribool udp,
|
||||||
|
tribool tfo, tribool scv,
|
||||||
|
tribool tls13, const std::string &underlying_proxy) {
|
||||||
|
commonConstruct(node, ProxyType::Mieru, group, remarks, host, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||||
|
node.Host = trim(host);
|
||||||
|
node.Password = password;
|
||||||
|
node.Ports = ports;
|
||||||
|
node.TransferProtocol = transfer_protocol.empty()? "TCP" : trim(transfer_protocol);
|
||||||
|
node.Username = username;
|
||||||
|
node.Multiplexing = multiplexing.empty() ? "MULTIPLEXING_LOW" : trim(multiplexing);
|
||||||
|
}
|
||||||
|
|
||||||
void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
|
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,
|
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 &flow, const std::string &mode,
|
const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode,
|
||||||
const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,
|
const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,
|
||||||
const std::string &pbk, const std::string &sid, const std::string &fp, const std::string &sni,
|
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 udp, tribool tfo,
|
||||||
tribool scv, tribool tls13) {
|
tribool scv, tribool tls13, const std::string &underlying_proxy) {
|
||||||
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13);
|
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.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
|
||||||
node.AlterId = to_int(aid);
|
node.AlterId = to_int(aid);
|
||||||
node.EncryptMethod = cipher;
|
node.EncryptMethod = cipher;
|
||||||
@@ -201,6 +249,8 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
|
|||||||
node.ShortId = sid;
|
node.ShortId = sid;
|
||||||
node.Fingerprint = fp;
|
node.Fingerprint = fp;
|
||||||
node.ServerName = sni;
|
node.ServerName = sni;
|
||||||
|
node.AlpnList = alpnList;
|
||||||
|
node.PacketEncoding = packet_encoding;
|
||||||
switch (hash_(net)) {
|
switch (hash_(net)) {
|
||||||
case "grpc"_hash:
|
case "grpc"_hash:
|
||||||
node.Host = host;
|
node.Host = host;
|
||||||
@@ -225,8 +275,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 &obfsParam, const std::string &obfsPassword, const std::string &sni,
|
||||||
const std::string &publicKey, const std::string &ports,
|
const std::string &publicKey, const std::string &ports,
|
||||||
tribool udp, tribool tfo,
|
tribool udp, tribool tfo,
|
||||||
tribool scv) {
|
tribool scv, const std::string &underlying_proxy) {
|
||||||
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool());
|
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||||
node.UpMbps = up;
|
node.UpMbps = up;
|
||||||
@@ -245,8 +295,9 @@ 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 &sni, const std::string &uuid, const std::string &udpRelayMode,
|
||||||
const std::string &token,
|
const std::string &token,
|
||||||
tribool udp, tribool tfo,
|
tribool udp, tribool tfo,
|
||||||
tribool scv, tribool reduceRtt, tribool disableSni,uint16_t request_timeout) {
|
tribool scv, tribool reduceRtt, tribool disableSni, uint16_t request_timeout,
|
||||||
commonConstruct(node, ProxyType::TUIC, group, remarks, add, port, udp, tfo, scv, tribool());
|
const std::string &underlying_proxy) {
|
||||||
|
commonConstruct(node, ProxyType::TUIC, group, remarks, add, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||||
node.Password = password;
|
node.Password = password;
|
||||||
node.Alpn = alpn;
|
node.Alpn = alpn;
|
||||||
node.ServerName = sni;
|
node.ServerName = sni;
|
||||||
@@ -319,7 +370,8 @@ void explodeVmess(std::string vmess, Proxy &node) {
|
|||||||
|
|
||||||
add = trim(add);
|
add = trim(add);
|
||||||
|
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, "auto", path, host, "", tls, sni);
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, "auto", path, host, "", tls, sni,
|
||||||
|
std::vector<std::string>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
||||||
@@ -390,13 +442,12 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, add + ":" + port, add, port, type, id, aid, net, cipher, path,
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, add + ":" + port, add, port, type, id, aid, net, cipher, path,
|
||||||
host, edge, tls, "", udp, tfo, scv);
|
host, edge, tls, "", std::vector<std::string>{}, udp, tfo, scv);
|
||||||
nodes.emplace_back(std::move(node));
|
nodes.emplace_back(std::move(node));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} catch (std::exception &e) {
|
||||||
catch (std::exception &e) {
|
|
||||||
//writeLog(0, "VMessConf parser throws an error. Leaving...", LOG_LEVEL_WARNING);
|
//writeLog(0, "VMessConf parser throws an error. Leaving...", LOG_LEVEL_WARNING);
|
||||||
//return;
|
//return;
|
||||||
//ignore
|
//ignore
|
||||||
@@ -443,7 +494,7 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
|||||||
json["vmess"][i]["security"] >> cipher;
|
json["vmess"][i]["security"] >> cipher;
|
||||||
json["vmess"][i]["sni"] >> sni;
|
json["vmess"][i]["sni"] >> sni;
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, cipher, path, host, "",
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, cipher, path, host, "",
|
||||||
tls, sni, udp, tfo, scv);
|
tls, sni, std::vector<std::string>{}, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case 3: //ss config
|
case 3: //ss config
|
||||||
json["vmess"][i]["id"] >> id;
|
json["vmess"][i]["id"] >> id;
|
||||||
@@ -463,7 +514,8 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void explodeSS(std::string ss, Proxy &node) {
|
void explodeSS(std::string ss, Proxy &node) {
|
||||||
std::string ps, password, method, server, port, plugins, plugin, pluginopts, addition, group = SS_DEFAULT_GROUP, secret;
|
std::string ps, password, method, server, port, plugins, plugin, pluginopts, addition, group = SS_DEFAULT_GROUP,
|
||||||
|
secret;
|
||||||
//std::vector<std::string> args, secret;
|
//std::vector<std::string> args, secret;
|
||||||
ss = replaceAllDistinct(ss.substr(5), "/?", "?");
|
ss = replaceAllDistinct(ss.substr(5), "/?", "?");
|
||||||
if (strFind(ss, "#")) {
|
if (strFind(ss, "#")) {
|
||||||
@@ -676,7 +728,8 @@ void explodeSSR(std::string ssr, Proxy &node) {
|
|||||||
|
|
||||||
void explodeSSRConf(std::string content, std::vector<Proxy> &nodes) {
|
void explodeSSRConf(std::string content, std::vector<Proxy> &nodes) {
|
||||||
Document json;
|
Document json;
|
||||||
std::string remarks, group, server, port, method, password, protocol, protoparam, obfs, obfsparam, plugin, pluginopts;
|
std::string remarks, group, server, port, method, password, protocol, protoparam, obfs, obfsparam, plugin,
|
||||||
|
pluginopts;
|
||||||
auto index = nodes.size();
|
auto index = nodes.size();
|
||||||
|
|
||||||
json.Parse(content.data());
|
json.Parse(content.data());
|
||||||
@@ -868,8 +921,8 @@ void explodeTrojan(std::string trojan, Proxy &node) {
|
|||||||
path = getUrlArg(addition, "wspath");
|
path = getUrlArg(addition, "wspath");
|
||||||
network = "ws";
|
network = "ws";
|
||||||
}
|
}
|
||||||
// support the trojan link format used by v2ryaN and X-ui.
|
// support the trojan link format used by v2ryaN and X-ui.
|
||||||
// format: trojan://{password}@{server}:{port}?type=ws&security=tls&path={path (urlencoded)}&sni={host}#{name}
|
// format: trojan://{password}@{server}:{port}?type=ws&security=tls&path={path (urlencoded)}&sni={host}#{name}
|
||||||
else if (getUrlArg(addition, "type") == "ws") {
|
else if (getUrlArg(addition, "type") == "ws") {
|
||||||
path = getUrlArg(addition, "path");
|
path = getUrlArg(addition, "path");
|
||||||
if (path.substr(0, 3) == "%2F")
|
if (path.substr(0, 3) == "%2F")
|
||||||
@@ -881,8 +934,13 @@ void explodeTrojan(std::string trojan, Proxy &node) {
|
|||||||
remark = server + ":" + port;
|
remark = server + ":" + port;
|
||||||
if (group.empty())
|
if (group.empty())
|
||||||
group = TROJAN_DEFAULT_GROUP;
|
group = TROJAN_DEFAULT_GROUP;
|
||||||
|
std::string alpn = getUrlArg(addition, "alpn");
|
||||||
trojanConstruct(node, group, remark, server, port, psk, network, host, path, fp, sni, true, tribool(), tfo, scv);
|
std::vector<std::string> alpnList;
|
||||||
|
if (!alpn.empty()) {
|
||||||
|
alpnList.push_back(alpn);
|
||||||
|
}
|
||||||
|
trojanConstruct(node, group, remark, server, port, psk, network, host, path, fp, sni, alpnList, true, tribool(),
|
||||||
|
tfo, scv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeVless(std::string vless, Proxy &node) {
|
void explodeVless(std::string vless, Proxy &node) {
|
||||||
@@ -892,6 +950,24 @@ void explodeVless(std::string vless, Proxy &node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void explodeMierus(std::string mierus, Proxy &node) {
|
||||||
|
if (strFind(mierus, "mierus://")) {
|
||||||
|
if (regMatch(mierus, "mierus://(.*?)@(.*)")) {
|
||||||
|
explodeStdMieru(mierus.substr(9), node);
|
||||||
|
}else {
|
||||||
|
mierus = urlSafeBase64Decode(mierus.substr(9));
|
||||||
|
explodeStdMieru("mierus://" + mierus, node);
|
||||||
|
}
|
||||||
|
}else if(strFind(mierus, "mieru://")) {
|
||||||
|
if (regMatch(mierus, "mierus://(.*?)@(.*)")) {
|
||||||
|
explodeStdMieru(mierus.substr(8), node);
|
||||||
|
}else {
|
||||||
|
mierus = urlSafeBase64Decode(mierus.substr(8));
|
||||||
|
explodeStdMieru("mierus://" + mierus, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void explodeHysteria(std::string hysteria, Proxy &node) {
|
void explodeHysteria(std::string hysteria, Proxy &node) {
|
||||||
printf("explodeHysteria\n");
|
printf("explodeHysteria\n");
|
||||||
hysteria = regReplace(hysteria, "(hysteria|hy)://", "hysteria://");
|
hysteria = regReplace(hysteria, "(hysteria|hy)://", "hysteria://");
|
||||||
@@ -914,7 +990,8 @@ void explodeHysteria2(std::string hysteria2, Proxy &node) {
|
|||||||
|
|
||||||
void explodeQuan(const std::string &quan, Proxy &node) {
|
void explodeQuan(const std::string &quan, Proxy &node) {
|
||||||
std::string strTemp, itemName, itemVal;
|
std::string strTemp, itemName, itemVal;
|
||||||
std::string group = V2RAY_DEFAULT_GROUP, ps, add, port, cipher, type = "none", id, aid = "0", net = "tcp", path, host, edge, tls;
|
std::string group = V2RAY_DEFAULT_GROUP, ps, add, port, cipher, type = "none", id, aid = "0", net = "tcp", path,
|
||||||
|
host, edge, tls;
|
||||||
string_array configs, vArray, headers;
|
string_array configs, vArray, headers;
|
||||||
strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2");
|
strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2");
|
||||||
configs = split(strTemp, ",");
|
configs = split(strTemp, ",");
|
||||||
@@ -970,7 +1047,8 @@ void explodeQuan(const std::string &quan, Proxy &node) {
|
|||||||
if (path.empty())
|
if (path.empty())
|
||||||
path = "/";
|
path = "/";
|
||||||
|
|
||||||
vmessConstruct(node, group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls, "");
|
vmessConstruct(node, group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls, "",
|
||||||
|
std::vector<std::string>{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,10 +1114,11 @@ void explodeNetch(std::string netch, Proxy &node) {
|
|||||||
edge = GetMember(json, "Edge");
|
edge = GetMember(json, "Edge");
|
||||||
tls = GetMember(json, "TLSSecure");
|
tls = GetMember(json, "TLSSecure");
|
||||||
sni = GetMember(json, "ServerName");
|
sni = GetMember(json, "ServerName");
|
||||||
|
|
||||||
if (group.empty())
|
if (group.empty())
|
||||||
group = V2RAY_DEFAULT_GROUP;
|
group = V2RAY_DEFAULT_GROUP;
|
||||||
vmessConstruct(node, group, remark, address, port, faketype, id, aid, transprot, method, path, host, edge,
|
vmessConstruct(node, group, remark, address, port, faketype, id, aid, transprot, method, path, host, edge,
|
||||||
tls, sni, udp, tfo, scv);
|
tls, sni, std::vector<std::string>{}, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "Socks5"_hash:
|
case "Socks5"_hash:
|
||||||
username = GetMember(json, "Username");
|
username = GetMember(json, "Username");
|
||||||
@@ -1061,7 +1140,8 @@ void explodeNetch(std::string netch, Proxy &node) {
|
|||||||
sni = host;
|
sni = host;
|
||||||
if (group.empty())
|
if (group.empty())
|
||||||
group = TROJAN_DEFAULT_GROUP;
|
group = TROJAN_DEFAULT_GROUP;
|
||||||
trojanConstruct(node, group, remark, address, port, password, transprot, host, path, fp, sni, tls == "true",
|
trojanConstruct(node, group, remark, address, port, password, transprot, host, path, fp, sni,
|
||||||
|
std::vector<std::string>{}, tls == "true",
|
||||||
udp,
|
udp,
|
||||||
tfo, scv);
|
tfo, scv);
|
||||||
break;
|
break;
|
||||||
@@ -1085,26 +1165,33 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
for (uint32_t i = 0; i < yamlnode[section].size(); i++) {
|
for (uint32_t i = 0; i < yamlnode[section].size(); i++) {
|
||||||
std::string proxytype, ps, server, port, cipher, group, password = "", ports, tempPassword; //common
|
std::string proxytype, ps, server, port, cipher, group, password = "", ports, tempPassword; //common
|
||||||
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
|
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
|
||||||
std::string fp = "chrome", pbk, sid; //vless
|
std::string fp = "chrome", pbk, sid, packet_encoding; //vless
|
||||||
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
|
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
|
||||||
std::string protocol, protoparam, obfs, obfsparam; //ssr
|
std::string protocol, protoparam, obfs, obfsparam; //ssr
|
||||||
std::string flow, mode; //trojan
|
std::string flow, mode; //trojan
|
||||||
std::string user; //socks
|
std::string user; //socks
|
||||||
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
|
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
|
||||||
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
|
std::string auth, up, down, obfsParam, insecure, alpn; //hysteria
|
||||||
std::string obfsPassword;//hysteria2
|
std::string obfsPassword; //hysteria2
|
||||||
std::string congestion_control, udp_relay_mode, token;// tuic
|
std::string congestion_control, udp_relay_mode, token; // tuic
|
||||||
string_array dns_server;
|
string_array dns_server;
|
||||||
|
std::vector<String> alpns;
|
||||||
|
String alpn2;
|
||||||
|
std::string fingerprint, multiplexing, transfer_protocol;
|
||||||
tribool udp, tfo, scv;
|
tribool udp, tfo, scv;
|
||||||
bool reduceRtt, disableSni;//tuic
|
bool reduceRtt, disableSni; //tuic
|
||||||
|
std::vector<std::string> alpnList;
|
||||||
Proxy node;
|
Proxy node;
|
||||||
singleproxy = yamlnode[section][i];
|
singleproxy = yamlnode[section][i];
|
||||||
singleproxy["type"] >>= proxytype;
|
singleproxy["type"] >>= proxytype;
|
||||||
singleproxy["name"] >>= ps;
|
singleproxy["name"] >>= ps;
|
||||||
singleproxy["server"] >>= server;
|
singleproxy["server"] >>= server;
|
||||||
singleproxy["port"] >>= port;
|
singleproxy["port"] >>= port;
|
||||||
|
singleproxy["port-range"] >>= ports;
|
||||||
|
|
||||||
if (port.empty() || port == "0")
|
if (port.empty() || port == "0")
|
||||||
continue;
|
if (ports.empty())
|
||||||
|
continue;
|
||||||
udp = safe_as<std::string>(singleproxy["udp"]);
|
udp = safe_as<std::string>(singleproxy["udp"]);
|
||||||
scv = safe_as<std::string>(singleproxy["skip-cert-verify"]);
|
scv = safe_as<std::string>(singleproxy["skip-cert-verify"]);
|
||||||
switch (hash_(proxytype)) {
|
switch (hash_(proxytype)) {
|
||||||
@@ -1126,13 +1213,16 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
break;
|
break;
|
||||||
case "ws"_hash:
|
case "ws"_hash:
|
||||||
if (singleproxy["ws-opts"].IsDefined()) {
|
if (singleproxy["ws-opts"].IsDefined()) {
|
||||||
path = singleproxy["ws-opts"]["path"].IsDefined() ? safe_as<std::string>(
|
path = singleproxy["ws-opts"]["path"].IsDefined()
|
||||||
singleproxy["ws-opts"]["path"]) : "/";
|
? safe_as<std::string>(
|
||||||
|
singleproxy["ws-opts"]["path"])
|
||||||
|
: "/";
|
||||||
singleproxy["ws-opts"]["headers"]["Host"] >>= host;
|
singleproxy["ws-opts"]["headers"]["Host"] >>= host;
|
||||||
singleproxy["ws-opts"]["headers"]["Edge"] >>= edge;
|
singleproxy["ws-opts"]["headers"]["Edge"] >>= edge;
|
||||||
} else {
|
} else {
|
||||||
path = singleproxy["ws-path"].IsDefined() ? safe_as<std::string>(singleproxy["ws-path"])
|
path = singleproxy["ws-path"].IsDefined()
|
||||||
: "/";
|
? safe_as<std::string>(singleproxy["ws-path"])
|
||||||
|
: "/";
|
||||||
singleproxy["ws-headers"]["Host"] >>= host;
|
singleproxy["ws-headers"]["Host"] >>= host;
|
||||||
singleproxy["ws-headers"]["Edge"] >>= edge;
|
singleproxy["ws-headers"]["Edge"] >>= edge;
|
||||||
}
|
}
|
||||||
@@ -1149,8 +1239,9 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : "";
|
tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : "";
|
||||||
|
singleproxy["alpn"] >>= alpnList;
|
||||||
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls, sni, udp,
|
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls, sni,
|
||||||
|
alpnList, udp,
|
||||||
tfo, scv);
|
tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "ss"_hash:
|
case "ss"_hash:
|
||||||
@@ -1204,7 +1295,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//support for go-shadowsocks2
|
//support for go-shadowsocks2
|
||||||
if (cipher == "AEAD_CHACHA20_POLY1305")
|
if (cipher == "AEAD_CHACHA20_POLY1305")
|
||||||
cipher = "chacha20-ietf-poly1305";
|
cipher = "chacha20-ietf-poly1305";
|
||||||
else if (strFind(cipher, "AEAD")) {
|
else if (strFind(cipher, "AEAD")) {
|
||||||
@@ -1269,8 +1360,10 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
path.clear();
|
path.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
singleproxy["alpn"] >>= alpnList;
|
||||||
|
|
||||||
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, sni, true, udp, tfo, scv);
|
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, sni, alpnList, true, udp,
|
||||||
|
tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "snell"_hash:
|
case "snell"_hash:
|
||||||
group = SNELL_DEFAULT_GROUP;
|
group = SNELL_DEFAULT_GROUP;
|
||||||
@@ -1292,7 +1385,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
singleproxy["ipv6"] >>= ipv6;
|
singleproxy["ipv6"] >>= ipv6;
|
||||||
|
|
||||||
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
||||||
dns_server, mtu, "0", "", "", udp);
|
dns_server, mtu, "0", "", "", udp, "");
|
||||||
break;
|
break;
|
||||||
case "vless"_hash:
|
case "vless"_hash:
|
||||||
group = XRAY_DEFAULT_GROUP;
|
group = XRAY_DEFAULT_GROUP;
|
||||||
@@ -1300,8 +1393,10 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
singleproxy["uuid"] >>= id;
|
singleproxy["uuid"] >>= id;
|
||||||
singleproxy["alterId"] >>= aid;
|
singleproxy["alterId"] >>= aid;
|
||||||
net = singleproxy["network"].IsDefined() ? safe_as<std::string>(singleproxy["network"]) : "tcp";
|
net = singleproxy["network"].IsDefined() ? safe_as<std::string>(singleproxy["network"]) : "tcp";
|
||||||
sni = singleproxy["sni"].IsDefined() ? safe_as<std::string>(singleproxy["sni"]) : safe_as<std::string>(
|
sni = singleproxy["sni"].IsDefined()
|
||||||
singleproxy["servername"]);
|
? safe_as<std::string>(singleproxy["sni"])
|
||||||
|
: safe_as<std::string>(
|
||||||
|
singleproxy["servername"]);
|
||||||
switch (hash_(net)) {
|
switch (hash_(net)) {
|
||||||
case "http"_hash:
|
case "http"_hash:
|
||||||
singleproxy["http-opts"]["path"][0] >>= path;
|
singleproxy["http-opts"]["path"][0] >>= path;
|
||||||
@@ -1310,13 +1405,16 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
break;
|
break;
|
||||||
case "ws"_hash:
|
case "ws"_hash:
|
||||||
if (singleproxy["ws-opts"].IsDefined()) {
|
if (singleproxy["ws-opts"].IsDefined()) {
|
||||||
path = singleproxy["ws-opts"]["path"].IsDefined() ? safe_as<std::string>(
|
path = singleproxy["ws-opts"]["path"].IsDefined()
|
||||||
singleproxy["ws-opts"]["path"]) : "/";
|
? safe_as<std::string>(
|
||||||
|
singleproxy["ws-opts"]["path"])
|
||||||
|
: "/";
|
||||||
singleproxy["ws-opts"]["headers"]["Host"] >>= host;
|
singleproxy["ws-opts"]["headers"]["Host"] >>= host;
|
||||||
singleproxy["ws-opts"]["headers"]["Edge"] >>= edge;
|
singleproxy["ws-opts"]["headers"]["Edge"] >>= edge;
|
||||||
} else {
|
} else {
|
||||||
path = singleproxy["ws-path"].IsDefined() ? safe_as<std::string>(singleproxy["ws-path"])
|
path = singleproxy["ws-path"].IsDefined()
|
||||||
: "/";
|
? safe_as<std::string>(singleproxy["ws-path"])
|
||||||
|
: "/";
|
||||||
singleproxy["ws-headers"]["Host"] >>= host;
|
singleproxy["ws-headers"]["Host"] >>= host;
|
||||||
singleproxy["ws-headers"]["Edge"] >>= edge;
|
singleproxy["ws-headers"]["Edge"] >>= edge;
|
||||||
}
|
}
|
||||||
@@ -1331,20 +1429,27 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
singleproxy["grpc-opts"]["grpc-service-name"] >>= path;
|
singleproxy["grpc-opts"]["grpc-service-name"] >>= path;
|
||||||
edge.clear();
|
edge.clear();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : "";
|
tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : "";
|
||||||
if (singleproxy["reality-opts"].IsDefined()) {
|
if (singleproxy["reality-opts"].IsDefined()) {
|
||||||
host = singleproxy["sni"].IsDefined() ? safe_as<std::string>(singleproxy["sni"])
|
host = singleproxy["sni"].IsDefined()
|
||||||
: safe_as<std::string>(singleproxy["servername"]);
|
? safe_as<std::string>(singleproxy["sni"])
|
||||||
|
: safe_as<std::string>(singleproxy["servername"]);
|
||||||
printf("host:%s", host.c_str());
|
printf("host:%s", host.c_str());
|
||||||
singleproxy["reality-opts"]["public-key"] >>= pbk;
|
singleproxy["reality-opts"]["public-key"] >>= pbk;
|
||||||
singleproxy["reality-opts"]["short-id"] >>= sid;
|
singleproxy["reality-opts"]["short-id"] >>= sid;
|
||||||
}
|
}
|
||||||
singleproxy["flow"] >>= flow;
|
singleproxy["flow"] >>= flow;
|
||||||
|
singleproxy["client-fingerprint"] >>= fp;
|
||||||
|
singleproxy["alpn"] >>= alpnList;
|
||||||
|
singleproxy["packet-encoding"] >>= packet_encoding;
|
||||||
|
bool vless_udp;
|
||||||
|
singleproxy["udp"] >> vless_udp;
|
||||||
vlessConstruct(node, XRAY_DEFAULT_GROUP, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
|
vlessConstruct(node, XRAY_DEFAULT_GROUP, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
|
||||||
host, "", tls, pbk, sid, fp, sni);
|
host, "", tls, pbk, sid, fp, sni, alpnList, packet_encoding, udp);
|
||||||
break;
|
break;
|
||||||
case "hysteria"_hash:
|
case "hysteria"_hash:
|
||||||
group = HYSTERIA_DEFAULT_GROUP;
|
group = HYSTERIA_DEFAULT_GROUP;
|
||||||
@@ -1361,6 +1466,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
singleproxy["protocol"] >> type;
|
singleproxy["protocol"] >> type;
|
||||||
singleproxy["sni"] >> host;
|
singleproxy["sni"] >> host;
|
||||||
singleproxy["alpn"][0] >> alpn;
|
singleproxy["alpn"][0] >> alpn;
|
||||||
|
singleproxy["alpn"] >> alpnList;
|
||||||
singleproxy["protocol"] >> insecure;
|
singleproxy["protocol"] >> insecure;
|
||||||
singleproxy["ports"] >> ports;
|
singleproxy["ports"] >> ports;
|
||||||
sni = host;
|
sni = host;
|
||||||
@@ -1402,9 +1508,44 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
|||||||
tuicConstruct(node, TUIC_DEFAULT_GROUP, ps, server, port, password, congestion_control, alpn, sni, id,
|
tuicConstruct(node, TUIC_DEFAULT_GROUP, ps, server, port, password, congestion_control, alpn, sni, id,
|
||||||
udp_relay_mode, token,
|
udp_relay_mode, token,
|
||||||
tribool(),
|
tribool(),
|
||||||
tribool(), scv, reduceRtt, disableSni,request_timeout);
|
tribool(), scv, reduceRtt, disableSni, request_timeout);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case "anytls"_hash:
|
||||||
|
group = ANYTLS_DEFAULT_GROUP;
|
||||||
|
singleproxy["password"] >>= password;
|
||||||
|
singleproxy["sni"] >>= sni;
|
||||||
|
|
||||||
|
if (!singleproxy["alpn"].IsNull() && singleproxy["alpn"].size() >= 1) {
|
||||||
|
singleproxy["alpn"][0] >>= alpn;
|
||||||
|
alpns.push_back(alpn);
|
||||||
|
if (singleproxy["alpn"].size() >= 2 && !singleproxy["alpn"][1].IsNull()) {
|
||||||
|
singleproxy["alpn"][1] >>= alpn2;
|
||||||
|
alpns.push_back(alpn2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
singleproxy["client-fingerprint"] >>= fingerprint;
|
||||||
|
anyTlSConstruct(node, ANYTLS_DEFAULT_GROUP, ps, port, password, server, alpns, fingerprint, sni,
|
||||||
|
udp,
|
||||||
|
tribool(), scv, tribool(), "", 30, 30, 0);
|
||||||
|
break;
|
||||||
|
case "mieru"_hash:
|
||||||
|
group = MIERU_DEFAULT_GROUP;
|
||||||
|
singleproxy["password"] >>= password;
|
||||||
|
singleproxy["username"] >>= user;
|
||||||
|
singleproxy["port-range"] >>= ports;
|
||||||
|
if (!singleproxy["multiplexing"].IsNull()) {
|
||||||
|
singleproxy["multiplexing"] >>= multiplexing;
|
||||||
|
}
|
||||||
|
transfer_protocol = "TCP";
|
||||||
|
if (!singleproxy["transport"].IsNull()) {
|
||||||
|
singleproxy["transport"] >>= transfer_protocol;
|
||||||
|
}
|
||||||
|
mieruConstruct(node, MIERU_DEFAULT_GROUP, ps, port, password, server, ports, user, multiplexing,
|
||||||
|
transfer_protocol,
|
||||||
|
udp,
|
||||||
|
tribool(), scv, tribool(), "");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1426,7 +1567,8 @@ void explodeStdVMess(std::string vmess, Proxy &node) {
|
|||||||
remarks = urlDecode(vmess.substr(pos + 1));
|
remarks = urlDecode(vmess.substr(pos + 1));
|
||||||
vmess.erase(pos);
|
vmess.erase(pos);
|
||||||
}
|
}
|
||||||
const std::string stdvmess_matcher = R"(^([a-z]+)(?:\+([a-z]+))?:([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})-(\d+)@(.+):(\d+)(?:\/?\?(.*))?$)";
|
const std::string stdvmess_matcher =
|
||||||
|
R"(^([a-z]+)(?:\+([a-z]+))?:([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})-(\d+)@(.+):(\d+)(?:\/?\?(.*))?$)";
|
||||||
if (regGetMatch(vmess, stdvmess_matcher, 8, 0, &net, &tls, &id, &aid, &add, &port, &addition))
|
if (regGetMatch(vmess, stdvmess_matcher, 8, 0, &net, &tls, &id, &aid, &add, &port, &addition))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1451,8 +1593,13 @@ void explodeStdVMess(std::string vmess, Proxy &node) {
|
|||||||
|
|
||||||
if (remarks.empty())
|
if (remarks.empty())
|
||||||
remarks = add + ":" + port;
|
remarks = add + ":" + port;
|
||||||
|
std::string alpn = getUrlArg(addition, "alpn");
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", path, host, "", tls, "");
|
std::vector<std::string> alpnList;
|
||||||
|
if (!alpn.empty()) {
|
||||||
|
alpnList.push_back(alpn);
|
||||||
|
}
|
||||||
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", path, host, "", tls, "",
|
||||||
|
alpnList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1483,13 +1630,61 @@ void explodeStdHysteria(std::string hysteria, Proxy &node) {
|
|||||||
|
|
||||||
if (remarks.empty())
|
if (remarks.empty())
|
||||||
remarks = add + ":" + port;
|
remarks = add + ":" + port;
|
||||||
|
std::vector<std::string> alpnList;
|
||||||
|
if (!alpn.empty()) {
|
||||||
|
alpnList.push_back(alpn);
|
||||||
|
}
|
||||||
hysteriaConstruct(node, HYSTERIA_DEFAULT_GROUP, remarks, add, port, type, auth, auth_str, host, up, down, alpn,
|
hysteriaConstruct(node, HYSTERIA_DEFAULT_GROUP, remarks, add, port, type, auth, auth_str, host, up, down, alpn,
|
||||||
obfsParam,
|
obfsParam,
|
||||||
insecure, "", sni);
|
insecure, "", sni);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void explodeStdMieru(std::string mieru, Proxy &node) {
|
||||||
|
std::string username, password, host, port, ports, profile, protocol, multiplexing, mtu, remarks;
|
||||||
|
std::string addition;
|
||||||
|
tribool udp, tfo, scv, tls13;
|
||||||
|
|
||||||
|
// 去除前缀
|
||||||
|
string_size pos;
|
||||||
|
|
||||||
|
// 提取 remarks
|
||||||
|
pos = mieru.rfind("#");
|
||||||
|
if (pos != mieru.npos) {
|
||||||
|
remarks = urlDecode(mieru.substr(pos + 1));
|
||||||
|
mieru.erase(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取参数
|
||||||
|
pos = mieru.rfind("?");
|
||||||
|
if (pos != mieru.npos) {
|
||||||
|
addition = mieru.substr(pos + 1);
|
||||||
|
mieru.erase(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 账号密码@host
|
||||||
|
if (regGetMatch(mieru, R"(^(.*?):(.*?)@(.*)$)", 4, 0, &username, &password, &host))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 提取端口(port=多个情况)
|
||||||
|
port = getUrlArg(addition, "port");
|
||||||
|
if (port.find('-') != std::string::npos) {
|
||||||
|
ports = port;
|
||||||
|
}
|
||||||
|
// 提取协议(多个 protocol)
|
||||||
|
protocol = getUrlArg(addition, "protocol");
|
||||||
|
|
||||||
|
multiplexing = getUrlArg(addition, "multiplexing");
|
||||||
|
mtu = getUrlArg(addition, "mtu");
|
||||||
|
|
||||||
|
if (remarks.empty())
|
||||||
|
remarks = host;
|
||||||
|
|
||||||
|
mieruConstruct(node, "MieruGroup", remarks, port,
|
||||||
|
password, host, ports, username, multiplexing, protocol,
|
||||||
|
udp, tfo, scv, tls13, "");
|
||||||
|
}
|
||||||
|
|
||||||
void explodeStdHysteria2(std::string hysteria2, Proxy &node) {
|
void explodeStdHysteria2(std::string hysteria2, Proxy &node) {
|
||||||
std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks, sni, ports;
|
std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks, sni, ports;
|
||||||
std::string addition;
|
std::string addition;
|
||||||
@@ -1553,7 +1748,8 @@ void explodeStdVless(std::string vless, Proxy &node) {
|
|||||||
remarks = urlDecode(vless.substr(pos + 1));
|
remarks = urlDecode(vless.substr(pos + 1));
|
||||||
vless.erase(pos);
|
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))
|
if (regGetMatch(vless, stdvless_matcher, 5, 0, &id, &add, &port, &addition))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1563,7 +1759,12 @@ void explodeStdVless(std::string vless, Proxy &node) {
|
|||||||
pbk = getUrlArg(addition, "pbk");
|
pbk = getUrlArg(addition, "pbk");
|
||||||
sid = getUrlArg(addition, "sid");
|
sid = getUrlArg(addition, "sid");
|
||||||
fp = getUrlArg(addition, "fp");
|
fp = getUrlArg(addition, "fp");
|
||||||
|
std::string packet_encoding = getUrlArg(addition, "packet-encoding");
|
||||||
|
std::string alpn = getUrlArg(addition, "alpn");
|
||||||
|
std::vector<std::string> alpnList;
|
||||||
|
if (!alpn.empty()) {
|
||||||
|
alpnList.push_back(alpn);
|
||||||
|
}
|
||||||
switch (hash_(net)) {
|
switch (hash_(net)) {
|
||||||
case "tcp"_hash:
|
case "tcp"_hash:
|
||||||
case "ws"_hash:
|
case "ws"_hash:
|
||||||
@@ -1590,7 +1791,7 @@ void explodeStdVless(std::string vless, Proxy &node) {
|
|||||||
remarks = add + ":" + port;
|
remarks = add + ":" + port;
|
||||||
sni = getUrlArg(addition, "sni");
|
sni = getUrlArg(addition, "sni");
|
||||||
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", flow, mode, path, host, "",
|
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", flow, mode, path, host, "",
|
||||||
tls, pbk, sid, fp, sni);
|
tls, pbk, sid, fp, sni, alpnList, packet_encoding);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1629,8 +1830,13 @@ void explodeShadowrocket(std::string rocket, Proxy &node) {
|
|||||||
|
|
||||||
if (remarks.empty())
|
if (remarks.empty())
|
||||||
remarks = add + ":" + port;
|
remarks = add + ":" + port;
|
||||||
|
std::string alpn = getUrlArg(addition, "alpn");
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "");
|
std::vector<std::string> alpnList;
|
||||||
|
if (!alpn.empty()) {
|
||||||
|
alpnList.push_back(alpn);
|
||||||
|
}
|
||||||
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "",
|
||||||
|
alpnList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeKitsunebi(std::string kit, Proxy &node) {
|
void explodeKitsunebi(std::string kit, Proxy &node) {
|
||||||
@@ -1664,8 +1870,13 @@ void explodeKitsunebi(std::string kit, Proxy &node) {
|
|||||||
|
|
||||||
if (remarks.empty())
|
if (remarks.empty())
|
||||||
remarks = add + ":" + port;
|
remarks = add + ":" + port;
|
||||||
|
std::string alpn = getUrlArg(addition, "alpn");
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "");
|
std::vector<std::string> alpnList;
|
||||||
|
if (!alpn.empty()) {
|
||||||
|
alpnList.push_back(alpn);
|
||||||
|
}
|
||||||
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "",
|
||||||
|
alpnList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// peer = (public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, allowed-ips = "0.0.0.0/0, ::/0", endpoint = engage.cloudflareclient.com:2408, client-id = 139/184/125),(public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, endpoint = engage.cloudflareclient.com:2408)
|
// peer = (public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, allowed-ips = "0.0.0.0/0, ::/0", endpoint = engage.cloudflareclient.com:2408, client-id = 139/184/125),(public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, endpoint = engage.cloudflareclient.com:2408)
|
||||||
@@ -1811,9 +2022,9 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
ssConstruct(node, SS_DEFAULT_GROUP, remarks, server, port, password, method, plugin, pluginopts, udp,
|
ssConstruct(node, SS_DEFAULT_GROUP, remarks, server, port, password, method, plugin, pluginopts, udp,
|
||||||
tfo, scv);
|
tfo, scv);
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
// continue;
|
// continue;
|
||||||
break;
|
break;
|
||||||
case "ss"_hash: //surge 3 style ss proxy
|
case "ss"_hash: //surge 3 style ss proxy
|
||||||
server = trim(configs[1]);
|
server = trim(configs[1]);
|
||||||
port = trim(configs[2]);
|
port = trim(configs[2]);
|
||||||
@@ -1951,7 +2162,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host,
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host,
|
||||||
edge, tls, "", udp, tfo, scv, tls13);
|
edge, tls, "", std::vector<std::string>{}, udp, tfo, scv, tls13);
|
||||||
break;
|
break;
|
||||||
case "http"_hash: //http proxy
|
case "http"_hash: //http proxy
|
||||||
server = trim(configs[1]);
|
server = trim(configs[1]);
|
||||||
@@ -2018,6 +2229,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp, sni,
|
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp, sni,
|
||||||
|
std::vector<std::string>{},
|
||||||
true,
|
true,
|
||||||
udp,
|
udp,
|
||||||
tfo, scv);
|
tfo, scv);
|
||||||
@@ -2117,7 +2329,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wireguardConstruct(node, WG_DEFAULT_GROUP, remarks, "", "0", ip, ipv6, private_key, "", "", dns_servers,
|
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);
|
parsePeers(node, peer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -2281,7 +2493,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
remarks = server + ":" + port;
|
remarks = server + ":" + port;
|
||||||
|
|
||||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
|
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
|
||||||
path, host, "", tls, "", udp, tfo, scv, tls13);
|
path, host, "", tls, "", std::vector<std::string>{}, udp, tfo, scv, tls13);
|
||||||
break;
|
break;
|
||||||
case "vless"_hash: //quantumult x style vless link
|
case "vless"_hash: //quantumult x style vless link
|
||||||
server = trim(configs[0].substr(0, configs[0].rfind(":")));
|
server = trim(configs[0].substr(0, configs[0].rfind(":")));
|
||||||
@@ -2348,7 +2560,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
remarks = server + ":" + port;
|
remarks = server + ":" + port;
|
||||||
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
|
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
|
||||||
"chrome", "", path, host, "",
|
"chrome", "", path, host, "",
|
||||||
tls, "", "", fp, sni, udp, tfo, scv, tls13);
|
tls, "", "", fp, sni, std::vector<std::string>{}, "", udp, tfo, scv, tls13);
|
||||||
break;
|
break;
|
||||||
case "trojan"_hash: //quantumult x style trojan link
|
case "trojan"_hash: //quantumult x style trojan link
|
||||||
server = trim(configs[0].substr(0, configs[0].rfind(':')));
|
server = trim(configs[0].substr(0, configs[0].rfind(':')));
|
||||||
@@ -2399,7 +2611,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
|||||||
remarks = server + ":" + port;
|
remarks = server + ":" + port;
|
||||||
|
|
||||||
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp,
|
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp,
|
||||||
sni,
|
sni, std::vector<std::string>{},
|
||||||
tls == "true", udp, tfo, scv, tls13);
|
tls == "true", udp, tfo, scv, tls13);
|
||||||
break;
|
break;
|
||||||
case "http"_hash: //quantumult x style http links
|
case "http"_hash: //quantumult x style http links
|
||||||
@@ -2628,16 +2840,17 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
if (outbounds[i].IsObject()) {
|
if (outbounds[i].IsObject()) {
|
||||||
std::string proxytype, ps, server, port, cipher, group, password, ports, tempPassword; //common
|
std::string proxytype, ps, server, port, cipher, group, password, ports, tempPassword; //common
|
||||||
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
|
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
|
||||||
std::string fp = "chrome", pbk, sid; //vless
|
std::string fp = "chrome", pbk, sid, packet_encoding; //vless
|
||||||
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
|
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
|
||||||
std::string protocol, protoparam, obfs, obfsparam; //ssr
|
std::string protocol, protoparam, obfs, obfsparam; //ssr
|
||||||
std::string flow, mode; //trojan
|
std::string flow, mode; //trojan
|
||||||
std::string user; //socks
|
std::string user; //socks
|
||||||
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
|
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
|
||||||
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
|
std::string auth, up, down, obfsParam, insecure, alpn; //hysteria
|
||||||
std::string obfsPassword;//hysteria2
|
std::string obfsPassword; //hysteria2
|
||||||
string_array dns_server;
|
string_array dns_server;
|
||||||
std::string congestion_control, udp_relay_mode;//quic
|
std::string fingerprint;
|
||||||
|
std::string congestion_control, udp_relay_mode; //quic
|
||||||
tribool udp, tfo, scv, rrt, disableSni;
|
tribool udp, tfo, scv, rrt, disableSni;
|
||||||
rapidjson::Value singboxNode = outbounds[i].GetObject();
|
rapidjson::Value singboxNode = outbounds[i].GetObject();
|
||||||
if (singboxNode.HasMember("type") && singboxNode["type"].IsString()) {
|
if (singboxNode.HasMember("type") && singboxNode["type"].IsString()) {
|
||||||
@@ -2647,6 +2860,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
server = GetMember(singboxNode, "server");
|
server = GetMember(singboxNode, "server");
|
||||||
port = GetMember(singboxNode, "server_port");
|
port = GetMember(singboxNode, "server_port");
|
||||||
tfo = GetMember(singboxNode, "tcp_fast_open");
|
tfo = GetMember(singboxNode, "tcp_fast_open");
|
||||||
|
std::vector<std::string> alpnList;
|
||||||
if (singboxNode.HasMember("tls") && singboxNode["tls"].IsObject()) {
|
if (singboxNode.HasMember("tls") && singboxNode["tls"].IsObject()) {
|
||||||
rapidjson::Value tlsObj = singboxNode["tls"].GetObject();
|
rapidjson::Value tlsObj = singboxNode["tls"].GetObject();
|
||||||
if (tlsObj.HasMember("enabled") && tlsObj["enabled"].IsBool() && tlsObj["enabled"].GetBool()) {
|
if (tlsObj.HasMember("enabled") && tlsObj["enabled"].IsBool() && tlsObj["enabled"].GetBool()) {
|
||||||
@@ -2657,6 +2871,10 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
rapidjson::Value alpns = tlsObj["alpn"].GetArray();
|
rapidjson::Value alpns = tlsObj["alpn"].GetArray();
|
||||||
if (alpns.Size() > 0) {
|
if (alpns.Size() > 0) {
|
||||||
alpn = alpns[0].GetString();
|
alpn = alpns[0].GetString();
|
||||||
|
for (auto &item: tlsObj["alpn"].GetArray()) {
|
||||||
|
if (item.IsString())
|
||||||
|
alpnList.emplace_back(item.GetString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tlsObj.HasMember("insecure") && tlsObj["insecure"].IsBool()) {
|
if (tlsObj.HasMember("insecure") && tlsObj["insecure"].IsBool()) {
|
||||||
@@ -2681,6 +2899,12 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
sid = reality["short_id"].GetString();
|
sid = reality["short_id"].GetString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tlsObj.HasMember("utls") && tlsObj["utls"].IsObject()) {
|
||||||
|
if (rapidjson::Value reality = tlsObj["utls"].GetObject();
|
||||||
|
reality.HasMember("fingerprint") && reality["fingerprint"].IsString()) {
|
||||||
|
fingerprint = reality["fingerprint"].GetString();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tls = "false";
|
tls = "false";
|
||||||
}
|
}
|
||||||
@@ -2695,7 +2919,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
cipher = GetMember(singboxNode, "security");
|
cipher = GetMember(singboxNode, "security");
|
||||||
explodeSingboxTransport(singboxNode, net, host, path, edge);
|
explodeSingboxTransport(singboxNode, net, host, path, edge);
|
||||||
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls,
|
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls,
|
||||||
sni, udp,
|
sni, alpnList, udp,
|
||||||
tfo, scv);
|
tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "shadowsocks"_hash:
|
case "shadowsocks"_hash:
|
||||||
@@ -2710,7 +2934,8 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
group = TROJAN_DEFAULT_GROUP;
|
group = TROJAN_DEFAULT_GROUP;
|
||||||
password = GetMember(singboxNode, "password");
|
password = GetMember(singboxNode, "password");
|
||||||
explodeSingboxTransport(singboxNode, net, host, path, edge);
|
explodeSingboxTransport(singboxNode, net, host, path, edge);
|
||||||
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, sni, true, udp,
|
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, sni, alpnList,
|
||||||
|
true, udp,
|
||||||
tfo,
|
tfo,
|
||||||
scv);
|
scv);
|
||||||
break;
|
break;
|
||||||
@@ -2718,6 +2943,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
group = XRAY_DEFAULT_GROUP;
|
group = XRAY_DEFAULT_GROUP;
|
||||||
id = GetMember(singboxNode, "uuid");
|
id = GetMember(singboxNode, "uuid");
|
||||||
flow = GetMember(singboxNode, "flow");
|
flow = GetMember(singboxNode, "flow");
|
||||||
|
packet_encoding = GetMember(singboxNode, "packet_encoding");
|
||||||
if (singboxNode.HasMember("transport") && singboxNode["transport"].IsObject()) {
|
if (singboxNode.HasMember("transport") && singboxNode["transport"].IsObject()) {
|
||||||
rapidjson::Value transport = singboxNode["transport"].GetObject();
|
rapidjson::Value transport = singboxNode["transport"].GetObject();
|
||||||
net = GetMember(transport, "type");
|
net = GetMember(transport, "type");
|
||||||
@@ -2754,8 +2980,9 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vlessConstruct(node, group, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
|
vlessConstruct(node, group, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
|
||||||
host, "", tls, pbk, sid, fp, sni);
|
host, "", tls, pbk, sid, fp, sni, alpnList, packet_encoding, udp);
|
||||||
break;
|
break;
|
||||||
case "http"_hash:
|
case "http"_hash:
|
||||||
password = GetMember(singboxNode, "password");
|
password = GetMember(singboxNode, "password");
|
||||||
@@ -2772,7 +2999,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
password = GetMember(singboxNode, "pre_shared_key");
|
password = GetMember(singboxNode, "pre_shared_key");
|
||||||
dns_server = {"8.8.8.8"};
|
dns_server = {"8.8.8.8"};
|
||||||
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
||||||
dns_server, mtu, "0", "", "", udp);
|
dns_server, mtu, "0", "", "", udp, "");
|
||||||
break;
|
break;
|
||||||
case "socks"_hash:
|
case "socks"_hash:
|
||||||
group = SOCKS_DEFAULT_GROUP;
|
group = SOCKS_DEFAULT_GROUP;
|
||||||
@@ -2797,6 +3024,14 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
|||||||
obfsParam, insecure, ports, sni,
|
obfsParam, insecure, ports, sni,
|
||||||
udp, tfo, scv);
|
udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
|
case "anytls"_hash:
|
||||||
|
group = ANYTLS_DEFAULT_GROUP;
|
||||||
|
password = GetMember(singboxNode, "password");
|
||||||
|
anyTlSConstruct(node, ANYTLS_DEFAULT_GROUP, ps, port, password, server, alpnList, fingerprint,
|
||||||
|
sni,
|
||||||
|
udp,
|
||||||
|
tribool(), scv, tribool(), "", 30, 30, 0);
|
||||||
|
break;
|
||||||
case "hysteria2"_hash:
|
case "hysteria2"_hash:
|
||||||
group = HYSTERIA2_DEFAULT_GROUP;
|
group = HYSTERIA2_DEFAULT_GROUP;
|
||||||
password = GetMember(singboxNode, "password");
|
password = GetMember(singboxNode, "password");
|
||||||
@@ -2919,6 +3154,8 @@ void explode(const std::string &link, Proxy &node) {
|
|||||||
explodeTuic(link, node);
|
explodeTuic(link, node);
|
||||||
else if (strFind(link, "hysteria2://") || strFind(link, "hy2://"))
|
else if (strFind(link, "hysteria2://") || strFind(link, "hy2://"))
|
||||||
explodeHysteria2(link, node);
|
explodeHysteria2(link, node);
|
||||||
|
else if (strFind(link, "mierus://") || strFind(link, "mieru://"))
|
||||||
|
explodeMierus(link, node);
|
||||||
else if (isLink(link))
|
else if (isLink(link))
|
||||||
explodeHTTPSub(link, node);
|
explodeHTTPSub(link, node);
|
||||||
}
|
}
|
||||||
@@ -2944,8 +3181,7 @@ void explodeSub(std::string sub, std::vector<Proxy> &nodes) {
|
|||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (std::exception &e) {
|
||||||
catch (std::exception &e) {
|
|
||||||
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
|
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
|
||||||
//ignore
|
//ignore
|
||||||
throw;
|
throw;
|
||||||
@@ -2970,8 +3206,7 @@ void explodeSub(std::string sub, std::vector<Proxy> &nodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (std::exception &e) {
|
||||||
catch (std::exception &e) {
|
|
||||||
writeLog(LOG_TYPE_ERROR, e.what(), LOG_LEVEL_ERROR);
|
writeLog(LOG_TYPE_ERROR, e.what(), LOG_LEVEL_ERROR);
|
||||||
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
|
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
|
||||||
//ignore
|
//ignore
|
||||||
|
|||||||
@@ -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 &down, const std::string &alpn, const std::string &obfsParam,
|
||||||
const std::string &insecure, const std::string &ports, const std::string &sni,
|
const std::string &insecure, const std::string &ports, const std::string &sni,
|
||||||
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
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,
|
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,
|
const std::string &port, const std::string &password, const std::string &host,
|
||||||
@@ -33,57 +33,75 @@ 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 &obfsParam, const std::string &obfsPassword, const std::string &sni,
|
||||||
const std::string &publicKey, const std::string &ports,
|
const std::string &publicKey, const std::string &ports,
|
||||||
tribool udp, tribool tfo,
|
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,
|
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,
|
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 &flow, const std::string &mode,
|
const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode,
|
||||||
const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,
|
const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,
|
||||||
const std::string &pkd, const std::string &sid, const std::string &fp, const std::string &sni,
|
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 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,
|
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 &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 &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, tribool udp = tribool(),
|
const std::string &edge, const std::string &tls, const std::string &sni,
|
||||||
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
const std::vector<std::string> &alpnList, tribool udp = 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,
|
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 &port, const std::string &protocol, const std::string &method,
|
||||||
const std::string &obfs, const std::string &password, const std::string &obfsparam,
|
const std::string &obfs, const std::string &password, const std::string &obfsparam,
|
||||||
const std::string &protoparam, tribool udp = tribool(), tribool tfo = tribool(),
|
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,
|
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 &port, const std::string &password, const std::string &method,
|
||||||
const std::string &plugin, const std::string &pluginopts, tribool udp = tribool(),
|
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,
|
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,
|
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,
|
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,
|
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,
|
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 &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::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(),
|
bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||||
tribool tls13 = tribool());
|
tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||||
|
void anyTlSConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||||
|
const std::string &port, const std::string &password,
|
||||||
|
const std::string &host, const std::vector<String> &AlpnList,
|
||||||
|
const std::string &fingerprint,
|
||||||
|
const std::string &sni, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||||
|
tribool tls13 = tribool(),const std::string& underlying_proxy="",uint16_t idleSessionCheckInterval=30,uint16_t idleSessionTimeout=30,uint16_t minIdleSession=0);
|
||||||
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
|
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 &port, const std::string &password, const std::string &obfs,
|
||||||
const std::string &host, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(),
|
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,
|
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,
|
const std::string &port, const std::string &password, const std::string &congestion_control,
|
||||||
const std::string &alpn,
|
const std::string &alpn,
|
||||||
const std::string &sni,const std::string & uuid,const std::string &udpRelayMode,const std::string &token,
|
const std::string &sni, const std::string &uuid, const std::string &udpRelayMode,
|
||||||
|
const std::string &token,
|
||||||
tribool udp = tribool(), tribool tfo = tribool(),
|
tribool udp = tribool(), tribool tfo = tribool(),
|
||||||
tribool scv = tribool(),tribool reduceRtt = tribool(),tribool disableSni = tribool(),uint16_t request_timeout = 15000);
|
tribool scv = tribool(), tribool reduceRtt = tribool(), tribool disableSni = tribool(),
|
||||||
|
uint16_t request_timeout = 15000,const std::string& underlying_proxy="");
|
||||||
|
void mieruConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||||
|
const std::string &port, const std::string &password,
|
||||||
|
const std::string &host, const std::string &ports,
|
||||||
|
const std::string &username,const std::string &multiplexing,
|
||||||
|
const std::string &transfer_protocol, tribool udp,
|
||||||
|
tribool tfo, tribool scv,
|
||||||
|
tribool tls13, const std::string &underlying_proxy);
|
||||||
void explodeVmess(std::string vmess, Proxy &node);
|
void explodeVmess(std::string vmess, Proxy &node);
|
||||||
|
|
||||||
void explodeSSR(std::string ssr, Proxy &node);
|
void explodeSSR(std::string ssr, Proxy &node);
|
||||||
@@ -93,11 +111,11 @@ void explodeSS(std::string ss, Proxy &node);
|
|||||||
void explodeTrojan(std::string trojan, Proxy &node);
|
void explodeTrojan(std::string trojan, Proxy &node);
|
||||||
|
|
||||||
void explodeQuan(const std::string &quan, Proxy &node);
|
void explodeQuan(const std::string &quan, Proxy &node);
|
||||||
|
void explodeMierus(std::string mieru, Proxy &node);
|
||||||
void explodeStdVMess(std::string vmess, Proxy &node);
|
void explodeStdVMess(std::string vmess, Proxy &node);
|
||||||
|
|
||||||
void explodeStdVless(std::string vless, Proxy &node);
|
void explodeStdVless(std::string vless, Proxy &node);
|
||||||
|
void explodeStdMieru(std::string mieru, Proxy &node);
|
||||||
void explodeStdHysteria(std::string hysteria, Proxy &node);
|
void explodeStdHysteria(std::string hysteria, Proxy &node);
|
||||||
|
|
||||||
void explodeStdHysteria2(std::string hysteria2, Proxy &node);
|
void explodeStdHysteria2(std::string hysteria2, Proxy &node);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <quickjspp.hpp>
|
#include <quickjspp.hpp>
|
||||||
|
#include <utility>
|
||||||
#include <quickjs/quickjs-libc.h>
|
#include <quickjs/quickjs-libc.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -226,7 +227,7 @@ public:
|
|||||||
qjs_fetch_Headers headers;
|
qjs_fetch_Headers headers;
|
||||||
std::string cookies;
|
std::string cookies;
|
||||||
std::string postdata;
|
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
|
class qjs_fetch_Response
|
||||||
@@ -389,7 +390,7 @@ void script_runtime_init(qjs::Runtime &runtime)
|
|||||||
js_std_init_handlers(runtime.rt);
|
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
|
#ifdef _WIN32
|
||||||
if(!type)
|
if(!type)
|
||||||
@@ -424,7 +425,7 @@ struct Lambda {
|
|||||||
|
|
||||||
uint32_t currentTime()
|
uint32_t currentTime()
|
||||||
{
|
{
|
||||||
return time(NULL);
|
return time(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int script_context_init(qjs::Context &context)
|
int script_context_init(qjs::Context &context)
|
||||||
@@ -525,7 +526,7 @@ int script_context_init(qjs::Context &context)
|
|||||||
)", "<import>", JS_EVAL_TYPE_MODULE);
|
)", "<import>", JS_EVAL_TYPE_MODULE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(qjs::exception)
|
catch(qjs::exception&)
|
||||||
{
|
{
|
||||||
script_print_stack(context);
|
script_print_stack(context);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -47,16 +47,23 @@ static httplib::Server::Handler makeHandler(const responseRoute &rr)
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
req.headers[h.first] = h.second;
|
req.headers.emplace(h.first.data(), h.second.data());
|
||||||
}
|
}
|
||||||
req.argument = request.params;
|
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);
|
if (request.is_multipart_form_data() && !request.files.empty())
|
||||||
}
|
{
|
||||||
else
|
req.postdata = request.files.begin()->second.content;
|
||||||
{
|
}
|
||||||
req.postdata = request.body;
|
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);
|
auto result = rr.rc(req, resp);
|
||||||
response.status = resp.status_code;
|
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-Headers", req.get_header_value("Access-Control-Request-Headers"));
|
||||||
}
|
}
|
||||||
|
res.set_header("Access-Control-Allow-Origin", "*");
|
||||||
return httplib::Server::HandlerResponse::Unhandled;
|
return httplib::Server::HandlerResponse::Unhandled;
|
||||||
});
|
});
|
||||||
for (auto &x : redirect_map)
|
for (auto &x : redirect_map)
|
||||||
@@ -187,7 +195,7 @@ int WebServer::start_web_server_multi(listener_args *args)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::rethrow_exception(e);
|
if (e) std::rethrow_exception(e);
|
||||||
}
|
}
|
||||||
catch (const httplib::Error &err)
|
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.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);
|
server.bind_to_port(args->listen_address, args->port, 0);
|
||||||
|
|
||||||
std::thread thread([&]()
|
std::thread thread([&]()
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ std::string getTime(int type)
|
|||||||
format = "%Y%m%d-%H%M%S";
|
format = "%Y%m%d-%H%M%S";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
format = "%Y/%m/%d %a %H:%M:%S." + std::string(cMillis);
|
format = "%Y/%m/%d %a %H:%M:%S.";
|
||||||
|
format += cMillis;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -5,9 +5,16 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct strICaseComp {
|
struct strICaseComp
|
||||||
bool operator()(const std::string &lhs, const std::string &rhs) const {
|
{
|
||||||
return strcasecmp(lhs.c_str(), rhs.c_str()) > 0;
|
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 <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <time.h>
|
#include <ctime>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "map_extra.h"
|
#include "map_extra.h"
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string &s, const std::string &separator)
|
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;
|
std::vector<std::string> result;
|
||||||
string_size i = 0;
|
while(bpos < s.size())
|
||||||
|
|
||||||
while(i != s.size())
|
|
||||||
{
|
{
|
||||||
int flag = 0;
|
if(epos == std::string::npos)
|
||||||
while(i != s.size() && flag == 0)
|
epos = s.size();
|
||||||
{
|
result.push_back(s.substr(bpos, epos - bpos));
|
||||||
flag = 1;
|
bpos = epos + separator.size();
|
||||||
for(char x : separator)
|
epos = s.find(separator, bpos);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void split(std::vector<std::string_view> &result, std::string_view s, char separator)
|
void split(std::vector<std::string_view> &result, std::string_view s, char separator)
|
||||||
{
|
{
|
||||||
string_size i = 0;
|
string_size bpos = 0, epos = s.find(separator);
|
||||||
|
while(bpos < s.size())
|
||||||
while (i != s.size())
|
|
||||||
{
|
{
|
||||||
int flag = 0;
|
if(epos == std::string_view::npos)
|
||||||
while(i != s.size() && flag == 0)
|
epos = s.size();
|
||||||
{
|
result.push_back(s.substr(bpos, epos - bpos));
|
||||||
flag = 1;
|
bpos = epos + 1;
|
||||||
if(s[i] == separator)
|
epos = s.find(separator, bpos);
|
||||||
{
|
|
||||||
++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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +91,7 @@ std::string toUpper(const std::string &str)
|
|||||||
void processEscapeChar(std::string &str)
|
void processEscapeChar(std::string &str)
|
||||||
{
|
{
|
||||||
string_size pos = str.find('\\');
|
string_size pos = str.find('\\');
|
||||||
while(pos != str.npos)
|
while(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
if(pos == str.size())
|
if(pos == str.size())
|
||||||
break;
|
break;
|
||||||
@@ -191,7 +141,7 @@ void processEscapeCharReverse(std::string &str)
|
|||||||
|
|
||||||
int parseCommaKeyValue(const std::string &input, const std::string &separator, string_pair_array &result)
|
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;
|
std::string kv;
|
||||||
while(bpos < input.size())
|
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] == '\\')
|
else if(epos && input[epos - 1] == '\\')
|
||||||
{
|
{
|
||||||
kv += input.substr(bpos, epos - bpos - 1);
|
kv += input.substr(bpos, epos - bpos - 1);
|
||||||
kv += ',';
|
kv += separator;
|
||||||
bpos = epos + 1;
|
bpos = epos + 1;
|
||||||
epos = input.find(',', bpos);
|
epos = input.find(separator, bpos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
kv += input.substr(bpos, epos - bpos);
|
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));
|
result.emplace_back(kv.substr(0, eqpos), kv.substr(eqpos + 1));
|
||||||
kv.clear();
|
kv.clear();
|
||||||
bpos = epos + 1;
|
bpos = epos + 1;
|
||||||
epos = input.find(',', bpos);
|
epos = input.find(separator, bpos);
|
||||||
}
|
}
|
||||||
if(kv.size())
|
if(!kv.empty())
|
||||||
{
|
{
|
||||||
string_size eqpos = kv.find('=');
|
string_size eqpos = kv.find('=');
|
||||||
if(eqpos == std::string::npos)
|
if(eqpos == std::string::npos)
|
||||||
@@ -328,12 +278,12 @@ std::string getUrlArg(const std::string &url, const std::string &request)
|
|||||||
while(pos)
|
while(pos)
|
||||||
{
|
{
|
||||||
pos = url.rfind(pattern, pos);
|
pos = url.rfind(pattern, pos);
|
||||||
if(pos != url.npos)
|
if(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
if(pos == 0 || url[pos - 1] == '&' || url[pos - 1] == '?')
|
if(pos == 0 || url[pos - 1] == '&' || url[pos - 1] == '?')
|
||||||
{
|
{
|
||||||
pos += pattern.size();
|
pos += pattern.size();
|
||||||
return url.substr(pos, url.find("&", pos) - pos);
|
return url.substr(pos, url.find('&', pos) - pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -410,23 +360,24 @@ bool isStrUTF8(const std::string &data)
|
|||||||
std::string randomStr(int len)
|
std::string randomStr(int len)
|
||||||
{
|
{
|
||||||
std::string retData;
|
std::string retData;
|
||||||
srand(time(NULL));
|
std::random_device rd;
|
||||||
int cnt = 0;
|
std::mt19937 gen(rd());
|
||||||
while(cnt < len)
|
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.push_back('a' + r);
|
||||||
retData += ('A' + rand() % 26);
|
}
|
||||||
break;
|
else if (r < 52)
|
||||||
case 2:
|
{
|
||||||
retData += ('a' + rand() % 26);
|
retData.push_back('A' + r - 26);
|
||||||
break;
|
}
|
||||||
default:
|
else
|
||||||
retData += ('0' + rand() % 10);
|
{
|
||||||
break;
|
retData.push_back('0' + r - 52);
|
||||||
}
|
}
|
||||||
cnt++;
|
|
||||||
}
|
}
|
||||||
return retData;
|
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)
|
std::string join(const string_array &arr, const std::string &delimiter)
|
||||||
{
|
{
|
||||||
if(arr.size() == 0)
|
if(arr.empty())
|
||||||
return "";
|
return "";
|
||||||
if(arr.size() == 1)
|
if(arr.size() == 1)
|
||||||
return arr[0];
|
return arr[0];
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef VERSION_H_INCLUDED
|
#ifndef VERSION_H_INCLUDED
|
||||||
#define VERSION_H_INCLUDED
|
#define VERSION_H_INCLUDED
|
||||||
|
|
||||||
#define VERSION "v0.9.6"
|
#define VERSION "v0.9.9"
|
||||||
|
|
||||||
#endif // VERSION_H_INCLUDED
|
#endif // VERSION_H_INCLUDED
|
||||||
|
|||||||
Reference in New Issue
Block a user