🎉 Sync 2026-04-03 20:25:30

This commit is contained in:
github-actions[bot] committed 2026-04-03 20:25:30 +08:00
1 parent 687ee81cf2
commit c3c67665a1
49 files changed
+754 -639

No files matched your search

+2 -2
View File
@@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-openclash
PKG_VERSION:=0.47.071
PKG_RELEASE:=2
PKG_VERSION:=0.47.075
PKG_RELEASE:=3
PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash>
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@@ -537,10 +537,10 @@ function fetch_sub_info(sub_url, sub_ua)
local info, upload, download, total, day_expire, http_code
local used, expire, day_left, percent, surplus
info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 --retry 2 -w 'http_code=%%{http_code}' -H 'User-Agent: %s' '%s'", sub_ua, sub_url))
info = luci.sys.exec(string.format("curl -sLI -X GET -m 5 --retry 2 -w 'http_code=%%{http_code}' -H 'User-Agent: %s' '%s'", sub_ua, sub_url))
local http_match = string.match(info, "http_code=(%d+)")
if not info or not http_match or tonumber(http_match) ~= 200 then
info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 --retry 2 -w 'http_code=%%{http_code}' -H 'User-Agent: Quantumultx' '%s'", sub_url))
info = luci.sys.exec(string.format("curl -sLI -X GET -m 5 --retry 2 -w 'http_code=%%{http_code}' -H 'User-Agent: Quantumultx' '%s'", sub_url))
http_match = string.match(info, "http_code=(%d+)")
end
@@ -735,7 +735,15 @@ function get_sub_url(filename)
function(s)
if s.name == filename and s.address and string.find(s.address, "http") then
string.gsub(s.address, '[^\n]+', function(w) table.insert(info_tb, w) end)
sub_url = info_tb[1]
if #info_tb == 1 then
local url, _ = parse_url_with_name(info_tb[1], filename)
sub_url = url
elseif #info_tb > 1 then
for _, raw in ipairs(info_tb) do
local url, name = parse_url_with_name(raw, filename)
table.insert(providers, {name = name, url = url})
end
end
end
end
)
@@ -744,6 +752,10 @@ function get_sub_url(filename)
return {type = "single", url = sub_url}
end
if #providers > 0 then
return {type = "multiple", providers = providers}
end
return nil
end
@@ -766,36 +778,33 @@ function sub_info_get()
if filename and not is_start() then
url_result = get_sub_url(filename)
if not url_result then
sub_info = "No Sub Info Found"
elseif url_result.type == "single" then
local info = fetch_sub_info(url_result.url, sub_ua)
if info then
table.insert(providers_data, info)
sub_info = "Successful"
else
sub_info = "No Sub Info Found"
end
elseif url_result.type == "multiple" then
for i, provider in ipairs(url_result.providers) do
local info = fetch_sub_info(provider.url, sub_ua)
if url_result then
if url_result.type == "single" then
local info = fetch_sub_info(url_result.url, sub_ua)
if info then
info.provider_name = provider.name
table.insert(providers_data, info)
end
end
if #providers_data > 0 then
sub_info = "Successful"
else
sub_info = "No Sub Info Found"
for i, provider in ipairs(url_result.providers) do
local info = fetch_sub_info(provider.url, sub_ua)
if info then
info.provider_name = provider.name
table.insert(providers_data, info)
end
end
end
end
end
if #providers_data == 0 then
if not url_result then
luci.http.status(400, "Subscription information not found")
return
end
end
luci.http.prepare_content("application/json")
luci.http.write_json({
sub_info = sub_info,
providers = providers_data,
get_time = os.time(),
url_result = url_result
@@ -903,6 +912,27 @@ function action_log_level()
})
end
function action_switch_log()
local level, info
if is_running() then
local daip = daip()
local dase = dase() or ""
local cn_port = cn_port()
level = luci.http.formvalue("log_level")
if not daip or not cn_port or not level then luci.http.status(500, "Switch Faild") return end
info = luci.sys.exec(string.format('curl -sL -m 3 --retry 2 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPATCH http://"%s":"%s"/configs -d \'{\"log-level\": \"%s\"}\'', dase, daip, cn_port, level))
if info ~= "" then
luci.http.status(500, "Switch Faild")
end
else
luci.http.status(500, "Switch Faild")
end
luci.http.prepare_content("application/json")
luci.http.write_json({
info = info;
})
end
local function s(e)
local t=0
local a={' B/S',' KB/S',' MB/S',' GB/S',' TB/S',' PB/S'}
@@ -123,6 +123,14 @@ end
o = s:option(TextValue, "address", translate("Subscribe Address"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
function o.validate(self, value)
if value then
value = value:gsub("\r\n?", "\n")
value = value:gsub("%c*$", "")
end
return value
end
---- template
@@ -510,8 +510,8 @@ function o.write(self, section, value)
value = value:gsub("\r\n?", "\n")
local old_value = NXFS.readfile("/etc/openclash/custom/openclash_custom_chnroute_pass.list")
if value ~= old_value then
NXFS.writefile("/etc/openclash/custom/openclash_custom_chnroute_pass.list", value)
end
NXFS.writefile("/etc/openclash/custom/openclash_custom_chnroute_pass.list", value)
end
end
end
@@ -612,8 +612,6 @@
<link rel="stylesheet" href="/luci-static/resources/openclash/lib/codemirror.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/theme/material.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/theme/material-log.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/theme/idea.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/fold/foldgutter.css"/>
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/lint/lint.css">
<link rel="stylesheet" href="/luci-static/resources/openclash/addon/display/fullscreen.css">
@@ -2972,13 +2972,15 @@
try {
var parsedData = JSON.parse(cachedData);
if (parsedData.sub_info && parsedData.sub_info !== "No Sub Info Found") {
if (this.currentConfigFile === requestConfigFile) {
this.displaySubscriptionInfo(parsedData);
}
} else if (parsedData.sub_info === "No Sub Info Found") {
if (this.currentConfigFile === requestConfigFile) {
this.showNoInfo();
if (parsedData.providers) {
if (parsedData.providers.length > 0) {
if (this.currentConfigFile === requestConfigFile) {
this.displaySubscriptionInfo(parsedData);
}
} else {
if (this.currentConfigFile === requestConfigFile) {
this.showNoInfo();
}
}
}
@@ -3006,16 +3008,32 @@
if (SubscriptionManager.currentConfigFile !== requestConfigFile) {
return;
}
if (x && x.status == 200 && status.sub_info && status.sub_info !== "No Sub Info Found") {
SubscriptionManager.retryCount = 0;
localStorage.setItem('sub_info_' + filename, JSON.stringify(status));
SubscriptionManager.displaySubscriptionInfo(status);
} else if (x && x.status == 200 && status.sub_info === "No Sub Info Found") {
SubscriptionManager.retryCount = 0;
localStorage.setItem('sub_info_' + filename, JSON.stringify(status));
SubscriptionManager.showNoInfo();
var needsErrorHandling = false;
if (x && x.status == 200 && status.providers) {
var newProvidersLength = (status.providers) ? status.providers.length : 0;
var cachedProvidersLength = (parsedData && parsedData.providers) ? parsedData.providers.length : 0;
if (newProvidersLength !== cachedProvidersLength && cachedProvidersLength > newProvidersLength) {
needsErrorHandling = true;
}
if (!needsErrorHandling) {
SubscriptionManager.retryCount = 0;
localStorage.setItem('sub_info_' + filename, JSON.stringify(status));
if (status.providers && status.providers.length === 0) {
SubscriptionManager.showNoInfo();
return;
}
SubscriptionManager.displaySubscriptionInfo(status);
return;
}
} else {
SubscriptionManager.handleError();
needsErrorHandling = true;
}
if (needsErrorHandling) {
SubscriptionManager.handleError(cachedData);
}
}, true);
}
@@ -3039,15 +3057,11 @@
container.style.display = 'flex';
if (data && data.sub_info && data.sub_info !== "No Sub Info Found") {
if (data.providers && Array.isArray(data.providers) && data.providers.length > 0) {
if (data.providers.length > 1 || data.providers[0].provider_name) {
this.displayMultipleProviders(data.providers, progressSection);
} else {
this.displaySingleProvider(data.providers[0], progressSection);
}
if (data && data.providers && data.providers.length > 0) {
if (data.providers.length > 1 || data.providers[0].provider_name) {
this.displayMultipleProviders(data.providers, progressSection);
} else {
progressSection.style.display = 'none';
this.displaySingleProvider(data.providers[0], progressSection);
}
} else {
progressSection.style.display = 'none';
@@ -3284,18 +3298,21 @@
}
},
handleError: function() {
if (this.retryCount >= this.maxRetries) {
handleError: function(cachedData) {
if (!cachedData) {
this.showNoInfo();
}
if (this.retryCount >= this.maxRetries) {
this.retryCount = 0;
if (this.currentConfigFile) {
if (this.currentConfigFile && cachedData) {
localStorage.removeItem('sub_info_' + this.extractFilename(this.currentConfigFile));
}
} else {
this.retryCount++;
setTimeout(function() {
SubscriptionManager.getSubscriptionInfo();
}, 5000);
}, 15000);
}
},
@@ -432,9 +432,11 @@
border: 1px solid #999999;
border-radius: 6px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
gap: 2px;
}
.sub_provider_fill {
@@ -458,6 +460,22 @@
text-overflow: ellipsis;
max-width: 100%;
padding: 0 4px;
line-height: 1;
}
.sub_provider_percent {
position: relative;
z-index: 1;
font-size: 12px;
color: #333;
font-weight: 400;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
padding: 0 4px;
line-height: 1;
}
/* Dark mode support */
@@ -470,6 +488,10 @@
color: #e0e0e0;
}
:root[data-darkmode="true"] .sub_provider_percent {
color: #e0e0e0;
}
/* Responsive adjustments for multiple providers */
@media (max-width: 1024px) {
.sub_providers_container {
@@ -483,6 +505,10 @@
.sub_provider_name {
font-size: 11px;
}
.sub_provider_percent {
font-size: 11px;
}
}
@media (max-width: 768px) {
@@ -498,6 +524,10 @@
.sub_provider_name {
font-size: 10px;
}
.sub_provider_percent {
font-size: 10px;
}
}
@media (max-width: 480px) {
@@ -510,6 +540,10 @@
.sub_provider_name {
font-size: 9px;
}
.sub_provider_percent {
font-size: 9px;
}
}
@media (max-width: 320px) {
@@ -521,6 +555,10 @@
.sub_provider_name {
font-size: 8px;
}
.sub_provider_percent {
font-size: 8px;
}
}
</style>
@@ -533,7 +571,7 @@
<div class="sub_div">
<span id='<%=idname%>' class="sub_tab"></span>
<button type="button" class="sub_setting" title='<%:Refresh%>' alt='<%:Refresh%>' onclick='return sub_info_refresh_<%=idname%>(this)'>
<button type="button" class="sub_setting" title='<%:Refresh%>' alt='<%:Refresh%>' onclick='return sub_info_refresh_<%=idname%>(true)'>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M23 4v6h-6"></path>
<path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path>
@@ -553,7 +591,7 @@
var retry_<%=idname%> = 0;
var s_<%=idname%>;
sub_info_get_<%=idname%>();
sub_info_refresh_<%=idname%>(false);
setTimeout(function(){
initDarkMode();
@@ -619,10 +657,6 @@ function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) {
};
function progressbar_multi_<%=idname%>(providers) {
if (!providers || !Array.isArray(providers) || providers.length === 0) {
return '<span>No Providers</span>';
}
var providerCount = providers.length;
var itemWidth;
var containerClass = 'sub_providers_container';
@@ -661,6 +695,7 @@ function progressbar_multi_<%=idname%>(providers) {
container += '<div class="sub_provider_item" style="width: ' + itemWidth + '" title="' + titleText + '">' +
'<div class="sub_provider_fill ' + bgColorClass + '" style="width: ' + percent + '%"></div>' +
'<span class="sub_provider_name">' + providerName + '</span>' +
'<span class="sub_provider_percent">' + ' (' + percent + '%)' + '</span>' +
'</div>';
});
@@ -673,7 +708,7 @@ function progressbar_multi_<%=idname%>(providers) {
}
return container;
}
};
function initDragScroll_<%=idname%>() {
var container = document.getElementById('sub_providers_<%=idname%>');
@@ -722,103 +757,93 @@ function initDragScroll_<%=idname%>() {
container.addEventListener('dragstart', function(e) {
e.preventDefault();
});
}
function sub_info_refresh_<%=idname%>()
{
if (s_<%=idname%>) { clearTimeout(s_<%=idname%>);};
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "sub_info_get")%>', {filename: "<%=filename%>"}, function(x, status) {
if (x && x.status == 200 && status.sub_info != "" && status.sub_info != "No Sub Info Found") {
retry_<%=idname%> = 0;
localStorage.setItem("sub_info_<%=filename%>",JSON.stringify(status));
document.getElementById('<%=idname%>').className = "sub_tab_show";
if (status.providers && Array.isArray(status.providers) && status.providers.length > 0) {
if (status.providers.length === 1) {
var provider = status.providers[0];
document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>(
(provider.surplus ? provider.surplus : provider.used),
(provider.total),
(provider.percent),
false, false,
(provider.expire),
(provider.day_left)
);
} else {
document.getElementById('<%=idname%>').innerHTML = progressbar_multi_<%=idname%>(status.providers);
}
} else {
document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>(
(status.surplus ? status.surplus : status.used),
(status.total),
(status.percent),
false, false,
(status.expire),
(status.day_left)
);
}
} else if ( x && x.status == 200 && status.sub_info == "No Sub Info Found" ) {
retry_<%=idname%> = 0;
localStorage.setItem("sub_info_<%=filename%>",JSON.stringify(status));
document.getElementById('<%=idname%>').className = "sub_tab_show";
document.getElementById('<%=idname%>').innerHTML = "<span><%:No Sub Info Found%></span>";
} else {
if (document.getElementById('<%=idname%>').innerHTML == "" || retry_<%=idname%> > 2) {
document.getElementById('<%=idname%>').className = "sub_tab_show";
document.getElementById('<%=idname%>').innerHTML = "<span style=color:red><%:Sub Info Get Error%></span>";
}
if (retry_<%=idname%> > 2) {
retry_<%=idname%> = 0;
localStorage.removeItem("sub_info_<%=filename%>");
} else {
retry_<%=idname%> ++;
s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*120);
return
}
};
s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*1800);
});
};
function sub_info_get_<%=idname%>()
{
if (localStorage.getItem("sub_info_<%=filename%>")) {
var save_info = JSON.parse(localStorage.getItem("sub_info_<%=filename%>"));
document.getElementById('<%=idname%>').className = "sub_tab_show";
if (save_info.sub_info == "No Sub Info Found") {
document.getElementById('<%=idname%>').innerHTML = "<span><%:No Sub Info Found%></span>";
}
else {
if (save_info.providers && Array.isArray(save_info.providers) && save_info.providers.length > 0) {
if (save_info.providers.length === 1) {
var provider = save_info.providers[0];
document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>(
(provider.surplus ? provider.surplus : provider.used),
(provider.total),
(provider.percent ? provider.percent : 0),
false, false,
(provider.expire),
(provider.day_left ? provider.day_left : 0)
);
} else {
document.getElementById('<%=idname%>').innerHTML = progressbar_multi_<%=idname%>(save_info.providers);
}
} else {
document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>(
(save_info.surplus ? save_info.surplus : save_info.used),
(save_info.total),
(save_info.percent ? save_info.percent : 0),
false, false,
(save_info.expire),
(save_info.day_left ? save_info.day_left : 0)
);
}
}
}
else {
sub_info_refresh_<%=idname%>();
};
s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*30);
function dispaly_progressbar(id, status) {
document.getElementById(id).className = "sub_tab_show";
if (status && status.providers && status.providers.length > 0) {
if (status.providers.length === 1) {
var provider = status.providers[0];
document.getElementById(id).innerHTML = window["progressbar_" + id](
(provider.surplus ? provider.surplus : provider.used),
(provider.total),
(provider.percent),
false, false,
(provider.expire),
(provider.day_left)
);
} else {
document.getElementById(id).innerHTML = window["progressbar_multi_" + id](status.providers);
}
} else {
document.getElementById(id).innerHTML = "<span><%:No Sub Info Found%></span>";
}
};
function sub_info_refresh_<%=idname%>(force) {
if (s_<%=idname%>) { clearTimeout(s_<%=idname%>);};
if (force) {
localStorage.removeItem("sub_info_<%=filename%>");
}
var save_info = (localStorage.getItem("sub_info_<%=filename%>")) ? JSON.parse(localStorage.getItem("sub_info_<%=filename%>")) : null;
var shouldFetchNew = true;
if (save_info && !force) {
dispaly_progressbar('<%=idname%>', save_info);
if (save_info.get_time) {
var currentTime = Math.floor(Date.now() / 1000);
var cacheTime = parseInt(save_info.get_time);
var timeDiff = currentTime - cacheTime;
var halfHourInSeconds = 30 * 60;
if (timeDiff <= halfHourInSeconds) {
shouldFetchNew = false;
}
}
}
if (retry_<%=idname%> >= 3) {
localStorage.removeItem("sub_info_<%=filename%>");
retry_<%=idname%> = 0;
shouldFetchNew = false;
}
if (!shouldFetchNew) {
s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>(false)", 60000*15);
return;
}
if (!save_info) {
document.getElementById('<%=idname%>').className = "sub_tab_show";
document.getElementById('<%=idname%>').innerHTML = "<span><%:Collecting data...%></span>";
}
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "sub_info_get")%>', {filename: "<%=filename%>"}, function(x, status) {
var needsErrorHandling = false;
if (x && x.status == 200 && status.providers) {
var save_info_length = (save_info && save_info.providers) ? save_info.providers.length : 0;
var newProvidersLength = (status && status.providers) ? status.providers.length : 0;
if (save_info_length !== newProvidersLength && save_info_length > newProvidersLength) {
needsErrorHandling = true;
}
if (!needsErrorHandling) {
retry_<%=idname%> = 0;
localStorage.setItem("sub_info_<%=filename%>", JSON.stringify(status));
dispaly_progressbar('<%=idname%>', status);
}
} else {
needsErrorHandling = true;
};
if (needsErrorHandling && retry_<%=idname%> <= 2) {
retry_<%=idname%>++;
s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>(false)", 15000);
} else {
s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>(false)", 60000*15);
};
});
};
function set_subinfo_url_<%=idname%>(btn, filename) {
@@ -872,14 +897,12 @@ function set_subinfo_url_<%=idname%>(btn, filename) {
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "set_subinfo_url")%>', {filename: filename, url: new_url}, function(x, status) {
if (x && x.status == 200 && status.info == "Success") {
sub_info_refresh_<%=idname%>();
sub_info_refresh_<%=idname%>(true);
alert("<%:Specify subscribe infos sources url successfully!%>");
}
else if (x && x.status == 200 && status.info == "Delete success") {
sub_info_refresh_<%=idname%>();
} else if (x && x.status == 200 && status.info == "Delete success") {
sub_info_refresh_<%=idname%>(true);
alert("<%:Delete Specify Subscribe infos sources url successfully!%>");
}
else {
} else {
alert("<%:Specify subscribe infos sources url failed:%>\n" + status.info);
}
});
-3
View File
@@ -2393,9 +2393,6 @@ msgstr "Información de suscripción"
msgid "No Sub Info Found"
msgstr "No se ha encontrado información de suscripción"
msgid "Sub Info Get Error"
msgstr "Error al obtener la información de suscripción"
msgid "Router-Self Proxy"
msgstr "Proxy para tráfico del propio router"
@@ -2391,9 +2391,6 @@ msgstr "订阅信息"
msgid "No Sub Info Found"
msgstr "无订阅信息"
msgid "Sub Info Get Error"
msgstr "订阅信息获取失败"
msgid "Router-Self Proxy"
msgstr "*路由本机代理"
+4 -5
View File
@@ -1042,10 +1042,10 @@ firewall_lan_ac_traffic()
rule_target_v4="! -d ${fakeip_range} ${src_ip} ${sport_ipt} ${interface_rule} ${dscp_ipt} -j ${target} -m comment --comment ${comment}"
output_rule_target_v4="! -d ${fakeip_range} ${src_ip} ${sport_ipt} ${user_rule} ${interface_rule} ${dscp_ipt} -j ${target} -m comment --comment ${comment}"
rule_target_v6_="! -d ${fakeip_range6} ${src_ip} ${sport_ipt} ${interface_rule} ${dscp_ipt} -j ${target_} -m comment --comment ${comment}"
output_rule_target_v6_="! -d ${fakeip_range6} ${src_ip} ${sport_ipt} ${user_rule} ${interface_rule} ${dscp_ipt} -j ${target_} -m comment --comment ${comment}"
rule_target_v6="! -d ${fakeip_range6} ${src_ip} ${sport_ipt} ${interface_rule} ${dscp_ipt} -j ${target} -m comment --comment ${comment}"
output_rule_target_v6="! -d ${fakeip_range6} ${src_ip} ${sport_ipt} ${user_rule} ${interface_rule} ${dscp_ipt} -j ${target} -m comment --comment ${comment}"
rule_target_v6_="! -d ${fakeip_range6} ${src_ip_v6} ${sport_ipt} ${interface_rule} ${dscp_ipt} -j ${target_} -m comment --comment ${comment}"
output_rule_target_v6_="! -d ${fakeip_range6} ${src_ip_v6} ${sport_ipt} ${user_rule} ${interface_rule} ${dscp_ipt} -j ${target_} -m comment --comment ${comment}"
rule_target_v6="! -d ${fakeip_range6} ${src_ip_v6} ${sport_ipt} ${interface_rule} ${dscp_ipt} -j ${target} -m comment --comment ${comment}"
output_rule_target_v6="! -d ${fakeip_range6} ${src_ip_v6} ${sport_ipt} ${user_rule} ${interface_rule} ${dscp_ipt} -j ${target} -m comment --comment ${comment}"
if [ "${family}" == "both" ] || [ "${family}" == "ipv4" ]; then
if [ -z "${en_mode_tun}" ] || [ "${en_mode_tun}" -eq 2 ]; then
@@ -3868,7 +3868,6 @@ stop_service()
rm -rf /tmp/clash_last_version \
/tmp/openclash_last_version \
/tmp/openclash.change \
/tmp/openclash_debug.log \
/tmp/openclash_announcement \
${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf \
${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf \
@@ -84,19 +84,22 @@ module YAML
indent = $1
value = $2.strip
if value.empty?
in_short_id = true
(short_id_index + 1...lines.size).each do |i|
line = lines[i]
next if line.strip.empty?
if line[/^\s*/].length <= short_id_indent_len
break
end
if line =~ LIST_ITEM_REGEX
if in_short_id
indent = $1
value = $2.strip
if value !~ QUOTED_VALUE_REGEX
lines[i] = "#{indent}- \"#{value}\"\n"
end
indent = $1
value = $2.strip
if value =~ KEY_REGEX
break
end
if value !~ QUOTED_VALUE_REGEX
lines[i] = "#{indent}- \"#{value}\"\n"
end
elsif line =~ KEY_REGEX
in_short_id = false
break
end
end
@@ -72,13 +72,13 @@ config_download()
LOG_TIP "Config File【$name】Downloading User-Agent【$sub_ua】..."
if [ -n "$subscribe_url_param" ] && [ -n "$c_address" ]; then
LOG_INFO "Config File【$name】Downloading URL【$c_address$subscribe_url_param】..."
DOWNLOAD_URL="${c_address}${subscribe_url_param}"
DOWNLOAD_PARAM="$sub_ua"
local DOWNLOAD_URL="${c_address}${subscribe_url_param}"
local DOWNLOAD_PARAM="$sub_ua"
fi
if [ -z "$DOWNLOAD_URL" ]; then
LOG_INFO "Config File【$name】Downloading URL【$subscribe_url】..."
DOWNLOAD_URL="${subscribe_url}"
DOWNLOAD_PARAM="$sub_ua"
local DOWNLOAD_URL="${subscribe_url}"
local DOWNLOAD_PARAM="$sub_ua"
fi
DOWNLOAD_FILE_CURL "$DOWNLOAD_URL" "$CFG_FILE" "$CONFIG_FILE" "$DOWNLOAD_PARAM"
DOWNLOAD_RESULT=$?
@@ -395,9 +395,9 @@ sub_info_get()
if [ "$sub_convert" -eq 0 ]; then
subscribe_url=$address
elif [ "$sub_convert" -eq 1 ] && [ -n "$template" ]; then
while read line
do
subscribe_url=$([ -n "$subscribe_url" ] && echo "$subscribe_url|")$(urlencode "$line")
while IFS= read -r line; do
line=$(echo "$line" | tr -d '\r')
subscribe_url=$([ -n "$subscribe_url" ] && echo "$subscribe_url|")$(urlencode "$line")
done < <(echo "$address")
if [ "$template" != "0" ]; then
template_path=$(grep "^$template," /usr/share/openclash/res/sub_ini.list |awk -F ',' '{print $3}' 2>/dev/null)
@@ -228,7 +228,7 @@ LOG_ERROR()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "${LOGTIME} [error] ${1}" >> $LOG_FILE
echo -e "${LOGTIME} [Error] ${1}" >> $LOG_FILE
fi
}
@@ -236,7 +236,7 @@ LOG_TIP()
{
if [ -n "${1}" ]; then
echo -e "${1}" > $START_LOG
echo -e "${LOGTIME} [tip] ${1}" >> $LOG_FILE
echo -e "${LOGTIME} [Tip] ${1}" >> $LOG_FILE
fi
}
@@ -182,6 +182,8 @@ done >/dev/null 2>&1
#check the clash service status
if ! ubus call service list '{"name":"openclash"}' 2>/dev/null | jsonfilter -e '@.openclash.instances.*.running' | grep -q 'true'; then
uci -q set openclash.config.enable=0
uci -q commit openclash
/etc/init.d/openclash stop >/dev/null 2>&1
exit 0
fi
@@ -2,11 +2,5 @@
uci_get_config() {
local key="$1"
local val
val=$(uci -q get openclash.@overwrite[0]."$key" 2>/dev/null)
if [ -n "$val" ]; then
echo "$val"
else
uci -q get openclash.config."$key"
fi
uci -q get openclash.@overwrite[0]."$key" || uci -q get openclash.config."$key"
}