diff --git a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua index 31989b01..4ba5d068 100644 --- a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua +++ b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua @@ -96,7 +96,7 @@ function check_port() local retstring = "

" local s local server_name = "" - local uci = luci.model.uci.cursor() + local uci = require "luci.model.uci".cursor() local iret = 1 uci:foreach("shadowsocksr", "servers", function(s) if s.alias then diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua index 0cb47f0a..593d8f2d 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua @@ -1,9 +1,9 @@ local m, s, o -local uci = luci.model.uci.cursor() +local uci = require "luci.model.uci".cursor() local server_table = {} local type_table = {} local function is_finded(e) - return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false + return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= "" end uci:foreach("shadowsocksr", "servers", function(s) @@ -203,6 +203,7 @@ for key, server_type in pairs(type_table) do o:depends("server", key) end end +o:depends({server = "same", disable = true}) -- Socks User o = s:option(Value, "socks5_user", translate("Socks5 User"), translate("Only when Socks5 Auth Mode is password valid, Mandatory.")) @@ -225,6 +226,7 @@ for key, server_type in pairs(type_table) do o:depends("server", key) end end +o:depends({server = "same", disable = true}) end -- Local Port 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 d3e668f8..7f476862 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 @@ -6,19 +6,29 @@ require "luci.sys" require "luci.http" require "luci.jsonc" require "luci.model.ipkg" +require "luci.model.uci" +local uci = require "luci.model.uci".cursor() local m, s, o + local sid = arg[1] local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") +-- 确保正确判断程序是否存在 local function is_finded(e) - return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false + return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= "" end local function is_installed(e) return luci.model.ipkg.installed(e) end +local has_ss_rust = is_finded("sslocal") or is_finded("ssserver") +local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local") + +-- 读取当前存储的 ss_type +local ss_type = uci:get_first("shadowsocksr", "server_subscribe", "ss_type") + local server_table = {} local encrypt_methods = { -- ssr @@ -79,7 +89,7 @@ local encrypt_methods_ss = { "camellia-256-cfb", "salsa20", "chacha20", - "chacha20-ietf" ]] + "chacha20-ietf" ]]-- } local protocol = { @@ -146,8 +156,8 @@ end if is_finded("ssr-redir") then o:value("ssr", translate("ShadowsocksR")) end -if is_finded("ss-local") or is_finded("ss-redir") or is_finded("sslocal") or is_finded("ssmanager") then - o:value("ss", translate("Shadowsocks")) +if has_ss_rust or has_ss_libev then + o:value("ss", translate("ShadowSocks")) end if is_finded("trojan") then o:value("trojan", translate("Trojan")) @@ -185,16 +195,44 @@ o:depends("type", "tun") o.description = translate("Redirect traffic to this network interface") -- 新增一个选择框,用于选择 Shadowsocks 版本 -o = s:option(ListValue, "ss_variant", translate("Shadowsocks Variant")) -local isSSRust = is_finded("sslocal") or is_finded("ssmanager") -local isSSLibev = is_finded("ss-local") or is_finded("ss-redir") -if isSSRust then - o:value("isSSRust", translate("Shadowsocks-rust Version")) +o = s:option(ListValue, "has_ss_type", string.format("%s", translate("ShadowSocks Node Use Version"))) +o.description = translate("Selection ShadowSocks Node Use Version.") +-- 设置默认 Shadowsocks 版本 +-- 动态添加选项 +if has_ss_rust then + o:value("ss-rust", translate("ShadowSocks-rust Version")) end -if isSSLibev then - o:value("isSSLibev", translate("Shadowsocks-libev Version")) +if has_ss_libev then + o:value("ss-libev", translate("ShadowSocks-libev Version")) +end +-- 设置默认值 +if ss_type == "ss-rust" then + o.default = "ss-rust" +elseif ss_type == "ss-libev" then + o.default = "ss-libev" end o:depends("type", "ss") +o.write = function(self, section, value) + -- 更新 Shadowsocks 节点的 has_ss_type + uci:foreach("shadowsocksr", "servers", function(s) + local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型 + if node_type == "ss" then -- 仅修改 Shadowsocks 节点 + local old_value = uci:get("shadowsocksr", s[".name"], "has_ss_type") + if old_value ~= value then + uci:set("shadowsocksr", s[".name"], "has_ss_type", value) + end + end + end) + + -- 更新 server_subscribe 的 ss_type + local old_value = uci:get("shadowsocksr", "server_subscribe", "ss_type") + if old_value ~= value then + uci:set("shadowsocksr", "@server_subscribe[0]", "ss_type", value) + end + + -- 更新当前 section 的 has_ss_type + Value.write(self, section, value) +end o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol")) o:value("vless", translate("VLESS")) @@ -271,7 +309,12 @@ o:depends("type", "ssr") o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method")) for _, v in ipairs(encrypt_methods_ss) do - o:value(v) + if v == "none" then + o.default = "none" + o:value("none", translate("none")) + else + o:value(v, translate(v)) + end end o.rmempty = true o:depends("type", "ss") diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua index 26de9baa..6e209e1a 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua @@ -3,11 +3,11 @@ -- Licensed to the public under the GNU General Public License v3. local m, s, sec, o -local uci = luci.model.uci.cursor() +local uci = require "luci.model.uci".cursor() local validation = require "luci.cbi.datatypes" local function is_finded(e) - return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false + return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= "" end m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"), translate("

Support SS/SSR/V2RAY/XRAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc.

")) diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua index 6ef44c08..db3160ab 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua @@ -120,15 +120,9 @@ function o.cfgvalue(...) end o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method")) -function o.cfgvalue(...) - local v = Value.cfgvalue(...) - return v and v:upper() or "-" -end - -o = sec:option(DummyValue, "encrypt_method_ss", translate("Encrypt Method")) -function o.cfgvalue(...) - local v = Value.cfgvalue(...) - return v and v:upper() or "-" +function o.cfgvalue(self, section) + local method = self.map:get(section, "encrypt_method") or self.map:get(section, "encrypt_method_ss") + return method and method:upper() or "-" end o = sec:option(DummyValue, "protocol", translate("Protocol")) 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 99188485..ac1bbc6f 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua @@ -1,10 +1,39 @@ -- Licensed to the public under the GNU General Public License v3. require "luci.http" +require "luci.sys" require "luci.dispatcher" require "luci.model.uci" -local m, s, o -local uci = luci.model.uci.cursor() +local uci = require "luci.model.uci".cursor() + +local m, s, o, node local server_count = 0 + +-- 确保正确判断程序是否存在 +local function is_finded(e) + return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= "" +end + +local has_ss_rust = is_finded("sslocal") or is_finded("ssserver") +local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local") + +local ss_type_list = {} + +if has_ss_rust then + table.insert(ss_type_list, { id = "ss-rust", name = translate("ShadowSocks-rust Version") }) +end +if has_ss_libev then + table.insert(ss_type_list, { id = "ss-libev", name = translate("ShadowSocks-libev Version") }) +end + +-- 如果用户没有手动设置,则自动选择 +if ss_type == "" then + if has_ss_rust then + ss_type = "ss-rust" + elseif has_ss_libev then + ss_type = "ss-libev" + end +end + uci:foreach("shadowsocksr", "servers", function(s) server_count = server_count + 1 end) @@ -48,6 +77,30 @@ o.default = 30 o.rmempty = true o:depends("auto_update", "1") +-- 确保 ss_type_list 不为空 +if #ss_type_list > 0 then + o = s:option(ListValue, "ss_type", string.format("%s", translate("ShadowSocks Node Use Version"))) + o.description = translate("Selection ShadowSocks Node Use Version.") + for _, v in ipairs(ss_type_list) do + o:value(v.id, v.name) -- 存储 "ss-libev" / "ss-rust",但 UI 显示完整名称 + end + o.default = ss_type -- 设置默认值 + o.write = function(self, section, value) + -- 更新 Shadowsocks 节点的 has_ss_type + uci:foreach("shadowsocksr", "servers", function(s) + local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型 + if node_type == "ss" then -- 仅修改 Shadowsocks 节点 + local old_value = uci:get("shadowsocksr", s[".name"], "has_ss_type") + if old_value ~= value then + uci:set("shadowsocksr", s[".name"], "has_ss_type", value) + end + end + end) + -- 更新当前 section 的 ss_type + Value.write(self, section, value) + end +end + o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL")) o.rmempty = true diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua index c7e84ec6..21b7c70d 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua @@ -15,7 +15,7 @@ local ad_count = 0 local ip_count = 0 local nfip_count = 0 local Process_list = luci.sys.exec("busybox ps -w") -local uci = luci.model.uci.cursor() +local uci = require "luci.model.uci".cursor() -- html constants font_blue = [[]] style_blue = [[]] diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm index f9befe53..2ba1be91 100644 --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm @@ -87,8 +87,18 @@ } // set tr draggable - function enableDragForTable(table_selecter, store) { - var trs = document.querySelectorAll(table_selecter + " tr"); + function enableDragForTable(table_selector, store) { + // 添加 CSS 样式 + const style = document.createElement("style"); + style.textContent = ` + tr[draggable="true"] { + cursor: move; + user-select: none; + } + `; + document.head.appendChild(style); + + var trs = document.querySelectorAll(table_selector + " tr"); if (!trs || trs.length.length < 3) { return; } @@ -104,12 +114,12 @@ ev.dataTransfer.dropEffect = "move"; } function moveToTop(id) { - var top = document.querySelectorAll(table_selecter + " tr")[2]; + var top = document.querySelectorAll(table_selector + " tr")[2]; cbi_row_drop(id, top.id, store); } function moveToBottom(id) { - console.log('moveToBottom:', id); - var trList = document.querySelectorAll(table_selecter + " tr"); + //console.log('moveToBottom:', id); + var trList = document.querySelectorAll(table_selector + " tr"); var bottom = trList[trList.length - 1]; cbi_row_drop(id, bottom.id, store, true); } diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm index d38d2121..72170dd5 100644 --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm @@ -1,6 +1,12 @@ <%+cbi/valueheader%> +<% +local map = self.map +local ss_type = map:get("@server_subscribe[0]", "ss_type") +-%>