Compare commits

...

178 Commits

Author SHA1 Message Date
asdlokj1qpi233
add52ec9cb Compatible with lowercase host in vless and vmess.(#55) 2025-08-29 15:50:36 +08:00
asdlokj1qpi23
d22cd9b50a Merge pull request #56 from mi0e/anytls-conversion
feat: add anytls link parser
2025-08-27 17:29:48 +08:00
asdlokj1qpi23
d22cba4c69 Merge pull request #54 from greatcoolge/master
参数映射缺失
2025-08-27 17:29:14 +08:00
mi0e
dfa8188739 feat: add anytls link parser 2025-08-26 13:15:58 +08:00
greatcoolge
4bd91f89d8 subparser.cpp 2025-08-23 13:54:48 +08:00
asdlokj1qpi23
57c18b0c69 Merge pull request #51 from ionull/master
vless ws on loon
2025-08-05 13:01:49 +08:00
Tsung Wu
d95995a807 fix: compile error 2025-08-02 00:56:12 +08:00
Tsung Wu
add0e6da1a fix: vless ws nodes export on loon 2025-08-01 22:09:32 +08:00
Tsung Wu
80363459f2 fix: some vless nodes not exported on loon 2025-08-01 21:08:59 +08:00
asdlokj1qpi233
1624d0f10d add xhttp support (#43) 2025-07-31 18:06:05 +08:00
asdlokj1qpi233
36229fc2ad fix compile error 2025-07-29 11:28:01 +08:00
asdlokj1qpi233
aa721c5b06 fix compile error 2025-07-29 11:25:32 +08:00
asdlokj1qpi233
60d20e42c8 fix bug(#37),(#39),(#42) 2025-07-29 11:21:19 +08:00
asdlokj1qpi233
645361a07e fix compile error 2025-07-29 11:03:32 +08:00
asdlokj1qpi23
9947eebbfc Merge pull request #47 from gengjiawen/patch-1
support surge hy2 port-hopping
2025-07-29 10:22:55 +08:00
Jiawen Geng
11bc5c7236 Update subexport.cpp 2025-07-25 01:38:00 -07:00
Jiawen Geng
4b4d227603 support surge hy2 port-hopping 2025-07-25 01:36:12 -07:00
asdlokj1qpi23
383deb54a7 Fix error about hysteria2.(#33) 2025-05-16 11:18:27 +08:00
asdlokj1qpi23
766434b771 Fix error about hysteria2.(#33) 2025-05-14 17:45:46 +08:00
asdlokj1qpi23
cc9e3b77d4 Fix error about v2ray-http-upgrade for vless.(#31) 2025-05-06 10:14:15 +08:00
asdlokj1qpi23
4ae0d1b0bd Resolve the VLESS TCP error.(#29) 2025-04-28 09:48:58 +08:00
asdlokj1qpi23
a428c844a2 update template 2025-04-27 15:02:54 +08:00
asdlokj1qpi23
3a0784f1f6 fix surge error,(#27) (#28) 2025-04-27 12:42:34 +08:00
asdlokj1qpi23
4787d821bd fix surge error,(#27) (#28) 2025-04-27 11:13:36 +08:00
asdlokj1qpi23
97192f9e5d fix windows compile error
Some checks failed
GitHub CI / Linux aarch64 Build (push) Failing after 29s
GitHub CI / Linux amd64 Build (push) Failing after 25s
GitHub CI / Linux armv7 Build (push) Failing after 30s
GitHub CI / Linux x86 Build (push) Failing after 20s
Publish Docker Image / Build linux/386 Image (push) Failing after 6m53s
Publish Docker Image / Build linux/amd64 Image (push) Failing after 14m57s
Publish Docker Image / Build linux/arm/v7 Image (push) Failing after 41m26s
Publish Docker Image / Build linux/arm64 Image (push) Failing after 23m44s
Publish Docker Image / Merge (push) Has been skipped
GitHub CI / macOS arm Build (push) Has been cancelled
GitHub CI / macOS x86 Build (push) Has been cancelled
GitHub CI / Windows amd64 Build (push) Has been cancelled
GitHub CI / Windows x86 Build (push) Has been cancelled
2025-04-24 15:10:37 +08:00
asdlokj1qpi23
b0b04a0130 fix bugs, (#23) 2025-04-24 14:55:15 +08:00
asdlokj1qpi23
4e73f5695e fix bugs, (#25)
Some checks failed
GitHub CI / Linux aarch64 Build (push) Failing after 31s
GitHub CI / Linux amd64 Build (push) Failing after 18s
GitHub CI / Linux armv7 Build (push) Failing after 22s
GitHub CI / Linux x86 Build (push) Failing after 20s
Publish Docker Image / Build linux/386 Image (push) Failing after 7m6s
Publish Docker Image / Build linux/amd64 Image (push) Failing after 21m7s
Publish Docker Image / Build linux/arm/v7 Image (push) Failing after 31m29s
Publish Docker Image / Build linux/arm64 Image (push) Failing after 33m17s
GitHub CI / macOS arm Build (push) Has been cancelled
GitHub CI / macOS x86 Build (push) Has been cancelled
GitHub CI / Windows amd64 Build (push) Has been cancelled
GitHub CI / Windows x86 Build (push) Has been cancelled
Publish Docker Image / Merge (push) Has been cancelled
2025-04-21 09:27:39 +08:00
asdlokj1qpi23
dd59d514bd fix bugs, (#24) 2025-04-21 09:22:53 +08:00
asdlokj1qpi23
57ed33f96c fix error
Some checks failed
GitHub CI / Linux aarch64 Build (push) Failing after 43s
GitHub CI / Linux amd64 Build (push) Failing after 20s
GitHub CI / Linux armv7 Build (push) Failing after 32s
GitHub CI / Linux x86 Build (push) Failing after 18s
Publish Docker Image / Build linux/386 Image (push) Failing after 6m32s
Publish Docker Image / Build linux/amd64 Image (push) Failing after 27m34s
Publish Docker Image / Build linux/arm/v7 Image (push) Failing after 31m23s
Publish Docker Image / Build linux/arm64 Image (push) Failing after 34m18s
Publish Docker Image / Merge (push) Has been skipped
GitHub CI / macOS arm Build (push) Has been cancelled
GitHub CI / macOS x86 Build (push) Has been cancelled
GitHub CI / Windows amd64 Build (push) Has been cancelled
GitHub CI / Windows x86 Build (push) Has been cancelled
2025-04-18 17:07:25 +08:00
asdlokj1qpi23
eab18a9568 support hy2 and vless for mixed (#2) (#23) (#9) 2025-04-18 17:04:22 +08:00
asdlokj1qpi23
c242e631ba support vless reality for Loon,(#22) 2025-04-18 15:04:42 +08:00
asdlokj1qpi23
b649fdc253 fix mieru error
Some checks failed
GitHub CI / Linux aarch64 Build (push) Failing after 1m4s
GitHub CI / Linux amd64 Build (push) Failing after 51s
GitHub CI / Linux armv7 Build (push) Failing after 54s
GitHub CI / Linux x86 Build (push) Failing after 51s
Publish Docker Image / Build linux/386 Image (push) Failing after 9m26s
Publish Docker Image / Build linux/amd64 Image (push) Failing after 22m56s
Publish Docker Image / Build linux/arm/v7 Image (push) Failing after 52m6s
Publish Docker Image / Build linux/arm64 Image (push) Failing after 28m15s
Publish Docker Image / Merge (push) Has been skipped
GitHub CI / macOS arm Build (push) Has been cancelled
GitHub CI / macOS x86 Build (push) Has been cancelled
GitHub CI / Windows amd64 Build (push) Has been cancelled
GitHub CI / Windows x86 Build (push) Has been cancelled
2025-04-17 17:38:13 +08:00
asdlokj1qpi23
5759f52ebc fix bugs,add mierus link support 2025-04-17 16:03:58 +08:00
asdlokj1qpi23
e4b3ee816d add support anytls for singbox, add support mieru for clash 2025-04-17 15:10:37 +08:00
asdlokj1qpi23
ebf6a08449 support anytls for clash
Some checks failed
GitHub CI / Linux aarch64 Build (push) Failing after 22s
GitHub CI / Linux amd64 Build (push) Failing after 15s
GitHub CI / Linux armv7 Build (push) Failing after 18s
GitHub CI / Linux x86 Build (push) Failing after 18s
Publish Docker Image / Build linux/386 Image (push) Failing after 7m13s
Publish Docker Image / Build linux/amd64 Image (push) Failing after 22m43s
Publish Docker Image / Build linux/arm/v7 Image (push) Failing after 33m40s
Publish Docker Image / Build linux/arm64 Image (push) Failing after 25m25s
Publish Docker Image / Merge (push) Has been skipped
GitHub CI / macOS arm Build (push) Has been cancelled
GitHub CI / macOS x86 Build (push) Has been cancelled
GitHub CI / Windows amd64 Build (push) Has been cancelled
GitHub CI / Windows x86 Build (push) Has been cancelled
2025-04-16 18:14:00 +08:00
asdlokj1qpi23
638137e1db Merge pull request #21 from lilucpp/master
Some checks failed
GitHub CI / Linux ${{ matrix.arch }} Build (aarch64, subconverter_aarch64, ubuntu-latest) (push) Failing after 18s
GitHub CI / Linux ${{ matrix.arch }} Build (amd64, subconverter_linux64, ubuntu-latest) (push) Failing after 14s
GitHub CI / Linux ${{ matrix.arch }} Build (armv7, subconverter_armv7, ubuntu-latest) (push) Failing after 17s
GitHub CI / Linux ${{ matrix.arch }} Build (x86, subconverter_linux32, ubuntu-latest) (push) Failing after 17s
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/386) (push) Failing after 6m31s
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/amd64) (push) Failing after 24m11s
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/arm/v7) (push) Failing after 24m27s
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/arm64) (push) Failing after 30m36s
GitHub CI / macOS ${{ matrix.arch }} Build (arm, subconverter_darwinarm, macos-14) (push) Has been cancelled
GitHub CI / macOS ${{ matrix.arch }} Build (x86, subconverter_darwin64, macos-13) (push) Has been cancelled
GitHub CI / Windows ${{ matrix.arch }} Build (amd64, subconverter_win64, x86_64, MINGW64) (push) Has been cancelled
GitHub CI / Windows ${{ matrix.arch }} Build (x86, subconverter_win32, i686, MINGW32) (push) Has been cancelled
Publish Docker Image / Merge (push) Has been cancelled
fix: MINGW32 compiler error
2025-03-31 14:49:26 +08:00
lilucpp
ea49fe862d fix: MINGW32 compiler error 2025-03-29 13:47:33 +08:00
asdlokj1qpi23
3971468034 Update subexport.cpp
Some checks failed
GitHub CI / macOS ${{ matrix.arch }} Build (arm, subconverter_darwinarm, macos-14) (push) Waiting to run
GitHub CI / macOS ${{ matrix.arch }} Build (x86, subconverter_darwin64, macos-13) (push) Waiting to run
GitHub CI / Windows ${{ matrix.arch }} Build (amd64, subconverter_win64, x86_64, MINGW64) (push) Waiting to run
GitHub CI / Windows ${{ matrix.arch }} Build (x86, subconverter_win32, i686, MINGW32) (push) Waiting to run
GitHub CI / Linux ${{ matrix.arch }} Build (aarch64, subconverter_aarch64, ubuntu-latest) (push) Failing after 38s
GitHub CI / Linux ${{ matrix.arch }} Build (amd64, subconverter_linux64, ubuntu-latest) (push) Failing after 16s
GitHub CI / Linux ${{ matrix.arch }} Build (armv7, subconverter_armv7, ubuntu-latest) (push) Failing after 19s
GitHub CI / Linux ${{ matrix.arch }} Build (x86, subconverter_linux32, ubuntu-latest) (push) Failing after 22s
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/386) (push) Failing after 6m49s
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/arm/v7) (push) Has been cancelled
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/arm64) (push) Has been cancelled
Publish Docker Image / Merge (push) Has been cancelled
Publish Docker Image / Build ${{ matrix.platform }} Image (ubuntu-latest, linux/amd64) (push) Has been cancelled
2025-03-25 23:23:37 +08:00
asdlokj1qpi23
75a7b1c84c fix windows build error 2025-03-25 19:00:21 +08:00
asdlokj1qpi23
4ee3e11950 fix windows build error 2025-03-25 18:51:53 +08:00
asdlokj1qpi23
68f2f3bb56 fix windows build error 2025-03-25 18:41:14 +08:00
asdlokj1qpi23
79b2e31096 fix windows build error 2025-03-25 18:25:57 +08:00
asdlokj1qpi23
d5e6159fbd fix windows build error 2025-03-25 18:07:08 +08:00
asdlokj1qpi23
eec5113947 fix windows build error 2025-03-25 17:54:07 +08:00
asdlokj1qpi23
695f5eb6d7 fix windows build error 2025-03-25 17:45:08 +08:00
asdlokj1qpi23
a0ad2b46e0 fix windows build error 2025-03-25 17:35:30 +08:00
asdlokj1qpi23
2b0011a127 fix windows build error 2025-03-25 17:27:28 +08:00
asdlokj1qpi23
f69597efb7 Merge pull request #17 from brillcn/master
Update ruleconvert.cpp
2025-03-25 16:56:30 +08:00
asdlokj1qpi23
ffbd262aae fix bug (#11) 2025-03-25 16:41:46 +08:00
asdlokj1qpi23
3ea867e4b8 fix actions error 2025-03-25 15:02:07 +08:00
asdlokj1qpi23
090c2def1d merge tindy2013 2025-03-25 14:55:22 +08:00
asdlokj1qpi23
e88f8fd485 Merge remote-tracking branch 'fork/master' into dev
# Conflicts:
#	.github/workflows/build.yml
#	.github/workflows/docker.yml
#	.gitignore
#	base/pref.example.toml
#	base/snippets/emoji.toml
#	base/snippets/emoji.txt
#	scripts/build.macos.release.sh
#	scripts/build.windows.release.sh
#	scripts/rules_config.conf
#	src/generator/config/subexport.cpp
#	src/handler/interfaces.cpp
#	src/handler/settings.cpp
#	src/parser/config/proxy.h
#	src/parser/subparser.cpp
#	src/parser/subparser.h
#	src/utils/map_extra.h
#	src/version.h
2025-03-25 14:08:43 +08:00
BrilliantChen
292850818a Update ruleconvert.cpp
support meta all rules
2025-01-24 17:32:20 +08:00
Tindy X
92f66bf5b5 Fix Clash classical rule provider not renaming properly 2025-01-16 18:08:34 +08:00
Tindy X
b39de30db9 Update toml11 to v4.3.0 in Dockerfile 2025-01-16 17:31:30 +08:00
Tindy X
223d75a10a Fix Clash rule provider did not trim domains and ip-cidrs 2025-01-16 17:29:46 +08:00
Tindy X
691193731f Update toml11 to v4.3.0 2025-01-16 17:26:52 +08:00
Tindy X
05959b09b4 Url-decode file name before adding as Clash rule provider (#815) 2025-01-16 17:11:45 +08:00
Tindy X
3f5ed82672 Add CORS header to httplib webserver 2024-12-31 15:38:56 +08:00
Fanx
05910ac5dd Update Flag category (#810) 2024-12-31 15:37:24 +08:00
Tindy X
1d56f44696 Add TCP Fast Open option to Clash configs 2024-12-08 22:27:01 +08:00
Lai Zn
c207bfc1f0 Add Hysteria & Hysteria 2 support (#731)
* feat: add hysteria & hysteria 2 support

* Fix build error

* Remove deleted rules repository

---------

Co-authored-by: Tindy X <49061470+tindy2013@users.noreply.github.com>
2024-11-29 01:00:26 +08:00
TAKO
3a8762c307 update .gitignore 2024-10-28 10:57:30 +08:00
asdlokj1qpi23
bc7e2c2e94 Merge pull request #3 from FanxJK/master
Update Flag category
2024-10-28 10:23:33 +08:00
Fanx
ad47d18a23 Update Flag category 2024-10-25 19:09:18 +08:00
star
79a7e888b1 Add underlying-proxy, smart policy group support for surge and renaming surge wireguard section (#747)
* Use short hash of wireguard name for surge section name
Add underlying-proxy support for clash parser and surge exporter

* Add surge smart group support

* Allow clash to fallback to url-test in smart proxygroup

* Fix duplicate break statement in binding.h
2024-09-30 06:39:23 +08:00
asdlokj1qpi23
a1f919eafb update version and docs. 2024-08-30 10:28:16 +08:00
asdlokj1qpi23
33f32deb32 fix actions error 2024-08-29 18:45:59 +08:00
asdlokj1qpi23
258a64ed4f update doc 2024-08-29 17:49:37 +08:00
asdlokj1qpi23
7e16236595 update doc 2024-08-29 17:41:22 +08:00
TioaChan
644b9040b9 Add timezone env to Docker image (#776) 2024-08-27 17:34:01 +08:00
ak1ra
3f2281e284 Add clash.external_controller option in config file (#772) 2024-08-27 17:33:17 +08:00
SpadeLushen
0c11565cc9 Use Proxy.Host as alternative tls.server_name in sing-box to support Trojan's sni (#777)
Co-authored-by: Spade Lushen <7971040+SpadeLushen@users.noreply.github.com>
2024-08-27 17:33:02 +08:00
asdlokj1qpi23
4e6e25c710 Fix short-id issues.Add udp and packet-encoding config for vless.(#33) 2024-07-26 13:16:08 +08:00
asdlokj1qpi23
7dec83d529 Fix alpn issues.(#30) 2024-07-25 10:53:56 +08:00
asdlokj1qpi23
c4aa8c5b5e Fix bug.(#30) 2024-07-23 19:25:41 +08:00
asdlokj1qpi23
e22f043213 Resolve the priority issue with SCV,UDP parameters.(#29) 2024-07-19 11:30:04 +08:00
asdlokj1qpi23
e9c39481df Add insecure for tuic in singbox. 2024-07-18 09:28:13 +08:00
asdlokj1qpi23
6854ea4923 Fix windows compilation error.(#26) 2024-07-17 14:34:19 +08:00
asdlokj1qpi23
dc5c13c76c Fix windows compilation error. 2024-07-17 14:33:44 +08:00
asdlokj1qpi23
5f644b0b08 Change windows script. 2024-07-17 14:19:06 +08:00
asdlokj1qpi23
73352ecb43 Change windows script. 2024-07-17 11:26:07 +08:00
asdlokj1qpi23
34adb36029 Change windows script. 2024-07-17 11:17:26 +08:00
asdlokj1qpi23
311c696c1d Change windows script. 2024-07-17 11:06:47 +08:00
asdlokj1qpi23
33660d7f1b Change windows script. 2024-07-17 10:44:49 +08:00
asdlokj1qpi23
0844ebcae7 Change windows script. 2024-07-16 17:38:01 +08:00
asdlokj1qpi23
27e82ca60c Change windows script. 2024-07-16 17:29:33 +08:00
asdlokj1qpi23
bd06896454 Change windows script. 2024-07-16 17:13:22 +08:00
asdlokj1qpi23
72ea8a098f Change windows script. 2024-07-16 16:55:22 +08:00
asdlokj1qpi23
456fc328d5 Change windows script. 2024-07-16 16:45:41 +08:00
asdlokj1qpi23
19fcccf7f8 Change windows script. 2024-07-16 16:36:49 +08:00
asdlokj1qpi23
e3101cfa5e Change windows script. 2024-07-16 16:16:33 +08:00
asdlokj1qpi23
198fe253d1 Change scripts toml11 version. 2024-07-16 15:59:12 +08:00
asdlokj1qpi23
3589cfd615 Fix windows sh remove curl and test. 2024-07-16 15:28:00 +08:00
asdlokj1qpi23
c204199477 Fix windows sh. 2024-07-16 14:55:05 +08:00
asdlokj1qpi23
dbba931701 Fix bugs for tuic in Clash.(#23) 2024-07-16 14:22:28 +08:00
asdlokj1qpi23
ee9b239e21 Fix bugs for tuic in Singbox.(#23) 2024-07-15 09:33:54 +08:00
asdlokj1qpi23
c56685fd40 Add TUIC protocol support to Clash and Singbox.(#23) 2024-07-12 21:56:29 +08:00
asdlokj1qpi23
3b2a2632d9 Fix vless bug for Quanx.(#16) 2024-07-12 15:41:44 +08:00
asdlokj1qpi23
c359424242 fix build issue. 2024-06-27 17:10:16 +08:00
asdlokj1qpi23
4d0ed9a105 v0.9.5 2024-06-27 15:16:27 +08:00
asdlokj1qpi23
63eee92062 Edit docs. 2024-06-25 16:38:43 +08:00
asdlokj1qpi23
b9b864cf51 Hy2 supports obtaining port hopping parameters from a link. 2024-06-19 14:56:59 +08:00
asdlokj1qpi23
bdd6bbf67a Fix Issue.Add default value.(#22) 2024-06-19 10:41:55 +08:00
asdlokj1qpi23
8a18d3564b Fix Issue.(#22) 2024-06-17 11:28:12 +08:00
asdlokj1qpi23
2ee7c3aa04 Fix Actions Issue.(#22) 2024-06-14 09:30:37 +08:00
asdlokj1qpi23
598f6ac414 Fix Bug.(#22) 2024-06-13 17:30:34 +08:00
asdlokj1qpi23
6c296bfbf2 Add Hy2 for Loon.(#22) 2024-06-13 17:29:22 +08:00
asdlokj1qpi23
43fc751a2d fix bugs.(#16) 2024-05-22 09:41:37 +08:00
asdlokj1qpi23
99c1ef8b1a Support vless for quanx.(#16) 2024-05-17 09:59:48 +08:00
asdlokj1qpi23
53b561bce7 Fix github actions. 2024-05-09 16:50:20 +08:00
asdlokj1qpi23
469feaf0f5 Fix github actions. 2024-05-09 16:34:20 +08:00
asdlokj1qpi23
0895a16876 Fix the bug related to certificate validation in the Hysteria2 protocol.(#17) 2024-05-09 15:34:06 +08:00
TAKO
6974910734 Update Flag category (#744)
* Update emoji.toml

* Update emoji.txt
2024-04-18 15:47:39 +08:00
Tindy X
0c8574755a Enhancements
Fix not properly handling data from multipart-form POST (#739).
Fix not cleaning up request parameters when generating profiles (#741).
2024-04-09 01:11:29 +08:00
Tindy X
b9ad0c2ee2 Bump version to v0.9.0 2024-04-08 16:31:25 +08:00
Tindy X
04ac98725c Add clash_api to default sing-box config base 2024-04-08 16:21:29 +08:00
Tindy X
6af2c56fc8 Do not add check-interval and tolerance to SSID groups in QuanX configs 2024-04-06 21:30:10 +08:00
Tindy X
fb6a830d7b Add lhie1 rules to auto update config 2024-04-06 19:21:00 +08:00
Tindy X
b82d49200d Fix update_rules checkout branch 2024-04-06 19:04:51 +08:00
Tindy X
40ba3fd970 Update rules updater script 2024-04-06 18:56:52 +08:00
Tindy X
1f57413025 Fix Linux self-hosted build 2024-04-05 21:48:03 +08:00
Tindy X
b228255d3b Update build script 2024-04-05 21:46:04 +08:00
Tindy X
55e765e7f9 Fix broken string split (#736 #737 #738) 2024-04-05 14:55:24 +08:00
Tindy X
535d1d01e1 Fix "Profile not found" when generating artifact (#719) 2024-04-03 19:55:38 +08:00
Tindy X
7fdba81f2c Fix implementation of getting random string (#726) 2024-04-03 19:43:33 +08:00
Tindy X
6c38710312 Add missing libraries 2024-04-03 19:16:13 +08:00
Tindy X
eeffa0f544 Use brew provided path for libraries on macOS 2024-04-03 19:13:12 +08:00
Tindy X
73da1a87ad Run with sudo when building for macOS 2024-04-03 18:57:30 +08:00
Tindy X
670544cfb1 Add macOS ARM build 2024-04-03 18:50:35 +08:00
Tindy X
4864a6b13c Support setting output style for proxy groups in Clash configs (#734) 2024-04-03 18:07:12 +08:00
Chi Zhang
cb15d568c0 Fix missing classical rulesets when exporting Clash configs with expand=false (#715)
* 尝试修正缺少RULE-SET问题
2024-04-03 17:15:35 +08:00
Tindy X
0f2cefd537 Enhancements
Read template_args from root in TOML preferences (#717).
Make max_workers work for httplib.
Fix implementation of str_icase_map for HTTP headers.
2024-04-03 17:09:21 +08:00
Tindy X
9e66b07251 Force delete 2024-04-03 16:45:05 +08:00
Tindy X
624f5cd120 Clean up digests before creating new image digest 2024-04-03 16:40:41 +08:00
Tindy X
c711f1ad05 Update Docker build workflow 2024-04-03 16:24:31 +08:00
Tindy X
88635b6ed8 Fix build error 2024-04-03 16:08:19 +08:00
Tindy X
0cb4053f8d Fix build error 2024-04-03 16:01:59 +08:00
Tindy X
fb2aca3237 * Fix Docker build 2024-04-03 15:51:20 +08:00
SummonHIM
37c4e13071 Add UA of Clash Verge to auto target (#713) 2024-04-02 18:37:09 +08:00
moexiami
623ffbb23f Set most node_pref settings to indeterminate by default (#728)
Settings within node_pref should be established with a thorough understanding of the subscription sources' configurations.
Additionally, defaulting skip_cert_verify_flag to true exposes security risks.

Since pref.example.toml serves as the default configuration file, it is suggested to reset these settings. Also moving us toward Secure-by-Default.

Signed-off-by: moexiami <i@f2light.com>
2024-04-02 18:34:50 +08:00
aylz10
be2de49360 Fix bug of request header forwarding (#709)
* Fix bug of request header forwarding

* Replace insert(make_pair()) with emplace()

---------

Co-authored-by: Tindy X <49061470+tindy2013@users.noreply.github.com>
2024-04-02 18:34:33 +08:00
asdlokj1qpi23
a8292b1fc6 Add support for Hysteria2 ports. 2024-03-13 18:12:36 +08:00
asdlokj1qpi23
1ff018c47b update docker actions 2024-03-13 10:23:15 +08:00
asdlokj1qpi23
6227eb4e7d update docker actions 2024-03-13 09:34:17 +08:00
asdlokj1qpi23
54c8e65c70 update docker actions 2024-03-13 09:25:03 +08:00
asdlokj1qpi23
b90e63b506 fix string_icase_map.(#10) 2024-03-12 10:36:33 +08:00
asdlokj1qpi23
185e3893bf To add custom certificate configuration for HY2 protocol.(#7) 2024-01-29 19:20:59 +08:00
asdlokj1qpi23
5a4049af89 When adding Surge as a target, support for hysteria2.(#6) 2024-01-24 14:45:17 +08:00
asdlokj1qpi23
c842defea8 Fix the conversion of TLS-related issues when Singbox is used as the source. Fix the issue of missing SNI in Trojan.(#4) 2024-01-03 09:59:25 +08:00
asdlokj1qpi23
e26eaf0bf5 Fix the issue of missing sni parameters in vless, hysteria, and hysteria2. Fix the problem of dirty data during Singbox conversion. (#4) 2024-01-02 17:19:13 +08:00
asdlokj1qpi23
766bdcd6e1 Fix the issue of incorrect conversion of VLESS reality in Singbox as the source. Fix the issue of missing SS nodes with the obfs type when converting to Singbox. (#4) 2024-01-02 11:36:00 +08:00
asdlokj1qpi23
897dc5ed43 fix singbox parser bug.(#4) 2023-12-30 19:18:30 +08:00
asdlokj1qpi23
7bd6670448 change README.md 2023-12-29 19:31:47 +08:00
asdlokj1qpi23
7af3bf1794 Include Singbox as a source.(#4) 2023-12-29 18:59:20 +08:00
asdlokj1qpi23
359d9794a8 Add singbox parser vmess.Change README.md 2023-12-28 15:39:27 +08:00
asdlokj1qpi23
089f782177 Add singbox parser function. 2023-12-28 14:10:31 +08:00
asdlokj1qpi23
75023b028e fix stash vmess uuid issue. 2023-12-26 11:06:01 +08:00
asdlokj1qpi23
322924f24a fix actions issues 2023-12-25 12:44:00 +08:00
asdlokj1qpi23
04a2c24904 fix actions issues 2023-12-25 12:38:55 +08:00
asdlokj1qpi23
e80ce5833c add arm test 2023-12-25 11:33:22 +08:00
asdlokj1qpi23
31ba5373f0 add arm test 2023-12-25 11:10:37 +08:00
asdlokj1qpi23
d3801b7951 add arm test 2023-12-25 11:09:32 +08:00
asdlokj1qpi23
31775a91a8 add arm test 2023-12-25 11:01:34 +08:00
asdlokj1qpi23
af4dd857a8 Revert "fix vless short_id issue.(#1)"
This reverts commit 686f6b3517.
2023-12-25 11:00:27 +08:00
asdlokj1qpi23
686f6b3517 fix vless short_id issue.(#1) 2023-12-25 11:00:02 +08:00
asdlokj1qpi23
ebad0e96f7 fix vless short_id issue.(#1) 2023-12-25 10:51:21 +08:00
asdlokj1qpi23
927c828a27 Hy1 add ports support for clash export. 2023-12-25 10:22:33 +08:00
asdlokj1qpi23
13a372511b Hy1 add ports support. 2023-12-25 10:19:50 +08:00
Tindy X
eef5328506 Enhancements
Refine libcurl logs.
Do not retry web request on API mode.
Optimize codes.
2023-12-22 14:46:52 +08:00
asdlokj1qpi23
119df56f35 clean useless code. 2023-12-22 10:32:09 +08:00
asdlokj1qpi23
0672bd11cd Add auth-str for export Clash. 2023-12-22 10:23:44 +08:00
asdlokj1qpi23
f4de5097a6 remove clash api 2023-12-22 09:48:22 +08:00
asdlokj1qpi23
cb36b431ce Update singbox.json for clash API 2023-12-22 09:47:04 +08:00
asdlokj1qpi23
d5b3f920b8 fix path bug for vless websocket 2023-12-22 09:34:50 +08:00
asdlokj1qpi23
69e35d6657 add insecure for hy 2023-12-21 20:24:12 +08:00
asdlokj1qpi23
936ff011e9 add insecure for hy2 2023-12-21 20:19:57 +08:00
asdlokj1qpi23
0cda1641d3 update version.h 2023-12-21 19:50:10 +08:00
42 changed files with 2480 additions and 1179 deletions

View File

@@ -7,6 +7,7 @@ body:
value: |
遇到问题请先尝试使用[Action](https://github.com/tindy2013/subconverter/actions)中的最新版本
如果是使用公共转换服务中遇到的问题,请先联系服务的提供者。
Please note that if the bug report does not include reproduction steps, configuration files, or relevant URL content, it will not be considered.
- type: checkboxes
id: version-check
attributes:

View File

@@ -1,5 +1,5 @@
name: GitHub CI
on:
on:
push:
branches: [ master ]
tags:
@@ -7,215 +7,144 @@ on:
workflow_dispatch:
pull_request:
concurrency:
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
jobs:
linux32_build:
name: Linux x86 Build
runs-on: ubuntu-latest
linux_build:
strategy:
matrix:
include:
- arch: x86
artifact: subconverter_linux32
os: ubuntu-latest
- arch: amd64
artifact: subconverter_linux64
os: ubuntu-latest
- arch: armv7
artifact: subconverter_armv7
os: ubuntu-latest
- arch: aarch64
artifact: subconverter_aarch64
os: ubuntu-latest
runs-on: ${{ matrix.os }}
name: Linux ${{ matrix.arch }} Build
steps:
- uses: actions/checkout@v3
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: docker run --rm -v $GITHUB_WORKSPACE:/root/workdir multiarch/alpine:x86-latest-stable /bin/sh -c "apk add bash git nodejs npm && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
- name: Upload
uses: actions/upload-artifact@v3
with:
name: subconverter_linux32
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: tar czf subconverter_linux32.tar.gz subconverter
- name: Draft Release
uses: softprops/action-gh-release@v1
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
with:
files: subconverter_linux32.tar.gz
draft: true
linux64_build:
name: Linux x86_64 Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: docker run --rm -v $GITHUB_WORKSPACE:/root/workdir multiarch/alpine:amd64-latest-stable /bin/sh -c "apk add bash git nodejs npm && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
- name: Upload
uses: actions/upload-artifact@v3
with:
name: subconverter_linux64
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: tar czf subconverter_linux64.tar.gz subconverter
- name: Draft Release
uses: softprops/action-gh-release@v1
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
with:
files: subconverter_linux64.tar.gz
draft: true
# armv7_build:
# name: Linux armv7 Build
# runs-on: [self-hosted, linux, ARM]
# steps:
# - uses: actions/checkout@v3
# - name: Add commit id into version
# if: ${{ !startsWith(github.ref, 'refs/tags/') }}
# run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
# - name: Build
# run: docker run --rm -v $GITHUB_WORKSPACE:/root/workdir multiarch/alpine:armv7-latest-stable /bin/sh -c "apk add bash git nodejs npm && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
# - name: Upload
# uses: actions/upload-artifact@v3
# with:
# name: subconverter_armv7
# path: subconverter/
# - name: Package Release
# if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
# run: tar czf subconverter_armv7.tar.gz subconverter
# - name: Draft Release
# uses: softprops/action-gh-release@v1
# if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
# with:
# files: subconverter_armv7.tar.gz
# draft: true
#
# aarch64_build:
# name: Linux aarch64 Build
# runs-on: [self-hosted, linux, ARM64]
# steps:
# - uses: actions/checkout@v3
# - name: Add commit id into version
# if: ${{ !startsWith(github.ref, 'refs/tags/') }}
# run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
# - name: Build
# run: docker run --rm -v $GITHUB_WORKSPACE:/root/workdir multiarch/alpine:aarch64-latest-stable /bin/sh -c "apk add bash git nodejs npm && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
# - name: Upload
# uses: actions/upload-artifact@v3
# with:
# name: subconverter_aarch64
# path: subconverter/
# - name: Package Release
# if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
# run: tar czf subconverter_aarch64.tar.gz subconverter
# - name: Draft Release
# uses: softprops/action-gh-release@v1
# if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
# with:
# files: subconverter_aarch64.tar.gz
# draft: true
- name: Checkout base
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: docker run --rm -v $GITHUB_WORKSPACE:/root/workdir multiarch/alpine:${{ matrix.arch }}-latest-stable /bin/sh -c "apk add bash git nodejs npm && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
- name: Upload
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: tar czf ${{ matrix.artifact }}.tar.gz subconverter
- name: Draft Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
uses: softprops/action-gh-release@v2
with:
files: ${{ matrix.artifact }}.tar.gz
draft: true
macos_build:
name: macOS Build
runs-on: macos-latest
strategy:
matrix:
include:
- arch: x86
artifact: subconverter_darwin64
os: macos-13
- arch: arm
artifact: subconverter_darwinarm
os: macos-14
runs-on: ${{ matrix.os }}
name: macOS ${{ matrix.arch }} Build
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i -e 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: bash scripts/build.macos.release.sh
- name: Upload
uses: actions/upload-artifact@v3
with:
name: subconverter_darwin64
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: tar czf subconverter_darwin64.tar.gz subconverter
- name: Draft Release
uses: softprops/action-gh-release@v1
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
with:
files: subconverter_darwin64.tar.gz
draft: true
- name: Checkout base
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i -e 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: bash scripts/build.macos.release.sh
- name: Upload
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: tar czf ${{ matrix.artifact }}.tar.gz subconverter
- name: Draft Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
uses: softprops/action-gh-release@v2
with:
files: ${{ matrix.artifact }}.tar.gz
draft: true
windows64_build:
name: Windows x86_64 Build
windows_build:
strategy:
matrix:
include:
- arch: x86
artifact: subconverter_win32
env: i686
msystem: MINGW32
- arch: amd64
artifact: subconverter_win64
env: x86_64
msystem: MINGW64
runs-on: windows-latest
name: Windows ${{ matrix.arch }} Build
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- uses: actions/setup-node@v3
with:
node-version: '16'
- uses: msys2/setup-msys2@v2
with:
update: true
install: base-devel git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-pcre2 patch
msystem: MINGW64
path-type: inherit
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: bash scripts/build.windows.release.sh
- name: Upload
uses: actions/upload-artifact@v3
with:
name: subconverter_win64
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: 7z a subconverter_win64.7z subconverter/
- name: Draft Release
uses: softprops/action-gh-release@v1
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
with:
files: subconverter_win64.7z
draft: true
windows32_build:
name: Windows x86 Build
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- uses: actions/setup-node@v3
with:
node-version: '16'
- uses: msys2/setup-msys2@v2
with:
update: true
install: base-devel git mingw-w64-i686-gcc mingw-w64-i686-cmake mingw-w64-i686-pcre2 patch
msystem: MINGW32
path-type: inherit
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: bash scripts/build.windows.release.sh
- name: Upload
uses: actions/upload-artifact@v3
with:
name: subconverter_win32
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: 7z a subconverter_win32.7z subconverter/
- name: Draft Release
uses: softprops/action-gh-release@v1
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
with:
files: subconverter_win32.7z
draft: true
- name: Checkout base
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '16'
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
update: true
install: base-devel git mingw-w64-${{ matrix.env }}-gcc mingw-w64-${{ matrix.env }}-cmake mingw-w64-${{ matrix.env }}-pcre2 patch
msystem: ${{ matrix.msystem }}
path-type: inherit
- name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
- name: Build
run: bash scripts/build.windows.release.sh
- name: Upload
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: subconverter/
- name: Package Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
run: 7z a ${{ matrix.artifact }}.7z subconverter/
- name: Draft Release
if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/') }}
uses: softprops/action-gh-release@v2
with:
files: ${{ matrix.artifact }}.7z
draft: true

View File

@@ -9,328 +9,122 @@ concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
env:
REGISTRY_IMAGE: asdlokj1qpi23/subconverter
jobs:
amd64_build:
name: Build AMD64 Image
runs-on: ubuntu-latest
steps:
- name: Checkout base
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Get commit SHA
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Build and export
id: build
if: github.ref == 'refs/heads/master'
uses: docker/build-push-action@v3
with:
platforms: linux/amd64
context: scripts/
tags: asdlokj1qpi23/subconverter:latest
build-args: |
SHA=${{ steps.vars.outputs.sha_short }}
outputs: type=image,push=true
- name: Replace tag without `v`
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v6
id: version
with:
script: |
return context.payload.ref.replace(/\/?refs\/tags\/v/, '')
result-encoding: string
- name: Build release and export
id: build_rel
if: startsWith(github.ref, 'refs/tags/')
uses: docker/build-push-action@v3
with:
platforms: linux/amd64
context: scripts/
tags: asdlokj1qpi23/subconverter:${{steps.version.outputs.result}}
outputs: type=image,push=true
- name: Save digest
if: github.ref == 'refs/heads/master'
run: echo ${{ steps.build.outputs.digest }} > /tmp/digest.txt
- name: Save release digest
if: startsWith(github.ref, 'refs/tags/')
run: echo ${{ steps.build_rel.outputs.digest }} > /tmp/digest.txt
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: digest_amd64
path: /tmp/digest.txt
x86_build:
name: Build x86 Image
runs-on: ubuntu-latest
steps:
- name: Checkout base
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Get commit SHA
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Build and export
id: build
if: github.ref == 'refs/heads/master'
uses: docker/build-push-action@v3
with:
platforms: linux/386
context: scripts/
tags: asdlokj1qpi23/subconverter:latest-x86
build-args: |
SHA=${{ steps.vars.outputs.sha_short }}
outputs: type=image,push=true
- name: Replace tag without `v`
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v6
id: version
with:
script: |
return context.payload.ref.replace(/\/?refs\/tags\/v/, '')
result-encoding: string
- name: Build release and export
id: build_rel
if: startsWith(github.ref, 'refs/tags/')
uses: docker/build-push-action@v3
with:
platforms: linux/386
context: scripts/
tags: asdlokj1qpi23/subconverter:${{steps.version.outputs.result}}-x86
outputs: type=image,push=true
- name: Save digest
if: github.ref == 'refs/heads/master'
run: echo ${{ steps.build.outputs.digest }} > /tmp/digest.txt
- name: Save release digest
if: startsWith(github.ref, 'refs/tags/')
run: echo ${{ steps.build_rel.outputs.digest }} > /tmp/digest.txt
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: digest_386
path: /tmp/digest.txt
# armv7_build:
# name: Build ARMv7 Image
# runs-on: [self-hosted, linux, ARM]
# steps:
# - name: Checkout base
# uses: actions/checkout@v3
# with:
# fetch-depth: 0
#
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v2
#
# - name: Docker login
# uses: docker/login-action@v2
# with:
# username: ${{ secrets.DOCKER_USERNAME }}
# password: ${{ secrets.DOCKER_PASSWORD }}
#
# - name: Get commit SHA
# id: vars
# run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
#
# - name: Build and export
# id: build
# if: github.ref == 'refs/heads/master'
# uses: docker/build-push-action@v3
# with:
# platforms: linux/arm/v7
# context: scripts/
# tags: asdlokj1qpi23/subconverter:latest-armv7
# build-args: |
# SHA=${{ steps.vars.outputs.sha_short }}
# THREADS=4
# outputs: type=image,push=true
#
# - name: Replace tag without `v`
# if: startsWith(github.ref, 'refs/tags/')
# uses: actions/github-script@v6
# id: version
# with:
# script: |
# return context.payload.ref.replace(/\/?refs\/tags\/v/, '')
# result-encoding: string
#
# - name: Build release and export
# id: build_rel
# if: startsWith(github.ref, 'refs/tags/')
# uses: docker/build-push-action@v3
# with:
# platforms: linux/arm/v7
# context: scripts/
# tags: asdlokj1qpi23/subconverter:${{steps.version.outputs.result}}-armv7
# build-args: |
# THREADS=4
# outputs: type=image,push=true
#
# - name: Save digest
# if: github.ref == 'refs/heads/master'
# run: echo ${{ steps.build.outputs.digest }} > /tmp/digest.txt
#
# - name: Save release digest
# if: startsWith(github.ref, 'refs/tags/')
# run: echo ${{ steps.build_rel.outputs.digest }} > /tmp/digest.txt
#
# - name: Upload artifact
# uses: actions/upload-artifact@v3
# with:
# name: digest_armv7
# path: /tmp/digest.txt
#
# arm64_build:
# name: Build ARM64 Image
# runs-on: [self-hosted, linux, ARM64]
# steps:
# - name: Checkout base
# uses: actions/checkout@v3
# with:
# fetch-depth: 0
#
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v2
#
# - name: Docker login
# uses: docker/login-action@v2
# with:
# username: ${{ secrets.DOCKER_USERNAME }}
# password: ${{ secrets.DOCKER_PASSWORD }}
#
# - name: Get commit SHA
# id: vars
# run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
#
# - name: Build and export
# id: build
# if: github.ref == 'refs/heads/master'
# uses: docker/build-push-action@v3
# with:
# platforms: linux/arm64
# context: scripts/
# tags: asdlokj1qpi23/subconverter:latest-arm64
# build-args: |
# SHA=${{ steps.vars.outputs.sha_short }}
# THREADS=4
# outputs: type=image,push=true
#
# - name: Replace tag without `v`
# if: startsWith(github.ref, 'refs/tags/')
# uses: actions/github-script@v6
# id: version
# with:
# script: |
# return context.payload.ref.replace(/\/?refs\/tags\/v/, '')
# result-encoding: string
#
# - name: Build release and export
# id: build_rel
# if: startsWith(github.ref, 'refs/tags/')
# uses: docker/build-push-action@v3
# with:
# platforms: linux/arm64
# context: scripts/
# tags: asdlokj1qpi23/subconverter:${{steps.version.outputs.result}}-arm64
# build-args: |
# THREADS=4
# outputs: type=image,push=true
#
# - name: Save digest
# if: github.ref == 'refs/heads/master'
# run: echo ${{ steps.build.outputs.digest }} > /tmp/digest.txt
#
# - name: Save release digest
# if: startsWith(github.ref, 'refs/tags/')
# run: echo ${{ steps.build_rel.outputs.digest }} > /tmp/digest.txt
#
# - name: Upload artifact
# uses: actions/upload-artifact@v3
# with:
# name: digest_arm64
# path: /tmp/digest.txt
build:
name: Build
# needs: [amd64_build, x86_build, armv7_build, arm64_build]
needs: [amd64_build, x86_build]
runs-on: ubuntu-latest
strategy:
matrix:
include:
- platform: linux/amd64
os: ubuntu-latest
- platform: linux/386
os: ubuntu-latest
- platform: linux/arm/v7
os: ubuntu-latest
- platform: linux/arm64
os: ubuntu-latest
runs-on: ${{ matrix.os }}
name: Build ${{ matrix.platform }} Image
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Checkout base
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
config-inline: |
[worker.oci]
max-parallelism = 1
uses: docker/setup-buildx-action@v3
- name: Download artifact
uses: actions/download-artifact@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
path: /tmp/images/
images: ${{ env.REGISTRY_IMAGE }}
tags: |
type=semver,pattern={{version}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Docker login
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Replace tag without `v`
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v6
id: version
with:
script: |
return context.payload.ref.replace(/\/?refs\/tags\/v/, '')
result-encoding: string
- name: Merge and push manifest on master branch
- name: Get commit SHA
if: github.ref == 'refs/heads/master'
run: python scripts/merge_manifest.py
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Merge and push manifest on release
if: startsWith(github.ref, 'refs/tags/')
run: python scripts/merge_manifest.py ${{steps.version.outputs.result}}
- name: Build and export
id: build
uses: docker/build-push-action@v5
with:
platforms: ${{ matrix.platform }}
context: scripts/
labels: ${{ steps.meta.outputs.labels }}
build-args: |
SHA=${{ steps.vars.outputs.sha_short }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
rm -rf /tmp/digests
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: digest-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
name: Merge
needs: build
runs-on: ubuntu-latest
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digest-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
tags: |
type=semver,pattern={{version}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}

6
.gitignore vendored
View File

@@ -3,3 +3,9 @@ subconverter.exe
cmake-build-debug
.idea
base/cache
scripts/quickjspp
scripts/yaml-cpp
.DS_Store
src/.DS_Store
build

View File

@@ -1,9 +1,13 @@
PROJECT(subconverter LANGUAGES CXX)
SET(BUILD_TARGET_NAME ${PROJECT_NAME})
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
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)
SET(CMAKE_BUILD_TYPE Release)
ENDIF()

View File

@@ -2,10 +2,12 @@
Utility to convert between various proxy subscription formats.
[![Build Status](https://github.com/asdlokj1qpi23/subconverter/actions/workflows/build.yml/badge.svg)](https://github.com/asdlokj1qpi23/subconverter/actions)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/asdlokj1qpi23/subconverter.svg)](https://github.com/asdlokj1qpi23/subconverter/tags)
[![GitHub release](https://img.shields.io/github/release/asdlokj1qpi23/subconverter.svg)](https://github.com/asdlokj1qpi23/subconverter/releases)
[![GitHub license](https://img.shields.io/github/license/asdlokj1qpi23/subconverter.svg)](https://github.com/tindy2013/subconverter/blob/master/LICENSE)
original git: https://github.com/asdlokj1qpi23/subconverter
[![Build Status](https://github.com/asdlokj1qpi233/subconverter/actions/workflows/docker.yml/badge.svg)](https://github.com/asdlokj1qpi233/subconverter/actions)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/asdlokj1qpi233/subconverter.svg)](https://github.com/asdlokj1qpi23/subconverter/tags)
[![GitHub release](https://img.shields.io/github/release/asdlokj1qpi233/subconverter.svg)](https://github.com/asdlokj1qpi233/subconverter/releases)
[![GitHub license](https://img.shields.io/github/license/asdlokj1qpi233/subconverter.svg)](https://github.com/tindy2013/subconverter/blob/master/LICENSE)
[Docker README](https://github.com/asdlokj1qpi23/subconverter/blob/master/README-docker.md)
@@ -59,9 +61,11 @@ services:
| Surge 2 | ✓ | ✓ | surge&ver=2 |
| Surge 3 | ✓ | ✓ | surge&ver=3 |
| Surge 4 | ✓ | ✓ | surge&ver=4 |
| Surge 5 | ✓ | ✓ | surge&ver=5 |
| V2Ray | ✓ | ✓ | v2ray |
| Telegram-liked HTTP/Socks 5 links | ✓ | × | Only as source |
| Singbox | × | ✓ | singbox |
| Singbox | | ✓ | singbox |
Notice:
1. Shadowrocket users should use `ss`, `ssr` or `v2ray` as target.

View File

@@ -5,7 +5,7 @@ socks-port: {{ default(global.clash.socks_port, "7891") }}
allow-lan: {{ default(global.clash.allow_lan, "true") }}
mode: Rule
log-level: {{ default(global.clash.log_level, "info") }}
external-controller: :9090
external-controller: {{ default(global.clash.external_controller, "127.0.0.1:9090") }}
{% if default(request.clash.dns, "") == "1" %}
dns:
enable: true
@@ -378,7 +378,16 @@ enhanced-mode-by-rule = true
"rules": [],
"auto_detect_interface": true
},
"experimental": {}
"experimental": {
"cache_file": {
"enabled": true,
"store_fakeip": true
},
"clash_api": {
"external_controller": "{{ default(global.clash.external_controller, "127.0.0.1:9090") }}",
"external_ui": "dashboard"
}
}
}
{% endif %}

View File

@@ -100,5 +100,14 @@
"rules": [],
"auto_detect_interface": true
},
"experimental": {}
"experimental": {
"cache_file": {
"enabled": true,
"store_fakeip": true
},
"clash_api": {
"external_controller": "127.0.0.1:9090",
"external_ui": "dashboard"
}
}
}

View File

@@ -109,13 +109,14 @@ filter_deprecated_nodes=false
append_sub_userinfo=true
clash_use_new_field_name=true
;Generate style of the proxies section of Clash subscriptions.
;Generate style of the proxies and proxy groups section of Clash subscriptions.
;Supported styles: block, flow, compact
;Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
; key: value - {name: name2, key: value}
; - name: name2
; key: value
clash_proxies_style=flow
clash_proxy_groups_style=block
;add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
singbox_add_clash_modes=true
@@ -232,6 +233,7 @@ clash.http_port=7890
clash.socks_port=7891
clash.allow_lan=true
clash.log_level=info
clash.external_controller=127.0.0.1:9090
singbox.allow_lan=true
singbox.mixed_port=2080

View File

@@ -117,10 +117,10 @@ match = '^Smart Access expire: (\d+)/(\d+)/(\d+)$'
replace = '$1:$2:$3:0:0:0'
[node_pref]
udp_flag = true
tcp_fast_open_flag = false
skip_cert_verify_flag = true
tls13_flag = false
#udp_flag = false
#tcp_fast_open_flag = false
#skip_cert_verify_flag = false
#tls13_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.
@@ -135,13 +135,14 @@ filter_deprecated_nodes = false
append_sub_userinfo = true
clash_use_new_field_name = true
# Generate style of the proxies section of Clash subscriptions.
# Generate style of the proxies and proxy groups section of Clash subscriptions.
# Supported styles: block, flow, compact
# Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}]
# key: value - {name: name2, key: value}
# - name: name2
# key: value
clash_proxies_style = "flow"
clash_proxy_groups_style = "block"
# add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
singbox_add_clash_modes = true
@@ -243,6 +244,10 @@ value = "true"
key = "clash.log_level"
value = "info"
[[template.globals]]
key = "clash.external_controller"
value = "127.0.0.1:9090"
[[template.globals]]
key = "singbox.allow_lan"
value = "true"

View File

@@ -50,6 +50,7 @@ node_pref:
append_sub_userinfo: true
clash_use_new_field_name: true
clash_proxies_style: flow
clash_proxy_groups_style: block
singbox_add_clash_modes: true
rename_node:
# - {match: "\\(?((x|X)?(\\d+)(\\.?\\d+)?)((\\s?倍率?)|(x|X))\\)?", replace: "$1x"}
@@ -108,9 +109,10 @@ template:
- {key: clash.socks_port, value: 7891}
- {key: clash.allow_lan, value: true}
- {key: clash.log_level, value: info}
- {key: clash.external_controller, value: '127.0.0.1:9090'}
- {key: singbox.allow_lan, value: true}
- {key: singbox.mixed_port, value: 2080}
aliases:
- {uri: /v, target: /version}
- {uri: /clash, target: "/sub?target=clash"}

View File

@@ -3,15 +3,15 @@ match = "(?i:Bandwidth|expire|流量|时间|应急|过期)"
emoji = "🏳️‍🌈"
[[emoji]]
match = "(?i:\\bHK[G]?\\b|Hong.*?Kong|\\bHKT\\b|\\bHKBN\\b|\\bHGC\\b|\\bWTT\\b|\\bCMI\\b|[^-]港)"
match = "(?i:\\bHK[G]?\\d*\\b|Hong.*?Kong|\\bHKT\\b|\\bHKBN\\b|\\bHGC\\b|\\bWTT\\b|\\bCMI\\b|[^-]港)"
emoji = "🇭🇰"
[[emoji]]
match = "(?i:\\bTW[N]?\\b|Taiwan|新北|彰化|\\bCHT\\b|台湾|[^-]台|\\bHINET\\b)"
match = "(?i:\\bTW[N]?\\d*\\b|Taiwan|新北|彰化|\\bCHT\\b|台湾|[^-]台|\\bHINET\\b)"
emoji = "🇨🇳"
[[emoji]]
match = "(?i:\\bSG[P]?\\b|Singapore|新加坡|狮城|[^-]新)"
match = "(?i:\\bSG[P]?\\d*\\b|Singapore|新加坡|狮城|[^-]新)"
emoji = "🇸🇬"
[[emoji]]
@@ -19,15 +19,15 @@ match = "(尼日利亚|Nigeria)"
emoji = "🇳🇬"
[[emoji]]
match = "(?i:\\bJP[N]?\\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日)"
match = "(?i:\\bJP[N]?\\d*\\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日)"
emoji = "🇯🇵"
[[emoji]]
match = "(?i:\\bK[O]?R\\b|Korea|首尔|韩|韓)"
match = "(?i:(?<!North\\s)(\\bK[O]?R\\d*\\b|Korea|首尔|韩|韓))"
emoji = "🇰🇷"
[[emoji]]
match = "(?i:\\bUS[A]?\\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥)"
match = "(?i:\\bUS[A]?\\d*\\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥)"
emoji = "🇺🇸"
[[emoji]]
@@ -42,6 +42,10 @@ emoji = "🇦🇪"
match = "(阿尔巴尼亚|Albania)"
emoji = "🇦🇱"
[[emoji]]
match = "(南极|Antarctica)"
emoji = "🇦🇶"
[[emoji]]
match = "(Argentina|阿根廷)"
emoji = "🇦🇷"
@@ -51,7 +55,7 @@ match = "(Austria|Vienna|奥地利|维也纳)"
emoji = "🇦🇹"
[[emoji]]
match = "(?i:\\bAU[S]?\\b|Australia|Sydney|澳大利亚|澳洲|悉尼)"
match = "(?i:\\bAU[S]?\\d*\\b|Australia|Sydney|澳大利亚|澳洲|悉尼)"
emoji = "🇦🇺"
[[emoji]]
@@ -75,7 +79,7 @@ match = "(Brazil|Paulo|巴西|圣保罗)"
emoji = "🇧🇷"
[[emoji]]
match = "(?i:\\bCA[N]?\\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶)"
match = "(?i:\\bCA[N]?\\d*\\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶)"
emoji = "🇨🇦"
[[emoji]]
@@ -103,7 +107,7 @@ match = "(Czech|捷克)"
emoji = "🇨🇿"
[[emoji]]
match = "(?i:\\bDE[U]?\\b|Germany|法兰克福|德(国|意志)|中德|^德$)"
match = "(?i:\\bDE[U]?\\d*\\b|Germany|法兰克福|德(国|意志)|中德|^德$)"
emoji = "🇩🇪"
[[emoji]]
@@ -119,7 +123,7 @@ match = "(埃及|Egypt)"
emoji = "🇪🇬"
[[emoji]]
match = "(?i:\\bES[P]?\\b|Spain|西班牙)"
match = "(?i:\\bES[P]?\\d*\\b|Spain|西班牙)"
emoji = "🇪🇸"
[[emoji]]
@@ -131,11 +135,11 @@ match = "(Finland|Helsinki|芬兰|赫尔辛基)"
emoji = "🇫🇮"
[[emoji]]
match = "(?i:\\bFR[A]?\\b|France|Paris|法国|巴黎)"
match = "(?i:\\bFR[A]?\\d*\\b|France|Paris|法国|巴黎)"
emoji = "🇫🇷"
[[emoji]]
match = "(?i:\\bUK\\b|\\bGB[R]?\\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦)"
match = "(?i:\\bUK\\d*\\b|\\bGB[R]?\\d*\\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦)"
emoji = "🇬🇧"
[[emoji]]
@@ -171,7 +175,7 @@ match = "(马恩岛|Mann)"
emoji = "🇮🇲"
[[emoji]]
match = "(?i:\\bIN[D]?\\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德)"
match = "(?i:\\bIN[D]?\\d*\\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德)"
emoji = "🇮🇳"
[[emoji]]
@@ -179,11 +183,11 @@ match = "(伊朗|Iran)"
emoji = "🇮🇷"
[[emoji]]
match = "(?i:\\bIS[L]?\\b|Iceland|冰岛)"
match = "(?i:\\bIS[L]?\\d*\\b|Iceland|冰岛)"
emoji = "🇮🇸"
[[emoji]]
match = "(Italy|Milan|意大利|米兰)"
match = "(Italy|Italia|Milan|意大利|米兰)"
emoji = "🇮🇹"
[[emoji]]
@@ -202,7 +206,6 @@ emoji = "🇰🇬"
match = "(柬埔寨|Cambodia)"
emoji = "🇰🇭"
[[emoji]]
match = "(North.*?Korea|朝鲜)"
emoji = "🇰🇵"
@@ -231,6 +234,10 @@ emoji = "🇲🇩"
match = "(北马其顿|Macedonia)"
emoji = "🇲🇰"
[[emoji]]
match = "(缅甸|Myanmar)"
emoji = "🇲🇲"
[[emoji]]
match = "(蒙古|Монголулс|Mongolia)"
emoji = "🇲🇳"
@@ -248,7 +255,7 @@ match = "(Malaysia|马来|MY)"
emoji = "🇲🇾"
[[emoji]]
match = "(?i:\\bNL[D]?\\b|Netherlands|荷兰|阿姆斯特丹)"
match = "(?i:\\bNL[D]?\\d*\\b|Netherlands|荷兰|阿姆斯特丹)"
emoji = "🇳🇱"
[[emoji]]
@@ -260,7 +267,7 @@ match = "(新西兰|纽西兰|New Zealand)"
emoji = "🇳🇿"
[[emoji]]
match = "(Philippines|菲律宾)"
match = "(?i:\\bP[O]?H\\d*\\b|Philippines|菲律宾)"
emoji = "🇵🇭"
[[emoji]]
@@ -292,7 +299,7 @@ match = "(塞尔维亚|Serbia)"
emoji = "🇷🇸"
[[emoji]]
match = "(?i:\\bRU[S]?\\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄)"
match = "(?i:\\bRU[S]?\\d*\\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄)"
emoji = "🇷🇺"
[[emoji]]
@@ -320,7 +327,7 @@ match = "(突尼斯|Tunisia)"
emoji = "🇹🇳"
[[emoji]]
match = "(Turkey|土耳其|伊斯坦布尔)"
match = "(Turkey|Türkiye|土耳其|伊斯坦布尔)"
emoji = "🇹🇷"
[[emoji]]
@@ -364,4 +371,4 @@ emoji = "🇧🇩"
[[emoji]]
match = "(?i:\\bC[H]?N\\b|China|back|回国|中国[^-]|江苏[^-]|北京[^-]|上海[^-]|广州[^-]|深圳[^-]|杭州[^-]|常州[^-]|徐州[^-]|青岛[^-]|宁波[^-]|镇江[^-]|成都[^-]|河北[^-]|山西[^-]|辽宁[^-]|吉林[^-]|黑龙江[^-]|江苏[^-]|浙江[^-]|安徽[^-]|福建[^-]|江西[^-]|山东[^-]|河南[^-]|湖北[^-]|湖南[^-]|广东[^-]|海南[^-]|四川[^-]|贵州[^-]|云南[^-]|陕西[^-]|甘肃[^-]|青海[^-]|内蒙古[^-]|广西[^-]|西藏[^-]|宁夏[^-]|新疆[^-])"
emoji = "🇨🇳"
emoji = "🇨🇳"

View File

@@ -1,38 +1,39 @@
(?i:Bandwidth|expire|流量|时间|应急|过期),🏳️‍🌈
(?i:\bHK[G]?\b|Hong.*?Kong|\bHKT\b|\bHKBN\b|\bHGC\b|\bWTT\b|\bCMI\b|[^-]港),🇭🇰
(?i:\bTW[N]?\b|Taiwan|新北|彰化|\bCHT\b|台湾|[^-]台|\bHINET\b),🇨🇳
(?i:\bSG[P]?\b|Singapore|新加坡|狮城|[^-]新),🇸🇬
(?i:\bHK[G]?\d*\b|Hong.*?Kong|\bHKT\b|\bHKBN\b|\bHGC\b|\bWTT\b|\bCMI\b|[^-]港),🇭🇰
(?i:\bTW[N]?\d*\b|Taiwan|新北|彰化|\bCHT\b|台湾|[^-]台|\bHINET\b),🇨🇳
(?i:\bSG[P]?\d*\b|Singapore|新加坡|狮城|[^-]新),🇸🇬
(尼日利亚|Nigeria),🇳🇬
(?i:\bJP[N]?\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
(?i:\bK[O]?R\b|Korea|首尔|韩|韓),🇰🇷
(?i:\bUS[A]?\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
(?i:\bJP[N]?\d*\b|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
(?i:(?<!North\s)(\bK[O]?R\d*\b|Korea|首尔|韩|韓)),🇰🇷
(?i:\bUS[A]?\d*\b|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
(Ascension|阿森松),🇦🇨
(?i:\bUAE\b|Dubai|阿联酋|迪拜),🇦🇪
(阿尔巴尼亚|Albania),🇦🇱
(南极|Antarctica),🇦🇶
(Argentina|阿根廷),🇦🇷
(Austria|Vienna|奥地利|维也纳),🇦🇹
(?i:\bAU[S]?\b|Australia|Sydney|澳大利亚|澳洲|悉尼),🇦🇺
(?i:\bAU[S]?\d*\b|Australia|Sydney|澳大利亚|澳洲|悉尼),🇦🇺
(阿塞拜疆|Azerbaijan),🇦🇿
(波黑共和国|波士尼亚与赫塞哥维纳|Bosnia|Herzegovina),🇧🇦
(Belgium|比利时),🇧🇪
(保加利亚|Bulgaria),🇧🇬
(Brazil|Paulo|巴西|圣保罗),🇧🇷
(?i:\bCA[N]?\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶),🇨🇦
(?i:\bCA[N]?\d*\b|Canada|Toronto|Montreal|Vancouver|加拿大|蒙特利尔|温哥华|楓葉|枫叶),🇨🇦
(Switzerland|Zurich|瑞士|苏黎世),🇨🇭
(智利|Chile),🇨🇱
(Colombia|哥伦比亚),🇨🇴
(Costa Rica|哥斯达黎加),🇨🇷
(塞浦路斯|Cyprus),🇨🇾
(Czech|捷克),🇨🇿
(?i:\bDE[U]?\b|Germany|法兰克福|德(国|意志)|中德|^德$),🇩🇪
(?i:\bDE[U]?\d*\b|Germany|法兰克福|德(国|意志)|中德|^德$),🇩🇪
(?i:\bD[N]?K\b|Denmark|丹麦),🇩🇰
(爱沙尼亚|Estonia),🇪🇪
(埃及|Egypt),🇪🇬
(?i:\bES[P]?\b|Spain|西班牙),🇪🇸
(?i:\bES[P]?\d*\b|Spain|西班牙),🇪🇸
(Europe|欧洲),🇪🇺
(Finland|Helsinki|芬兰|赫尔辛基),🇫🇮
(?i:\bFR[A]?\b|France|Paris|法国|巴黎),🇫🇷
(?i:\bUK\b|\bGB[R]?\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦),🇬🇧
(?i:\bFR[A]?\d*\b|France|Paris|法国|巴黎),🇫🇷
(?i:\bUK\d*\b|\bGB[R]?\d*\b|England|United.*?Kingdom|London|英国|[^-]英|伦敦),🇬🇧
(希腊|Greece),🇬🇷
(格鲁吉亚|Georgia),🇬🇪
(克罗地亚|Croatia),🇭🇷
@@ -41,10 +42,10 @@
(Ireland|Dublin|爱尔兰|都柏林),🇮🇪
(Israel|以色列),🇮🇱
(马恩岛|Mann),🇮🇲
(?i:\bIN[D]?\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德),🇮🇳
(?i:\bIN[D]?\d*\b|India|Mumbai|印度|孟买|加尔各答|贾坎德|泰米尔纳德),🇮🇳
(伊朗|Iran),🇮🇷
(?i:\bIS[L]?\b|Iceland|冰岛),🇮🇸
(Italy|Milan|意大利|米兰),🇮🇹
(?i:\bIS[L]?\d*\b|Iceland|冰岛),🇮🇸
(Italy|Italia|Milan|意大利|米兰),🇮🇹
(约旦|Jordan),🇯🇴
(肯尼亚|Kenya),🇰🇪
(吉尔吉斯斯坦|Kyrgyzstan),🇰🇬
@@ -56,14 +57,15 @@
(拉脱维亚|Latvia),🇱🇻
(Moldova|摩尔多瓦),🇲🇩
(北马其顿|Macedonia),🇲🇰
(缅甸|Myanmar),🇲🇲
(蒙古|Монголулс|Mongolia),🇲🇳
(Macao|澳门|\bCTM\b),🇲🇴
(墨西哥|Mexico),🇲🇽
(Malaysia|马来|MY),🇲🇾
(?i:\bNL[D]?\b|Netherlands|荷兰|阿姆斯特丹),🇳🇱
(?i:\bNL[D]?\d*\b|Netherlands|荷兰|阿姆斯特丹),🇳🇱
(挪威|Norway),🇳🇴
(新西兰|纽西兰|New Zealand),🇳🇿
(Philippines|菲律宾),🇵🇭
(?i:\bP[O]?H\d*\b|Philippines|菲律宾),🇵🇭
(Pakistan|巴基斯坦),🇵🇰
(?i:\bP[O]?L\b|Poland|波兰),🇵🇱
(巴拿马|Panama),🇵🇦
@@ -71,15 +73,16 @@
(葡萄牙|Portugal),🇵🇹
(Romania|罗马尼亚),🇷🇴
(塞尔维亚|Serbia),🇷🇸
(?i:\bRU[S]?\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄),🇷🇺
(?i:\bRU[S]?\d*\b|Russia|Moscow|Petersburg|Siberia|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚|哈巴罗夫斯克|俄罗斯|[^-]俄),🇷🇺
(Arabia|沙特),🇸🇦
(Sweden|瑞典),🇸🇪
(斯洛文尼亚|Slovenia),🇸🇮
(斯洛伐克|Slovensko),🇸🇰
(Thailand|泰国|曼谷),🇹🇭
(突尼斯|Tunisia),🇹🇳
(Turkey|土耳其|伊斯坦布尔),🇹🇷
(Turkey|Türkiye|土耳其|伊斯坦布尔),🇹🇷
(乌拉圭|Uruguay),🇺🇾
(梵蒂冈|Vatican),🇻🇦
(Vietnam|越南),🇻🇳
(Africa|南非),🇿🇦
(Ukraine|UA|乌克兰),🇺🇦

View File

@@ -8,8 +8,10 @@ WORKDIR /
RUN set -xe && \
apk add --no-cache --virtual .build-tools git g++ build-base linux-headers cmake python3 && \
apk add --no-cache --virtual .build-deps curl-dev rapidjson-dev pcre2-dev yaml-cpp-dev && \
git clone https://github.com/ftk/quickjspp --depth=1 && \
git clone --no-checkout https://github.com/ftk/quickjspp.git && \
cd quickjspp && \
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09 && \
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09 && \
git submodule update --init && \
cmake -DCMAKE_BUILD_TYPE=Release . && \
make quickjs -j $THREADS && \
@@ -30,12 +32,12 @@ RUN set -xe && \
install -d /usr/include/date/ && \
install -m644 libcron/externals/date/include/date/* /usr/include/date/ && \
cd .. && \
git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1 && \
git clone https://github.com/ToruNiina/toml11 --branch="v4.3.0" --depth=1 && \
cd toml11 && \
cmake -DCMAKE_CXX_STANDARD=11 . && \
make install -j $THREADS && \
cd .. && \
git clone https://github.com/asdlokj1qpi23/subconverter --depth=1 && \
git clone https://github.com/asdlokj1qpi233/subconverter --depth=1 && \
cd subconverter && \
[ -n "$SHA" ] && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h;\
python3 -m ensurepip && \
@@ -53,6 +55,10 @@ RUN apk add --no-cache --virtual subconverter-deps pcre2 libcurl yaml-cpp
COPY --from=builder /subconverter/subconverter /usr/bin/
COPY --from=builder /subconverter/base /base/
ENV TZ=Africa/Abidjan
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime
RUN echo $TZ > /etc/timezone
# set entry
WORKDIR /base
CMD subconverter

View File

@@ -4,7 +4,7 @@ set -xe
apk add gcc g++ build-base linux-headers cmake make autoconf automake libtool python2 python3
apk add mbedtls-dev mbedtls-static zlib-dev rapidjson-dev zlib-static pcre2-dev
git clone https://github.com/curl/curl --depth=1 --branch curl-8_4_0
git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0
cd curl
cmake -DCURL_USE_MBEDTLS=ON -DHTTP_ONLY=ON -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_USE_LIBSSH2=OFF -DBUILD_CURL_EXE=OFF . > /dev/null
make install -j2 > /dev/null
@@ -16,8 +16,10 @@ cmake -DCMAKE_BUILD_TYPE=Release -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOO
make install -j3 > /dev/null
cd ..
git clone https://github.com/ftk/quickjspp --depth=1
git clone --no-checkout https://github.com/ftk/quickjspp.git
cd quickjspp
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
cmake -DCMAKE_BUILD_TYPE=Release .
make quickjs -j3 > /dev/null
install -d /usr/lib/quickjs/
@@ -34,7 +36,7 @@ cmake -DCMAKE_BUILD_TYPE=Release .
make libcron install -j3
cd ..
git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1
git clone https://github.com/ToruNiina/toml11 --branch="v4.3.0" --depth=1
cd toml11
cmake -DCMAKE_CXX_STANDARD=11 .
make install -j4

View File

@@ -14,49 +14,49 @@ brew reinstall rapidjson zlib pcre2 pkgconfig
git clone https://github.com/jbeder/yaml-cpp --depth=1
cd yaml-cpp
cmake -DCMAKE_BUILD_TYPE=Release -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF . > /dev/null
make install -j8 > /dev/null
make -j6 > /dev/null
sudo make install > /dev/null
cd ..
git clone https://github.com/ftk/quickjspp --depth=1
git clone --no-checkout https://github.com/ftk/quickjspp.git
cd quickjspp
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
cmake -DCMAKE_BUILD_TYPE=Release .
make quickjs -j8
install -d /usr/local/lib/quickjs/
install -m644 quickjs/libquickjs.a /usr/local/lib/quickjs/
install -d /usr/local/include/quickjs/
install -m644 quickjs/quickjs.h quickjs/quickjs-libc.h /usr/local/include/quickjs/
install -m644 quickjspp.hpp /usr/local/include/
make quickjs -j6 > /dev/null
sudo install -d /usr/local/lib/quickjs/
sudo install -m644 quickjs/libquickjs.a /usr/local/lib/quickjs/
sudo install -d /usr/local/include/quickjs/
sudo install -m644 quickjs/quickjs.h quickjs/quickjs-libc.h /usr/local/include/quickjs/
sudo install -m644 quickjspp.hpp /usr/local/include/
cd ..
git clone https://github.com/PerMalmberg/libcron --depth=1
cd libcron
git submodule update --init
cmake -DCMAKE_BUILD_TYPE=Release .
make libcron install -j8
install -m644 libcron/out/Release/liblibcron.a /usr/local/lib/
install -d /usr/local/include/libcron/
install -m644 libcron/include/libcron/* /usr/local/include/libcron/
install -d /usr/local/include/date/
install -m644 libcron/externals/date/include/date/* /usr/local/include/date/
make libcron -j6
sudo install -m644 libcron/out/Release/liblibcron.a /usr/local/lib/
sudo install -d /usr/local/include/libcron/
sudo install -m644 libcron/include/libcron/* /usr/local/include/libcron/
sudo install -d /usr/local/include/date/
sudo install -m644 libcron/externals/date/include/date/* /usr/local/include/date/
cd ..
git clone https://github.com/ToruNiina/toml11 --depth=1
git clone https://github.com/ToruNiina/toml11 --branch="v4.3.0" --depth=1
cd toml11
cmake -DCMAKE_CXX_STANDARD=11 .
make install -j4
sudo make install -j6 > /dev/null
cd ..
cp /usr/local/opt/zlib/lib/libz.a .
cp /usr/local/lib/libpcre2-8.a .
cmake -DCMAKE_BUILD_TYPE=Release .
make -j8
make -j6
rm subconverter
# shellcheck disable=SC2046
c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter -framework CoreFoundation -framework Security $(find CMakeFiles/subconverter.dir/src/ -name "*.o") $(find . -name "*.a") -lcurl -O3
c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter -framework CoreFoundation -framework Security $(find CMakeFiles/subconverter.dir/src/ -name "*.o") "$(brew --prefix zlib)/lib/libz.a" "$(brew --prefix pcre2)/lib/libpcre2-8.a" $(find . -name "*.a") -lcurl -O3
python -m ensurepip
python -m pip install gitpython
sudo python -m pip install gitpython
python scripts/update_rules.py -c scripts/rules_config.conf
cd base

View File

@@ -1,7 +1,7 @@
#!/bin/bash
set -xe
git clone https://github.com/curl/curl --depth=1 --branch curl-8_4_0
git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0
cd curl
cmake -DCMAKE_BUILD_TYPE=Release -DCURL_USE_LIBSSH2=OFF -DHTTP_ONLY=ON -DCURL_USE_SCHANNEL=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DHAVE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF .
make install -j4
@@ -13,11 +13,16 @@ cmake -DCMAKE_BUILD_TYPE=Release -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOO
make install -j4
cd ..
git clone https://github.com/ftk/quickjspp --depth=1
git clone --no-checkout https://github.com/ftk/quickjspp.git
cd quickjspp
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
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
install -d "$MINGW_PREFIX/lib/quickjs/"
install -m644 quickjs/libquickjs.a "$MINGW_PREFIX/lib/quickjs/"
install -d "$MINGW_PREFIX/include/quickjs"
@@ -38,7 +43,7 @@ cmake -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD
make install -j4
cd ..
git clone https://github.com/ToruNiina/toml11 --depth=1
git clone https://github.com/ToruNiina/toml11 --branch "v4.3.0" --depth=1
cd toml11
cmake -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=11 .
make install -j4
@@ -53,5 +58,5 @@ cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" .
make -j4
rm subconverter.exe
# shellcheck disable=SC2046
g++ $(find CMakeFiles/subconverter.dir/src -name "*.obj") curl/lib/libcurl.a -o base/subconverter.exe -static -lbcrypt -lpcre2-8 -l:quickjs/libquickjs.a -llibcron -lyaml-cpp -liphlpapi -lcrypt32 -lws2_32 -lwsock32 -lz -s
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

View File

@@ -16,8 +16,10 @@ cd rapidjson
cp -r include/* $PREFIX/include/
cd ..
git clone https://github.com/ftk/quickjspp --depth=1
git clone --no-checkout https://github.com/ftk/quickjspp.git
cd quickjspp
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
cmake -DCMAKE_BUILD_TYPE=Release .
make quickjs -j3
install -d $PREFIX/lib/quickjs/

View File

@@ -1,23 +1,23 @@
[ACL4SSR]
name=ACL4SSR
url=https://github.com/ACL4SSR/ACL4SSR
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
branch=master
match=Clash/*.list|Clash/Ruleset/**
[ACL4SSR_config]
name=ACL4SSR
url=https://github.com/ACL4SSR/ACL4SSR
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
branch=master
match=Clash/config/**
dest=base/config/
keep_tree=false
[DivineEngine]
url=https://github.com/DivineEngine/Profiles
checkout=f4d75f7d48a3f42129e030bef751d4d22bca02da
match=Surge/Ruleset/**
[NobyDa]
url=https://github.com/NobyDa/Script
checkout=ae4c12f23de8078e02c373c9969b19af28257fcb
branch=master
match=Surge/*.list
[lhie1]
url=https://github.com/dler-io/Rules
branch=main
match=Surge/Surge 3/Provider/**

View File

@@ -0,0 +1,23 @@
[ACL4SSR]
name=ACL4SSR
url=https://github.com/ACL4SSR/ACL4SSR
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
match=Clash/*.list|Clash/Ruleset/**
[ACL4SSR_config]
name=ACL4SSR
url=https://github.com/ACL4SSR/ACL4SSR
checkout=1dc5c92b0c8ceaaecbc66530c309961f53e52c8c
match=Clash/config/**
dest=base/config/
keep_tree=false
[DivineEngine]
url=https://github.com/DivineEngine/Profiles
checkout=f4d75f7d48a3f42129e030bef751d4d22bca02da
match=Surge/Ruleset/**
[NobyDa]
url=https://github.com/NobyDa/Script
checkout=ae4c12f23de8078e02c373c9969b19af28257fcb
match=Surge/*.list

View File

@@ -22,10 +22,13 @@ def open_repo(path: str):
return None
def update_rules(repo_path, save_path, commit, matches, keep_tree):
def update_rules(repo_path: str, save_path: str, matches: list[str], keep_tree: bool):
os.makedirs(save_path, exist_ok=True)
for pattern in matches:
files = glob.glob(os.path.join(repo_path, pattern), recursive=True)
if len(files) == 0:
logging.warn(f"no files found for pattern {pattern}")
continue
for file in files:
if os.path.isdir(file):
continue
@@ -51,12 +54,13 @@ def main():
for section in config.sections():
repo = config.get(section, "name", fallback=section)
url = config.get(section, "url")
commit = config.get(section, "checkout")
commit = config.get(section, "commit", fallback=None)
branch = config.get(section, "branch", fallback=None)
matches = config.get(section, "match").split("|")
save_path = config.get(section, "dest", fallback=f"base/rules/{repo}")
keep_tree = config.getboolean(section, "keep_tree", fallback=True)
logging.info(f"reading files from url {url} with commit {commit} and matches {matches}, save to {save_path} keep_tree {keep_tree}")
logging.info(f"reading files from url {url}, matches {matches}, save to {save_path} keep_tree {keep_tree}")
repo_path = os.path.join("./tmp/repo/", repo)
@@ -67,8 +71,21 @@ def main():
else:
logging.info(f"repo {repo_path} exists")
r.git.checkout(commit)
update_rules(repo_path, save_path, commit, matches, keep_tree)
try:
if commit is not None:
logging.info(f"checking out to commit {commit}")
r.git.checkout(commit)
elif branch is not None:
logging.info(f"checking out to branch {branch}")
r.git.checkout(branch)
else:
logging.info(f"checking out to default branch")
r.active_branch.checkout()
except Exception as e:
logging.error(f"checkout failed {e}")
continue
update_rules(repo_path, save_path, matches, keep_tree)
shutil.rmtree("./tmp", ignore_errors=True)

View File

@@ -17,9 +17,9 @@ namespace toml
static ProxyGroupConfig from_toml(const value& v)
{
ProxyGroupConfig conf;
conf.Name = toml::find<String>(v, "name");
String type = toml::find<String>(v, "type");
String strategy = toml::find_or<String>(v, "strategy", "");
conf.Name = find<String>(v, "name");
String type = find<String>(v, "type");
String strategy = find_or<String>(v, "strategy", "");
switch(hash_(type))
{
case "select"_hash:
@@ -27,18 +27,18 @@ namespace toml
break;
case "url-test"_hash:
conf.Type = ProxyGroupType::URLTest;
conf.Url = toml::find<String>(v, "url");
conf.Interval = toml::find<Integer>(v, "interval");
conf.Tolerance = toml::find_or<Integer>(v, "tolerance", 0);
conf.Url = find<String>(v, "url");
conf.Interval = find<Integer>(v, "interval");
conf.Tolerance = find_or<Integer>(v, "tolerance", 0);
if(v.contains("lazy"))
conf.Lazy = toml::find_or<bool>(v, "lazy", false);
conf.Lazy = find_or<bool>(v, "lazy", false);
if(v.contains("evaluate-before-use"))
conf.EvaluateBeforeUse = toml::find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
conf.EvaluateBeforeUse = find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
break;
case "load-balance"_hash:
conf.Type = ProxyGroupType::LoadBalance;
conf.Url = toml::find<String>(v, "url");
conf.Interval = toml::find<Integer>(v, "interval");
conf.Url = find<String>(v, "url");
conf.Interval = find<Integer>(v, "interval");
switch(hash_(strategy))
{
case "consistent-hashing"_hash:
@@ -49,14 +49,14 @@ namespace toml
break;
}
if(v.contains("persistent"))
conf.Persistent = toml::find_or(v, "persistent", conf.Persistent.get());
conf.Persistent = find_or(v, "persistent", conf.Persistent.get());
break;
case "fallback"_hash:
conf.Type = ProxyGroupType::Fallback;
conf.Url = toml::find<String>(v, "url");
conf.Interval = toml::find<Integer>(v, "interval");
conf.Url = find<String>(v, "url");
conf.Interval = find<Integer>(v, "interval");
if(v.contains("evaluate-before-use"))
conf.EvaluateBeforeUse = toml::find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
conf.EvaluateBeforeUse = find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
break;
case "relay"_hash:
conf.Type = ProxyGroupType::Relay;
@@ -64,16 +64,26 @@ namespace toml
case "ssid"_hash:
conf.Type = ProxyGroupType::SSID;
break;
case "smart"_hash:
conf.Type = ProxyGroupType::Smart;
conf.Url = find<String>(v, "url");
conf.Interval = find<Integer>(v, "interval");
conf.Tolerance = find_or<Integer>(v, "tolerance", 0);
if(v.contains("lazy"))
conf.Lazy = find_or<bool>(v, "lazy", false);
if(v.contains("evaluate-before-use"))
conf.EvaluateBeforeUse = find_or(v, "evaluate-before-use", conf.EvaluateBeforeUse.get());
break;
default:
throw toml::syntax_error("Proxy Group has incorrect type, should be one of following:\n select, url-test, load-balance, fallback, relay, ssid", v.at("type").location());
throw serialization_error(format_error("Proxy Group has unsupported type!", v.at("type").location(), "should be one of following: select, url-test, load-balance, fallback, relay, ssid"), v.at("type").location());
}
conf.Timeout = toml::find_or(v, "timeout", 5);
conf.Proxies = toml::find_or<StrArray>(v, "rule", {});
conf.UsingProvider = toml::find_or<StrArray>(v, "use", {});
conf.Timeout = find_or(v, "timeout", 5);
conf.Proxies = find_or<StrArray>(v, "rule", {});
conf.UsingProvider = find_or<StrArray>(v, "use", {});
if(conf.Proxies.empty() && conf.UsingProvider.empty())
throw toml::syntax_error("Proxy Group must contains at least one of proxy match rule or provider", v.location());
throw serialization_error(format_error("Proxy Group must contains at least one of proxy match rule or provider!", v.location(), "here"), v.location());
if(v.contains("disable-udp"))
conf.DisableUdp = toml::find_or(v, "disable-udp", conf.DisableUdp.get());
conf.DisableUdp = find_or(v, "disable-udp", conf.DisableUdp.get());
return conf;
}
};
@@ -84,8 +94,8 @@ namespace toml
static RulesetConfig from_toml(const value& v)
{
RulesetConfig conf;
conf.Group = toml::find<String>(v, "group");
String type = toml::find_or<String>(v, "type", "surge-ruleset");
conf.Group = find<String>(v, "group");
String type = find_or<String>(v, "type", "surge-ruleset");
switch(hash_(type))
{
/*
@@ -122,10 +132,10 @@ namespace toml
conf.Url = type + ":";
break;
default:
throw toml::syntax_error("Ruleset has incorrect type, should be one of following:\n surge-ruleset, quantumultx, clash-domain, clash-ipcidr, clash-classic", v.at("type").location());
throw serialization_error(format_error("Ruleset has unsupported type!", v.at("type").location(), "should be one of following: surge-ruleset, quantumultx, clash-domain, clash-ipcidr, clash-classic"), v.at("type").location());
}
conf.Url += toml::find<String>(v, "ruleset");
conf.Interval = toml::find_or<Integer>(v, "interval", 86400);
conf.Url += find<String>(v, "ruleset");
conf.Interval = find_or<Integer>(v, "interval", 86400);
return conf;
}
};
@@ -138,14 +148,14 @@ namespace toml
RegexMatchConfig conf;
if(v.contains("script"))
{
conf.Script = toml::find<String>(v, "script");
conf.Script = find<String>(v, "script");
return conf;
}
conf.Match = toml::find<String>(v, "match");
conf.Match = find<String>(v, "match");
if(v.contains("emoji"))
conf.Replace = toml::find<String>(v, "emoji");
conf.Replace = find<String>(v, "emoji");
else
conf.Replace = toml::find<String>(v, "replace");
conf.Replace = find<String>(v, "replace");
return conf;
}
};
@@ -156,10 +166,10 @@ namespace toml
static CronTaskConfig from_toml(const value& v)
{
CronTaskConfig conf;
conf.Name = toml::find<String>(v, "name");
conf.CronExp = toml::find<String>(v, "cronexp");
conf.Path = toml::find<String>(v, "path");
conf.Timeout = toml::find_or<Integer>(v, "timeout", 0);
conf.Name = find<String>(v, "name");
conf.CronExp = find<String>(v, "cronexp");
conf.Path = find<String>(v, "path");
conf.Timeout = find_or<Integer>(v, "timeout", 0);
return conf;
}
};
@@ -220,6 +230,9 @@ namespace INIBinding
case "ssid"_hash:
conf.Type = ProxyGroupType::SSID;
break;
case "smart"_hash:
conf.Type = ProxyGroupType::Smart;
break;
default:
continue;
}

View File

@@ -3,17 +3,18 @@
#include "def.h"
enum ProxyGroupType
enum class ProxyGroupType
{
Select,
URLTest,
Fallback,
LoadBalance,
Relay,
SSID
SSID,
Smart
};
enum BalanceStrategy
enum class BalanceStrategy
{
ConsistentHashing,
RoundRobin
@@ -45,6 +46,7 @@ struct ProxyGroupConfig
case ProxyGroupType::Fallback: return "fallback";
case ProxyGroupType::Relay: return "relay";
case ProxyGroupType::SSID: return "ssid";
case ProxyGroupType::Smart: return "smart";
}
return "";
}

View File

@@ -3,7 +3,7 @@
#include "def.h"
enum RulesetType
enum class RulesetType
{
SurgeRuleset,
QuantumultX,

View File

@@ -10,7 +10,9 @@
/// rule type lists
#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL"
string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME"};
// 新增meta路由规则
//string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME"};
string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME", "DOMAIN-REGEX", "GEOSITE", "IP-SUFFIX", "IP-ASN", "SRC-GEOIP", "SRC-IP-ASN", "SRC-IP-SUFFIX", "IN-PORT", "IN-TYPE", "IN-USER", "IN-NAME", "PROCESS-PATH-REGEX", "PROCESS-PATH", "PROCESS-NAME-REGEX", "UID", "NETWORK", "DSCP", "SUB-RULE", "RULE-SET", "AND", "OR", "NOT"};
string_array Surge2RuleTypes = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
string_array SurgeRuleTypes = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
string_array QuanXRuleTypes = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"};
@@ -248,8 +250,26 @@ std::string rulesetToClashStr(YAML::Node &base_rule, std::vector<RulesetContent>
strLine.erase(strLine.find("//"));
strLine = trimWhitespace(strLine);
}
strLine = transformRuleToCommon(temp, strLine, rule_group);
output_content += " - " + strLine + "\n";
//AND & OR & NOT
if(startsWith(strLine, "AND") || startsWith(strLine, "OR") || startsWith(strLine, "NOT"))
{
output_content += " - " + strLine + "," + rule_group + "\n";
}
//SUB-RULE & RULE-SET
else if (startsWith(strLine, "SUB-RULE") || startsWith(strLine, "RULE-SET"))
{
output_content += " - " + strLine + "\n";
}
else
//OTHER
{
strLine = transformRuleToCommon(temp, strLine, rule_group);
output_content += " - " + strLine + "\n";
}
//strLine = transformRuleToCommon(temp, strLine, rule_group);
//output_content += " - " + strLine + "\n";
total_rules++;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@ struct extra_settings
bool clash_classical_ruleset = false;
std::string sort_script;
std::string clash_proxies_style = "flow";
std::string clash_proxy_groups_style = "flow";
bool authorized = false;
extra_settings() = default;

View File

@@ -357,10 +357,10 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
if(x.rule_type == RULESET_CLASH_IPCIDR || x.rule_type == RULESET_CLASH_DOMAIN || x.rule_type == RULESET_CLASH_CLASSICAL)
{
//rule_name = std::to_string(hash_(rule_group + rule_path));
rule_name = old_rule_name = findFileName(rule_path);
rule_name = old_rule_name = urlDecode(findFileName(rule_path));
int idx = 2;
while(std::find(groups.begin(), groups.end(), rule_name) != groups.end())
rule_name = old_rule_name + "_" + std::to_string(idx++);
rule_name = old_rule_name + " " + std::to_string(idx++);
names[rule_name] = rule_group;
urls[rule_name] = "*" + rule_path;
rule_type[rule_name] = x.rule_type;
@@ -386,10 +386,10 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
if(fileExist(rule_path, true) || isLink(rule_path))
{
//rule_name = std::to_string(hash_(rule_group + rule_path));
rule_name = old_rule_name = findFileName(rule_path);
rule_name = old_rule_name = urlDecode(findFileName(rule_path));
int idx = 2;
while(std::find(groups.begin(), groups.end(), rule_name) != groups.end())
rule_name = old_rule_name + "_" + std::to_string(idx++);
rule_name = old_rule_name + " " + std::to_string(idx++);
names[rule_name] = rule_group;
urls[rule_name] = rule_path_typed;
rule_type[rule_name] = x.rule_type;
@@ -436,9 +436,9 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
if(vArray.size() < 2)
continue;
if(keywords.find(rule_name) == keywords.end())
keywords[rule_name] = "\"" + vArray[1] + "\"";
keywords[rule_name] = "\"" + trim(vArray[1]) + "\"";
else
keywords[rule_name] += ",\"" + vArray[1] + "\"";
keywords[rule_name] += ",\"" + trim(vArray[1]) + "\"";
}
else
{
@@ -449,7 +449,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
}
else
{
strLine = vArray[0] + "," + vArray[1] + "," + rule_group;
strLine = vArray[0] + "," + trim(vArray[1]) + "," + rule_group;
if(vArray.size() > 2)
strLine += "," + vArray[2];
}
@@ -466,14 +466,16 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
}
}
if(has_domain[rule_name] && !script)
rules.emplace_back("RULE-SET," + rule_name + "_domain," + rule_group);
rules.emplace_back("RULE-SET," + rule_name + " (Domain)," + rule_group);
if(has_ipcidr[rule_name] && !script)
{
if(has_no_resolve)
rules.emplace_back("RULE-SET," + rule_name + "_ipcidr," + rule_group + ",no-resolve");
rules.emplace_back("RULE-SET," + rule_name + " (IP-CIDR)," + rule_group + ",no-resolve");
else
rules.emplace_back("RULE-SET," + rule_name + "_ipcidr," + rule_group);
rules.emplace_back("RULE-SET," + rule_name + " (IP-CIDR)," + rule_group);
}
if(!has_domain[rule_name] && !has_ipcidr[rule_name] && !script)
rules.emplace_back("RULE-SET," + rule_name + "," + rule_group);
if(std::find(groups.begin(), groups.end(), rule_name) == groups.end())
groups.emplace_back(rule_name);
}
@@ -488,14 +490,14 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
{
std::string yaml_key = x;
if(rule_type[x] != RULESET_CLASH_DOMAIN)
yaml_key += "_domain";
yaml_key += " (Domain)";
base_rule["rule-providers"][yaml_key]["type"] = "http";
base_rule["rule-providers"][yaml_key]["behavior"] = "domain";
if(url[0] == '*')
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
else
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=3&url=" + urlSafeBase64Encode(url);
base_rule["rule-providers"][yaml_key]["path"] = "./providers/rule-provider_" + yaml_key + ".yaml";
base_rule["rule-providers"][yaml_key]["path"] = "./providers/" + std::to_string(hash_(url)) + "_domain.yaml";
if(interval)
base_rule["rule-providers"][yaml_key]["interval"] = interval;
}
@@ -503,14 +505,14 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
{
std::string yaml_key = x;
if(rule_type[x] != RULESET_CLASH_IPCIDR)
yaml_key += "_ipcidr";
yaml_key += " (IP-CIDR)";
base_rule["rule-providers"][yaml_key]["type"] = "http";
base_rule["rule-providers"][yaml_key]["behavior"] = "ipcidr";
if(url[0] == '*')
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
else
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=4&url=" + urlSafeBase64Encode(url);
base_rule["rule-providers"][yaml_key]["path"] = "./providers/rule-provider_" + yaml_key + ".yaml";
base_rule["rule-providers"][yaml_key]["path"] = "./providers/" + std::to_string(hash_(url)) + "_ipcidr.yaml";
if(interval)
base_rule["rule-providers"][yaml_key]["interval"] = interval;
}
@@ -523,7 +525,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<RulesetContent> &rulese
base_rule["rule-providers"][yaml_key]["url"] = url.substr(1);
else
base_rule["rule-providers"][yaml_key]["url"] = remote_path_prefix + "/getruleset?type=6&url=" + urlSafeBase64Encode(url);
base_rule["rule-providers"][yaml_key]["path"] = "./providers/rule-provider_" + yaml_key + ".yaml";
base_rule["rule-providers"][yaml_key]["path"] = "./providers/" + std::to_string(hash_(url)) + ".yaml";
if(interval)
base_rule["rule-providers"][yaml_key]["interval"] = interval;
}

View File

@@ -58,31 +58,33 @@ struct UAProfile {
};
const std::vector<UAProfile> UAMatchList = {
{"ClashForAndroid", "\\/([0-9.]+)", "2.0", "clash", true},
{"ClashForAndroid", "\\/([0-9.]+)R", "", "clashr", false},
{"ClashForAndroid", "", "", "clash", false},
{"ClashforWindows", "\\/([0-9.]+)", "0.11", "clash", true},
{"ClashforWindows", "", "", "clash", false},
{"ClashX Pro", "", "", "clash", true},
{"ClashX", "\\/([0-9.]+)", "0.13", "clash", true},
{"Clash", "", "", "clash", true},
{"Kitsunebi", "", "", "v2ray"},
{"Loon", "", "", "loon"},
{"Pharos", "", "", "mixed"},
{"Potatso", "", "", "mixed"},
{"Quantumult%20X", "", "", "quanx"},
{"Quantumult", "", "", "quan"},
{"Qv2ray", "", "", "v2ray"},
{"Shadowrocket", "", "", "mixed"},
{"Surfboard", "", "", "surfboard"},
{"Surge", "\\/([0-9.]+).*x86", "906", "surge", false, 4}, /// Surge for Mac (supports VMess)
{"Surge", "\\/([0-9.]+).*x86", "368", "surge", false, 3}, /// Surge for Mac (supports new rule types and Shadowsocks without plugin)
{"Surge", "\\/([0-9.]+)", "1419", "surge", false, 4}, /// Surge iOS 4 (first version)
{"Surge", "\\/([0-9.]+)", "900", "surge", false, 3}, /// Surge iOS 3 (approx)
{"Surge", "", "", "surge", false, 2}, /// any version of Surge as fallback
{"Trojan-Qt5", "", "", "trojan"},
{"V2rayU", "", "", "v2ray"},
{"V2RayX", "", "", "v2ray"}
{"ClashForAndroid", "\\/([0-9.]+)", "2.0", "clash", true},
{"ClashForAndroid", "\\/([0-9.]+)R", "", "clashr", false},
{"ClashForAndroid", "", "", "clash", false},
{"ClashforWindows", "\\/([0-9.]+)", "0.11", "clash", true},
{"ClashforWindows", "", "", "clash", false},
{"clash-verge", "", "", "clash", true},
{"ClashX Pro", "", "", "clash", true},
{"ClashX", "\\/([0-9.]+)", "0.13", "clash", true},
{"Clash", "", "", "clash", true},
{"Kitsunebi", "", "", "v2ray"},
{"Loon", "", "", "loon"},
{"Pharos", "", "", "mixed"},
{"Potatso", "", "", "mixed"},
{"Quantumult%20X", "", "", "quanx"},
{"Quantumult", "", "", "quan"},
{"Qv2ray", "", "", "v2ray"},
{"Shadowrocket", "", "", "mixed"},
{"Surfboard", "", "", "surfboard"},
{"Surge", "\\/([0-9.]+).*x86", "906", "surge", false, 4}, /// Surge for Mac (supports VMess)
{"Surge", "\\/([0-9.]+).*x86", "368", "surge", false, 3},
/// Surge for Mac (supports new rule types and Shadowsocks without plugin)
{"Surge", "\\/([0-9.]+)", "1419", "surge", false, 4}, /// Surge iOS 4 (first version)
{"Surge", "\\/([0-9.]+)", "900", "surge", false, 3}, /// Surge iOS 3 (approx)
{"Surge", "", "", "surge", false, 2}, /// any version of Surge as fallback
{"Trojan-Qt5", "", "", "trojan"},
{"V2rayU", "", "", "v2ray"},
{"V2RayX", "", "", "v2ray"}
};
bool verGreaterEqual(const std::string &src_ver, const std::string &target_ver) {
@@ -134,8 +136,8 @@ std::string getRuleset(RESPONSE_CALLBACK_ARGS) {
int *status_code = &response.status_code;
/// type: 1 for Surge, 2 for Quantumult X, 3 for Clash domain rule-provider, 4 for Clash ipcidr rule-provider, 5 for Surge DOMAIN-SET, 6 for Clash classical ruleset
std::string url = urlSafeBase64Decode(getUrlArg(argument, "url")), type = getUrlArg(argument,
"type"), group = urlSafeBase64Decode(
getUrlArg(argument, "group"));
"type"), group = urlSafeBase64Decode(
getUrlArg(argument, "group"));
std::string output_content, dummy;
int type_int = to_int(type, 0);
@@ -332,26 +334,26 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
std::string argGroupName = getUrlArg(argument, "group"), argUploadPath = getUrlArg(argument, "upload_path");
std::string argIncludeRemark = getUrlArg(argument, "include"), argExcludeRemark = getUrlArg(argument, "exclude");
std::string argCustomGroups = urlSafeBase64Decode(
getUrlArg(argument, "groups")), argCustomRulesets = urlSafeBase64Decode(
getUrlArg(argument, "ruleset")), argExternalConfig = getUrlArg(argument, "config");
getUrlArg(argument, "groups")), argCustomRulesets = urlSafeBase64Decode(
getUrlArg(argument, "ruleset")), argExternalConfig = getUrlArg(argument, "config");
std::string argDeviceID = getUrlArg(argument, "dev_id"), argFilename = getUrlArg(argument,
"filename"), argUpdateInterval = getUrlArg(
argument, "interval"), argUpdateStrict = getUrlArg(argument, "strict");
"filename"), argUpdateInterval = getUrlArg(
argument, "interval"), argUpdateStrict = getUrlArg(argument, "strict");
std::string argRenames = getUrlArg(argument, "rename"), argFilterScript = getUrlArg(argument, "filter_script");
/// switches with default value
tribool argUpload = getUrlArg(argument, "upload"), argEmoji = getUrlArg(argument, "emoji"), argAddEmoji = getUrlArg(
argument, "add_emoji"), argRemoveEmoji = getUrlArg(argument, "remove_emoji");
argument, "add_emoji"), argRemoveEmoji = getUrlArg(argument, "remove_emoji");
tribool argAppendType = getUrlArg(argument, "append_type"), argTFO = getUrlArg(argument, "tfo"), argUDP = getUrlArg(
argument, "udp"), argGenNodeList = getUrlArg(argument, "list");
argument, "udp"), argGenNodeList = getUrlArg(argument, "list");
tribool argSort = getUrlArg(argument, "sort"), argUseSortScript = getUrlArg(argument, "sort_script");
tribool argGenClashScript = getUrlArg(argument, "script"), argEnableInsert = getUrlArg(argument, "insert");
tribool argSkipCertVerify = getUrlArg(argument, "scv"), argFilterDeprecated = getUrlArg(argument,
"fdn"), argExpandRulesets = getUrlArg(
argument, "expand"), argAppendUserinfo = getUrlArg(argument, "append_info");
"fdn"), argExpandRulesets = getUrlArg(
argument, "expand"), argAppendUserinfo = getUrlArg(argument, "append_info");
tribool argPrependInsert = getUrlArg(argument, "prepend"), argGenClassicalRuleProvider = getUrlArg(argument,
"classic"), argTLS13 = getUrlArg(
argument, "tls13");
"classic"), argTLS13 = getUrlArg(
argument, "tls13");
std::string base_content, output_content;
ProxyGroupConfigs lCustomProxyGroups = global.customProxyGroups;
@@ -360,20 +362,23 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
std::vector<RulesetContent> lRulesetContent;
extra_settings ext;
std::string subInfo, dummy;
int interval = !argUpdateInterval.empty() ? to_int(argUpdateInterval, global.updateInterval)
: global.updateInterval;
int interval = !argUpdateInterval.empty()
? to_int(argUpdateInterval, global.updateInterval)
: global.updateInterval;
bool authorized =
!global.APIMode || getUrlArg(argument, "token") == global.accessToken, strict = !argUpdateStrict.empty() ?
argUpdateStrict == "true"
: global.updateStrict;
!global.APIMode || getUrlArg(argument, "token") == global.accessToken, strict = !argUpdateStrict.empty()
? argUpdateStrict == "true"
: global.updateStrict;
if (std::find(gRegexBlacklist.cbegin(), gRegexBlacklist.cend(), argIncludeRemark) != gRegexBlacklist.cend() ||
std::find(gRegexBlacklist.cbegin(), gRegexBlacklist.cend(), argExcludeRemark) != gRegexBlacklist.cend())
return "Invalid request!";
/// for external configuration
std::string lClashBase = global.clashBase, lSurgeBase = global.surgeBase, lMellowBase = global.mellowBase, lSurfboardBase = global.surfboardBase;
std::string lQuanBase = global.quanBase, lQuanXBase = global.quanXBase, lLoonBase = global.loonBase, lSSSubBase = global.SSSubBase;
std::string lClashBase = global.clashBase, lSurgeBase = global.surgeBase, lMellowBase = global.mellowBase,
lSurfboardBase = global.surfboardBase;
std::string lQuanBase = global.quanBase, lQuanXBase = global.quanXBase, lLoonBase = global.loonBase, lSSSubBase =
global.SSSubBase;
std::string lSingBoxBase = global.singBoxBase;
/// validate urls
@@ -386,20 +391,20 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
}
/// load request arguments as template variables
// string_array req_args = split(argument, "&");
// string_map req_arg_map;
// for(std::string &x : req_args)
// {
// string_size pos = x.find("=");
// if(pos == x.npos)
// {
// req_arg_map[x] = "";
// continue;
// }
// if(x.substr(0, pos) == "token")
// continue;
// req_arg_map[x.substr(0, pos)] = x.substr(pos + 1);
// }
// string_array req_args = split(argument, "&");
// string_map req_arg_map;
// for(std::string &x : req_args)
// {
// string_size pos = x.find("=");
// if(pos == x.npos)
// {
// req_arg_map[x] = "";
// continue;
// }
// if(x.substr(0, pos) == "token")
// continue;
// req_arg_map[x.substr(0, pos)] = x.substr(pos + 1);
// }
string_map req_arg_map;
for (auto &x: argument) {
if (x.first == "token")
@@ -424,6 +429,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
argExpandRulesets.define(true);
ext.clash_proxies_style = global.clashProxiesStyle;
ext.clash_proxy_groups_style = global.clashProxyGroupsStyle;
/// read preference from argument, assign global var if not in argument
ext.tfo.define(argTFO).define(global.TFOFlag);
@@ -652,8 +658,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
ctx.eval(filterScript);
auto filter = (std::function<bool(const Proxy &)>) ctx.eval("filter");
nodes.erase(std::remove_if(nodes.begin(), nodes.end(), filter), nodes.end());
}
catch (qjs::exception) {
} catch (qjs::exception) {
script_print_stack(ctx);
}
}, global.scriptCleanContext);
@@ -686,7 +691,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
std::string managed_url = base64Decode(getUrlArg(argument, "profile_data"));
if (managed_url.empty())
managed_url = global.managedConfigPrefix + "/sub?" + joinArguments(argument);
size_t found;
//std::cerr<<"Generate target: ";
proxy = parseProxy(global.proxyConfig);
switch (hash_(argTarget)) {
@@ -734,9 +739,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
uploadGist("surge" + argSurgeVer, argUploadPath, output_content, true);
if (global.writeManagedConfig && !global.managedConfigPrefix.empty())
output_content = "#!MANAGED-CONFIG " + managed_url +
(interval ? " interval=" + std::to_string(interval) : "") \
+ " strict=" + std::string(strict ? "true" : "false") + "\n\n" + output_content;
output_content = "#!MANAGED-CONFIG " + managed_url + (interval
? " interval=" + std::to_string(interval)
: "")
+ " strict=" + std::string(strict ? "true" : "false") + "\n\n" + output_content;
}
break;
case "surfboard"_hash:
@@ -752,9 +758,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
uploadGist("surfboard", argUploadPath, output_content, true);
if (global.writeManagedConfig && !global.managedConfigPrefix.empty())
output_content =
"#!MANAGED-CONFIG " + managed_url + (interval ? " interval=" + std::to_string(interval) : "") \
+ " strict=" + std::string(strict ? "true" : "false") + "\n\n" + output_content;
output_content = "#!MANAGED-CONFIG " + managed_url + (interval
? " interval=" + std::to_string(interval)
: "")
+ " strict=" + std::string(strict ? "true" : "false") + "\n\n" + output_content;
break;
case "mellow"_hash:
writeLog(0, "Generate target: Mellow", LOG_LEVEL_INFO);
@@ -805,9 +812,21 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
if (argUpload)
uploadGist("trojan", argUploadPath, output_content, false);
break;
case "vless"_hash:
writeLog(0, "Generate target: vless", LOG_LEVEL_INFO);
output_content = proxyToSingle(nodes, 16, ext);
if (argUpload)
uploadGist("vless", argUploadPath, output_content, false);
break;
case "hysteria2"_hash:
writeLog(0, "Generate target: hysteria2", LOG_LEVEL_INFO);
output_content = proxyToSingle(nodes, 32, ext);
if (argUpload)
uploadGist("hysteria2", argUploadPath, output_content, false);
break;
case "mixed"_hash:
writeLog(0, "Generate target: Standard Subscription", LOG_LEVEL_INFO);
output_content = proxyToSingle(nodes, 15, ext);
output_content = proxyToSingle(nodes, 63, ext);
if (argUpload)
uploadGist("sub", argUploadPath, output_content, false);
break;
@@ -873,11 +892,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
}
output_content = proxyToSingBox(nodes, base_content, lRulesetContent, lCustomProxyGroups, ext);
found = output_content.find('\u0000');
while (found != std::string::npos) {
output_content.erase(found, 1);
found = output_content.find('\u0000', found);
}
if (argUpload)
uploadGist("singbox", argUploadPath, output_content, false);
@@ -890,12 +904,11 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) {
writeLog(0, "Generate completed.", LOG_LEVEL_INFO);
if (!argFilename.empty())
response.headers.emplace("Content-Disposition",
"attachment; filename=\"" + argFilename + "\"; filename*=utf-8''" +
urlEncode(argFilename));
"attachment; filename=\"" + argFilename + "\"; filename*=utf-8''" + urlEncode(
argFilename));
return output_content;
}
std::string simpleToClashR(RESPONSE_CALLBACK_ARGS) {
auto argument = joinArguments(request.argument);
int *status_code = &response.status_code;
@@ -922,9 +935,8 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS) {
string_array dummy_str_array;
std::vector<Proxy> nodes;
std::string base_content, url = argument.size() <= 5 ? "" : argument.substr(5);
const std::string proxygroup_name = global.clashUseNewField ? "proxy-groups"
: "Proxy Group", rule_name = global.clashUseNewField
? "rules" : "Rule";
const std::string proxygroup_name = global.clashUseNewField ? "proxy-groups" : "Proxy Group", rule_name =
global.clashUseNewField ? "rules" : "Rule";
ini.store_any_line = true;
@@ -987,8 +999,8 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS) {
if (dummy_str_array.empty())
continue;
type = dummy_str_array[0];
if (!(type == "select" || type == "url-test" || type == "fallback" ||
type == "load-balance")) //remove unsupported types
if (!(type == "select" || type == "url-test" || type == "fallback" || type == "load-balance"))
//remove unsupported types
continue;
singlegroup["name"] = name;
singlegroup["type"] = type;
@@ -1100,8 +1112,8 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS) {
lineSize = strLine.size();
if (lineSize && strLine[lineSize - 1] == '\r') //remove line break
strLine.erase(--lineSize);
if (!lineSize || strLine[0] == ';' || strLine[0] == '#' ||
(lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored
if (!lineSize || strLine[0] == ';' || strLine[0] == '#' || (
lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored
continue;
else if (!std::any_of(ClashRuleTypes.begin(), ClashRuleTypes.end(),
[&strLine](const std::string &type) {
@@ -1115,8 +1127,9 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS) {
}
ss.clear();
continue;
} else if (!std::any_of(ClashRuleTypes.begin(), ClashRuleTypes.end(),
[&strLine](const std::string &type) { return startsWith(strLine, type); }))
} else if (!std::any_of(ClashRuleTypes.begin(), ClashRuleTypes.end(), [&strLine](const std::string &type) {
return startsWith(strLine, type);
}))
continue;
rule.push_back(x);
}
@@ -1244,8 +1257,8 @@ std::string subInfoToMessage(std::string subinfo) {
using ull = unsigned long long;
subinfo = replaceAllDistinct(subinfo, "; ", "&");
std::string retdata, useddata = "N/A", totaldata = "N/A", expirydata = "N/A";
std::string upload = getUrlArg(subinfo, "upload"), download = getUrlArg(subinfo, "download"), total = getUrlArg(
subinfo, "total"), expire = getUrlArg(subinfo, "expire");
std::string upload = getUrlArg(subinfo, "upload"), download = getUrlArg(subinfo, "download"), total =
getUrlArg(subinfo, "total"), expire = getUrlArg(subinfo, "expire");
ull used = to_number<ull>(upload, 0) + to_number<ull>(download, 0), tot = to_number<ull>(total, 0);
auto expiry = to_number<time_t>(expire, 0);
if (used != 0)
@@ -1302,7 +1315,7 @@ int simpleGenerator() {
sections = new_targets;
sections.shrink_to_fit();
} else
//std::cerr<<"Generating all artifacts...\n";
//std::cerr<<"Generating all artifacts...\n";
writeLog(0, "Generating all artifacts...", LOG_LEVEL_INFO);
string_multimap allItems;

View File

@@ -1,6 +1,5 @@
#include <string>
#include <mutex>
#include <toml.hpp>
#include "config/binding.h"
#include "handler/webget.h"
@@ -566,13 +565,13 @@ void readYAMLConf(YAML::Node &node)
}
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 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)
{
@@ -801,7 +800,7 @@ void readConf()
return readYAMLConf(yaml);
}
toml::value conf = parseToml(prefdata, global.prefPath);
if(!conf.is_uninitialized() && toml::find_or<int>(conf, "version", 0))
if(!conf.is_empty() && toml::find_or<int>(conf, "version", 0))
return readTOMLConf(conf);
}
catch (YAML::Exception &e)
@@ -1210,7 +1209,7 @@ int loadExternalConfig(std::string &path, ExternalConfig &ext)
if(yaml.size() && yaml["custom"].IsDefined())
return loadExternalYAML(yaml, ext);
toml::value conf = parseToml(base_content, path);
if(!conf.is_uninitialized() && toml::find_or<int>(conf, "version", 0))
if(!conf.is_empty() && toml::find_or<int>(conf, "version", 0))
return loadExternalTOML(conf, ext);
}
catch (YAML::Exception &e)

View File

@@ -13,6 +13,7 @@
#include "utils/string.h"
#include "utils/stl_extra.h"
#include "utils/tribool.h"
#include <toml.hpp>
struct Settings
{
@@ -48,7 +49,7 @@ struct Settings
tribool UDPFlag, TFOFlag, skipCertVerify, TLS13Flag, enableInsert;
bool enableSort = false, updateStrict = false;
bool clashUseNewField = false, singBoxAddClashModes = true;
std::string clashProxiesStyle = "flow";
std::string clashProxiesStyle = "flow", clashProxyGroupsStyle = "block";
std::string proxyConfig, proxyRuleset, proxySubscription;
int updateInterval = 0;
std::string sortScript, filterScript;
@@ -100,7 +101,12 @@ extern Settings global;
int importItems(string_array &target, bool scope_limit = true);
int loadExternalConfig(std::string &path, ExternalConfig &ext);
//template <class T, class... U>
//void find_if_exist(const toml::value &v, const toml::key &k, T& target, U&&... args)
//{
// if(v.contains(k)) target = toml::find<T>(v, k);
// if constexpr (sizeof...(args) > 0) find_if_exist(v, std::forward<U>(args)...);
//}
template <class... Args>
void parseGroupTimes(const std::string &src, Args... args)
{

View File

@@ -87,11 +87,13 @@ static int logger(CURL *handle, curl_infotype type, char *data, size_t size, voi
switch(type)
{
case CURLINFO_TEXT:
prefix = "CURL_INFO";
prefix = "CURL_INFO: ";
break;
case CURLINFO_HEADER_IN:
prefix = "CURL_HEADER: < ";
break;
case CURLINFO_HEADER_OUT:
prefix = "CURL_HEADER";
prefix = "CURL_HEADER: > ";
break;
case CURLINFO_DATA_IN:
case CURLINFO_DATA_OUT:
@@ -105,7 +107,6 @@ static int logger(CURL *handle, curl_infotype type, char *data, size_t size, voi
for(auto &x : lines)
{
std::string log_content = prefix;
log_content += ": ";
log_content += x;
writeLog(0, log_content, LOG_LEVEL_VERBOSE);
}
@@ -113,7 +114,6 @@ static int logger(CURL *handle, curl_infotype type, char *data, size_t size, voi
else
{
std::string log_content = prefix;
log_content += ": ";
log_content += trimWhitespace(content);
writeLog(0, log_content, LOG_LEVEL_VERBOSE);
}
@@ -172,7 +172,8 @@ static int curlGet(const FetchArgument &argument, FetchResult &result)
{
for(auto &x : *argument.request_headers)
{
header_list = curl_slist_append(header_list, (x.first + ": " + x.second).data());
auto header = x.first + ": " + x.second;
header_list = curl_slist_append(header_list, header.data());
}
if(!argument.request_headers->contains("User-Agent"))
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent_str);
@@ -233,7 +234,7 @@ static int curlGet(const FetchArgument &argument, FetchResult &result)
while(true)
{
retVal = curl_easy_perform(curl_handle);
if(retVal == CURLE_OK || max_fails <= fail_count)
if(retVal == CURLE_OK || max_fails <= fail_count || global.APIMode)
break;
else
fail_count++;

View File

@@ -233,10 +233,10 @@ int main(int argc, char *argv[])
}
}
std::string type = getUrlArg(request.argument, "type");
if(type == "form")
fileWrite(global.prefPath, getFormData(request.postdata), true);
else if(type == "direct")
if(type == "form" || type == "direct")
{
fileWrite(global.prefPath, request.postdata, true);
}
else
{
response.status_code = 501;

View File

@@ -9,7 +9,8 @@
using String = std::string;
using StringArray = std::vector<String>;
enum class ProxyType {
enum class ProxyType
{
Unknown,
Shadowsocks,
ShadowsocksR,
@@ -22,7 +23,10 @@ enum class ProxyType {
WireGuard,
VLESS,
Hysteria,
Hysteria2
Hysteria2,
TUIC,
AnyTLS,
Mieru
};
inline String getProxyTypeName(ProxyType type) {
@@ -51,6 +55,10 @@ inline String getProxyTypeName(ProxyType type) {
return "Hysteria";
case ProxyType::Hysteria2:
return "Hysteria2";
case ProxyType::TUIC:
return "Tuic";
case ProxyType::AnyTLS:
return "AnyTLS";
default:
return "Unknown";
}
@@ -64,7 +72,7 @@ struct Proxy {
String Remark;
String Hostname;
uint16_t Port = 0;
String CongestionControl;
String Username;
String Password;
String EncryptMethod;
@@ -79,7 +87,10 @@ struct Proxy {
String TransferProtocol;
String FakeType;
String AuthStr;
uint16_t IdleSessionCheckInterval=30;
uint16_t IdleSessionTimeout=30;
uint16_t MinIdleSession=0;
String TLSStr;
bool TLSSecure = false;
String Host;
@@ -109,7 +120,7 @@ struct Proxy {
uint16_t KeepAlive = 0;
String TestUrl;
String ClientId;
String Ports;
String Auth;
String Alpn;
String UpMbps;
@@ -122,6 +133,19 @@ struct Proxy {
String ShortId;
String Flow;
bool FlowShow = false;
tribool DisableSni;
uint32_t UpSpeed;
uint32_t DownSpeed;
String SNI;
tribool ReduceRtt;
String UdpRelayMode = "native";
uint16_t RequestTimeout = 15000;
String token;
String UnderlyingProxy;
std::vector<String> AlpnList;
String PacketEncoding;
String Multiplexing;
tribool V2rayHttpUpgrade;
};
#define SS_DEFAULT_GROUP "SSProvider"
@@ -135,5 +159,7 @@ struct Proxy {
#define XRAY_DEFAULT_GROUP "XRayProvider"
#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider"
#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider"
#define TUIC_DEFAULT_GROUP "TuicProvider"
#define ANYTLS_DEFAULT_GROUP "AnyTLSProvider"
#define MIERU_DEFAULT_GROUP "MieruProvider"
#endif // PROXY_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,7 @@
#include "config/proxy.h"
enum class ConfType
{
enum class ConfType {
Unknow,
SS,
SSR,
@@ -19,36 +18,129 @@ enum class ConfType
SUB,
Local
};
void hysteriaConstruct(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 &auth, const std::string &auth_str, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &insecure ,tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
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 &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure ,tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
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 &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 &pkd, const std::string &sid, const std::string &fp, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls, const std::string &sni, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &protocol, const std::string &method, const std::string &obfs, const std::string &password, const std::string &obfsparam, const std::string &protoparam, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
void ssConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &method, const std::string &plugin, const std::string &pluginopts, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void socksConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &network, const std::string &host, const std::string &path,const std::string &fp, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
void hysteriaConstruct(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 &auth,
const std::string &auth_str, const std::string &host, const std::string &up,
const std::string &down, const std::string &alpn, const std::string &obfsParam,
const std::string &insecure, const std::string &ports, const std::string &sni,
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
tribool tls13 = tribool(),const std::string& underlying_proxy="");
void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
const std::string &port, const std::string &password, const std::string &host,
const std::string &up, const std::string &down, const std::string &alpn,
const std::string &obfsParam, const std::string &obfsPassword, const std::string &sni,
const std::string &publicKey, const std::string &ports,
tribool udp, tribool tfo,
tribool scv,const std::string& underlying_proxy="");
void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
const std::string &port, const std::string &type, const std::string &id, const std::string &aid,
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 &pkd, const std::string &sid, const std::string &fp, const std::string &sni,
const std::vector<std::string> &alpnList,const std::string &packet_encoding,
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
tribool tls13 = tribool(),const std::string& underlying_proxy="",tribool v2ray_http_upgrade=tribool());
void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
const std::string &port, const std::string &type, const std::string &id, const std::string &aid,
const std::string &net, const std::string &cipher, const std::string &path, const std::string &host,
const std::string &edge, const std::string &tls, const std::string &sni,
const std::vector<std::string> &alpnList, tribool udp = tribool(),
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool(),const std::string& underlying_proxy="");
void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
const std::string &port, const std::string &protocol, const std::string &method,
const std::string &obfs, const std::string &password, const std::string &obfsparam,
const std::string &protoparam, tribool udp = tribool(), tribool tfo = tribool(),
tribool scv = tribool(),const std::string& underlying_proxy="");
void ssConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
const std::string &port, const std::string &password, const std::string &method,
const std::string &plugin, const std::string &pluginopts, tribool udp = tribool(),
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool(),const std::string& underlying_proxy="");
void socksConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
const std::string &port, const std::string &username, const std::string &password,
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),const std::string& underlying_proxy="");
void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
const std::string &port, const std::string &username, const std::string &password, bool tls,
tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool(),const std::string& underlying_proxy="");
void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
const std::string &port, const std::string &password, const std::string &network,
const std::string &host, const std::string &path, const std::string &fp, const std::string &sni,
const std::vector<std::string> &alpnList,
bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
tribool tls13 = tribool(),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,
const std::string &port, const std::string &password, const std::string &obfs,
const std::string &host, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(),
tribool scv = tribool(),const std::string& underlying_proxy="");
void tuicConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add,
const std::string &port, const std::string &password, const std::string &congestion_control,
const std::string &alpn,
const std::string &sni, const std::string &uuid, const std::string &udpRelayMode,
const std::string &token,
tribool udp = tribool(), tribool tfo = tribool(),
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 explodeSSR(std::string ssr, Proxy &node);
void explodeSS(std::string ss, Proxy &node);
void explodeTrojan(std::string trojan, 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 explodeStdVless(std::string vless, Proxy &node);
void explodeStdMieru(std::string mieru, Proxy &node);
void explodeStdHysteria(std::string hysteria, Proxy &node);
void explodeStdHysteria2(std::string hysteria2, Proxy &node);
void explodeShadowrocket(std::string kit, Proxy &node);
void explodeKitsunebi(std::string kit, Proxy &node);
void explodeVless(std::string vless, Proxy &node);
void explodeHysteria(std::string hysteria, Proxy &node);
void explodeHysteria2(std::string hysteria2, Proxy &node);
void explodeAnyTLS(std::string anytls, Proxy &node);
/// Parse a link
void explode(const std::string &link, Proxy &node);
void explodeSSD(std::string link, std::vector<Proxy> &nodes);
void explodeSub(std::string sub, std::vector<Proxy> &nodes);
int explodeConf(const std::string &filepath, std::vector<Proxy> &nodes);
int explodeConfContent(const std::string &content, std::vector<Proxy> &nodes);
#endif // SUBPARSER_H_INCLUDED

View File

@@ -2,6 +2,7 @@
#include <map>
#include <iostream>
#include <quickjspp.hpp>
#include <utility>
#include <quickjs/quickjs-libc.h>
#ifdef _WIN32
@@ -226,7 +227,7 @@ public:
qjs_fetch_Headers headers;
std::string cookies;
std::string postdata;
explicit qjs_fetch_Request(const std::string &url) : url(url) {}
explicit qjs_fetch_Request(std::string url) : url(std::move(url)) {}
};
class qjs_fetch_Response
@@ -389,7 +390,7 @@ void script_runtime_init(qjs::Runtime &runtime)
js_std_init_handlers(runtime.rt);
}
int ShowMsgbox(const std::string &title, std::string content, uint16_t type = 0)
int ShowMsgbox(const std::string &title, const std::string &content, uint16_t type = 0)
{
#ifdef _WIN32
if(!type)
@@ -424,7 +425,7 @@ struct Lambda {
uint32_t currentTime()
{
return time(NULL);
return time(nullptr);
}
int script_context_init(qjs::Context &context)
@@ -525,7 +526,7 @@ int script_context_init(qjs::Context &context)
)", "<import>", JS_EVAL_TYPE_MODULE);
return 0;
}
catch(qjs::exception)
catch(qjs::exception&)
{
script_print_stack(context);
return 1;

View File

@@ -47,16 +47,23 @@ static httplib::Server::Handler makeHandler(const responseRoute &rr)
{
continue;
}
req.headers[h.first] = h.second;
req.headers.emplace(h.first.data(), h.second.data());
}
req.argument = request.params;
if (request.get_header_value("Content-Type") == "application/x-www-form-urlencoded")
if (request.method == "POST" || request.method == "PUT" || request.method == "PATCH")
{
req.postdata = urlDecode(request.body);
}
else
{
req.postdata = request.body;
if (request.is_multipart_form_data() && !request.files.empty())
{
req.postdata = request.files.begin()->second.content;
}
else if (request.get_header_value("Content-Type") == "application/x-www-form-urlencoded")
{
req.postdata = urlDecode(request.body);
}
else
{
req.postdata = request.body;
}
}
auto result = rr.rc(req, resp);
response.status = resp.status_code;
@@ -163,6 +170,7 @@ int WebServer::start_web_server_multi(listener_args *args)
{
res.set_header("Access-Control-Allow-Headers", req.get_header_value("Access-Control-Request-Headers"));
}
res.set_header("Access-Control-Allow-Origin", "*");
return httplib::Server::HandlerResponse::Unhandled;
});
for (auto &x : redirect_map)
@@ -187,7 +195,7 @@ int WebServer::start_web_server_multi(listener_args *args)
{
try
{
std::rethrow_exception(e);
if (e) std::rethrow_exception(e);
}
catch (const httplib::Error &err)
{
@@ -212,6 +220,9 @@ int WebServer::start_web_server_multi(listener_args *args)
{
server.set_mount_point("/", serve_file_root);
}
server.new_task_queue = [args] {
return new httplib::ThreadPool(args->max_workers);
};
server.bind_to_port(args->listen_address, args->port, 0);
std::thread thread([&]()

View File

@@ -26,7 +26,8 @@ std::string getTime(int type)
format = "%Y%m%d-%H%M%S";
break;
case 2:
format = "%Y/%m/%d %a %H:%M:%S." + std::string(cMillis);
format = "%Y/%m/%d %a %H:%M:%S.";
format += cMillis;
break;
case 3:
default:

View File

@@ -9,7 +9,12 @@ struct strICaseComp
{
bool operator() (const std::string &lhs, const std::string &rhs) const
{
return strcasecmp(lhs.c_str(), rhs.c_str());
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
rhs.end(),
[](unsigned char c1, unsigned char c2)
{
return ::tolower(c1) < ::tolower(c2);
});
}
};

View File

@@ -3,88 +3,38 @@
#include <sstream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <cstdlib>
#include <ctime>
#include <random>
#include "string.h"
#include "map_extra.h"
std::vector<std::string> split(const std::string &s, const std::string &separator)
{
string_size bpos = 0, epos = s.find(separator);
std::vector<std::string> result;
string_size i = 0;
while(i != s.size())
while(bpos < s.size())
{
int flag = 0;
while(i != s.size() && flag == 0)
{
flag = 1;
for(char x : separator)
if(s[i] == x)
{
++i;
flag = 0;
break;
}
}
flag = 0;
string_size j = i;
while(j != s.size() && flag == 0)
{
for(char x : separator)
if(s[j] == x)
{
flag = 1;
break;
}
if(flag == 0)
++j;
}
if(i != j)
{
result.push_back(s.substr(i, j-i));
i = j;
}
if(epos == std::string::npos)
epos = s.size();
result.push_back(s.substr(bpos, epos - bpos));
bpos = epos + separator.size();
epos = s.find(separator, bpos);
}
return result;
}
void split(std::vector<std::string_view> &result, std::string_view s, char separator)
{
string_size i = 0;
while (i != s.size())
string_size bpos = 0, epos = s.find(separator);
while(bpos < s.size())
{
int flag = 0;
while(i != s.size() && flag == 0)
{
flag = 1;
if(s[i] == separator)
{
++i;
flag = 0;
break;
}
}
flag = 0;
string_size j = i;
while(j != s.size() && flag == 0)
{
if(s[j] == separator)
{
flag = 1;
break;
}
++j;
}
if (i != j)
{
result.push_back(s.substr(i, j-i));
i = j;
}
if(epos == std::string_view::npos)
epos = s.size();
result.push_back(s.substr(bpos, epos - bpos));
bpos = epos + 1;
epos = s.find(separator, bpos);
}
}
@@ -141,7 +91,7 @@ std::string toUpper(const std::string &str)
void processEscapeChar(std::string &str)
{
string_size pos = str.find('\\');
while(pos != str.npos)
while(pos != std::string::npos)
{
if(pos == str.size())
break;
@@ -191,7 +141,7 @@ void processEscapeCharReverse(std::string &str)
int parseCommaKeyValue(const std::string &input, const std::string &separator, string_pair_array &result)
{
string_size bpos = 0, epos = input.find(',');
string_size bpos = 0, epos = input.find(separator);
std::string kv;
while(bpos < input.size())
{
@@ -200,9 +150,9 @@ int parseCommaKeyValue(const std::string &input, const std::string &separator, s
else if(epos && input[epos - 1] == '\\')
{
kv += input.substr(bpos, epos - bpos - 1);
kv += ',';
kv += separator;
bpos = epos + 1;
epos = input.find(',', bpos);
epos = input.find(separator, bpos);
continue;
}
kv += input.substr(bpos, epos - bpos);
@@ -213,9 +163,9 @@ int parseCommaKeyValue(const std::string &input, const std::string &separator, s
result.emplace_back(kv.substr(0, eqpos), kv.substr(eqpos + 1));
kv.clear();
bpos = epos + 1;
epos = input.find(',', bpos);
epos = input.find(separator, bpos);
}
if(kv.size())
if(!kv.empty())
{
string_size eqpos = kv.find('=');
if(eqpos == std::string::npos)
@@ -328,12 +278,12 @@ std::string getUrlArg(const std::string &url, const std::string &request)
while(pos)
{
pos = url.rfind(pattern, pos);
if(pos != url.npos)
if(pos != std::string::npos)
{
if(pos == 0 || url[pos - 1] == '&' || url[pos - 1] == '?')
{
pos += pattern.size();
return url.substr(pos, url.find("&", pos) - pos);
return url.substr(pos, url.find('&', pos) - pos);
}
}
else
@@ -410,23 +360,24 @@ bool isStrUTF8(const std::string &data)
std::string randomStr(int len)
{
std::string retData;
srand(time(NULL));
int cnt = 0;
while(cnt < len)
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 61);
for(int i = 0; i < len; i++)
{
switch((rand() % 3))
int r = dis(gen);
if (r < 26)
{
case 1:
retData += ('A' + rand() % 26);
break;
case 2:
retData += ('a' + rand() % 26);
break;
default:
retData += ('0' + rand() % 10);
break;
retData.push_back('a' + r);
}
else if (r < 52)
{
retData.push_back('A' + r - 26);
}
else
{
retData.push_back('0' + r - 52);
}
cnt++;
}
return retData;
}
@@ -451,7 +402,7 @@ int to_int(const std::string &str, int def_value)
std::string join(const string_array &arr, const std::string &delimiter)
{
if(arr.size() == 0)
if(arr.empty())
return "";
if(arr.size() == 1)
return arr[0];

View File

@@ -1,6 +1,6 @@
#ifndef VERSION_H_INCLUDED
#define VERSION_H_INCLUDED
#define VERSION "v0.8.2"
#define VERSION "v0.9.9"
#endif // VERSION_H_INCLUDED