🤞 Sync 2026-05-16 20:23:58

This commit is contained in:
github-actions[bot] 2026-05-16 20:23:58 +08:00
parent ccfd18b795
commit 1d77fe1b27
38 changed files with 477 additions and 4497 deletions

View File

@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk
PKG_NAME:=easytier-noweb
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.2)
PKG_RELEASE:=2
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.4)
PKG_RELEASE:=3
ifeq ($(ARCH),mipsel)
APP_ARCH:=mipsel

View File

@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk
PKG_NAME:=easytier
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.2)
PKG_RELEASE:=5
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.4)
PKG_RELEASE:=6
ifeq ($(ARCH),mipsel)
APP_ARCH:=mipsel

View File

View File

@ -7,8 +7,8 @@
include $(TOPDIR)/rules.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.2)
PKG_RELEASE:=8
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.4)
PKG_RELEASE:=9
LUCI_TITLE:=LuCI support for EasyTier
LUCI_DEPENDS:=+kmod-tun +easytier +luci-compat

View File

@ -163,7 +163,7 @@ function get_upload_config()
easytierbin = uci:get_first("easytier", "easytier", "easytierbin") or "/usr/bin/easytier-core",
webbin = uci:get_first("easytier", "easytier", "webbin") or "/usr/bin/easytier-web",
github_proxys = {},
fallback_version = uci:get_first("easytier", "easytier", "fallback_version") or "v2.6.2"
fallback_version = uci:get_first("easytier", "easytier", "fallback_version") or "v2.6.4"
}
-- 读取代理列表list 类型)
@ -200,7 +200,7 @@ function save_upload_config()
-- 保存配置
uci:set("easytier", "@easytier[0]", "easytierbin", data.easytierbin or "/usr/bin/easytier-core")
uci:set("easytier", "@easytier[0]", "webbin", data.webbin or "/usr/bin/easytier-web")
uci:set("easytier", "@easytier[0]", "fallback_version", data.fallback_version or "v2.6.2")
uci:set("easytier", "@easytier[0]", "fallback_version", data.fallback_version or "v2.6.4")
-- 删除旧的代理列表
uci:delete("easytier", "@easytier[0]", "github_proxys")

View File

@ -56,12 +56,6 @@ network_name = s:taboption("general", Value, "network_name", translate("Network
network_name.password = true
network_name.placeholder = "easytier-name"
network_name.maxlength = 64
network_name.validate = function(self, value)
if value and value ~= "" and value:match("[^%w%-_]") then
return nil, translate("Only alphanumeric characters, hyphens and underscores allowed")
end
return value
end
network_name:depends("etcmd", "etcmd")
network_secret = s:taboption("general", Value, "network_secret", translate("Network Secret"),
@ -412,9 +406,28 @@ foreign_relay_bps_limit = s:taboption("privacy", Value, "foreign_relay_bps_limit
.. "(--foreign-relay-bps-limit parameter)"))
foreign_relay_bps_limit:depends("etcmd", "etcmd")
extra_args = s:taboption("privacy", Value, "extra_args", translate("Extra Parameters"),
extra_args = s:taboption("privacy", DynamicList, "extra_args", translate("Extra Parameters"),
translate("Additional command-line arguments passed to the backend process"))
extra_args.placeholder = "--tcp-whitelist 80 --udp-whitelist 53"
extra_args.placeholder = "--tcp-whitelist=80"
extra_args.validate = function(self, value, section)
if type(value) == "table" then
local seen = {}
local i
for i = 1, #value do
local arg = value[i]
if arg then
arg = tostring(arg):match("^%s*(.-)%s*$")
if arg ~= "" then
if seen[arg] then
return nil, translate("Duplicate extra parameter") .. ": " .. arg
end
seen[arg] = true
end
end
end
end
return value
end
extra_args:depends("etcmd", "etcmd")
log = s:taboption("general", ListValue, "log", translate("Program Log"),

View File

@ -370,6 +370,8 @@ local uci = require 'luci.model.uci'.cursor()
border-radius: 12px;
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: anywhere;
word-break: break-word;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 13px;
color: var(--text-primary);
@ -377,6 +379,34 @@ local uci = require 'luci.model.uci'.cursor()
line-height: 1.5;
}
.et-command-panel {
position: relative;
}
.et-command-toolbar {
display: flex;
justify-content: flex-end;
margin-bottom: 8px;
}
.et-copy-btn {
display: inline-flex;
align-items: center;
padding: 5px 10px;
background: var(--tab-active);
color: #fff;
border: 1px solid var(--tab-active);
border-radius: 6px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
line-height: 1.4;
}
.et-copy-btn:hover {
opacity: 0.9;
}
@media (max-width: 768px) {
.et-conninfo-header {
flex-direction: column;
@ -893,6 +923,50 @@ function escapeHtml(text) {
return div.innerHTML;
}
function copyTextFromElement(elementId, button) {
var el = document.getElementById(elementId);
if (!el) return;
var text = el.textContent || el.innerText || '';
function markCopied() {
if (!button) return;
var oldText = button.textContent;
button.textContent = '<%:Copied%>';
window.setTimeout(function() {
button.textContent = oldText;
}, 1500);
}
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text).then(markCopied);
return;
}
var textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', 'readonly');
textarea.style.position = 'fixed';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
markCopied();
} finally {
document.body.removeChild(textarea);
}
}
function renderCopyablePre(content, className) {
var id = 'et_copy_' + Math.random().toString(36).slice(2);
return '<div class="et-command-panel">' +
'<div class="et-command-toolbar">' +
'<button type="button" class="et-copy-btn" onclick="copyTextFromElement(\'' + id + '\', this); return false;"><%:Copy%></button>' +
'</div>' +
'<div id="' + id + '" class="' + (className || 'et-pre') + '">' + escapeHtml(content) + '</div>' +
'</div>';
}
function parseTable(content, tabName) {
if (!content || content.trim() === '') {
return '<div class="et-empty"><%:No data available%></div>';
@ -916,6 +990,47 @@ function parseTable(content, tabName) {
if (content.indexOf('Error: Invalid service name: "PeerCenterRpc"') !== -1) {
return '<div class="et-error"><%:Peer Center service not available. This feature requires multiple nodes in the network.%></div>';
}
// 启动参数可能包含管道符等特殊字符,必须先于表格解析处理。
if (tabName === 'cmdline') {
var html = renderCopyablePre(content);
// 检查是否使用配置文件启动
if (content.indexOf('--config-file') !== -1 || content.match(/-c\s+\//)) {
XHR.get('<%=url("admin/vpn/easytier/api_conninfo")%>', null, function(x, data) {
if (data && data.config_file) {
var configDiv = document.createElement('div');
configDiv.className = 'et-pre';
configDiv.style.marginTop = '16px';
configDiv.style.borderTop = '2px solid var(--border-color)';
configDiv.style.paddingTop = '16px';
var title = document.createElement('div');
title.style.fontWeight = '600';
title.style.marginBottom = '8px';
title.style.color = 'var(--primary-color)';
title.textContent = tr('Configuration File Content') + ':';
var contentDiv = document.createElement('pre');
contentDiv.style.margin = '0';
contentDiv.style.whiteSpace = 'pre-wrap';
contentDiv.style.overflowWrap = 'anywhere';
contentDiv.style.wordBreak = 'break-word';
contentDiv.textContent = data.config_file;
configDiv.appendChild(title);
configDiv.appendChild(contentDiv);
var container = document.getElementById('tab_cmdline');
if (container) {
container.appendChild(configDiv);
}
}
});
}
return html;
}
// 连接失败错误处理
if (content.indexOf('failed to get peer manager client') !== -1 ||
@ -948,46 +1063,6 @@ function parseTable(content, tabName) {
var lines = content.split(/\r?\n/).filter(function(l) { return l.trim() !== ''; });
if (lines.length === 0 || lines[0].indexOf('|') === -1) {
// 启动参数不翻译
if (tabName === 'cmdline') {
var html = '<div class="et-pre">' + escapeHtml(content) + '</div>';
// 检查是否使用配置文件启动
if (content.indexOf('--config-file') !== -1 || content.match(/-c\s+\//)) {
XHR.get('<%=url("admin/vpn/easytier/api_conninfo")%>', null, function(x, data) {
if (data && data.config_file) {
var configDiv = document.createElement('div');
configDiv.className = 'et-pre';
configDiv.style.marginTop = '16px';
configDiv.style.borderTop = '2px solid var(--border-color)';
configDiv.style.paddingTop = '16px';
var title = document.createElement('div');
title.style.fontWeight = '600';
title.style.marginBottom = '8px';
title.style.color = 'var(--primary-color)';
title.textContent = tr('Configuration File Content') + ':';
var contentDiv = document.createElement('pre');
contentDiv.style.margin = '0';
contentDiv.style.whiteSpace = 'pre-wrap';
contentDiv.style.wordBreak = 'break-all';
contentDiv.textContent = data.config_file;
configDiv.appendChild(title);
configDiv.appendChild(contentDiv);
var container = document.querySelector('.et-tab-content[data-tab="cmdline"]');
if (container) {
container.appendChild(configDiv);
}
}
});
}
return html;
}
// 对非表格内容进行全面翻译处理
var translatedContent = content;

View File

@ -383,7 +383,7 @@ local translate = i18n.translate
<select id="fallback_version_select" class="config-input" style="display:none;width:100%;">
<option value=""><%=translate("Loading versions...")%></option>
</select>
<input type="text" id="fallback_version" class="config-input" placeholder="v2.6.2" style="display:none;width:100%;">
<input type="text" id="fallback_version" class="config-input" placeholder="v2.6.4" style="display:none;width:100%;">
</div>
<button type="button" class="upload-btn" onclick="showDownloadModal()" style="padding:8px 16px;min-width:auto;flex-shrink:0;">
<%=translate("Online Download")%>
@ -758,14 +758,14 @@ function loadConfig() {
proxyList = Array.isArray(proxys) ? proxys : [];
renderProxyList();
versionManager.setVersion(config.fallback_version || 'v2.6.2');
versionManager.setVersion(config.fallback_version || 'v2.6.4');
// 保存原始配置
originalConfig = {
easytierbin: config.easytierbin || '/usr/bin/easytier-core',
webbin: config.webbin || '/usr/bin/easytier-web',
github_proxys: JSON.stringify(proxyList),
fallback_version: config.fallback_version || 'v2.6.2'
fallback_version: config.fallback_version || 'v2.6.4'
};
checkDiskSpace('easytierbin');
@ -843,7 +843,7 @@ function getCurrentConfig() {
easytierbin: document.getElementById('easytierbin').value || '/usr/bin/easytier-core',
webbin: document.getElementById('webbin').value || '/usr/bin/easytier-web',
github_proxys: JSON.stringify(proxyList),
fallback_version: versionManager.getCurrentVersion() || 'v2.6.2'
fallback_version: versionManager.getCurrentVersion() || 'v2.6.4'
};
}
@ -868,7 +868,7 @@ function saveConfig() {
easytierbin: document.getElementById('easytierbin').value || '/usr/bin/easytier-core',
webbin: document.getElementById('webbin').value || '/usr/bin/easytier-web',
github_proxys: proxyList,
fallback_version: versionManager.getCurrentVersion() || 'v2.6.2'
fallback_version: versionManager.getCurrentVersion() || 'v2.6.4'
};
var xhr = new XMLHttpRequest();

View File

@ -1403,3 +1403,12 @@ msgstr ""
msgid "GEOIP Database Path"
msgstr ""
msgid "Copy"
msgstr ""
msgid "Copied"
msgstr ""
msgid "Duplicate extra parameter"
msgstr ""

View File

@ -1267,6 +1267,15 @@ msgstr "统计数据"
msgid "Command Line"
msgstr "启动参数"
msgid "Copy"
msgstr "复制"
msgid "Copied"
msgstr "已复制"
msgid "Duplicate extra parameter"
msgstr "重复的额外参数"
msgid "IPv4 Address"
msgstr "IPv4地址"
@ -2098,4 +2107,3 @@ msgstr "数据库重置成功"
msgid "Restart service to apply changes?"
msgstr "重启服务以生效?"

View File

@ -5,3 +5,5 @@ config easytier
option auto_config_interface '1'
option auto_config_firewall '1'
option interface_netmask '255.0.0.0'
option web_enabled '0'
option webbin '/usr/bin/easytier-web'

View File

@ -71,6 +71,10 @@ get_tz() {
}
fi
shell_quote() {
printf "'%s'" "$(printf "%s" "$1" | sed "s/'/'\\\\''/g")"
}
check_bin() {
# 优先使用 UCI 配置的代理列表list 类型),否则使用默认值
local proxys=""
@ -103,10 +107,15 @@ check_bin() {
# 如果获取失败,从 UCI 配置或使用默认版本
if [ -z "$tag" ]; then
tag=$(uci -q get easytier.@easytier[0].fallback_version)
[ -z "$tag" ] && tag="v2.6.2"
[ -z "$tag" ] && tag="v2.6.4"
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 开始在线下载${tag}版本,${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip下载较慢耐心等候" >>/tmp/easytier.log
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 开始在线下载${tag}版本,${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip下载较慢耐心等候" >>/tmp/easytierweb.log
if ! command -v unzip >/dev/null 2>&1; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 系统缺少 unzip无法解压下载的 EasyTier 压缩包,请安装 unzip 后重试" >>/tmp/easytier.log
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 系统缺少 unzip无法解压下载的 EasyTier 压缩包,请安装 unzip 后重试" >>/tmp/easytierweb.log
return 1
fi
mkdir -p "$path"
for proxy in $proxys ; do
if curl -L -k -o /tmp/easytier.zip --connect-timeout 10 --retry 3 "${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip" || \
@ -205,7 +214,6 @@ get_etconfig() {
quic_port="$(uci -q get easytier.@easytier[0].quic_port)"
peeradd="$(uci -q get easytier.@easytier[0].peeradd)"
desvice_name="$(uci -q get easytier.@easytier[0].desvice_name)"
[ -z "$desvice_name" ] || desvice_name=$(echo "$desvice_name" | sed 's/[\\$`"()|><&;]/\\&/g')
instance_name="$(uci -q get easytier.@easytier[0].instance_name)"
vpn_portal="$(uci -q get easytier.@easytier[0].vpn_portal)"
mtu="$(uci -q get easytier.@easytier[0].mtu)"
@ -442,8 +450,8 @@ start_et() {
core_cmd=""
if [ "$etcmd" = "etcmd" ] ; then
#默认方式启动
[ -z "$network_name" ] || core_cmd="${core_cmd} --network-name $network_name"
[ -z "$network_secret" ] || core_cmd="${core_cmd} --network-secret $network_secret"
[ -z "$network_name" ] || core_cmd="${core_cmd} --network-name $(shell_quote "$network_name")"
[ -z "$network_secret" ] || core_cmd="${core_cmd} --network-secret $(shell_quote "$network_secret")"
[ -z "$ipaddr" ] || core_cmd="${core_cmd} -i $ipaddr"
[ -z "$ip6addr" ] || core_cmd="${core_cmd} --ipv6 $ip6addr"
[ "$ip_dhcp" = "0" ] || core_cmd="${core_cmd} -d"
@ -524,7 +532,7 @@ start_et() {
[ -z "$quic_port" ] || core_cmd="${core_cmd} -l quic:$quic_port"
[ -z "$external_node" ] || core_cmd="${core_cmd} -e $external_node"
[ "$listenermode" = "ON" ] || core_cmd="${core_cmd} --no-listener"
[ -z "$desvice_name" ] || core_cmd="${core_cmd} --hostname $desvice_name"
[ -z "$desvice_name" ] || core_cmd="${core_cmd} --hostname $(shell_quote "$desvice_name")"
[ -z "$instance_name" ] || core_cmd="${core_cmd} -m $instance_name"
[ -z "$vpn_portal" ] || core_cmd="${core_cmd} --vpn-portal $vpn_portal"
[ -z "$mtu" ] || core_cmd="${core_cmd} --mtu $mtu"
@ -563,7 +571,13 @@ start_et() {
[ "$relay_kcp" = "0" ] || core_cmd="${core_cmd} --enable-relay-foreign-network-kcp true"
[ -z "$udp_white_port" ] || core_cmd="${core_cmd} --udp-whitelist $udp_white_port"
[ -z "$tcp_white_port" ] || core_cmd="${core_cmd} --tcp-whitelist $tcp_white_port"
[ -z "$extra_args" ] || core_cmd="${core_cmd} $extra_args"
if [ -n "$extra_args" ] ; then
while IFS= read -r extra_arg; do
[ -n "$extra_arg" ] && core_cmd="${core_cmd} $extra_arg"
done <<EOF
$(sed -n "s/^[[:space:]]*list[[:space:]]\\+extra_args[[:space:]]\\+'\\(.*\\)'[[:space:]]*$/\\1/p" /etc/config/easytier)
EOF
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 运行 ${easytierbin} ${core_cmd} --console-log-level ${log}" >>/tmp/easytier.log
@ -580,7 +594,7 @@ start_et() {
et_uuid="$(cat /etc/easytier/et_machine_id | tr -d ' \n')"
[ -z "$et_uuid" ] || core_cmd="${core_cmd} --machine-id $et_uuid"
[ -z "$web_config" ] || core_cmd="${core_cmd} -w $web_config"
[ -z "$desvice_name" ] || core_cmd="${core_cmd} --hostname $desvice_name"
[ -z "$desvice_name" ] || core_cmd="${core_cmd} --hostname $(shell_quote "$desvice_name")"
fi
procd_set_param command /bin/sh -c "
cd /tmp ; ${easytierbin} ${core_cmd} --console-log-level ${log} >> /tmp/easytier.log 2>&1 &
@ -636,6 +650,7 @@ start_et() {
start_web() {
webbin="$(uci -q get easytier.@easytier[0].webbin)"
[ -z "$webbin" ] && webbin="/usr/bin/easytier-web" && uci -q set easytier.@easytier[0].webbin=/usr/bin/easytier-web
path=$(dirname "$webbin")
if [ -f /tmp/easytier-web-embed ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 找到上传的easytier-web程序替换${webbin} " >>/tmp/easytierweb.log
@ -813,7 +828,7 @@ start_service() {
# 延迟重载网络配置,避免与拨号等网络事件冲突
if [ -n "$(uci changes network)" ] || [ -n "$(uci changes firewall)" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 检测到配置变更将在5秒后后台重载... " >>/tmp/easytier.log
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 检测到配置变更将在5秒后后台重载网络、防火墙... " >>/tmp/easytier.log
(
sleep 5
# 使用锁文件防止重复重载
@ -891,4 +906,3 @@ service_triggers() {
#如果WAN网络接口上线则触发重新启动easytier
# procd_add_interface_trigger "interface.*.up" wan /etc/init.d/easytier reload
}

View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mosdns
PKG_VERSION:=1.7.3
PKG_RELEASE:=9
PKG_RELEASE:=10
LUCI_TITLE:=LuCI Support for mosdns
LUCI_PKGARCH:=all

View File

@ -155,7 +155,6 @@ function update_adlist() {
}
if (download_failed) {
print("\x1b[1;31mRules download failed.\n");
exec_sys(`rm -rf "${ad_tmpdir}"`);
unlink(lock_file);
die("Rules download failed.");
@ -215,7 +214,6 @@ function update_geodat() {
let sum_downloaded = split(exec_sys(`sha256sum "${tmpdir}/geoip.dat"`).stdout, /[ \t\n]+/)[0];
if (sum_downloaded !== geoip_sum_remote) {
print("\x1b[1;31mgeoip.dat checksum error\n");
exec_sys(`rm -rf "${tmpdir}"`); die("geoip.dat checksum error");
}
geoip_updated = true;
@ -248,7 +246,6 @@ function update_geodat() {
let sum_downloaded = split(exec_sys(`sha256sum "${tmpdir}/geosite.dat"`).stdout, /[ \t\n]+/)[0];
if (sum_downloaded !== geosite_sum_remote) {
print("\x1b[1;31mgeosite.dat checksum error\n");
exec_sys(`rm -rf "${tmpdir}"`); die("geosite.dat checksum error");
}
geosite_updated = true;
@ -332,7 +329,7 @@ switch (action) {
print("UPDATE_FINISHED\n");
stdout.flush();
} catch (e) {
print("\x1b[1;31mUpdate failed: " + e + "\n\x1b[0m");
print("Update failed: " + e + "\n");
print("UPDATE_EXITED\n");
stdout.flush();
unlink('/var/lock/mosdns_update.lock');

View File

View File

@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.5.11
PKG_RELEASE:=124
PKG_RELEASE:=125
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \

View File

@ -24,27 +24,50 @@ o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("udp", "UDP")
o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o:depends({ [_n("realms")] = false })
o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port"
o:depends({ [_n("realms")] = false })
o = s:option(Value, _n("hop"), translate("Port hopping range"))
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o.rewrite_option = o.option
o:depends({ [_n("realms")] = false })
o = s:option(Value, _n("hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
o.datatype = "or(uinteger,portrange)"
o.placeholder = "30"
o.default = "30"
o.rewrite_option = o.option
o:depends({ [_n("realms")] = false })
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
o = s:option(Flag, _n("realms"), translate("Realms"))
o.default = "0"
o.rewrite_option = o.option
o = s:option(Value, _n("realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name")
o.rewrite_option = o.option
o:depends({ [_n("realms")] = "1" })
o = s:option(DynamicList, _n("realm_stun"), translate("Realm STUN"))
o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" }
o.rewrite_option = o.option
o:depends({ [_n("realms")] = "1" })
o = s:option(Value, _n("auth_password"), translate("Auth Password"))
o.password = true
o.rewrite_option = o.option
o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o.rewrite_option = o.option
o = s:option(Value, _n("obfs_password"), translate("Obfs Password"))
o.rewrite_option = o.option
o:depends({ [_n("obfs_type")] = "salamander" })
o = s:option(Flag, _n("fast_open"), translate("Fast Open"))
o.default = "0"

View File

@ -339,11 +339,9 @@ o.placeholder = "30"
o.default = "30"
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
@ -353,9 +351,11 @@ o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)")
o:depends({ [_n("protocol")] = "hysteria2"})

View File

@ -353,17 +353,15 @@ if singbox_tags:find("with_quic") then
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(Second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
o.datatype = "or(uinteger,portrange)"
o.placeholder = "30"
o.default = "30"
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
@ -373,8 +371,20 @@ if singbox_tags:find("with_quic") then
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)")
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(Value, _n("hysteria2_keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)")
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(Flag, _n("hysteria2_disable_mtu_discovery"), translate("Disable MTU detection"))
o.default = "0"
o:depends({ [_n("protocol")] = "hysteria2"})
end

View File

@ -26,15 +26,35 @@ o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
o = s:option(Flag, _n("realms"), translate("Realms"))
o.default = "0"
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name")
o.rewrite_option = o.option
o:depends({ [_n("realms")] = "1" })
o = s:option(DynamicList, _n("realm_stun"), translate("Realm STUN"))
o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" }
o.rewrite_option = o.option
o:depends({ [_n("realms")] = "1" })
o = s:option(Value, _n("auth_password"), translate("Auth Password"))
o.password = true
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("obfs_password"), translate("Obfs Password"))
o.rewrite_option = o.option
o:depends({ [_n("obfs_type")] = "salamander" })
o = s:option(Flag, _n("udp"), translate("UDP"))
o.default = "1"
o.rewrite_option = o.option

View File

@ -128,6 +128,14 @@ o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"))
o.default = 0
o:depends({ [_n("protocol")] = "hysteria2" })
@ -138,14 +146,6 @@ o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwid
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false })
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
---- [[ TLS ]]
o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0

View File

@ -158,6 +158,14 @@ if singbox_tags:find("with_quic") then
o.password = true
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"), translate("Commands the client to use the BBR flow control algorithm"))
o.default = 0
o:depends({ [_n("protocol")] = "hysteria2" })
@ -167,14 +175,6 @@ if singbox_tags:find("with_quic") then
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false })
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
end
o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol"))

View File

@ -31,7 +31,11 @@ local type_table = {}
for filename in fs.dir(types_dir) do
table.insert(type_table, filename)
end
table.sort(type_table)
table.sort(type_table, function(a, b)
if a == "socks.lua" then return true end
if b == "socks.lua" then return false end
return a < b
end)
for index, value in ipairs(type_table) do
local p_func = loadfile(types_dir .. value)

View File

@ -5,15 +5,24 @@ local jsonc = api.jsonc
function gen_config_server(node)
local config = {
listen = ":" .. node.port,
listen = (function()
if node.hysteria2_realms and node.hysteria2_realm_url then
local url = node.hysteria2_realm_url:gsub("/+$", "")
if node.port then
url = url .. (url:find("?") and "&lport=" or "?lport=") .. node.port
end
return url
end
return ":" .. (node.port or "0")
end)(),
tls = {
cert = node.tls_certificateFile,
key = node.tls_keyFile,
},
obfs = (node.hysteria2_obfs) and {
obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and {
type = "salamander",
salamander = {
password = node.hysteria2_obfs
password = node.hysteria2_obfs_password
}
} or nil,
auth = {
@ -26,6 +35,9 @@ function gen_config_server(node)
} or nil,
ignoreClientBandwidth = (node.hysteria2_ignoreClientBandwidth == "1") and true or false,
disableUDP = (node.hysteria2_udp == "0") and true or false,
realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and {
stunServers = node.hysteria2_realm_stun
} or nil
}
return config
end
@ -49,7 +61,7 @@ function gen_config(var)
local local_http_password = var["local_http_password"]
local tcp_proxy_way = var["tcp_proxy_way"]
local server_host = var["server_host"] or (node.address or ""):lower()
local server_port = var["server_port"] or node.port
local server_port = var["server_port"] or (node.port or "443")
if api.is_ipv6(server_host) then
server_host = api.get_ipv6_full(server_host)
@ -61,7 +73,15 @@ function gen_config(var)
end
local config = {
server = server,
server = (function()
if node.hysteria2_realms and node.hysteria2_realm_url then
return node.hysteria2_realm_url:gsub("/+$", "")
end
return server
end)(),
realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and {
stunServers = node.hysteria2_realm_stun
} or nil,
transport = {
type = "udp",
udp = node.hysteria2_hop and (function()
@ -86,10 +106,10 @@ function gen_config(var)
return udp
end)() or nil
},
obfs = (node.hysteria2_obfs) and {
obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and {
type = "salamander",
salamander = {
password = node.hysteria2_obfs
password = node.hysteria2_obfs_password
}
} or nil,
auth = node.hysteria2_auth_password,

View File

@ -103,8 +103,8 @@ function gen_outbound(flag, node, tag, proxy_table)
local run_socks_instance = true
if proxy_table ~= nil and type(proxy_table) == "table" then
proxy_tag = proxy_table.tag or nil
fragment = proxy_table.fragment or nil
record_fragment = proxy_table.record_fragment or nil
fragment = (proxy_table.fragment and node.protocol ~= "naive") and true or nil
record_fragment = (proxy_table.record_fragment and node.protocol ~= "naive") and true or nil
run_socks_instance = proxy_table.run_socks_instance
end
@ -485,9 +485,9 @@ function gen_outbound(flag, node, tag, proxy_table)
obfs = node.hysteria_obfs,
auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil,
auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil,
recv_window_conn = tonumber(node.hysteria_recv_window_conn),
recv_window = tonumber(node.hysteria_recv_window),
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false,
recv_window_conn = tonumber(node.hysteria_recv_window_conn), --1.14 将变更为 stream_receive_window
recv_window = tonumber(node.hysteria_recv_window), --1.14 将变更为 connection_receive_window
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false, --1.14 将变更为 disable_path_mtu_discovery
tls = tls
}
end
@ -560,6 +560,17 @@ function gen_outbound(flag, node, tag, proxy_table)
password = node.hysteria2_obfs_password
} or nil,
password = node.hysteria2_auth_password or nil,
idle_timeout = (function(t)
if not version_ge_1_14_0 then return nil end
t = tonumber(tostring(t or "30"):match("^%d+"))
return (t and t >= 4 and t <= 120) and t or 30
end)(node.hysteria2_idle_timeout),
keep_alive_period = (function(t)
if not version_ge_1_14_0 then return nil end
t = tonumber(tostring(t or "0"):match("^%d+"))
return (t and t >= 2 and t <= 60) and t or nil
end)(node.hysteria2_keep_alive_period),
disable_path_mtu_discovery = version_ge_1_14_0 and (tonumber(node.hysteria2_disable_mtu_discovery) == 1) or nil,
tls = tls
}
end
@ -846,10 +857,10 @@ function gen_config_server(node)
auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil,
}
},
recv_window_conn = node.hysteria_recv_window_conn and tonumber(node.hysteria_recv_window_conn) or nil,
recv_window_client = node.hysteria_recv_window_client and tonumber(node.hysteria_recv_window_client) or nil,
max_conn_client = node.hysteria_max_conn_client and tonumber(node.hysteria_max_conn_client) or nil,
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false,
recv_window_conn = node.hysteria_recv_window_conn and tonumber(node.hysteria_recv_window_conn) or nil, --1.14 to stream_receive_window
recv_window_client = node.hysteria_recv_window_client and tonumber(node.hysteria_recv_window_client) or nil, --1.14 to connection_receive_window
max_conn_client = node.hysteria_max_conn_client and tonumber(node.hysteria_max_conn_client) or nil, --1.14 to max_concurrent_streams
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false, --1.14 to disable_path_mtu_discover
tls = tls
}
end

View File

@ -602,10 +602,10 @@ local current_node = map:get(section)
if (v_type === "Hysteria2") {
v_password = opt.get("hysteria2_auth_password");
var dom_obfs = opt.get("hysteria2_obfs");
var dom_obfs = opt.get("hysteria2_obfs_password");
if (dom_obfs && dom_obfs.value != "") {
params += "&obfs=" + "salamander";
params += opt.query("obfs-password", "hysteria2_obfs");
params += opt.query("obfs-password", "hysteria2_obfs_password");
}
params += opt.query("mport", "hysteria2_hop");
} else {
@ -1620,7 +1620,8 @@ local current_node = map:get(section)
dom_prefix = "hysteria2_"
opt.set(dom_prefix + 'auth_password', decodeURIComponent(password));
if (queryParam["obfs-password"] || queryParam["obfs_password"]) {
opt.set(dom_prefix + 'obfs', queryParam["obfs-password"] || queryParam["obfs_password"]);
opt.set(dom_prefix + 'obfs_type', "salamander");
opt.set(dom_prefix + 'obfs_password', queryParam["obfs-password"] || queryParam["obfs_password"]);
}
opt.set(dom_prefix + 'hop', queryParam.mport || "");
}

View File

@ -1415,22 +1415,19 @@ local function processData(szType, content, add_mode, group, sub_cfg)
local insecure = params.allowinsecure or params.insecure
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
result.hysteria2_hop = params.mport
if params["obfs-password"] or params["obfs_password"] then
result.hysteria2_obfs_type = "salamander"
result.hysteria2_obfs_password = params["obfs-password"] or params["obfs_password"]
end
if (sub_hysteria2_type == "sing-box" and has_singbox) or (sub_hysteria2_type == "xray" and has_xray) then
local is_singbox = sub_hysteria2_type == "sing-box" and has_singbox
result.type = is_singbox and 'sing-box' or 'Xray'
result.protocol = "hysteria2"
if params["obfs-password"] or params["obfs_password"] then
result.hysteria2_obfs_type = "salamander"
result.hysteria2_obfs_password = params["obfs-password"] or params["obfs_password"]
end
result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil
result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil
elseif has_hysteria2 then
result.type = "Hysteria2"
if params["obfs-password"] or params["obfs_password"] then
result.hysteria2_obfs = params["obfs-password"] or params["obfs_password"]
end
else
log("跳过 Hysteria2 节点,因未适配到 Hysteria2 核心程序,或未正确设置节点使用类型。")
return nil

View File

@ -7,10 +7,10 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Argon Theme
LUCI_DEPENDS:=+@wget-any +jsonfilter
LUCI_DEPENDS:=+wget-any +jsonfilter
PKG_VERSION:=2.4.3
PKG_RELEASE:=2
PKG_RELEASE:=3
LUCI_MINIFY_CSS:=0

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -257,6 +257,11 @@ select[multiple="multiple"] {
margin: 5em auto;
}
.alert-message {
transform: none;
position: static;
}
.alert-message>h4 {
font-size: 110%;
font-weight: bold;
@ -270,6 +275,11 @@ select[multiple="multiple"] {
padding: .3rem .6rem;
}
#maincontent > .alert-message {
position: fixed;
transform: translate(-50%, -50%);
}
.container .alert,
.container .alert-message {
margin-left: 0;
@ -464,14 +474,16 @@ table>thead>tr>th,
flex: 1 1 auto;
}
tr>td,
tr>th,
.tr>.td,
.tr>.th,
.cbi-section-table-row::before,
#cbi-wireless>#wifi_assoclist_table>.tr:nth-child(2) {
border-top: thin solid #ddd;
padding: 1.1em 1.25rem;
body:not([data-page="admin-dashboard"]) {
tr>td,
tr>th,
.tr>.td,
.tr>.th,
.cbi-section-table-row::before,
#cbi-wireless>#wifi_assoclist_table>.tr:nth-child(2) {
border-top: thin solid #ddd;
padding: 1.1em 1.25rem;
}
}
#cbi-wireless .td,
@ -1431,7 +1443,6 @@ body:not(.Interfaces) .cbi-rowstyle-2:first-child {
cursor: pointer;
user-select: none;
font-size: 0;
color: #8898aa;
background-color: currentColor;
mask-image: var(--dropdown-arrow-icon);
mask-repeat: no-repeat;
@ -2493,6 +2504,26 @@ pre.command-output {
padding: 1.5rem;
}
.alert-message.spinning,
.modal.alert-message.spinning {
position: relative;
&::before {
height: 16px;
width: 16px;
position: absolute;
top: 2rem;
left: 0.5rem;
}
}
.cbi-dropdown.cbi-button-positive>ul>li[display="0"] {
color: #fff;
}
.cbi-dropdown[open]>ul.dropdown>li[selected] {
color: #000;
}
/* page fix */
@import url("page-fix.less");

View File

@ -38,17 +38,19 @@ body {
filter: invert(1);
}
.login-page .login-container {
.login-form {
background-color: #1e1e1e;
-webkit-backdrop-filter: blur(var(--blur-radius-dark)) brightness(0);
backdrop-filter: blur(var(--blur-radius-dark)) brightness(0);
background-color: rgba(0, 0, 0, var(--blur-opacity-dark));
.brand {
color: #adb5bd;
}
.login-page .login-container {
background-color: rgba(0, 0, 0, var(--blur-opacity-dark));
-webkit-backdrop-filter: blur(var(--blur-radius-dark));
backdrop-filter: blur(var(--blur-radius-dark));
.login-form {
background-color: transparent;
-webkit-backdrop-filter: none;
backdrop-filter: none;
.brand {
color: #adb5bd;
}
.form-login {
.input-group {
@ -1069,10 +1071,10 @@ input,
.developer-container {
background: transparent !important;
}
}
.config-upload-content{
background: #1e1e1e !important;
.config-upload-content{
background: #1e1e1e !important;
}
}
.cbi-tabmenu::-webkit-scrollbar-thumb {
@ -1220,3 +1222,19 @@ input,
background-color: rgb(112, 112, 112);
color: #fff;
}
[data-page="admin-system-admin-repokeys"] #key-input {
background-color: #1e1e1e;
color: #ccc;
border: 1px solid #3c3c3c !important;
}
[data-page="admin-system-package-manager"] #modal_overlay textarea{
background-color: #1e1e1e;
color: #ccc;
border: 1px solid #3c3c3c !important;
}
.cbi-dropdown[open]>ul.dropdown>li[selected] {
color: #fff;
}

View File

@ -439,6 +439,7 @@
p span:nth-child(2) {
max-height: 18.5px;
max-width: inherit;
top: 4px;
}

View File

@ -760,6 +760,15 @@
margin-top: 5px;
}
.oc .sub-card:hover {
transform: none;
}
.oc .myip-ip-item:hover,
.oc .myip-check-item:hover {
transform: none;
}
.oc .main-cards-container {
margin: 0 !important;
gap: 0 !important;
@ -867,6 +876,24 @@
background: transparent;
}
// VPN - Passwall2
[data-page^="admin-vpn-passwall2"],
[data-page^="admin-services-passwall2"] {
.tr,
.td,
.th,
.cbi-section-table-row,
#cbi-passwall2-socks,
#cbi-passwall2-socks * {
overflow: visible !important;
max-height: none !important;
transform: none !important;
filter: none !important;
contain: none !important;
clip-path: none !important;
}
}
/* openvpn bug fix */
.OpenVPN a {
line-height: initial !important;
@ -912,6 +939,24 @@
}
}
#cbi-wireless,
#cbi-wireless *,
#wifi_assoclist_table,
#wifi_assoclist_table * {
overflow: visible !important;
max-height: none !important;
transform: none !important;
filter: none !important;
contain: none !important;
clip-path: none !important;
}
#cbi-wireless,
#wifi_assoclist_table {
height: auto !important;
min-height: 0 !important;
}
/* samba */
#cbi-samba [data-tab="template"] {
.cbi-value-field {

View File

@ -88,11 +88,17 @@
// Login form
.login-form {
.absolute-full();
position: relative;
top: 0;
left: 0;
min-height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
max-width: 26rem;
-webkit-backdrop-filter: none;
backdrop-filter: none;
// Brand/Logo section
@ -254,4 +260,4 @@
}
}
}
}
}

View File

@ -62,7 +62,7 @@
<!-- Security -->
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<meta http-equiv="X-Frame-Options" content="SAMEORIGIN">
<!-- <meta http-equiv="X-Frame-Options" content="SAMEORIGIN"> -->
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">

View File

@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=natflow
PKG_VERSION:=20260313
PKG_RELEASE:=8
PKG_RELEASE:=9
PKG_SOURCE:=$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=22c630b387a5ca027bc77d3364818ed87e0a6254
PKG_SOURCE_VERSION:=874c41f26a54920ef7577cf4fe6be8b842be2821
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
PKG_LICENSE:=GPL-2.0

View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=teleproxy
PKG_VERSION:=4.12.2
PKG_RELEASE:=8
PKG_RELEASE:=9
PKG_MAINTAINER:=Kosntantine Shevlakov <shevlakov@132lan.ru>
PKG_LICENSE:=GPLv2
@ -10,7 +10,7 @@ PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/teleproxy/teleproxy.git
PKG_SOURCE_VERSION:=4dc15ffbcce1ae83070ca5da88c8ad80323935c8
PKG_SOURCE_VERSION:=12a822ef794bab357772348d698dfef3a13487de
PKG_SOURCE_SUBDIR:=$(PKG_NAME)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz