mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 18:12:51 +08:00
⛅ Sync 2026-09-22 23:24:55
This commit is contained in:
1 parent
de9cc9a6a9
commit
d45e210b8a
16 files changed
+174
-72
No files matched your search
@@ -12,7 +12,7 @@ LUCI_DEPENDS:=+luci-base +logd +jsonfilter
|
|||||||
LUCI_PKGARCH:=all
|
LUCI_PKGARCH:=all
|
||||||
|
|
||||||
PKG_VERSION:=0.1.45
|
PKG_VERSION:=0.1.45
|
||||||
PKG_RELEASE:=31
|
PKG_RELEASE:=32
|
||||||
|
|
||||||
# Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI).
|
# Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI).
|
||||||
ifdef SOURCE_DATE_EPOCH
|
ifdef SOURCE_DATE_EPOCH
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
/* Copyright 2025-2026 Lucas Albers <lucas.b.albers@gmail.com> */
|
/* Copyright 2025-2026 Lucas Albers <lucas.b.albers@gmail.com> */
|
||||||
'require baseclass'; /* LuCI require() needs Class.isSubclass — plain return {} fails */
|
'require baseclass'; /* LuCI require() needs Class.isSubclass — plain return {} fails */
|
||||||
'require fwlive.log as log';
|
'require fwlive.log as log';
|
||||||
|
'require fwlive.hostname as hostname';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link-builder helpers for luci-app-fwlive.
|
* Link-builder helpers for luci-app-fwlive.
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
* filterLink, addrFilterLink, ruleAdminPath, ruleAdminLink, ifaceLink
|
* filterLink, addrFilterLink, ruleAdminPath, ruleAdminLink, ifaceLink
|
||||||
*
|
*
|
||||||
* No host element — all functions return DOM nodes or strings.
|
* No host element — all functions return DOM nodes or strings.
|
||||||
* May require fwlive.log for formatCell.
|
* May require fwlive.log for formatCell and fwlive.hostname for cache reads.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function luciUrl(path) {
|
function luciUrl(path) {
|
||||||
@@ -75,7 +76,14 @@ function filterLink(field, value, label, onFilterClick) {
|
|||||||
function addrFilterLink(field, ip, showHostnames, hostnameCache, onFilterClick) {
|
function addrFilterLink(field, ip, showHostnames, hostnameCache, onFilterClick) {
|
||||||
if (!ip) return log.formatCell(ip);
|
if (!ip) return log.formatCell(ip);
|
||||||
|
|
||||||
const name = showHostnames && hostnameCache ? hostnameCache.get(ip) : null;
|
let name = null;
|
||||||
|
if (showHostnames && hostnameCache) {
|
||||||
|
/* Display reads refresh recency so visible names remain warm in the LRU. */
|
||||||
|
name =
|
||||||
|
hostname && typeof hostname.lruGet === 'function'
|
||||||
|
? hostname.lruGet(hostnameCache, ip)
|
||||||
|
: hostnameCache.get(ip);
|
||||||
|
}
|
||||||
const display = name || ip;
|
const display = name || ip;
|
||||||
const title = name ? ip : _('Filter by %s').format(field);
|
const title = name ? ip : _('Filter by %s').format(field);
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ function labelWithZoneCandidates(label, st) {
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function appendLoggingNotice(host, state) {
|
||||||
|
if (!state.loggingNotice) return;
|
||||||
|
host.appendChild(E('span', { 'class': 'fwlive-logging-notice' }, [state.loggingNotice]));
|
||||||
|
}
|
||||||
|
|
||||||
function renderToolbar(host, state, callbacks) {
|
function renderToolbar(host, state, callbacks) {
|
||||||
host.innerHTML = '';
|
host.innerHTML = '';
|
||||||
const st = state.loggingStatus;
|
const st = state.loggingStatus;
|
||||||
@@ -107,6 +112,7 @@ function renderToolbar(host, state, callbacks) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
host.appendChild(links.firewallZonesLink());
|
host.appendChild(links.firewallZonesLink());
|
||||||
|
appendLoggingNotice(host, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +122,7 @@ function renderToolbar(host, state, callbacks) {
|
|||||||
_('WAN logging unavailable: missing kernel log modules')
|
_('WAN logging unavailable: missing kernel log modules')
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
appendLoggingNotice(host, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +151,7 @@ function renderToolbar(host, state, callbacks) {
|
|||||||
children
|
children
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
appendLoggingNotice(host, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +170,7 @@ function renderToolbar(host, state, callbacks) {
|
|||||||
[state.loggingBusy ? _('Enabling…') : _('Enable logging')]
|
[state.loggingBusy ? _('Enabling…') : _('Enable logging')]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
appendLoggingNotice(host, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildConsentPanel(state, callbacks) {
|
function buildConsentPanel(state, callbacks) {
|
||||||
|
|||||||
@@ -77,6 +77,14 @@ function createScheduler(options) {
|
|||||||
const elapsed = bucketMs === null ? 0 : Math.max(0, timestamp - bucketMs);
|
const elapsed = bucketMs === null ? 0 : Math.max(0, timestamp - bucketMs);
|
||||||
bucketMs = timestamp;
|
bucketMs = timestamp;
|
||||||
bucket = Math.min(capacity, bucket + (elapsed * capacity) / 1000);
|
bucket = Math.min(capacity, bucket + (elapsed * capacity) / 1000);
|
||||||
|
/* A single batch can cost more than one second's budget. Once the
|
||||||
|
* bucket is full, spend that full interval on one paint so a sustained
|
||||||
|
* flood cannot freeze the table until the user changes a control. */
|
||||||
|
if (cost > bucket && bucket >= capacity) {
|
||||||
|
bucket = 0;
|
||||||
|
floodSuppressed = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
floodSuppressed = cost > bucket;
|
floodSuppressed = cost > bucket;
|
||||||
if (floodSuppressed) return false;
|
if (floodSuppressed) return false;
|
||||||
bucket -= cost;
|
bucket -= cost;
|
||||||
|
|||||||
@@ -683,10 +683,15 @@ return view.extend({
|
|||||||
const status = await callFwliveLoggingStatus();
|
const status = await callFwliveLoggingStatus();
|
||||||
if (this.viewDisposed) return;
|
if (this.viewDisposed) return;
|
||||||
this.loggingStatus = status;
|
this.loggingStatus = status;
|
||||||
|
this.loggingNotice = '';
|
||||||
this.weakDevice = !!(this.loggingStatus && this.loggingStatus.weak_device === true);
|
this.weakDevice = !!(this.loggingStatus && this.loggingStatus.weak_device === true);
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
if (this.viewDisposed) return;
|
if (this.viewDisposed) return;
|
||||||
this.loggingStatus = null;
|
/* Keep last toolbar state. Do not clobber a toggle success/failure notice. */
|
||||||
|
if (!this.loggingNotice)
|
||||||
|
this.loggingNotice = _(
|
||||||
|
'Could not refresh logging status; showing the last known state.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.updateBackendUi();
|
this.updateBackendUi();
|
||||||
this.updateLoggingToolbarUi();
|
this.updateLoggingToolbarUi();
|
||||||
@@ -712,6 +717,10 @@ return view.extend({
|
|||||||
|
|
||||||
this.loggingNotice = opts.successNotice(res);
|
this.loggingNotice = opts.successNotice(res);
|
||||||
if (opts.onSuccess) opts.onSuccess(res);
|
if (opts.onSuccess) opts.onSuccess(res);
|
||||||
|
if (this.loggingStatus && typeof opts.wanLog === 'boolean')
|
||||||
|
this.loggingStatus = Object.assign({}, this.loggingStatus, {
|
||||||
|
wan_log: opts.wanLog
|
||||||
|
});
|
||||||
await this.loadLoggingStatus();
|
await this.loadLoggingStatus();
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
this.loggingNotice = opts.catchNotice();
|
this.loggingNotice = opts.catchNotice();
|
||||||
@@ -725,6 +734,7 @@ return view.extend({
|
|||||||
|
|
||||||
async handleEnableLogging() {
|
async handleEnableLogging() {
|
||||||
return this.runLoggingToggle({
|
return this.runLoggingToggle({
|
||||||
|
wanLog: true,
|
||||||
call: () => callFwliveEnableLogging(),
|
call: () => callFwliveEnableLogging(),
|
||||||
initialUi: () => {
|
initialUi: () => {
|
||||||
this.updateEmptyStateUi();
|
this.updateEmptyStateUi();
|
||||||
@@ -752,6 +762,7 @@ return view.extend({
|
|||||||
|
|
||||||
async handleDisableLogging() {
|
async handleDisableLogging() {
|
||||||
return this.runLoggingToggle({
|
return this.runLoggingToggle({
|
||||||
|
wanLog: false,
|
||||||
call: () => callFwliveDisableLogging(),
|
call: () => callFwliveDisableLogging(),
|
||||||
initialUi: () => this.updateLoggingToolbarUi(),
|
initialUi: () => this.updateLoggingToolbarUi(),
|
||||||
failureNotice: (res) => {
|
failureNotice: (res) => {
|
||||||
@@ -1333,7 +1344,14 @@ return view.extend({
|
|||||||
this.summaryRowsShown = false;
|
this.summaryRowsShown = false;
|
||||||
this.summaryData = null;
|
this.summaryData = null;
|
||||||
this.updateSummaryUi();
|
this.updateSummaryUi();
|
||||||
this.renderRows(true);
|
if (this.tablePaused) {
|
||||||
|
const empty = document.getElementById('fwlive-empty');
|
||||||
|
if (empty) {
|
||||||
|
const rows = this.filteredRows();
|
||||||
|
empty.style.display = rows.length ? 'none' : 'block';
|
||||||
|
}
|
||||||
|
this.updateStatus();
|
||||||
|
} else this.renderRows(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
onSummaryRowsToggle() {
|
onSummaryRowsToggle() {
|
||||||
@@ -1469,8 +1487,10 @@ return view.extend({
|
|||||||
this.resolveGeneration = (this.resolveGeneration || 0) + 1;
|
this.resolveGeneration = (this.resolveGeneration || 0) + 1;
|
||||||
this.resolveInFlight = false;
|
this.resolveInFlight = false;
|
||||||
|
|
||||||
if (this.showHostnames) this.resolveHostnamesForEntries(this.filteredRows());
|
/* Paint the existing cache immediately; resolving only fills misses. */
|
||||||
|
if (this.tablePaused) this.updateStatus();
|
||||||
else this.renderRows(true);
|
else this.renderRows(true);
|
||||||
|
if (this.showHostnames) this.resolveHostnamesForEntries(this.filteredRows());
|
||||||
},
|
},
|
||||||
|
|
||||||
onFetchModeChange(ev) {
|
onFetchModeChange(ev) {
|
||||||
@@ -1646,7 +1666,7 @@ return view.extend({
|
|||||||
|
|
||||||
for (let i = 0; i < ips.length && need.length < 32; i++) {
|
for (let i = 0; i < ips.length && need.length < 32; i++) {
|
||||||
const ip = ips[i];
|
const ip = ips[i];
|
||||||
if (this.hostnameCache.has(ip)) continue;
|
if (hostname.lruGet(this.hostnameCache, ip) !== undefined) continue;
|
||||||
if (hostname.failIsHot(this.hostnameFailed, ip, now)) continue;
|
if (hostname.failIsHot(this.hostnameFailed, ip, now)) continue;
|
||||||
need.push(ip);
|
need.push(ip);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,10 @@ msgstr "Connection lost — retrying…"
|
|||||||
msgid "Could not disable logging."
|
msgid "Could not disable logging."
|
||||||
msgstr "Protokollierung konnte nicht deaktiviert werden."
|
msgstr "Protokollierung konnte nicht deaktiviert werden."
|
||||||
|
|
||||||
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||||
|
msgid "Could not refresh logging status; showing the last known state."
|
||||||
|
msgstr "Could not refresh logging status; showing the last known state."
|
||||||
|
|
||||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||||
msgid "Could not enable logging."
|
msgid "Could not enable logging."
|
||||||
msgstr "Protokollierung konnte nicht aktiviert werden."
|
msgstr "Protokollierung konnte nicht aktiviert werden."
|
||||||
|
|||||||
@@ -129,6 +129,10 @@ msgstr "Connection lost — retrying…"
|
|||||||
msgid "Could not disable logging."
|
msgid "Could not disable logging."
|
||||||
msgstr "Ðе ÑдалоÑÑ Ð¾ÑклÑÑиÑÑ Ð¶ÑÑналиÑование."
|
msgstr "Ðе ÑдалоÑÑ Ð¾ÑклÑÑиÑÑ Ð¶ÑÑналиÑование."
|
||||||
|
|
||||||
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||||
|
msgid "Could not refresh logging status; showing the last known state."
|
||||||
|
msgstr "Could not refresh logging status; showing the last known state."
|
||||||
|
|
||||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||||
msgid "Could not enable logging."
|
msgid "Could not enable logging."
|
||||||
msgstr "Ðе ÑдалоÑÑ Ð²ÐºÐ»ÑÑиÑÑ Ð¶ÑÑналиÑование."
|
msgstr "Ðе ÑдалоÑÑ Ð²ÐºÐ»ÑÑиÑÑ Ð¶ÑÑналиÑование."
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ msgstr ""
|
|||||||
msgid "Could not disable logging."
|
msgid "Could not disable logging."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||||
|
msgid "Could not refresh logging status; showing the last known state."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||||
msgid "Could not enable logging."
|
msgid "Could not enable logging."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ msgstr "Connection lost — retrying…"
|
|||||||
msgid "Could not disable logging."
|
msgid "Could not disable logging."
|
||||||
msgstr "æ æ³"
|
msgstr "æ æ³"
|
||||||
|
|
||||||
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:690
|
||||||
|
msgid "Could not refresh logging status; showing the last known state."
|
||||||
|
msgstr "Could not refresh logging status; showing the last known state."
|
||||||
|
|
||||||
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:573
|
||||||
msgid "Could not enable logging."
|
msgid "Could not enable logging."
|
||||||
msgstr "æ æ³å¼å¯æ¥å¿è®°å½ã"
|
msgstr "æ æ³å¼å¯æ¥å¿è®°å½ã"
|
||||||
|
|||||||
@@ -276,7 +276,8 @@ fwlive_adaptive_bucket_for_ms() {
|
|||||||
|
|
||||||
# Args: requested_limit duration_ms prev_limit prev_bucket prev_warm
|
# Args: requested_limit duration_ms prev_limit prev_bucket prev_warm
|
||||||
# prev_completed_cs planning
|
# prev_completed_cs planning
|
||||||
# Prints next limit.
|
# Prints next limit. A full-sized cold sample may retain one upward probe
|
||||||
|
# above the number of lines served; planning then holds that retained probe.
|
||||||
fwlive_adaptive_compute_limit() {
|
fwlive_adaptive_compute_limit() {
|
||||||
_req=$1
|
_req=$1
|
||||||
_ms=$2
|
_ms=$2
|
||||||
@@ -343,7 +344,21 @@ fwlive_adaptive_compute_limit() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
case "$_bucket" in
|
case "$_bucket" in
|
||||||
cold) _limit=$_max ;;
|
cold)
|
||||||
|
_base=$_prev_l
|
||||||
|
[ "$_base" -lt 1 ] && _base=$_max
|
||||||
|
if [ "$_planning" = 1 ]; then
|
||||||
|
# Keep a cold probe at the limit that was actually retained.
|
||||||
|
_limit=$_base
|
||||||
|
elif [ "$_req" -ge "$_base" ]; then
|
||||||
|
# A full-sized cold sample earns one doubling, not a jump
|
||||||
|
# from the 250-line floor straight to the maximum.
|
||||||
|
_limit=$((_base * 2))
|
||||||
|
else
|
||||||
|
# A short cold sample does not prove the larger request is safe.
|
||||||
|
_limit=$_base
|
||||||
|
fi
|
||||||
|
;;
|
||||||
cool)
|
cool)
|
||||||
# A healthy cooldown probe may retain its raised limit for the
|
# A healthy cooldown probe may retain its raised limit for the
|
||||||
# short probe window. Ordinary cool samples still use the fixed
|
# short probe window. Ordinary cool samples still use the fixed
|
||||||
@@ -370,7 +385,10 @@ fwlive_adaptive_compute_limit() {
|
|||||||
hot) _limit=$FWLIVE_ADAPTIVE_HOT_FLOOR ;;
|
hot) _limit=$FWLIVE_ADAPTIVE_HOT_FLOOR ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
[ "$_limit" -gt "$_req" ] && _limit=$_req
|
if [ "$_planning" = 1 ] || [ "$_bucket" != cold ] || \
|
||||||
|
[ "$_prev_l" -lt 1 ] || [ "$_req" -lt "$_prev_l" ]; then
|
||||||
|
[ "$_limit" -gt "$_req" ] && _limit=$_req
|
||||||
|
fi
|
||||||
[ "$_limit" -gt "$_max" ] && _limit=$_max
|
[ "$_limit" -gt "$_max" ] && _limit=$_max
|
||||||
[ "$_limit" -lt 1 ] && _limit=1
|
[ "$_limit" -lt 1 ] && _limit=1
|
||||||
printf '%s\n' "$_limit"
|
printf '%s\n' "$_limit"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=luci-app-passwall
|
PKG_NAME:=luci-app-passwall
|
||||||
PKG_VERSION:=26.9.16
|
PKG_VERSION:=26.9.16
|
||||||
PKG_RELEASE:=286
|
PKG_RELEASE:=287
|
||||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:= \
|
PKG_CONFIG_DEPENDS:= \
|
||||||
|
|||||||
@@ -197,16 +197,19 @@ function exec_call(cmd)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function base64Decode(text)
|
function base64Decode(text)
|
||||||
if not text then return '' end
|
if type(text) ~= "string" then return "" end
|
||||||
local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+")
|
local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+"):gsub("=+$", "")
|
||||||
|
if encoded == "" then return text end
|
||||||
|
if not encoded:match("^[A-Za-z0-9+/]*$") then return text end
|
||||||
local mod4 = #encoded % 4
|
local mod4 = #encoded % 4
|
||||||
encoded = encoded .. string.sub('====', mod4 + 1)
|
if mod4 == 1 then return text end
|
||||||
local result = nixio.bin.b64decode(encoded)
|
local padded = encoded .. string.rep("=", (4 - mod4) % 4)
|
||||||
if result then
|
local result = nixio.bin.b64decode(padded)
|
||||||
return result:gsub("%z", "")
|
if not result then return text end
|
||||||
else
|
-- Verify that the normalized input is canonical Base64.
|
||||||
return text
|
local reencoded = nixio.bin.b64encode(result):gsub("=+$", "")
|
||||||
end
|
if reencoded ~= encoded then return text end
|
||||||
|
return (result:gsub("%z", ""))
|
||||||
end
|
end
|
||||||
|
|
||||||
function base64Encode(text)
|
function base64Encode(text)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=luci-app-xray
|
PKG_NAME:=luci-app-xray
|
||||||
PKG_VERSION:=3.7.2
|
PKG_VERSION:=3.7.2
|
||||||
PKG_RELEASE:=9
|
PKG_RELEASE:=10
|
||||||
|
|
||||||
PKG_LICENSE:=MPLv2
|
PKG_LICENSE:=MPLv2
|
||||||
PKG_LICENSE_FILES:=LICENSE
|
PKG_LICENSE_FILES:=LICENSE
|
||||||
|
|||||||
@@ -2,52 +2,70 @@
|
|||||||
|
|
||||||
import { server_outbound } from "./outbound.mjs";
|
import { server_outbound } from "./outbound.mjs";
|
||||||
|
|
||||||
|
function manual_tproxy_redirect(v) {
|
||||||
|
return sprintf("%s:%d", v["dest_addr"] || "", v["dest_port"] || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function manual_tproxy_outbound_tag(v, name) {
|
||||||
|
return `manual_tproxy:${v[".name"]}@${name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function manual_tproxy_force_forward_tag(v, name, force_forward_key, server_key) {
|
||||||
|
if (v[force_forward_key] !== "1" || v[server_key] == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return `manual_tproxy:${v[".name"]}@${name}@force_forward:${v[server_key]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function manual_tproxy_needs_dialer_proxy(v, force_forward_key, server_key) {
|
||||||
|
if (v[force_forward_key] !== "1") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (v[server_key] == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (manual_tproxy_redirect(v) !== ":0") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function manual_tproxy_outbound(config, v, name, force_forward_key, server_key) {
|
||||||
|
const force_forward_tag = manual_tproxy_force_forward_tag(v, name, force_forward_key, server_key);
|
||||||
|
let result = [];
|
||||||
|
if (force_forward_tag != null) {
|
||||||
|
push(result, ...server_outbound(config[v[server_key]], force_forward_tag, config));
|
||||||
|
}
|
||||||
|
if (manual_tproxy_needs_dialer_proxy(v, force_forward_key, server_key)) {
|
||||||
|
push(result, {
|
||||||
|
protocol: "freedom",
|
||||||
|
tag: manual_tproxy_outbound_tag(v, name),
|
||||||
|
settings: {
|
||||||
|
redirect: manual_tproxy_redirect(v),
|
||||||
|
domainStrategy: "AsIs"
|
||||||
|
},
|
||||||
|
streamSettings: {
|
||||||
|
sockOpt: {
|
||||||
|
dialerProxy: force_forward_tag != null ? force_forward_tag : "direct"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function manual_tproxy_rule_tag(v, name, force_forward_key, server_key) {
|
||||||
|
if (manual_tproxy_needs_dialer_proxy(v, force_forward_key, server_key)) {
|
||||||
|
return manual_tproxy_outbound_tag(v, name);
|
||||||
|
}
|
||||||
|
return manual_tproxy_force_forward_tag(v, name, force_forward_key, server_key);
|
||||||
|
}
|
||||||
|
|
||||||
export function manual_tproxy_outbounds(config, manual_tproxy) {
|
export function manual_tproxy_outbounds(config, manual_tproxy) {
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let v in manual_tproxy) {
|
for (let v in manual_tproxy) {
|
||||||
let tcp_tag = "direct";
|
push(result, ...manual_tproxy_outbound(config, v, "tcp_outbound", "force_forward_tcp", "force_forward_server_tcp"));
|
||||||
if (v["force_forward_tcp"] === "1") {
|
push(result, ...manual_tproxy_outbound(config, v, "udp_outbound", "force_forward_udp", "force_forward_server_udp"));
|
||||||
if (v["force_forward_server_tcp"] != null) {
|
|
||||||
tcp_tag = `manual_tproxy:${v[".name"]}@tcp_outbound@force_forward:${v["force_forward_server_tcp"]}`;
|
|
||||||
const force_forward_server_tcp = config[v["force_forward_server_tcp"]];
|
|
||||||
push(result, ...server_outbound(force_forward_server_tcp, tcp_tag, config));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
push(result, {
|
|
||||||
protocol: "freedom",
|
|
||||||
tag: sprintf("manual_tproxy:%s@tcp_outbound", v[".name"]),
|
|
||||||
settings: {
|
|
||||||
redirect: sprintf("%s:%d", v["dest_addr"] || "", v["dest_port"] || 0),
|
|
||||||
domainStrategy: "AsIs"
|
|
||||||
},
|
|
||||||
streamSettings: {
|
|
||||||
sockOpt: {
|
|
||||||
dialerProxy: tcp_tag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let udp_tag = "direct";
|
|
||||||
if (v["force_forward_udp"] === "1") {
|
|
||||||
if (v["force_forward_server_udp"] != null) {
|
|
||||||
udp_tag = `manual_tproxy:${v[".name"]}@udp_outbound@force_forward:${v["force_forward_server_udp"]}`;
|
|
||||||
const force_forward_server_udp = config[v["force_forward_server_udp"]];
|
|
||||||
push(result, ...server_outbound(force_forward_server_udp, udp_tag, config));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
push(result, {
|
|
||||||
protocol: "freedom",
|
|
||||||
tag: sprintf("manual_tproxy:%s@udp_outbound", v[".name"]),
|
|
||||||
settings: {
|
|
||||||
redirect: sprintf("%s:%d", v["dest_addr"] || "", v["dest_port"] || 0),
|
|
||||||
domainStrategy: "AsIs"
|
|
||||||
},
|
|
||||||
streamSettings: {
|
|
||||||
sockOpt: {
|
|
||||||
dialerProxy: udp_tag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -55,11 +73,13 @@ export function manual_tproxy_outbounds(config, manual_tproxy) {
|
|||||||
export function manual_tproxy_outbound_tags(manual_tproxy) {
|
export function manual_tproxy_outbound_tags(manual_tproxy) {
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let v in manual_tproxy) {
|
for (let v in manual_tproxy) {
|
||||||
if (v["force_forward_tcp"] === "1") {
|
const tcp_tag = manual_tproxy_force_forward_tag(v, "tcp_outbound", "force_forward_tcp", "force_forward_server_tcp");
|
||||||
push(result, `manual_tproxy:${v[".name"]}@tcp_outbound@force_forward:${v["force_forward_server_tcp"]}`);
|
if (tcp_tag != null) {
|
||||||
|
push(result, tcp_tag);
|
||||||
}
|
}
|
||||||
if (v["force_forward_udp"] === "1") {
|
const udp_tag = manual_tproxy_force_forward_tag(v, "udp_outbound", "force_forward_udp", "force_forward_server_udp");
|
||||||
push(result, `manual_tproxy:${v[".name"]}@udp_outbound@force_forward:${v["force_forward_server_udp"]}`);
|
if (udp_tag != null) {
|
||||||
|
push(result, udp_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -73,14 +93,14 @@ export function manual_tproxy_rules(manual_tproxy) {
|
|||||||
inboundTag: ["tproxy_tcp_inbound_v4", "tproxy_tcp_inbound_v6", "socks_inbound", "https_inbound", "http_inbound"],
|
inboundTag: ["tproxy_tcp_inbound_v4", "tproxy_tcp_inbound_v6", "socks_inbound", "https_inbound", "http_inbound"],
|
||||||
ip: [v["source_addr"]],
|
ip: [v["source_addr"]],
|
||||||
port: v["source_port"],
|
port: v["source_port"],
|
||||||
outboundTag: sprintf("manual_tproxy:%s@tcp_outbound", v[".name"])
|
outboundTag: manual_tproxy_rule_tag(v, "tcp_outbound", "force_forward_tcp", "force_forward_server_tcp")
|
||||||
});
|
});
|
||||||
splice(result, 0, 0, {
|
splice(result, 0, 0, {
|
||||||
type: "field",
|
type: "field",
|
||||||
inboundTag: ["tproxy_udp_inbound_v4", "tproxy_udp_inbound_v6"],
|
inboundTag: ["tproxy_udp_inbound_v4", "tproxy_udp_inbound_v6"],
|
||||||
ip: [v["source_addr"]],
|
ip: [v["source_addr"]],
|
||||||
port: v["source_port"],
|
port: v["source_port"],
|
||||||
outboundTag: sprintf("manual_tproxy:%s@udp_outbound", v[".name"])
|
outboundTag: manual_tproxy_rule_tag(v, "udp_outbound", "force_forward_udp", "force_forward_server_udp")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
LUCI_TITLE:=Argon Theme
|
LUCI_TITLE:=Argon Theme
|
||||||
LUCI_DEPENDS:=+USE_APK:wget-any +!USE_APK:wget +jsonfilter
|
LUCI_DEPENDS:=+USE_APK:wget-any +!USE_APK:wget +jsonfilter
|
||||||
PKG_VERSION:=2.4.7
|
PKG_VERSION:=2.4.7
|
||||||
PKG_RELEASE:=15
|
PKG_RELEASE:=16
|
||||||
|
|
||||||
CONFIG_LUCI_CSSTIDY:=
|
CONFIG_LUCI_CSSTIDY:=
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
body{background:#1e1e1e;color:#ccc}.spinning::before{filter:invert(1)}.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-page .login-container .login-form{background-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.login-page .login-container .login-form .brand{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group::before{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group input{background-color:transparent!important;color:#adb5bd;border-bottom:#adb5bd 1px solid!important;border-radius:0!important;border-top:none!important;border-left:none!important;border-right:none!important;box-shadow:none}.login-page .login-container .login-form .form-login .cbi-button-apply{background-color:#483d8b!important;background-color:var(--dark-primary)!important}.login-page .login-container .login-form .form-login .cbi-button-apply:focus,.login-page .login-container .login-form .form-login .cbi-button-apply:hover{opacity:.9}header::after{background-color:#1e1e1e!important}.main .main-left{background-color:#333!important;box-shadow:0 0 .5rem 0 rgba(0,0,0,.15)}.main .main-left .sidenav-header .brand{color:#ccc}.main .main-left .nav .slide .slide-menu .active a{color:#ccc}.main .main-left .nav .slide .slide-menu .active a::after{background-color:#ccc!important}.main .main-left .nav .slide .slide-menu .active::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .slide-menu li a{color:#ccc}.main .main-left .nav .slide .slide-menu li a:hover{background:0 0!important}.main .main-left .nav .slide .slide-menu li::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .menu.active{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left .nav .slide .menu.active a::after{background-color:#fff!important}.main .main-left .nav li a{color:#ccc!important}.main .main-left .nav li a:hover{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left::-webkit-scrollbar-thumb{background-color:#252526!important}.main .main-left::-webkit-scrollbar-track{background-color:#333}.main .main-right{background-color:#1e1e1e}h2{color:#ccc;background:#333}h3{color:#ccc;border-bottom:0;background:#333}h4{color:#8c6900}abbr{color:var(--dark-primary)!important}a:active,a:link,a:visited{color:#a5b2ff}input:-webkit-autofill{background-color:#3c3c3c!important}#channel_graph{background-color:transparent!important}.cbi-button-apply,.cbi-button-edit,.cbi-value-field .cbi-input-apply{color:#fff!important;background-color:#483d8b!important;background-color:var(--dark-primary)!important;border-color:#483d8b!important;border-color:var(--dark-primary)!important}.cbi-section em{color:#ccc}header.bg-primary{background-color:#1e1e1e!important}.cbi-map-descr{color:#ccc}.cbi-section{background:0 0;box-shadow:0 0 .5rem 0 rgba(0,0,0,.35)}.panel-title{color:#ccc;background-color:#333}div>.table>.tr:nth-of-type(2n),div>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{color:#ccc}fieldset>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{border-top:1px solid #252526}#conns>div>div,#membuff>div>div,#memfree>div>div,#memtotal>div>div,#swapfree>div>div,#swaptotal>div>div{background-color:var(--dark-primary)!important}#conns>div>div>div>small,#membuff>div>div>div>small,#memfree>div>div>div>small,#memtotal>div>div>div>small,#swapfree>div>div>div>small,#swaptotal>div>div>div>small{color:#ccc!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last{line-height:1.8em}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"]{border:1px solid #999!important;background-color:transparent!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"] div{background-color:#ba8b00!important}table>tbody>tr>th,table>tfoot>tr>th,table>thead>tr>th{background-color:#252526;border-bottom:#000 1px solid!important}.tr.cbi-section-table-titles.named::before,.tr[data-title]::before{background-color:#252526}#cbi-wireless>#wifi_assoclist_table>.tr:nth-child(2),.cbi-section-table-row::before,.tr>.td,.tr>.th,tr>td,tr>th{border-top:0}.cbi-rowstyle-2{background-color:#1e1e1e}.cbi-rowstyle-1{background-color:#252526}.cbi-rowstyle-2 .cbi-button-down,.cbi-rowstyle-2 .cbi-button-up,body:not(.Interfaces) .cbi-rowstyle-2:first-child{background-color:#666!important}.cbi-section>h3:first-child,.panel-title,h3{color:#ccc}h4{background-color:#1e1e1f}.cLine truncated
|
body{background:#1e1e1e;color:#ccc}.spinning::before{filter:invert(1)}.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-page .login-container .login-form{background-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.login-page .login-container .login-form .brand{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group::before{color:#adb5bd}.login-page .login-container .login-form .form-login .input-group input{background-color:transparent!important;color:#adb5bd;border-bottom:#adb5bd 1px solid!important;border-radius:0!important;border-top:none!important;border-left:none!important;border-right:none!important;box-shadow:none}.login-page .login-container .login-form .form-login .cbi-button-apply{background-color:#483d8b!important;background-color:var(--dark-primary)!important}.login-page .login-container .login-form .form-login .cbi-button-apply:focus,.login-page .login-container .login-form .form-login .cbi-button-apply:hover{opacity:.9}header::after{background-color:#1e1e1e!important}.main .main-left{background-color:#333!important;box-shadow:0 0 .5rem 0 rgba(0,0,0,.15)}.main .main-left .sidenav-header .brand{color:#ccc}.main .main-left .nav .slide .slide-menu .active a{color:#ccc}.main .main-left .nav .slide .slide-menu .active a::after{background-color:#ccc!important}.main .main-left .nav .slide .slide-menu .active::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .slide-menu li a{color:#ccc}.main .main-left .nav .slide .slide-menu li a:hover{background:0 0!important}.main .main-left .nav .slide .slide-menu li::after{background-color:var(--dark-primary)!important}.main .main-left .nav .slide .menu.active{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left .nav .slide .menu.active a::after{background-color:#fff!important}.main .main-left .nav li a{color:#ccc!important}.main .main-left .nav li a:hover{background-color:#483d8b!important;background-color:var(--dark-primary)!important;color:#fff!important}.main .main-left::-webkit-scrollbar-thumb{background-color:#252526!important}.main .main-left::-webkit-scrollbar-track{background-color:#333}.main .main-right{background-color:#1e1e1e}h2{color:#ccc;background:#333}h3{color:#ccc;border-bottom:0;background:#333}h4{color:#8c6900}abbr{color:var(--dark-primary)!important}a:active,a:link,a:visited{color:#a5b2ff}input:-webkit-autofill{background-color:#3c3c3c!important}#channel_graph{background-color:transparent!important}.cbi-button-apply,.cbi-button-edit,.cbi-value-field .cbi-input-apply{color:#fff!important;background-color:#483d8b!important;background-color:var(--dark-primary)!important;border-color:#483d8b!important;border-color:var(--dark-primary)!important}.cbi-section em{color:#ccc}header.bg-primary{background-color:#1e1e1e!important}.cbi-map-descr{color:#ccc}.cbi-section{background:0 0;box-shadow:0 0 .5rem 0 rgba(0,0,0,.35)}.panel-title{color:#ccc;background-color:#333}div>.table>.tr:nth-of-type(2n),div>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{color:#ccc}fieldset>table>tbody>tr:nth-of-type(2n){background-color:#252526}table>tbody>tr>td,table>tfoot>tr>td,table>thead>tr>td{border-top:1px solid #252526}#conns>div>div,#membuff>div>div,#memfree>div>div,#memtotal>div>div,#swapfree>div>div,#swaptotal>div>div{background-color:var(--dark-primary)!important}#conns>div>div>div>small,#membuff>div>div>div>small,#memfree>div>div>div>small,#memtotal>div>div>div>small,#swapfree>div>div>div>small,#swaptotal>div>div>div>small{color:#ccc!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last{line-height:1.8em}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"]{border:1px solid #999!important;background-color:transparent!important}.node-system-packages>.main .cbi-section-node:first-child .cbi-value-last div[style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080"] div{background-color:#ba8b00!important}table>tbody>tr>th,table>tfoot>tr>th,table>thead>tr>th{background-color:#252526;border-bottom:#000 1px solid!important}.tr.cbi-section-table-titles.named::before,.tr[data-title]::before{background-color:#252526}#cbi-wireless>#wifi_assoclist_table>.tr:nth-child(2),.cbi-section-table-row::before,.tr>.td,.tr>.th,tr>td,tr>th{border-top:0}.cbi-rowstyle-2{background-color:#1e1e1e}.cbi-rowstyle-1{background-color:#252526}.cbi-rowstyle-2 .cbi-button-down,.cbi-rowstyle-2 .cbi-button-up,body:not(.Interfaces) .cbi-rowstyle-2:first-child{background-color:#666!important}.cbi-section>h3:first-child,.panel-title,h3{color:#ccc}h4{background-color:#1e1e1f}.cLine truncated
|
||||||
Reference in new issue
Block a user