update 2025-07-29 09:50:00

This commit is contained in:
actions-user 2025-07-29 09:50:00 +08:00
parent d602e7e620
commit 8848075e6e
15 changed files with 247 additions and 66 deletions

View File

@ -84,6 +84,8 @@ function index()
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true
entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true
--[[rule_list]]
entry({"admin", "services", appname, "read_rulelist"}, call("read_rulelist")).leaf = true
@ -721,3 +723,51 @@ function subscribe_del_all()
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1")
http.status(200, "OK")
end
function subscribe_manual()
local section = http.formvalue("section") or ""
local current_url = http.formvalue("url") or ""
if section == "" or current_url == "" then
http_write_json({ success = false, msg = "Missing section or URL, skip." })
return
end
local uci_url = api.sh_uci_get(appname, section, "url")
if not uci_url or uci_url == "" then
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
return
end
if uci_url ~= current_url then
api.sh_uci_set(appname, section, "url", current_url, true)
end
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &")
http_write_json({ success = true, msg = "Subscribe triggered." })
end
function subscribe_manual_all()
local sections = http.formvalue("sections") or ""
local urls = http.formvalue("urls") or ""
if sections == "" or urls == "" then
http_write_json({ success = false, msg = "Missing section or URL, skip." })
return
end
local section_list = util.split(sections, ",")
local url_list = util.split(urls, ",")
-- 检查是否存在未保存配置
for i, section in ipairs(section_list) do
local uci_url = api.sh_uci_get(appname, section, "url")
if not uci_url or uci_url == "" then
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
return
end
end
-- 保存有变动的url
for i, section in ipairs(section_list) do
local current_url = url_list[i] or ""
local uci_url = api.sh_uci_get(appname, section, "url")
if current_url ~= "" and uci_url ~= current_url then
api.sh_uci_set(appname, section, "url", current_url, true)
end
end
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &")
http_write_json({ success = true, msg = "Subscribe triggered." })
end

View File

@ -136,14 +136,15 @@ function o.cfgvalue(self, section)
translate("Delete All Subscribe Node"))
end
o = s:option(Button, "_update", translate("Manual subscription All"))
o.inputstyle = "apply"
function o.write(t, n)
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual > /dev/null 2>&1 &")
luci.http.redirect(api.url("log"))
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
o.rawhtml = true
o.cfgvalue = function(self, section)
return string.format([[
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribeAll()">%s</button>]],
translate("Manual subscription All"))
end
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("Please input the subscription url first, save and submit before manual subscription.") .. "</font>")
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
s.addremove = true
s.anonymous = true
s.sortable = true
@ -204,11 +205,12 @@ function o.cfgvalue(self, section)
remark, translate("Delete the subscribed node"))
end
o = s:option(Button, "_update", translate("Manual subscription"))
o.inputstyle = "apply"
function o.write(t, n)
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " manual > /dev/null 2>&1 &")
luci.http.redirect(api.url("log"))
o = s:option(DummyValue, "_update", translate("Manual subscription"))
o.rawhtml = true
o.cfgvalue = function(self, section)
return string.format([[
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')">%s</button>]],
section, translate("Manual subscription"))
end
s:append(Template(appname .. "/node_subscribe/js"))

View File

@ -132,7 +132,7 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
end
-- 探测地址
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custom Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" })
@ -373,6 +373,19 @@ o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translat
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("ech")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
-- [[ REALITY部分 ]] --
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
@ -403,6 +416,19 @@ o.default = "chrome"
o:depends({ [_n("tls")] = true, [_n("utls")] = true })
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(Flag, _n("use_mldsa65Verify"), translate("ML-DSA-65"))
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(TextValue, _n("reality_mldsa65Verify"), "ML-DSA-65 " .. translate("Public key"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("use_mldsa65Verify")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW (TCP)")
o:value("mkcp", "mKCP")

View File

@ -465,14 +465,6 @@ o.validate = function(self, value)
return value
end
o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
o.default = "0"
o:depends({ [_n("ech")] = true })
o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
o.default = "0"
o:depends({ [_n("ech")] = true })
if singbox_tags:find("with_utls") then
o = s:option(Flag, _n("utls"), translate("uTLS"))
o.default = "0"

View File

@ -186,6 +186,19 @@ o:value("h2,http/1.1")
o:value("h3,h2,http/1.1")
o:depends({ [_n("tls")] = true })
o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65"))
o.default = "0"
o:depends({ [_n("reality")] = true })
o = s:option(TextValue, _n("reality_mldsa65Seed"), "ML-DSA-65 " .. translate("Private Key"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("use_mldsa65Seed")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
-- o = s:option(Value, _n("minversion"), translate("minversion"))
-- o.default = "1.3"
-- o:value("1.3")
@ -223,6 +236,19 @@ o.validate = function(self, value, t)
return nil
end
o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("ech")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW")
o:value("mkcp", "mKCP")

View File

@ -323,14 +323,6 @@ o.validate = function(self, value)
return value
end
o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
o.default = "0"
o:depends({ [_n("ech")] = true })
o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
o.default = "0"
o:depends({ [_n("ech")] = true })
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("tcp", "TCP")
o:value("http", "HTTP")

View File

@ -60,7 +60,8 @@ function uci_save(cursor, config, commit, apply)
end
function sh_uci_get(config, section, option)
exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
local _, val = exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
return val
end
function sh_uci_set(config, section, option, val, commit)

View File

@ -1,11 +1,13 @@
local _M = {}
local function gh_release_url(self)
return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
--return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-release-api.json"
end
local function gh_pre_release_url(self)
return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
--return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
end
-- 排序顺序定义

View File

@ -159,9 +159,7 @@ function gen_outbound(flag, node, tag, proxy_table)
--max_version = "1.3",
ech = {
enabled = (node.ech == "1") and true or false,
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
},
utls = {
enabled = (node.utls == "1" or node.reality == "1") and true or false,
@ -380,9 +378,7 @@ function gen_outbound(flag, node, tag, proxy_table)
} or nil,
ech = {
enabled = (node.ech == "1") and true or false,
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
}
}
}
@ -414,9 +410,7 @@ function gen_outbound(flag, node, tag, proxy_table)
} or nil,
ech = {
enabled = (node.ech == "1") and true or false,
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
}
}
}
@ -448,9 +442,7 @@ function gen_outbound(flag, node, tag, proxy_table)
insecure = (node.tls_allowInsecure == "1") and true or false,
ech = {
enabled = (node.ech == "1") and true or false,
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
}
}
}
@ -507,9 +499,7 @@ function gen_config_server(node)
if node.tls == "1" and node.ech == "1" then
tls.ech = {
enabled = true,
key = node.ech_key and split(node.ech_key:gsub("\\n", "\n"), "\n") or {},
pq_signature_schemes_enabled = (node.pq_signature_schemes_enabled == "1") and true or false,
dynamic_record_sizing_disabled = (node.dynamic_record_sizing_disabled == "1") and true or false,
key = node.ech_key and split(node.ech_key:gsub("\\n", "\n"), "\n") or {}
}
end

View File

@ -157,14 +157,16 @@ function gen_outbound(flag, node, tag, proxy_table)
tlsSettings = (node.stream_security == "tls") and {
serverName = node.tls_serverName,
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil,
echConfigList = (node.ech == "1") and node.ech_config or nil
} or nil,
realitySettings = (node.stream_security == "reality") and {
serverName = node.tls_serverName,
publicKey = node.reality_publicKey,
shortId = node.reality_shortId or "",
spiderX = node.reality_spiderX or "/",
fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome"
fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome",
mldsa65Verify = (node.use_mldsa65Verify == "1") and node.reality_mldsa65Verify or nil
} or nil,
rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and {
header = {
@ -463,7 +465,8 @@ function gen_config_server(node)
certificateFile = node.tls_certificateFile,
keyFile = node.tls_keyFile
}
}
},
echServerKeys = (node.ech == "1") and node.ech_key or nil
} or nil,
rawSettings = (node.transport == "raw" or node.transport == "tcp") and {
header = {
@ -548,7 +551,8 @@ function gen_config_server(node)
dest = node.reality_dest,
serverNames = node.reality_serverNames or {},
privateKey = node.reality_private_key,
shortIds = node.reality_shortId or ""
shortIds = node.reality_shortId or "",
mldsa65Seed = (node.use_mldsa65Seed == "1") and node.reality_mldsa65Seed or nil
} or nil
end
end

View File

@ -286,6 +286,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
@ -294,6 +295,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
params += opt.query("ech", dom_prefix + "ech_config");
}
if (opt.get(dom_prefix + "shadowtls")?.checked) {
@ -461,6 +464,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
@ -470,6 +474,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
params += opt.query("ech", dom_prefix + "ech_config");
}
params += "#" + encodeURI(v_alias.value);
@ -529,6 +534,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
@ -538,6 +544,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
params += opt.query("ech", dom_prefix + "ech_config");
}
params += "#" + encodeURI(v_alias.value);
if (params[0] == "&") {
@ -968,6 +975,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'utls', true);
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
}
opt.set(dom_prefix + 'ech', !!queryParam.ech);
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
}
if (queryParam.security == "reality") {
@ -983,6 +992,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
}
}
@ -1347,6 +1358,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'utls', true);
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
}
opt.set(dom_prefix + 'ech', !!queryParam.ech);
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
}
if (queryParam.security == "reality") {
@ -1362,6 +1375,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
}
}

View File

@ -3,6 +3,8 @@ local api = require "luci.passwall.api"
-%>
<script type="text/javascript">
//<![CDATA[
var appname = "<%= api.appname %>"
function confirmDeleteNode(remark) {
if (!confirm("<%:Delete the subscribed node%>: " + remark + " ?"))
return false;
@ -34,5 +36,76 @@ local api = require "luci.passwall.api"
});
return false;
}
function ManualSubscribe(sectionId) {
var urlInput = document.querySelector("input[name='cbid." + appname + "." + sectionId + ".url']");
var currentUrl = urlInput ? urlInput.value.trim() : "";
if (!currentUrl) {
alert("<%:Subscribe URL cannot be empty.%>");
return;
}
fetch('<%= api.url("subscribe_manual") %>?section='
+ encodeURIComponent(sectionId)
+ '&url='
+ encodeURIComponent(currentUrl))
.then(response => response.json())
.then(data => {
if (!data.success) {
alert(data.msg || "Operation failed");
} else {
window.location.href = '<%= api.url("log") %>'
}
});
}
function ManualSubscribeAll() {
var sectionIds = [];
var urls = [];
var table = document.getElementById("cbi-" + appname + "-subscribe_list");
var editBtns = table ? table.getElementsByClassName("cbi-button cbi-button-edit") : [];
for (var i = 0; i < editBtns.length; i++) {
var btn = editBtns[i];
var onclickStr = btn.getAttribute("onclick");
if (!onclickStr) continue;
var id = onclickStr.substring(onclickStr.lastIndexOf('/') + 1, onclickStr.length - 1);
if (!id) continue;
var urlInput = document.querySelector("input[name='cbid." + appname + "." + id + ".url']");
var currentUrl = urlInput ? urlInput.value.trim() : "";
if (!currentUrl) {
alert("<%:Subscribe URL cannot be empty.%>");
return;
}
sectionIds.push(id);
urls.push(currentUrl);
}
if (sectionIds.length === 0) {
//alert("No subscriptions found.");
return;
}
var params = new URLSearchParams();
params.append("sections", sectionIds.join(","));
params.append("urls", urls.join(","));
fetch('<%= api.url("subscribe_manual_all") %>', {
method: 'POST',
body: params
})
.then(response => response.json())
.then(data => {
if (!data.success) {
alert(data.msg || "Operation failed");
} else {
window.location.href = '<%= api.url("log") %>'
}
});
}
//]]>
</script>

View File

@ -445,7 +445,7 @@ msgstr "负载均衡策略"
msgid "Fallback Node"
msgstr "后备节点"
msgid "Use Custome Probe URL"
msgid "Use Custom Probe URL"
msgstr "使用自定义探测网址"
msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL."
@ -1072,8 +1072,14 @@ msgstr "订阅网址"
msgid "Subscribe URL Access Method"
msgstr "订阅网址访问方式"
msgid "Please input the subscription url first, save and submit before manual subscription."
msgstr "请输入订阅网址保存应用后再手动订阅。"
msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically."
msgstr "新增订阅请先保存并应用后再手动订阅;如仅修改订阅地址,可直接手动订阅,系统将自动保存。"
msgid "Please save and apply before manually subscribing."
msgstr "请先保存并应用后再手动订阅。"
msgid "Subscribe URL cannot be empty."
msgstr "订阅网址不能为空。"
msgid "Subscribe via proxy"
msgstr "通过代理订阅"
@ -1706,16 +1712,10 @@ msgid "Protocol parameter. Enable length block encryption."
msgstr "协议参数。启用长度块加密。"
msgid "ECH Config"
msgstr "ECH 密钥"
msgid "ECH Key"
msgstr "ECH 配置"
msgid "PQ signature schemes"
msgstr "后量子对等证书签名方案"
msgid "Disable adaptive sizing of TLS records"
msgstr "禁用 TLS 记录的自适应大小调整"
msgid "ECH Key"
msgstr "ECH 密钥"
msgid "Enable Multipath TCP, need to be enabled in both server and client configuration."
msgstr "启用 Multipath TCP需在服务端和客户端配置中同时启用。"

View File

@ -8,7 +8,3 @@
120.53.53.53
180.184.1.1
180.184.2.2
203.208.39.192/28
203.208.40.0/23
34.149.0.0/16
72.18.83.0/24

View File

@ -820,11 +820,17 @@ local function processData(szType, content, add_mode, add_from)
result.utls = "1"
result.fingerprint = params.fp
end
if params.ech and params.ech ~= "" then
result.ech = "1"
result.ech_config = params.ech
end
if params.security == "reality" then
result.reality = "1"
result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
result.reality_mldsa65Verify = params.pqv or nil
end
end
params.allowinsecure = params.allowinsecure or params.insecure
@ -1196,11 +1202,17 @@ local function processData(szType, content, add_mode, add_from)
result.utls = "1"
result.fingerprint = params.fp
end
if params.ech and params.ech ~= "" then
result.ech = "1"
result.ech_config = params.ech
end
if params.security == "reality" then
result.reality = "1"
result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
result.reality_mldsa65Verify = params.pqv or nil
end
end
@ -1913,7 +1925,6 @@ local execute = function()
local raw_data = api.trim(stdout)
local old_md5 = value.md5 or ""
local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "")
os.remove(tmp_file)
if not manual_sub and old_md5 == new_md5 then
log('订阅:【' .. remark .. '】没有变化,无需更新。')
else
@ -1924,6 +1935,7 @@ local execute = function()
fail_list[#fail_list + 1] = value
end
end
luci.sys.call("rm -f " .. tmp_file)
allowInsecure_default = nil
filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
filter_keyword_discard_list_default = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}