🎄 Sync 2025-11-13 00:13:36

This commit is contained in:
actions-user
2025-11-13 00:13:36 +08:00
parent 34c022445a
commit 7d9ba80838
8 changed files with 121 additions and 73 deletions

View File

@@ -5,19 +5,18 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=libcron PKG_NAME:=libcron
PKG_VERSION:=1.3.3
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/PerMalmberg/libcron.git PKG_SOURCE_URL:=https://github.com/PerMalmberg/libcron.git
PKG_SOURCE_DATE:=2023-11-14 PKG_SOURCE_VERSION:=v$(PKG_VERSION)
PKG_SOURCE_VERSION:=41f238ceb09d4179e7346d78584a0c978e5d0059 PKG_MIRROR_HASH:=74a81dc759bc6ff664601c9b0767120957e54571c0d8500177f7645e07287f24
PKG_MIRROR_HASH:=1d5ed3dd15abd1df765904b80153943c12cf1b2b212432c8f116a5eff30e953d
PKG_LICENSE:=MIT PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org> PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_BUILD_PARALLEL:=1
CMAKE_INSTALL:=1 CMAKE_INSTALL:=1
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk

View File

@@ -134,10 +134,10 @@ local api = require "luci.passwall.api"
setTimeout(function () { setTimeout(function () {
if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) { if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
var xhr1 = new XMLHttpRequest(); var xhr1 = new XMLHttpRequest();
xhr1.open("GET",'<%= api.url("clear_log") %>', true); xhr1.open("GET",'<%= api.url("clear_log") %>', false);
xhr1.send(); xhr1.send();
var xhr2 = new XMLHttpRequest(); var xhr2 = new XMLHttpRequest();
xhr2.open("GET",'<%= api.url("reset_config") %>', true); xhr2.open("GET",'<%= api.url("reset_config") %>', false);
xhr2.send(); xhr2.send();
window.location.href = '<%= api.url("log") %>' window.location.href = '<%= api.url("log") %>'
} }

View File

@@ -659,6 +659,21 @@ table td, .table .td {
if (default_group) { if (default_group) {
cbi_t_switch("passwall.nodes", default_group) cbi_t_switch("passwall.nodes", default_group)
} }
//clear expire data
if (localStorage && localStorage.length > 0) {
const now = Date.now();
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
if (key && (key.startsWith("icmp") || key.startsWith("tcping"))) {
let value_str = localStorage.getItem(key);
const value = JSON.parse(value_str);
if (!(value && value.savetime && (now - value.timestamp) < value.savetime)) {
localStorage.removeItem(key);
}
}
}
}
get_now_use_node(); get_now_use_node();

View File

@@ -449,6 +449,26 @@ local function get_subscribe_info(cfgid, value)
end end
end end
-- 设置 ss 协议实现类型
local function set_ss_implementation(result)
if ss_type_default == "shadowsocks-libev" and has_ss then
result.type = "SS"
elseif ss_type_default == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
elseif ss_type_default == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'raw'
elseif ss_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
else
log("跳过 SS 节点,因未适配到 SS 核心程序,或未正确设置节点使用类型。")
return nil
end
return result
end
-- 处理数据 -- 处理数据
local function processData(szType, content, add_mode, group) local function processData(szType, content, add_mode, group)
--log(content, add_mode, group) --log(content, add_mode, group)
@@ -602,21 +622,8 @@ local function processData(szType, content, add_mode, group)
return nil return nil
end end
elseif szType == "ss" then elseif szType == "ss" then
if ss_type_default == "shadowsocks-libev" and has_ss then result = set_ss_implementation(result)
result.type = "SS" if not result then return nil end
elseif ss_type_default == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
elseif ss_type_default == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'raw'
elseif ss_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
else
log("跳过 SS 节点,因未适配到 SS 核心程序,或未正确设置节点使用类型。")
return nil
end
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ] --SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
--userinfo = websafe-base64-encode-utf8(method ":" password) --userinfo = websafe-base64-encode-utf8(method ":" password)
@@ -1069,7 +1076,8 @@ local function processData(szType, content, add_mode, group)
end end
elseif szType == "ssd" then elseif szType == "ssd" then
result.type = "SS" result = set_ss_implementation(result)
if not result then return nil end
result.address = content.server result.address = content.server
result.port = content.port result.port = content.port
result.password = content.password result.password = content.password
@@ -1831,7 +1839,7 @@ local function parse_link(raw, add_mode, group, cfgid)
end end
for _, v in ipairs(nodes) do for _, v in ipairs(nodes) do
if v and not string.match(v, "^%s*$") then if v and (szType == 'ssd' or not string.match(v, "^%s*$")) then
xpcall(function () xpcall(function ()
local result local result
if szType == 'ssd' then if szType == 'ssd' then

View File

@@ -134,10 +134,10 @@ local api = require "luci.passwall2.api"
setTimeout(function () { setTimeout(function () {
if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) { if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
var xhr1 = new XMLHttpRequest(); var xhr1 = new XMLHttpRequest();
xhr1.open("GET",'<%= api.url("clear_log") %>', true); xhr1.open("GET",'<%= api.url("clear_log") %>', false);
xhr1.send(); xhr1.send();
var xhr2 = new XMLHttpRequest(); var xhr2 = new XMLHttpRequest();
xhr2.open("GET",'<%= api.url("reset_config") %>', true); xhr2.open("GET",'<%= api.url("reset_config") %>', false);
xhr2.send(); xhr2.send();
window.location.href = '<%= api.url("log") %>' window.location.href = '<%= api.url("log") %>'
} }

View File

@@ -177,13 +177,13 @@ local api = require "luci.passwall2.api"
<div id="add_link_div"> <div id="add_link_div">
<div id="add_link_modal_container"> <div id="add_link_modal_container">
<h3><%:Add the node via the link%></h3> <h3><%:Add the node via the link%></h3>
<div class="cbi-value"> <div class="value-custom">
<textarea id="nodes_link" rows="10"></textarea> <textarea id="nodes_link" rows="10"></textarea>
<p id="nodes_link_text"><%:Enter share links, one per line. Subscription links are not supported!%></p> <p id="nodes_link_text"><%:Enter share links, one per line. Subscription links are not supported!%></p>
</div> </div>
<div class="cbi-value modal-center"> <div class="value-custom">
<label class="cbi-value-title"><%:Group Name%></label> <div class="value-field-custom">
<div class="cbi-value-field"> <label class="value-title-custom"><%:Group Name%></label>
<div id="addlink_group_custom" class="custom-dropdown"> <div id="addlink_group_custom" class="custom-dropdown">
<div class="selected-display"> <div class="selected-display">
<span class="text"><%:default%></span> <span class="text"><%:default%></span>
@@ -253,13 +253,12 @@ local api = require "luci.passwall2.api"
padding: 5px; padding: 5px;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 5px; border-radius: 5px;
margin-bottom: -10px;
} }
#nodes_link_text { #nodes_link_text {
color: red; color: red;
font-size: 14px; font-size: 14px;
margin-top: 0; margin-top: 5px;
text-align: center; text-align: center;
width: 100%; width: 100%;
} }
@@ -272,43 +271,40 @@ local api = require "luci.passwall2.api"
margin-top: 10px; margin-top: 10px;
} }
#add_link_modal_container .modal-center { .value-custom {
display: flex; display: flex;
flex-direction: row; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; width: 100%;
gap: 10px; margin: 10px 0;
margin-bottom: 15px; padding: 0px 5px 0px 5px;
width: auto;
} }
#add_link_modal_container .modal-center .cbi-value-title { .value-field-custom {
display: inline-block; display: inline-flex;
width: 80px; align-items: center;
text-align: right; gap: 10px;
}
.value-title-custom {
font-size: 13px; font-size: 13px;
line-height: 28px; line-height: 28px;
margin: 0;
white-space: nowrap; white-space: nowrap;
flex-shrink: 0; text-align: right;
}
#add_link_modal_container .modal-center .cbi-value-field {
display: flex;
justify-content: flex-start;
width: 200px;
} }
.custom-dropdown { .custom-dropdown {
position: relative; position: relative;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-radius: 2px; border-radius: 2px;
width: 200px; width: 180px;
height: 28px;
font-size: 13px; font-size: 13px;
background: #fff; background: #fff;
cursor: pointer; cursor: pointer;
box-sizing: border-box; box-sizing: border-box;
height: 28px; display: flex;
align-items: center;
} }
.selected-display { .selected-display {
@@ -316,7 +312,9 @@ local api = require "luci.passwall2.api"
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0 8px; padding: 0 8px;
width: 100%;
height: 100%; height: 100%;
box-sizing: border-box;
} }
.selected-display:hover { .selected-display:hover {
@@ -332,7 +330,7 @@ local api = require "luci.passwall2.api"
position: absolute; position: absolute;
top: 100%; top: 100%;
left: 0; left: 0;
width: 100%; width: 180px;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-top: none; border-top: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.15); box-shadow: 0 1px 3px rgba(0,0,0,0.15);
@@ -340,7 +338,7 @@ local api = require "luci.passwall2.api"
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
max-height: 250px; max-height: 200px;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
z-index: 100; z-index: 100;
@@ -350,6 +348,7 @@ local api = require "luci.passwall2.api"
.dropdown-item { .dropdown-item {
padding: 4px 8px; padding: 4px 8px;
line-height: 20px; line-height: 20px;
cursor: pointer;
} }
.dropdown-item.selected { .dropdown-item.selected {
@@ -357,13 +356,17 @@ local api = require "luci.passwall2.api"
color: #fff; color: #fff;
} }
.create-item-input::placeholder {
text-align: center;
}
.dropdown-item.custom-input input { .dropdown-item.custom-input input {
width: 100%; width: 100%;
max-width: 200px;
box-sizing: border-box; box-sizing: border-box;
padding: 3px; padding: 3px;
font-size: 13px; font-size: 13px;
line-height: 20px; line-height: 20px;
border: 1px solid #ccc; border: 1px solid #ccc;
text-align: left;
} }
</style> </style>

View File

@@ -497,7 +497,7 @@ table td, .table .td {
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/> <input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/>
<input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/> <input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/>
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>"> <input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>">
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Del%>" onclick="del_node('{{id}}')" alt="<%:Del%>" title="<%:Del%>"> <input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>">
</div> </div>
</td> </td>
</tr> </tr>
@@ -659,6 +659,21 @@ table td, .table .td {
cbi_t_switch("passwall2.nodes", default_group) cbi_t_switch("passwall2.nodes", default_group)
} }
//clear expire data
if (localStorage && localStorage.length > 0) {
const now = Date.now();
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
if (key && (key.startsWith("icmp") || key.startsWith("tcping"))) {
let value_str = localStorage.getItem(key);
const value = JSON.parse(value_str);
if (!(value && value.savetime && (now - value.timestamp) < value.savetime)) {
localStorage.removeItem(key);
}
}
}
}
get_now_use_node(); get_now_use_node();
pingAllNodes(); pingAllNodes();
@@ -684,4 +699,4 @@ table td, .table .td {
<input class="btn cbi-button cbi-button-remove" type="button" onclick="close_set_node_div()" value="<%:Close%>" /> <input class="btn cbi-button cbi-button-remove" type="button" onclick="close_set_node_div()" value="<%:Close%>" />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -443,6 +443,26 @@ local function get_subscribe_info(cfgid, value)
end end
end end
-- 设置 ss 协议实现类型
local function set_ss_implementation(result)
if ss_type_default == "shadowsocks-libev" and has_ss then
result.type = "SS"
elseif ss_type_default == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
elseif ss_type_default == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'raw'
elseif ss_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
else
log("跳过 SS 节点,因未适配到 SS 核心程序,或未正确设置节点使用类型。")
return nil
end
return result
end
-- 处理数据 -- 处理数据
local function processData(szType, content, add_mode, group) local function processData(szType, content, add_mode, group)
--log(content, add_mode, group) --log(content, add_mode, group)
@@ -606,21 +626,8 @@ local function processData(szType, content, add_mode, group)
return nil return nil
end end
elseif szType == "ss" then elseif szType == "ss" then
if ss_type_default == "shadowsocks-libev" and has_ss then result = set_ss_implementation(result)
result.type = "SS" if not result then return nil end
elseif ss_type_default == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
elseif ss_type_default == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'raw'
elseif ss_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
else
log("跳过 SS 节点,因未适配到 SS 核心程序,或未正确设置节点使用类型。")
return nil
end
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ] --SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
--userinfo = websafe-base64-encode-utf8(method ":" password) --userinfo = websafe-base64-encode-utf8(method ":" password)
@@ -1075,7 +1082,8 @@ local function processData(szType, content, add_mode, group)
end end
end end
elseif szType == "ssd" then elseif szType == "ssd" then
result.type = "SS" result = set_ss_implementation(result)
if not result then return nil end
result.address = content.server result.address = content.server
result.port = content.port result.port = content.port
result.password = content.password result.password = content.password
@@ -1836,7 +1844,7 @@ local function parse_link(raw, add_mode, group, cfgid)
end end
for _, v in ipairs(nodes) do for _, v in ipairs(nodes) do
if v and not string.match(v, "^%s*$") then if v and (szType == 'ssd' or not string.match(v, "^%s*$")) then
xpcall(function () xpcall(function ()
local result local result
if szType == 'ssd' then if szType == 'ssd' then