mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-05 18:44:06 +08:00
update 2026-06-29 23:37:40
This commit is contained in:
1 parent
c8ceebd509
commit
f769dc4727
15 files changed
+1645
-1217
No files matched your search
@@ -29,6 +29,8 @@ local allow_insecure = ucic:get_first(name, 'server_subscribe', 'allow_insecure'
|
||||
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期/重置/套餐/剩余/网址/QQ群/官网/防失联/回国')
|
||||
local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '')
|
||||
local user_agent = ucic:get_first(name, 'server_subscribe', 'user_agent', 'v2rayN/9.99')
|
||||
-- 读取 enable_mihomo 配置
|
||||
local enable_mihomo = ucic:get_first(name, 'server_subscribe', 'enable_mihomo', '')
|
||||
local sub_convert = ucic:get_first(name, 'server_subscribe', 'sub_convert', '0')
|
||||
local convert_address = ucic:get_first(name, 'server_subscribe', 'convert_address', 'https://api.asailor.org/sub')
|
||||
local template_url = ucic:get_first(name, 'server_subscribe', 'template_url', '')
|
||||
@@ -44,8 +46,30 @@ local log = function(...)
|
||||
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
|
||||
end
|
||||
|
||||
-- 检查是否需要使用 Mihomo 订阅模式
|
||||
local function should_use_mihomo_mode()
|
||||
-- 如果 enable_mihomo == 1,使用 Mihomo 模式
|
||||
if enable_mihomo == "1" and has_mihomo then
|
||||
return true
|
||||
end
|
||||
-- 如果 enable_mihomo ~= 1,检查是否有其他可用核心
|
||||
if enable_mihomo ~= "1" then
|
||||
-- 有其他核心可用,使用传统模式
|
||||
if has_xray or has_ss_rust then
|
||||
return false
|
||||
end
|
||||
-- 没有其他核心,回退到 Mihomo 模式
|
||||
if has_mihomo then
|
||||
log("回退: Xray/ss-rust 不存在,使用 Mihomo 订阅模式")
|
||||
return true
|
||||
end
|
||||
end
|
||||
-- 默认:如果有 Mihomo 则使用 Mihomo 模式
|
||||
return has_mihomo
|
||||
end
|
||||
|
||||
local function preferred_ss_backend()
|
||||
if has_mihomo then
|
||||
if should_use_mihomo_mode() and has_mihomo then
|
||||
return "ss"
|
||||
end
|
||||
if has_ss_rust then
|
||||
@@ -54,6 +78,9 @@ local function preferred_ss_backend()
|
||||
if has_xray then
|
||||
return "v2ray"
|
||||
end
|
||||
if has_mihomo then
|
||||
return "ss"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -89,6 +116,7 @@ local encrypt_methods_ss = {
|
||||
"chacha20",
|
||||
"chacha20-ietf" ]]--
|
||||
}
|
||||
|
||||
-- 分割字符串
|
||||
local function split(full, sep)
|
||||
if full == nil or type(full) ~= "string" then
|
||||
@@ -117,6 +145,7 @@ local function split(full, sep)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- urlencode
|
||||
local function get_urlencode(c)
|
||||
return sformat("%%%02X", sbyte(c))
|
||||
@@ -136,6 +165,7 @@ end
|
||||
local function get_urldecode(h)
|
||||
return schar(tonumber(h, 16))
|
||||
end
|
||||
|
||||
local function UrlDecode(szText)
|
||||
return szText:gsub("+", " "):gsub("%%(%x%x)", get_urldecode)
|
||||
end
|
||||
@@ -269,12 +299,14 @@ local function parse_host_port(value, default_port)
|
||||
|
||||
return normalize_host(value), default_port
|
||||
end
|
||||
|
||||
-- md5
|
||||
local function md5(content)
|
||||
local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1')
|
||||
-- assert(nixio.errno() == 0)
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
-- base64 解码
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
@@ -296,6 +328,7 @@ local function base64Decode(text)
|
||||
return raw
|
||||
end
|
||||
end
|
||||
|
||||
-- base64 编码
|
||||
local function base64Encode(text)
|
||||
if not text or text == "" then
|
||||
@@ -309,6 +342,7 @@ local function base64Encode(text)
|
||||
return text
|
||||
end
|
||||
end
|
||||
|
||||
-- 检查数组(table)中是否存在某个字符值
|
||||
-- https://www.04007.cn/article/135.html
|
||||
local function checkTabValue(tab)
|
||||
@@ -318,6 +352,7 @@ local function checkTabValue(tab)
|
||||
end
|
||||
return revtab
|
||||
end
|
||||
|
||||
-- JSON完整性检查
|
||||
local function isCompleteJSON(str)
|
||||
-- 检查JSON格式
|
||||
@@ -349,7 +384,8 @@ local function processClashSubscription(url)
|
||||
return nil
|
||||
end
|
||||
|
||||
local alias = "Clash_" .. parsed.host
|
||||
local url_hash = string.sub(md5(url), 1, 8)
|
||||
local alias = "Clash_" .. parsed.host .. "_" .. url_hash
|
||||
local server_port = parsed.port or ((parsed.scheme == "http") and "80" or "443")
|
||||
local result = {
|
||||
type = "clash",
|
||||
@@ -796,6 +832,10 @@ local function can_group_into_mihomo(node)
|
||||
if not node then
|
||||
return false
|
||||
end
|
||||
-- 如果不使用 Mihomo 模式,返回 false
|
||||
if not should_use_mihomo_mode() then
|
||||
return false
|
||||
end
|
||||
if node.type == "ssr" or node.type == "ss" or node.type == "ss-rust" then
|
||||
return true
|
||||
end
|
||||
@@ -820,6 +860,11 @@ local function can_group_into_mihomo(node)
|
||||
end
|
||||
|
||||
local function buildMihomoSubscribeYaml(nodes, group_name)
|
||||
-- 如果不使用 Mihomo 模式,返回 nil
|
||||
if not should_use_mihomo_mode() then
|
||||
return nil, 0
|
||||
end
|
||||
|
||||
local proxies = {}
|
||||
local names = {}
|
||||
|
||||
@@ -943,6 +988,10 @@ local function processData(szType, content, cfgid)
|
||||
result.flag_obfs = "1"
|
||||
result.obfs_type = params.obfs
|
||||
result.salamander = params["obfs-password"] or params["obfs_password"]
|
||||
if params.obfs == "gecko" then
|
||||
result.obfs_MinPacketSize = params.minPacketSize or "512"
|
||||
result.obfs_MaxPacketSize = params.maxPacketSize or "1200"
|
||||
end
|
||||
end
|
||||
if params.allowInsecure or params.insecure then
|
||||
local insecure = params.allowInsecure or params.insecure
|
||||
@@ -2386,6 +2435,10 @@ local function is_mihomo_subscribe_node(section)
|
||||
if not section then
|
||||
return false
|
||||
end
|
||||
-- 如果不使用 Mihomo 模式,返回 false
|
||||
if not should_use_mihomo_mode() then
|
||||
return false
|
||||
end
|
||||
if section.type == "clash" and section.clash_path and tostring(section.clash_path):match("%.mihomo%.yaml$") then
|
||||
return true
|
||||
end
|
||||
@@ -2413,7 +2466,7 @@ local function is_mihomo_subscribe_node(section)
|
||||
end
|
||||
|
||||
local function group_needs_mihomo_subscribe_refresh(groupHash)
|
||||
if not has_mihomo then
|
||||
if not should_use_mihomo_mode() then
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -2446,13 +2499,26 @@ local function preserve_unselected_groups(selected_hashes)
|
||||
end)
|
||||
end
|
||||
|
||||
-- 获取 groupHash 的公共函数(预留函数)
|
||||
local function get_group_hash(url, fetch_url)
|
||||
if should_use_mihomo_mode() then
|
||||
return md5(fetch_url)
|
||||
else
|
||||
return md5(url)
|
||||
end
|
||||
end
|
||||
|
||||
local execute = function()
|
||||
local updated = false
|
||||
local selected_hashes = {}
|
||||
|
||||
for _, item in ipairs(subscribe_items) do
|
||||
local fetch_url = build_convert_url(item.url)
|
||||
selected_hashes[md5(fetch_url)] = true
|
||||
if should_use_mihomo_mode() then
|
||||
selected_hashes[md5(fetch_url)] = true
|
||||
else
|
||||
selected_hashes[md5(item.url)] = true
|
||||
end
|
||||
end
|
||||
|
||||
if target_subscribe_sid ~= "" then
|
||||
@@ -2462,24 +2528,33 @@ local execute = function()
|
||||
for _, item in ipairs(subscribe_items) do
|
||||
local url = item.url
|
||||
local fetch_url, converted = build_convert_url(url)
|
||||
local raw, new_md5 = curl(fetch_url, user_agent)
|
||||
local raw, new_md5
|
||||
local groupHash
|
||||
local yaml_removed_count = 0
|
||||
if isClashYAML(raw) then
|
||||
raw, yaml_removed_count = filterClashYamlRaw(raw)
|
||||
if yaml_removed_count and yaml_removed_count > 0 then
|
||||
new_md5 = md5_string(raw)
|
||||
|
||||
if should_use_mihomo_mode() then
|
||||
raw, new_md5 = curl(fetch_url, user_agent)
|
||||
if isClashYAML(raw) then
|
||||
raw, yaml_removed_count = filterClashYamlRaw(raw)
|
||||
if yaml_removed_count and yaml_removed_count > 0 then
|
||||
new_md5 = md5_string(raw)
|
||||
end
|
||||
end
|
||||
groupHash = md5(fetch_url)
|
||||
else
|
||||
raw, new_md5 = curl(url, user_agent)
|
||||
groupHash = md5(url)
|
||||
end
|
||||
|
||||
log("raw 长度: "..#raw)
|
||||
local groupHash = md5(fetch_url)
|
||||
local old_md5 = read_old_md5(groupHash)
|
||||
|
||||
log("处理订阅: " .. url)
|
||||
if converted then
|
||||
if should_use_mihomo_mode() and converted then
|
||||
log("使用订阅转换模板: " .. template_url)
|
||||
log("转换服务: " .. convert_address)
|
||||
end
|
||||
if yaml_removed_count and yaml_removed_count > 0 then
|
||||
if should_use_mihomo_mode() and yaml_removed_count and yaml_removed_count > 0 then
|
||||
log("Clash/Mihomo YAML 已按订阅过滤关键词移除节点数量: " .. tostring(yaml_removed_count))
|
||||
end
|
||||
log("groupHash: " .. groupHash)
|
||||
@@ -2489,110 +2564,111 @@ local execute = function()
|
||||
local backend_refresh = group_needs_ss_backend_refresh(groupHash)
|
||||
local mihomo_subscribe_refresh = group_needs_mihomo_subscribe_refresh(groupHash)
|
||||
local missing_saved_nodes = old_md5 and new_md5 == old_md5 and not group_has_saved_nodes(groupHash)
|
||||
|
||||
if #raw == 0 then
|
||||
log(url .. ': 获取内容为空')
|
||||
loadOldNodes(groupHash)
|
||||
elseif old_md5 and new_md5 == old_md5 and not backend_refresh and not mihomo_subscribe_refresh and not missing_saved_nodes then
|
||||
log("订阅未变化, 跳过无需更新的订阅: " .. url)
|
||||
-- 防止 diff 阶段误删未更新订阅节点
|
||||
loadOldNodes(groupHash)
|
||||
--ucic:foreach(name, uciType, function(s)
|
||||
-- if s.grouphashkey == groupHash and s.hashkey then
|
||||
-- cache[groupHash][s.hashkey] = s
|
||||
-- tinsert(nodeResult[index], s)
|
||||
-- end
|
||||
--end)
|
||||
log("订阅未变化, 跳过无需更新的订阅: " .. url)
|
||||
-- 防止 diff 阶段误删未更新订阅节点
|
||||
loadOldNodes(groupHash)
|
||||
--ucic:foreach(name, uciType, function(s)
|
||||
-- if s.grouphashkey == groupHash and s.hashkey then
|
||||
-- cache[groupHash][s.hashkey] = s
|
||||
-- tinsert(nodeResult[index], s)
|
||||
-- end
|
||||
--end)
|
||||
else
|
||||
if backend_refresh and old_md5 and new_md5 == old_md5 then
|
||||
log("检测到 SS 后端偏好变化,强制重建订阅节点: " .. url)
|
||||
end
|
||||
if mihomo_subscribe_refresh and old_md5 and new_md5 == old_md5 then
|
||||
log("检测到可迁移订阅节点,强制重建为 Mihomo 总节点: " .. url)
|
||||
end
|
||||
if missing_saved_nodes then
|
||||
log("订阅内容未变化但本地节点不存在,强制重建订阅节点: " .. url)
|
||||
end
|
||||
updated = true
|
||||
-- 保存更新后的 MD5 值到以 groupHash 为标识的临时文件中,用于下次订阅更新时进行对比
|
||||
write_new_md5(groupHash, new_md5)
|
||||
if backend_refresh and old_md5 and new_md5 == old_md5 then
|
||||
log("检测到 SS 后端偏好变化,强制重建订阅节点: " .. url)
|
||||
end
|
||||
if mihomo_subscribe_refresh and old_md5 and new_md5 == old_md5 then
|
||||
log("检测到可迁移订阅节点,强制重建为 Mihomo 总节点: " .. url)
|
||||
end
|
||||
if missing_saved_nodes then
|
||||
log("订阅内容未变化但本地节点不存在,强制重建订阅节点: " .. url)
|
||||
end
|
||||
updated = true
|
||||
-- 保存更新后的 MD5 值到以 groupHash 为标识的临时文件中,用于下次订阅更新时进行对比
|
||||
write_new_md5(groupHash, new_md5)
|
||||
|
||||
cache[groupHash] = {}
|
||||
tinsert(nodeResult, {})
|
||||
local index = #nodeResult
|
||||
local nodes, szType
|
||||
local is_clash_subscription = false
|
||||
cache[groupHash] = {}
|
||||
tinsert(nodeResult, {})
|
||||
local index = #nodeResult
|
||||
local nodes, szType
|
||||
local is_clash_subscription = false
|
||||
|
||||
if isClashYAML(raw) then
|
||||
is_clash_subscription = true
|
||||
local result = processClashSubscription(fetch_url)
|
||||
if result and check_filer(result) then
|
||||
log('过滤 Clash 总节点: ' .. result.alias)
|
||||
elseif result and not cache[groupHash][result.hashkey] then
|
||||
result.grouphashkey = groupHash
|
||||
table.insert(nodeResult[index], result)
|
||||
cache[groupHash][result.hashkey] = result
|
||||
log('成功导入 Clash 总节点: ' .. result.alias)
|
||||
else
|
||||
log('丢弃无效 Clash 总节点: ' .. url)
|
||||
end
|
||||
-- SSD 似乎是这种格式 ssd:// 开头的
|
||||
elseif raw:find('ssd://') then
|
||||
szType = 'ssd'
|
||||
local nEnd = select(2, raw:find('ssd://'))
|
||||
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
|
||||
nodes = jsonParse(nodes)
|
||||
local extra = {
|
||||
airport = nodes.airport,
|
||||
port = nodes.port,
|
||||
encryption = nodes.encryption,
|
||||
password = nodes.password
|
||||
}
|
||||
local servers = {}
|
||||
-- SS里面包着 干脆直接这样
|
||||
for _, server in ipairs(nodes.servers or {}) do
|
||||
tinsert(servers, setmetatable(server, {__index = extra}))
|
||||
end
|
||||
nodes = servers
|
||||
-- SS SIP008 直接使用 Json 格式
|
||||
elseif jsonParse(raw) then
|
||||
nodes = jsonParse(raw).servers or jsonParse(raw)
|
||||
if nodes[1] and nodes[1].server and nodes[1].method then
|
||||
szType = 'sip008'
|
||||
end
|
||||
-- 其他 base64 格式
|
||||
if isClashYAML(raw) then
|
||||
is_clash_subscription = true
|
||||
local result = processClashSubscription(fetch_url)
|
||||
if result and check_filer(result) then
|
||||
log('过滤 Clash 总节点: ' .. result.alias)
|
||||
elseif result and not cache[groupHash][result.hashkey] then
|
||||
result.grouphashkey = groupHash
|
||||
table.insert(nodeResult[index], result)
|
||||
cache[groupHash][result.hashkey] = result
|
||||
log('成功导入 Clash 总节点: ' .. result.alias)
|
||||
else
|
||||
-- ssd 外的格式
|
||||
nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n")
|
||||
log('丢弃无效 Clash 总节点: ' .. url)
|
||||
end
|
||||
-- SSD 似乎是这种格式 ssd:// 开头的
|
||||
elseif raw:find('ssd://') then
|
||||
szType = 'ssd'
|
||||
local nEnd = select(2, raw:find('ssd://'))
|
||||
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
|
||||
nodes = jsonParse(nodes)
|
||||
local extra = {
|
||||
airport = nodes.airport,
|
||||
port = nodes.port,
|
||||
encryption = nodes.encryption,
|
||||
password = nodes.password
|
||||
}
|
||||
local servers = {}
|
||||
-- SS里面包着 干脆直接这样
|
||||
for _, server in ipairs(nodes.servers or {}) do
|
||||
tinsert(servers, setmetatable(server, {__index = extra}))
|
||||
end
|
||||
nodes = servers
|
||||
-- SS SIP008 直接使用 Json 格式
|
||||
elseif jsonParse(raw) then
|
||||
nodes = jsonParse(raw).servers or jsonParse(raw)
|
||||
if nodes[1] and nodes[1].server and nodes[1].method then
|
||||
szType = 'sip008'
|
||||
end
|
||||
-- 其他 base64 格式
|
||||
else
|
||||
-- ssd 外的格式
|
||||
nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n")
|
||||
end
|
||||
|
||||
if not is_clash_subscription and not szType and type(nodes) == "table" then
|
||||
local anytls_nodes = {}
|
||||
local normal_nodes = {}
|
||||
for _, node in ipairs(nodes) do
|
||||
local line = trim(node or "")
|
||||
if line:match("^anytls://") then
|
||||
local parsed = parseAnytlsShare(line:gsub("^anytls://", ""))
|
||||
if parsed then
|
||||
table.insert(anytls_nodes, anytls_to_mihomo_node(parsed))
|
||||
end
|
||||
elseif line ~= "" then
|
||||
table.insert(normal_nodes, node)
|
||||
end
|
||||
end
|
||||
|
||||
if not is_clash_subscription and not szType and type(nodes) == "table" then
|
||||
local anytls_nodes = {}
|
||||
local normal_nodes = {}
|
||||
for _, node in ipairs(nodes) do
|
||||
local line = trim(node or "")
|
||||
if line:match("^anytls://") then
|
||||
local parsed = parseAnytlsShare(line:gsub("^anytls://", ""))
|
||||
if parsed then
|
||||
table.insert(anytls_nodes, anytls_to_mihomo_node(parsed))
|
||||
end
|
||||
elseif line ~= "" then
|
||||
table.insert(normal_nodes, node)
|
||||
end
|
||||
if #anytls_nodes > 0 then
|
||||
for _, parsed in ipairs(anytls_nodes) do
|
||||
table.insert(normal_nodes, parsed)
|
||||
end
|
||||
|
||||
if #anytls_nodes > 0 then
|
||||
for _, parsed in ipairs(anytls_nodes) do
|
||||
table.insert(normal_nodes, parsed)
|
||||
end
|
||||
end
|
||||
|
||||
nodes = normal_nodes
|
||||
end
|
||||
|
||||
-- 临时存储该订阅解析出的节点(带原始别名)
|
||||
local groupRawNodes = {}
|
||||
nodes = normal_nodes
|
||||
end
|
||||
|
||||
if not is_clash_subscription then
|
||||
-- 临时存储该订阅解析出的节点(带原始别名)
|
||||
local groupRawNodes = {}
|
||||
|
||||
if not is_clash_subscription then
|
||||
for _, v in ipairs(nodes) do
|
||||
if v and (type(v) == "table" or not string.match(v, "^%s*$")) then
|
||||
xpcall(function()
|
||||
@@ -2621,52 +2697,61 @@ local execute = function()
|
||||
log('跳过未知类型: ' .. szType)
|
||||
end
|
||||
-- log(result)
|
||||
if result then
|
||||
local filtered = check_filer(result)
|
||||
-- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
|
||||
local invalid = not result.server or not result.server_port
|
||||
or (result.type ~= "clash" and result.server == "127.0.0.1")
|
||||
or result.alias == "NULL"
|
||||
or (result.type ~= "clash" and result.server:match("[^0-9a-zA-Z%-_%.%s]"))
|
||||
or cache[groupHash][result.hashkey]
|
||||
if filtered then
|
||||
log('过滤节点: ' .. result.alias)
|
||||
elseif invalid then
|
||||
log('丢弃无效节点: ' .. result.alias)
|
||||
else
|
||||
-- 暂存节点
|
||||
table.insert(groupRawNodes, result)
|
||||
end
|
||||
if result then
|
||||
local filtered = check_filer(result)
|
||||
-- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
|
||||
local invalid = not result.server or not result.server_port
|
||||
or (result.type ~= "clash" and result.server == "127.0.0.1")
|
||||
or result.alias == "NULL"
|
||||
or (result.type ~= "clash" and result.server:match("[^0-9a-zA-Z%-_%.%s]"))
|
||||
or cache[groupHash][result.hashkey]
|
||||
if filtered then
|
||||
log('过滤节点: ' .. result.alias)
|
||||
elseif invalid then
|
||||
log('丢弃无效节点: ' .. result.alias)
|
||||
else
|
||||
-- 暂存节点
|
||||
table.insert(groupRawNodes, result)
|
||||
end
|
||||
end
|
||||
end, function(err)
|
||||
log(string.format("解析节点出错: %s\n原始数据: %s", tostring(err), tostring(v)))
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 对该组节点进行别名编号:重复节点加后缀,唯一节点不加
|
||||
-- 传统模式:对 groupRawNodes 进行组内编号
|
||||
if not should_use_mihomo_mode() then
|
||||
local freq = {}
|
||||
for _, node in ipairs(groupRawNodes) do
|
||||
local raw = node.raw_alias or ""
|
||||
freq[raw] = (freq[raw] or 0) + 1
|
||||
if raw ~= "" then
|
||||
freq[raw] = (freq[raw] or 0) + 1
|
||||
end
|
||||
end
|
||||
local aliasCount = {}
|
||||
for _, node in ipairs(groupRawNodes) do
|
||||
local raw = node.raw_alias or ""
|
||||
if freq[raw] > 1 then
|
||||
local count = (aliasCount[raw] or 0) + 1
|
||||
aliasCount[raw] = count
|
||||
node.alias = raw .. "_" .. count
|
||||
else
|
||||
node.alias = raw
|
||||
if raw ~= "" then
|
||||
if freq[raw] and freq[raw] > 1 then
|
||||
local count = (aliasCount[raw] or 0) + 1
|
||||
aliasCount[raw] = count
|
||||
node.alias = raw .. "_" .. count
|
||||
else
|
||||
node.alias = raw
|
||||
end
|
||||
end
|
||||
-- 清理临时字段
|
||||
node.raw_alias = nil
|
||||
end
|
||||
end
|
||||
|
||||
local mihomo_nodes = {}
|
||||
local legacy_nodes = {}
|
||||
local mihomo_nodes = {}
|
||||
local legacy_nodes = {}
|
||||
|
||||
-- 只有当 should_use_mihomo_mode() 为 true 时才尝试分组
|
||||
if should_use_mihomo_mode() then
|
||||
for _, node in ipairs(groupRawNodes) do
|
||||
if has_mihomo and can_group_into_mihomo(node) then
|
||||
mihomo_nodes[#mihomo_nodes + 1] = node
|
||||
@@ -2674,41 +2759,50 @@ local execute = function()
|
||||
legacy_nodes[#legacy_nodes + 1] = node
|
||||
end
|
||||
end
|
||||
else
|
||||
-- 传统模式:所有节点作为普通节点
|
||||
for _, node in ipairs(groupRawNodes) do
|
||||
legacy_nodes[#legacy_nodes + 1] = node
|
||||
end
|
||||
end
|
||||
|
||||
if #mihomo_nodes > 0 then
|
||||
local parsed_url = URL.parse(url)
|
||||
local alias = item.alias ~= "" and item.alias or ("Mihomo_" .. ((parsed_url and parsed_url.host) or groupHash))
|
||||
local local_path = string.format("%s/%s.mihomo.yaml", local_clash_dir, groupHash)
|
||||
local yaml, proxy_count = buildMihomoSubscribeYaml(mihomo_nodes, "Proxy")
|
||||
if #mihomo_nodes > 0 then
|
||||
local parsed_url = URL.parse(url)
|
||||
local alias = item.alias ~= "" and item.alias or ("Mihomo_" .. ((parsed_url and parsed_url.host) or groupHash))
|
||||
local local_path = string.format("%s/%s.mihomo.yaml", local_clash_dir, groupHash)
|
||||
local yaml, proxy_count = buildMihomoSubscribeYaml(mihomo_nodes, "Proxy")
|
||||
|
||||
if yaml and proxy_count > 0 then
|
||||
nixio.fs.mkdirr(local_clash_dir)
|
||||
nixio.fs.writefile(local_path, yaml)
|
||||
if yaml and proxy_count > 0 then
|
||||
nixio.fs.mkdirr(local_clash_dir)
|
||||
nixio.fs.writefile(local_path, yaml)
|
||||
|
||||
local result = processLocalClashSubscription(local_path, alias)
|
||||
if result and not cache[groupHash][result.hashkey] then
|
||||
result.grouphashkey = groupHash
|
||||
table.insert(nodeResult[index], result)
|
||||
cache[groupHash][result.hashkey] = result
|
||||
log('成功导入 Mihomo 总节点: ' .. result.alias .. ',包含节点数量: ' .. proxy_count)
|
||||
end
|
||||
else
|
||||
log('Mihomo 总节点生成失败,回退为普通订阅节点。')
|
||||
for _, node in ipairs(mihomo_nodes) do
|
||||
legacy_nodes[#legacy_nodes + 1] = node
|
||||
end
|
||||
local result = processLocalClashSubscription(local_path, alias)
|
||||
if result and not cache[groupHash][result.hashkey] then
|
||||
result.grouphashkey = groupHash
|
||||
table.insert(nodeResult[index], result)
|
||||
cache[groupHash][result.hashkey] = result
|
||||
log('成功导入 Mihomo 总节点: ' .. result.alias .. ',包含节点数量: ' .. proxy_count)
|
||||
end
|
||||
else
|
||||
log('Mihomo 总节点生成失败,回退为普通订阅节点。')
|
||||
for _, node in ipairs(mihomo_nodes) do
|
||||
legacy_nodes[#legacy_nodes + 1] = node
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, node in ipairs(legacy_nodes) do
|
||||
node.grouphashkey = groupHash
|
||||
table.insert(nodeResult[index], node)
|
||||
cache[groupHash][node.hashkey] = node
|
||||
end
|
||||
for _, node in ipairs(legacy_nodes) do
|
||||
node.grouphashkey = groupHash
|
||||
table.insert(nodeResult[index], node)
|
||||
cache[groupHash][node.hashkey] = node
|
||||
end
|
||||
|
||||
if not should_use_mihomo_mode() then
|
||||
log('成功解析节点数量: ' .. #groupRawNodes)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 输出日志并判断是否需要进行 diff
|
||||
if not updated then
|
||||
log("订阅未变化,无需更新节点信息。")
|
||||
@@ -2729,8 +2823,8 @@ local execute = function()
|
||||
del = del + 1
|
||||
else
|
||||
local dat = nodeResult[old.grouphashkey][old.hashkey]
|
||||
ucic:tset(name, old['.name'], dat)
|
||||
-- 标记一下
|
||||
ucic:tset(name, old['.name'], dat)
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
|
||||
end
|
||||
else
|
||||
@@ -2746,11 +2840,12 @@ local execute = function()
|
||||
end
|
||||
end
|
||||
end)
|
||||
-- 1615-1653 行为生成 sid
|
||||
|
||||
-- 生成 sid
|
||||
-- 记录已使用编号
|
||||
local used_sid = {}
|
||||
local next_sid = 1
|
||||
-- 扫描已有 section
|
||||
-- 检查已有 section
|
||||
ucic:foreach(name, uciType, function(s)
|
||||
local num = s[".name"]:match("^cfg(%x%x)") -- 提取两位十六进制序号
|
||||
if num then
|
||||
@@ -2820,6 +2915,14 @@ if subscribe_items and #subscribe_items > 0 then
|
||||
else
|
||||
log("当前订阅模式: 不通过代理订阅")
|
||||
end
|
||||
|
||||
-- 记录当前使用的订阅模式
|
||||
if should_use_mihomo_mode() then
|
||||
log("订阅模式: Mihomo 总节点模式")
|
||||
else
|
||||
log("订阅模式: 传统节点模式")
|
||||
end
|
||||
|
||||
local direct_bypass = create_direct_subscribe_bypass()
|
||||
if direct_bypass then
|
||||
direct_bypass:apply()
|
||||
|
||||
Reference in new issue
Block a user