mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-17 21:03:30 +00:00
luci-app-ssr-plus: optimize subscribe script and fix ssd subscribe (#2846)
This commit is contained in:
parent
89b72b7ad9
commit
2194a78deb
@ -10,8 +10,11 @@ require 'luci.sys'
|
||||
|
||||
-- these global functions are accessed all the time by the event handler
|
||||
-- so caching them is worth the effort
|
||||
local luci = luci
|
||||
local tinsert = table.insert
|
||||
local ssub, slen, schar, srep, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.rep, string.byte, string.format, string.gsub
|
||||
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
|
||||
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
|
||||
local b64decode = nixio.bin.b64decode
|
||||
local cache = {}
|
||||
local nodeResult = setmetatable({}, { __index = cache }) -- update result
|
||||
local name = 'shadowsocksr'
|
||||
@ -74,17 +77,15 @@ local function md5(content)
|
||||
return trim(stdout)
|
||||
end
|
||||
-- base64
|
||||
local function base64Decode(text, safe)
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
if not text then return '' end
|
||||
text = text:gsub("%z", "")
|
||||
if safe then
|
||||
text = text:gsub("_", "/")
|
||||
text = text:gsub("-", "+")
|
||||
local mod4 = #text % 4
|
||||
text = text .. string.sub('====', mod4 + 1)
|
||||
end
|
||||
local result = nixio.bin.b64decode(text)
|
||||
text = text:gsub("_", "/")
|
||||
text = text:gsub("-", "+")
|
||||
local mod4 = #text % 4
|
||||
text = text .. string.sub('====', mod4 + 1)
|
||||
local result = b64decode(text)
|
||||
if result then
|
||||
return result:gsub("%z", "")
|
||||
else
|
||||
@ -104,13 +105,7 @@ local function processData(szType, content)
|
||||
kcp_port = 0,
|
||||
kcp_param = '--nocomp'
|
||||
}
|
||||
local hash
|
||||
if type(content) == 'string' then
|
||||
hash = md5(content)
|
||||
else
|
||||
hash = md5(luci.jsonc.stringify(content))
|
||||
end
|
||||
result.hashkey = hash
|
||||
result.hashkey = type(content) == 'string' and md5(content) or md5(jsonStringify(content))
|
||||
if szType == 'ssr' then
|
||||
local dat = split(content, "/\\?")
|
||||
local hostInfo = split(dat[1], ':')
|
||||
@ -119,21 +114,21 @@ local function processData(szType, content)
|
||||
result.protocol = hostInfo[3]
|
||||
result.encrypt_method = hostInfo[4]
|
||||
result.obfs = hostInfo[5]
|
||||
result.password = base64Decode(hostInfo[6], true)
|
||||
result.password = base64Decode(hostInfo[6])
|
||||
local params = {}
|
||||
for k, v in pairs(split(dat[2], '&')) do
|
||||
for _, v in pairs(split(dat[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
params[t[1]] = t[2]
|
||||
end
|
||||
result.obfs_param = base64Decode(params.bfsparam, true)
|
||||
result.protocol_param = base64Decode(params.protoparam, true)
|
||||
local group = base64Decode(params.group, true)
|
||||
result.obfs_param = base64Decode(params.bfsparam)
|
||||
result.protocol_param = base64Decode(params.protoparam)
|
||||
local group = base64Decode(params.group)
|
||||
if group then
|
||||
result.alias = "[" .. group .. "] "
|
||||
end
|
||||
result.alias = result.alias .. base64Decode(params.remarks, true)
|
||||
result.alias = result.alias .. base64Decode(params.remarks)
|
||||
elseif szType == 'vmess' then
|
||||
local info = luci.jsonc.parse(content)
|
||||
local info = jsonParse(content)
|
||||
result.type = 'v2ray'
|
||||
result.server = info.add
|
||||
result.server_port = info.port
|
||||
@ -143,32 +138,32 @@ local function processData(szType, content)
|
||||
result.alias = info.ps
|
||||
result.mux = 1
|
||||
result.concurrency = 8
|
||||
if info.net == 'ws'then
|
||||
result.ws_host = info.host
|
||||
result.ws_path = info.path
|
||||
if info.net == 'ws' then
|
||||
result.ws_host = info.host
|
||||
result.ws_path = info.path
|
||||
end
|
||||
if info.net == 'h2'then
|
||||
result.h2_host = info.host
|
||||
result.h2_path = info.path
|
||||
if info.net == 'h2' then
|
||||
result.h2_host = info.host
|
||||
result.h2_path = info.path
|
||||
end
|
||||
if info.net == 'tcp'then
|
||||
result.tcp_guise = info.type
|
||||
result.http_host = info.host
|
||||
result.http_path = info.path
|
||||
if info.net == 'tcp' then
|
||||
result.tcp_guise = info.type
|
||||
result.http_host = info.host
|
||||
result.http_path = info.path
|
||||
end
|
||||
if info.net == 'kcp'then
|
||||
result.kcp_guise = info.type
|
||||
result.mtu = 1350
|
||||
result.tti = 50
|
||||
result.uplink_capacity = 5
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
if info.net == 'kcp' then
|
||||
result.kcp_guise = info.type
|
||||
result.mtu = 1350
|
||||
result.tti = 50
|
||||
result.uplink_capacity = 5
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
end
|
||||
if info.net == 'quic'then
|
||||
result.quic_guise = info.type
|
||||
result.quic_key = info.key
|
||||
result.quic_security = info.securty
|
||||
if info.net == 'quic' then
|
||||
result.quic_guise = info.type
|
||||
result.quic_key = info.key
|
||||
result.quic_security = info.securty
|
||||
end
|
||||
if not info.security then
|
||||
result.security = "auto"
|
||||
@ -187,9 +182,9 @@ local function processData(szType, content)
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
end
|
||||
local info = content:sub(1, idx_sp - 1)
|
||||
local hostInfo = split(base64Decode(info, true), "@")
|
||||
local hostInfo = split(base64Decode(info), "@")
|
||||
local host = split(hostInfo[2], ":")
|
||||
local userinfo = base64Decode(hostInfo[1], true)
|
||||
local userinfo = base64Decode(hostInfo[1])
|
||||
local method = userinfo:sub(1, userinfo:find(":") - 1)
|
||||
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
||||
result.alias = UrlDecode(alias)
|
||||
@ -199,7 +194,7 @@ local function processData(szType, content)
|
||||
local query = split(host[2], "/\\?")
|
||||
result.server_port = query[1]
|
||||
-- local params = {}
|
||||
-- for k, v in pairs(split(query[2], '&')) do
|
||||
-- for _, v in pairs(split(query[2], '&')) do
|
||||
-- local t = split(v, '=')
|
||||
-- params[t[1]] = t[2]
|
||||
-- end
|
||||
@ -217,8 +212,10 @@ local function processData(szType, content)
|
||||
result.encrypt_method_ss = content.encryption
|
||||
result.alias = "[" .. content.airport .. "] " .. content.remarks
|
||||
end
|
||||
if result.alias == ''then result.alias = result.server ..':'.. result.server_port end
|
||||
return result, hash
|
||||
if not result.alias then
|
||||
result.alias = result.server .. ':' .. result.server_port
|
||||
end
|
||||
return result
|
||||
end
|
||||
-- wget
|
||||
local function wget(url)
|
||||
@ -229,7 +226,6 @@ end
|
||||
local execute = function()
|
||||
-- exec
|
||||
do
|
||||
-- subscribe_url = {'https://www.google.comc'}
|
||||
if proxy == '0' then -- 不使用代理更新的话先暂停
|
||||
log('服务正在暂停')
|
||||
luci.sys.init.stop(name)
|
||||
@ -237,7 +233,7 @@ local execute = function()
|
||||
for k, url in ipairs(subscribe_url) do
|
||||
local raw = wget(url)
|
||||
if #raw > 0 then
|
||||
local node, szType
|
||||
local nodes, szType
|
||||
local groupHash = md5(url)
|
||||
cache[groupHash] = {}
|
||||
tinsert(nodeResult, {})
|
||||
@ -246,61 +242,61 @@ local execute = function()
|
||||
if raw:find('ssd://') then
|
||||
szType = 'ssd'
|
||||
local nEnd = select(2, raw:find('ssd://'))
|
||||
node = base64Decode(raw:sub(nEnd + 1, #raw), true)
|
||||
node = luci.jsonc.parse(node)
|
||||
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
|
||||
nodes = jsonParse(nodes)
|
||||
local extra = {
|
||||
airport = node.airport,
|
||||
port = node.port,
|
||||
encryption = node.encryption,
|
||||
password = node.password
|
||||
airport = nodes.airport,
|
||||
port = nodes.port,
|
||||
encryption = nodes.encryption,
|
||||
password = nodes.password
|
||||
}
|
||||
local servers = {}
|
||||
-- SS里面包着 干脆直接这样
|
||||
for _, server in ipairs(node.servers) do
|
||||
for _, server in ipairs(nodes.servers) do
|
||||
tinsert(servers, setmetatable(server, { __index = extra }))
|
||||
end
|
||||
node = servers
|
||||
nodes = servers
|
||||
else
|
||||
-- ssd 外的格式
|
||||
node = split(base64Decode(raw, true):gsub(" ", "\n"), "\n")
|
||||
nodes = split(base64Decode(raw):gsub(" ", "\n"), "\n")
|
||||
end
|
||||
for _, v in ipairs(node) do
|
||||
for _, v in ipairs(nodes) do
|
||||
if v then
|
||||
v = trim(v)
|
||||
local result, hash
|
||||
local result
|
||||
if szType == 'ssd' then
|
||||
result, hash = processData(szType, v)
|
||||
result = processData(szType, v)
|
||||
elseif not szType then
|
||||
local dat = split(v, "://")
|
||||
local node = trim(v)
|
||||
local dat = split(node, "://")
|
||||
if dat and dat[1] and dat[2] then
|
||||
if dat[1] == 'ss' then
|
||||
result, hash = processData(dat[1], dat[2])
|
||||
result = processData(dat[1], dat[2])
|
||||
else
|
||||
result, hash = processData(dat[1], base64Decode(dat[2], true))
|
||||
result = processData(dat[1], base64Decode(dat[2]))
|
||||
end
|
||||
end
|
||||
else
|
||||
log('跳过未知类型: ' .. szType)
|
||||
end
|
||||
-- log(hash, result)
|
||||
if hash or result then
|
||||
-- log(result)
|
||||
if result then
|
||||
if result.alias:find("过期时间") or
|
||||
result.alias:find("剩余流量") or
|
||||
result.alias:find("QQ群") or
|
||||
result.alias:find("官网") or
|
||||
result.server == ''
|
||||
not result.server
|
||||
then
|
||||
log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias)
|
||||
else
|
||||
log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
|
||||
result.grouphashkey = groupHash
|
||||
tinsert(nodeResult[index], result)
|
||||
cache[groupHash][hash] = nodeResult[index][#nodeResult[index]]
|
||||
cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
log('成功解析节点数量: ' ..#node)
|
||||
log('成功解析节点数量: ' ..#nodes)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -345,9 +341,9 @@ local execute = function()
|
||||
end
|
||||
end
|
||||
if firstServer then
|
||||
luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
|
||||
luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
|
||||
else
|
||||
luci.sys.call("/etc/init.d/" .. name .." stop > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
|
||||
luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
|
||||
end
|
||||
log('新增节点数量: ' ..add, '删除节点数量: ' .. del)
|
||||
log('更新成功服务正在启动')
|
||||
|
Loading…
Reference in New Issue
Block a user