Init meta version

This commit is contained in:
Maze.tsz 2022-01-19 18:23:24 +08:00 committed by metacubex
parent d47b8868e5
commit 7b473676a5
12 changed files with 440 additions and 601 deletions

View File

@ -58,9 +58,11 @@ jobs:
armv7_build: armv7_build:
name: Linux armv7 Build name: Linux armv7 Build
runs-on: [self-hosted, linux, ARM64] runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Add commit id into version - name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }} 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 run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
@ -81,11 +83,38 @@ jobs:
files: subconverter_armv7.tar.gz files: subconverter_armv7.tar.gz
draft: true draft: true
aarch64_build: armhf_build:
name: Linux aarch64 Build name: Linux armhf Build
runs-on: [self-hosted, linux, ARM64] runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- 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 -v $GITHUB_WORKSPACE:/root/workdir multiarch/alpine:armhf-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@v1
with:
name: subconverter_armhf
path: subconverter/
- name: Package Release
run: tar czf subconverter_armhf.tar.gz subconverter
- name: Draft Release
uses: softprops/action-gh-release@v1
with:
files: subconverter_armhf.tar.gz
release: true
aarch64_build:
name: Linux aarch64 Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Add commit id into version - name: Add commit id into version
if: ${{ !startsWith(github.ref, 'refs/tags/') }} 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 run: SHA=$(git rev-parse --short HEAD) && sed -i 's/\(v[0-9]\.[0-9]\.[0-9]\)/\1-'"$SHA"'/' src/version.h
@ -97,14 +126,12 @@ jobs:
name: subconverter_aarch64 name: subconverter_aarch64
path: subconverter/ path: subconverter/
- name: Package Release - name: Package Release
if: startsWith(github.ref, 'refs/tags/')
run: tar czf subconverter_aarch64.tar.gz subconverter run: tar czf subconverter_aarch64.tar.gz subconverter
- name: Draft Release - name: Draft Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with: with:
files: subconverter_aarch64.tar.gz files: subconverter_aarch64.tar.gz
draft: true release: true
macos_build: macos_build:
name: macOS Build name: macOS Build

View File

@ -1,382 +0,0 @@
name: Publish Docker Image
on: [push]
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
jobs:
amd64_build:
name: Build AMD64 Image
runs-on: ubuntu-latest
steps:
- name: Checkout base
uses: actions/checkout@v2
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 "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- 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: tindy2013/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@v1
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: tindy2013/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@v2
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 "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- 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: tindy2013/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@v1
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: tindy2013/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_386
path: /tmp/digest.txt
armv7_build:
name: Build ARMv7 Image
runs-on: [self-hosted, linux, ARM64]
steps:
- name: Checkout base
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- 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 "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- 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: tindy2013/subconverter:latest
build-args: |
SHA=${{ steps.vars.outputs.sha_short }}
THREADS=2
outputs: type=image,push=true
- name: Replace tag without `v`
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v1
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: tindy2013/subconverter:${{steps.version.outputs.result}}
build-args: |
THREADS=2
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@v2
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- 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 "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- 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: tindy2013/subconverter:latest
build-args: |
SHA=${{ steps.vars.outputs.sha_short }}
THREADS=2
outputs: type=image,push=true
- name: Replace tag without `v`
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v1
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: tindy2013/subconverter:${{steps.version.outputs.result}}
build-args: |
THREADS=2
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]
runs-on: ubuntu-latest
steps:
- name: Checkout base
uses: actions/checkout@v2
with:
fetch-depth: 0
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
# 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
- name: Download artifact
uses: actions/download-artifact@v3
with:
path: /tmp/images/
# - name: Load image
# if: github.ref == 'refs/heads/master'
# run: |
# docker load --input /tmp/image_amd64/image_amd64.tar
# docker load --input /tmp/image_386/image_386.tar
# docker load --input /tmp/image_armv7/image_armv7.tar
# docker load --input /tmp/image_arm64/image_arm64.tar
# docker image ls -a
- 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 "::set-output name=sha_short::$(git rev-parse --short HEAD)"
# - name: Docker buildx image and push on master branch
# if: github.ref == 'refs/heads/master'
# uses: docker/build-push-action@v3
# with:
# platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/386
# context: scripts/
# tags: tindy2013/subconverter:latest
# build-args: |
# SHA=${{ steps.vars.outputs.sha_short }}
# THREADS=1
# outputs: |
# type=image,push=true
- name: Replace tag without `v`
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v1
id: version
with:
script: |
return context.payload.ref.replace(/\/?refs\/tags\/v/, '')
result-encoding: string
# - name: Load release image
# if: startsWith(github.ref, 'refs/tags/')
# run: |
# docker load --input /tmp/image_amd64/image_amd64_release.tar
# docker load --input /tmp/image_386/image_386_release.tar
# docker load --input /tmp/image_armv7/image_armv7_release.tar
# docker load --input /tmp/image_arm64/image_arm64_release.tar
# docker image ls -a
# - name: Docker buildx image and push on release
# if: startsWith(github.ref, 'refs/tags/')
# uses: docker/build-push-action@v3
# with:
# platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/386
# context: scripts/
# tags: tindy2013/subconverter:${{steps.version.outputs.result}}
# build-args: THREADS=1
# outputs: type=image,push=true
- name: Merge and push manifest on master branch
if: github.ref == 'refs/heads/master'
run: python scripts/merge_manifest.py
- name: Merge and push manifest on release
if: startsWith(github.ref, 'refs/tags/')
run: python scripts/merge_manifest.py ${{steps.version.outputs.result}}

View File

@ -40,7 +40,7 @@ cd ..
git clone https://github.com/ToruNiina/toml11 --depth=1 git clone https://github.com/ToruNiina/toml11 --depth=1
cd toml11 cd toml11
cmake . cmake -DCMAKE_CXX_STANDARD=17 .
make install -j4 make install -j4
cd .. cd ..

View File

@ -41,7 +41,7 @@ cd ..
git clone https://github.com/ToruNiina/toml11 --depth=1 git clone https://github.com/ToruNiina/toml11 --depth=1
cd toml11 cd toml11
cmake . cmake -DCMAKE_CXX_STANDARD=17 .
make install -j4 make install -j4
cd .. cd ..

View File

@ -44,7 +44,7 @@ cd ..
git clone https://github.com/ToruNiina/toml11 --depth=1 git clone https://github.com/ToruNiina/toml11 --depth=1
cd toml11 cd toml11
cmake -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" . cmake -DCMAKE_CXX_STANDARD=17 -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" .
make install -j4 make install -j4
cd .. cd ..

View File

@ -40,6 +40,6 @@ cd ..
git clone https://github.com/ToruNiina/toml11 --depth=1 git clone https://github.com/ToruNiina/toml11 --depth=1
cd toml11 cd toml11
cmake -DCMAKE_INSTALL_PREFIX=$PREFIX . cmake -DCMAKE_CXX_STANDARD=17 -DCMAKE_INSTALL_PREFIX=$PREFIX .
make install -j3 make install -j3
cd .. cd ..

View File

@ -332,8 +332,66 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
break; break;
case "grpc"_hash: case "grpc"_hash:
singleproxy["network"] = x.TransferProtocol; singleproxy["network"] = x.TransferProtocol;
singleproxy["servername"] = x.ServerName;
singleproxy["grpc-opts"]["grpc-mode"] = x.GRPCMode;
singleproxy["grpc-opts"]["grpc-service-name"]= x.GRPCServiceName;
break;
default:
continue;
}
break;
case ProxyType::Vless:
singleproxy["type"] = "vless";
singleproxy["uuid"] = x.UserId;
singleproxy["tls"] = x.TLSSecure;
if(!x.Host.empty())
singleproxy["servername"] = x.Host; singleproxy["servername"] = x.Host;
singleproxy["grpc-opts"]["grpc-service-name"] = x.Path; if (!x.Flow.empty())
singleproxy["flow"] = x.Flow;
if(!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
switch(hash_(x.TransferProtocol))
{
case "tcp"_hash:
break;
case "ws"_hash:
singleproxy["network"] = x.TransferProtocol;
if(ext.clash_new_field_name)
{
singleproxy["ws-opts"]["path"] = x.Path;
if(!x.Host.empty())
singleproxy["ws-opts"]["headers"]["Host"] = x.Host;
if(!x.Edge.empty())
singleproxy["ws-opts"]["headers"]["Edge"] = x.Edge;
}
else
{
singleproxy["ws-path"] = x.Path;
if(!x.Host.empty())
singleproxy["ws-headers"]["Host"] = x.Host;
if(!x.Edge.empty())
singleproxy["ws-headers"]["Edge"] = x.Edge;
}
break;
case "http"_hash:
singleproxy["network"] = x.TransferProtocol;
singleproxy["http-opts"]["method"] = "GET";
singleproxy["http-opts"]["path"].push_back(x.Path);
if(!x.Host.empty())
singleproxy["http-opts"]["headers"]["Host"].push_back(x.Host);
if(!x.Edge.empty())
singleproxy["http-opts"]["headers"]["Edge"].push_back(x.Edge);
break;
case "h2"_hash:
singleproxy["network"] = x.TransferProtocol;
singleproxy["h2-opts"]["path"] = x.Path;
if(!x.Host.empty())
singleproxy["h2-opts"]["host"].push_back(x.Host);
break;
case "grpc"_hash:
singleproxy["network"] = x.TransferProtocol;
singleproxy["grpc-opts"]["grpc-mode"] = x.GRPCMode;
singleproxy["grpc-opts"]["grpc-service-name"] = x.GRPCServiceName;
break; break;
default: default:
continue; continue;
@ -412,8 +470,8 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
break; break;
case "grpc"_hash: case "grpc"_hash:
singleproxy["network"] = x.TransferProtocol; singleproxy["network"] = x.TransferProtocol;
if(!x.Path.empty()) singleproxy["grpc-opts"]["grpc-mode"] = x.GRPCMode;
singleproxy["grpc-opts"]["grpc-service-name"] = x.Path; singleproxy["grpc-opts"]["grpc-service-name"] = x.GRPCServiceName;
break; break;
case "ws"_hash: case "ws"_hash:
singleproxy["network"] = x.TransferProtocol; singleproxy["network"] = x.TransferProtocol;

View File

@ -76,6 +76,11 @@ void chkArg(int argc, char *argv[])
{ {
global.generatorMode = true; global.generatorMode = true;
} }
else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
{
std::cerr<<"subconverter " VERSION " backend\n";
return;
}
else if(strcmp(argv[i], "--artifact") == 0) else if(strcmp(argv[i], "--artifact") == 0)
{ {
if(i < argc - 1) if(i < argc - 1)

View File

@ -13,6 +13,7 @@ enum ProxyType
Shadowsocks, Shadowsocks,
ShadowsocksR, ShadowsocksR,
VMess, VMess,
Vless,
Trojan, Trojan,
Snell, Snell,
HTTP, HTTP,
@ -30,6 +31,8 @@ inline String getProxyTypeName(int type)
return "SSR"; return "SSR";
case ProxyType::VMess: case ProxyType::VMess:
return "VMess"; return "VMess";
case ProxyType::Vless:
return "Vless";
case ProxyType::Trojan: case ProxyType::Trojan:
return "Trojan"; return "Trojan";
case ProxyType::Snell: case ProxyType::Snell:
@ -70,12 +73,17 @@ struct Proxy
String FakeType; String FakeType;
bool TLSSecure = false; bool TLSSecure = false;
String Flow;
bool FlowShow = false;
String Host; String Host;
String Path; String Path;
String Edge; String Edge;
String QUICSecure; String QUICSecure;
String QUICSecret; String QUICSecret;
String GRPCServiceName;
String GRPCMode;
tribool UDP; tribool UDP;
tribool TCPFastOpen; tribool TCPFastOpen;
@ -89,6 +97,7 @@ struct Proxy
#define SS_DEFAULT_GROUP "SSProvider" #define SS_DEFAULT_GROUP "SSProvider"
#define SSR_DEFAULT_GROUP "SSRProvider" #define SSR_DEFAULT_GROUP "SSRProvider"
#define V2RAY_DEFAULT_GROUP "V2RayProvider" #define V2RAY_DEFAULT_GROUP "V2RayProvider"
#define XRAY_DEFAULT_GROUP "XRayProvider"
#define SOCKS_DEFAULT_GROUP "SocksProvider" #define SOCKS_DEFAULT_GROUP "SocksProvider"
#define HTTP_DEFAULT_GROUP "HTTPProvider" #define HTTP_DEFAULT_GROUP "HTTPProvider"
#define TROJAN_DEFAULT_GROUP "TrojanProvider" #define TROJAN_DEFAULT_GROUP "TrojanProvider"

View File

@ -37,7 +37,7 @@ void commonConstruct(Proxy &node, ProxyType type, const std::string &group, cons
node.TLS13 = tls13; node.TLS13 = tls13;
} }
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 tfo, tribool scv, tribool tls13) 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::string &alpn, tribool udp, tribool tfo, tribool scv, tribool tls13)
{ {
commonConstruct(node, ProxyType::VMess, group, remarks, add, port, udp, tfo, scv, tls13); commonConstruct(node, ProxyType::VMess, group, remarks, add, port, udp, tfo, scv, tls13);
node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id; node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
@ -46,19 +46,54 @@ void vmessConstruct(Proxy &node, const std::string &group, const std::string &re
node.TransferProtocol = net.empty() ? "tcp" : net; node.TransferProtocol = net.empty() ? "tcp" : net;
node.Edge = edge; node.Edge = edge;
node.ServerName = sni; node.ServerName = sni;
if(net == "quic")
{
node.QUICSecure = host;
node.QUICSecret = path;
}
else
{
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
node.Path = path.empty() ? "/" : trim(path);
}
node.FakeType = type; node.FakeType = type;
node.TLSSecure = tls == "tls"; node.TLSSecure = tls == "tls";
switch(hash_(net))
{
case "grpc"_hash:
node.GRPCMode = type.empty() ? "gun" : type;
node.GRPCServiceName = path.empty() ? "/" : urlEncode(urlDecode(trim(path)));
break;
case "quic"_hash:
node.QUICSecure = host;
node.QUICSecret = path.empty() ? "/" : trim(path);
break;
default:
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
node.Path = path.empty() ? "/" : trim(path);
break;
}
}
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, 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;
node.AlterId = to_int(aid);
node.EncryptMethod = cipher;
node.TransferProtocol = net.empty() ? "tcp" : type=="http" ? "http": net;
node.Edge = edge;
node.Flow = flow;
node.FakeType = type;
node.TLSSecure = tls == "tls" || tls == "xtls";
switch(hash_(net))
{
case "grpc"_hash:
node.Host = host;
node.GRPCMode = mode.empty() ? "gun" : mode;
node.GRPCServiceName = path.empty() ? "/" : urlEncode(urlDecode(trim(path)));
break;
case "quic"_hash:
node.QUICSecure = host;
node.QUICSecret = path.empty() ? "/" : trim(path);
break;
default:
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
node.Path = path.empty() ? "/" : urlDecode(trim(path));
break;
}
} }
void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &protocol, const std::string &method, const std::string &obfs, const std::string &password, const std::string &obfsparam, const std::string &protoparam, tribool udp, tribool tfo, tribool scv) void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &protocol, const std::string &method, const std::string &obfs, const std::string &password, const std::string &obfsparam, const std::string &protoparam, tribool udp, tribool tfo, tribool scv)
@ -96,14 +131,17 @@ void httpConstruct(Proxy &node, const std::string &group, const std::string &rem
node.TLSSecure = tls; node.TLSSecure = tls;
} }
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, bool tlssecure, tribool udp, tribool tfo, tribool scv, tribool tls13) 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 &mode, const std::string &host, const std::string &path, const std::string &flow, const std::string &tls, tribool udp, tribool tfo, tribool scv, tribool tls13)
{ {
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13); commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13);
node.Password = password; node.Password = password;
node.Host = host; node.Host = host;
node.TLSSecure = tlssecure; node.TLSSecure = tls == "tls" || tls == "xtls";;
node.TransferProtocol = network.empty() ? "tcp" : network; node.TransferProtocol = network.empty() ? "tcp" : network;
node.Path = path; node.Path = path;
node.Flow = flow;
node.GRPCMode = mode.empty() ? "gun" : mode;
node.GRPCServiceName = path.empty() ? "/" : urlEncode(urlDecode(trim(path)));
} }
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv) void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv)
@ -115,9 +153,18 @@ void snellConstruct(Proxy &node, const std::string &group, const std::string &re
node.SnellVersion = version; node.SnellVersion = version;
} }
void explodeVless(std::string vless, Proxy &node)
{
if(regMatch(vless, "vless://(.*?)@(.*)"))
{
explodeStdVless(vless, node);
return;
}
}
void explodeVmess(std::string vmess, Proxy &node) void explodeVmess(std::string vmess, Proxy &node)
{ {
std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni; std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni, alpn;
Document jsondata; Document jsondata;
std::vector<std::string> vArray; std::vector<std::string> vArray;
@ -162,6 +209,8 @@ void explodeVmess(std::string vmess, Proxy &node)
GetMember(jsondata, "host", host); GetMember(jsondata, "host", host);
GetMember(jsondata, "sni", sni); GetMember(jsondata, "sni", sni);
GetMember(jsondata, "alpn", alpn);
switch(to_int(version)) switch(to_int(version))
{ {
case 1: case 1:
@ -182,14 +231,14 @@ void explodeVmess(std::string vmess, Proxy &node)
add = trim(add); add = trim(add);
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, "auto", path, host, "", tls, sni); vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, "auto", path, host, "", tls, sni, alpn);
} }
void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) void explodeVmessConf(std::string content, std::vector<Proxy> &nodes)
{ {
Document json; Document json;
rapidjson::Value nodejson, settings; rapidjson::Value nodejson, settings;
std::string group, ps, add, port, type, id, aid, net, path, host, edge, tls, cipher, subid, sni; std::string group, ps, add, port, type, id, aid, net, path, host, edge, tls, cipher, subid, sni, alpn;
tribool udp, tfo, scv; tribool udp, tfo, scv;
int configType; int configType;
uint32_t index = nodes.size(); uint32_t index = nodes.size();
@ -260,7 +309,7 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes)
} }
} }
} }
vmessConstruct(node, V2RAY_DEFAULT_GROUP, add + ":" + port, add, port, type, id, aid, net, cipher, path, host, edge, tls, "", udp, tfo, scv); vmessConstruct(node, V2RAY_DEFAULT_GROUP, add + ":" + port, add, port, type, id, aid, net, cipher, path, host, edge, tls, "", "", udp, tfo, scv);
nodes.emplace_back(std::move(node)); nodes.emplace_back(std::move(node));
} }
return; return;
@ -314,7 +363,8 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes)
json["vmess"][i]["streamSecurity"] >> tls; json["vmess"][i]["streamSecurity"] >> tls;
json["vmess"][i]["security"] >> cipher; json["vmess"][i]["security"] >> cipher;
json["vmess"][i]["sni"] >> sni; json["vmess"][i]["sni"] >> sni;
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, cipher, path, host, "", tls, sni, udp, tfo, scv); json["vmess"][i]["alpn"] >> alpn;
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, cipher, path, host, "", tls, sni, alpn, udp, tfo, scv);
break; break;
case 3: //ss config case 3: //ss config
json["vmess"][i]["id"] >> id; json["vmess"][i]["id"] >> id;
@ -725,9 +775,9 @@ void explodeHTTPSub(std::string link, Proxy &node)
void explodeTrojan(std::string trojan, Proxy &node) void explodeTrojan(std::string trojan, Proxy &node)
{ {
std::string server, port, psk, addition, group, remark, host, path, network; std::string server, port, psk, addition, group, remark, host, path, network, mode, flow, tls;
tribool tfo, scv; tribool tfo, scv;
trojan.erase(0, 9); trojan.erase(0, trojan.find("://") + 3);
string_size pos = trojan.rfind("#"); string_size pos = trojan.rfind("#");
if(pos != trojan.npos) if(pos != trojan.npos)
@ -747,25 +797,35 @@ void explodeTrojan(std::string trojan, Proxy &node)
if(port == "0") if(port == "0")
return; return;
host = getUrlArg(addition, "sni"); host = getUrlArg(addition, strFind(addition,"sni") ? "sni" : strFind(addition,"host") ? "host" : "peer");
if(host.empty())
host = getUrlArg(addition, "peer");
tfo = getUrlArg(addition, "tfo"); tfo = getUrlArg(addition, "tfo");
scv = getUrlArg(addition, "allowInsecure"); scv = getUrlArg(addition, "allowInsecure");
group = urlDecode(getUrlArg(addition, "group")); group = urlDecode(getUrlArg(addition, "group"));
tls = getUrlArg(addition,"security");
flow = getUrlArg(addition,"flow");
//Case WS
if(getUrlArg(addition, "ws") == "1") if(getUrlArg(addition, "ws") == "1")
{ {
path = getUrlArg(addition, "wspath"); path = getUrlArg(addition, "wspath");
network = "ws"; network = "ws";
} }
//Case GRPC
if(getUrlArg(addition, "type") == "grpc")
{
mode = getUrlArg(addition,"mode");
path = getUrlArg(addition, "serviceName");
network = "grpc";
}
if(remark.empty()) if(remark.empty())
remark = server + ":" + port; remark = server + ":" + port;
if(group.empty()) if(group.empty())
group = TROJAN_DEFAULT_GROUP; group = TROJAN_DEFAULT_GROUP;
trojanConstruct(node, group, remark, server, port, psk, network, host, path, true, tribool(), tfo, scv); trojanConstruct(node, group, remark, server, port, psk, network, mode, host, path, flow, tls, tribool(), tfo, scv);
} }
void explodeQuan(const std::string &quan, Proxy &node) void explodeQuan(const std::string &quan, Proxy &node)
@ -831,7 +891,7 @@ void explodeQuan(const std::string &quan, Proxy &node)
if(path.empty()) if(path.empty())
path = "/"; path = "/";
vmessConstruct(node, group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls, ""); vmessConstruct(node, group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls, "","");
} }
} }
@ -839,7 +899,7 @@ void explodeNetch(std::string netch, Proxy &node)
{ {
Document json; Document json;
std::string type, group, remark, address, port, username, password, method, plugin, pluginopts; std::string type, group, remark, address, port, username, password, method, plugin, pluginopts;
std::string protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, edge, path, tls, sni; std::string protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, edge, path, tls, sni, flow, alpn, mode;
tribool udp, tfo, scv; tribool udp, tfo, scv;
netch = urlSafeBase64Decode(netch.substr(8)); netch = urlSafeBase64Decode(netch.substr(8));
@ -901,7 +961,7 @@ void explodeNetch(std::string netch, Proxy &node)
sni = GetMember(json, "ServerName"); sni = GetMember(json, "ServerName");
if(group.empty()) if(group.empty())
group = V2RAY_DEFAULT_GROUP; group = V2RAY_DEFAULT_GROUP;
vmessConstruct(node, group, remark, address, port, faketype, id, aid, transprot, method, path, host, edge, tls, sni, udp, tfo, scv); vmessConstruct(node, group, remark, address, port, faketype, id, aid, transprot, method, path, host, edge, tls, sni, alpn, udp, tfo, scv);
break; break;
case "Socks5"_hash: case "Socks5"_hash:
username = GetMember(json, "Username"); username = GetMember(json, "Username");
@ -916,13 +976,15 @@ void explodeNetch(std::string netch, Proxy &node)
httpConstruct(node, group, remark, address, port, username, password, type == "HTTPS", tfo, scv); httpConstruct(node, group, remark, address, port, username, password, type == "HTTPS", tfo, scv);
break; break;
case "Trojan"_hash: case "Trojan"_hash:
host = GetMember(json, "Servername");
if (host.empty())
host = GetMember(json, "Host"); host = GetMember(json, "Host");
path = GetMember(json, "Path"); path = GetMember(json, "Path");
transprot = GetMember(json, "TransferProtocol"); transprot = GetMember(json, "TransferProtocol");
tls = GetMember(json, "TLSSecure"); tls = GetMember(json, "TLSSecure");
if(group.empty()) if(group.empty())
group = TROJAN_DEFAULT_GROUP; group = TROJAN_DEFAULT_GROUP;
trojanConstruct(node, group, remark, address, port, password, transprot, host, path, tls == "true", udp, tfo, scv); trojanConstruct(node, group, remark, address, port, password, transprot, mode, host, path, flow, tls, udp, tfo, scv);
break; break;
case "Snell"_hash: case "Snell"_hash:
obfs = GetMember(json, "OBFS"); obfs = GetMember(json, "OBFS");
@ -940,9 +1002,10 @@ void explodeNetch(std::string netch, Proxy &node)
void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
{ {
std::string proxytype, ps, server, port, cipher, group, password; //common std::string proxytype, ps, server, port, cipher, group, password; //common
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni, alpn; //vmess
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
std::string protocol, protoparam, obfs, obfsparam; //ssr std::string protocol, protoparam, obfs, obfsparam; //ssr
std::string flow, mode; //trojan
std::string user; //socks std::string user; //socks
tribool udp, tfo, scv; tribool udp, tfo, scv;
Node singleproxy; Node singleproxy;
@ -969,7 +1032,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
singleproxy["alterId"] >>= aid; singleproxy["alterId"] >>= aid;
singleproxy["cipher"] >>= cipher; singleproxy["cipher"] >>= cipher;
net = singleproxy["network"].IsDefined() ? safe_as<std::string>(singleproxy["network"]) : "tcp"; net = singleproxy["network"].IsDefined() ? safe_as<std::string>(singleproxy["network"]) : "tcp";
singleproxy["servername"] >>= sni; sni = singleproxy["servername"].IsDefined() ? safe_as<std::string>(singleproxy["servername"]) : "";
switch(hash_(net)) switch(hash_(net))
{ {
case "http"_hash: case "http"_hash:
@ -1004,7 +1067,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
} }
tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : ""; tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : "";
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls, sni, udp, tfo, scv); vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls, sni, alpn, udp, tfo, scv);
break; break;
case "ss"_hash: case "ss"_hash:
group = SS_DEFAULT_GROUP; group = SS_DEFAULT_GROUP;
@ -1117,9 +1180,11 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
singleproxy["password"] >>= password; singleproxy["password"] >>= password;
singleproxy["sni"] >>= host; singleproxy["sni"] >>= host;
singleproxy["network"] >>= net; singleproxy["network"] >>= net;
singleproxy["flow"] >>= flow;
switch(hash_(net)) switch(hash_(net))
{ {
case "grpc"_hash: case "grpc"_hash:
singleproxy["grpc-opts"]["grpc-mode"] >>= mode;
singleproxy["grpc-opts"]["grpc-service-name"] >>= path; singleproxy["grpc-opts"]["grpc-service-name"] >>= path;
break; break;
case "ws"_hash: case "ws"_hash:
@ -1131,7 +1196,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
break; break;
} }
trojanConstruct(node, group, ps, server, port, password, net, host, path, true, udp, tfo, scv); trojanConstruct(node, group, ps, server, port, password, net, mode, host, path, flow, tls, udp, tfo, scv);
break; break;
case "snell"_hash: case "snell"_hash:
group = SNELL_DEFAULT_GROUP; group = SNELL_DEFAULT_GROUP;
@ -1155,7 +1220,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
void explodeStdVMess(std::string vmess, Proxy &node) void explodeStdVMess(std::string vmess, Proxy &node)
{ {
std::string add, port, type, id, aid, net, path, host, tls, remarks; std::string add, port, type, id, aid, net, path, host, tls, sni, alpn, remarks;
std::string addition; std::string addition;
vmess = vmess.substr(8); vmess = vmess.substr(8);
string_size pos; string_size pos;
@ -1169,7 +1234,7 @@ void explodeStdVMess(std::string vmess, Proxy &node)
const std::string stdvmess_matcher = R"(^([a-z]+)(?:\+([a-z]+))?:([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})-(\d+)@(.+):(\d+)(?:\/?\?(.*))?$)"; const std::string stdvmess_matcher = R"(^([a-z]+)(?:\+([a-z]+))?:([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})-(\d+)@(.+):(\d+)(?:\/?\?(.*))?$)";
if(regGetMatch(vmess, stdvmess_matcher, 8, 0, &net, &tls, &id, &aid, &add, &port, &addition)) if(regGetMatch(vmess, stdvmess_matcher, 8, 0, &net, &tls, &id, &aid, &add, &port, &addition))
return; return;
sni = getUrlArg(addition, "servername");
switch(hash_(net)) switch(hash_(net))
{ {
case "tcp"_hash: case "tcp"_hash:
@ -1193,7 +1258,58 @@ void explodeStdVMess(std::string vmess, Proxy &node)
if(remarks.empty()) if(remarks.empty())
remarks = add + ":" + port; remarks = add + ":" + port;
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", path, host, "", tls, ""); vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", path, host, "", tls, "","");
return;
}
void explodeStdVless(std::string vless, Proxy &node)
{
std::string add, port, type, id, aid, net, flow, mode, path, host, tls, remarks;
std::string addition;
vless = vless.substr(8);
string_size pos;
pos = vless.rfind("#");
if(pos != vless.npos)
{
remarks = urlDecode(vless.substr(pos + 1));
vless.erase(pos);
}
const std::string stdvless_matcher = R"(^([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})@\[?([\d\-a-zA-Z:.]+)\]?:(\d+)(?:\/?\?(.*))?$)";
if(regGetMatch(vless, stdvless_matcher, 5, 0, &id, &add, &port, &addition))
return;
tls = getUrlArg(addition,"security");
net = getUrlArg(addition,"type");
flow = getUrlArg(addition,"flow");
switch(hash_(net))
{
case "tcp"_hash:
case "ws"_hash:
case "h2"_hash:
type = getUrlArg(addition, "headerType");
host = getUrlArg(addition, strFind(addition,"sni") ? "sni" : "host");
path = getUrlArg(addition, "path");
break;
case "grpc"_hash:
host = getUrlArg(addition, "sni");
path = getUrlArg(addition, "serviceName");
mode = getUrlArg(addition, "mode");
break;
case "quic"_hash:
type = getUrlArg(addition, "headerType");
host = getUrlArg(addition, strFind(addition,"sni") ? "sni" : "quicSecurity");
path = getUrlArg(addition, "key");
break;
default:
return;
}
if(remarks.empty())
remarks = add + ":" + port;
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", flow, mode, path, host, "", tls);
return; return;
} }
@ -1238,7 +1354,7 @@ void explodeShadowrocket(std::string rocket, Proxy &node)
if(remarks.empty()) if(remarks.empty())
remarks = add + ":" + port; remarks = add + ":" + port;
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, ""); vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "","");
} }
void explodeKitsunebi(std::string kit, Proxy &node) void explodeKitsunebi(std::string kit, Proxy &node)
@ -1276,7 +1392,7 @@ void explodeKitsunebi(std::string kit, Proxy &node)
if(remarks.empty()) if(remarks.empty())
remarks = add + ":" + port; remarks = add + ":" + port;
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, ""); vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "","");
} }
bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
@ -1311,7 +1427,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
{ {
std::string remarks, server, port, method, username, password; //common std::string remarks, server, port, method, username, password; //common
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, mod_url, mod_md5; //ss std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, mod_url, mod_md5; //ss
std::string id, net, tls, host, edge, path; //v2 std::string id, net, tls, host, edge, path, sni, alpn, mode, flow; //v2
std::string protocol, protoparam; //ssr std::string protocol, protoparam; //ssr
std::string version, aead = "1"; std::string version, aead = "1";
std::string itemName, itemVal, config; std::string itemName, itemVal, config;
@ -1540,7 +1656,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
} }
} }
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host, edge, tls, "", udp, tfo, scv, tls13); vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host, edge, tls, "", "", udp, tfo, scv, tls13);
break; break;
case "http"_hash: //http proxy case "http"_hash: //http proxy
server = trim(configs[1]); server = trim(configs[1]);
@ -1606,7 +1722,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
} }
} }
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", true, udp, tfo, scv); trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", mode, host, "", flow, tls, udp, tfo, scv);
break; break;
case "snell"_hash: case "snell"_hash:
server = trim(configs[1]); server = trim(configs[1]);
@ -1821,7 +1937,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
if(remarks.empty()) if(remarks.empty())
remarks = server + ":" + port; remarks = server + ":" + port;
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host, "", tls, "", udp, tfo, scv, tls13); vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host, "", tls, "", "", udp, tfo, scv, tls13);
break; break;
case "trojan"_hash: //quantumult x style trojan link case "trojan"_hash: //quantumult x style trojan link
server = trim(configs[0].substr(0, configs[0].rfind(":"))); server = trim(configs[0].substr(0, configs[0].rfind(":")));
@ -1868,8 +1984,9 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
} }
if(remarks.empty()) if(remarks.empty())
remarks = server + ":" + port; remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server))
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", host, "", tls == "true", udp, tfo, scv, tls13); host = server;
trojanConstruct(node, TROJAN_DEFAULT_GROUP, remarks, server, port, password, "", mode, host, "", flow, tls, udp, tfo, scv, tls13);
break; break;
case "http"_hash: //quantumult x style http links case "http"_hash: //quantumult x style http links
server = trim(configs[0].substr(0, configs[0].rfind(":"))); server = trim(configs[0].substr(0, configs[0].rfind(":")));
@ -2069,6 +2186,8 @@ void explode(const std::string &link, Proxy &node)
explodeSSR(link, node); explodeSSR(link, node);
else if(strFind(link, "vmess://") || strFind(link, "vmess1://")) else if(strFind(link, "vmess://") || strFind(link, "vmess1://"))
explodeVmess(link, node); explodeVmess(link, node);
else if(strFind(link, "vless://") || strFind(link, "vless1://"))
explodeVless(link, node);
else if(strFind(link, "ss://")) else if(strFind(link, "ss://"))
explodeSS(link, node); explodeSS(link, node);
else if(strFind(link, "socks://") || strFind(link, "https://t.me/socks") || strFind(link, "tg://socks")) else if(strFind(link, "socks://") || strFind(link, "https://t.me/socks") || strFind(link, "tg://socks"))
@ -2077,7 +2196,7 @@ void explode(const std::string &link, Proxy &node)
explodeHTTP(link, node); explodeHTTP(link, node);
else if(strFind(link, "Netch://")) else if(strFind(link, "Netch://"))
explodeNetch(link, node); explodeNetch(link, node);
else if(strFind(link, "trojan://")) else if(strFind(link, "trojan://") || strFind(link, "trojan-go://"))
explodeTrojan(link, node); explodeTrojan(link, node);
else if(isLink(link)) else if(isLink(link))
explodeHTTPSub(link, node); explodeHTTPSub(link, node);

View File

@ -20,19 +20,22 @@ enum class ConfType
Local Local
}; };
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 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::string &alpn, 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, 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 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 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 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 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, bool tlssecure, tribool udp = tribool(), 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 &mode, const std::string &host, const std::string &path, const std::string &flow, const std::string &tls, 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 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 explodeVmess(std::string vmess, Proxy &node);
void explodeVless(std::string vless, Proxy &node);
void explodeSSR(std::string ssr, Proxy &node); void explodeSSR(std::string ssr, Proxy &node);
void explodeSS(std::string ss, Proxy &node); void explodeSS(std::string ss, Proxy &node);
void explodeTrojan(std::string trojan, Proxy &node); void explodeTrojan(std::string trojan, Proxy &node);
void explodeQuan(const std::string &quan, Proxy &node); void explodeQuan(const std::string &quan, Proxy &node);
void explodeStdVMess(std::string vmess, Proxy &node); void explodeStdVMess(std::string vmess, Proxy &node);
void explodeStdVless(std::string vless, Proxy &node);
void explodeShadowrocket(std::string kit, Proxy &node); void explodeShadowrocket(std::string kit, Proxy &node);
void explodeKitsunebi(std::string kit, Proxy &node); void explodeKitsunebi(std::string kit, Proxy &node);
/// Parse a link /// Parse a link

View File

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