Compare commits

..

40 Commits

Author SHA1 Message Date
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
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
11 changed files with 787 additions and 454 deletions

View File

@@ -1,7 +1,6 @@
name: GitHub CI
on:
push:
branches: [ master ]
tags:
- '**'
workflow_dispatch:
@@ -62,55 +61,59 @@ jobs:
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
armv7_build:
name: Linux armv7 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: Set up QEMU
uses: docker/setup-qemu-action@v2
- 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: 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: Set up QEMU
uses: docker/setup-qemu-action@v2
- 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
macos_build:
name: macOS Build

View File

@@ -1,336 +1,130 @@
name: Publish Docker Image
on:
on:
push:
branches: [ master ]
tags:
- '**'
concurrency:
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 }}

View File

@@ -2,7 +2,7 @@
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)
[![Build Status](https://github.com/asdlokj1qpi23/subconverter/actions/workflows/docker.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)
@@ -59,9 +59,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

@@ -13,8 +13,8 @@ dest=base/config/
keep_tree=false
[DivineEngine]
url=https://github.com/DivineEngine/Profiles
checkout=f4d75f7d48a3f42129e030bef751d4d22bca02da
url=https://github.com/asdlokj1qpi23/DivineEngine.git
checkout=e5043a1cee1678254b424267bdcfccbcb574bad6
match=Surge/Ruleset/**
[NobyDa]

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

@@ -236,9 +236,8 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
tribool tfo = ext.tfo;
udp.define(x.UDP);
xudp.define(x.XUDP);
scv.define(x.AllowInsecure);
scv = x.AllowInsecure;
tfo.define(x.TCPFastOpen);
singleproxy["name"] = x.Remark;
singleproxy["server"] = x.Hostname;
singleproxy["port"] = x.Port;
@@ -382,10 +381,14 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
case ProxyType::Trojan:
singleproxy["type"] = "trojan";
singleproxy["password"] = x.Password;
if (!x.Host.empty())
if (!x.ServerName.empty())
singleproxy["sni"] = x.ServerName;
else if (!x.Host.empty()) {
singleproxy["sni"] = x.Host;
if (std::all_of(x.Password.begin(), x.Password.end(), ::isdigit) && !x.Password.empty())
}
if (std::all_of(x.Password.begin(), x.Password.end(), ::isdigit) && !x.Password.empty()) {
singleproxy["password"].SetTag("str");
}
if (!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
switch (hash_(x.TransferProtocol)) {
@@ -439,12 +442,16 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
singleproxy["auth-str"] = x.Auth;
singleproxy["up"] = x.UpMbps;
singleproxy["down"] = x.DownMbps;
if (!tfo.is_undef())
if (!x.Ports.empty()) {
singleproxy["ports"] = x.Ports;
}
if (!tfo.is_undef()) {
singleproxy["fast-open"] = tfo.get();
}
if (!x.FakeType.empty())
singleproxy["protocol"] = x.FakeType;
if (!x.Host.empty())
singleproxy["sni"] = x.Host;
if (!x.ServerName.empty())
singleproxy["sni"] = x.ServerName;
if (!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
if (x.Insecure == "1")
@@ -458,12 +465,16 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
singleproxy["type"] = "hysteria2";
singleproxy["password"] = x.Password;
singleproxy["auth"] = x.Password;
if (!x.PublicKey.empty()) {
singleproxy["ca-str"] = x.PublicKey;
}
if (!x.ServerName.empty()) {
singleproxy["sni"] = x.ServerName;
}
if (!x.UpMbps.empty())
singleproxy["up"] = x.UpMbps;
if (!x.DownMbps.empty())
singleproxy["down"] = x.DownMbps;
if (!x.Host.empty())
singleproxy["sni"] = x.Host;
if (!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
if (!x.Alpn.empty())
@@ -472,6 +483,8 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
singleproxy["obfs"] = x.OBFSParam;
if (!x.OBFSPassword.empty())
singleproxy["obfs-password"] = x.OBFSPassword;
if (!x.Ports.empty())
singleproxy["ports"] = x.Ports;
break;
case ProxyType::VLESS:
singleproxy["type"] = "vless";
@@ -481,8 +494,6 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
singleproxy["tfo"] = tfo.get();
if (xudp && udp)
singleproxy["xudp"] = true;
if (!x.Host.empty())
singleproxy["servername"] = x.Host;
if (!x.Flow.empty())
singleproxy["flow"] = x.Flow;
if (!scv.is_undef())
@@ -490,6 +501,8 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
if (!x.PublicKey.empty()) {
singleproxy["reality-opts"]["public-key"] = x.PublicKey;
}
if (!x.ServerName.empty())
singleproxy["servername"] = x.ServerName;
if (!x.ShortId.empty()) {
singleproxy["reality-opts"]["short-id"] = x.ShortId;
}
@@ -498,6 +511,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
}
switch (hash_(x.TransferProtocol)) {
case "tcp"_hash:
singleproxy["network"] = x.TransferProtocol;
break;
case "ws"_hash:
singleproxy["network"] = x.TransferProtocol;
@@ -744,7 +758,7 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
processRemark(x.Remark, remarks_list);
std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &edge = x.Edge, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption;
std::string &hostname = x.Hostname, &sni = x.ServerName, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &edge = x.Edge, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption;
std::string port = std::to_string(x.Port);
bool &tlssecure = x.TLSSecure;
@@ -860,8 +874,11 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
proxy = "trojan, " + hostname + ", " + port + ", password=" + password;
if (x.SnellVersion != 0)
proxy += ", version=" + std::to_string(x.SnellVersion);
if (!host.empty())
if (!sni.empty()) {
proxy += ", sni=" + sni;
} else if (!host.empty()) {
proxy += ", sni=" + host;
}
if (!scv.is_undef())
proxy += ", skip-cert-verify=" + scv.get_str();
break;
@@ -875,6 +892,13 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
if (x.SnellVersion != 0)
proxy += ", version=" + std::to_string(x.SnellVersion);
break;
case ProxyType::Hysteria2:
if (surge_ver < 4 && surge_ver != -3)
continue;
proxy = "hysteria2, " + hostname + ", " + port + ", password=" + password;
if (!scv.is_undef())
proxy += ", skip-cert-verify=" + scv.get_str();
break;
case ProxyType::WireGuard:
if (surge_ver < 4 && surge_ver != -3)
continue;
@@ -990,7 +1014,7 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
for (Proxy &x: nodes) {
std::string remark = x.Remark;
std::string &hostname = x.Hostname, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &faketype = x.FakeType;
std::string &hostname = x.Hostname, &sni = x.ServerName, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &faketype = x.FakeType;
bool &tlssecure = x.TLSSecure;
std::string port = std::to_string(x.Port);
std::string aid = std::to_string(x.AlterId);
@@ -1040,8 +1064,11 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
continue;
proxyStr = "trojan://" + password + "@" + hostname + ":" + port + "?allowInsecure=" +
(x.AllowInsecure.get() ? "1" : "0");
if (!host.empty())
if (!sni.empty()) {
proxyStr += "&sni=" + sni;
} else if (!host.empty()) {
proxyStr += "&sni=" + host;
}
if (transproto == "ws") {
proxyStr += "&ws=1";
if (!path.empty())
@@ -1407,6 +1434,23 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
} else if (tlssecure)
proxyStr += ", obfs=over-tls, obfs-host=" + host;
break;
case ProxyType::VLESS:
if (method == "auto")
method = "chacha20-ietf-poly1305";
proxyStr = "vless = " + hostname + ":" + port + ", method=" + method + ", password=" + id;
if (x.AlterId != 0)
proxyStr += ", aead=false";
if (tlssecure && !tls13.is_undef())
proxyStr += ", tls13=" + std::string(tls13 ? "true" : "false");
if (transproto == "ws") {
if (tlssecure)
proxyStr += ", obfs=wss";
else
proxyStr += ", obfs=ws";
proxyStr += ", obfs-host=" + host + ", obfs-uri=" + path;
} else if (tlssecure)
proxyStr += ", obfs=over-tls, obfs-host=" + host;
break;
case ProxyType::Shadowsocks:
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
if (!plugin.empty()) {
@@ -1938,14 +1982,48 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf, std::vector
proxy += ", keepalive=" + std::to_string(x.KeepAlive);
proxy += ", peers=[{" + generatePeer(x, true) + "}]";
break;
case ProxyType::Hysteria2:
proxy = "Hysteria2," + hostname + "," + port + ",\"" + password + "\"";
if(!x.ServerName.empty()){
proxy += ",sni="+x.ServerName;
}
if(!x.UpMbps.empty()){
std::string search = " Mbps";
size_t pos = x.UpMbps.find(search);
if (pos != std::string::npos) {
x.UpMbps.replace(pos, search.length(), "");
} else{
search = "Mbps";
pos = x.UpMbps.find(search);
if (pos != std::string::npos) {
x.UpMbps.replace(pos, search.length(), "");
}
}
proxy += ",download-bandwidth="+x.UpMbps;
}else{
proxy += ",download-bandwidth=100";
}
if (!scv.is_undef())
proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false");
break;
default:
continue;
}
if (ext.tfo)
if (ext.tfo){
proxy += ",fast-open=true";
if (ext.udp)
} else {
if (x.Type == ProxyType::Hysteria2){
proxy += ",fast-open=false";
}
}
if (ext.udp){
proxy += ",udp=true";
} else {
if (x.Type == ProxyType::Hysteria2){
proxy += ",udp=true";
}
}
if (ext.nodelist)
@@ -2163,6 +2241,9 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
if (!x.Plugin.empty() && !x.PluginOption.empty()) {
if (x.Plugin == "simple-obfs")
x.Plugin = "obfs-local";
if (x.Plugin != "obfs-local" && x.Plugin != "v2ray-plugin") {
continue;
}
proxy.AddMember("plugin", rapidjson::StringRef(x.Plugin.c_str()), allocator);
proxy.AddMember("plugin_opts", rapidjson::StringRef(x.PluginOption.c_str()), allocator);
}
@@ -2276,7 +2357,9 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
auto reserved = stringArrayToJsonArray(x.ClientId, ",", allocator);
peer.AddMember("reserved", reserved, allocator);
}
if (!x.Password.empty()) {
proxy.AddMember("pre_shared_key", rapidjson::StringRef(x.Password.c_str()), allocator);
}
rapidjson::Value peers(rapidjson::kArrayType);
peers.PushBack(peer, allocator);
proxy.AddMember("peers", peers, allocator);
@@ -2325,6 +2408,9 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
auto alpns = stringArrayToJsonArray(x.Alpn, ",", allocator);
tls.AddMember("alpn", alpns, allocator);
}
if (!x.ServerName.empty()) {
tls.AddMember("server_name", rapidjson::StringRef(x.ServerName.c_str()), allocator);
}
tls.AddMember("insecure", buildBooleanValue(scv), allocator);
proxy.AddMember("tls", tls, allocator);
}
@@ -2338,12 +2424,18 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
addSingBoxCommonMembers(proxy, x, "hysteria2", allocator);
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
if (!x.TLSSecure) {
rapidjson::Value tls(rapidjson::kObjectType);
tls.AddMember("enabled", true, allocator);
if (!x.ServerName.empty())
tls.AddMember("server_name", rapidjson::StringRef(x.ServerName.c_str()), allocator);
if (!x.Alpn.empty()) {
auto alpns = stringArrayToJsonArray(x.Alpn, ",", allocator);
tls.AddMember("alpn", alpns, allocator);
}
if (!x.PublicKey.empty()) {
tls.AddMember("certificate", rapidjson::StringRef(x.PublicKey.c_str()), allocator);
}
tls.AddMember("insecure", buildBooleanValue(scv), allocator);
proxy.AddMember("tls", tls, allocator);
}
@@ -2366,15 +2458,13 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
proxy.AddMember("down_mbps", std::stoi(x.DownMbps), allocator);
}
if (!x.OBFSParam.empty()) {
rapidjson::Value obfs(rapidjson::kObjectType);
obfs.AddMember("type", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
if (!x.OBFSPassword.empty()) {
proxy.AddMember("obfs", rapidjson::StringRef(std::string(
R"({ "type": )" + x.OBFSParam + ",password: \"" + x.OBFSPassword + "\"}").c_str()),
allocator);
} else {
proxy.AddMember("obfs",
rapidjson::StringRef(std::string(R"({ "type": )" + x.OBFSParam + "}").c_str()),
allocator);
obfs.AddMember("password", rapidjson::StringRef(x.OBFSPassword.c_str()), allocator);
}
proxy.AddMember("obfs", obfs, allocator);
}
break;
}
@@ -2394,10 +2484,6 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
if (x.Type == ProxyType::VLESS) {
rapidjson::Value reality(rapidjson::kObjectType);
if (!x.PublicKey.empty() || !x.ShortId.empty()) {
if (!x.Host.empty()) {
tls.EraseMember("server_name");
tls.AddMember("server_name", rapidjson::StringRef(x.Host.c_str()), allocator);
}
rapidjson::Value utls(rapidjson::kObjectType);
utls.AddMember("enabled", true, allocator);
utls.AddMember("fingerprint", rapidjson::StringRef("chrome"), allocator);
@@ -2406,8 +2492,12 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::vector
if (!x.PublicKey.empty()) {
reality.AddMember("public_key", rapidjson::StringRef(x.PublicKey.c_str()), allocator);
}
auto shortIds = stringArrayToJsonArray(x.Alpn, ",", allocator);
reality.AddMember("short_id", shortIds, allocator);
// auto shortIds = stringArrayToJsonArray(x.ShortId, ",", allocator);
if (!x.ShortId.empty()) {
reality.AddMember("short_id", rapidjson::StringRef(x.ShortId.c_str()), allocator);
} else {
reality.AddMember("short_id", rapidjson::StringRef(""), allocator);
}
tls.AddMember("reality", reality, allocator);
}
}

View File

@@ -109,7 +109,7 @@ struct Proxy {
uint16_t KeepAlive = 0;
String TestUrl;
String ClientId;
String Ports;
String Auth;
String Alpn;
String UpMbps;

View File

@@ -12,6 +12,7 @@
#include "utils/yamlcpp_extra.h"
#include "config/proxy.h"
#include "subparser.h"
#include "utils/logger.h"
using namespace rapidjson;
using namespace rapidjson_ext;
@@ -115,7 +116,8 @@ void httpConstruct(Proxy &node, const std::string &group, const std::string &rem
void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
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,
const std::string &host, const std::string &path, const std::string &fp, const std::string &sni,
bool tlssecure,
tribool udp, tribool tfo,
tribool scv, tribool tls13) {
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13);
@@ -125,6 +127,7 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
node.TransferProtocol = network.empty() ? "tcp" : network;
node.Path = path;
node.Fingerprint = fp;
node.ServerName = sni;
}
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server,
@@ -156,9 +159,12 @@ void wireguardConstruct(Proxy &node, const std::string &group, const std::string
}
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 &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 tfo, tribool scv,
const std::string &obfsParam, const std::string &insecure, const std::string &ports,
const std::string &sni, tribool udp,
tribool tfo, tribool scv,
tribool tls13) {
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13);
node.Auth = auth;
@@ -170,6 +176,8 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
node.Insecure = insecure;
node.FakeType = type;
node.AuthStr = auth_str;
node.Ports = ports;
node.ServerName = sni;
}
@@ -177,7 +185,8 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
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 &pbk, const std::string &sid, const std::string &fp, tribool udp, tribool tfo,
const std::string &pbk, const std::string &sid, const std::string &fp, const std::string &sni,
tribool udp, tribool tfo,
tribool scv, tribool tls13) {
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13);
node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
@@ -191,7 +200,7 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
node.PublicKey = pbk;
node.ShortId = sid;
node.Fingerprint = fp;
node.ServerName = sni;
switch (hash_(net)) {
case "grpc"_hash:
node.Host = host;
@@ -213,7 +222,9 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
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, tribool udp, tribool tfo,
const std::string &obfsParam, const std::string &obfsPassword, const std::string &sni,
const std::string &publicKey, const std::string &ports,
tribool udp, tribool tfo,
tribool scv) {
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool());
node.Password = password;
@@ -223,6 +234,9 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string
node.Alpn = alpn;
node.OBFSParam = obfsParam;
node.OBFSPassword = obfsPassword;
node.ServerName = sni;
node.PublicKey = publicKey;
node.Ports = ports;
}
void explodeVmess(std::string vmess, Proxy &node) {
@@ -796,7 +810,7 @@ void explodeHTTPSub(std::string link, Proxy &node) {
}
void explodeTrojan(std::string trojan, Proxy &node) {
std::string server, port, psk, addition, group, remark, host, path, network, fp;
std::string server, port, psk, addition, group, remark, host, path, network, fp, sni;
tribool tfo, scv;
if (startsWith(trojan, "trojan://")) {
trojan.erase(0, 9);
@@ -821,6 +835,7 @@ void explodeTrojan(std::string trojan, Proxy &node) {
return;
host = getUrlArg(addition, "sni");
sni = getUrlArg(addition, "sni");
if (host.empty())
host = getUrlArg(addition, "peer");
tfo = getUrlArg(addition, "tfo");
@@ -846,7 +861,7 @@ void explodeTrojan(std::string trojan, Proxy &node) {
if (group.empty())
group = TROJAN_DEFAULT_GROUP;
trojanConstruct(node, group, remark, server, port, psk, network, host, path, fp, true, tribool(), tfo, scv);
trojanConstruct(node, group, remark, server, port, psk, network, host, path, fp, sni, true, tribool(), tfo, scv);
}
void explodeVless(std::string vless, Proxy &node) {
@@ -858,6 +873,7 @@ void explodeVless(std::string vless, Proxy &node) {
void explodeHysteria(std::string hysteria, Proxy &node) {
printf("explodeHysteria\n");
hysteria = regReplace(hysteria, "(hysteria|hy)://", "hysteria://");
if (regMatch(hysteria, "hysteria://(.*?)[:](.*)")) {
explodeStdHysteria(hysteria, node);
return;
@@ -1021,9 +1037,11 @@ void explodeNetch(std::string netch, Proxy &node) {
path = GetMember(json, "Path");
transprot = GetMember(json, "TransferProtocol");
tls = GetMember(json, "TLSSecure");
sni = host;
if (group.empty())
group = TROJAN_DEFAULT_GROUP;
trojanConstruct(node, group, remark, address, port, password, transprot, host, path, fp, tls == "true", udp,
trojanConstruct(node, group, remark, address, port, password, transprot, host, path, fp, sni, tls == "true",
udp,
tfo, scv);
break;
case "Snell"_hash:
@@ -1040,22 +1058,22 @@ void explodeNetch(std::string netch, Proxy &node) {
}
void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
std::string proxytype, ps, server, port, cipher, group, password = "", tempPassword; //common
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
std::string fp = "chrome", pbk, sid; //vless
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
std::string protocol, protoparam, obfs, obfsparam; //ssr
std::string flow, mode; //trojan
std::string user; //socks
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
std::string obfsPassword;//hysteria2
string_array dns_server;
tribool udp, tfo, scv;
Node singleproxy;
uint32_t index = nodes.size();
const std::string section = yamlnode["proxies"].IsDefined() ? "proxies" : "Proxy";
for (uint32_t i = 0; i < yamlnode[section].size(); i++) {
std::string proxytype, ps, server, port, cipher, group, password = "", ports, tempPassword; //common
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
std::string fp = "chrome", pbk, sid; //vless
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
std::string protocol, protoparam, obfs, obfsparam; //ssr
std::string flow, mode; //trojan
std::string user; //socks
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
std::string obfsPassword;//hysteria2
string_array dns_server;
tribool udp, tfo, scv;
Proxy node;
singleproxy = yamlnode[section][i];
singleproxy["type"] >>= proxytype;
@@ -1068,9 +1086,11 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
scv = safe_as<std::string>(singleproxy["skip-cert-verify"]);
switch (hash_(proxytype)) {
case "vmess"_hash:
group = V2RAY_DEFAULT_GROUP;
singleproxy["uuid"] >>= id;
if (id.length() < 36) {
break;
}
group = V2RAY_DEFAULT_GROUP;
singleproxy["alterId"] >>= aid;
singleproxy["cipher"] >>= cipher;
net = singleproxy["network"].IsDefined() ? safe_as<std::string>(singleproxy["network"]) : "tcp";
@@ -1212,6 +1232,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
group = TROJAN_DEFAULT_GROUP;
singleproxy["password"] >>= password;
singleproxy["sni"] >>= host;
singleproxy["sni"] >>= sni;
singleproxy["network"] >>= net;
switch (hash_(net)) {
case "grpc"_hash:
@@ -1226,7 +1247,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
break;
}
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, true, udp, tfo, scv);
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, sni, true, udp, tfo, scv);
break;
case "snell"_hash:
group = SNELL_DEFAULT_GROUP;
@@ -1300,7 +1321,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
singleproxy["flow"] >>= flow;
vlessConstruct(node, XRAY_DEFAULT_GROUP, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
host, "", tls, pbk, sid, fp);
host, "", tls, pbk, sid, fp, sni);
break;
case "hysteria"_hash:
group = HYSTERIA_DEFAULT_GROUP;
@@ -1318,8 +1339,10 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
singleproxy["sni"] >> host;
singleproxy["alpn"][0] >> alpn;
singleproxy["protocol"] >> insecure;
hysteriaConstruct(node, group, ps, server, port, type, auth,"", host, up, down, alpn, obfsParam, insecure,
singleproxy["ports"] >> ports;
sni = host;
hysteriaConstruct(node, group, ps, server, port, type, auth, "", host, up, down, alpn, obfsParam,
insecure, ports, sni,
udp, tfo, scv);
break;
case "hysteria2"_hash:
@@ -1333,9 +1356,10 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
singleproxy["obfs-password"] >>= obfsPassword;
singleproxy["sni"] >>= host;
singleproxy["alpn"][0] >>= alpn;
singleproxy["ports"] >> ports;
sni = host;
hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam,
obfsPassword, udp, tfo, scv);
obfsPassword, sni, public_key, ports, udp, tfo, scv);
break;
default:
continue;
@@ -1389,7 +1413,7 @@ void explodeStdVMess(std::string vmess, Proxy &node) {
void explodeStdHysteria(std::string hysteria, Proxy &node) {
std::string add, port, type, auth, host, insecure, up, down, alpn, obfsParam, remarks,auth_str;
std::string add, port, type, auth, host, insecure, up, down, alpn, obfsParam, remarks, auth_str, sni;
std::string addition;
hysteria = hysteria.substr(11);
string_size pos;
@@ -1411,16 +1435,19 @@ void explodeStdHysteria(std::string hysteria, Proxy &node) {
down = getUrlArg(addition, "downmbps");
alpn = getUrlArg(addition, "alpn");
obfsParam = getUrlArg(addition, "obfsParam");
sni = getUrlArg(addition, "peer");
if (remarks.empty())
remarks = add + ":" + port;
hysteriaConstruct(node, HYSTERIA_DEFAULT_GROUP, remarks, add, port, type, auth,auth_str, host, up, down, alpn, obfsParam,
insecure);
hysteriaConstruct(node, HYSTERIA_DEFAULT_GROUP, remarks, add, port, type, auth, auth_str, host, up, down, alpn,
obfsParam,
insecure, "", sni);
return;
}
void explodeStdHysteria2(std::string hysteria2, Proxy &node) {
std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks;
std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks, sni ,ports;
std::string addition;
tribool scv;
hysteria2 = hysteria2.substr(12);
@@ -1460,18 +1487,19 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) {
obfsParam = getUrlArg(addition, "obfs");
obfsPassword = getUrlArg(addition, "obfs-password");
host = getUrlArg(addition, "sni");
sni = getUrlArg(addition, "sni");
ports = getUrlArg(addition, "ports");
if (remarks.empty())
remarks = add + ":" + port;
hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam,
obfsPassword, tribool(), tribool(), scv);
obfsPassword, host, "", ports, tribool(), tribool(), scv);
return;
}
void explodeStdVless(std::string vless, Proxy &node) {
std::string add, port, type, id, aid, net, flow, pbk, sid, fp, mode, path, host, tls, remarks;
std::string add, port, type, id, aid, net, flow, pbk, sid, fp, mode, path, host, tls, remarks, sni;
std::string addition;
vless = vless.substr(8);
string_size pos;
@@ -1516,9 +1544,9 @@ void explodeStdVless(std::string vless, Proxy &node) {
if (remarks.empty())
remarks = add + ":" + port;
sni = getUrlArg(addition, "sni");
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", flow, mode, path, host, "",
tls, pbk, sid, fp);
tls, pbk, sid, fp, sni);
return;
}
@@ -1655,7 +1683,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
const std::string proxystr = "(.*?)\\s*=\\s*(.*)";
for (auto &x: proxies) {
std::string remarks, server, port, method, username, password; //common
std::string remarks, server, port, method, username, password, sni; //common
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, mod_url, mod_md5; //ss
std::string id, net, tls, host, edge, path, fp; //v2
std::string protocol, protoparam; //ssr
@@ -1926,6 +1954,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
break;
case "sni"_hash:
host = itemVal;
sni = itemVal;
break;
case "udp-relay"_hash:
udp = itemVal;
@@ -1944,7 +1973,8 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
}
}
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp, true,
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp, sni,
true,
udp,
tfo, scv);
break;
@@ -2209,6 +2239,73 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
path, host, "", tls, "", udp, tfo, scv, tls13);
break;
case "vless"_hash: //quantumult x style vless link
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = trim(configs[0].substr(configs[0].rfind(":") + 1));
if (port == "0")
continue;
net = "tcp";
for (i = 1; i < configs.size(); i++) {
vArray = split(trim(configs[i]), "=");
if (vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch (hash_(itemName)) {
case "method"_hash:
method = itemVal;
break;
case "password"_hash:
id = itemVal;
break;
case "tag"_hash:
remarks = itemVal;
break;
case "obfs"_hash:
switch (hash_(itemVal)) {
case "ws"_hash:
net = "ws";
break;
case "over-tls"_hash:
tls = "tls";
break;
case "wss"_hash:
net = "ws";
tls = "tls";
break;
}
break;
case "obfs-host"_hash:
host = itemVal;
break;
case "obfs-uri"_hash:
path = itemVal;
break;
case "over-tls"_hash:
tls = itemVal == "true" ? "tls" : "";
break;
case "udp-relay"_hash:
udp = itemVal;
break;
case "fast-open"_hash:
tfo = itemVal;
break;
case "tls13"_hash:
tls13 = itemVal;
break;
case "aead"_hash:
aead = itemVal == "true" ? "0" : "1";
default:
continue;
}
}
if (remarks.empty())
remarks = server + ":" + port;
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
"chrome", "", path, host, "",
tls, "", "", fp, sni, udp, tfo, scv, tls13);
break;
case "trojan"_hash: //quantumult x style trojan link
server = trim(configs[0].substr(0, configs[0].rfind(':')));
port = trim(configs[0].substr(configs[0].rfind(':') + 1));
@@ -2233,6 +2330,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
break;
case "tls-host"_hash:
host = itemVal;
sni = itemVal;
break;
case "udp-relay"_hash:
udp = itemVal;
@@ -2257,6 +2355,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
remarks = server + ":" + port;
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", fp,
sni,
tls == "true", udp, tfo, scv, tls13);
break;
case "http"_hash: //quantumult x style http links
@@ -2443,6 +2542,237 @@ int explodeConfContent(const std::string &content, std::vector<Proxy> &nodes) {
return !nodes.empty();
}
void explodeSingboxTransport(rapidjson::Value &singboxNode, std::string &net, std::string &host, std::string &path,
std::string edge) {
if (singboxNode.HasMember("transport") && singboxNode["transport"].IsObject()) {
rapidjson::Value transport = singboxNode["transport"].GetObject();
net = GetMember(transport, "type");
switch (hash_(net)) {
case "http"_hash: {
host = GetMember(transport, "host");
break;
}
case "ws"_hash: {
path = GetMember(transport, "path");
if (transport.HasMember("headers") && transport["headers"].IsObject()) {
rapidjson::Value headers = transport["headers"].GetObject();
host = GetMember(headers, "Host");
edge = GetMember(headers, "Edge");
}
break;
}
case "grpc"_hash: {
path = GetMember(transport, "service_name");
break;
}
default:
net = "tcp";
path.clear();
break;
}
} else {
net = "tcp";
host.clear();
edge.clear();
path.clear();
}
}
void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
uint32_t index = nodes.size();
for (rapidjson::SizeType i = 0; i < outbounds.Size(); ++i) {
if (outbounds[i].IsObject()) {
std::string proxytype, ps, server, port, cipher, group, password, ports, tempPassword; //common
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
std::string fp = "chrome", pbk, sid; //vless
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
std::string protocol, protoparam, obfs, obfsparam; //ssr
std::string flow, mode; //trojan
std::string user; //socks
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
std::string obfsPassword;//hysteria2
string_array dns_server;
tribool udp, tfo, scv;
rapidjson::Value singboxNode = outbounds[i].GetObject();
if (singboxNode.HasMember("type") && singboxNode["type"].IsString()) {
Proxy node;
proxytype = singboxNode["type"].GetString();
ps = GetMember(singboxNode, "tag");
server = GetMember(singboxNode, "server");
port = GetMember(singboxNode, "server_port");
tfo = GetMember(singboxNode, "tcp_fast_open");
if (singboxNode.HasMember("tls") && singboxNode["tls"].IsObject()) {
rapidjson::Value tlsObj = singboxNode["tls"].GetObject();
if (tlsObj.HasMember("enabled") && tlsObj["enabled"].IsBool() && tlsObj["enabled"].GetBool()) {
tls = "tls";
}
sni = GetMember(tlsObj, "server_name");
if (tlsObj.HasMember("alpn") && tlsObj["alpn"].IsArray() && !tlsObj["alpn"].Empty()) {
rapidjson::Value alpns = tlsObj["alpn"].GetArray();
if (alpns.Size() > 0) {
alpn = alpns[0].GetString();
}
}
if (tlsObj.HasMember("insecure") && tlsObj["insecure"].IsBool()) {
scv = tlsObj["insecure"].GetBool();
}
if (tlsObj.HasMember("certificate") && tlsObj["certificate"].IsString()) {
public_key = tlsObj["certificate"].GetString();
}
if (tlsObj.HasMember("reality") && tlsObj["reality"].IsObject()) {
tls = "reality";
rapidjson::Value reality = tlsObj["reality"].GetObject();
if (reality.HasMember("server_name") && reality["server_name"].IsString()) {
host = reality["server_name"].GetString();
}
if (reality.HasMember("public_key") && reality["public_key"].IsString()) {
pbk = reality["public_key"].GetString();
}
if (reality.HasMember("short_id") && reality["short_id"].IsString()) {
sid = reality["short_id"].GetString();
}
}
} else {
tls = "false";
}
switch (hash_(proxytype)) {
case "vmess"_hash:
group = V2RAY_DEFAULT_GROUP;
id = GetMember(singboxNode, "uuid");
if (id.length() < 36) {
break;
}
aid = GetMember(singboxNode, "alter_id");
cipher = GetMember(singboxNode, "security");
explodeSingboxTransport(singboxNode, net, host, path, edge);
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls,
sni, udp,
tfo, scv);
break;
case "shadowsocks"_hash:
group = SS_DEFAULT_GROUP;
cipher = GetMember(singboxNode, "method");
password = GetMember(singboxNode, "password");
plugin = GetMember(singboxNode, "plugin");
pluginopts = GetMember(singboxNode, "plugin_opts");
ssConstruct(node, group, ps, server, port, password, cipher, plugin, pluginopts, udp, tfo, scv);
break;
case "trojan"_hash:
group = TROJAN_DEFAULT_GROUP;
password = GetMember(singboxNode, "password");
explodeSingboxTransport(singboxNode, net, host, path, edge);
trojanConstruct(node, group, ps, server, port, password, net, host, path, fp, sni, true, udp,
tfo,
scv);
break;
case "vless"_hash:
group = XRAY_DEFAULT_GROUP;
id = GetMember(singboxNode, "uuid");
flow = GetMember(singboxNode, "flow");
if (singboxNode.HasMember("transport") && singboxNode["transport"].IsObject()) {
rapidjson::Value transport = singboxNode["transport"].GetObject();
net = GetMember(transport, "type");
switch (hash_(net)) {
case "tcp"_hash: {
break;
}
case "ws"_hash: {
path = GetMember(transport, "path");
if (transport.HasMember("headers") && transport["headers"].IsObject()) {
rapidjson::Value headers = transport["headers"].GetObject();
host = GetMember(headers, "Host");
edge = GetMember(headers, "Edge");
}
break;
}
case "http"_hash: {
host = GetMember(transport, "host");
path = GetMember(transport, "path");
edge.clear();
break;
}
case "httpupgrade"_hash: {
net = "h2";
host = GetMember(transport, "host");
path = GetMember(transport, "path");
edge.clear();
break;
}
case "grpc"_hash: {
host = server;
path = GetMember(transport, "service_name");
break;
}
}
}
vlessConstruct(node, group, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
host, "", tls, pbk, sid, fp, sni);
break;
case "http"_hash:
password = GetMember(singboxNode, "password");
user = GetMember(singboxNode, "username");
httpConstruct(node, group, ps, server, port, user, password, tls == "tls", tfo, scv);
break;
case "wireguard"_hash:
group = WG_DEFAULT_GROUP;
ip = GetMember(singboxNode, "inet4_bind_address");
ipv6 = GetMember(singboxNode, "inet6_bind_address");
public_key = GetMember(singboxNode, "private_key");
private_key = GetMember(singboxNode, "public_key");
mtu = GetMember(singboxNode, "mtu");
password = GetMember(singboxNode, "pre_shared_key");
dns_server = {"8.8.8.8"};
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
dns_server, mtu, "0", "", "", udp);
break;
case "socks"_hash:
group = SOCKS_DEFAULT_GROUP;
user = GetMember(singboxNode, "username");
password = GetMember(singboxNode, "password");
socksConstruct(node, group, ps, server, port, user, password);
break;
case "hysteria"_hash:
group = HYSTERIA_DEFAULT_GROUP;
up = GetMember(singboxNode, "up");
if (up.empty()) {
up = GetMember(singboxNode, "up_mbps");
}
down = GetMember(singboxNode, "down");
if (down.empty()) {
down = GetMember(singboxNode, "down_mbps");
}
auth = GetMember(singboxNode, "auth_str");
type = GetMember(singboxNode, "network");
obfsParam = GetMember(singboxNode, "obfs");
hysteriaConstruct(node, group, ps, server, port, type, auth, "", host, up, down, alpn,
obfsParam, insecure, ports, sni,
udp, tfo, scv);
break;
case "hysteria2"_hash:
group = HYSTERIA2_DEFAULT_GROUP;
password = GetMember(singboxNode, "password");
up = GetMember(singboxNode, "up");
down = GetMember(singboxNode, "down");
if (singboxNode.HasMember("obfs") && singboxNode["obfs"].IsObject()) {
rapidjson::Value obfsOpt = singboxNode["obfs"].GetObject();
obfsParam = GetMember(obfsOpt, "type");
obfsPassword = GetMember(obfsOpt, "password");
}
hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam,
obfsPassword, sni, public_key, "", udp, tfo, scv);
break;
default:
continue;
}
node.Id = index;
nodes.emplace_back(std::move(node));
index++;
}
}
}
}
void explode(const std::string &link, Proxy &node) {
if (startsWith(link, "ssr://"))
explodeSSR(link, node);
@@ -2460,7 +2790,7 @@ void explode(const std::string &link, Proxy &node) {
explodeTrojan(link, node);
else if (strFind(link, "vless://") || strFind(link, "vless1://"))
explodeVless(link, node);
else if (strFind(link, "hysteria://"))
else if (strFind(link, "hysteria://") || strFind(link, "hy://"))
explodeHysteria(link, node);
else if (strFind(link, "hysteria2://") || strFind(link, "hy2://"))
explodeHysteria2(link, node);
@@ -2495,7 +2825,33 @@ void explodeSub(std::string sub, std::vector<Proxy> &nodes) {
//ignore
throw;
}
try {
std::string pattern = "\"?(inbounds)\"?:";
if (!processed &&
regFind(sub, pattern)) {
pattern = "\"?(outbounds)\"?:";
if (regFind(sub, pattern)) {
pattern = "\"?(route)\"?:";
if (regFind(sub, pattern)) {
rapidjson::Document document;
document.Parse(sub.c_str());
if (!document.HasParseError() || document.IsObject()) {
rapidjson::Value &value = document["outbounds"];
if (value.IsArray() && !value.Empty()) {
explodeSingbox(value, nodes);
processed = true;
}
}
}
}
}
}
catch (std::exception &e) {
writeLog(LOG_TYPE_ERROR, e.what(), LOG_LEVEL_ERROR);
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
//ignore
throw;
}
//try to parse as surge configuration
if (!processed && explodeSurge(sub, nodes)) {
processed = true;

View File

@@ -5,8 +5,7 @@
#include "config/proxy.h"
enum class ConfType
{
enum class ConfType {
Unknow,
SS,
SSR,
@@ -19,36 +18,104 @@ 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());
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);
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,
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, const std::string &sni,
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 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 explodeStdVMess(std::string vmess, Proxy &node);
void explodeStdVless(std::string vless, 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);
/// 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

@@ -5,11 +5,9 @@
#include <map>
#include <string.h>
struct strICaseComp
{
bool operator() (const std::string &lhs, const std::string &rhs) const
{
return strcasecmp(lhs.c_str(), rhs.c_str());
struct strICaseComp {
bool operator()(const std::string &lhs, const std::string &rhs) const {
return strcasecmp(lhs.c_str(), rhs.c_str()) > 0;
}
};

View File

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