mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-26 19:32:55 +00:00
Breaking changes
Fix data URIs not correctly parsed. Fix downloading files may be caught in infinite redirect loops. Add experimental JavaScript support for providing subscriptions, filtering nodes, sorting nodes and generating groups. Add tag support for adding group name to a specific link. Add complete matcher support for Emoji and rename match rule. Optimize codes. Update build scripts.
This commit is contained in:
@@ -101,6 +101,10 @@ TARGET_LINK_LIBRARIES(subconverter ${YAML_CPP_LIBRARY})
|
|||||||
ADD_DEFINITIONS(-DPCRE2_STATIC)
|
ADD_DEFINITIONS(-DPCRE2_STATIC)
|
||||||
#ENDIF()
|
#ENDIF()
|
||||||
|
|
||||||
|
FIND_PACKAGE(Duktape REQUIRED)
|
||||||
|
INCLUDE_DIRECTORIES(${DUKTAPE_INCLUDE_DIRS})
|
||||||
|
TARGET_LINK_LIBRARIES(subconverter ${DUKTAPE_LIBRARIES})
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
TARGET_LINK_LIBRARIES(subconverter wsock32 ws2_32)
|
TARGET_LINK_LIBRARIES(subconverter wsock32 ws2_32)
|
||||||
ELSE()
|
ELSE()
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ common:
|
|||||||
prepend_insert_url: true
|
prepend_insert_url: true
|
||||||
exclude_remarks: ["(到期|剩余流量|时间|官网|产品)"]
|
exclude_remarks: ["(到期|剩余流量|时间|官网|产品)"]
|
||||||
include_remarks: []
|
include_remarks: []
|
||||||
|
enable_filter: false
|
||||||
|
filter_script: ""
|
||||||
default_external_config: "" # config/example_external_config.yml
|
default_external_config: "" # config/example_external_config.yml
|
||||||
base_path: base
|
base_path: base
|
||||||
clash_rule_base: base/all_base.tpl
|
clash_rule_base: base/all_base.tpl
|
||||||
@@ -39,6 +41,7 @@ node_pref:
|
|||||||
# udp_flag: false
|
# udp_flag: false
|
||||||
# tcp_fast_open_flag: false
|
# tcp_fast_open_flag: false
|
||||||
sort_flag: false
|
sort_flag: false
|
||||||
|
sort_script: ""
|
||||||
# skip_cert_verify_flag: false
|
# skip_cert_verify_flag: false
|
||||||
filter_deprecated_nodes: false
|
filter_deprecated_nodes: false
|
||||||
append_sub_userinfo: true
|
append_sub_userinfo: true
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ exclude_remarks=(到期|剩余流量|时间|官网|产品)
|
|||||||
;Only include nodes which remarks match the following patterns. Supports regular expression.
|
;Only include nodes which remarks match the following patterns. Supports regular expression.
|
||||||
;include_remarks=V3.*港
|
;include_remarks=V3.*港
|
||||||
|
|
||||||
|
;Enable script support for filtering nodes
|
||||||
|
enable_filter=false
|
||||||
|
;Script used for filtering nodes. Supports inline script and script path. A "filter" function with 1 argument which is a node should be defined in the script.
|
||||||
|
;Example: Inline script: Set value to content of script. Replace all line break with "\n".
|
||||||
|
; Script path: Set value to "path:/path/to/script.js".
|
||||||
|
;filter_script=function filter(node) {\n const info = JSON.parse(node.ProxyInfo);\n if(info.EncryptMethod.includes('chacha20'))\n return true;\n return false;\n}
|
||||||
|
|
||||||
;Setting an external config file as default when none is specified, supports local files/URL
|
;Setting an external config file as default when none is specified, supports local files/URL
|
||||||
;default_external_config=config/example_external_config.ini
|
;default_external_config=config/example_external_config.ini
|
||||||
|
|
||||||
@@ -84,7 +91,12 @@ time_rule=^.*?流量:(?:.*?) 剩:(.*)$|left=$1d
|
|||||||
[node_pref]
|
[node_pref]
|
||||||
;udp_flag=false
|
;udp_flag=false
|
||||||
;tcp_fast_open_flag=false
|
;tcp_fast_open_flag=false
|
||||||
|
|
||||||
sort_flag=false
|
sort_flag=false
|
||||||
|
;Script used for sorting nodes. A "compare" function with 2 arguments which are the 2 nodes to be compared should be defined in the script. Supports inline script and script path.
|
||||||
|
;Examples can be seen at the filter_script option in [common] section.
|
||||||
|
;sort_script=function compare(node_a, node_b) {\n const info_a = JSON.parse(node_a.ProxyInfo);\n const info_b = JSON.parse(node_b.ProxyInfo);\n return info_a.Remark > info_b.Remark;\n}
|
||||||
|
|
||||||
;skip_cert_verify_flag=false
|
;skip_cert_verify_flag=false
|
||||||
filter_deprecated_nodes=false
|
filter_deprecated_nodes=false
|
||||||
append_sub_userinfo=true
|
append_sub_userinfo=true
|
||||||
@@ -152,7 +164,7 @@ update_ruleset_on_request=false
|
|||||||
surge_ruleset=!!import:snippets/rulesets.txt
|
surge_ruleset=!!import:snippets/rulesets.txt
|
||||||
|
|
||||||
[clash_proxy_group]
|
[clash_proxy_group]
|
||||||
;Generate Clash Proxy Group with the following patterns. Node filterting rule supports regular expression.
|
;Generate Clash Proxy Group with the following patterns. Node filtering rule supports regular expression.
|
||||||
;Format: Group_Name`select`Rule_1`Rule_2`...
|
;Format: Group_Name`select`Rule_1`Rule_2`...
|
||||||
; Group_Name`url-test|fallback|load-balance`Rule_1`Rule_2`...`test_url`interval[,timeout][,tolerance]
|
; Group_Name`url-test|fallback|load-balance`Rule_1`Rule_2`...`test_url`interval[,timeout][,tolerance]
|
||||||
;Rule with "[]" prefix will be added directly.
|
;Rule with "[]" prefix will be added directly.
|
||||||
@@ -170,6 +182,9 @@ surge_ruleset=!!import:snippets/rulesets.txt
|
|||||||
;custom_proxy_group=g1hk`select`!!GROUPID=0!!(HGC|HKBN|PCCW|HKT|hk|港)
|
;custom_proxy_group=g1hk`select`!!GROUPID=0!!(HGC|HKBN|PCCW|HKT|hk|港)
|
||||||
;custom_proxy_group=sstw`select`!!GROUP=V2RayProvider!!(深台|彰化|新北|台|tw)
|
;custom_proxy_group=sstw`select`!!GROUP=V2RayProvider!!(深台|彰化|新北|台|tw)
|
||||||
|
|
||||||
|
;Also supports using script for filtering nodes. A "filter" function with one argument which is an array of all available nodes should be defined in the script.
|
||||||
|
;custom_proxy_group=script`select`script:/path/to/script.js
|
||||||
|
|
||||||
;for forcerule.yml
|
;for forcerule.yml
|
||||||
;custom_proxy_group=!!import:snippets/groups_forcerule.txt
|
;custom_proxy_group=!!import:snippets/groups_forcerule.txt
|
||||||
|
|
||||||
|
|||||||
12
cmake/FindDuktape.cmake
Normal file
12
cmake/FindDuktape.cmake
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
find_path(DUKTAPE_INCLUDE_DIRS duktape.h)
|
||||||
|
|
||||||
|
find_library(DUKTAPE_LIBRARY duktape)
|
||||||
|
find_library(DUKTAPE_MODULE_LIBRARY duktape_module)
|
||||||
|
|
||||||
|
set(DUKTAPE_LIBRARIES "${DUKTAPE_LIBRARY} ${DUKTAPE_MODULE_LIBRARY}")
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(DUKTAPE DEFAULT_MSG
|
||||||
|
DUKTAPE_INCLUDE_DIRS DUKTAPE_LIBRARY DUKTAPE_MODULE_LIBRARY)
|
||||||
|
|
||||||
|
mark_as_advanced(DUKTAPE_INCLUDE_DIRS DUKTAPE_LIBRARY)
|
||||||
@@ -3,7 +3,20 @@ MAINTAINER Tindy X <tindy.it@gmail.com>
|
|||||||
|
|
||||||
# build minimized
|
# build minimized
|
||||||
RUN apk add git g++ build-base linux-headers cmake && \
|
RUN apk add git g++ build-base linux-headers cmake && \
|
||||||
apk add libressl-dev curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev && \
|
apk add libressl-dev curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev python2 py2-pip && \
|
||||||
|
git clone https://github.com/svaarala/duktape --depth=1 && \
|
||||||
|
cd duktape && \
|
||||||
|
pip2 install PyYAML && \
|
||||||
|
python2 util/dist.py && \
|
||||||
|
cd dist/src && \
|
||||||
|
cc -c -O3 -o duktape.o duktape.c && \
|
||||||
|
cc -c -O3 -o duk_module_node.o -I. ../extras/module-node/duk_module_node.c && \
|
||||||
|
ar cr libduktape.a duktape.o && \
|
||||||
|
ar cr libduktape_module.a duk_module_node.o && \
|
||||||
|
install -m0644 *.a /usr/lib && \
|
||||||
|
install -m0644 duk*.h /usr/include && \
|
||||||
|
install -m0644 ../extras/module-node/duk_module_node.h /usr/include && \
|
||||||
|
cd ../../.. && \
|
||||||
git clone https://github.com/tindy2013/subconverter && \
|
git clone https://github.com/tindy2013/subconverter && \
|
||||||
cd subconverter && \
|
cd subconverter && \
|
||||||
cmake . && \
|
cmake . && \
|
||||||
@@ -13,7 +26,7 @@ RUN apk add git g++ build-base linux-headers cmake && \
|
|||||||
cd .. && \
|
cd .. && \
|
||||||
rm -rf subconverter && \
|
rm -rf subconverter && \
|
||||||
apk add pcre2 libcurl yaml-cpp libevent && \
|
apk add pcre2 libcurl yaml-cpp libevent && \
|
||||||
apk del git gcc g++ build-base linux-headers cmake libressl-dev curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev
|
apk del git gcc g++ build-base linux-headers cmake libressl-dev curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev python2 py2-pip
|
||||||
|
|
||||||
# set entry
|
# set entry
|
||||||
WORKDIR /base
|
WORKDIR /base
|
||||||
|
|||||||
@@ -1,15 +1,29 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
apk add gcc g++ build-base linux-headers cmake make autoconf automake libtool
|
apk add gcc g++ build-base linux-headers cmake make autoconf automake libtool python2 py2-pip
|
||||||
apk add openssl-dev openssl-libs-static curl curl-dev curl-static nghttp2-static zlib-dev rapidjson-dev libevent-dev libevent-static zlib-static pcre2-dev bzip2-static
|
apk add openssl-dev openssl-libs-static curl curl-dev curl-static nghttp2-static zlib-dev rapidjson-dev libevent-dev libevent-static zlib-static pcre2-dev bzip2-static
|
||||||
|
|
||||||
git clone https://github.com/jbeder/yaml-cpp
|
git clone https://github.com/jbeder/yaml-cpp --depth=1
|
||||||
cd yaml-cpp
|
cd yaml-cpp
|
||||||
cmake -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF . > /dev/null
|
cmake -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF . > /dev/null
|
||||||
make install -j2 > /dev/null
|
make install -j2 > /dev/null
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
git clone https://github.com/svaarala/duktape --depth=1
|
||||||
|
cd duktape
|
||||||
|
pip2 install PyYAML
|
||||||
|
python2 util/dist.py
|
||||||
|
cd dist/src
|
||||||
|
cc -c -O3 -o duktape.o duktape.c
|
||||||
|
cc -c -O3 -o duk_module_node.o -I. ../extras/module-node/duk_module_node.c
|
||||||
|
ar cr libduktape.a duktape.o
|
||||||
|
ar cr libduktape_module.a duk_module_node.o
|
||||||
|
install -m0644 *.a /usr/lib
|
||||||
|
install -m0644 duk*.h /usr/include
|
||||||
|
install -m0644 ../extras/module-node/duk_module_node.h /usr/include
|
||||||
|
cd ../../..
|
||||||
|
|
||||||
cmake .
|
cmake .
|
||||||
make -j2
|
make -j2
|
||||||
rm subconverter
|
rm subconverter
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ c++ -std=c++17 -Wall -fexceptions -c src/upload.cpp -o obj/upload.o
|
|||||||
c++ -std=c++17 -Wall -fexceptions -c src/templates.cpp -o obj/templates.o
|
c++ -std=c++17 -Wall -fexceptions -c src/templates.cpp -o obj/templates.o
|
||||||
c++ -std=c++17 -Wall -fexceptions -c src/webget.cpp -o obj/webget.o
|
c++ -std=c++17 -Wall -fexceptions -c src/webget.cpp -o obj/webget.o
|
||||||
c++ -std=c++17 -Wall -fexceptions -c src/webserver_libevent.cpp -o obj/webserver_libevent.o
|
c++ -std=c++17 -Wall -fexceptions -c src/webserver_libevent.cpp -o obj/webserver_libevent.o
|
||||||
c++ -o subconverter obj/*.o -lpcre2-8 -levent -lpthread -lyaml-cpp -lcurl -lssl -lcrypto -lz -O3 -s
|
c++ -o subconverter obj/*.o -lpcre2-8 -levent -lpthread -lyaml-cpp -lcurl -lssl -lcrypto -lz -O3 -s -lduktape -lduktape_module
|
||||||
|
|
||||||
chmod +x subconverter
|
chmod +x subconverter
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ set -xe
|
|||||||
|
|
||||||
brew reinstall rapidjson libevent zlib pcre2 bzip2 libssh2 pkgconfig
|
brew reinstall rapidjson libevent zlib pcre2 bzip2 libssh2 pkgconfig
|
||||||
|
|
||||||
git clone https://github.com/curl/curl
|
git clone https://github.com/curl/curl --depth=1
|
||||||
cd curl
|
cd curl
|
||||||
#./buildconf > /dev/null
|
#./buildconf > /dev/null
|
||||||
#./configure --with-ssl=/usr/local/opt/openssl@1.1 --without-mbedtls --disable-ldap --disable-ldaps --disable-rtsp --without-libidn2 > /dev/null
|
#./configure --with-ssl=/usr/local/opt/openssl@1.1 --without-mbedtls --disable-ldap --disable-ldaps --disable-rtsp --without-libidn2 > /dev/null
|
||||||
@@ -11,14 +11,29 @@ cmake -DHTTP_ONLY=ON -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DOPENSSL_ROOT_
|
|||||||
make -j8 > /dev/null
|
make -j8 > /dev/null
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
git clone https://github.com/jbeder/yaml-cpp
|
git clone https://github.com/jbeder/yaml-cpp --depth=1
|
||||||
cd yaml-cpp
|
cd yaml-cpp
|
||||||
cmake -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF . > /dev/null
|
cmake -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF . > /dev/null
|
||||||
make install -j8 > /dev/null
|
make install -j8 > /dev/null
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
git clone https://github.com/svaarala/duktape --depth=1
|
||||||
|
cd duktape
|
||||||
|
pip2 install PyYAML
|
||||||
|
python2 util/dist.py
|
||||||
|
cd dist/src
|
||||||
|
cc -c -O3 -o duktape.o duktape.c
|
||||||
|
cc -c -O3 -o duk_module_node.o -I. ../extras/module-node/duk_module_node.c
|
||||||
|
ar cr libduktape.a duktape.o
|
||||||
|
ar cr libduktape_module.a duk_module_node.o
|
||||||
|
install -m0644 *.a /usr/lib
|
||||||
|
install -m0644 duk*.h /usr/include
|
||||||
|
install -m0644 ../extras/module-node/duk_module_node.h /usr/include
|
||||||
|
cd ../../..
|
||||||
|
|
||||||
cp curl/lib/libcurl.a .
|
cp curl/lib/libcurl.a .
|
||||||
cp yaml-cpp/libyaml-cpp.a .
|
cp yaml-cpp/libyaml-cpp.a .
|
||||||
|
cp duktape/dist/src/*.a .
|
||||||
cp /usr/local/lib/libevent.a .
|
cp /usr/local/lib/libevent.a .
|
||||||
cp /usr/local/opt/zlib/lib/libz.a .
|
cp /usr/local/opt/zlib/lib/libz.a .
|
||||||
cp /usr/local/opt/openssl@1.1/lib/libssl.a .
|
cp /usr/local/opt/openssl@1.1/lib/libssl.a .
|
||||||
@@ -31,7 +46,7 @@ export CMAKE_CXX_FLAGS="-I/usr/local/include -I/usr/local/opt/openssl@1.1/includ
|
|||||||
cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 .
|
cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 .
|
||||||
make -j8
|
make -j8
|
||||||
rm subconverter
|
rm subconverter
|
||||||
c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter CMakeFiles/subconverter.dir/src/*.o libpcre2-8.a libevent.a libcurl.a libz.a libssl.a libcrypto.a libyaml-cpp.a libbz2.a libssh2.a -ldl -lpthread -O3
|
c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter CMakeFiles/subconverter.dir/src/*.o libpcre2-8.a libevent.a libcurl.a libz.a libssl.a libcrypto.a libyaml-cpp.a libbz2.a libssh2.a libduktape.a libduktape_module.a -ldl -lpthread -O3
|
||||||
|
|
||||||
cd base
|
cd base
|
||||||
chmod +rx subconverter
|
chmod +rx subconverter
|
||||||
|
|||||||
@@ -3,15 +3,29 @@ set -xe
|
|||||||
|
|
||||||
apt update
|
apt update
|
||||||
apt install -y git cmake clang pkg-config
|
apt install -y git cmake clang pkg-config
|
||||||
apt install -y libevent libcurl openssl pcre2
|
apt install -y libevent libcurl openssl pcre2 python2
|
||||||
|
|
||||||
git clone https://github.com/jbeder/yaml-cpp
|
git clone https://github.com/jbeder/yaml-cpp --depth=1
|
||||||
cd yaml-cpp
|
cd yaml-cpp
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=/data/data/com.termux/files/usr -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF .
|
cmake -DCMAKE_INSTALL_PREFIX=/data/data/com.termux/files/usr -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF .
|
||||||
make install -j3
|
make install -j3
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
git clone https://github.com/tencent/rapidjson
|
git clone https://github.com/tencent/rapidjson --depth=1
|
||||||
cd rapidjson
|
cd rapidjson
|
||||||
cp -r include/* /data/data/com.termux/files/usr/include/
|
cp -r include/* /data/data/com.termux/files/usr/include/
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
git clone https://github.com/svaarala/duktape --depth=1
|
||||||
|
cd duktape
|
||||||
|
pip2 install PyYAML
|
||||||
|
python2 util/dist.py
|
||||||
|
cd dist/src
|
||||||
|
cc -c -O3 -o duktape.o duktape.c
|
||||||
|
cc -c -O3 -o duk_module_node.o -I. ../extras/module-node/duk_module_node.c
|
||||||
|
ar cr libduktape.a duktape.o
|
||||||
|
ar cr libduktape_module.a duk_module_node.o
|
||||||
|
install -m0644 *.a /data/data/com.termux/files/usr/lib
|
||||||
|
install -m0644 duk*.h /data/data/com.termux/files/usr/include
|
||||||
|
install -m0644 ../extras/module-node/duk_module_node.h /data/data/com.termux/files/usr/include
|
||||||
|
cd ../../..
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "string_hash.h"
|
#include "string_hash.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "upload.h"
|
#include "upload.h"
|
||||||
|
#include "script_duktape.h"
|
||||||
|
|
||||||
#define MAX_EXTCONF_RULESET_COUNT 64
|
#define MAX_EXTCONF_RULESET_COUNT 64
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ bool do_sort = false, config_update_strict = false;
|
|||||||
bool clash_use_new_field_name = false;
|
bool clash_use_new_field_name = false;
|
||||||
std::string proxy_config, proxy_ruleset, proxy_subscription;
|
std::string proxy_config, proxy_ruleset, proxy_subscription;
|
||||||
int config_update_interval = 0;
|
int config_update_interval = 0;
|
||||||
|
std::string sort_script, filter_script;
|
||||||
|
|
||||||
std::string clash_rule_base;
|
std::string clash_rule_base;
|
||||||
string_array clash_extra_group;
|
string_array clash_extra_group;
|
||||||
@@ -84,6 +86,11 @@ template <typename T> T safe_as (const YAML::Node& node)
|
|||||||
return T();
|
return T();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T> void operator >>= (const YAML::Node& node, T& i)
|
||||||
|
{
|
||||||
|
i = safe_as<T>(node);
|
||||||
|
};
|
||||||
|
|
||||||
std::string parseProxy(const std::string &source)
|
std::string parseProxy(const std::string &source)
|
||||||
{
|
{
|
||||||
std::string proxy = source;
|
std::string proxy = source;
|
||||||
@@ -516,6 +523,9 @@ void readYAMLConf(YAML::Node &node)
|
|||||||
section["exclude_remarks"] >> def_exclude_remarks;
|
section["exclude_remarks"] >> def_exclude_remarks;
|
||||||
if(section["include_remarks"].IsSequence())
|
if(section["include_remarks"].IsSequence())
|
||||||
section["include_remarks"] >> def_include_remarks;
|
section["include_remarks"] >> def_include_remarks;
|
||||||
|
filter_script = safe_as<bool>(section["enable_filter"]) ? safe_as<std::string>(section["filter_script"]) : "";
|
||||||
|
if(startsWith(filter_script, "path:"))
|
||||||
|
filter_script = fileGet(filter_script.substr(5), false);
|
||||||
section["base_path"] >> base_path;
|
section["base_path"] >> base_path;
|
||||||
section["clash_rule_base"] >> clash_rule_base;
|
section["clash_rule_base"] >> clash_rule_base;
|
||||||
section["surge_rule_base"] >> surge_rule_base;
|
section["surge_rule_base"] >> surge_rule_base;
|
||||||
@@ -561,6 +571,7 @@ void readYAMLConf(YAML::Node &node)
|
|||||||
tfo_flag.set(safe_as<std::string>(section["tcp_fast_open_flag"]));
|
tfo_flag.set(safe_as<std::string>(section["tcp_fast_open_flag"]));
|
||||||
scv_flag.set(safe_as<std::string>(section["skip_cert_verify_flag"]));
|
scv_flag.set(safe_as<std::string>(section["skip_cert_verify_flag"]));
|
||||||
section["sort_flag"] >> do_sort;
|
section["sort_flag"] >> do_sort;
|
||||||
|
section["sort_script"] >> sort_script;
|
||||||
section["filter_deprecated_nodes"] >> filter_deprecated;
|
section["filter_deprecated_nodes"] >> filter_deprecated;
|
||||||
section["append_sub_userinfo"] >> append_userinfo;
|
section["append_sub_userinfo"] >> append_userinfo;
|
||||||
section["clash_use_new_field_name"] >> clash_use_new_field_name;
|
section["clash_use_new_field_name"] >> clash_use_new_field_name;
|
||||||
@@ -753,6 +764,9 @@ void readConf()
|
|||||||
ini.GetAll("exclude_remarks", def_exclude_remarks);
|
ini.GetAll("exclude_remarks", def_exclude_remarks);
|
||||||
if(ini.ItemPrefixExist("include_remarks"))
|
if(ini.ItemPrefixExist("include_remarks"))
|
||||||
ini.GetAll("include_remarks", def_include_remarks);
|
ini.GetAll("include_remarks", def_include_remarks);
|
||||||
|
filter_script = ini.GetBool("enable_filter") ? replace_all_distinct(ini.Get("filter_script"), "\\n", "\n") : "";
|
||||||
|
if(startsWith(filter_script, "path:"))
|
||||||
|
filter_script = fileGet(filter_script.substr(5), false);
|
||||||
ini.GetIfExist("base_path", base_path);
|
ini.GetIfExist("base_path", base_path);
|
||||||
ini.GetIfExist("clash_rule_base", clash_rule_base);
|
ini.GetIfExist("clash_rule_base", clash_rule_base);
|
||||||
ini.GetIfExist("surge_rule_base", surge_rule_base);
|
ini.GetIfExist("surge_rule_base", surge_rule_base);
|
||||||
@@ -785,6 +799,7 @@ void readConf()
|
|||||||
tfo_flag.set(ini.Get("tcp_fast_open_flag"));
|
tfo_flag.set(ini.Get("tcp_fast_open_flag"));
|
||||||
scv_flag.set(ini.Get("skip_cert_verify_flag"));
|
scv_flag.set(ini.Get("skip_cert_verify_flag"));
|
||||||
ini.GetBoolIfExist("sort_flag", do_sort);
|
ini.GetBoolIfExist("sort_flag", do_sort);
|
||||||
|
sort_script = replace_all_distinct(ini.Get("sort_script"), "\\n", "\n");
|
||||||
ini.GetBoolIfExist("filter_deprecated_nodes", filter_deprecated);
|
ini.GetBoolIfExist("filter_deprecated_nodes", filter_deprecated);
|
||||||
ini.GetBoolIfExist("append_sub_userinfo", append_userinfo);
|
ini.GetBoolIfExist("append_sub_userinfo", append_userinfo);
|
||||||
ini.GetBoolIfExist("clash_use_new_field_name", clash_use_new_field_name);
|
ini.GetBoolIfExist("clash_use_new_field_name", clash_use_new_field_name);
|
||||||
@@ -1163,7 +1178,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
/// switches with default value
|
/// switches with default value
|
||||||
tribool upload = getUrlArg(argument, "upload"), emoji = getUrlArg(argument, "emoji");
|
tribool upload = getUrlArg(argument, "upload"), emoji = getUrlArg(argument, "emoji");
|
||||||
tribool append_type = getUrlArg(argument, "append_type"), tfo = getUrlArg(argument, "tfo"), udp = getUrlArg(argument, "udp"), nodelist = getUrlArg(argument, "list");
|
tribool append_type = getUrlArg(argument, "append_type"), tfo = getUrlArg(argument, "tfo"), udp = getUrlArg(argument, "udp"), nodelist = getUrlArg(argument, "list");
|
||||||
tribool sort_flag = getUrlArg(argument, "sort");
|
tribool sort_flag = getUrlArg(argument, "sort"), use_sort_script = getUrlArg(argument, "sort_script");
|
||||||
tribool clash_new_field = getUrlArg(argument, "new_name"), clash_script = getUrlArg(argument, "script"), add_insert = getUrlArg(argument, "insert");
|
tribool clash_new_field = getUrlArg(argument, "new_name"), clash_script = getUrlArg(argument, "script"), add_insert = getUrlArg(argument, "insert");
|
||||||
tribool scv = getUrlArg(argument, "scv"), fdn = getUrlArg(argument, "fdn"), expand = getUrlArg(argument, "expand"), append_sub_userinfo = getUrlArg(argument, "append_info");
|
tribool scv = getUrlArg(argument, "scv"), fdn = getUrlArg(argument, "fdn"), expand = getUrlArg(argument, "expand"), append_sub_userinfo = getUrlArg(argument, "append_info");
|
||||||
tribool prepend_insert = getUrlArg(argument, "prepend");
|
tribool prepend_insert = getUrlArg(argument, "prepend");
|
||||||
@@ -1246,6 +1261,9 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
ext.skip_cert_verify.define(scv_flag);
|
ext.skip_cert_verify.define(scv_flag);
|
||||||
|
|
||||||
ext.sort_flag = sort_flag.get(do_sort);
|
ext.sort_flag = sort_flag.get(do_sort);
|
||||||
|
use_sort_script.define(sort_script.size());
|
||||||
|
if(ext.sort_flag && use_sort_script)
|
||||||
|
ext.sort_script = sort_script;
|
||||||
ext.filter_deprecated = fdn.get(filter_deprecated);
|
ext.filter_deprecated = fdn.get(filter_deprecated);
|
||||||
ext.clash_new_field_name = clash_new_field.get(clash_use_new_field_name);
|
ext.clash_new_field_name = clash_new_field.get(clash_use_new_field_name);
|
||||||
ext.clash_script = clash_script.get();
|
ext.clash_script = clash_script.get();
|
||||||
@@ -1415,6 +1433,31 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
else
|
else
|
||||||
nodes.emplace_back(x);
|
nodes.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
//run filter script
|
||||||
|
if(filter_script.size())
|
||||||
|
{
|
||||||
|
duk_context *ctx = duktape_init();
|
||||||
|
if(ctx)
|
||||||
|
{
|
||||||
|
defer(duk_destroy_heap(ctx);)
|
||||||
|
if(duktape_peval(ctx, filter_script) == 0)
|
||||||
|
{
|
||||||
|
auto filter = [&](const nodeInfo &x)
|
||||||
|
{
|
||||||
|
duk_get_global_string(ctx, "filter");
|
||||||
|
duktape_push_nodeinfo(ctx, x);
|
||||||
|
duk_pcall(ctx, 1);
|
||||||
|
return !duktape_get_res_bool(ctx);
|
||||||
|
};
|
||||||
|
nodes.erase(std::remove_if(nodes.begin(), nodes.end(), filter), nodes.end());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeLog(0, "Error when trying to parse script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
||||||
|
duk_pop(ctx); /// pop err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//check custom group name
|
//check custom group name
|
||||||
if(group.size())
|
if(group.size())
|
||||||
@@ -1662,14 +1705,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
std::string simpleToClashR(RESPONSE_CALLBACK_ARGS)
|
std::string simpleToClashR(RESPONSE_CALLBACK_ARGS)
|
||||||
{
|
{
|
||||||
std::string url = argument.size() <= 8 ? "" : argument.substr(8);
|
std::string url = argument.size() <= 8 ? "" : argument.substr(8);
|
||||||
std::string base_content;
|
|
||||||
std::vector<nodeInfo> nodes;
|
|
||||||
string_array extra_group, extra_ruleset, include_remarks, exclude_remarks;
|
|
||||||
std::vector<ruleset_content> rca;
|
|
||||||
std::string subInfo;
|
|
||||||
|
|
||||||
if(!url.size() && !api_mode)
|
|
||||||
url = default_url;
|
|
||||||
if(!url.size() || argument.substr(0, 8) != "sublink=")
|
if(!url.size() || argument.substr(0, 8) != "sublink=")
|
||||||
{
|
{
|
||||||
*status_code = 400;
|
*status_code = 400;
|
||||||
@@ -1680,71 +1715,7 @@ std::string simpleToClashR(RESPONSE_CALLBACK_ARGS)
|
|||||||
*status_code = 400;
|
*status_code = 400;
|
||||||
return "Please insert your subscription link instead of clicking the default link.";
|
return "Please insert your subscription link instead of clicking the default link.";
|
||||||
}
|
}
|
||||||
if(insert_url.size())
|
return subconverter("target=clashr&url=" + UrlEncode(url), postdata, status_code, extra_headers);
|
||||||
url = insert_url + "|" + url;
|
|
||||||
if(!api_mode || cfw_child_process)
|
|
||||||
readConf();
|
|
||||||
|
|
||||||
extra_group = clash_extra_group;
|
|
||||||
|
|
||||||
if(update_ruleset_on_request || cfw_child_process)
|
|
||||||
refreshRulesets(rulesets, ruleset_content_array);
|
|
||||||
rca = ruleset_content_array;
|
|
||||||
|
|
||||||
extra_settings ext = {true, overwrite_original_rules, safe_get_renames(), safe_get_emojis(), add_emoji, remove_old_emoji, append_proxy_type, false, do_sort, filter_deprecated, clash_use_new_field_name, false, "", "", ""};
|
|
||||||
|
|
||||||
std::string proxy = parseProxy(proxy_subscription);
|
|
||||||
|
|
||||||
include_remarks = def_include_remarks;
|
|
||||||
exclude_remarks = def_exclude_remarks;
|
|
||||||
|
|
||||||
//start parsing urls
|
|
||||||
int groupID = 0;
|
|
||||||
string_array dummy;
|
|
||||||
string_array urls = split(url, "|");
|
|
||||||
for(std::string &x : urls)
|
|
||||||
{
|
|
||||||
x = trim(x);
|
|
||||||
//std::cerr<<"Fetching node data from url '"<<x<<"'."<<std::endl;
|
|
||||||
writeLog(0, "Fetching node data from url '" + x + "'.", LOG_LEVEL_INFO);
|
|
||||||
if(addNodes(x, nodes, groupID, proxy, exclude_remarks, include_remarks, dummy, dummy, subInfo, false) == -1)
|
|
||||||
{
|
|
||||||
*status_code = 400;
|
|
||||||
return std::string("The following link doesn't contain any valid node info: " + x);
|
|
||||||
}
|
|
||||||
groupID++;
|
|
||||||
}
|
|
||||||
//exit if found nothing
|
|
||||||
if(!nodes.size())
|
|
||||||
{
|
|
||||||
*status_code = 400;
|
|
||||||
return "No nodes were found!";
|
|
||||||
}
|
|
||||||
|
|
||||||
writeLog(0, "Generate target: ClashR", LOG_LEVEL_INFO);
|
|
||||||
|
|
||||||
template_args tpl_args;
|
|
||||||
tpl_args.global_vars = global_vars;
|
|
||||||
tpl_args.local_vars["clash.new_field_name"] = clash_use_new_field_name ? "true" : "false";
|
|
||||||
tpl_args.request_params["target"] = "clashr";
|
|
||||||
tpl_args.request_params["url"] = url;
|
|
||||||
|
|
||||||
if(!enable_base_gen)
|
|
||||||
{
|
|
||||||
if(render_template(fetchFile(clash_rule_base, proxy, cache_config), tpl_args, base_content, template_path) != 0)
|
|
||||||
{
|
|
||||||
*status_code = 400;
|
|
||||||
return base_content;
|
|
||||||
}
|
|
||||||
//base_content = fetchFile(clash_rule_base, proxy, cache_config);
|
|
||||||
return netchToClash(nodes, base_content, rca, extra_group, true, ext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
YAML::Node yamlnode = safe_get_clash_base();
|
|
||||||
netchToClash(nodes, yamlnode, extra_group, true, ext);
|
|
||||||
return YAML::Dump(yamlnode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
|
std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
|
|
||||||
#define concat(a,b) a ## b
|
#define concat(a,b) a ## b
|
||||||
#define do_concat(a,b) concat(a,b)
|
#define do_concat(a,b) concat(a,b)
|
||||||
#define defer(x) std::shared_ptr<void> do_concat(__defer_deleter_,__LINE__) (nullptr, [&](...){x});
|
template <typename T> class __defer_struct final {private: T fn; bool __cancelled = false; public: __defer_struct(T func) : fn(std::move(func)) {} ~__defer_struct() {if(!__cancelled) fn();} void cancel() {__cancelled = true;} };
|
||||||
|
//#define defer(x) std::unique_ptr<void> do_concat(__defer_deleter_,__LINE__) (nullptr, [&](...){x});
|
||||||
|
#define defer(x) __defer_struct do_concat(__defer_deleter,__COUNTER__) ([&](...){x;});
|
||||||
|
|
||||||
typedef std::string::size_type string_size;
|
typedef std::string::size_type string_size;
|
||||||
typedef std::vector<std::string> string_array;
|
typedef std::vector<std::string> string_array;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "webget.h"
|
#include "webget.h"
|
||||||
#include "speedtestutil.h"
|
#include "speedtestutil.h"
|
||||||
|
#include "script_duktape.h"
|
||||||
|
|
||||||
std::string override_conf_port;
|
std::string override_conf_port;
|
||||||
bool ss_libev, ssr_libev;
|
bool ss_libev, ssr_libev;
|
||||||
@@ -26,18 +27,54 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std
|
|||||||
int linkType = -1;
|
int linkType = -1;
|
||||||
std::vector<nodeInfo> nodes;
|
std::vector<nodeInfo> nodes;
|
||||||
nodeInfo node;
|
nodeInfo node;
|
||||||
std::string strSub, extra_headers;
|
std::string strSub, extra_headers, custom_group;
|
||||||
|
|
||||||
// TODO: replace with startsWith if appropriate
|
// TODO: replace with startsWith if appropriate
|
||||||
link = replace_all_distinct(link, "\"", "");
|
link = replace_all_distinct(link, "\"", "");
|
||||||
|
|
||||||
|
/// script:filepath,arg1,arg2,...
|
||||||
|
if(startsWith(link, "script:") && authorized) /// process subscription with script
|
||||||
|
{
|
||||||
|
writeLog(0, "Found script link. Start running...", LOG_LEVEL_INFO);
|
||||||
|
string_array args = split(link.substr(7), ",");
|
||||||
|
if(args.size() >= 1)
|
||||||
|
{
|
||||||
|
std::string script = fileGet(args[0], false);
|
||||||
|
duk_context *ctx = duktape_init();
|
||||||
|
defer(duk_destroy_heap(ctx);)
|
||||||
|
duktape_peval(ctx, script);
|
||||||
|
duk_get_global_string(ctx, "parse");
|
||||||
|
for(size_t i = 1; i < args.size(); i++)
|
||||||
|
duk_push_string(ctx, trim(args[i]).c_str());
|
||||||
|
if(duk_pcall(ctx, args.size() - 1) == 0)
|
||||||
|
link = duktape_get_res_str(ctx);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeLog(0, "Error when trying to evaluate script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
||||||
|
duk_pop(ctx); /// pop err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// tag:group_name,link
|
||||||
|
if(startsWith(link, "tag:"))
|
||||||
|
{
|
||||||
|
string_size pos = link.find(",");
|
||||||
|
if(pos != link.npos)
|
||||||
|
{
|
||||||
|
custom_group = link.substr(4, pos - 4);
|
||||||
|
link.erase(0, pos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
writeLog(LOG_TYPE_INFO, "Received Link.");
|
writeLog(LOG_TYPE_INFO, "Received Link.");
|
||||||
if(strFind(link, "https://t.me/socks") || strFind(link, "tg://socks"))
|
if(startsWith(link, "https://t.me/socks") || startsWith(link, "tg://socks"))
|
||||||
linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||||
else if(strFind(link, "https://t.me/http") || strFind(link, "tg://http"))
|
else if(startsWith(link, "https://t.me/http") || startsWith(link, "tg://http"))
|
||||||
linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
else if(startsWith(link, "http://") || startsWith(link, "https://") || startsWith(link, "data:") || strFind(link, "surge:///install-config"))
|
else if(startsWith(link, "http://") || startsWith(link, "https://") || startsWith(link, "data:") || startsWith(link, "surge:///install-config"))
|
||||||
linkType = SPEEDTEST_MESSAGE_FOUNDSUB;
|
linkType = SPEEDTEST_MESSAGE_FOUNDSUB;
|
||||||
else if(strFind(link, "Netch://"))
|
else if(startsWith(link, "Netch://"))
|
||||||
linkType = SPEEDTEST_MESSAGE_FOUNDNETCH;
|
linkType = SPEEDTEST_MESSAGE_FOUNDNETCH;
|
||||||
else if(fileExist(link))
|
else if(fileExist(link))
|
||||||
linkType = SPEEDTEST_MESSAGE_FOUNDLOCAL;
|
linkType = SPEEDTEST_MESSAGE_FOUNDLOCAL;
|
||||||
@@ -46,7 +83,7 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std
|
|||||||
{
|
{
|
||||||
case SPEEDTEST_MESSAGE_FOUNDSUB:
|
case SPEEDTEST_MESSAGE_FOUNDSUB:
|
||||||
writeLog(LOG_TYPE_INFO, "Downloading subscription data...");
|
writeLog(LOG_TYPE_INFO, "Downloading subscription data...");
|
||||||
if(strFind(link, "surge:///install-config")) //surge config link
|
if(startsWith(link, "surge:///install-config")) //surge config link
|
||||||
link = UrlDecode(getUrlArg(link, "url"));
|
link = UrlDecode(getUrlArg(link, "url"));
|
||||||
strSub = webGet(link, proxy, extra_headers, cache_subscription);
|
strSub = webGet(link, proxy, extra_headers, cache_subscription);
|
||||||
/*
|
/*
|
||||||
@@ -82,7 +119,11 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std
|
|||||||
}
|
}
|
||||||
filterNodes(nodes, exclude_remarks, include_remarks, groupID);
|
filterNodes(nodes, exclude_remarks, include_remarks, groupID);
|
||||||
for(nodeInfo &x : nodes)
|
for(nodeInfo &x : nodes)
|
||||||
|
{
|
||||||
x.groupID = groupID;
|
x.groupID = groupID;
|
||||||
|
if(custom_group.size())
|
||||||
|
x.group = custom_group;
|
||||||
|
}
|
||||||
copyNodes(nodes, allNodes);
|
copyNodes(nodes, allNodes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -110,7 +151,11 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std
|
|||||||
}
|
}
|
||||||
filterNodes(nodes, exclude_remarks, include_remarks, groupID);
|
filterNodes(nodes, exclude_remarks, include_remarks, groupID);
|
||||||
for(nodeInfo &x : nodes)
|
for(nodeInfo &x : nodes)
|
||||||
|
{
|
||||||
x.groupID = groupID;
|
x.groupID = groupID;
|
||||||
|
if(custom_group.size())
|
||||||
|
x.group = custom_group;
|
||||||
|
}
|
||||||
copyNodes(nodes, allNodes);
|
copyNodes(nodes, allNodes);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -121,6 +166,8 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
node.groupID = groupID;
|
node.groupID = groupID;
|
||||||
|
if(custom_group.size())
|
||||||
|
node.group = custom_group;
|
||||||
allNodes.push_back(node);
|
allNodes.push_back(node);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
224
src/script.cpp
Normal file
224
src/script.cpp
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <duktape.h>
|
||||||
|
#include <duk_module_node.h>
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "multithread.h"
|
||||||
|
#include "nodeinfo.h"
|
||||||
|
|
||||||
|
extern int cache_config;
|
||||||
|
|
||||||
|
std::string parseProxy(const std::string &source);
|
||||||
|
|
||||||
|
std::string foldPathString(const std::string &path)
|
||||||
|
{
|
||||||
|
std::string output = path;
|
||||||
|
string_size pos_up, pos_slash, pos_unres = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pos_up = output.find("../", pos_unres);
|
||||||
|
if(pos_up == output.npos)
|
||||||
|
break;
|
||||||
|
else if(pos_up == 0)
|
||||||
|
{
|
||||||
|
pos_unres = pos_up + 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pos_slash = output.rfind("/", pos_up - 1);
|
||||||
|
if(pos_slash != output.npos)
|
||||||
|
{
|
||||||
|
pos_slash = output.rfind("/", pos_slash - 1);
|
||||||
|
if(pos_slash != output.npos)
|
||||||
|
output.erase(pos_slash + 1, pos_up - pos_slash + 2);
|
||||||
|
else
|
||||||
|
output.erase(0, pos_up + 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pos_unres = pos_up + 3;
|
||||||
|
} while(pos_up != output.npos);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
duk_ret_t cb_resolve_module(duk_context *ctx)
|
||||||
|
{
|
||||||
|
const char *requested_id = duk_get_string(ctx, 0);
|
||||||
|
const char *parent_id = duk_get_string(ctx, 1); /* calling module */
|
||||||
|
//const char *resolved_id;
|
||||||
|
std::string resolved_id;
|
||||||
|
if(strlen(parent_id))
|
||||||
|
{
|
||||||
|
std::string parent_path = parent_id;
|
||||||
|
string_size pos = parent_path.rfind("/");
|
||||||
|
if(pos != parent_path.npos)
|
||||||
|
resolved_id += parent_path.substr(0, pos + 1);
|
||||||
|
}
|
||||||
|
resolved_id += requested_id;
|
||||||
|
if(!endsWith(resolved_id, ".js"))
|
||||||
|
resolved_id += ".js";
|
||||||
|
resolved_id = foldPathString(resolved_id);
|
||||||
|
|
||||||
|
/* Arrive at the canonical module ID somehow. */
|
||||||
|
std::cout<<resolved_id<<std::endl;
|
||||||
|
if(!fileExist(resolved_id))
|
||||||
|
duk_push_undefined(ctx);
|
||||||
|
else
|
||||||
|
duk_push_string(ctx, resolved_id.c_str());
|
||||||
|
return 1; /*nrets*/
|
||||||
|
}
|
||||||
|
|
||||||
|
duk_ret_t cb_load_module(duk_context *ctx)
|
||||||
|
{
|
||||||
|
const char *resolved_id = duk_get_string(ctx, 0);
|
||||||
|
std::string module_source = fileGet(resolved_id, true);
|
||||||
|
|
||||||
|
/* Arrive at the JS source code for the module somehow. */
|
||||||
|
|
||||||
|
duk_push_string(ctx, module_source.c_str());
|
||||||
|
return 1; /*nrets*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static duk_ret_t native_print(duk_context *ctx)
|
||||||
|
{
|
||||||
|
duk_push_string(ctx, " ");
|
||||||
|
duk_insert(ctx, 0);
|
||||||
|
duk_join(ctx, duk_get_top(ctx) - 1);
|
||||||
|
printf("%s\n", duk_safe_to_string(ctx, -1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static duk_ret_t fetch(duk_context *ctx)
|
||||||
|
{
|
||||||
|
std::string filepath = duk_safe_to_string(ctx, -1), proxy = duk_safe_to_string(ctx, -1);
|
||||||
|
std::string content = fetchFile(filepath, proxy, cache_config);
|
||||||
|
duk_push_lstring(ctx, content.c_str(), content.size());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static duk_ret_t atob(duk_context *ctx)
|
||||||
|
{
|
||||||
|
std::string data = duk_safe_to_string(ctx, -1);
|
||||||
|
duk_push_string(ctx, base64_encode(data).c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static duk_ret_t btoa(duk_context *ctx)
|
||||||
|
{
|
||||||
|
std::string data = duk_safe_to_string(ctx, -1);
|
||||||
|
duk_push_string(ctx, base64_decode(data, true).c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
duk_context *duktape_init()
|
||||||
|
{
|
||||||
|
duk_context *ctx = duk_create_heap_default();
|
||||||
|
if(!ctx)
|
||||||
|
return NULL;
|
||||||
|
/// init module
|
||||||
|
duk_push_object(ctx);
|
||||||
|
duk_push_c_function(ctx, cb_resolve_module, DUK_VARARGS);
|
||||||
|
duk_put_prop_string(ctx, -2, "resolve");
|
||||||
|
duk_push_c_function(ctx, cb_load_module, DUK_VARARGS);
|
||||||
|
duk_put_prop_string(ctx, -2, "load");
|
||||||
|
duk_module_node_init(ctx);
|
||||||
|
|
||||||
|
duk_push_c_function(ctx, native_print, DUK_VARARGS);
|
||||||
|
duk_put_global_string(ctx, "print");
|
||||||
|
duk_push_c_function(ctx, fetch, 1);
|
||||||
|
duk_put_global_string(ctx, "fetch");
|
||||||
|
duk_push_c_function(ctx, atob, 1);
|
||||||
|
duk_put_global_string(ctx, "atob");
|
||||||
|
duk_push_c_function(ctx, btoa, 1);
|
||||||
|
duk_put_global_string(ctx, "btoa");
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int duktape_peval(duk_context *ctx, const std::string &script)
|
||||||
|
{
|
||||||
|
return duk_peval_string(ctx, script.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int duktape_call_function(duk_context *ctx, const std::string &name, size_t nargs, ...)
|
||||||
|
{
|
||||||
|
duk_get_global_string(ctx, name.c_str());
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, nargs);
|
||||||
|
size_t index = 0;
|
||||||
|
while(index < nargs)
|
||||||
|
{
|
||||||
|
std::string *arg = va_arg(vl, std::string*);
|
||||||
|
if(arg != NULL)
|
||||||
|
duk_push_string(ctx, arg->c_str());
|
||||||
|
else
|
||||||
|
duk_push_undefined(ctx);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
va_end(vl);
|
||||||
|
return duk_pcall(ctx, nargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int duktape_get_res_int(duk_context *ctx)
|
||||||
|
{
|
||||||
|
int retval = duk_to_int(ctx, -1);
|
||||||
|
duk_pop(ctx);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int duktape_push_nodeinfo(duk_context *ctx, const nodeInfo &node)
|
||||||
|
{
|
||||||
|
duk_push_object(ctx);
|
||||||
|
duk_push_string(ctx, node.group.c_str());
|
||||||
|
duk_put_prop_string(ctx, -2, "Group");
|
||||||
|
duk_push_int(ctx, node.groupID);
|
||||||
|
duk_put_prop_string(ctx, -2, "GroupID");
|
||||||
|
duk_push_int(ctx, node.id);
|
||||||
|
duk_put_prop_string(ctx, -2, "Index");
|
||||||
|
duk_push_string(ctx, node.remarks.c_str());
|
||||||
|
duk_put_prop_string(ctx, -2, "Remark");
|
||||||
|
duk_push_string(ctx, node.proxyStr.c_str());
|
||||||
|
duk_put_prop_string(ctx, -2, "ProxyInfo");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int duktape_push_nodeinfo_arr(duk_context *ctx, const nodeInfo &node, duk_idx_t index)
|
||||||
|
{
|
||||||
|
duk_push_object(ctx);
|
||||||
|
duk_push_string(ctx, "Group");
|
||||||
|
duk_push_string(ctx, node.group.c_str());
|
||||||
|
duk_def_prop(ctx, index - 2, DUK_DEFPROP_HAVE_VALUE);
|
||||||
|
duk_push_string(ctx, "GroupID");
|
||||||
|
duk_push_int(ctx, node.groupID);
|
||||||
|
duk_def_prop(ctx, index - 2, DUK_DEFPROP_HAVE_VALUE);
|
||||||
|
duk_push_string(ctx, "Index");
|
||||||
|
duk_push_int(ctx, node.id);
|
||||||
|
duk_def_prop(ctx, index - 2, DUK_DEFPROP_HAVE_VALUE);
|
||||||
|
duk_push_string(ctx, "Remark");
|
||||||
|
duk_push_string(ctx, node.remarks.c_str());
|
||||||
|
duk_def_prop(ctx, index - 2, DUK_DEFPROP_HAVE_VALUE);
|
||||||
|
duk_push_string(ctx, "ProxyInfo");
|
||||||
|
duk_push_string(ctx, node.proxyStr.c_str());
|
||||||
|
duk_def_prop(ctx, index - 2, DUK_DEFPROP_HAVE_VALUE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string duktape_get_res_str(duk_context *ctx)
|
||||||
|
{
|
||||||
|
std::string retstr = duk_safe_to_string(ctx, -1);
|
||||||
|
duk_pop(ctx);
|
||||||
|
return retstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool duktape_get_res_bool(duk_context *ctx)
|
||||||
|
{
|
||||||
|
bool ret = duk_to_boolean(ctx, -1);
|
||||||
|
duk_pop(ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string duktape_get_err_stack(duk_context *ctx)
|
||||||
|
{
|
||||||
|
duk_get_prop_string(ctx, -1, "stack");
|
||||||
|
std::string stackstr = duk_get_string(ctx, -1);
|
||||||
|
duk_pop(ctx);
|
||||||
|
return stackstr;
|
||||||
|
}
|
||||||
19
src/script_duktape.h
Normal file
19
src/script_duktape.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef SCRIPT_DUKTAPE_H_INCLUDED
|
||||||
|
#define SCRIPT_DUKTAPE_H_INCLUDED
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <duktape.h>
|
||||||
|
|
||||||
|
#include "nodeinfo.h"
|
||||||
|
|
||||||
|
duk_context *duktape_init();
|
||||||
|
int duktape_push_nodeinfo(duk_context *ctx, const nodeInfo &node);
|
||||||
|
int duktape_push_nodeinfo_arr(duk_context *ctx, const nodeInfo &node, duk_idx_t index = -1);
|
||||||
|
int duktape_peval(duk_context *ctx, const std::string &script);
|
||||||
|
int duktape_call_function(duk_context *ctx, const std::string &name, size_t nargs, ...);
|
||||||
|
int duktape_get_res_int(duk_context *ctx);
|
||||||
|
std::string duktape_get_res_str(duk_context *ctx);
|
||||||
|
bool duktape_get_res_bool(duk_context *ctx);
|
||||||
|
std::string duktape_get_err_stack(duk_context *ctx);
|
||||||
|
|
||||||
|
#endif // SCRIPT_DUKTAPE_H_INCLUDED
|
||||||
@@ -107,7 +107,7 @@ void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &n
|
|||||||
node.remarks = ps;
|
node.remarks = ps;
|
||||||
node.server = add;
|
node.server = add;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = vmessConstruct(add, port, type, id, aid, net, "auto", path, host, "", tls);
|
node.proxyStr = vmessConstruct(node.group, ps, add, port, type, id, aid, net, "auto", path, host, "", tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeVmessConf(std::string content, const std::string &custom_port, bool libev, std::vector<nodeInfo> &nodes)
|
void explodeVmessConf(std::string content, const std::string &custom_port, bool libev, std::vector<nodeInfo> &nodes)
|
||||||
@@ -185,11 +185,11 @@ void explodeVmessConf(std::string content, const std::string &custom_port, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
||||||
node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, edge, tls, udp, tfo, scv);
|
|
||||||
node.group = V2RAY_DEFAULT_GROUP;
|
node.group = V2RAY_DEFAULT_GROUP;
|
||||||
node.remarks = add + ":" + port;
|
node.remarks = add + ":" + port;
|
||||||
node.server = add;
|
node.server = add;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
|
node.proxyStr = vmessConstruct(node.group, node.remarks, add, port, type, id, aid, net, cipher, path, host, edge, tls, udp, tfo, scv);
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -242,19 +242,19 @@ void explodeVmessConf(std::string content, const std::string &custom_port, bool
|
|||||||
json["vmess"][i]["security"] >> cipher;
|
json["vmess"][i]["security"] >> cipher;
|
||||||
group = V2RAY_DEFAULT_GROUP;
|
group = V2RAY_DEFAULT_GROUP;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
||||||
node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls, udp, tfo, scv);
|
node.proxyStr = vmessConstruct(group, ps, add, port, type, id, aid, net, cipher, path, host, "", tls, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case 3: //ss config
|
case 3: //ss config
|
||||||
json["vmess"][i]["id"] >> id;
|
json["vmess"][i]["id"] >> id;
|
||||||
json["vmess"][i]["security"] >> cipher;
|
json["vmess"][i]["security"] >> cipher;
|
||||||
group = SS_DEFAULT_GROUP;
|
group = SS_DEFAULT_GROUP;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.proxyStr = ssConstruct(add, port, id, cipher, "", "", ps, libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(group, ps, add, port, id, cipher, "", "", libev, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case 4: //socks config
|
case 4: //socks config
|
||||||
group = SOCKS_DEFAULT_GROUP;
|
group = SOCKS_DEFAULT_GROUP;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||||
node.proxyStr = socksConstruct(ps, add, port, "", "", udp, tfo, scv);
|
node.proxyStr = socksConstruct(group, ps, add, port, "", "", udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
@@ -338,7 +338,7 @@ void explodeSS(std::string ss, bool libev, const std::string &custom_port, nodeI
|
|||||||
node.remarks = ps;
|
node.remarks = ps;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, ps, libev);
|
node.proxyStr = ssConstruct(group, ps, server, port, password, method, plugin, pluginopts, libev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeSSD(std::string link, bool libev, const std::string &custom_port, std::vector<nodeInfo> &nodes)
|
void explodeSSD(std::string link, bool libev, const std::string &custom_port, std::vector<nodeInfo> &nodes)
|
||||||
@@ -417,7 +417,7 @@ void explodeSSD(std::string link, bool libev, const std::string &custom_port, st
|
|||||||
node.remarks = remarks;
|
node.remarks = remarks;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev);
|
node.proxyStr = ssConstruct(group, remarks, server, port, password, method, plugin, pluginopts, libev);
|
||||||
node.id = index;
|
node.id = index;
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
index++;
|
index++;
|
||||||
@@ -461,7 +461,7 @@ void explodeSSAndroid(std::string ss, bool libev, const std::string &custom_port
|
|||||||
node.remarks = ps;
|
node.remarks = ps;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, ps, libev);
|
node.proxyStr = ssConstruct(group, ps, server, port, password, method, plugin, pluginopts, libev);
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -499,7 +499,7 @@ void explodeSSConf(std::string content, const std::string &custom_port, bool lib
|
|||||||
node.id = index;
|
node.id = index;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, ps, libev);
|
node.proxyStr = ssConstruct(group, ps, server, port, password, method, plugin, pluginopts, libev);
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -561,7 +561,7 @@ void explodeSSR(std::string ssr, bool ss_libev, bool ssr_libev, const std::strin
|
|||||||
if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs.empty() || obfs == "plain") && (protocol.empty() || protocol == "origin"))
|
if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs.empty() || obfs == "plain") && (protocol.empty() || protocol == "origin"))
|
||||||
{
|
{
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, "", "", remarks, ss_libev);
|
node.proxyStr = ssConstruct(group, remarks, server, port, password, method, "", "", ss_libev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -597,7 +597,7 @@ void explodeSSRConf(std::string content, const std::string &custom_port, bool ss
|
|||||||
pluginopts = GetMember(json, "plugin_opts");
|
pluginopts = GetMember(json, "plugin_opts");
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.group = SS_DEFAULT_GROUP;
|
node.group = SS_DEFAULT_GROUP;
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, node.remarks, ss_libev);
|
node.proxyStr = ssConstruct(node.group, node.remarks, server, port, password, method, plugin, pluginopts, ss_libev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -687,7 +687,7 @@ void explodeSocks(std::string link, const std::string &custom_port, nodeInfo &no
|
|||||||
node.remarks = remarks;
|
node.remarks = remarks;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = socksConstruct(remarks, server, port, username, password);
|
node.proxyStr = socksConstruct(group, remarks, server, port, username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeHTTP(std::string link, const std::string &custom_port, nodeInfo &node)
|
void explodeHTTP(std::string link, const std::string &custom_port, nodeInfo &node)
|
||||||
@@ -714,7 +714,7 @@ void explodeHTTP(std::string link, const std::string &custom_port, nodeInfo &nod
|
|||||||
node.remarks = remarks;
|
node.remarks = remarks;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = httpConstruct(remarks, server, port, username, password, strFind(link, "/https"));
|
node.proxyStr = httpConstruct(group, remarks, server, port, username, password, strFind(link, "/https"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeHTTPSub(std::string link, const std::string &custom_port, nodeInfo &node)
|
void explodeHTTPSub(std::string link, const std::string &custom_port, nodeInfo &node)
|
||||||
@@ -776,7 +776,7 @@ void explodeHTTPSub(std::string link, const std::string &custom_port, nodeInfo &
|
|||||||
node.remarks = remarks;
|
node.remarks = remarks;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = httpConstruct(remarks, server, port, username, password, tls);
|
node.proxyStr = httpConstruct(group, remarks, server, port, username, password, tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeTrojan(std::string trojan, const std::string &custom_port, nodeInfo &node)
|
void explodeTrojan(std::string trojan, const std::string &custom_port, nodeInfo &node)
|
||||||
@@ -827,7 +827,7 @@ void explodeTrojan(std::string trojan, const std::string &custom_port, nodeInfo
|
|||||||
node.remarks = remark;
|
node.remarks = remark;
|
||||||
node.server = server;
|
node.server = server;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = trojanConstruct(remark, server, port, psk, host, true);
|
node.proxyStr = trojanConstruct(node.group, remark, server, port, psk, host, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeQuan(std::string quan, const std::string &custom_port, nodeInfo &node)
|
void explodeQuan(std::string quan, const std::string &custom_port, nodeInfo &node)
|
||||||
@@ -889,23 +889,24 @@ void explodeQuan(std::string quan, const std::string &custom_port, nodeInfo &nod
|
|||||||
node.remarks = ps;
|
node.remarks = ps;
|
||||||
node.server = add;
|
node.server = add;
|
||||||
node.port = to_int(port, 1);
|
node.port = to_int(port, 1);
|
||||||
node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, edge, tls);
|
node.proxyStr = vmessConstruct(group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::string &custom_port, nodeInfo &node)
|
void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::string &custom_port, nodeInfo &node)
|
||||||
{
|
{
|
||||||
Document json;
|
Document json;
|
||||||
std::string type, remark, address, port, username, password, method, plugin, pluginopts, protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, edge, path, tls;
|
std::string type, group, remark, address, port, username, password, method, plugin, pluginopts, protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, edge, path, tls;
|
||||||
tribool udp, tfo, scv;
|
tribool udp, tfo, scv;
|
||||||
netch = urlsafe_base64_decode(netch.substr(8));
|
netch = urlsafe_base64_decode(netch.substr(8));
|
||||||
|
|
||||||
json.Parse(netch.data());
|
json.Parse(netch.data());
|
||||||
if(json.HasParseError())
|
if(json.HasParseError())
|
||||||
return;
|
return;
|
||||||
json["Type"] >> type;
|
type = GetMember(json, "Type");
|
||||||
json["Remark"] >> remark;
|
group = GetMember(json, "Group");
|
||||||
json["Hostname"] >> address;
|
remark = GetMember(json, "Remark");
|
||||||
|
address = GetMember(json, "Hostname");
|
||||||
udp = GetMember(json, "EnableUDP");
|
udp = GetMember(json, "EnableUDP");
|
||||||
tfo = GetMember(json, "EnableTFO");
|
tfo = GetMember(json, "EnableTFO");
|
||||||
scv = GetMember(json, "AllowInsecure");
|
scv = GetMember(json, "AllowInsecure");
|
||||||
@@ -921,9 +922,11 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
|
|||||||
case "SS"_hash:
|
case "SS"_hash:
|
||||||
plugin = GetMember(json, "Plugin");
|
plugin = GetMember(json, "Plugin");
|
||||||
pluginopts = GetMember(json, "PluginOption");
|
pluginopts = GetMember(json, "PluginOption");
|
||||||
node.group = SS_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
|
group = SS_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, ss_libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(group, remark, address, port, password, method, plugin, pluginopts, ss_libev, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "SSR"_hash:
|
case "SSR"_hash:
|
||||||
protocol = GetMember(json, "Protocol");
|
protocol = GetMember(json, "Protocol");
|
||||||
@@ -932,17 +935,21 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
|
|||||||
{
|
{
|
||||||
plugin = GetMember(json, "Plugin");
|
plugin = GetMember(json, "Plugin");
|
||||||
pluginopts = GetMember(json, "PluginOption");
|
pluginopts = GetMember(json, "PluginOption");
|
||||||
node.group = SS_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
|
group = SS_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, ss_libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(group, remark, address, port, password, method, plugin, pluginopts, ss_libev, udp, tfo, scv);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
protoparam = GetMember(json, "ProtocolParam");
|
protoparam = GetMember(json, "ProtocolParam");
|
||||||
obfsparam = GetMember(json, "OBFSParam");
|
obfsparam = GetMember(json, "OBFSParam");
|
||||||
node.group = SSR_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
|
group = SSR_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
|
||||||
node.proxyStr = ssrConstruct(SSR_DEFAULT_GROUP, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, ssr_libev, udp, tfo, scv);
|
node.proxyStr = ssrConstruct(group, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, ssr_libev, udp, tfo, scv);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "VMess"_hash:
|
case "VMess"_hash:
|
||||||
@@ -955,34 +962,44 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
|
|||||||
edge = GetMember(json, "Edge");
|
edge = GetMember(json, "Edge");
|
||||||
tls = GetMember(json, "TLSSecure");
|
tls = GetMember(json, "TLSSecure");
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
||||||
node.group = V2RAY_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, edge, tls, udp, tfo, scv);
|
group = V2RAY_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
|
node.proxyStr = vmessConstruct(group, remark, address, port, faketype, id, aid, transprot, method, path, host, edge, tls, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "Socks5"_hash:
|
case "Socks5"_hash:
|
||||||
username = GetMember(json, "Username");
|
username = GetMember(json, "Username");
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||||
node.group = SOCKS_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
node.proxyStr = socksConstruct(remark, address, port, username, password, udp, tfo, scv);
|
group = SOCKS_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
|
node.proxyStr = socksConstruct(group, remark, address, port, username, password, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "HTTP"_hash:
|
case "HTTP"_hash:
|
||||||
case "HTTPS"_hash:
|
case "HTTPS"_hash:
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
node.group = HTTP_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
node.proxyStr = httpConstruct(remark, address, port, username, password, type == "HTTPS", scv);
|
group = HTTP_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
|
node.proxyStr = httpConstruct(group, remark, address, port, username, password, type == "HTTPS", scv);
|
||||||
break;
|
break;
|
||||||
case "Trojan"_hash:
|
case "Trojan"_hash:
|
||||||
host = GetMember(json, "Host");
|
host = GetMember(json, "Host");
|
||||||
tls = GetMember(json, "TLSSecure");
|
tls = GetMember(json, "TLSSecure");
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
||||||
node.group = TROJAN_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
node.proxyStr = trojanConstruct(remark, address, port, username, password, tls == "true", udp, tfo, scv);
|
group = TROJAN_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
|
node.proxyStr = trojanConstruct(group, remark, address, port, username, password, tls == "true", udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "Snell"_hash:
|
case "Snell"_hash:
|
||||||
obfs = GetMember(json, "OBFS");
|
obfs = GetMember(json, "OBFS");
|
||||||
host = GetMember(json, "Host");
|
host = GetMember(json, "Host");
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
||||||
node.group = SNELL_DEFAULT_GROUP;
|
if(group.empty())
|
||||||
node.proxyStr = snellConstruct(remark, address, port, password, obfs, host, udp, tfo, scv);
|
group = SNELL_DEFAULT_GROUP;
|
||||||
|
node.group = group;
|
||||||
|
node.proxyStr = snellConstruct(group, remark, address, port, password, obfs, host, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@@ -1031,7 +1048,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
singleproxy["ws-headers"]["Edge"] >>= edge;
|
singleproxy["ws-headers"]["Edge"] >>= edge;
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
||||||
node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, edge, tls, udp, tfo, scv);
|
node.proxyStr = vmessConstruct(group, ps, server, port, type, id, aid, net, cipher, path, host, edge, tls, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "ss"_hash:
|
case "ss"_hash:
|
||||||
group = SS_DEFAULT_GROUP;
|
group = SS_DEFAULT_GROUP;
|
||||||
@@ -1101,7 +1118,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
}
|
}
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.proxyStr = ssConstruct(server, port, password, cipher, plugin, pluginopts, ps, ss_libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(group, ps, server, port, password, cipher, plugin, pluginopts, ss_libev, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "socks"_hash:
|
case "socks"_hash:
|
||||||
group = SOCKS_DEFAULT_GROUP;
|
group = SOCKS_DEFAULT_GROUP;
|
||||||
@@ -1110,7 +1127,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
singleproxy["password"] >>= password;
|
singleproxy["password"] >>= password;
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||||
node.proxyStr = socksConstruct(ps, server, port, user, password);
|
node.proxyStr = socksConstruct(group, ps, server, port, user, password);
|
||||||
break;
|
break;
|
||||||
case "ssr"_hash:
|
case "ssr"_hash:
|
||||||
group = SSR_DEFAULT_GROUP;
|
group = SSR_DEFAULT_GROUP;
|
||||||
@@ -1133,7 +1150,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
singleproxy["tls"] >>= tls;
|
singleproxy["tls"] >>= tls;
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
node.proxyStr = httpConstruct(ps, server, port, user, password, tls == "true", scv);
|
node.proxyStr = httpConstruct(group, ps, server, port, user, password, tls == "true", scv);
|
||||||
break;
|
break;
|
||||||
case "trojan"_hash:
|
case "trojan"_hash:
|
||||||
group = TROJAN_DEFAULT_GROUP;
|
group = TROJAN_DEFAULT_GROUP;
|
||||||
@@ -1141,7 +1158,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
singleproxy["sni"] >>= host;
|
singleproxy["sni"] >>= host;
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
||||||
node.proxyStr = trojanConstruct(ps, server, port, password, host, true, udp, tfo, scv);
|
node.proxyStr = trojanConstruct(group, ps, server, port, password, host, true, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "snell"_hash:
|
case "snell"_hash:
|
||||||
group = SNELL_DEFAULT_GROUP;
|
group = SNELL_DEFAULT_GROUP;
|
||||||
@@ -1150,7 +1167,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
singleproxy["obfs-opts"]["host"] >>= host;
|
singleproxy["obfs-opts"]["host"] >>= host;
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
||||||
node.proxyStr = snellConstruct(ps, server, port, password, obfs, host, udp, tfo, scv);
|
node.proxyStr = snellConstruct(group, ps, server, port, password, obfs, host, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
@@ -1224,7 +1241,7 @@ void explodeShadowrocket(std::string rocket, const std::string &custom_port, nod
|
|||||||
node.remarks = remarks;
|
node.remarks = remarks;
|
||||||
node.server = add;
|
node.server = add;
|
||||||
node.port = to_int(port, 0);
|
node.port = to_int(port, 0);
|
||||||
node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls);
|
node.proxyStr = vmessConstruct(node.group, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeKitsunebi(std::string kit, const std::string &custom_port, nodeInfo &node)
|
void explodeKitsunebi(std::string kit, const std::string &custom_port, nodeInfo &node)
|
||||||
@@ -1278,7 +1295,7 @@ void explodeKitsunebi(std::string kit, const std::string &custom_port, nodeInfo
|
|||||||
node.remarks = remarks;
|
node.remarks = remarks;
|
||||||
node.server = add;
|
node.server = add;
|
||||||
node.port = to_int(port, 0);
|
node.port = to_int(port, 0);
|
||||||
node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls);
|
node.proxyStr = vmessConstruct(node.group, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool explodeSurge(std::string surge, const std::string &custom_port, std::vector<nodeInfo> &nodes, bool libev)
|
bool explodeSurge(std::string surge, const std::string &custom_port, std::vector<nodeInfo> &nodes, bool libev)
|
||||||
@@ -1385,7 +1402,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.group = SS_DEFAULT_GROUP;
|
node.group = SS_DEFAULT_GROUP;
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(node.group, remarks, server, port, password, method, plugin, pluginopts, libev, udp, tfo, scv);
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
// continue;
|
// continue;
|
||||||
@@ -1425,7 +1442,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.group = SS_DEFAULT_GROUP;
|
node.group = SS_DEFAULT_GROUP;
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(node.group, remarks, server, port, password, method, plugin, pluginopts, libev, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "socks5"_hash: //surge 3 style socks5 proxy
|
case "socks5"_hash: //surge 3 style socks5 proxy
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||||
@@ -1454,7 +1471,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.proxyStr = socksConstruct(remarks, server, port, username, password, udp, tfo, scv);
|
node.proxyStr = socksConstruct(node.group, remarks, server, port, username, password, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "vmess"_hash: //surge 4 style vmess proxy
|
case "vmess"_hash: //surge 4 style vmess proxy
|
||||||
server = trim(configs[1]);
|
server = trim(configs[1]);
|
||||||
@@ -1502,7 +1519,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
||||||
node.group = V2RAY_DEFAULT_GROUP;
|
node.group = V2RAY_DEFAULT_GROUP;
|
||||||
node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, edge, tls, udp, tfo, scv);
|
node.proxyStr = vmessConstruct(node.group, remarks, server, port, "", id, "0", net, method, path, host, edge, tls, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "http"_hash: //http proxy
|
case "http"_hash: //http proxy
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
@@ -1526,7 +1543,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.proxyStr = httpConstruct(remarks, server, port, username, password, false, scv);
|
node.proxyStr = httpConstruct(node.group, remarks, server, port, username, password, false, scv);
|
||||||
break;
|
break;
|
||||||
case "trojan"_hash: // surge 4 style trojan proxy
|
case "trojan"_hash: // surge 4 style trojan proxy
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
||||||
@@ -1556,7 +1573,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
if(host.empty() && !isIPv4(server) && !isIPv6(server))
|
if(host.empty() && !isIPv4(server) && !isIPv6(server))
|
||||||
host = server;
|
host = server;
|
||||||
|
|
||||||
node.proxyStr = trojanConstruct(remarks, server, port, password, host, true, udp, tfo, scv);
|
node.proxyStr = trojanConstruct(node.group, remarks, server, port, password, host, true, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "snell"_hash:
|
case "snell"_hash:
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
||||||
@@ -1588,7 +1605,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
if(host.empty() && !isIPv4(server) && !isIPv6(server))
|
if(host.empty() && !isIPv4(server) && !isIPv6(server))
|
||||||
host = server;
|
host = server;
|
||||||
|
|
||||||
node.proxyStr = snellConstruct(remarks, server, port, password, plugin, host, udp, tfo, scv);
|
node.proxyStr = snellConstruct(node.group, remarks, server, port, password, plugin, host, udp, tfo, scv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch(hash_(remarks))
|
switch(hash_(remarks))
|
||||||
@@ -1642,7 +1659,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
{
|
{
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.group = SS_DEFAULT_GROUP;
|
node.group = SS_DEFAULT_GROUP;
|
||||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev, udp, tfo, scv);
|
node.proxyStr = ssConstruct(node.group, remarks, server, port, password, method, plugin, pluginopts, libev, udp, tfo, scv);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "vmess"_hash: //quantumult x style vmess link
|
case "vmess"_hash: //quantumult x style vmess link
|
||||||
@@ -1687,7 +1704,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
|
||||||
node.group = V2RAY_DEFAULT_GROUP;
|
node.group = V2RAY_DEFAULT_GROUP;
|
||||||
node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls, udp, tfo, scv);
|
node.proxyStr = vmessConstruct(node.group, remarks, server, port, "", id, "0", net, method, path, host, "", tls, udp, tfo, scv);
|
||||||
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(":")));
|
||||||
@@ -1722,7 +1739,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
||||||
node.group = TROJAN_DEFAULT_GROUP;
|
node.group = TROJAN_DEFAULT_GROUP;
|
||||||
node.proxyStr = trojanConstruct(remarks, server, port, password, host, tls == "true", udp, tfo, scv);
|
node.proxyStr = trojanConstruct(node.group, remarks, server, port, password, host, tls == "true", udp, tfo, scv);
|
||||||
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(":")));
|
||||||
@@ -1760,7 +1777,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
node.group = HTTP_DEFAULT_GROUP;
|
node.group = HTTP_DEFAULT_GROUP;
|
||||||
node.proxyStr = httpConstruct(remarks, server, port, username, password, tls == "true", scv);
|
node.proxyStr = httpConstruct(node.group, remarks, server, port, username, password, tls == "true", scv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
@@ -1810,7 +1827,7 @@ void explodeSSTap(std::string sstap, const std::string &custom_port, std::vector
|
|||||||
case 5: //socks 5
|
case 5: //socks 5
|
||||||
json["configs"][i]["username"] >> user;
|
json["configs"][i]["username"] >> user;
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||||
node.proxyStr = socksConstruct(remarks, server, port, user, pass);
|
node.proxyStr = socksConstruct(group, remarks, server, port, user, pass);
|
||||||
break;
|
break;
|
||||||
case 6: //ss/ssr
|
case 6: //ss/ssr
|
||||||
json["configs"][i]["protocol"] >> protocol;
|
json["configs"][i]["protocol"] >> protocol;
|
||||||
@@ -1819,7 +1836,7 @@ void explodeSSTap(std::string sstap, const std::string &custom_port, std::vector
|
|||||||
if(find(ss_ciphers.begin(), ss_ciphers.end(), cipher) != ss_ciphers.end() && protocol == "origin" && obfs == "plain") //is ss
|
if(find(ss_ciphers.begin(), ss_ciphers.end(), cipher) != ss_ciphers.end() && protocol == "origin" && obfs == "plain") //is ss
|
||||||
{
|
{
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
|
||||||
node.proxyStr = ssConstruct(server, port, pass, cipher, "", "", remarks, ss_libev);
|
node.proxyStr = ssConstruct(group, remarks, server, port, pass, cipher, "", "", ss_libev);
|
||||||
}
|
}
|
||||||
else //is ssr cipher
|
else //is ssr cipher
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "nodeinfo.h"
|
#include "nodeinfo.h"
|
||||||
|
|
||||||
std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string vmessConstruct(std::string group, std::string remarks, std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string ssConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string socksConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string username, std::string password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls, tribool scv = tribool());
|
std::string httpConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls, tribool scv = tribool());
|
||||||
std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string trojanConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string snellConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &node);
|
void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &node);
|
||||||
void explodeSSR(std::string ssr, bool ss_libev, bool libev, const std::string &custom_port, nodeInfo &node);
|
void explodeSSR(std::string ssr, bool ss_libev, bool libev, const std::string &custom_port, nodeInfo &node);
|
||||||
void explodeSS(std::string ss, bool libev, const std::string &custom_port, nodeInfo &node);
|
void explodeSS(std::string ss, bool libev, const std::string &custom_port, nodeInfo &node);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "string_hash.h"
|
#include "string_hash.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
#include "script_duktape.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
#include <rapidjson/writer.h>
|
#include <rapidjson/writer.h>
|
||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
#include <duktape.h>
|
||||||
|
|
||||||
#define MAX_RULES_COUNT 32768
|
#define MAX_RULES_COUNT 32768
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ std::string hostnameToIPAddr(const std::string &host)
|
|||||||
return retAddr;
|
return retAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls, tribool udp, tribool tfo, tribool scv)
|
std::string vmessConstruct(std::string group, std::string remarks, std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls, tribool udp, tribool tfo, tribool scv)
|
||||||
{
|
{
|
||||||
if(!path.size())
|
if(!path.size())
|
||||||
path = "/";
|
path = "/";
|
||||||
@@ -94,8 +96,10 @@ std::string vmessConstruct(std::string add, std::string port, std::string type,
|
|||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
writer.Key("Type");
|
writer.Key("Type");
|
||||||
writer.String("VMess");
|
writer.String("VMess");
|
||||||
|
writer.Key("Group");
|
||||||
|
writer.String(group.data());
|
||||||
writer.Key("Remark");
|
writer.Key("Remark");
|
||||||
writer.String(std::string(add + ":" + port).data());
|
writer.String(remarks.data());
|
||||||
writer.Key("Hostname");
|
writer.Key("Hostname");
|
||||||
writer.String(add.data());
|
writer.String(add.data());
|
||||||
writer.Key("Port");
|
writer.Key("Port");
|
||||||
@@ -194,13 +198,15 @@ std::string ssrConstruct(std::string group, std::string remarks, std::string rem
|
|||||||
return sb.GetString();
|
return sb.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, bool libev, tribool udp, tribool tfo, tribool scv)
|
std::string ssConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, bool libev, tribool udp, tribool tfo, tribool scv)
|
||||||
{
|
{
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
writer.Key("Type");
|
writer.Key("Type");
|
||||||
writer.String("SS");
|
writer.String("SS");
|
||||||
|
writer.Key("Group");
|
||||||
|
writer.String(group.data());
|
||||||
writer.Key("Remark");
|
writer.Key("Remark");
|
||||||
writer.String(remarks.data());
|
writer.String(remarks.data());
|
||||||
writer.Key("Hostname");
|
writer.Key("Hostname");
|
||||||
@@ -234,13 +240,15 @@ std::string ssConstruct(std::string server, std::string port, std::string passwo
|
|||||||
return sb.GetString();
|
return sb.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, tribool udp, tribool tfo, tribool scv)
|
std::string socksConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string username, std::string password, tribool udp, tribool tfo, tribool scv)
|
||||||
{
|
{
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
writer.Key("Type");
|
writer.Key("Type");
|
||||||
writer.String("Socks5");
|
writer.String("Socks5");
|
||||||
|
writer.Key("Group");
|
||||||
|
writer.String(group.data());
|
||||||
writer.Key("Remark");
|
writer.Key("Remark");
|
||||||
writer.String(remarks.data());
|
writer.String(remarks.data());
|
||||||
writer.Key("Hostname");
|
writer.Key("Hostname");
|
||||||
@@ -270,13 +278,15 @@ std::string socksConstruct(std::string remarks, std::string server, std::string
|
|||||||
return sb.GetString();
|
return sb.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls, tribool scv)
|
std::string httpConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls, tribool scv)
|
||||||
{
|
{
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
writer.Key("Type");
|
writer.Key("Type");
|
||||||
writer.String(tls ? "HTTPS" : "HTTP");
|
writer.String(tls ? "HTTPS" : "HTTP");
|
||||||
|
writer.Key("Group");
|
||||||
|
writer.String(group.data());
|
||||||
writer.Key("Remark");
|
writer.Key("Remark");
|
||||||
writer.String(remarks.data());
|
writer.String(remarks.data());
|
||||||
writer.Key("Hostname");
|
writer.Key("Hostname");
|
||||||
@@ -296,13 +306,15 @@ std::string httpConstruct(std::string remarks, std::string server, std::string p
|
|||||||
return sb.GetString();
|
return sb.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure, tribool udp, tribool tfo, tribool scv)
|
std::string trojanConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure, tribool udp, tribool tfo, tribool scv)
|
||||||
{
|
{
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
writer.Key("Type");
|
writer.Key("Type");
|
||||||
writer.String("Trojan");
|
writer.String("Trojan");
|
||||||
|
writer.Key("Group");
|
||||||
|
writer.String(group.data());
|
||||||
writer.Key("Remark");
|
writer.Key("Remark");
|
||||||
writer.String(remarks.data());
|
writer.String(remarks.data());
|
||||||
writer.Key("Hostname");
|
writer.Key("Hostname");
|
||||||
@@ -334,13 +346,15 @@ std::string trojanConstruct(std::string remarks, std::string server, std::string
|
|||||||
return sb.GetString();
|
return sb.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host, tribool udp, tribool tfo, tribool scv)
|
std::string snellConstruct(std::string group, std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host, tribool udp, tribool tfo, tribool scv)
|
||||||
{
|
{
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
writer.Key("Type");
|
writer.Key("Type");
|
||||||
writer.String("Snell");
|
writer.String("Snell");
|
||||||
|
writer.Key("Group");
|
||||||
|
writer.String(group.data());
|
||||||
writer.Key("Remark");
|
writer.Key("Remark");
|
||||||
writer.String(remarks.data());
|
writer.String(remarks.data());
|
||||||
writer.Key("Hostname");
|
writer.Key("Hostname");
|
||||||
@@ -409,7 +423,7 @@ bool matchRange(std::string &range, int target)
|
|||||||
bool match = false;
|
bool match = false;
|
||||||
std::string range_begin_str, range_end_str;
|
std::string range_begin_str, range_end_str;
|
||||||
int range_begin = 0, range_end = 0;
|
int range_begin = 0, range_end = 0;
|
||||||
const std::string reg_num = "-?\\d+", reg_range = "(\\d+)-(\\d+)", reg_not = "\\!-?(\\d+)", reg_not_range = "\\!(\\d+)-(\\d+)", reg_less = "(\\d+)-", reg_more = "(\\d+)\\+";
|
static const std::string reg_num = "-?\\d+", reg_range = "(\\d+)-(\\d+)", reg_not = "\\!-?(\\d+)", reg_not_range = "\\!(\\d+)-(\\d+)", reg_less = "(\\d+)-", reg_more = "(\\d+)\\+";
|
||||||
for(std::string &x : vArray)
|
for(std::string &x : vArray)
|
||||||
{
|
{
|
||||||
if(regMatch(x, reg_num))
|
if(regMatch(x, reg_num))
|
||||||
@@ -460,15 +474,35 @@ bool matchRange(std::string &range, int target)
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string nodeRename(const std::string &orig_remark, int groupID, const string_array &rename_array)
|
bool applyMatcher(const std::string &rule, std::string &real_rule, const nodeInfo &node)
|
||||||
|
{
|
||||||
|
std::string group, ret_real_rule;
|
||||||
|
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.*?)(?:!!(.*))?$)";
|
||||||
|
if(startsWith(rule, "!!GROUP="))
|
||||||
|
{
|
||||||
|
regGetMatch(rule, group_regex, 3, NULL, &group, &ret_real_rule);
|
||||||
|
real_rule = ret_real_rule;
|
||||||
|
return regFind(node.group, group);
|
||||||
|
}
|
||||||
|
else if(startsWith(rule, "!!GROUPID=") || startsWith(rule, "!!INSERT="))
|
||||||
|
{
|
||||||
|
int dir = startsWith(rule, "!!INSERT=") ? -1 : 1;
|
||||||
|
regGetMatch(rule, groupid_regex, 3, NULL, &group, &ret_real_rule);
|
||||||
|
real_rule = ret_real_rule;
|
||||||
|
return matchRange(group, dir * node.groupID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
real_rule = rule;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string nodeRename(const nodeInfo &node, const string_array &rename_array)
|
||||||
{
|
{
|
||||||
string_array vArray;
|
string_array vArray;
|
||||||
std::string targetRange, remark = orig_remark;
|
std::string remark = node.remarks, real_rule;
|
||||||
string_size pos;
|
|
||||||
|
|
||||||
for(const std::string &x : rename_array)
|
for(const std::string &x : rename_array)
|
||||||
{
|
{
|
||||||
targetRange = std::to_string(groupID);
|
|
||||||
vArray = split(x, "@");
|
vArray = split(x, "@");
|
||||||
if(vArray.size() == 1)
|
if(vArray.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -476,22 +510,11 @@ std::string nodeRename(const std::string &orig_remark, int groupID, const string
|
|||||||
}
|
}
|
||||||
else if(vArray.size() != 2)
|
else if(vArray.size() != 2)
|
||||||
continue;
|
continue;
|
||||||
if(startsWith(vArray[0], "!!GROUPID="))
|
if(applyMatcher(vArray[0], real_rule, node) && real_rule.size())
|
||||||
{
|
remark = regReplace(remark, real_rule, vArray[1]);
|
||||||
pos = vArray[0].find("!!", vArray[0].find("!!") + 2);
|
|
||||||
if(pos != vArray[0].npos)
|
|
||||||
{
|
|
||||||
targetRange = vArray[0].substr(10, pos - 10);
|
|
||||||
vArray[0] = vArray[0].substr(pos + 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(matchRange(targetRange, groupID))
|
|
||||||
remark = regReplace(remark, vArray[0], vArray[1]);
|
|
||||||
}
|
}
|
||||||
if(remark.empty())
|
if(remark.empty())
|
||||||
return orig_remark;
|
return node.remarks;
|
||||||
return remark;
|
return remark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,36 +534,21 @@ std::string removeEmoji(const std::string &orig_remark)
|
|||||||
return remark;
|
return remark;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string addEmoji(std::string remark, int groupID, const string_array &emoji_array)
|
std::string addEmoji(const nodeInfo &node, const string_array &emoji_array)
|
||||||
{
|
{
|
||||||
string_array vArray;
|
string_array vArray;
|
||||||
std::string targetRange;
|
std::string real_rule;
|
||||||
string_size pos;
|
string_size pos;
|
||||||
|
|
||||||
for(const std::string &x : emoji_array)
|
for(const std::string &x : emoji_array)
|
||||||
{
|
{
|
||||||
targetRange = std::to_string(groupID);
|
pos = x.rfind(",");
|
||||||
vArray = split(x, ",");
|
if(pos == x.npos)
|
||||||
if(vArray.size() != 2)
|
|
||||||
continue;
|
continue;
|
||||||
if(startsWith(vArray[0], "!!GROUPID="))
|
if(applyMatcher(x.substr(0, pos), real_rule, node) && real_rule.size() && regFind(node.remarks, real_rule))
|
||||||
{
|
return x.substr(pos + 1) + " " + node.remarks;
|
||||||
pos = vArray[0].find("!!", vArray[0].find("!!") + 2);
|
|
||||||
if(pos != vArray[0].npos)
|
|
||||||
{
|
|
||||||
targetRange = vArray[0].substr(10, pos - 10);
|
|
||||||
vArray[0] = vArray[0].substr(pos + 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(matchRange(targetRange, groupID) && regFind(remark, vArray[0]))
|
|
||||||
{
|
|
||||||
remark = vArray[1] + " " + remark;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return remark;
|
return node.remarks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void processRemark(std::string &oldremark, std::string &newremark, string_array &remarks_list)
|
void processRemark(std::string &oldremark, std::string &newremark, string_array &remarks_list)
|
||||||
@@ -934,61 +942,54 @@ void parseGroupTimes(const std::string &src, int *interval, int *tolerance, int
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void groupGenerate(std::string &rule, std::vector<nodeInfo> &nodelist, std::vector<std::string> &filtered_nodelist, bool add_direct)
|
void groupGenerate(std::string &rule, std::vector<nodeInfo> &nodelist, string_array &filtered_nodelist, bool add_direct)
|
||||||
{
|
{
|
||||||
std::string group, real_rule;
|
std::string group, real_rule;
|
||||||
const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.*?)(?:!!(.*))?$)";
|
const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.*?)(?:!!(.*))?$)";
|
||||||
if(rule.find("[]") == 0 && add_direct)
|
if(startsWith(rule, "[]") && add_direct)
|
||||||
{
|
{
|
||||||
filtered_nodelist.emplace_back(rule.substr(2));
|
filtered_nodelist.emplace_back(rule.substr(2));
|
||||||
}
|
}
|
||||||
else if(rule.find("!!GROUP=") == 0)
|
else if(startsWith(rule, "script:"))
|
||||||
{
|
{
|
||||||
regGetMatch(rule, group_regex, 3, NULL, &group, &real_rule);
|
duk_context *ctx = duktape_init();
|
||||||
if(real_rule.empty())
|
if(ctx)
|
||||||
{
|
{
|
||||||
for(nodeInfo &y : nodelist)
|
defer(duk_destroy_heap(ctx);)
|
||||||
|
std::string script = fileGet(rule.substr(7), true);
|
||||||
|
if(duktape_peval(ctx, script) == 0)
|
||||||
{
|
{
|
||||||
if(regFind(y.group, group) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
duk_get_global_string(ctx, "filter");
|
||||||
filtered_nodelist.emplace_back(y.remarks);
|
duk_idx_t arr_idx = duk_push_array(ctx), node_idx = 0;
|
||||||
|
for(nodeInfo &x : nodelist)
|
||||||
|
{
|
||||||
|
duktape_push_nodeinfo_arr(ctx, x, -1);
|
||||||
|
duk_put_prop_index(ctx, arr_idx, node_idx++);
|
||||||
|
}
|
||||||
|
if(duk_pcall(ctx, 1) == 0)
|
||||||
|
{
|
||||||
|
std::string result_list = duktape_get_res_str(ctx);
|
||||||
|
filtered_nodelist = split(regTrim(result_list), "\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeLog(0, "Error when trying to evaluate script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
||||||
|
duk_pop(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
for(nodeInfo &y : nodelist)
|
|
||||||
{
|
{
|
||||||
if(regFind(y.group, group) && regFind(y.remarks, real_rule) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
writeLog(0, "Error when trying to parse script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
||||||
filtered_nodelist.emplace_back(y.remarks);
|
duk_pop(ctx);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(rule.find("!!GROUPID=") == 0 || rule.find("!!INSERT=") == 0)
|
|
||||||
{
|
|
||||||
int dir = rule.find("!!INSERT=") == 0 ? -1 : 1;
|
|
||||||
regGetMatch(rule, groupid_regex, 3, NULL, &group, &real_rule);
|
|
||||||
if(real_rule.empty())
|
|
||||||
{
|
|
||||||
for(nodeInfo &y : nodelist)
|
|
||||||
{
|
|
||||||
if(matchRange(group, dir * y.groupID) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
|
||||||
filtered_nodelist.emplace_back(y.remarks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(nodeInfo &y : nodelist)
|
|
||||||
{
|
|
||||||
if(matchRange(group, dir * y.groupID) && regFind(y.remarks, real_rule) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
|
||||||
filtered_nodelist.emplace_back(y.remarks);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(nodeInfo &y : nodelist)
|
for(nodeInfo &x : nodelist)
|
||||||
{
|
{
|
||||||
if(regFind(y.remarks, rule) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
if(applyMatcher(rule, real_rule, x) && (real_rule.empty() || regFind(x.remarks, real_rule)) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), x.remarks) == filtered_nodelist.end())
|
||||||
filtered_nodelist.emplace_back(y.remarks);
|
filtered_nodelist.emplace_back(x.remarks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -997,17 +998,45 @@ void preprocessNodes(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
{
|
{
|
||||||
std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x)
|
std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x)
|
||||||
{
|
{
|
||||||
x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array);
|
x.remarks = nodeRename(x, ext.rename_array);
|
||||||
if(ext.remove_emoji)
|
if(ext.remove_emoji)
|
||||||
x.remarks = trim(removeEmoji(x.remarks));
|
x.remarks = trim(removeEmoji(x.remarks));
|
||||||
|
|
||||||
if(ext.add_emoji)
|
if(ext.add_emoji)
|
||||||
x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array);
|
x.remarks = addEmoji(x, ext.emoji_array);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(ext.sort_flag)
|
if(ext.sort_flag)
|
||||||
{
|
{
|
||||||
std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b)
|
bool failed = true;
|
||||||
|
if(ext.sort_script.size())
|
||||||
|
{
|
||||||
|
duk_context *ctx = duktape_init();
|
||||||
|
if(ctx)
|
||||||
|
{
|
||||||
|
defer(duk_destroy_heap(ctx);)
|
||||||
|
if(duktape_peval(ctx, ext.sort_script) == 0)
|
||||||
|
{
|
||||||
|
auto comparer = [&](const nodeInfo &a, const nodeInfo &b)
|
||||||
|
{
|
||||||
|
duk_get_global_string(ctx, "compare");
|
||||||
|
/// push 2 nodeinfo
|
||||||
|
duktape_push_nodeinfo(ctx, a);
|
||||||
|
duktape_push_nodeinfo(ctx, b);
|
||||||
|
/// call function
|
||||||
|
return duktape_get_res_int(ctx);
|
||||||
|
};
|
||||||
|
std::sort(nodes.begin(), nodes.end(), comparer);
|
||||||
|
failed = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeLog(0, "Error when trying to parse script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
||||||
|
duk_pop(ctx); /// pop err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(failed) std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b)
|
||||||
{
|
{
|
||||||
return a.remarks < b.remarks;
|
return a.remarks < b.remarks;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ struct extra_settings
|
|||||||
tribool udp = false;
|
tribool udp = false;
|
||||||
tribool tfo = false;
|
tribool tfo = false;
|
||||||
tribool skip_cert_verify = false;
|
tribool skip_cert_verify = false;
|
||||||
|
std::string sort_script;
|
||||||
};
|
};
|
||||||
|
|
||||||
void rulesetToClash(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset_content_array, bool overwrite_original_rules, bool new_field_name);
|
void rulesetToClash(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset_content_array, bool overwrite_original_rules, bool new_field_name);
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ static inline void curl_set_common_options(CURL *curl_handle, const char *url)
|
|||||||
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
|
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1L);
|
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1L);
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
|
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||||
|
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 20L);
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 15L);
|
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 15L);
|
||||||
@@ -109,12 +110,12 @@ static std::string curlGet(const std::string &url, const std::string &proxy, std
|
|||||||
static std::string dataGet(const std::string &url)
|
static std::string dataGet(const std::string &url)
|
||||||
{
|
{
|
||||||
if (!startsWith(url, "data:"))
|
if (!startsWith(url, "data:"))
|
||||||
return "";
|
return std::string();
|
||||||
std::string::size_type comma = url.find(',');
|
std::string::size_type comma = url.find(',');
|
||||||
if (comma == std::string::npos)
|
if (comma == std::string::npos || comma == url.size() - 1)
|
||||||
return "";
|
return std::string();
|
||||||
|
|
||||||
std::string data = UrlDecode(url.substr(comma));
|
std::string data = UrlDecode(url.substr(comma + 1));
|
||||||
if (endsWith(url.substr(0, comma), ";base64")) {
|
if (endsWith(url.substr(0, comma), ";base64")) {
|
||||||
return urlsafe_base64_decode(data);
|
return urlsafe_base64_decode(data);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user