From 1a2f3e74c1b3eef30d69b4da4941debd961f0425 Mon Sep 17 00:00:00 2001 From: action Date: Sun, 21 Jun 2026 16:24:44 +0800 Subject: [PATCH] update 2026-06-21 16:24:44 --- luci-app-ssr-plus/Makefile | 5 +- luci-app-ssr-plus/Makefile.rej | 11 + .../luasrc/controller/shadowsocksr.lua | 7 + .../model/cbi/shadowsocksr/client-config.lua | 30 + .../model/cbi/shadowsocksr/server-config.lua | 56 +- .../luasrc/model/cbi/shadowsocksr/servers.lua | 21 + .../luasrc/view/shadowsocksr/ssrurl.htm | 61 +- .../shadowsocksr/subscribe_actions_footer.htm | 55 +- luci-app-ssr-plus/po/templates/ssr-plus.pot | 16 + luci-app-ssr-plus/po/zh_Hans/ssr-plus.po | 16 + .../root/etc/init.d/shadowsocksr | 324 ++++++--- .../root/etc/uci-defaults/luci-ssr-plus | 7 + luci-app-ssr-plus/root/usr/bin/ssr-switch | 28 +- .../usr/share/shadowsocksr/clash_yaml.lua | 475 ++++++++++++- .../share/shadowsocksr/shadowsocksr.config | 2 +- .../root/usr/share/shadowsocksr/subscribe.lua | 637 +++++++++++++++++- v2ray-geodata/Makefile | 4 +- 17 files changed, 1567 insertions(+), 188 deletions(-) create mode 100644 luci-app-ssr-plus/Makefile.rej diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile index e40b16ea..89426f4a 100644 --- a/luci-app-ssr-plus/Makefile +++ b/luci-app-ssr-plus/Makefile @@ -3,8 +3,8 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=luci-app-ssr-plus LUCI_PKGARCH:=all PKG_NAME:=luci-app-ssr-plus -PKG_VERSION:=193 -PKG_RELEASE:=23 +PKG_VERSION:=195 +PKG_RELEASE:=5 PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ @@ -99,7 +99,6 @@ endchoice choice prompt "V2ray-core Selection" - default PACKAGE_$(PKG_NAME)_INCLUDE_Xray default PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY config PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY diff --git a/luci-app-ssr-plus/Makefile.rej b/luci-app-ssr-plus/Makefile.rej new file mode 100644 index 00000000..378c64b7 --- /dev/null +++ b/luci-app-ssr-plus/Makefile.rej @@ -0,0 +1,11 @@ +--- luci-app-ssr-plus/Makefile ++++ luci-app-ssr-plus/Makefile +@@ -118,7 +118,7 @@ endchoice + + choice + prompt "V2ray-core Selection" +- default PACKAGE_$(PKG_NAME)_INCLUDE_Xray if aarch64||arm||i386||x86_64 ++ default PACKAGE_$(PKG_NAME)_INCLUDE_Xray + default PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY + + config PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY diff --git a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua index 7db25438..36934c99 100644 --- a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua +++ b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua @@ -817,6 +817,13 @@ function add_subscribe_item() return end + local commit_subscribe = luci.sys.call("uci -q commit shadowsocksr >/dev/null 2>&1") + if commit_subscribe ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "commit failed" }) + return + end + luci.http.prepare_content("application/json") luci.http.write_json({ ret = 1, sid = sid, alias = alias, enabled = "1" }) end diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua index aa201e81..4b490ed3 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua @@ -417,6 +417,9 @@ end if is_finded("xray") then o:value("hysteria2", translate("Hysteria2")) end +if is_finded("mihomo") then + o:value("snell", translate("Snell")) +end o:value("socks", translate("Socks")) o:value("http", translate("HTTP")) o:depends("type", "v2ray") @@ -500,6 +503,11 @@ o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", auth_enabl o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o = s:option(Value, "snell_psk", translate("Snell PSK")) +o.password = true +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "snell"}) + o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) for _, v in ipairs(encrypt_methods) do o:value(v) @@ -946,6 +954,28 @@ o.rmempty = true o.default = "5" o:depends({type = "v2ray", v2ray_protocol = "socks"}) +o = s:option(ListValue, "snell_version", translate("Snell Version")) +o:value("1", "v1") +o:value("2", "v2") +o:value("3", "v3") +o:value("4", "v4") +o:value("5", "v5") +o.default = "4" +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "snell"}) + +o = s:option(ListValue, "snell_obfs", translate("Snell Obfs")) +o:value("", translate("Disable")) +o:value("http", "HTTP") +o:value("tls", "TLS") +o.default = "" +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "snell"}) + +o = s:option(Value, "snell_obfs_host", translate("Snell Obfs Host")) +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "snell"}) + -- 浼犺緭鍗忚 o = s:option(ListValue, "transport", translate("Transport")) o:value("raw", "RAW (TCP)") diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua index 2fdf777d..4c8fcca1 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua @@ -7,7 +7,7 @@ require "nixio.fs" local m, s, o local sid = arg[1] --- 加密方式(SS/SSR用) +-- 鍔犲瘑鏂瑰紡锛圫S/SSR鐢級 local encrypt_methods = { "rc4-md5", "rc4-md5-6", "rc4", "table", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", @@ -23,13 +23,13 @@ local encrypt_methods_ss = { "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" } --- Shadowsocks 加密方法(Xray 版) +-- Shadowsocks 鍔犲瘑鏂规硶锛圶ray 鐗堬級 local v_ss_encrypt_method_list = { "aes-128-cfb", "aes-256-cfb", "aes-128-gcm", "aes-256-gcm", "chacha20", "chacha20-ietf", "chacha20-poly1305", "chacha20-ietf-poly1305" } --- 伪装类型(用于 mKCP/QUIC) +-- 浼绫诲瀷锛堢敤浜 mKCP/QUIC锛 local header_type_list = { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" } @@ -50,7 +50,7 @@ s = m:section(NamedSection, sid, "server_config") s.anonymous = true s.addremove = false --- ========== 基本设置 ========== +-- ========== 鍩烘湰璁剧疆 ========== o = s:option(Flag, "enable", translate("Enable")) o.default = 1 o.rmempty = false @@ -63,12 +63,14 @@ end if nixio.fs.access("/usr/bin/ssr-server") then o:value("ssr", translate("ShadowsocksR")) end --- Xray 协议支持 -if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/libexec/xray") then - o:value("vmess", "VMess (Xray)") - o:value("vless", "VLESS (Xray)") - o:value("trojan", "Trojan (Xray)") - o:value("shadowsocks", "Shadowsocks (Xray)") +-- Xray 鍗忚鏀寔 +if nixio.fs.access("/usr/bin/mihomo") or nixio.fs.access("/usr/libexec/mihomo") + or nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/libexec/xray") +then + o:value("vmess", "VMess (Mihomo/Xray)") + o:value("vless", "VLESS (Mihomo/Xray)") + o:value("trojan", "Trojan (Mihomo/Xray)") + o:value("shadowsocks", "Shadowsocks (Mihomo/Xray)") end o.default = "socks5" @@ -99,7 +101,7 @@ o:depends("type", "ssr") o:depends("type", "trojan") o:depends("type", "shadowsocks") --- ========== SS/SSR 协议特有 ========== +-- ========== SS/SSR 鍗忚鐗规湁 ========== o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) for _, v in ipairs(encrypt_methods) do o:value(v) end o.rmempty = false @@ -128,8 +130,8 @@ o.rmempty = false o:depends("type", "ss") o:depends("type", "ssr") --- ========== Xray 协议通用字段 ========== --- 用户备注 +-- ========== Xray 鍗忚閫氱敤瀛楁 ========== +-- 鐢ㄦ埛澶囨敞 o = s:option(Value, "remarks", translate("Remarks")) o.default = translate("Remarks") o.rmempty = true @@ -138,7 +140,7 @@ o:depends("type", "vless") o:depends("type", "trojan") o:depends("type", "shadowsocks") --- 用户等级 +-- 鐢ㄦ埛绛夌骇 o = s:option(Value, "level", translate("User Level")) o.datatype = "uinteger" o.default = 1 @@ -148,21 +150,21 @@ o:depends("type", "vless") o:depends("type", "shadowsocks") o:depends("type", "trojan") --- ========== Xray 协议认证字段 ========== --- UUID (用于 vmess/vless) +-- ========== Xray 鍗忚璁よ瘉瀛楁 ========== +-- UUID (鐢ㄤ簬 vmess/vless) o = s:option(Value, "uuid", translate("UUID")) o.description = translate("Required for VMess/VLESS. Generate with: uuidgen") o.rmempty = true o:depends("type", "vmess") o:depends("type", "vless") --- Trojan 密码 +-- Trojan 瀵嗙爜 o = s:option(Value, "trojan_password", translate("Trojan Password")) o.password = true o.rmempty = true o:depends("type", "trojan") --- Shadowsocks 密码和加密(Xray 内置) +-- Shadowsocks 瀵嗙爜鍜屽姞瀵嗭紙Xray 鍐呯疆锛 o = s:option(Value, "ss_password", translate("Shadowsocks Password")) o.password = true o.rmempty = true @@ -195,7 +197,7 @@ o.default = "none" o.rmempty = true o:depends("type", "vless") --- ========== TLS / XTLS 设置 ========== +-- ========== TLS / XTLS 璁剧疆 ========== o = s:option(Flag, "tls", translate("TLS")) o.default = 0 o.rmempty = true @@ -234,7 +236,7 @@ o.description = translate("e.g.: /etc/ssl/private.key") o.rmempty = true o:depends("tls", "1") --- ========== 传输层设置 (Transport) ========== +-- ========== 浼犺緭灞傝缃 (Transport) ========== o = s:option(ListValue, "transport", translate("Transport Protocol")) o:value("tcp", "TCP") o:value("mkcp", "mKCP") @@ -248,7 +250,7 @@ o:depends("type", "vmess") o:depends("type", "vless") o:depends("type", "trojan") --- ----- WebSocket 设置 ----- +-- ----- WebSocket 璁剧疆 ----- o = s:option(Value, "ws_host", translate("WebSocket Host")) o.rmempty = true o:depends("transport", "ws") @@ -264,7 +266,7 @@ o:depends("type", "vmess") o:depends("type", "vless") o:depends("type", "trojan") --- ----- HTTP/2 设置 ----- +-- ----- HTTP/2 璁剧疆 ----- o = s:option(Value, "h2_host", translate("HTTP/2 Host")) o.rmempty = true o:depends("transport", "h2") @@ -278,7 +280,7 @@ o:depends("transport", "h2") o:depends("type", "vmess") o:depends("type", "vless") --- ----- TCP 伪装设置 ----- +-- ----- TCP 浼璁剧疆 ----- o = s:option(ListValue, "tcp_guise", translate("TCP Camouflage Type")) o:value("none", "none") o:value("http", "http") @@ -296,7 +298,7 @@ o = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path")) o.rmempty = true o:depends("tcp_guise", "http") --- ----- mKCP 设置 ----- +-- ----- mKCP 璁剧疆 ----- o = s:option(ListValue, "mkcp_guise", translate("mKCP Camouflage Type")) for _, v in ipairs(header_type_list) do o:value(v) end o.default = "none" @@ -349,13 +351,13 @@ o.datatype = "uinteger" o.rmempty = true o:depends("transport", "mkcp") --- ----- DomainSocket 设置 ----- +-- ----- DomainSocket 璁剧疆 ----- o = s:option(Value, "ds_path", translate("DomainSocket Path")) o.description = translate("A legal file path. This file must not exist before running.") o.rmempty = true o:depends("transport", "ds") --- ----- QUIC 设置 ----- +-- ----- QUIC 璁剧疆 ----- o = s:option(ListValue, "quic_security", translate("QUIC Security")) o:value("none", "none") o:value("aes-128-gcm", "aes-128-gcm") @@ -374,7 +376,7 @@ o.default = "none" o.rmempty = true o:depends("transport", "quic") --- ========== 访问控制 ========== +-- ========== 璁块棶鎺у埗 ========== o = s:option(Flag, "bind_local", translate("Bind Local Only")) o.description = translate("When selected, it can only be accessed locally. Recommended when using reverse proxies.") o.default = 0 diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua index 6e5e01e3..3802d9f7 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua @@ -458,6 +458,7 @@ o.remove = function() end o = s:option(Value, "filter_words", translate("Subscribe Filter Words")) o.rmempty = true +o.default = "杩囨湡/閲嶇疆/濂楅/鍓╀綑/缃戝潃/QQ缇/瀹樼綉/闃插け鑱/鍥炲浗" o.description = translate("Filter Words splited by /") o:depends("_subscribe_advanced_toggle", "1") preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") @@ -544,6 +545,26 @@ if has_mihomo then o = s:option(DummyValue, "_upload_clash_yaml", translate("Upload Custom YAML File")) o.template = "shadowsocksr/clash_yaml_upload" o.description = translate("Upload a custom Clash/Mihomo YAML file. The file will be preprocessed and saved as a local Clash node.") + + o = s:option(Flag, "sub_convert", translate("Subscribe Convert Online")) + o.description = translate("Convert subscriptions to Clash/Mihomo YAML with a subscription template URL.") + o.default = "0" + o.rmempty = false + + o = s:option(Value, "convert_address", translate("Convert Address")) + o.default = "https://api.asailor.org/sub" + o.placeholder = "https://api.asailor.org/sub" + o:value("https://api.asailor.org/sub", "api.asailor.org") + o:value("https://api.wcc.best/sub", "api.wcc.best") + o.rmempty = true + o:depends("sub_convert", "1") + + o = s:option(Value, "template_url", translate("Subscribe Template URL")) + o.default = "https://raw.githubusercontent.com/Fzlwhyc/OpenClash-Templates/main//fzlwhyc-openclash.ini" + o.placeholder = "https://raw.githubusercontent.com/Fzlwhyc/OpenClash-Templates/main//fzlwhyc-openclash.ini" + o:value("https://raw.githubusercontent.com/Fzlwhyc/OpenClash-Templates/main//fzlwhyc-openclash.ini", "Fzlwhyc") + o.rmempty = true + o:depends("sub_convert", "1") end s:append(cbi.Template("shadowsocksr/subscribe_schedule_compact")) diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm index 025fd51b..a7390a24 100644 --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm @@ -3,7 +3,7 @@ local map = self.map local has_ss_rust = luci.sys.exec('type -t -p sslocal 2>/dev/null || type -t -p ssserver 2>/dev/null') ~= "" -local has_mihomo = luci.sys.exec('type -t -p mihomo -p /usr/libexec/mihomo 2>/dev/null') ~= "" +local has_mihomo = luci.sys.exec('type -t -p mihomo 2>/dev/null || { test -x /usr/libexec/mihomo && echo /usr/libexec/mihomo; }') ~= "" local has_xray = luci.sys.exec('type -t -p xray 2>/dev/null') ~= "" -%>