update 2025-02-16 20:43:00
This commit is contained in:
parent
d8232e36df
commit
811b401d54
@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-bypass
|
PKG_NAME:=luci-app-bypass
|
||||||
PKG_VERSION:=1.8.1
|
PKG_VERSION:=1.8.2
|
||||||
PKG_RELEASE:=23
|
PKG_RELEASE:=23
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:= \
|
PKG_CONFIG_DEPENDS:= \
|
||||||
|
@ -4,16 +4,6 @@ local uci=luci.model.uci.cursor()
|
|||||||
local server_count=0
|
local server_count=0
|
||||||
local SYS=require"luci.sys"
|
local SYS=require"luci.sys"
|
||||||
|
|
||||||
function url(...)
|
|
||||||
local url = string.format("admin/services/%s", bypass)
|
|
||||||
local args = { ... }
|
|
||||||
for i, v in pairs(args) do
|
|
||||||
if v ~= "" then
|
|
||||||
url = url .. "/" .. v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return require "luci.dispatcher".build_url(url)
|
|
||||||
end
|
|
||||||
local server_table={}
|
local server_table={}
|
||||||
luci.model.uci.cursor():foreach("bypass","servers",function(s)
|
luci.model.uci.cursor():foreach("bypass","servers",function(s)
|
||||||
if (s.type=="ss" and not nixio.fs.access("/usr/bin/ss-local")) or (s.type=="ssr" and not nixio.fs.access("/usr/bin/ssr-local")) or s.type=="socks5" or s.type=="tun" then
|
if (s.type=="ss" and not nixio.fs.access("/usr/bin/ss-local")) or (s.type=="ssr" and not nixio.fs.access("/usr/bin/ssr-local")) or s.type=="socks5" or s.type=="tun" then
|
||||||
@ -82,7 +72,7 @@ o = s:option(Value, "ad_url", translate("anti-AD Update URL"))
|
|||||||
o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", translate("privacy-protection-tools/anti-ad-github"))
|
o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", translate("privacy-protection-tools/anti-ad-github"))
|
||||||
o:value("https://anti-ad.net/domains.txt", translate("privacy-protection-tools/anti-AD"))
|
o:value("https://anti-ad.net/domains.txt", translate("privacy-protection-tools/anti-AD"))
|
||||||
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt", translate("sirpdboy/ad_list"))
|
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt", translate("sirpdboy/ad_list"))
|
||||||
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt"
|
o.default = "https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt"
|
||||||
|
|
||||||
---- gfwlist URL
|
---- gfwlist URL
|
||||||
o = s:option(Value, "gfwlist_url", translate("GFW domains Update URL"))
|
o = s:option(Value, "gfwlist_url", translate("GFW domains Update URL"))
|
||||||
@ -91,8 +81,7 @@ o:value("https://fastly.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt", t
|
|||||||
o:value("https://fastly.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt", translate("gfwlist/gfwlist"))
|
o:value("https://fastly.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt", translate("gfwlist/gfwlist"))
|
||||||
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt", translate("sirpdboy/gfwlist"))
|
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt", translate("sirpdboy/gfwlist"))
|
||||||
o:value("https://openwrt.ai/bypass/gfwlist.txt", translate("supes/gfwlist"))
|
o:value("https://openwrt.ai/bypass/gfwlist.txt", translate("supes/gfwlist"))
|
||||||
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt"
|
o.default = "https://fastly.jsdelivr.net/gh/YW5vbnltb3Vz/domain-list-community@release/gfwlist.txt"
|
||||||
|
|
||||||
|
|
||||||
----chnroute URL
|
----chnroute URL
|
||||||
o = s:option(Value, "chnroute_url", translate("China IPv4 Update URL"))
|
o = s:option(Value, "chnroute_url", translate("China IPv4 Update URL"))
|
||||||
@ -104,26 +93,26 @@ o:value("https://fastly.jsdelivr.net/gh/soffchen/GeoIP2-CN@release/CN-ip-cidr.tx
|
|||||||
o:value("https://fastly.jsdelivr.net/gh/Hackl0us/GeoIP2-CN@release/CN-ip-cidr.txt", translate("Hackl0us/GeoIP2-CN"))
|
o:value("https://fastly.jsdelivr.net/gh/Hackl0us/GeoIP2-CN@release/CN-ip-cidr.txt", translate("Hackl0us/GeoIP2-CN"))
|
||||||
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt", translate("sirpdboy/all_cn"))
|
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt", translate("sirpdboy/all_cn"))
|
||||||
o:value("https://openwrt.ai/bypass/all_cn.txt", translate("supes/all_cn"))
|
o:value("https://openwrt.ai/bypass/all_cn.txt", translate("supes/all_cn"))
|
||||||
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt"
|
o.default = "https://ispip.clang.cn/all_cn.txt"
|
||||||
|
|
||||||
----chnroute6 URL
|
----chnroute6 URL
|
||||||
o = s:option(Value, "chnroute6_url", translate("China IPv6 Update URL"))
|
o = s:option(Value, "chnroute6_url", translate("China IPv6 Update URL"))
|
||||||
o:value("https://ispip.clang.cn/all_cn_ipv6.txt", translate("Clang.CN.IPv6"))
|
o:value("https://ispip.clang.cn/all_cn_ipv6.txt", translate("Clang.CN.IPv6"))
|
||||||
o:value("https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china6.txt", translate("gaoyifan/china-ipv6"))
|
o:value("https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china6.txt", translate("gaoyifan/china-ipv6"))
|
||||||
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt", translate("sirpdboy/all_cn_ipv6"))
|
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt", translate("sirpdboy/all_cn_ipv6"))
|
||||||
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt"
|
o.default = "https://ispip.clang.cn/all_cn_ipv6.txt"
|
||||||
|
|
||||||
----domains URL
|
----domains URL
|
||||||
o = s:option(Value, "domains_url", translate("China Domains Update URL"))
|
o = s:option(Value, "domains_url", translate("China Domains Update URL"))
|
||||||
o:value("https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt", translate("yubanmeiqin9048/domains.china"))
|
o:value("https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt", translate("yubanmeiqin9048/domains.china"))
|
||||||
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt", translate("sirpdboy/domains_cn"))
|
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt", translate("sirpdboy/domains_cn"))
|
||||||
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt"
|
o.default = "https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt"
|
||||||
|
|
||||||
o = s:option(Button, "UpdateRule", translate("Update All Rule List"))
|
o = s:option(Button, "UpdateRule", translate("Update All Rule List"))
|
||||||
o.inputstyle = "apply"
|
o.inputstyle = "apply"
|
||||||
function o.write(t, n)
|
o.write = function()
|
||||||
luci.sys.call("/usr/share/bypass/update")
|
luci.sys.call("bash /usr/share/bypass/update")
|
||||||
luci.http.redirect(url("log"))
|
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "bypass", "log"))
|
||||||
end
|
end
|
||||||
|
|
||||||
s=m:section(TypedSection,"socks5_proxy",translate("Global SOCKS5 Server"))
|
s=m:section(TypedSection,"socks5_proxy",translate("Global SOCKS5 Server"))
|
||||||
|
@ -154,8 +154,8 @@ end
|
|||||||
if is_finded("sslocal") or is_finded("ssmanager") then
|
if is_finded("sslocal") or is_finded("ssmanager") then
|
||||||
o:value("ss", translate("Shadowsocks-rust Version"))
|
o:value("ss", translate("Shadowsocks-rust Version"))
|
||||||
end
|
end
|
||||||
if is_finded("trojan-plus") or is_finded("trojan") then
|
if is_finded("trojan") then
|
||||||
o:value("trojan", translate("Trojan-plus"))
|
o:value("trojan", translate("Trojan"))
|
||||||
end
|
end
|
||||||
if is_finded("naive") then
|
if is_finded("naive") then
|
||||||
o:value("naiveproxy", translate("NaiveProxy"))
|
o:value("naiveproxy", translate("NaiveProxy"))
|
||||||
@ -509,6 +509,7 @@ o.rmempty = true
|
|||||||
|
|
||||||
-- Tuic settings for the local inbound socks5 server
|
-- Tuic settings for the local inbound socks5 server
|
||||||
o = s:option(Flag, "tuic_dual_stack", translate("Dual-stack Listening Socket"))
|
o = s:option(Flag, "tuic_dual_stack", translate("Dual-stack Listening Socket"))
|
||||||
|
o.description = translate("If this option is not set, the socket behavior is platform dependent.")
|
||||||
o:depends("type", "tuic")
|
o:depends("type", "tuic")
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
@ -564,6 +565,7 @@ o:value("kcp", "mKCP")
|
|||||||
o:value("ws", "WebSocket")
|
o:value("ws", "WebSocket")
|
||||||
o:value("httpupgrade", "HTTPUpgrade")
|
o:value("httpupgrade", "HTTPUpgrade")
|
||||||
o:value("splithttp", "SplitHTTP")
|
o:value("splithttp", "SplitHTTP")
|
||||||
|
o:value("xhttp", "XHTTP")
|
||||||
o:value("h2", "HTTP/2")
|
o:value("h2", "HTTP/2")
|
||||||
o:value("quic", "QUIC")
|
o:value("quic", "QUIC")
|
||||||
o:value("grpc", "gRPC")
|
o:value("grpc", "gRPC")
|
||||||
@ -641,6 +643,71 @@ o.rmempty = true
|
|||||||
o = s:option(Value, "splithttp_path", translate("Splithttp Path"))
|
o = s:option(Value, "splithttp_path", translate("Splithttp Path"))
|
||||||
o:depends("transport", "splithttp")
|
o:depends("transport", "splithttp")
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
|
-- [[ XHTTP部分 ]]--
|
||||||
|
o = s:option(ListValue, "xhttp_alpn", translate("XHTTP Alpn"))
|
||||||
|
o.default = ""
|
||||||
|
o:value("", translate("Default"))
|
||||||
|
o:value("h3")
|
||||||
|
o:value("h2")
|
||||||
|
o:value("h3,h2")
|
||||||
|
o:value("http/1.1")
|
||||||
|
o:value("h2,http/1.1")
|
||||||
|
o:value("h3,h2,http/1.1")
|
||||||
|
o:depends("transport", "xhttp")
|
||||||
|
o = s:option(ListValue, "xhttp_mode", translate("XHTTP Mode"))
|
||||||
|
o:depends("transport", "xhttp")
|
||||||
|
o.default = "auto"
|
||||||
|
o:value("auto")
|
||||||
|
o:value("packet-up")
|
||||||
|
o:value("stream-up")
|
||||||
|
o:value("stream-one")
|
||||||
|
o = s:option(Value, "xhttp_host", translate("XHTTP Host"))
|
||||||
|
o:depends({transport = "xhttp", tls = false})
|
||||||
|
o.rmempty = true
|
||||||
|
o = s:option(Value, "xhttp_path", translate("XHTTP Path"))
|
||||||
|
o.placeholder = "/"
|
||||||
|
o:depends("transport", "xhttp")
|
||||||
|
o.rmempty = true
|
||||||
|
o = s:option(Flag, "enable_xhttp_extra", translate("XHTTP Extra"))
|
||||||
|
o.description = translate("Enable this option to configure XHTTP Extra (JSON format).")
|
||||||
|
o.rmempty = true
|
||||||
|
o.default = "0"
|
||||||
|
o:depends("transport", "xhttp")
|
||||||
|
o = s:option(TextValue, "xhttp_extra", " ")
|
||||||
|
o.description = translate(
|
||||||
|
"<font><b>" .. translate("Configure XHTTP Extra Settings (JSON format), see:") .. "</b></font>" ..
|
||||||
|
" <a href='https://xtls.github.io/config/transports/splithttp.html#extra' target='_blank'>" ..
|
||||||
|
"<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
|
||||||
|
o:depends("enable_xhttp_extra", true)
|
||||||
|
o.rmempty = true
|
||||||
|
o.rows = 10
|
||||||
|
o.wrap = "off"
|
||||||
|
o.custom_write = function(self, section, value)
|
||||||
|
m:set(section, "xhttp_extra", value)
|
||||||
|
local success, data = pcall(luci.jsonc.parse, value)
|
||||||
|
if success and data then
|
||||||
|
local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address)
|
||||||
|
or (data.downloadSettings and data.downloadSettings.address)
|
||||||
|
if address and address ~= "" then
|
||||||
|
m:set(section, "download_address", address)
|
||||||
|
else
|
||||||
|
m:del(section, "download_address")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
m:del(section, "download_address")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
o.validate = function(self, value)
|
||||||
|
value = value:gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n")
|
||||||
|
if value:sub(-1) == "\n" then
|
||||||
|
value = value:sub(1, -2)
|
||||||
|
end
|
||||||
|
local success, data = pcall(luci.jsonc.parse, value)
|
||||||
|
if not success or not data then
|
||||||
|
return nil, translate("Invalid JSON format")
|
||||||
|
end
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
-- [[ H2部分 ]]--
|
-- [[ H2部分 ]]--
|
||||||
|
|
||||||
@ -871,6 +938,18 @@ if is_finded("xray") then
|
|||||||
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", tls = true})
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", tls = true})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", reality = true})
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", reality = true})
|
||||||
|
|
||||||
|
o = s:option(ListValue, "xhttp_tls_flow", translate("Flow"))
|
||||||
|
for _, v in ipairs(tls_flows) do
|
||||||
|
if v == "none" then
|
||||||
|
o.default = "none"
|
||||||
|
o:value("none", translate("none"))
|
||||||
|
else
|
||||||
|
o:value("xtls-rprx-vision", translate("xtls-rprx-vision"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
o.rmempty = true
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp", tls = true})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp", reality = true})
|
||||||
-- [[ uTLS ]]--
|
-- [[ uTLS ]]--
|
||||||
o = s:option(ListValue, "fingerprint", translate("Finger Print"))
|
o = s:option(ListValue, "fingerprint", translate("Finger Print"))
|
||||||
o.default = ""
|
o.default = ""
|
||||||
@ -919,43 +998,77 @@ o:depends({type = "hysteria", insecure = true })
|
|||||||
o:depends({type = "hysteria2", insecure = true })
|
o:depends({type = "hysteria2", insecure = true })
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
|
|
||||||
-- [[ Mux ]]--
|
-- [[ Mux.Cool ]] --
|
||||||
o = s:option(Flag, "mux", translate("Mux"))
|
o = s:option(Flag, "mux", translate("Mux"), translate("Enable Mux.Cool"))
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
o.default = false
|
o.default = false
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "vless"})
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "ws"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "kcp"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "httpupgrade"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "splithttp"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "h2"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "quic"})
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "grpc"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
|
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "trojan"})
|
o:depends({type = "v2ray", v2ray_protocol = "trojan"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
|
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "socks"})
|
o:depends({type = "v2ray", v2ray_protocol = "socks"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "http"})
|
o:depends({type = "v2ray", v2ray_protocol = "http"})
|
||||||
|
|
||||||
|
-- [[ XUDP Mux ]] --
|
||||||
|
o = s:option(Flag, "xmux", translate("Xudp Mux"), translate("Enable Xudp Mux"))
|
||||||
|
o.rmempty = false
|
||||||
|
o.default = false
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
|
||||||
-- [[ TCP 最大并发连接数 ]]--
|
-- [[ TCP 最大并发连接数 ]]--
|
||||||
o = s:option(ListValue, "concurrency", translate("concurrency"))
|
o = s:option(Value, "concurrency", translate("concurrency"))
|
||||||
|
o.description = translate(
|
||||||
|
"<ul>"
|
||||||
|
.. "<li>" .. translate("Default: disable. When entering a negative number, such as -1, The Mux module will not be used to carry TCP traffic.") .. "</li>"
|
||||||
|
.. "<li>" .. translate("Min value is 1, Max value is 128. When omitted or set to 0, it equals 8.") .. "</li>"
|
||||||
|
.. "</ul>")
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
o.default = "-1"
|
o.default = "-1"
|
||||||
o:value("-1", translate("disable"))
|
o:value("-1", translate("disable"))
|
||||||
o:value("8", translate("8"))
|
o:value("8", translate("8"))
|
||||||
o:depends("mux", true)
|
o:depends("mux", true)
|
||||||
-- [[ UDP 最大并发连接数 ]]--
|
-- [[ UDP 最大并发连接数 ]]--
|
||||||
o = s:option(ListValue, "xudpConcurrency", translate("xudpConcurrency"))
|
o = s:option(Value, "xudpConcurrency", translate("xudpConcurrency"))
|
||||||
|
o.description = translate(
|
||||||
|
"<ul>"
|
||||||
|
.. "<li>" .. translate("Default:16. When entering a negative number, such as -1, The Mux module will not be used to carry UDP traffic, Use original UDP transmission method of proxy protocol.") .. "</li>"
|
||||||
|
.. "<li>" .. translate("Min value is 1, Max value is 1024. When omitted or set to 0, Will same path as TCP traffic.") .. "</li>"
|
||||||
|
.. "</ul>")
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
o.default = "16"
|
o.default = "16"
|
||||||
o:value("-1", translate("disable"))
|
o:value("-1", translate("disable"))
|
||||||
o:value("16", translate("16"))
|
o:value("16", translate("16"))
|
||||||
o:depends("mux", true)
|
o:depends("mux", true)
|
||||||
|
o:depends("xmux", true)
|
||||||
-- [[ 对被代理的 UDP/443 流量处理方式 ]]--
|
-- [[ 对被代理的 UDP/443 流量处理方式 ]]--
|
||||||
o = s:option(ListValue, "xudpProxyUDP443", translate("xudpProxyUDP443"))
|
o = s:option(ListValue, "xudpProxyUDP443", translate("xudpProxyUDP443"))
|
||||||
|
o.description = translate(
|
||||||
|
"<ul>"
|
||||||
|
.. "<li>" .. translate("Default reject rejects traffic.") .. "</li>"
|
||||||
|
.. "<li>" .. translate("allow: Allows use Mux connection.") .. "</li>"
|
||||||
|
.. "<li>" .. translate("skip: Not use Mux module to carry UDP 443 traffic, Use original UDP transmission method of proxy protocol.") .. "</li>"
|
||||||
|
.. "</ul>")
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
o.default = "reject"
|
o.default = "reject"
|
||||||
o:value("reject", translate("reject"))
|
o:value("reject", translate("reject"))
|
||||||
o:value("allow", translate("allow"))
|
o:value("allow", translate("allow"))
|
||||||
o:value("skip", translate("skip"))
|
o:value("skip", translate("skip"))
|
||||||
o:depends("mux", true)
|
o:depends("mux", true)
|
||||||
|
-- [[ XHTTP TCP Fast Open ]]--
|
||||||
|
o = s:option(Flag, "tcpfastopen", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
|
||||||
|
o.rmempty = true
|
||||||
|
o.default = "0"
|
||||||
|
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
|
||||||
-- [[ MPTCP ]]--
|
-- [[ MPTCP ]]--
|
||||||
o = s:option(Flag, "mptcp", translate("MPTCP"))
|
o = s:option(Flag, "mptcp", translate("MPTCP"), translate("Enable Multipath TCP, need to be enabled in both server and client configuration."))
|
||||||
o.rmempty = false
|
o.rmempty = true
|
||||||
o.default = false
|
o.default = "0"
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "vless"})
|
o:depends({type = "v2ray", v2ray_protocol = "vless"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
|
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
|
||||||
o:depends({type = "v2ray", v2ray_protocol = "trojan"})
|
o:depends({type = "v2ray", v2ray_protocol = "trojan"})
|
||||||
@ -1029,7 +1142,7 @@ o:value("/etc/ssl/private/ca.pem")
|
|||||||
o.description = translate("Please confirm the current certificate path")
|
o.description = translate("Please confirm the current certificate path")
|
||||||
o.default = "/etc/ssl/private/ca.pem"
|
o.default = "/etc/ssl/private/ca.pem"
|
||||||
|
|
||||||
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
|
o = s:option(Flag, "fast_open", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
o:depends("type", "ssr")
|
o:depends("type", "ssr")
|
||||||
|
@ -9,17 +9,26 @@ local dsp=require "luci.dispatcher"
|
|||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
window.addEventListener('load',function(){
|
window.addEventListener('load',function(){
|
||||||
const doms=document.getElementsByClassName('pingtime');
|
const doms=document.getElementsByClassName('pingtime');
|
||||||
const ports=document.getElementsByClassName("socket-connected")
|
const ports = document.getElementsByClassName("socket-connected");
|
||||||
|
const transports = document.getElementsByClassName("transport");
|
||||||
|
const wsPaths = document.getElementsByClassName("wsPath");
|
||||||
|
const tlss = document.getElementsByClassName("tls");
|
||||||
const xhr=(index) =>{
|
const xhr=(index) =>{
|
||||||
return new Promise((res) =>{
|
return new Promise((res) =>{
|
||||||
const dom=doms[index];
|
const dom=doms[index];
|
||||||
const port=ports[index];
|
const port=ports[index];
|
||||||
|
const transport = transports[index];
|
||||||
|
const wsPath = wsPaths[index];
|
||||||
|
const tls = tlss[index];
|
||||||
if (!dom) res()
|
if (!dom) res()
|
||||||
port.innerHTML='<font style=\"color:#0072c3\"><%:connecting%></font>';
|
port.innerHTML='<font style=\"color:#0072c3\"><%:connecting%></font>';
|
||||||
XHR.get('<%=dsp.build_url("admin/services/bypass/ping")%>',{
|
XHR.get('<%=dsp.build_url("admin/services/bypass/ping")%>',{
|
||||||
index,
|
index,
|
||||||
domain: dom.getAttribute("hint"),
|
domain: dom.getAttribute("hint"),
|
||||||
port: port.getAttribute("hint")
|
port: port.getAttribute("hint"),
|
||||||
|
transport: transport.getAttribute("hint"),
|
||||||
|
wsPath: wsPath.getAttribute("hint"),
|
||||||
|
tls: tls.getAttribute("hint")
|
||||||
},
|
},
|
||||||
(x,result) =>{
|
(x,result) =>{
|
||||||
let col='#ff0000';
|
let col='#ff0000';
|
||||||
@ -27,27 +36,29 @@ local dsp=require "luci.dispatcher"
|
|||||||
if (result.ping < 300) col='#ff3300';
|
if (result.ping < 300) col='#ff3300';
|
||||||
if (result.ping < 200) col='#ff7700';
|
if (result.ping < 200) col='#ff7700';
|
||||||
if (result.ping < 100) col='#249400';
|
if (result.ping < 100) col='#249400';
|
||||||
|
}
|
||||||
|
dom.innerHTML = `<font style=\"color:${col}\">${(result.ping ? result.ping : "--") + " ms"}</font>`;
|
||||||
|
if (result.socket) {
|
||||||
port.innerHTML='<font style=\"color:#249400\"><%:ok%></font>'
|
port.innerHTML='<font style=\"color:#249400\"><%:ok%></font>'
|
||||||
}else{
|
}else{
|
||||||
port.innerHTML='<font style=\"color:#ff0000\"><%:fail%></font>'
|
port.innerHTML='<font style=\"color:#ff0000\"><%:fail%></font>'
|
||||||
}
|
}
|
||||||
dom.innerHTML =`<font style=\"${col}\">${(result.ping?result.ping:"--")+" ms"}</font>`
|
|
||||||
res();
|
res();
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
let task=-1;
|
let task=-1;
|
||||||
const thread=() =>{
|
const thread=() =>{
|
||||||
task=task + 1
|
task = task + 1;
|
||||||
if (doms[task]){
|
if (doms[task]){
|
||||||
xhr(task).then(thread);
|
xhr(task).then(thread);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
for (let i=0; i < 20; i++){
|
for (let i=0; i < 20; i++){
|
||||||
thread()
|
thread();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
function cbi_row_drop(fromId,toId,store,isToBottom){
|
function cbi_row_drop(fromId,toId,store,isToBottom){
|
||||||
var fromNode=document.getElementById(fromId);
|
var fromNode=document.getElementById(fromId);
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
<%+cbi/valueheader%>
|
<%+cbi/valueheader%>
|
||||||
<span class="socket-connected" hint="<%=self:cfgvalue(section)%>"><%:None%></span>
|
<span class="socket-connected" hint="<%=self:cfgvalue(section)%>">wait</span>
|
||||||
|
<span class="transport" hint="<%=self.transport%>"></span>
|
||||||
|
<span class="wsPath" hint="<%=self.ws_path%>"></span>
|
||||||
|
<span class="tls" hint="<%=self.tls%>"></span>
|
||||||
<%+cbi/valuefooter%>
|
<%+cbi/valuefooter%>
|
||||||
|
@ -20,7 +20,23 @@ function b64DecodeUnicode(str) {
|
|||||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
}).join(''));
|
}).join(''));
|
||||||
}
|
}
|
||||||
|
// Check if the elements exist before trying to modify them
|
||||||
|
function setElementValue(name, value) {
|
||||||
|
const element = document.getElementsByName(name)[0];
|
||||||
|
if (element) {
|
||||||
|
if (element.type === "checkbox" || element.type === "radio") {
|
||||||
|
element.checked = value === true;
|
||||||
|
} else {
|
||||||
|
element.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function dispatchEventIfExists(name, event) {
|
||||||
|
const element = document.getElementsByName(name)[0];
|
||||||
|
if (element) {
|
||||||
|
element.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
function b64decutf8safe(str) {
|
function b64decutf8safe(str) {
|
||||||
var l;
|
var l;
|
||||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||||
@ -518,8 +534,9 @@ function import_ssr_url(btn, urlname, sid) {
|
|||||||
case "trojan":
|
case "trojan":
|
||||||
try {
|
try {
|
||||||
var url = new URL("http://" + ssu[1]);
|
var url = new URL("http://" + ssu[1]);
|
||||||
|
var params = url.searchParams;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
alert(e)
|
alert(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,7 +550,77 @@ function import_ssr_url(btn, urlname, sid) {
|
|||||||
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = decodeURIComponent(url.username);
|
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = decodeURIComponent(url.username);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].checked = true;
|
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].checked = true;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].dispatchEvent(event);
|
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].dispatchEvent(event);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = url.searchParams.get("sni");
|
document.getElementsByName('cbid.bypass.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = params.get("sni");
|
||||||
|
if (params.get("allowInsecure") === "1") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.insecure')[0].checked = true; // ÉèÖà insecure Ϊ true
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.insecure')[0].dispatchEvent(event); // ´¥·¢Ê¼þ
|
||||||
|
}
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value =
|
||||||
|
params.get("type") == "http" ? "h2" :
|
||||||
|
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
|
||||||
|
(params.get("type") || "raw"));
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
|
||||||
|
switch (params.get("type")) {
|
||||||
|
case "ws":
|
||||||
|
if (params.get("security") !== "tls") {
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
|
}
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
|
||||||
|
break;
|
||||||
|
case "httpupgrade":
|
||||||
|
if (params.get("security") !== "tls") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||||
|
}
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
||||||
|
break;
|
||||||
|
case "splithttp":
|
||||||
|
if (params.get("security") !== "tls") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||||
|
}
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
||||||
|
break;
|
||||||
|
case "xhttp":
|
||||||
|
if (params.get("security") !== "tls") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||||
|
}
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_mode')[0].value = params.get("mode") || "auto";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
||||||
|
if (params.get("extra") && params.get("extra").trim() !== "") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].checked = true; // ÉèÖà enable_xhttp_extra Ϊ true
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // ´¥·¢Ê¼þ
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_extra')[0].value = params.get("extra") || "";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "kcp":
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.seed')[0].value = params.get("seed") || "";
|
||||||
|
break;
|
||||||
|
case "http":
|
||||||
|
/* this is non-standard, bullshit */
|
||||||
|
case "h2":
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
||||||
|
break;
|
||||||
|
case "quic":
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.quic_key')[0].value = params.get("key") || "";
|
||||||
|
break;
|
||||||
|
case "grpc":
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
|
||||||
|
break;
|
||||||
|
case "raw":
|
||||||
|
case "tcp":
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].dispatchEvent(event);
|
||||||
|
if (params.get("headerType") === "http") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||||
return false;
|
return false;
|
||||||
@ -556,10 +643,11 @@ function import_ssr_url(btn, urlname, sid) {
|
|||||||
document.getElementsByName('cbid.bypass.' + sid + '.alter_id')[0].value = ssm.aid;
|
document.getElementsByName('cbid.bypass.' + sid + '.alter_id')[0].value = ssm.aid;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = ssm.id;
|
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = ssm.id;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value = ssm.net;
|
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value = ssm.net;
|
||||||
|
(ssm.net === "raw" || ssm.net === "tcp") ? "raw" : ssm.net;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
|
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
|
||||||
if (ssm.net == "tcp") {
|
if (ssm.net === "raw" || ssm.net === "tcp") {
|
||||||
if (ssm.type && ssm.type != "http") {
|
if (ssm.type && ssm.type != "http") {
|
||||||
ssm.type = "none"
|
ssm.type = "none";
|
||||||
} else {
|
} else {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = ssm.host;
|
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = ssm.host;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = ssm.path;
|
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = ssm.path;
|
||||||
@ -579,6 +667,16 @@ function import_ssr_url(btn, urlname, sid) {
|
|||||||
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = ssm.host;
|
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = ssm.host;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = ssm.path;
|
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = ssm.path;
|
||||||
}
|
}
|
||||||
|
if (ssm.net == "xhttp") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_mode')[0].value = ssm.mode;
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_host')[0].value = ssm.host;
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_path')[0].value = ssm.path;
|
||||||
|
if (params.get("extra") && params.get("extra").trim() !== "") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].checked = true; // ÉèÖà enable_xhttp_extra Ϊ true
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // ´¥·¢Ê¼þ
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_extra')[0].value = ssm.extra;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ssm.net == "h2") {
|
if (ssm.net == "h2") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = ssm.host;
|
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = ssm.host;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = ssm.path;
|
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = ssm.path;
|
||||||
@ -593,10 +691,20 @@ function import_ssr_url(btn, urlname, sid) {
|
|||||||
if (ssm.tls == "tls") {
|
if (ssm.tls == "tls") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].checked = true;
|
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].checked = true;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].dispatchEvent(event);
|
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].dispatchEvent(event);
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.fingerprint')[0].value = ssm.fp;
|
||||||
|
if (ssm.net == "xhttp") {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_alpn')[0].value = ssm.alpn;
|
||||||
|
}
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = ssm.sni || ssm.host;
|
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = ssm.sni || ssm.host;
|
||||||
}
|
}
|
||||||
|
if (ssm.mux !== undefined) {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].checked = true;
|
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].checked = true;
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].dispatchEvent(event);
|
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].dispatchEvent(event);
|
||||||
|
}
|
||||||
|
if (ssm.xmux !== undefined) {
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xmux')[0].checked = true;
|
||||||
|
document.getElementsByName('cbid.bypass.' + sid + '.xmux')[0].dispatchEvent(event);
|
||||||
|
}
|
||||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -605,89 +713,99 @@ function import_ssr_url(btn, urlname, sid) {
|
|||||||
var url = new URL("http://" + ssu[1]);
|
var url = new URL("http://" + ssu[1]);
|
||||||
var params = url.searchParams;
|
var params = url.searchParams;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
alert(e)
|
alert(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
|
setElementValue('cbid.bypass.' + sid + '.alias', url.hash ? decodeURIComponent(url.hash.slice(1)) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].value = "v2ray";
|
setElementValue('cbid.bypass.' + sid + '.type', "v2ray");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].dispatchEvent(event);
|
dispatchEventIfExists('cbid.bypass.' + sid + '.type', event);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.v2ray_protocol')[0].value = "vless";
|
setElementValue('cbid.bypass.' + sid + '.v2ray_protocol', "vless");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
|
dispatchEventIfExists('cbid.bypass.' + sid + '.v2ray_protocol', event);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = url.hostname;
|
setElementValue('cbid.bypass.' + sid + '.server', url.hostname);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = url.port || "80";
|
setElementValue('cbid.bypass.' + sid + '.server_port', url.port || "80");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = url.username;
|
setElementValue('cbid.bypass.' + sid + '.vmess_id', url.username);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value =
|
setElementValue('cbid.bypass.' + sid + '.transport',
|
||||||
params.get("type") == "http" ? "h2" :
|
params.get("type") === "http" ? "h2" :
|
||||||
(params.get("type") == "raw" ? "raw" :
|
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
|
||||||
(params.get("type") || "tcp"));
|
(params.get("type") || "tcp"))
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
|
);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.vless_encryption')[0].value = params.get("encryption") || "none";
|
dispatchEventIfExists('cbid.bypass.' + sid + '.transport', event);
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.vless_encryption', params.get("encryption") || "none");
|
||||||
if ([ "tls", "xtls", "reality" ].includes(params.get("security"))) {
|
if ([ "tls", "xtls", "reality" ].includes(params.get("security"))) {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.' + params.get("security"))[0].checked = true;
|
setElementValue('cbid.bypass.' + sid + '.' + params.get("security"), true);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.' + params.get("security"))[0].dispatchEvent(event);
|
dispatchEventIfExists('cbid.bypass.' + sid + '.' + params.get("security"), event);
|
||||||
|
|
||||||
|
|
||||||
if (params.get("security") === "reality") {
|
if (params.get("security") === "reality") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.reality_publickey')[0].value = params.get("pbk") ? decodeURIComponent(params.get("pbk")) : "";
|
setElementValue('cbid.bypass.' + sid + '.reality_publickey', params.get("pbk") ? decodeURIComponent(params.get("pbk")) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.reality_shortid')[0].value = params.get("sid") || "";
|
setElementValue('cbid.bypass.' + sid + '.reality_shortid', params.get("sid") || "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.reality_spiderx')[0].value = params.get("spx") ? decodeURIComponent(params.get("spx")) : "";
|
setElementValue('cbid.bypass.' + sid + '.reality_spiderx', params.get("spx") ? decodeURIComponent(params.get("spx")) : "");
|
||||||
}
|
}
|
||||||
if (params.get("security") === "xtls") {
|
setElementValue('cbid.bypass.' + sid + '.tls_flow', params.get("flow") || "none");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls_flow')[0].value = params.get("flow") || "";
|
dispatchEventIfExists('cbid.bypass.' + sid + '.tls_flow', event);
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls_flow')[0].dispatchEvent(event);
|
|
||||||
}
|
setElementValue('cbid.bypass.' + sid + '.xhttp_alpn', params.get("alpn") || "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
|
setElementValue('cbid.bypass.' + sid + '.fingerprint', params.get("fp") || "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = params.get("sni") || "";
|
setElementValue('cbid.bypass.' + sid + '.tls_host', params.get("sni") || "");
|
||||||
}
|
}
|
||||||
switch (params.get("type")) {
|
switch (params.get("type")) {
|
||||||
case "ws":
|
case "ws":
|
||||||
if (params.get("security") !== "tls")
|
if (params.get("security") !== "tls") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.ws_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
setElementValue('cbid.bypass.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.ws_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
}
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
|
||||||
break;
|
break;
|
||||||
case "httpupgrade":
|
case "httpupgrade":
|
||||||
if (params.get("security") !== "tls")
|
if (params.get("security") !== "tls") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
setElementValue('cbid.bypass.' + sid + '.httpupgrade_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
}
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.httpupgrade_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
|
||||||
break;
|
break;
|
||||||
case "splithttp":
|
case "splithttp":
|
||||||
if (params.get("security") !== "tls")
|
if (params.get("security") !== "tls") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
setElementValue('cbid.bypass.' + sid + '.splithttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
}
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.splithttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
|
||||||
|
break;
|
||||||
|
case "xhttp":
|
||||||
|
if (params.get("security") !== "tls") {
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.xhttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
|
}
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.xhttp_mode', params.get("mode") || "auto");
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.xhttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
|
||||||
|
if (params.get("extra") && params.get("extra").trim() !== "") {
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.enable_xhttp_extra', true); // ÉèÖà enable_xhttp_extra Ϊ true
|
||||||
|
dispatchEventIfExists('cbid.bypass.' + sid + '.enable_xhttp_extra', event); // ´¥·¢Ê¼þ
|
||||||
|
setElementValue('cbid.bypass.' + sid + '.xhttp_extra', params.get("extra") || "");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "kcp":
|
case "kcp":
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
|
setElementValue('cbid.bypass.' + sid + '.kcp_guise', params.get("headerType") || "none");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.seed')[0].value = params.get("seed") || "";
|
setElementValue('cbid.bypass.' + sid + '.seed', params.get("seed") || "");
|
||||||
break;
|
break;
|
||||||
case "http":
|
case "http":
|
||||||
/* this is non-standard, bullshit */
|
/* this is non-standard, bullshit */
|
||||||
case "h2":
|
case "h2":
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
setElementValue('cbid.bypass.' + sid + '.h2_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
setElementValue('cbid.bypass.' + sid + '.h2_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
|
||||||
break;
|
break;
|
||||||
case "quic":
|
case "quic":
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
|
setElementValue('cbid.bypass.' + sid + '.quic_guise', params.get("headerType") || "none");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
|
setElementValue('cbid.bypass.' + sid + '.quic_security', params.get("quicSecurity") || "none");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_key')[0].value = params.get("key") || "";
|
setElementValue('cbid.bypass.' + sid + '.quic_key', params.get("key") || "");
|
||||||
break;
|
break;
|
||||||
case "grpc":
|
case "grpc":
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
|
setElementValue('cbid.bypass.' + sid + '.serviceName', params.get("serviceName") || "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
|
setElementValue('cbid.bypass.' + sid + '.grpc_mode', params.get("mode") || "gun");
|
||||||
break;
|
break;
|
||||||
case "tcp":
|
case "tcp":
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
|
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].dispatchEvent(event);
|
|
||||||
if (params.get("headerType") === "http") {
|
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
|
||||||
}
|
|
||||||
case "raw":
|
case "raw":
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.raw_guise')[0].value = params.get("headerType") || "none";
|
setElementValue('cbid.bypass.' + sid + '.tcp_guise', params.get("headerType") || "none");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.raw_guise')[0].dispatchEvent(event);
|
dispatchEventIfExists('cbid.bypass.' + sid + '.tcp_guise', event);
|
||||||
if (params.get("headerType") === "http") {
|
if (params.get("headerType") === "http") {
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
setElementValue('cbid.bypass.' + sid + '.http_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||||
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
setElementValue('cbid.bypass.' + sid + '.http_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -32,11 +32,11 @@ config access_control
|
|||||||
config server_global
|
config server_global
|
||||||
|
|
||||||
config global_rules
|
config global_rules
|
||||||
option ad_url 'https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt'
|
option ad_url 'https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt'
|
||||||
option gfwlist_url 'https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt'
|
option gfwlist_url 'https://fastly.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt'
|
||||||
option chnroute_url 'https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt'
|
option chnroute_url 'https://ispip.clang.cn/all_cn.txt'
|
||||||
option chnroute6_url 'https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt'
|
option chnroute6_url 'https://ispip.clang.cn/all_cn_ipv6.txt'
|
||||||
option domains_url 'https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt'
|
option domains_url 'https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt'
|
||||||
|
|
||||||
config server_subscribe
|
config server_subscribe
|
||||||
option proxy '0'
|
option proxy '0'
|
||||||
|
@ -4,7 +4,7 @@ local ucursor = require "luci.model.uci".cursor()
|
|||||||
local json = require "luci.jsonc"
|
local json = require "luci.jsonc"
|
||||||
|
|
||||||
local server_section = arg[1]
|
local server_section = arg[1]
|
||||||
local proto = arg[2]
|
local proto = arg[2] or "tcp"
|
||||||
local local_port = arg[3] or "0"
|
local local_port = arg[3] or "0"
|
||||||
local socks_port = arg[4] or "0"
|
local socks_port = arg[4] or "0"
|
||||||
local chain = arg[5] or "0"
|
local chain = arg[5] or "0"
|
||||||
@ -178,12 +178,12 @@ if local_port ~= "0" then
|
|||||||
end
|
end
|
||||||
-- 开启 socks 代理
|
-- 开启 socks 代理
|
||||||
-- 检查是否启用 socks 代理
|
-- 检查是否启用 socks 代理
|
||||||
if proto:find("tcp") and socks_port ~= "0" then
|
if proto and proto:find("tcp") and socks_port ~= "0" then
|
||||||
table.insert(Xray.inbounds, {
|
table.insert(Xray.inbounds, {
|
||||||
-- socks
|
-- socks
|
||||||
protocol = "socks",
|
protocol = "socks",
|
||||||
port = tonumber(socks_port),
|
port = tonumber(socks_port),
|
||||||
settings = {
|
settings = (socks_server.server ~= "same") and {
|
||||||
auth = socks_server.socks5_auth,
|
auth = socks_server.socks5_auth,
|
||||||
udp = true,
|
udp = true,
|
||||||
mixed = (socks_server.socks5_mixed == '1') and true or false,
|
mixed = (socks_server.socks5_mixed == '1') and true or false,
|
||||||
@ -193,7 +193,7 @@ if proto:find("tcp") and socks_port ~= "0" then
|
|||||||
pass = socks_server.socks5_pass
|
pass = socks_server.socks5_pass
|
||||||
}
|
}
|
||||||
} or nil
|
} or nil
|
||||||
}
|
} or nil
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
-- 传出连接
|
-- 传出连接
|
||||||
@ -207,7 +207,7 @@ end
|
|||||||
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
|
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
|
||||||
tlsSettings = (server.tls == '1') and {
|
tlsSettings = (server.tls == '1') and {
|
||||||
-- tls
|
-- tls
|
||||||
alpn = server.tls_alpn,
|
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or server.tls_alpn,
|
||||||
fingerprint = server.fingerprint,
|
fingerprint = server.fingerprint,
|
||||||
allowInsecure = (server.insecure == "1"),
|
allowInsecure = (server.insecure == "1"),
|
||||||
serverName = server.tls_host,
|
serverName = server.tls_host,
|
||||||
@ -223,6 +223,7 @@ end
|
|||||||
minVersion = "1.3"
|
minVersion = "1.3"
|
||||||
} or nil,
|
} or nil,
|
||||||
realitySettings = (server.reality == '1') and {
|
realitySettings = (server.reality == '1') and {
|
||||||
|
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or nil,
|
||||||
publicKey = server.reality_publickey,
|
publicKey = server.reality_publickey,
|
||||||
shortId = server.reality_shortid,
|
shortId = server.reality_shortid,
|
||||||
spiderX = server.reality_spiderx,
|
spiderX = server.reality_spiderx,
|
||||||
@ -269,6 +270,20 @@ end
|
|||||||
host = (server.splithttp_host or server.tls_host) or nil,
|
host = (server.splithttp_host or server.tls_host) or nil,
|
||||||
path = server.splithttp_path or "/"
|
path = server.splithttp_path or "/"
|
||||||
} or nil,
|
} or nil,
|
||||||
|
xhttpSettings = (server.transport == "xhttp") and {
|
||||||
|
-- xhttp
|
||||||
|
mode = server.xhttp_mode or "auto",
|
||||||
|
host = (server.xhttp_host or server.tls_host) or nil,
|
||||||
|
path = server.xhttp_path or "/",
|
||||||
|
extra = (server.enable_xhttp_extra == "1" and server.xhttp_extra) and (function()
|
||||||
|
local success, parsed = pcall(json.parse, server.xhttp_extra)
|
||||||
|
if success then
|
||||||
|
return parsed.extra or parsed
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end)() or nil
|
||||||
|
} or nil,
|
||||||
httpSettings = (server.transport == "h2") and {
|
httpSettings = (server.transport == "h2") and {
|
||||||
-- h2
|
-- h2
|
||||||
path = server.h2_path or "",
|
path = server.h2_path or "",
|
||||||
@ -293,18 +308,19 @@ end
|
|||||||
} or nil,
|
} or nil,
|
||||||
sockopt = {
|
sockopt = {
|
||||||
mark = 250,
|
mark = 250,
|
||||||
|
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
|
||||||
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||||
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
|
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
|
||||||
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
||||||
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
|
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
|
||||||
}
|
}
|
||||||
} or nil,
|
} or nil,
|
||||||
mux = (server.v2ray_protocol ~= "wireguard") and {
|
mux = (server.v2ray_protocol ~= "wireguard") and {
|
||||||
-- mux
|
-- mux
|
||||||
enabled = (server.mux == "1") and true or false, -- Mux
|
enabled = (server.mux == "1" or server.xmux == "1") and true or false, -- Mux
|
||||||
concurrency = tonumber(server.concurrency), -- TCP 最大并发连接数
|
concurrency = (server.mux == "1" and ((server.concurrency ~= "0") and tonumber(server.concurrency) or 8)) or (server.xmux == "1" and -1) or nil, -- TCP 最大并发连接数
|
||||||
xudpConcurrency = tonumber(server.xudpConcurrency), -- UDP 最大并发连接数
|
xudpConcurrency = ((server.xudpConcurrency ~= "0") and tonumber(server.xudpConcurrency)) or nil, -- UDP 最大并发连接数
|
||||||
xudpProxyUDP443 = server.xudpProxyUDP443 -- 对被代理的 UDP/443 流量处理方式
|
xudpProxyUDP443 = (server.mux == "1") and server.xudpProxyUDP443 or nil -- 对被代理的 UDP/443 流量处理方式
|
||||||
} or nil
|
} or nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,8 +347,9 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
|
|||||||
streamSettings = {
|
streamSettings = {
|
||||||
sockopt = {
|
sockopt = {
|
||||||
mark = 250,
|
mark = 250,
|
||||||
|
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
|
||||||
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||||
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
|
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
|
||||||
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
|
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -584,6 +601,10 @@ function config:handleIndex(index)
|
|||||||
hysteria = function()
|
hysteria = function()
|
||||||
print(json.stringify(hysteria, 1))
|
print(json.stringify(hysteria, 1))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
hysteria2 = function()
|
||||||
|
print(json.stringify(hysteria2, 1))
|
||||||
|
end,
|
||||||
shadowtls = function()
|
shadowtls = function()
|
||||||
local chain_switch = {
|
local chain_switch = {
|
||||||
sslocal = function()
|
sslocal = function()
|
||||||
|
@ -180,12 +180,12 @@ end
|
|||||||
|
|
||||||
-- 开启 socks 代理
|
-- 开启 socks 代理
|
||||||
-- 检查是否启用 socks 代理
|
-- 检查是否启用 socks 代理
|
||||||
if proto:find("tcp") and socks_port ~= "0" then
|
if proto and proto:find("tcp") and socks_port ~= "0" then
|
||||||
table.insert(Xray.inbounds, {
|
table.insert(Xray.inbounds, {
|
||||||
-- socks
|
-- socks
|
||||||
protocol = "socks",
|
protocol = "socks",
|
||||||
port = tonumber(socks_port),
|
port = tonumber(socks_port),
|
||||||
settings = {
|
settings = (socks_server.server ~= "same") and {
|
||||||
auth = socks_server.socks5_auth,
|
auth = socks_server.socks5_auth,
|
||||||
udp = true,
|
udp = true,
|
||||||
mixed = (socks_server.socks5_mixed == '1') and true or false,
|
mixed = (socks_server.socks5_mixed == '1') and true or false,
|
||||||
@ -195,7 +195,7 @@ if proto:find("tcp") and socks_port ~= "0" then
|
|||||||
pass = socks_server.socks5_pass
|
pass = socks_server.socks5_pass
|
||||||
}
|
}
|
||||||
} or nil
|
} or nil
|
||||||
}
|
} or nil
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -210,10 +210,10 @@ end
|
|||||||
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
|
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
|
||||||
tlsSettings = (server.tls == '1') and {
|
tlsSettings = (server.tls == '1') and {
|
||||||
-- tls
|
-- tls
|
||||||
alpn = server.tls_alpn,
|
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or server.tls_alpn,
|
||||||
fingerprint = server.fingerprint,
|
fingerprint = server.fingerprint,
|
||||||
allowInsecure = (server.insecure == "1"),
|
allowInsecure = (server.insecure == "1"),
|
||||||
serverName = tls_host,
|
serverName = server.tls_host,
|
||||||
certificates = server.certificate and {
|
certificates = server.certificate and {
|
||||||
usage = "verify",
|
usage = "verify",
|
||||||
certificateFile = server.certpath
|
certificateFile = server.certpath
|
||||||
@ -226,6 +226,7 @@ end
|
|||||||
minVersion = "1.3"
|
minVersion = "1.3"
|
||||||
} or nil,
|
} or nil,
|
||||||
realitySettings = (server.reality == '1') and {
|
realitySettings = (server.reality == '1') and {
|
||||||
|
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or nil,
|
||||||
publicKey = server.reality_publickey,
|
publicKey = server.reality_publickey,
|
||||||
shortId = server.reality_shortid,
|
shortId = server.reality_shortid,
|
||||||
spiderX = server.reality_spiderx,
|
spiderX = server.reality_spiderx,
|
||||||
@ -272,6 +273,20 @@ end
|
|||||||
host = (server.splithttp_host or server.tls_host) or nil,
|
host = (server.splithttp_host or server.tls_host) or nil,
|
||||||
path = server.splithttp_path or "/"
|
path = server.splithttp_path or "/"
|
||||||
} or nil,
|
} or nil,
|
||||||
|
xhttpSettings = (server.transport == "xhttp") and {
|
||||||
|
-- xhttp
|
||||||
|
mode = server.xhttp_mode or "auto",
|
||||||
|
host = (server.xhttp_host or server.tls_host) or nil,
|
||||||
|
path = server.xhttp_path or "/",
|
||||||
|
extra = (server.enable_xhttp_extra == "1" and server.xhttp_extra) and (function()
|
||||||
|
local success, parsed = pcall(json.parse, server.xhttp_extra)
|
||||||
|
if success then
|
||||||
|
return parsed.extra or parsed
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end)() or nil
|
||||||
|
} or nil,
|
||||||
httpSettings = (server.transport == "h2") and {
|
httpSettings = (server.transport == "h2") and {
|
||||||
-- h2
|
-- h2
|
||||||
path = server.h2_path or "",
|
path = server.h2_path or "",
|
||||||
@ -296,18 +311,19 @@ end
|
|||||||
} or nil,
|
} or nil,
|
||||||
sockopt = {
|
sockopt = {
|
||||||
mark = 250,
|
mark = 250,
|
||||||
|
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
|
||||||
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||||
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
|
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
|
||||||
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
||||||
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
|
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
|
||||||
}
|
}
|
||||||
} or nil,
|
} or nil,
|
||||||
mux = (server.v2ray_protocol ~= "wireguard") and {
|
mux = (server.v2ray_protocol ~= "wireguard") and {
|
||||||
-- mux
|
-- mux
|
||||||
enabled = (server.mux == "1") and true or false, -- Mux
|
enabled = (server.mux == "1" or server.xmux == "1") and true or false, -- Mux
|
||||||
concurrency = tonumber(server.concurrency), -- TCP 最大并发连接数
|
concurrency = (server.mux == "1" and ((server.concurrency ~= "0") and tonumber(server.concurrency) or 8)) or (server.xmux == "1" and -1) or nil, -- TCP 最大并发连接数
|
||||||
xudpConcurrency = tonumber(server.xudpConcurrency), -- UDP 最大并发连接数
|
xudpConcurrency = ((server.xudpConcurrency ~= "0") and tonumber(server.xudpConcurrency)) or nil, -- UDP 最大并发连接数
|
||||||
xudpProxyUDP443 = server.xudpProxyUDP443 -- 对被代理的 UDP/443 流量处理方式
|
xudpProxyUDP443 = (server.mux == "1") and server.xudpProxyUDP443 or nil -- 对被代理的 UDP/443 流量处理方式
|
||||||
} or nil
|
} or nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,8 +350,9 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
|
|||||||
streamSettings = {
|
streamSettings = {
|
||||||
sockopt = {
|
sockopt = {
|
||||||
mark = 250,
|
mark = 250,
|
||||||
|
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
|
||||||
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||||
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
|
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
|
||||||
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
|
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,38 @@ local log = function(...)
|
|||||||
io.write(os.date("%Y-%m-%d %H:%M:%S ").."Subscribe : "..table.concat({...}," ").."\n")
|
io.write(os.date("%Y-%m-%d %H:%M:%S ").."Subscribe : "..table.concat({...}," ").."\n")
|
||||||
io.close(file)
|
io.close(file)
|
||||||
end
|
end
|
||||||
|
local encrypt_methods_ss = {
|
||||||
|
-- plain
|
||||||
|
"none",
|
||||||
|
"plain",
|
||||||
|
-- aead
|
||||||
|
"aes-128-gcm",
|
||||||
|
"aes-192-gcm",
|
||||||
|
"aes-256-gcm",
|
||||||
|
"chacha20-ietf-poly1305",
|
||||||
|
"xchacha20-ietf-poly1305",
|
||||||
|
-- aead 2022
|
||||||
|
"2022-blake3-aes-128-gcm",
|
||||||
|
"2022-blake3-aes-256-gcm",
|
||||||
|
"2022-blake3-chacha20-poly1305"
|
||||||
|
--[[ stream
|
||||||
|
"table",
|
||||||
|
"rc4",
|
||||||
|
"rc4-md5",
|
||||||
|
"aes-128-cfb",
|
||||||
|
"aes-192-cfb",
|
||||||
|
"aes-256-cfb",
|
||||||
|
"aes-128-ctr",
|
||||||
|
"aes-192-ctr",
|
||||||
|
"aes-256-ctr",
|
||||||
|
"bf-cfb",
|
||||||
|
"camellia-128-cfb",
|
||||||
|
"camellia-192-cfb",
|
||||||
|
"camellia-256-cfb",
|
||||||
|
"salsa20",
|
||||||
|
"chacha20",
|
||||||
|
"chacha20-ietf" ]]
|
||||||
|
}
|
||||||
-- 分割字符串
|
-- 分割字符串
|
||||||
local function split(full, sep)
|
local function split(full, sep)
|
||||||
if full then
|
if full then
|
||||||
@ -92,9 +123,10 @@ end
|
|||||||
-- base64
|
-- base64
|
||||||
local function base64Decode(text)
|
local function base64Decode(text)
|
||||||
local raw = text
|
local raw = text
|
||||||
if not text then return '' end
|
if not text then
|
||||||
|
return ''
|
||||||
|
end
|
||||||
text = text:gsub("%z", "")
|
text = text:gsub("%z", "")
|
||||||
text = text:gsub("%c", "")
|
|
||||||
text = text:gsub("_", "/")
|
text = text:gsub("_", "/")
|
||||||
text = text:gsub("-", "+")
|
text = text:gsub("-", "+")
|
||||||
local mod4 = #text % 4
|
local mod4 = #text % 4
|
||||||
@ -119,20 +151,15 @@ end
|
|||||||
local function processData(szType, content)
|
local function processData(szType, content)
|
||||||
local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
|
local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
|
||||||
if szType == 'ssr' then
|
if szType == 'ssr' then
|
||||||
|
|
||||||
result.type = 'ssr'
|
|
||||||
local dat = split(content, "/%?")
|
local dat = split(content, "/%?")
|
||||||
local hostInfo = split(dat[1], ':')
|
local hostInfo = split(dat[1], ':')
|
||||||
if dat[1]:match('%[(.*)%]') then
|
result.type = 'ssr'
|
||||||
result.server = dat[1]:match('%[(.*)%]')
|
result.server = hostInfo[1]
|
||||||
else
|
result.server_port = hostInfo[2]
|
||||||
result.server = hostInfo[#hostInfo-5]
|
result.protocol = hostInfo[3]
|
||||||
end
|
result.encrypt_method = hostInfo[4]
|
||||||
result.server_port = hostInfo[#hostInfo-4]
|
result.obfs = hostInfo[5]
|
||||||
result.protocol = hostInfo[#hostInfo-3]
|
result.password = base64Decode(hostInfo[6])
|
||||||
result.encrypt_method = hostInfo[#hostInfo-2]
|
|
||||||
result.obfs = hostInfo[#hostInfo-1]
|
|
||||||
result.password = base64Decode(hostInfo[#hostInfo])
|
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, v in pairs(split(dat[2], '&')) do
|
for _, v in pairs(split(dat[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
@ -148,23 +175,18 @@ local function processData(szType, content)
|
|||||||
elseif szType == 'vmess' then
|
elseif szType == 'vmess' then
|
||||||
local info = jsonParse(content)
|
local info = jsonParse(content)
|
||||||
result.type = 'v2ray'
|
result.type = 'v2ray'
|
||||||
|
result.v2ray_protocol = 'vmess'
|
||||||
|
|
||||||
|
|
||||||
result.alter_id = info.aid
|
|
||||||
|
|
||||||
result.server = info.add
|
result.server = info.add
|
||||||
result.server_port = info.port
|
result.server_port = info.port
|
||||||
result.v2ray_protocol = 'vmess'
|
if info.net == "tcp" then
|
||||||
|
info.net = "raw"
|
||||||
|
end
|
||||||
|
result.transport = info.net
|
||||||
|
result.alter_id = info.aid
|
||||||
result.vmess_id = info.id
|
result.vmess_id = info.id
|
||||||
result.alias = info.ps
|
result.alias = info.ps
|
||||||
-- result.mux = 1
|
-- result.mux = 1
|
||||||
-- result.concurrency = 8
|
-- result.concurrency = 8
|
||||||
if not info.net then
|
|
||||||
info.net = "tcp"
|
|
||||||
end
|
|
||||||
info.net = string.lower(info.net)
|
|
||||||
result.transport = info.net
|
|
||||||
if info.net == 'ws' then
|
if info.net == 'ws' then
|
||||||
result.ws_host = info.host
|
result.ws_host = info.host
|
||||||
result.ws_path = info.path
|
result.ws_path = info.path
|
||||||
@ -177,11 +199,29 @@ local function processData(szType, content)
|
|||||||
result.splithttp_host = info.host
|
result.splithttp_host = info.host
|
||||||
result.splithttp_path = info.path
|
result.splithttp_path = info.path
|
||||||
end
|
end
|
||||||
|
if info.net == 'xhttp' then
|
||||||
|
result.xhttp_mode = info.mode
|
||||||
|
result.xhttp_host = info.host
|
||||||
|
result.xhttp_path = info.path
|
||||||
|
-- 检查 extra 参数是否存在且非空
|
||||||
|
result.enable_xhttp_extra = (info.extra and info.extra ~= "") and "1" or nil
|
||||||
|
result.xhttp_extra = (info.extra and info.extra ~= "") and info.extra or nil
|
||||||
|
-- 尝试解析 JSON 数据
|
||||||
|
local success, Data = pcall(jsonParse, info.extra)
|
||||||
|
if success and Data then
|
||||||
|
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
|
||||||
|
or (Data.downloadSettings and Data.downloadSettings.address)
|
||||||
|
result.download_address = address and address ~= "" and address or nil
|
||||||
|
else
|
||||||
|
-- 如果解析失败,清空下载地址
|
||||||
|
result.download_address = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
if info.net == 'h2' then
|
if info.net == 'h2' then
|
||||||
result.h2_host = info.host
|
result.h2_host = info.host
|
||||||
result.h2_path = info.path
|
result.h2_path = info.path
|
||||||
end
|
end
|
||||||
if info.net == 'tcp' then
|
if info.net == 'raw' or info.net == 'tcp' then
|
||||||
if info.type and info.type ~= "http" then
|
if info.type and info.type ~= "http" then
|
||||||
info.type = "none"
|
info.type = "none"
|
||||||
end
|
end
|
||||||
@ -189,7 +229,7 @@ local function processData(szType, content)
|
|||||||
result.http_host = info.host
|
result.http_host = info.host
|
||||||
result.http_path = info.path
|
result.http_path = info.path
|
||||||
end
|
end
|
||||||
if info.net == 'kcp' or info.net == 'mkcp' then
|
if info.net == 'kcp' then
|
||||||
result.kcp_guise = info.type
|
result.kcp_guise = info.type
|
||||||
result.mtu = 1350
|
result.mtu = 1350
|
||||||
result.tti = 50
|
result.tti = 50
|
||||||
@ -213,13 +253,18 @@ local function processData(szType, content)
|
|||||||
end
|
end
|
||||||
if info.security then
|
if info.security then
|
||||||
result.security = info.security
|
result.security = info.security
|
||||||
else
|
|
||||||
result.security = "auto"
|
|
||||||
end
|
end
|
||||||
if info.tls == "tls" or info.tls == "1" then
|
if info.tls == "tls" or info.tls == "1" then
|
||||||
result.tls = "1"
|
result.tls = "1"
|
||||||
result.tls_host = (info.sni and info.sni ~= "") and info.sni or info.host
|
if info.alpn and info.alpn ~= "" then
|
||||||
result.insecure = insecure and "1" or "0"
|
result.xhttp_alpn = info.alpn
|
||||||
|
end
|
||||||
|
if info.sni and info.sni ~= "" then
|
||||||
|
result.tls_host = info.sni
|
||||||
|
elseif info.host then
|
||||||
|
result.tls_host = info.host
|
||||||
|
end
|
||||||
|
result.insecure = 1
|
||||||
else
|
else
|
||||||
result.tls = "0"
|
result.tls = "0"
|
||||||
end
|
end
|
||||||
@ -228,9 +273,6 @@ local function processData(szType, content)
|
|||||||
-- result.server = nil
|
-- result.server = nil
|
||||||
-- end
|
-- end
|
||||||
elseif szType == "ss" then
|
elseif szType == "ss" then
|
||||||
|
|
||||||
result.type = v2_ss
|
|
||||||
|
|
||||||
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
|
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
|
||||||
--userinfo = websafe-base64-encode-utf8(method ":" password)
|
--userinfo = websafe-base64-encode-utf8(method ":" password)
|
||||||
--ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1
|
--ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1
|
||||||
@ -244,11 +286,21 @@ local function processData(szType, content)
|
|||||||
idx_sp = content:find("#")
|
idx_sp = content:find("#")
|
||||||
alias = content:sub(idx_sp + 1, -1)
|
alias = content:sub(idx_sp + 1, -1)
|
||||||
end
|
end
|
||||||
result.alias = UrlDecode(alias)
|
|
||||||
local info = content:sub(1, idx_sp - 1)
|
local info = content:sub(1, idx_sp - 1)
|
||||||
if info:find("/%?") then
|
local hostInfo = split(base64Decode(info), "@")
|
||||||
local find_index = info:find("/%?")
|
local host = split(hostInfo[2], ":")
|
||||||
local query = split(info, "/%?")
|
local userinfo = base64Decode(hostInfo[1])
|
||||||
|
local method = userinfo:sub(1, userinfo:find(":") - 1)
|
||||||
|
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
||||||
|
result.alias = UrlDecode(alias)
|
||||||
|
result.type = v2_ss
|
||||||
|
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
||||||
|
result.encrypt_method_ss = method
|
||||||
|
result.password = password
|
||||||
|
result.server = host[1]
|
||||||
|
if host[2]:find("/%?") then
|
||||||
|
local query = split(host[2], "/%?")
|
||||||
|
result.server_port = query[1]
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, v in pairs(split(query[2], '&')) do
|
for _, v in pairs(split(query[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
@ -263,122 +315,32 @@ local function processData(szType, content)
|
|||||||
else
|
else
|
||||||
result.plugin = plugin_info
|
result.plugin = plugin_info
|
||||||
end
|
end
|
||||||
end
|
-- 部分机场下发的插件名为 simple-obfs,这里应该改为 obfs-local
|
||||||
if result.plugin and result.plugin == "simple-obfs" then
|
if result.plugin == "simple-obfs" then
|
||||||
result.plugin = "obfs-local"
|
result.plugin = "obfs-local"
|
||||||
end
|
end
|
||||||
info = info:sub(1, find_index - 1)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local hostInfo = split(base64Decode(info), "@")
|
|
||||||
if hostInfo and #hostInfo > 0 then
|
|
||||||
local host_port = hostInfo[#hostInfo]
|
|
||||||
-- [2001:4860:4860::8888]:443
|
|
||||||
-- 8.8.8.8:443
|
|
||||||
if host_port:find(":") then
|
|
||||||
local sp = split(host_port, ":")
|
|
||||||
result.server_port = sp[#sp]
|
|
||||||
|
|
||||||
result.server = sp[1]
|
|
||||||
|
|
||||||
else
|
else
|
||||||
result.server = host_port
|
result.server_port = host[2]:gsub("/","")
|
||||||
end
|
end
|
||||||
|
if not checkTabValue(encrypt_methods_ss)[method] then
|
||||||
local userinfo = nil
|
-- 1202 年了还不支持 SS AEAD 的屑机场
|
||||||
if #hostInfo > 2 then
|
result.server = nil
|
||||||
userinfo = {}
|
|
||||||
for i = 1, #hostInfo - 1 do
|
|
||||||
tinsert(userinfo, hostInfo[i])
|
|
||||||
end
|
end
|
||||||
userinfo = table.concat(userinfo, '@')
|
elseif szType == "sip008" then
|
||||||
else
|
result.type = v2_ss
|
||||||
userinfo = base64Decode(hostInfo[1])
|
|
||||||
end
|
|
||||||
|
|
||||||
local method = userinfo:sub(1, userinfo:find(":") - 1)
|
|
||||||
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
|
||||||
|
|
||||||
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
||||||
result.encrypt_method_ss = method
|
result.server = content.server
|
||||||
result.password = password
|
result.server_port = content.server_port
|
||||||
|
result.password = content.password
|
||||||
local aead = false
|
result.encrypt_method_ss = content.method
|
||||||
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do
|
result.plugin = content.plugin
|
||||||
if method:lower() == v:lower() then
|
result.plugin_opts = content.plugin_opts
|
||||||
aead = true
|
result.alias = content.remarks
|
||||||
end
|
if not checkTabValue(encrypt_methods_ss)[content.method] then
|
||||||
end
|
result.server = nil
|
||||||
if aead then
|
|
||||||
|
|
||||||
result.type = v2_ss
|
|
||||||
result.v2ray_protocol = 'shadowsocks'
|
|
||||||
result.transport = 'tcp'
|
|
||||||
if method:lower() == "chacha20-ietf-poly1305" then
|
|
||||||
result.method = "chacha20-poly1305"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
local aead2022 = false
|
|
||||||
for k, v in ipairs({"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"}) do
|
|
||||||
if method:lower() == v:lower() then
|
|
||||||
aead2022 = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if aead2022 then
|
|
||||||
result.type = v2_ss
|
|
||||||
result.v2ray_protocol = 'shadowsocks'
|
|
||||||
result.transport = 'tcp'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif szType == "trojan" then
|
|
||||||
|
|
||||||
local alias = ""
|
|
||||||
if content:find("#") then
|
|
||||||
local idx_sp = content:find("#")
|
|
||||||
alias = content:sub(idx_sp + 1, -1)
|
|
||||||
content = content:sub(0, idx_sp - 1)
|
|
||||||
end
|
|
||||||
result.alias = UrlDecode(alias)
|
|
||||||
result.type = "trojan"
|
|
||||||
if content:find("@") then
|
|
||||||
local Info = split(content, "@")
|
|
||||||
result.password = UrlDecode(Info[1])
|
|
||||||
local port = "443"
|
|
||||||
Info[2] = (Info[2] or ""):gsub("/%?", "?")
|
|
||||||
local query = split(Info[2], "?")
|
|
||||||
local host_port = query[1]
|
|
||||||
local params = {}
|
|
||||||
for _, v in pairs(split(query[2], '&')) do
|
|
||||||
local t = split(v, '=')
|
|
||||||
params[string.lower(t[1])] = UrlDecode(t[2])
|
|
||||||
end
|
|
||||||
if host_port:find(":") then
|
|
||||||
local sp = split(host_port, ":")
|
|
||||||
port = sp[#sp]
|
|
||||||
result.server = sp[1]
|
|
||||||
else
|
|
||||||
result.server = host_port
|
|
||||||
end
|
|
||||||
|
|
||||||
local peer, sni = nil, ""
|
|
||||||
if params.peer then peer = params.peer end
|
|
||||||
sni = params.sni and params.sni or ""
|
|
||||||
result.server_port = port
|
|
||||||
result.tls = '1'
|
|
||||||
result.tls_host = peer and peer or sni
|
|
||||||
if params.allowinsecure then
|
|
||||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
|
||||||
result.insecure = params.allowinsecure
|
|
||||||
else
|
|
||||||
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
|
||||||
end
|
|
||||||
--log(result.alias .. ' 使用节点AllowInsecure设定: '.. result.insecure)
|
|
||||||
else
|
|
||||||
-- 按照官方的建议 默认验证ssl证书
|
|
||||||
result.insecure = insecure and "1" or "0"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif szType == "ssd" then
|
elseif szType == "ssd" then
|
||||||
result.type = v2_ss
|
result.type = v2_ss
|
||||||
@ -386,8 +348,7 @@ local function processData(szType, content)
|
|||||||
result.server = content.server
|
result.server = content.server
|
||||||
result.server_port = content.port
|
result.server_port = content.port
|
||||||
result.password = content.password
|
result.password = content.password
|
||||||
result.encrypt_method_ss = content.encryption
|
result.encrypt_method_ss = content.method
|
||||||
result.plugin = content.plugin
|
|
||||||
result.plugin_opts = content.plugin_options
|
result.plugin_opts = content.plugin_options
|
||||||
result.alias = "[" .. content.airport .. "] " .. content.remarks
|
result.alias = "[" .. content.airport .. "] " .. content.remarks
|
||||||
if content.plugin == "simple-obfs" then
|
if content.plugin == "simple-obfs" then
|
||||||
@ -395,45 +356,142 @@ local function processData(szType, content)
|
|||||||
else
|
else
|
||||||
result.plugin = content.plugin
|
result.plugin = content.plugin
|
||||||
end
|
end
|
||||||
|
if not checkTabValue(encrypt_methods_ss)[content.encryption] then
|
||||||
elseif szType == "vless" then
|
result.server = nil
|
||||||
result.type = "v2ray"
|
end
|
||||||
result.v2ray_protocol = "vless"
|
elseif szType == "trojan" then
|
||||||
|
local params = {}
|
||||||
|
local idx_sp = 0
|
||||||
local alias = ""
|
local alias = ""
|
||||||
if content:find("#") then
|
if content:find("#") then
|
||||||
local idx_sp = content:find("#")
|
idx_sp = content:find("#")
|
||||||
alias = content:sub(idx_sp + 1, -1)
|
alias = content:sub(idx_sp + 1, -1)
|
||||||
content = content:sub(0, idx_sp - 1)
|
|
||||||
end
|
end
|
||||||
|
local info = content:sub(1, idx_sp - 1)
|
||||||
|
local hostInfo = split(info, "@")
|
||||||
|
local userinfo = hostInfo[1]
|
||||||
|
local password = userinfo
|
||||||
|
-- 分离服务器地址和端口
|
||||||
|
local host = split(hostInfo[2], ":")
|
||||||
|
local server = host[1]
|
||||||
|
local port = host[2]
|
||||||
result.alias = UrlDecode(alias)
|
result.alias = UrlDecode(alias)
|
||||||
if content:find("@") then
|
result.type = v2_tj
|
||||||
local Info = split(content, "@")
|
result.v2ray_protocol = "trojan"
|
||||||
result.vmess_id = UrlDecode(Info[1])
|
result.server = server
|
||||||
local port = "443"
|
result.password = password
|
||||||
Info[2] = (Info[2] or ""):gsub("/%?", "?")
|
-- 按照官方的建议 默认验证ssl证书
|
||||||
local query = split(Info[2], "?")
|
result.insecure = "0"
|
||||||
local host_port = query[1]
|
result.tls = "1"
|
||||||
local params = {}
|
if port:find("?") then
|
||||||
|
local query = split(port, "?")
|
||||||
|
result.server_port = query[1]
|
||||||
for _, v in pairs(split(query[2], '&')) do
|
for _, v in pairs(split(query[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
params[t[1]] = UrlDecode(t[2])
|
params[t[1]] = t[2]
|
||||||
|
end
|
||||||
|
if params.alpn then
|
||||||
|
-- 处理 alpn 参数
|
||||||
|
result.xhttp_alpn = params.alpn
|
||||||
|
end
|
||||||
|
if params.sni then
|
||||||
|
-- 未指定peer(sni)默认使用remote addr
|
||||||
|
result.tls_host = params.sni
|
||||||
|
end
|
||||||
|
if params.allowInsecure then
|
||||||
|
-- 处理 insecure 参数
|
||||||
|
result.insecure = params.allowInsecure
|
||||||
end
|
end
|
||||||
-- [2001:4860:4860::8888]:443
|
|
||||||
-- 8.8.8.8:443
|
|
||||||
if host_port:find(":") then
|
|
||||||
local sp = split(host_port, ":")
|
|
||||||
port = sp[#sp]
|
|
||||||
result.server = sp[1]
|
|
||||||
else
|
else
|
||||||
result.server = host_port
|
result.server_port = port
|
||||||
|
end
|
||||||
|
if v2_tj ~= "trojan" then
|
||||||
|
if params.fp then
|
||||||
|
-- 处理 fingerprint 参数
|
||||||
|
result.fingerprint = params.fp
|
||||||
|
end
|
||||||
|
-- 处理传输协议
|
||||||
|
result.transport = params.type or "tcp" -- 默认传输协议为 tcp
|
||||||
|
if result.transport == "tcp" then
|
||||||
|
result.transport = "raw"
|
||||||
|
end
|
||||||
|
if result.transport == "ws" then
|
||||||
|
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
|
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
||||||
|
elseif result.transport == "httpupgrade" then
|
||||||
|
result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
|
result.httpupgrade_path = params.path and UrlDecode(params.path) or "/"
|
||||||
|
elseif result.transport == "splithttp" then
|
||||||
|
result.splithttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
|
result.splithttp_path = params.path and UrlDecode(params.path) or "/"
|
||||||
|
elseif result.transport == "xhttp" then
|
||||||
|
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
|
result.xhttp_mode = params.mode or "auto"
|
||||||
|
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
|
||||||
|
-- 检查 extra 参数是否存在且非空
|
||||||
|
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
|
||||||
|
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
|
||||||
|
-- 尝试解析 JSON 数据
|
||||||
|
local success, Data = pcall(jsonParse, params.extra)
|
||||||
|
if success and Data then
|
||||||
|
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
|
||||||
|
or (Data.downloadSettings and Data.downloadSettings.address)
|
||||||
|
result.download_address = address and address ~= "" and address or nil
|
||||||
|
else
|
||||||
|
-- 如果解析失败,清空下载地址
|
||||||
|
result.download_address = nil
|
||||||
|
end
|
||||||
|
elseif result.transport == "http" or result.transport == "h2" then
|
||||||
|
result.transport = "h2"
|
||||||
|
result.h2_host = params.host and UrlDecode(params.host) or nil
|
||||||
|
result.h2_path = params.path and UrlDecode(params.path) or nil
|
||||||
|
elseif result.transport == "kcp" then
|
||||||
|
result.kcp_guise = params.headerType or "none"
|
||||||
|
result.seed = params.seed
|
||||||
|
result.mtu = 1350
|
||||||
|
result.tti = 50
|
||||||
|
result.uplink_capacity = 5
|
||||||
|
result.downlink_capacity = 20
|
||||||
|
result.read_buffer_size = 2
|
||||||
|
result.write_buffer_size = 2
|
||||||
|
elseif result.transport == "quic" then
|
||||||
|
result.quic_guise = params.headerType or "none"
|
||||||
|
result.quic_security = params.quicSecurity or "none"
|
||||||
|
result.quic_key = params.key
|
||||||
|
elseif result.transport == "grpc" then
|
||||||
|
result.serviceName = params.serviceName
|
||||||
|
result.grpc_mode = params.mode or "gun"
|
||||||
|
elseif result.transport == "tcp" or result.transport == "raw" then
|
||||||
|
result.tcp_guise = params.headerType and params.headerType ~= "" and params.headerType or "none"
|
||||||
|
if result.tcp_guise == "http" then
|
||||||
|
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
||||||
|
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not params.type then
|
elseif szType == "vless" then
|
||||||
params.type = "tcp"
|
local url = URL.parse("http://" .. content)
|
||||||
end
|
local params = url.query
|
||||||
params.type = string.lower(params.type)
|
|
||||||
result.transport = params.type
|
result.alias = url.fragment and UrlDecode(url.fragment) or nil
|
||||||
if params.type == 'ws' then
|
result.type = "v2ray"
|
||||||
|
result.v2ray_protocol = "vless"
|
||||||
|
result.server = url.host
|
||||||
|
result.server_port = url.port
|
||||||
|
result.vmess_id = url.user
|
||||||
|
result.vless_encryption = params.encryption or "none"
|
||||||
|
result.transport = params.type or "tcp"
|
||||||
|
result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0"
|
||||||
|
result.xhttp_alpn = params.alpn or ""
|
||||||
|
result.tls_host = params.sni
|
||||||
|
result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil
|
||||||
|
result.fingerprint = params.fp
|
||||||
|
result.reality = (params.security == "reality") and "1" or "0"
|
||||||
|
result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil
|
||||||
|
result.reality_shortid = params.sid
|
||||||
|
result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil
|
||||||
|
if result.transport == "ws" then
|
||||||
|
|
||||||
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
||||||
@ -443,60 +501,51 @@ local function processData(szType, content)
|
|||||||
elseif result.transport == "splithttp" then
|
elseif result.transport == "splithttp" then
|
||||||
result.splithttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
result.splithttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
result.splithttp_path = params.path and UrlDecode(params.path) or "/"
|
result.splithttp_path = params.path and UrlDecode(params.path) or "/"
|
||||||
|
elseif result.transport == "xhttp" then
|
||||||
|
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||||
|
result.xhttp_mode = params.mode or "auto"
|
||||||
|
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
|
||||||
|
-- 检查 extra 参数是否存在且非空
|
||||||
|
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
|
||||||
|
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
|
||||||
|
-- 尝试解析 JSON 数据
|
||||||
|
local success, Data = pcall(jsonParse, params.extra)
|
||||||
|
if success and Data then
|
||||||
|
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
|
||||||
|
or (Data.downloadSettings and Data.downloadSettings.address)
|
||||||
|
result.download_address = address and address ~= "" and address or nil
|
||||||
|
else
|
||||||
|
-- 如果解析失败,清空下载地址
|
||||||
|
result.download_address = nil
|
||||||
|
end
|
||||||
-- make it compatible with bullshit, "h2" transport is non-existent at all
|
-- make it compatible with bullshit, "h2" transport is non-existent at all
|
||||||
elseif result.transport == "http" or result.transport == "h2" then
|
elseif result.transport == "http" or result.transport == "h2" then
|
||||||
|
|
||||||
result.transport = "h2"
|
result.transport = "h2"
|
||||||
result.h2_host = params.host and UrlDecode(params.host) or nil
|
result.h2_host = params.host and UrlDecode(params.host) or nil
|
||||||
result.h2_path = params.path and UrlDecode(params.path) or nil
|
result.h2_path = params.path and UrlDecode(params.path) or nil
|
||||||
elseif params.type == 'tcp' then
|
elseif result.transport == "kcp" then
|
||||||
result.tcp_guise = params.headerType or "none"
|
|
||||||
if result.tcp_guise == "http" then
|
|
||||||
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
|
||||||
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
|
||||||
end
|
|
||||||
elseif params.type == 'kcp' or params.type == 'mkcp' then
|
|
||||||
params.type = "kcp"
|
|
||||||
result.kcp_guise = params.headerType or "none"
|
result.kcp_guise = params.headerType or "none"
|
||||||
|
result.seed = params.seed
|
||||||
result.mtu = 1350
|
result.mtu = 1350
|
||||||
result.tti = 50
|
result.tti = 50
|
||||||
result.uplink_capacity = 5
|
result.uplink_capacity = 5
|
||||||
result.downlink_capacity = 20
|
result.downlink_capacity = 20
|
||||||
result.read_buffer_size = 2
|
result.read_buffer_size = 2
|
||||||
result.write_buffer_size = 2
|
result.write_buffer_size = 2
|
||||||
result.seed = params.seed
|
elseif result.transport == "quic" then
|
||||||
elseif params.type == 'quic' then
|
|
||||||
result.quic_guise = params.headerType or "none"
|
result.quic_guise = params.headerType or "none"
|
||||||
result.quic_key = params.key
|
|
||||||
result.quic_security = params.quicSecurity or "none"
|
result.quic_security = params.quicSecurity or "none"
|
||||||
elseif params.type == 'grpc' then
|
result.quic_key = params.key
|
||||||
if params.path then result.serviceName = params.path end
|
elseif result.transport == "grpc" then
|
||||||
if params.serviceName then result.serviceName = params.serviceName end
|
result.serviceName = params.serviceName
|
||||||
result.grpc_mode = params.mode
|
result.grpc_mode = params.mode or "gun"
|
||||||
|
elseif result.transport == "tcp" or result.transport == "raw" then
|
||||||
|
result.tcp_guise = params.headerType or "none"
|
||||||
|
if result.tcp_guise == "http" then
|
||||||
|
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
||||||
|
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
result.vless_encryption = params.encryption or "none"
|
|
||||||
|
|
||||||
result.tls_flow = params.flow or nil
|
|
||||||
|
|
||||||
result.tls = "0"
|
|
||||||
if params.security == "tls" or params.security == "reality" then
|
|
||||||
result.tls = "1"
|
|
||||||
result.tls_host = (params.sni and params.sni ~= "") and params.sni or params.host
|
|
||||||
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
|
|
||||||
if params.security == "reality" then
|
|
||||||
result.reality = "1"
|
|
||||||
result.tls = "0"
|
|
||||||
result.reality_publickey = params.pbk or nil
|
|
||||||
result.reality_shortId = params.sid or nil
|
|
||||||
result.reality_spiderX = params.spx or nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
result.xtls = (params.security == "xtls") and "1" or nil
|
|
||||||
result.tls_flow = (result.tls == "1" or result.xtls == "1" or result.reality == "1") and params.flow or nil
|
|
||||||
|
|
||||||
result.server_port = port
|
|
||||||
result.insecure = insecure and "1" or "0"
|
|
||||||
end
|
end
|
||||||
elseif szType == 'hysteria' then
|
elseif szType == 'hysteria' then
|
||||||
local alias = ""
|
local alias = ""
|
||||||
|
Loading…
Reference in New Issue
Block a user