update 2026-06-17 00:42:25

This commit is contained in:
action committed 2026-06-17 00:42:25 +08:00
1 parent 0bae71881b
commit 3e2b32ac97
30 files changed
+412 -298

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2 PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.6.3 PKG_VERSION:=26.6.16
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
@@ -320,15 +320,6 @@ o.rewrite_option = "method"
for a, t in ipairs(ss_method_list) do o:value(t) end for a, t in ipairs(ss_method_list) do o:value(t) end
o:depends({ [_n("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, _n("iv_check"), translate("IV Check"))
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-128-gcm" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-256-gcm" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "chacha20-poly1305" })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "xchacha20-poly1305" })
o = s:option(Flag, _n("uot"), translate("UDP over TCP"))
o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(ListValue, _n("flow"), translate("flow")) o = s:option(ListValue, _n("flow"), translate("flow"))
o.default = "" o.default = ""
o:value("", translate("Disable")) o:value("", translate("Disable"))
@@ -420,7 +411,6 @@ o:value("http/1.1")
o:value("h2,http/1.1") o:value("h2,http/1.1")
o:value("h3,h2,http/1.1") o:value("h3,h2,http/1.1")
o:depends({ [_n("tls")] = true, [_n("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "hysteria2" })
-- o = s:option(Value, _n("minversion"), translate("minversion")) -- o = s:option(Value, _n("minversion"), translate("minversion"))
-- o.default = "1.3" -- o.default = "1.3"
@@ -772,11 +762,6 @@ o.default = 0
o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration."))
o.default = 0 o.default = 0
o = s:option(Value, _n("preconns"), translate("Pre-connections"), translate("Number of early established connections to reduce latency."))
o.datatype = "uinteger"
o.placeholder = 0
o:depends({ [_n("protocol")] = "vless" })
o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve"), translate("If the node address is a domain name, this DNS will be used for resolution.")) o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve"), translate("If the node address is a domain name, this DNS will be used for resolution."))
o:value("", translate("Auto")) o:value("", translate("Auto"))
o:value("tcp", "TCP") o:value("tcp", "TCP")
@@ -97,9 +97,6 @@ o.rewrite_option = "method"
for a, t in ipairs(x_ss_method_list) do o:value(t) end for a, t in ipairs(x_ss_method_list) do o:value(t) end
o:depends({ [_n("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(Flag, _n("iv_check"), translate("IV Check"))
o:depends({ [_n("protocol")] = "shadowsocks" })
o = s:option(ListValue, _n("ss_network"), translate("Transport")) o = s:option(ListValue, _n("ss_network"), translate("Transport"))
o.default = "tcp,udp" o.default = "tcp,udp"
o:value("tcp", "TCP") o:value("tcp", "TCP")
@@ -232,7 +229,6 @@ o:value("http/1.1")
o:value("h2,http/1.1") o:value("h2,http/1.1")
o:value("h3,h2,http/1.1") o:value("h3,h2,http/1.1")
o:depends({ [_n("tls")] = true, [_n("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65")) o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65"))
o.default = "0" o.default = "0"
+10 -14
View File
@@ -1611,27 +1611,23 @@ end
function parse_realm_uri(uri) function parse_realm_uri(uri)
if type(uri) ~= "string" then return nil end if type(uri) ~= "string" then return nil end
-- realm://token@server/realm_id?query -- realm[+http]://token@server/realm_id?query
local token, server_url, realm_id, query = trim(uri):match("^realm://([^@]+)@([^/]+)/([^?]*)%??(.*)$") local scheme, token, server_url, realm_id, query = trim(uri):match("^(realm%+http|realm)://([^@]+)@([^/]+)/([^?]*)%??(.*)$")
if not token or not server_url or not realm_id then return nil end if not scheme or not token or not server_url or not realm_id then return nil end
realm_id = realm_id:gsub("/+$", "") realm_id = realm_id:gsub("/+$", "")
local realm = { local realm = {
scheme = scheme,
token = token, token = token,
server_url = server_url, server_url = server_url,
realm_id = realm_id realm_id = realm_id
} }
-- 解析 query 中的 stun= -- Parse stun= in the query
if query and query ~= "" then local stun_servers
local stun_servers = {} for value in (query or ""):gmatch("[?&]?[Ss][Tt][Uu][Nn]=([^&]+)") do
for key, value in query:gmatch("([^&=?]+)=([^&]+)") do if not stun_servers then stun_servers = {} end
if key == "stun" and value ~= "" then stun_servers[#stun_servers + 1] = value
stun_servers[#stun_servers + 1] = value
end
end
if #stun_servers > 0 then
realm.stun_servers = stun_servers
end
end end
realm.stun_servers = stun_servers
return realm return realm
end end
@@ -64,7 +64,8 @@ function gen_config(var)
server_host = api.get_ipv6_full(server_host) server_host = api.get_ipv6_full(server_host)
end end
local server = server_host .. ":" .. ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-") local port_hop = ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-")
local server = server_host .. ":" .. (port_hop ~= "" and port_hop or "443")
local config = { local config = {
server = (function() server = (function()
@@ -617,8 +617,9 @@ function gen_outbound(flag, node, tag, proxy_table)
result.server_port = nil result.server_port = nil
local realm = api.parse_realm_uri(node.hysteria2_realm_url) local realm = api.parse_realm_uri(node.hysteria2_realm_url)
if realm then if realm then
realm.server_url = realm.server_url and "https://" .. realm.server_url or nil realm.server_url = (realm.scheme == "realm+http" and "http://" or "https://") .. realm.server_url
realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun
realm.scheme = nil
return realm return realm
end end
return nil return nil
@@ -959,8 +960,9 @@ function gen_config_server(node)
realm = node.hysteria2_realms and (function() realm = node.hysteria2_realms and (function()
local realm = api.parse_realm_uri(node.hysteria2_realm_url) local realm = api.parse_realm_uri(node.hysteria2_realm_url)
if realm then if realm then
realm.server_url = realm.server_url and "https://" .. realm.server_url or nil realm.server_url = (realm.scheme == "realm+http" and "http://" or "https://") .. realm.server_url
realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun
realm.scheme = nil
realm.stun_domain_resolver = "direct" realm.stun_domain_resolver = "direct"
return realm return realm
end end
@@ -1797,13 +1799,12 @@ function gen_config(var)
end end
end end
table.insert(route.rules, {
action = "route",
ip_is_private = true,
outbound = "direct"
})
if COMMON.default_outbound_tag then if COMMON.default_outbound_tag then
table.insert(route.rules, {
action = "route",
port_range = { "0:65535" },
outbound = COMMON.default_outbound_tag
})
route.final = COMMON.default_outbound_tag route.final = COMMON.default_outbound_tag
end end
@@ -285,21 +285,22 @@ function gen_outbound(flag, node, tag, proxy_table)
local finalmask = {} local finalmask = {}
local TP = node.transport local TP = node.transport
if TP == "mkcp" then if TP == "mkcp" then
local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", local map = {none = "none", srtp = "srtp", utp = "utp", ["wechat-video"] = "wechat",
dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} dtls = "dtls", wireguard = "wireguard", dns = "dns"}
local udp = {} local udp = {}
if node.mkcp_guise and node.mkcp_guise ~= "none" then if node.mkcp_guise and node.mkcp_guise ~= "none" then
local g = { type = map[node.mkcp_guise] } local g = { type = "mkcp-legacy" }
g.settings = { header = map[node.mkcp_guise] }
if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then
g.settings = { domain = node.mkcp_domain } g.settings.value = node.mkcp_domain
end end
udp[#udp+1] = g udp[#udp+1] = g
end end
local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } local s = { type = "mkcp-legacy" }
if node.mkcp_seed and node.mkcp_seed ~= "" then if node.mkcp_seed and node.mkcp_seed ~= "" then
c.settings = { password = node.mkcp_seed } s.settings = { value = node.mkcp_seed }
end end
udp[#udp+1] = c udp[#udp+1] = s
finalmask.udp = udp finalmask.udp = udp
elseif TP == "hysteria" then elseif TP == "hysteria" then
local udp = {} local udp = {}
@@ -317,9 +318,7 @@ function gen_outbound(flag, node, tag, proxy_table)
local realm = api.parse_realm_uri(node.hysteria2_realm_url) local realm = api.parse_realm_uri(node.hysteria2_realm_url)
local url, stun local url, stun
if realm then if realm then
if realm.token and realm.server_url and realm.realm_id then url = realm.scheme .. "://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id
url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id
end
stun = realm.stun_servers or node.hysteria2_realm_stun stun = realm.stun_servers or node.hysteria2_realm_stun
end end
local r = { local r = {
@@ -386,43 +385,18 @@ function gen_outbound(flag, node, tag, proxy_table)
end)() end)()
} or nil, } or nil,
settings = { settings = {
vnext = (node.protocol == "vmess" or node.protocol == "vless") and { address = (node.protocol == "wireguard") and node.wireguard_local_address or node.address,
{ port = tonumber(node.port),
address = node.address, id = (node.protocol == "vmess" or node.protocol == "vless") and node.uuid or nil,
port = tonumber(node.port), encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil,
users = { flow = (node.protocol == "vless" and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none"))
{ and node.flow and node.flow ~= "") and node.flow or nil,
id = node.uuid, security = (node.protocol == "vmess") and node.security or nil,
level = 0, user = (node.protocol == "socks" or node.protocol == "http") and node.username or nil,
security = (node.protocol == "vmess") and node.security or nil, pass = (node.protocol == "socks" or node.protocol == "http") and node.password or nil,
testpre = (node.protocol == "vless") and tonumber(node.preconns) or nil, password = (node.protocol == "shadowsocks" or node.protocol == "trojan") and node.password or nil,
encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil, method = (node.protocol == "shadowsocks") and ((node.method == "chacha20-ietf-poly1305" and "chacha20-poly1305") or
flow = (node.protocol == "vless" (node.method == "xchacha20-ietf-poly1305" and "xchacha20-poly1305") or (node.method ~= "" and node.method) or nil) or nil,
and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none"))
and node.flow and node.flow ~= "") and node.flow or nil
}
}
}
} or nil,
servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks" or node.protocol == "trojan") and {
{
address = node.address,
port = tonumber(node.port),
method = (node.method == "chacha20-ietf-poly1305" and "chacha20-poly1305") or
(node.method == "xchacha20-ietf-poly1305" and "xchacha20-poly1305") or
(node.method ~= "" and node.method) or nil,
ivCheck = (node.protocol == "shadowsocks") and node.iv_check == "1" or nil,
uot = (node.protocol == "shadowsocks") and node.uot == "1" or nil,
password = node.password or "",
users = (node.username and node.password) and {
{
user = node.username,
pass = node.password
}
} or nil
}
} or nil,
address = (node.protocol == "wireguard" and node.wireguard_local_address) or (node.protocol == "hysteria" and node.address) or nil,
secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil, secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil,
peers = (node.protocol == "wireguard") and { peers = (node.protocol == "wireguard") and {
{ {
@@ -434,13 +408,13 @@ function gen_outbound(flag, node, tag, proxy_table)
} or nil, } or nil,
mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil, mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil,
reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil, reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil,
port = (node.protocol == "hysteria" and node.port) and tonumber(node.port) or nil, version = (node.protocol == "hysteria") and 2 or nil,
version = node.protocol == "hysteria" and 2 or nil level = 0
} }
} }
if node.protocol == "wireguard" then if node.protocol == "wireguard" then
result.settings.kernelMode = false result.settings.noKernelTun = true
if node.finalmask and node.finalmask ~= "" then if node.finalmask and node.finalmask ~= "" then
local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask))
if ok and type(fm) == "table" then if ok and type(fm) == "table" then
@@ -561,7 +535,6 @@ function gen_config_server(node)
settings = { settings = {
method = node.method, method = node.method,
password = node.password, password = node.password,
ivCheck = ("1" == node.iv_check) and true or false,
network = node.ss_network or "TCP,UDP" network = node.ss_network or "TCP,UDP"
} }
elseif node.protocol == "trojan" then elseif node.protocol == "trojan" then
@@ -740,21 +713,22 @@ function gen_config_server(node)
finalmask = (function() finalmask = (function()
local finalmask = {} local finalmask = {}
if node.transport == "mkcp" then if node.transport == "mkcp" then
local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", local map = {none = "none", srtp = "srtp", utp = "utp", ["wechat-video"] = "wechat",
dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} dtls = "dtls", wireguard = "wireguard", dns = "dns"}
local udp = {} local udp = {}
if node.mkcp_guise and node.mkcp_guise ~= "none" then if node.mkcp_guise and node.mkcp_guise ~= "none" then
local g = { type = map[node.mkcp_guise] } local g = { type = "mkcp-legacy" }
g.settings = { header = map[node.mkcp_guise] }
if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then
g.settings = { domain = node.mkcp_domain } g.settings.value = node.mkcp_domain
end end
udp[#udp+1] = g udp[#udp+1] = g
end end
local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } local s = { type = "mkcp-legacy" }
if node.mkcp_seed and node.mkcp_seed ~= "" then if node.mkcp_seed and node.mkcp_seed ~= "" then
c.settings = { password = node.mkcp_seed } s.settings = { value = node.mkcp_seed }
end end
udp[#udp+1] = c udp[#udp+1] = s
finalmask.udp = udp finalmask.udp = udp
elseif node.transport == "hysteria" then elseif node.transport == "hysteria" then
local udp = {} local udp = {}
@@ -772,9 +746,7 @@ function gen_config_server(node)
local realm = api.parse_realm_uri(node.hysteria2_realm_url) local realm = api.parse_realm_uri(node.hysteria2_realm_url)
local url, stun local url, stun
if realm then if realm then
if realm.token and realm.server_url and realm.realm_id then url = realm.scheme .. "://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id
url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id
end
stun = realm.stun_servers or node.hysteria2_realm_stun stun = realm.stun_servers or node.hysteria2_realm_stun
end end
local r = { local r = {
@@ -1524,7 +1496,7 @@ function gen_config(var)
outboundTag = default_outboundTag, outboundTag = default_outboundTag,
} }
if node.domainStrategy == "IPIfNonMatch" then if node.domainStrategy == "IPIfNonMatch" then
rule.ip = { "0.0.0.0/0", "::/0" } rule.port = "1-65535"
else else
rule.network = "tcp,udp" rule.network = "tcp,udp"
end end
@@ -1718,7 +1690,8 @@ function gen_config(var)
}) })
end end
end end
local dns_outbound
if dns_listen_port then if dns_listen_port then
table.insert(inbounds, { table.insert(inbounds, {
listen = "127.0.0.1", listen = "127.0.0.1",
@@ -1775,12 +1748,13 @@ function gen_config(var)
} }
} }
local type_dns = direct_type_dns local type_dns = direct_type_dns
table.insert(outbounds, { dns_outbound = {
tag = "dns-out", tag = "dns-out",
protocol = "dns", protocol = "dns",
proxySettings = type_dns.proxySettings, proxySettings = type_dns.proxySettings,
settings = type_dns.settings settings = type_dns.settings
}) }
table.insert(outbounds, dns_outbound)
table.insert(routing.rules, 1, { table.insert(routing.rules, 1, {
inboundTag = { inboundTag = {
"dns-in" "dns-in"
@@ -1815,6 +1789,7 @@ function gen_config(var)
end end
-- Shunt rule DNS logic -- Shunt rule DNS logic
local dns_out_rules = {}
if dns_domain_rules and #dns_domain_rules > 0 then if dns_domain_rules and #dns_domain_rules > 0 then
for index, value in ipairs(dns_domain_rules) do for index, value in ipairs(dns_domain_rules) do
if value.domain and value.outboundTag then if value.domain and value.outboundTag then
@@ -1834,19 +1809,19 @@ function gen_config(var)
end end
end end
end end
local dns_block = true -- If you do not want the blackhole rule to use DNS routing, please change it to `nil` or do not assign a value.
if dns_outboundTag == "blackhole" then if dns_outboundTag == "blackhole" then
if dns_block then table.insert(dns_out_rules, {
local dns_block_mode = "Hosts" -- use the Hosts mode to block. action = "return",
if dns_block_mode == "Hosts" then rCode = 0,
for d_i, d_k in ipairs(value.domain) do domain = api.clone(value.domain)
dns.hosts[d_k] = "0.0.0.0" })
end dns_server = nil
dns_server = nil else
end table.insert(dns_out_rules, {
else action = "hijack",
dns_server = nil qType = "1,28",
end domain = api.clone(value.domain)
})
end end
if dns_server then if dns_server then
dns_server.finalQuery = true dns_server.finalQuery = true
@@ -1861,6 +1836,11 @@ function gen_config(var)
end end
end end
end end
if dns_outbound and #dns_out_rules > 0 then
for i = #dns_out_rules, 1, -1 do
table.insert(dns_outbound.settings.rules, 1, dns_out_rules[i])
end
end
end end
end end
-9
View File
@@ -1251,9 +1251,6 @@ msgstr "پاک کردن گزارش‌ها"
msgid "Password" msgid "Password"
msgstr "رمز عبور" msgstr "رمز عبور"
msgid "IV Check"
msgstr "بررسی IV"
msgid "UDP over TCP" msgid "UDP over TCP"
msgstr "UDP بر روی TCP" msgstr "UDP بر روی TCP"
@@ -1266,12 +1263,6 @@ msgstr "پورت محلی"
msgid "Fast Open" msgid "Fast Open"
msgstr "بازگشایی سریع (Fast Open)" msgstr "بازگشایی سریع (Fast Open)"
msgid "Pre-connections"
msgstr "پیش‌اتصالات"
msgid "Number of early established connections to reduce latency."
msgstr "تعداد اتصالات از پیش برقرار شده برای کاهش تاخیر."
msgid "plugin" msgid "plugin"
msgstr "افزونه" msgstr "افزونه"
-9
View File
@@ -1252,9 +1252,6 @@ msgstr "Очистить журнал"
msgid "Password" msgid "Password"
msgstr "Пароль" msgstr "Пароль"
msgid "IV Check"
msgstr "Проверка IV"
msgid "UDP over TCP" msgid "UDP over TCP"
msgstr "UDP через TCP" msgstr "UDP через TCP"
@@ -1267,12 +1264,6 @@ msgstr "Локальный порт"
msgid "Fast Open" msgid "Fast Open"
msgstr "Fast Open" msgstr "Fast Open"
msgid "Pre-connections"
msgstr "Предварительные соединения"
msgid "Number of early established connections to reduce latency."
msgstr "Количество заранее установленных соединений для снижения задержки."
msgid "plugin" msgid "plugin"
msgstr "Плагин" msgstr "Плагин"
-9
View File
@@ -1243,9 +1243,6 @@ msgstr "清空日志"
msgid "Password" msgid "Password"
msgstr "密码" msgstr "密码"
msgid "IV Check"
msgstr "IV 检查"
msgid "UDP over TCP" msgid "UDP over TCP"
msgstr "TCP 封装 UDP" msgstr "TCP 封装 UDP"
@@ -1258,12 +1255,6 @@ msgstr "本地端口"
msgid "Fast Open" msgid "Fast Open"
msgstr "快速打开" msgstr "快速打开"
msgid "Pre-connections"
msgstr "预连接"
msgid "Number of early established connections to reduce latency."
msgstr "预连接的数量,用于降低延迟。"
msgid "plugin" msgid "plugin"
msgstr "插件" msgstr "插件"
-9
View File
@@ -1243,9 +1243,6 @@ msgstr "清空日誌"
msgid "Password" msgid "Password"
msgstr "密碼" msgstr "密碼"
msgid "IV Check"
msgstr "IV 檢查"
msgid "UDP over TCP" msgid "UDP over TCP"
msgstr "TCP 封装 UDP" msgstr "TCP 封装 UDP"
@@ -1258,12 +1255,6 @@ msgstr "本地端口"
msgid "Fast Open" msgid "Fast Open"
msgstr "快速打開" msgstr "快速打開"
msgid "Pre-connections"
msgstr "預連接"
msgid "Number of early established connections to reduce latency."
msgstr "預連接的數量,用於降低延遲。"
msgid "plugin" msgid "plugin"
msgstr "插件" msgstr "插件"
@@ -2,6 +2,15 @@
START=99 START=99
boot_func() {
sleep 90
restart
}
boot() {
boot_func >/dev/null 2>&1 &
}
start() { start() {
lua /usr/lib/lua/luci/passwall2/server_app.lua start lua /usr/lib/lua/luci/passwall2/server_app.lua start
} }
@@ -88,6 +88,23 @@ config shunt_rules 'Russia'
option ip_list 'geoip:ru option ip_list 'geoip:ru
#rule-set:remote:https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-geoip/geoip-ru.srs' #rule-set:remote:https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-geoip/geoip-ru.srs'
config shunt_rules 'PrivateIP'
option remarks 'PrivateIP'
option network 'tcp,udp'
option ip_list '10.0.0.0/8
127.0.0.0/8
198.51.100.0/24
192.0.0.0/24
169.254.0.0/16
224.0.0.0/3
192.168.0.0/16
192.88.99.0/24
100.64.0.0/10
172.16.0.0/12
0.0.0.0/8
192.0.2.0/24
203.0.113.0/24'
config nodes 'examplenode' config nodes 'examplenode'
option remarks 'Example' option remarks 'Example'
option type 'Xray' option type 'Xray'
@@ -104,6 +121,7 @@ config nodes 'rulenode'
option remarks 'rulenode' option remarks 'rulenode'
option type 'Xray' option type 'Xray'
option protocol '_shunt' option protocol '_shunt'
option PrivateIP '_direct'
option default_node 'examplenode' option default_node 'examplenode'
option domainStrategy 'IPOnDemand' option domainStrategy 'IPOnDemand'
option domainMatcher 'hybrid' option domainMatcher 'hybrid'
@@ -1937,7 +1937,6 @@ local function curl(url, file, ua, mode)
ua = (ua == "passwall2") and ("passwall2/" .. api.get_version()) or ua ua = (ua == "passwall2") and ("passwall2/" .. api.get_version()) or ua
curl_args[#curl_args + 1] = '--user-agent "' .. ua .. '"' curl_args[#curl_args + 1] = '--user-agent "' .. ua .. '"'
end end
curl_args[#curl_args + 1] = get_headers()
local return_code, result local return_code, result
if mode == "direct" then if mode == "direct" then
return_code, result = api.curl_direct(url, file, curl_args) return_code, result = api.curl_direct(url, file, curl_args)
@@ -1949,57 +1948,6 @@ local function curl(url, file, ua, mode)
return return_code, tonumber(result) return return_code, tonumber(result)
end end
function get_headers()
local cache_file = "/tmp/etc/" .. appname .. "_tmp/sub_curl_headers"
if fs.access(cache_file) then
return luci.sys.exec("cat " .. cache_file)
end
local headers = {}
local function readfile(path)
local f = io.open(path, "r")
if not f then return nil end
local c = f:read("*a")
f:close()
return api.trim(c)
end
headers[#headers + 1] = "x-device-os: OpenWrt"
local rel = readfile("/etc/openwrt_release")
local os_ver = rel and rel:match("DISTRIB_RELEASE='([^']+)'")
if os_ver then
headers[#headers + 1] = "x-ver-os: " .. os_ver
end
local model = readfile("/tmp/sysinfo/model")
if model then
headers[#headers + 1] = "x-device-model: " .. model
end
local mac = readfile("/sys/class/net/eth0/address")
if mac and model then
local raw = mac .. "-" .. model
local p = io.popen("printf '%s' '" .. raw:gsub("'", "'\\''") .. "' | sha256sum")
if p then
local hash = p:read("*l")
p:close()
hash = hash and hash:match("^%w+")
if hash then
headers[#headers + 1] = "x-hwid: " .. hash
end
end
end
local out = {}
for i = 1, #headers do
out[i] = "-H '" .. headers[i]:gsub("'", "'\\''") .. "'"
end
local headers_str = table.concat(out, " ")
local f = io.open(cache_file, "w"); if f then f:write(headers_str); f:close() end
return headers_str
end
local function truncate_nodes(group) local function truncate_nodes(group)
for _, config in pairs(CONFIG) do for _, config in pairs(CONFIG) do
if config.currentNodes and #config.currentNodes > 0 then if config.currentNodes and #config.currentNodes > 0 then
+9 -6
View File
@@ -5,19 +5,21 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI based ipk store LUCI_TITLE:=LuCI based ipk/apk store
LUCI_DESCRIPTION:=luci-app-store is a ipk store developed by LinkEase team LUCI_DESCRIPTION:=luci-app-store is a ipk/apk store developed by LinkEase team
LUCI_DEPENDS:=+curl +opkg +tar +libuci-lua +mount-utils +luci-lib-taskd LUCI_DEPENDS:=+curl +tar +libuci-lua +mount-utils +luci-lib-taskd
LUCI_DEPENDS+=$(if $(CONFIG_USE_APK),+apk +luci-compat,+opkg)
LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19) LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19)
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=0.1.34-1 PKG_VERSION:=0.2.0-r1
# PKG_RELEASE MUST be empty for luci.mk # PKG_RELEASE MUST be empty for luci.mk
PKG_RELEASE:= PKG_RELEASE:=
ISTORE_UI_VERSION:=0.1.32 ISTORE_UI_VERSION:=0.2.0
ISTORE_UI_RELEASE:=1 ISTORE_UI_RELEASE:=1
PKG_HASH:=d4f86a88bfd2d6fdd59d5e7f356c1bd51d333f70271f4f28e45feecee9bc1578 PKG_HASH:=01f91eec06a3d9125bd74a9a75e457f4fbb591afd9333bd2e9073c2522b79b3d
PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz
PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE) PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE)
@@ -27,6 +29,7 @@ PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
TARGET_CONFIGURE_OPTS= FRONTEND_DIST="$(BUILD_DIR)/istore-ui-$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE)/app-store-ui/src/dist" APP_STORE_VERSION="$(PKG_VERSION)" TARGET_CONFIGURE_OPTS= FRONTEND_DIST="$(BUILD_DIR)/istore-ui-$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE)/app-store-ui/src/dist" APP_STORE_VERSION="$(PKG_VERSION)"
TARGET_CONFIGURE_OPTS+= SED="$(SED)" TARGET_CONFIGURE_OPTS+= SED="$(SED)"
TARGET_CONFIGURE_OPTS+= USE_APK="$(CONFIG_USE_APK)"
define Package/luci-app-store/conffiles define Package/luci-app-store/conffiles
/etc/.app_store.id /etc/.app_store.id
+7 -2
View File
@@ -166,6 +166,11 @@ end
function store_index() function store_index()
local fs = require "nixio.fs" local fs = require "nixio.fs"
local features = { "_lua_force_array_" } local features = { "_lua_force_array_" }
if fs.access("/etc/apk/arch") then
features[#features+1] = "apk"
else
features[#features+1] = "opkg"
end
if fs.access("/usr/libexec/istore/backup") then if fs.access("/usr/libexec/istore/backup") then
features[#features+1] = "backup" features[#features+1] = "backup"
end end
@@ -251,7 +256,7 @@ function validate_pkgname(val)
end end
local function get_installed_and_cache() local function get_installed_and_cache()
local metadir = "/usr/lib/opkg/meta" local metadir = "/tmp/run/istore-meta/meta"
local cachedir = "/tmp/cache/istore" local cachedir = "/tmp/cache/istore"
local cachefile = cachedir .. "/installed.json" local cachefile = cachedir .. "/installed.json"
local nixio = require "nixio" local nixio = require "nixio"
@@ -321,7 +326,7 @@ local function get_installed_and_cache()
end end
function store_action(param) function store_action(param)
local metadir = "/usr/lib/opkg/meta" local metadir = "/tmp/run/istore-meta/meta"
local metapkgpre = "app-meta-" local metapkgpre = "app-meta-"
local code, out, err, ret local code, out, err, ret
local fs = require "nixio.fs" local fs = require "nixio.fs"
+211 -57
View File
@@ -10,25 +10,46 @@ if [ "${action:0:9}" = "AUTOCONF=" ]; then
fi fi
IS_ROOT=/tmp/is-root IS_ROOT=/tmp/is-root
DL_DIR=${IS_ROOT}/tmp/dl TMP_SELF_COPY=/var/run/cloned-is-opkg
LISTS_DIR_O=/tmp/opkg-lists USE_APK=false
LISTS_DIR=${IS_ROOT}${LISTS_DIR_O}
OPKG_CONF_DIR=${IS_ROOT}/etc/opkg
OPKG_CONF_DIR_M=${IS_ROOT}/etc/opkg_m
FEEDS_SERVER=https://istore.istoreos.com/repo
FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo"
DISABLE_MIRROR=false DISABLE_MIRROR=false
ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1` if [[ -s /etc/apk/arch ]]; then
USE_APK=true
fi
if $USE_APK; then
LISTS_DIR=${IS_ROOT}/apk
APK_CONF=${IS_ROOT}/etc/apk.conf
FEEDS_SERVER=https://istore.istoreos.com/repo-apk
FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo-apk"
ISTORE_INDEX=$FEEDS_SERVER/all/store/packages.adb
META_DIR=/lib/apk
ARCH=`cat /rom/etc/apk/arch /etc/apk/arch 2>/dev/null | head -1`
else
LISTS_DIR_O=/tmp/opkg-lists
LISTS_DIR=${IS_ROOT}${LISTS_DIR_O}
OPKG_CONF_DIR=${IS_ROOT}/etc/opkg
OPKG_CONF_DIR_M=${IS_ROOT}/etc/opkg_m
FEEDS_SERVER=https://istore.istoreos.com/repo
FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo"
ISTORE_INDEX=$FEEDS_SERVER/all/store/Packages.gz
META_DIR=/usr/lib/opkg
ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1`
fi
# for istore self upgrade # for istore self upgrade
ISTORE_PKG=luci-app-store ISTORE_PKG=luci-app-store
ISTORE_DEP_PKGS="luci-lib-taskd luci-lib-xterm taskd" ISTORE_DEP_PKGS="luci-lib-taskd luci-lib-xterm taskd"
ISTORE_INDEX=https://istore.istoreos.com/repo/all/store/Packages.gz
NEWLINE=$'\n' NEWLINE=$'\n'
is_init() { is_init() {
mkdir -p ${DL_DIR} ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var mkdir -p ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var
if $USE_APK; then
return 0
fi
cat /etc/opkg.conf | grep -Fv lists_dir | grep -Fv check_signature > ${IS_ROOT}/etc/opkg.conf cat /etc/opkg.conf | grep -Fv lists_dir | grep -Fv check_signature > ${IS_ROOT}/etc/opkg.conf
@@ -44,35 +65,71 @@ is_init() {
[ -e ${IS_ROOT}/var/lock ] || ln -s /var/lock ${IS_ROOT}/var/lock [ -e ${IS_ROOT}/var/lock ] || ln -s /var/lock ${IS_ROOT}/var/lock
} }
apk_wrap() {
APK_CONFIG=${APK_CONF} apk "$@"
}
opkg_wrap() { opkg_wrap() {
OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@"
} }
opkg_wrap_mirrors() { simple_apk_opkg() {
local action="$1"
shift
if $USE_APK; then
case "$action" in
"install")
action=add
;;
"remove")
action=del
;;
esac
apk_wrap "$action" "$@"
else
opkg_wrap "$action" "$@"
fi
}
do_in_mirrors() {
local server local server
local file
if ! $DISABLE_MIRROR; then if ! $DISABLE_MIRROR; then
local newpath="/usr/libexec/istore/mirror-bin:$PATH"
for server in $FEEDS_SERVER_MIRRORS ; do for server in $FEEDS_SERVER_MIRRORS ; do
rm -rf "${OPKG_CONF_DIR_M}" 2>/dev/null
mkdir -p "${OPKG_CONF_DIR_M}" 2>/dev/null
ls "${OPKG_CONF_DIR}/" | while read; do
file="$REPLY"
if [ -f "${OPKG_CONF_DIR}/$file" -a "${file: -5}" = ".conf" ]; then
sed "s#$FEEDS_SERVER/#$server/#g" "${OPKG_CONF_DIR}/$file" >"${OPKG_CONF_DIR_M}/$file"
touch -r "${OPKG_CONF_DIR}/$file" "${OPKG_CONF_DIR_M}/$file" 2>/dev/null
else
cp -a "${OPKG_CONF_DIR}/$file" "${OPKG_CONF_DIR_M}/"
fi
done
echo "Try mirror server $server" echo "Try mirror server $server"
OPKG_CONF_DIR=${OPKG_CONF_DIR_M} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" && return 0 PATH="$newpath" IS_ORIG_SERVER=$FEEDS_SERVER IS_MIRROR_SERVER=$server "$@" && return 0
done done
DISABLE_MIRROR=true DISABLE_MIRROR=true
fi fi
echo "Try origin server $FEEDS_SERVER" echo "Try origin server $FEEDS_SERVER"
OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" "$@"
} }
apk_wrap_mirrors() {
do_in_mirrors apk_wrap "$@"
}
opkg_wrap_mirrors() {
do_in_mirrors opkg_wrap "$@"
}
do_install_in_mirrors() {
if $USE_APK; then
apk_wrap_mirrors add "$@"
else
opkg_wrap_mirrors install "$@"
fi
}
do_upgrade_in_mirrors() {
if $USE_APK; then
apk_wrap_mirrors upgrade "$@"
else
opkg_wrap_mirrors upgrade "$@"
fi
}
alias fcurl='curl -L --fail --show-error' alias fcurl='curl -L --fail --show-error'
check_space() { check_space() {
@@ -91,14 +148,41 @@ update() {
fi fi
echo "Fetch feed list for ${ARCH}" echo "Fetch feed list for ${ARCH}"
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \ if $USE_APK; then
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \ rm -rf ${IS_ROOT}/var/tmp ${IS_ROOT}/etc/arch ${IS_ROOT}/etc/istore.pem
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \ mkdir -p ${IS_ROOT}/var/tmp
return 1 fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \
fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \
fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" && \
fcurl --no-progress-meter -o ${IS_ROOT}/etc/arch "${FEEDS_SERVER}/${ARCH}/archlist.conf" || \
return 1
echo "cache-dir $LISTS_DIR" > ${APK_CONF}
cat ${IS_ROOT}/var/tmp/arch.conf ${IS_ROOT}/var/tmp/all.conf ${IS_ROOT}/var/tmp/meta.conf >> ${APK_CONF}
local line
while read -r line; do
if [[ -n "$line" ]]; then
grep -Fxq "$line" /etc/apk/arch || echo "$line" >> /etc/apk/arch
fi
done < ${IS_ROOT}/etc/arch
sync /etc/apk/arch
if [[ ! -s /etc/apk/keys/istore.pem && ! -s /etc/apk/keys/istore-tmp.pem ]]; then
fcurl --no-progress-meter -o ${IS_ROOT}/etc/istore.pem "${FEEDS_SERVER}/istore-apk.pem" && \
cp -a ${IS_ROOT}/etc/istore.pem /etc/apk/keys/istore-tmp.pem || \
return 1
fi
else
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \
return 1
fi
echo "Update feeds index" echo "Update feeds index"
opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update if $USE_APK; then
apk_wrap update
else
opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update
fi
return 0 return 0
} }
@@ -110,9 +194,30 @@ update_if_outdate() {
return 0 return 0
} }
get_online_version() {
local index="$1"
local pkg="$2"
if $USE_APK; then
apk --cache-dir $LISTS_DIR --cache-max-age 0 --repositories-file /dev/null --repository "$index" update >/dev/null 2>&1
local ver=$(apk --cache-dir $LISTS_DIR --cache-max-age 0 --repositories-file /dev/null --repository "$index" query --available --fields version "$pkg" 2>/dev/null | grep -Fm1 'Version: ' | sed 's/^Version: //')
echo "${ver:-0.2.0-r1}"
else
curl --connect-timeout 2 --max-time 5 -s "$index" | gunzip | grep -FA10 "Package: $pkg" | grep -Fm1 'Version: ' | sed 's/^Version: //'
fi
}
get_local_version() {
local pkg="$1"
if $USE_APK; then
apk query --installed --fields version "$pkg" 2>/dev/null | grep -Fm1 'Version: ' | sed 's/^Version: //'
else
grep -Fm1 'Version: ' /usr/lib/opkg/info/$pkg.control 2>/dev/null | sed 's/^Version: //'
fi
}
check_self_upgrade() { check_self_upgrade() {
local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'` local newest=`get_online_version "$ISTORE_INDEX" "$ISTORE_PKG"`
local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'` local current=`get_local_version "$ISTORE_PKG"`
if [ "v$newest" = "v" -o "v$current" = "v" ]; then if [ "v$newest" = "v" -o "v$current" = "v" ]; then
echo "Check version failed!" >&2 echo "Check version failed!" >&2
exit 255 exit 255
@@ -124,13 +229,13 @@ check_self_upgrade() {
} }
do_self_upgrade_0() { do_self_upgrade_0() {
opkg_wrap upgrade ${ISTORE_DEP_PKGS} && opkg_wrap upgrade ${ISTORE_PKG} simple_apk_opkg upgrade ${ISTORE_DEP_PKGS} && simple_apk_opkg upgrade ${ISTORE_PKG}
} }
do_self_upgrade() { do_self_upgrade() {
check_mtime || return 1 check_mtime || return 1
local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'` local newest=`get_online_version "$ISTORE_INDEX" "$ISTORE_PKG"`
local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'` local current=`get_local_version "$ISTORE_PKG"`
if [ "v$newest" = "v" -o "v$current" = "v" ]; then if [ "v$newest" = "v" -o "v$current" = "v" ]; then
echo "Check version failed!" >&2 echo "Check version failed!" >&2
return 1 return 1
@@ -139,7 +244,7 @@ do_self_upgrade() {
echo "Already the latest version!" >&2 echo "Already the latest version!" >&2
return 1 return 1
fi fi
if opkg_wrap info ${ISTORE_PKG} | grep -qFm1 "Version: $newest"; then if $USE_APK || opkg_wrap info ${ISTORE_PKG} | grep -qFm1 "Version: $newest"; then
do_self_upgrade_0 && return 0 do_self_upgrade_0 && return 0
update_if_outdate || return 1 update_if_outdate || return 1
do_self_upgrade_0 do_self_upgrade_0
@@ -150,7 +255,13 @@ do_self_upgrade() {
} }
check_mtime() { check_mtime() {
find ${OPKG_CONF_DIR}/arch.conf -mtime -1 2>/dev/null | grep -q . || update local file
if $USE_APK; then
file=${APK_CONF}
else
file=${OPKG_CONF_DIR}/arch.conf
fi
find "$file" -mtime -1 2>/dev/null | grep -q . || update
} }
wrapped_in_update() { wrapped_in_update() {
@@ -164,7 +275,7 @@ refresh_installed() {
local pkg local pkg
for pkg in $@; do for pkg in $@; do
[[ $pkg == app-meta-* ]] || continue [[ $pkg == app-meta-* ]] || continue
pkg="/usr/lib/opkg/meta/${pkg#app-meta-}.json" pkg="$META_DIR/meta/${pkg#app-meta-}.json"
[[ -f "$pkg" ]] && touch "$pkg" [[ -f "$pkg" ]] && touch "$pkg"
done done
return 0 return 0
@@ -182,10 +293,10 @@ step_upgrade() {
fi fi
done done
if [ -n "$pkgs" ]; then if [ -n "$pkgs" ]; then
opkg_wrap_mirrors upgrade $pkgs || return 1 do_upgrade_in_mirrors $pkgs || return 1
fi fi
if [ -n "$metapkg" ]; then if [ -n "$metapkg" ]; then
opkg_wrap_mirrors upgrade $metapkg || return 1 do_upgrade_in_mirrors $metapkg || return 1
refresh_installed $metapkg refresh_installed $metapkg
fi fi
return 0 return 0
@@ -194,7 +305,7 @@ step_upgrade() {
new_upgrade() { new_upgrade() {
check_mtime || return 1 check_mtime || return 1
local metapkg=`echo "$@" | sed 's/ /\n/g' | grep -F app-meta-` local metapkg=`echo "$@" | sed 's/ /\n/g' | grep -F app-meta-`
if [ -z "$metapkg" ] || opkg_wrap info $metapkg | grep -qF not-installed ; then if [[ -z "$metapkg" ]] || [[ -z "$(get_local_version $metapkg)" ]]; then
true true
else else
update_if_outdate update_if_outdate
@@ -203,7 +314,11 @@ new_upgrade() {
} }
remove() { remove() {
opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@" if $USE_APK; then
apk_wrap del -r "$@"
else
opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@"
fi
} }
autoconf_to_env() { autoconf_to_env() {
@@ -235,16 +350,29 @@ try_autoconf() {
PATH="$CLEANPATH" /usr/libexec/istorea/${ISTORE_AUTOCONF}.sh PATH="$CLEANPATH" /usr/libexec/istorea/${ISTORE_AUTOCONF}.sh
} }
try_upgrade_depends() { try_upgrade_depends() {
local pkg="$1" local pkg="$1"
if [[ $pkg == app-meta-* ]]; then if [[ $pkg == app-meta-* ]]; then
local deps=$(grep '^Depends: ' /usr/lib/opkg/info/$pkg.control | busybox sed -e 's/^Depends: //' -e 's/,/\n/g' -e 's/ //g' | grep -vFw libc | xargs echo) local deps
[ -z "$deps" ] || opkg_wrap_mirrors install $deps if $USE_APK; then
deps=$(apk --repositories-file /dev/null info -R "$pkg" | tail +2 | grep -vFw libc | xargs echo)
else
deps=$(grep '^Depends: ' "/usr/lib/opkg/info/$pkg.control" | busybox sed -e 's/^Depends: //' -e 's/,/\n/g' -e 's/ //g' | grep -vFw libc | xargs echo)
fi
[ -z "$deps" ] || do_install_in_mirrors $deps
fi fi
return 0 return 0
} }
CMD_INSTALLED="opkg list-installed | cut -d' ' -f1 | sort -u" if $USE_APK; then
CMD_INSTALLED="apk --repositories-file /dev/null info | cut -d' ' -f1 | sort -u"
CMD_INSTALL="apk add --allow-untrusted"
else
CMD_INSTALLED="opkg list-installed | cut -d' ' -f1 | sort -u"
CMD_INSTALL="opkg install"
fi
dotrun() { dotrun() {
local path="$1" local path="$1"
[ -f "$path" ] || { echo "file not found: $path" >&2; return 1; } [ -f "$path" ] || { echo "file not found: $path" >&2; return 1; }
@@ -259,8 +387,8 @@ dotrun() {
echo "Executing .run file" echo "Executing .run file"
chmod 0755 "$path" && "$path" chmod 0755 "$path" && "$path"
else else
echo "Installing .ipk file" echo "Installing pkg file"
opkg install "$path" $CMD_INSTALL "$path"
fi fi
local RET=$? local RET=$?
rm -f "$path" rm -f "$path"
@@ -297,6 +425,13 @@ run_records() {
echo "]" echo "]"
} }
if $USE_APK; then
CMD_REMOVE="apk del"
else
CMD_REMOVE="opkg --autoremove remove"
fi
unrun() { unrun() {
local id="$1" local id="$1"
[ -s "/usr/share/istore/run-records/$id.txt" ] || { echo "record not found: $id" >&2; return 1; } [ -s "/usr/share/istore/run-records/$id.txt" ] || { echo "record not found: $id" >&2; return 1; }
@@ -306,9 +441,9 @@ unrun() {
local round max_round=6 local round max_round=6
for round in `seq 1 $max_round`; do for round in `seq 1 $max_round`; do
if [ $round == $max_round ]; then if [ $round == $max_round ]; then
opkg --autoremove remove `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` $CMD_REMOVE `cat "/tmp/is-root/tmp/to_unrun_$id.txt"`
else else
opkg --autoremove remove `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` 2>/dev/null && break $CMD_REMOVE `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` 2>/dev/null && break
fi fi
done done
sh -c "$CMD_INSTALLED" > "/tmp/is-root/tmp/post_unrun_$id.txt" sh -c "$CMD_INSTALLED" > "/tmp/is-root/tmp/post_unrun_$id.txt"
@@ -338,13 +473,19 @@ usage() {
echo " do_self_upgrade Upgrade iStore" echo " do_self_upgrade Upgrade iStore"
echo " arch Show libc architecture" echo " arch Show libc architecture"
echo " opkg sys opkg wrap" echo " opkg sys opkg wrap"
echo " dotrun {path} install .run/.ipk" echo " dotrun {path} install .run/.ipk/.apk"
echo " run_records list .run/.ipk install records" echo " run_records list .run/.ipk/.apk install records"
echo " del_record {id} delete .run/.ipk install record" echo " del_record {id} delete .run/.ipk/.apk install record"
echo " unrun {id} Remove installed packages by .run/.ipk" echo " unrun {id} Remove installed packages by .run/.ipk/.apk"
exit 1 exit 1
} }
if [[ "$action" = "do_self_upgrade" && "$0" != "$TMP_SELF_COPY" ]]; then
echo "copy self $0 to $TMP_SELF_COPY when self upgrade"
cp -af "$0" "$TMP_SELF_COPY" || exit 1
exec "$TMP_SELF_COPY" do_self_upgrade "$@" || exit 1
fi
is_init >/dev/null 2>&1 is_init >/dev/null 2>&1
CLEANPATH="$PATH" CLEANPATH="$PATH"
@@ -363,7 +504,7 @@ case $action in
;; ;;
"install") "install")
check_space check_space
wrapped_in_update opkg_wrap_mirrors install "$@" && refresh_installed "$1" && try_upgrade_depends "$1" && try_autoconf wrapped_in_update do_install_in_mirrors "$@" && refresh_installed "$1" && try_upgrade_depends "$1" && try_autoconf
;; ;;
"autoconf") "autoconf")
try_autoconf try_autoconf
@@ -375,10 +516,18 @@ case $action in
remove "$@" || remove "$@" remove "$@" || remove "$@"
;; ;;
"info") "info")
opkg_wrap info "$@" if $USE_APK; then
apk_wrap query "$@"
else
opkg_wrap info "$@"
fi
;; ;;
"list-upgradable") "list-upgradable")
opkg_wrap list-upgradable if $USE_APK; then
apk_wrap query --upgradable --summarize package '*'
else
opkg_wrap list-upgradable
fi
;; ;;
"check_self_upgrade") "check_self_upgrade")
check_self_upgrade check_self_upgrade
@@ -405,6 +554,11 @@ case $action in
"unrun") "unrun")
unrun "$1" unrun "$1"
;; ;;
"link_meta")
[[ -d "$META_DIR/meta" ]] || mkdir -p "$META_DIR/meta"
mkdir -p /tmp/run/istore
ln -sf "$META_DIR" /tmp/run/istore-meta
;;
*) *)
usage usage
;; ;;
+1
View File
@@ -7,6 +7,7 @@ boot() {
local ARCH=`/bin/is-opkg arch` local ARCH=`/bin/is-opkg arch`
generate_store_id $ARCH generate_store_id $ARCH
generate_super_arch $ARCH generate_super_arch $ARCH
/bin/is-opkg link_meta
} }
generate_store_id() { generate_store_id() {
@@ -9,4 +9,7 @@ if [ -z "`uci -q get istore.istore.hide_docker`" ] && ! which docker >/dev/null;
EOF EOF
fi fi
# remove tmp keys that used for self-installation, which is not needed after installation
rm -f /etc/apk/keys/istore-tmp.pem
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
+23 -18
View File
@@ -5,11 +5,12 @@
IS_ROOT=/tmp/is-backup IS_ROOT=/tmp/is-backup
APP_LIST_FILE=/etc/istore/app.list APP_LIST_FILE=/etc/istore/app.list
BACKUP_CONFIG_FILE=/etc/config/istore BACKUP_CONFIG_FILE=/etc/config/istore
USE_APK=false
[[ -s /etc/apk/arch ]] && USE_APK=true
action=${1} action=${1}
shift shift
is_init() { is_init() {
mkdir -p ${IS_ROOT} mkdir -p ${IS_ROOT}
} }
@@ -90,23 +91,23 @@ ipk_build() {
# if arg is NULL, use light backup, otherwise use local backup # if arg is NULL, use light backup, otherwise use local backup
backup() { backup() {
[ -n "$1" ] && BACKUP_PATH=$1 if [ -n "$1" ]; then
if $USE_APK; then
echo "does not support apk package manager" >&2
exit 1
fi
BACKUP_PATH=$1
fi
#1.add all istore self data to sysupgrade config file, if $USE_APK; then
#sysupgrade will backup/restore it auto when flash new firmware ( cd /lib/apk/packages && ls *.list ) | grep '^app-meta-' | sed 's/.list$//' | sort -u > ${IS_ROOT}/istore_installed_package.list
echo "/etc/.app_store.id" > /lib/upgrade/keep.d/luci-app-store else
cat /usr/lib/opkg/info/luci-app-store.list >> /lib/upgrade/keep.d/luci-app-store #write user installed package list to file
echo "/etc/rc.d/S45istore" >> /lib/upgrade/keep.d/luci-app-store opkg_list_installed_packages "userinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/user_installed_package.list
echo "/etc/istore/uci-defaults_bak" >> /lib/upgrade/keep.d/luci-app-store #write installed package list by istore feed to file
echo "${APP_LIST_FILE}" >> /lib/upgrade/keep.d/luci-app-store cat ${IS_ROOT}/user_installed_package.list | \
echo "${BACKUP_CONFIG_FILE}" >> /lib/upgrade/keep.d/luci-app-store grep '^app-meta-' > ${IS_ROOT}/istore_installed_package.list
fi
#write user installed package list to file
opkg_list_installed_packages "userinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/user_installed_package.list
#write installed package list by istore feed to file
cat ${IS_ROOT}/user_installed_package.list | \
grep '^app-meta-' > ${IS_ROOT}/istore_installed_package.list
#if no input backup path, only back app.list #if no input backup path, only back app.list
mkdir -p /etc/istore mkdir -p /etc/istore
@@ -186,6 +187,10 @@ backup() {
# if arg is NULL, use light backup, otherwise use local backup # if arg is NULL, use light backup, otherwise use local backup
restore() { restore() {
if [ -n "$1" ]; then if [ -n "$1" ]; then
if $USE_APK; then
echo "does not support apk package manager" >&2
exit 1
fi
BACKUP_PATH_FILE=$1 BACKUP_PATH_FILE=$1
else else
echo "install package by ${APP_LIST_FILE}" echo "install package by ${APP_LIST_FILE}"
@@ -233,7 +238,7 @@ restore() {
get_support_backup_features() { get_support_backup_features() {
echo "light_backup" echo "light_backup"
#istore custom img mean support local_backup #istore custom img mean support local_backup
if [ -f /etc/istore_img_flag ];then if ! $USE_APK; then
echo "local_backup" echo "local_backup"
fi fi
} }
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/mirror-bin:#:#g' -e 's/^:*//' -e 's/:*$//')
[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH="$newpath"
# if url starts with $IS_ORIG_SERVER, replace it with $IS_MIRROR_SERVER
if [ -n "$IS_ORIG_SERVER" ] && [ -n "$IS_MIRROR_SERVER" ]; then
for i in "$@"; do
if [[ "$i" == "$IS_ORIG_SERVER"* ]]; then
set -- "${@/$i/$IS_MIRROR_SERVER${i#$IS_ORIG_SERVER}}"
fi
done
fi
export -n IS_ORIG_SERVER IS_MIRROR_SERVER
exec curl "$@"
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/mirror-bin:#:#g' -e 's/^:*//' -e 's/:*$//')
[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH="$newpath"
# if url starts with $IS_ORIG_SERVER, replace it with $IS_MIRROR_SERVER
if [ -n "$IS_ORIG_SERVER" ] && [ -n "$IS_MIRROR_SERVER" ]; then
for i in "$@"; do
if [[ "$i" == "$IS_ORIG_SERVER"* ]]; then
set -- "${@/$i/$IS_MIRROR_SERVER${i#$IS_ORIG_SERVER}}"
fi
done
fi
export -n IS_ORIG_SERVER IS_MIRROR_SERVER
exec wget "$@"
+7 -3
View File
@@ -10,13 +10,17 @@ include $(TOPDIR)/feeds/luci/luci.mk
install: install:
[ -n "$(APP_STORE_VERSION)" ] [ -n "$(APP_STORE_VERSION)" ]
mkdir -p "$(DESTDIR)/www/luci-static" mkdir -p "$(DESTDIR)/www/luci-static" "$(DESTDIR)/etc"
cp -a "$(FRONTEND_DIST)/luci-static/istore" "$(DESTDIR)/www/luci-static/" cp -a "$(FRONTEND_DIST)/luci-static/istore" "$(DESTDIR)/www/luci-static/"
$(SED) 's#\.js"#.js?v=$(APP_STORE_VERSION)"#g' "$(DESTDIR)/www/luci-static/istore/index.js" $(SED) 's#\.js"#.js?v=$(APP_STORE_VERSION)"#g' "$(DESTDIR)/www/luci-static/istore/index.js"
mkdir -p "$(DESTDIR)/etc/opkg/keys"
echo "$(APP_STORE_VERSION)" > "$(DESTDIR)/etc/.app_store.version" echo "$(APP_STORE_VERSION)" > "$(DESTDIR)/etc/.app_store.version"
cp -a ./compat.conf "$(DESTDIR)/etc/opkg/compatfeeds.conf" ifneq ($(USE_APK),)
cp -pR ./root-apk/* "$(DESTDIR)/"
else
cp -pR ./root-opkg/* "$(DESTDIR)/"
mkdir -p "$(DESTDIR)/etc/opkg/keys"
cp -a ./key-build.pub $(DESTDIR)/etc/opkg/keys/`$(STAGING_DIR_HOST)/bin/usign -F -p ./key-build.pub` cp -a ./key-build.pub $(DESTDIR)/etc/opkg/keys/`$(STAGING_DIR_HOST)/bin/usign -F -p ./key-build.pub`
endif
mkdir -p "$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n" mkdir -p "$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n"
$(foreach lang,$(LUCI_LANGUAGES),$(foreach po,$(wildcard ${CURDIR}/po/$(lang)/*.po), \ $(foreach lang,$(LUCI_LANGUAGES),$(foreach po,$(wildcard ${CURDIR}/po/$(lang)/*.po), \
po2lmo $(po) \ po2lmo $(po) \
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEybK5eaXsrK06Thc1dbA3FC45Tlp8
8X5Z831vU6JggiV6tJiwI/B05IsdklTaZE8SYh0XCHcnXSjzRMLtarBisg==
-----END PUBLIC KEY-----
@@ -0,0 +1 @@
https://istore.istoreos.com/repo-apk/all/compat/packages.adb
+2 -2
View File
@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=tuic-client PKG_NAME:=tuic-client
PKG_VERSION:=1.8.6 PKG_VERSION:=1.8.7
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/Itsusinn/tuic/tar.gz/v$(PKG_VERSION)? PKG_SOURCE_URL:=https://codeload.github.com/Itsusinn/tuic/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=2ddd401f414aa7e6fa52d711e234edcc11646a79a65eda781023d003aa1e06c3 PKG_HASH:=d393071e5e840d3e3440b28c8b175d40e939699f610815da0ace171037a44028
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org> PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
+2 -2
View File
@@ -21,13 +21,13 @@ define Download/geoip
HASH:=a322dfb6bfd8987c83453c39582a07771c9deddf9f8f7d2d19c7927ebd5e76c8 HASH:=a322dfb6bfd8987c83453c39582a07771c9deddf9f8f7d2d19c7927ebd5e76c8
endef endef
GEOSITE_VER:=20260614143513 GEOSITE_VER:=20260616073835
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
define Download/geosite define Download/geosite
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
URL_FILE:=dlc.dat URL_FILE:=dlc.dat
FILE:=$(GEOSITE_FILE) FILE:=$(GEOSITE_FILE)
HASH:=7452b05d903867db8f3b3ace0c462b6033b37bef0b842a60133e5c6f91d3ef5d HASH:=b42bbf00f29270806e088f7402298f6f02932caef159f69d5a1ee5d18acd7496
endef endef
GEOSITE_IRAN_VER:=202606150209 GEOSITE_IRAN_VER:=202606150209