OSDN Git Service

luci-app-ssr-plus: sync with upstream
authorTianling Shen <cnsztl@immortalwrt.org>
Tue, 14 Jun 2022 15:34:36 +0000 (23:34 +0800)
committerTianling Shen <cnsztl@immortalwrt.org>
Tue, 14 Jun 2022 15:34:36 +0000 (23:34 +0800)
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
applications/luci-app-ssr-plus/Makefile
applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua
applications/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po
applications/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua
applications/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua

index b009926..3b82010 100644 (file)
@@ -5,12 +5,15 @@ PKG_VERSION:=186
 PKG_RELEASE:=3
 
 PKG_CONFIG_DEPENDS:= \
+       CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \
+       CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
+       CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
+       CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2 \
-       CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server \
        CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client \
@@ -28,13 +31,17 @@ LUCI_DEPENDS:= \
        +coreutils +coreutils-base64 +dns2socks +dns2tcp +dnsmasq-full +ipset +ip-full \
        +iptables +iptables-mod-tproxy +lua +libuci-lua +luci-lib-ipkg +microsocks \
        +tcping +resolveip +shadowsocksr-libev-ssr-check +uclient-fetch \
+       +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \
+       +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
+       +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
+       +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
+       +PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:curl \
+       +PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:sagernet-core \
        +PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
        +PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
        +PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks:ipt2socks \
        +PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
        +PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2:redsocks2 \
-       +PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:curl \
-       +PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:sagernet-core \
        +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-local \
        +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-redir \
        +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server:shadowsocks-libev-ss-server \
@@ -48,6 +55,24 @@ LUCI_DEPENDS:= \
        +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin
 
 define Package/$(PKG_NAME)/config
+choice
+       prompt "V2ray-core Selection"
+       default PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core if aarch64||arm||i386||x86_64
+       default PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY
+
+       config PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY
+       bool "None"
+
+       config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
+       bool "Include V2ray-core"
+
+       config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
+       bool "Include Xray-core"
+
+       config PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core
+       bool "Include SagerNet-core (An enhanced edition of v2ray-core)"
+endchoice
+
 config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
        bool "Include Kcptun"
        default n
@@ -69,10 +94,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Redsocks2
        bool "Include Redsocks2"
        default n
 
-config PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core
-       bool "Include sagernet-core (An enhanced edition of v2ray-core)"
-       default y if aarch64||arm||i386||x86_64
-
 config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client
        bool "Include Shadowsocks Libev Client"
        default y if !(aarch64||i386||x86_64)
index c31a56d..97e4739 100644 (file)
@@ -186,6 +186,7 @@ o:value("vmess", translate("VMess"))
 o:value("trojan", translate("Trojan"))
 o:value("shadowsocks", translate("Shadowsocks"))
 if is_installed("sagernet-core") then
+       o:value("shadowsocksr", translate("ShadowsocksR"))
        o:value("wireguard", translate("WireGuard"))
 end
 o:value("socks", translate("Socks"))
@@ -237,8 +238,9 @@ o:depends("type", "trojan")
 o:depends("type", "naiveproxy")
 o:depends({type = "socks5", auth_enable = true})
 o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true})
-o:depends({type = "v2ray", v2ray_protocol = "socks", auth_enable = true})
+o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", auth_enable = true})
 o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
 o:depends({type = "v2ray", v2ray_protocol = "trojan"})
 
 o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
@@ -247,6 +249,7 @@ for _, v in ipairs(encrypt_methods) do
 end
 o.rmempty = true
 o:depends("type", "ssr")
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
 
 o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
 for _, v in ipairs(encrypt_methods_ss) do
@@ -270,7 +273,7 @@ o.default = "1"
 -- Shadowsocks Plugin
 o = s:option(Value, "plugin", translate("Obfs"))
 o:value("none", translate("None"))
-if is_finded("obfs-local") then
+if is_finded("obfs-local") or is_installed("sagernet-core") then
        o:value("obfs-local", translate("obfs-local"))
 end
 if is_finded("v2ray-plugin") or is_installed("sagernet-core") then
@@ -281,12 +284,16 @@ if is_finded("xray-plugin") then
 end
 o.rmempty = true
 o:depends("type", "ss")
-o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+if is_installed("sagernet-core") then
+       o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+end
 
 o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
 o.rmempty = true
 o:depends("type", "ss")
-o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+if is_installed("sagernet-core") then
+       o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+end
 
 o = s:option(ListValue, "protocol", translate("Protocol"))
 for _, v in ipairs(protocol) do
@@ -294,9 +301,11 @@ for _, v in ipairs(protocol) do
 end
 o.rmempty = true
 o:depends("type", "ssr")
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
 
 o = s:option(Value, "protocol_param", translate("Protocol param (optional)"))
 o:depends("type", "ssr")
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
 
 o = s:option(ListValue, "obfs", translate("Obfs"))
 for _, v in ipairs(obfs) do
@@ -304,9 +313,11 @@ for _, v in ipairs(obfs) do
 end
 o.rmempty = true
 o:depends("type", "ssr")
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
 
 o = s:option(Value, "obfs_param", translate("Obfs param (optional)"))
 o:depends("type", "ssr")
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
 
 -- [[ Hysteria ]]--
 o = s:option(ListValue, "hysteria_protocol", translate("Protocol"))
@@ -364,6 +375,15 @@ end
 o.rmempty = true
 o:depends({type = "v2ray", v2ray_protocol = "vmess"})
 
+-- SOCKS Version
+o = s:option(ListValue, "socks_ver", translate("Socks Version"))
+o:value("4", "Socks4")
+o:value("4a", "Socks4A")
+o:value("5", "Socks5")
+o.rmempty = true
+o.default = "5"
+o:depends({type = "v2ray", v2ray_protocol = "socks"})
+
 -- 传输协议
 o = s:option(ListValue, "transport", translate("Transport"))
 o:value("tcp", "TCP")
@@ -410,18 +430,20 @@ o = s:option(Value, "ws_path", translate("WebSocket Path"))
 o:depends("transport", "ws")
 o.rmempty = true
 
--- WS前置数据
-o = s:option(Value, "ws_ed", translate("Max Early Data"))
-o:depends("transport", "ws")
-o.datatype = "uinteger"
-o.default = 2048
-o.rmempty = true
+if is_finded("v2ray") then
+       -- WS前置数据
+       o = s:option(Value, "ws_ed", translate("Max Early Data"))
+       o:depends("transport", "ws")
+       o.datatype = "uinteger"
+       o.default = 2048
+       o.rmempty = true
 
--- WS前置数据标头
-o = s:option(Value, "ws_ed_header", translate("Early Data Header Name"))
-o:depends("transport", "ws")
-o.default = "Sec-WebSocket-Protocol"
-o.rmempty = true
+       -- WS前置数据标头
+       o = s:option(Value, "ws_ed_header", translate("Early Data Header Name"))
+       o:depends("transport", "ws")
+       o.default = "Sec-WebSocket-Protocol"
+       o.rmempty = true
+end
 
 -- [[ H2部分 ]]--
 
@@ -440,48 +462,52 @@ o = s:option(Value, "serviceName", translate("gRPC Service Name"))
 o:depends("transport", "grpc")
 o.rmempty = true
 
--- gPRC模式
-o = s:option(ListValue, "grpc_mode", translate("gRPC Mode"))
-o:depends("transport", "grpc")
-o:value("gun", translate("Gun"))
-o:value("multi", translate("Multi"))
-o:value("raw", translate("Raw"))
-o.rmempty = true
+if is_installed("sagernet-core") then
+       -- gPRC模式
+       o = s:option(ListValue, "grpc_mode", translate("gRPC Mode"))
+       o:depends("transport", "grpc")
+       o:value("gun", translate("Gun"))
+       o:value("multi", translate("Multi"))
+       o:value("raw", translate("Raw"))
+       o.rmempty = true
+end
 
--- gRPC初始窗口
-o = s:option(Value, "initial_windows_size", translate("Initial Windows Size"))
-o.datatype = "uinteger"
-o:depends("transport", "grpc")
-o.default = 0
-o.rmempty = true
+if is_finded("xray") or is_installed("sagernet-core") then
+       -- gRPC初始窗口
+       o = s:option(Value, "initial_windows_size", translate("Initial Windows Size"))
+       o.datatype = "uinteger"
+       o:depends("transport", "grpc")
+       o.default = 0
+       o.rmempty = true
 
--- H2/gRPC健康检查
-o = s:option(Flag, "health_check", translate("H2/gRPC Health Check"))
-o:depends("transport", "h2")
-o:depends("transport", "grpc")
-o.rmempty = true
+       -- H2/gRPC健康检查
+       o = s:option(Flag, "health_check", translate("H2/gRPC Health Check"))
+       o:depends("transport", "h2")
+       o:depends("transport", "grpc")
+       o.rmempty = true
 
-o = s:option(Value, "read_idle_timeout", translate("H2 Read Idle Timeout"))
-o.datatype = "uinteger"
-o:depends({health_check = true, transport = "h2"})
-o.default = 60
-o.rmempty = true
+       o = s:option(Value, "read_idle_timeout", translate("H2 Read Idle Timeout"))
+       o.datatype = "uinteger"
+       o:depends({health_check = true, transport = "h2"})
+       o.default = 60
+       o.rmempty = true
 
-o = s:option(Value, "idle_timeout", translate("gRPC Idle Timeout"))
-o.datatype = "uinteger"
-o:depends({health_check = true, transport = "grpc"})
-o.default = 60
-o.rmempty = true
+       o = s:option(Value, "idle_timeout", translate("gRPC Idle Timeout"))
+       o.datatype = "uinteger"
+       o:depends({health_check = true, transport = "grpc"})
+       o.default = 60
+       o.rmempty = true
 
-o = s:option(Value, "health_check_timeout", translate("Health Check Timeout"))
-o.datatype = "uinteger"
-o:depends("health_check", 1)
-o.default = 20
-o.rmempty = true
+       o = s:option(Value, "health_check_timeout", translate("Health Check Timeout"))
+       o.datatype = "uinteger"
+       o:depends("health_check", 1)
+       o.default = 20
+       o.rmempty = true
 
-o = s:option(Flag, "permit_without_stream", translate("Permit Without Stream"))
-o:depends({health_check = true, transport = "grpc"})
-o.rmempty = true
+       o = s:option(Flag, "permit_without_stream", translate("Permit Without Stream"))
+       o:depends({health_check = true, transport = "grpc"})
+       o.rmempty = true
+end
 
 -- [[ QUIC部分 ]]--
 o = s:option(ListValue, "quic_security", translate("QUIC Security"))
@@ -591,7 +617,7 @@ o:depends({type = "v2ray", v2ray_protocol = "vless", xtls = false})
 o:depends({type = "v2ray", v2ray_protocol = "vmess", xtls = false})
 o:depends({type = "v2ray", v2ray_protocol = "trojan", xtls = false})
 o:depends({type = "v2ray", v2ray_protocol = "shadowsocks", xtls = false})
-o:depends({type = "v2ray", v2ray_protocol = "socks", xtls = false})
+o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", xtls = false})
 o:depends({type = "v2ray", v2ray_protocol = "http", xtls = false})
 o:depends("type", "trojan")
 
@@ -620,15 +646,17 @@ o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket"))
 o:depends({type = "trojan", tls = true})
 o.default = "0"
 
--- [[ uTLS ]]--
-o = s:option(ListValue, "fingerprint", translate("Finger Print"))
-o:value("disable", translate("disable"))
-o:value("firefox", translate("firefox"))
-o:value("chrome", translate("chrome"))
-o:value("safari", translate("safari"))
-o:value("randomized", translate("randomized"))
-o:depends({type = "v2ray", tls = true})
-o.default = "disable"
+if is_finded("xray") then
+       -- [[ uTLS ]]--
+       o = s:option(ListValue, "fingerprint", translate("Finger Print"))
+       o:value("disable", translate("disable"))
+       o:value("firefox", translate("firefox"))
+       o:value("chrome", translate("chrome"))
+       o:value("safari", translate("safari"))
+       o:value("randomized", translate("randomized"))
+       o:depends({type = "v2ray", tls = true})
+       o.default = "disable"
+end
 
 o = s:option(Value, "tls_host", translate("TLS Host"))
 o.datatype = "hostname"
index 1d1b7a5..9be3eb1 100644 (file)
@@ -70,6 +70,9 @@ msgstr "布隆过滤器"
 msgid "VLESS Encryption"
 msgstr "VLESS 加密"
 
+msgid "Socks Version"
+msgstr "Socks 版本"
+
 msgid "Flow"
 msgstr "流控 (Flow)"
 
index 181ab62..a4b2391 100755 (executable)
@@ -32,14 +32,21 @@ function vmess_vless()
 end
 function trojan_shadowsocks()
        outbound_settings = {
-               plugin = (server.v2ray_protocol == "shadowsocks") and server.plugin ~= "none" and server.plugin or nil,
+               plugin = ((server.v2ray_protocol == "shadowsocks") and server.plugin ~= "none" and server.plugin) or (server.v2ray_protocol == "shadowsocksr" and "shadowsocksr") or nil,
                pluginOpts = (server.v2ray_protocol == "shadowsocks") and server.plugin_opts or nil,
+               pluginArgs = (server.v2ray_protocol == "shadowsocksr") and {
+                       "--protocol=" .. server.protocol,
+                       "--protocol-param=" .. (server.protocol_param or ""),
+                       "--obfs=" .. server.obfs,
+                       "--obfs-param=" .. (server.obfs_param or "")
+               } or nil,
                servers = {
                        {
                                address = server.server,
                                port = tonumber(server.server_port),
                                password = server.password,
                                method = (server.v2ray_protocol == "shadowsocks") and server.encrypt_method_ss or nil,
+                               method = (server.v2ray_protocol == "shadowsocksr") and server.encrypt_method or nil,
                                uot = (server.v2ray_protocol == "shadowsocks") and (server.uot == '1') or nil,
                                ivCheck = (server.v2ray_protocol == "shadowsocks") and (server.ivCheck == '1') or nil,
                                flow = (server.v2ray_protocol == "trojan") and (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-splice") or nil
@@ -47,7 +54,9 @@ function trojan_shadowsocks()
                }
        }
 
-       if (server.v2ray_protocol == "shadowsocks") and (server.mux ~= "1") and (not (outbound_settings.plugin or server.transport ~= "tcp" or server.tls or server.xtls)) then
+       if server.v2ray_protocol == "shadowsocksr" then
+               server.v2ray_protocol = "shadowsocks"
+       elseif (server.v2ray_protocol == "shadowsocks") and (server.mux ~= "1") and (not (outbound_settings.plugin or server.transport ~= "tcp" or server.tls or server.xtls)) then
                server.v2ray_protocol = "shadowsocks_sing"
                outbound_settings = outbound_settings.servers[1]
        elseif (server.v2ray_protocol == "trojan") and (server.tls and server.mux ~= "1") and (not (server.transport ~= "tcp" or server.xtls)) then
@@ -59,6 +68,7 @@ function trojan_shadowsocks()
 end
 function socks_http()
        outbound_settings = {
+               version = server.socks_ver or nil,
                servers = {
                        {
                                address = server.server,
@@ -105,6 +115,9 @@ function outbound:handleIndex(index)
                shadowsocks = function()
                        trojan_shadowsocks()
                end,
+               shadowsocksr = function()
+                       trojan_shadowsocks()
+               end,
                socks = function()
                        socks_http()
                end,
index cc4c87a..078482d 100755 (executable)
@@ -28,6 +28,7 @@ local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '
 local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '')
 local packet_encoding = luci.model.ipkg.installed("sagernet-core") and ucic:get_first(name, 'global', 'default_packet_encoding', 'xudp') or nil
 local v2_ss = luci.sys.exec('type -t -p ss-redir sslocal') ~= "" and "ss" or "v2ray"
+local v2_ssr = luci.sys.exec('type -t -p ssr-redir') ~= "" and "ssr" or "v2ray"
 local v2_tj = luci.sys.exec('type -t -p trojan') ~= "" and "trojan" or "v2ray"
 local log = function(...)
        print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
@@ -147,6 +148,8 @@ local function processData(szType, content)
        if szType == 'ssr' then
                local dat = split(content, "/%?")
                local hostInfo = split(dat[1], ':')
+               result.type = v2_ssr
+               result.v2ray_protocol = (v2_ssr == "v2ray") and "shadowsocksr" or nil
                result.server = hostInfo[1]
                result.server_port = hostInfo[2]
                result.protocol = hostInfo[3]