mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 18:52:51 +08:00
🐤 Sync 2026-08-14 17:37:24
This commit is contained in:
1 parent
706ba9bda3
commit
badefb504c
85 files changed
+2298
-2242
No files matched your search
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-daede
|
||||
PKG_VERSION:=1.14.7
|
||||
PKG_RELEASE:=39
|
||||
PKG_RELEASE:=40
|
||||
PKG_MAINTAINER:=kenzok8
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ function convertAnytls(node) {
|
||||
setIf(params, 'alpn', arrayValue(node.alpn));
|
||||
setIf(params, 'client-fingerprint', node['client-fingerprint'] || node.fingerprint);
|
||||
if (node['skip-cert-verify'])
|
||||
params.set('allowInsecure', '1');
|
||||
params.set('insecure', '1');
|
||||
if (node.udp)
|
||||
params.set('udp', '1');
|
||||
return 'anytls://' + encodeURIComponent(node.password) + '@' + endpoint(node.server, node.port) +
|
||||
|
||||
@@ -597,6 +597,11 @@ return view.extend({
|
||||
so.modalonly = true;
|
||||
|
||||
/* AnyTLS fields */
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_client_metadata', _('Client metadata'),
|
||||
_('The client metadata sent to the server.'));
|
||||
so.depends('type', 'anytls');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_idle_session_check_interval', _('Idle session check interval'),
|
||||
_('In seconds.'));
|
||||
so.placeholder = '30';
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -572,6 +572,7 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
} : null,
|
||||
|
||||
/* AnyTLS */
|
||||
"client-metadata": cfg.anytls_client_metadata,
|
||||
"idle-session-check-interval": durationToSecond(cfg.anytls_idle_session_check_interval),
|
||||
"idle-session-timeout": durationToSecond(cfg.anytls_idle_session_timeout),
|
||||
"min-idle-session": strToInt(cfg.anytls_min_idle_session),
|
||||
|
||||
+32
-13
@@ -1,14 +1,14 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2026-03-02 22:45+0000\n"
|
||||
"Last-Translator: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>\n"
|
||||
"PO-Revision-Date: 2026-08-13 09:16+0000\n"
|
||||
"Last-Translator: Jonatan Nyberg <nickwick@users.noreply.hosted.weblate.org>\n"
|
||||
"Language-Team: Swedish <https://hosted.weblate.org/projects/openwrt/"
|
||||
"luciapplicationsfrpc/sv/>\n"
|
||||
"Language: sv\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
"X-Generator: Weblate 2026.9.dev0\n"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1454
|
||||
msgid "Add new proxy or visitor..."
|
||||
@@ -32,7 +32,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:174
|
||||
msgid "Additional configs"
|
||||
msgstr "Extra konfigurationer"
|
||||
msgstr "Ytterligare konfigurationer"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1060
|
||||
msgid "Additional proxy metadata. Use key=value."
|
||||
@@ -45,6 +45,8 @@ msgstr ""
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:187
|
||||
msgid "Address of the frps server."
|
||||
msgstr ""
|
||||
"AdminAddr anger adressen som administrationsservern binds till.<br />Som "
|
||||
"standard är värdet ”0.0.0.0”."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1430
|
||||
msgid "Advanced"
|
||||
@@ -53,14 +55,20 @@ msgstr "Avancerat"
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:839
|
||||
msgid "Allow users"
|
||||
msgstr ""
|
||||
"AdminPort anger porten som administrationsservern ska lyssna på. Om värdet "
|
||||
"är 0 startas inte administrationsservern.<br />Som standard är värdet 0."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1069
|
||||
msgid "Annotations"
|
||||
msgstr ""
|
||||
"AdminPwd anger lösenordet som administrationsservern använder för "
|
||||
"inloggning.<br />Som standard är värdet ”admin”."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1070
|
||||
msgid "Annotations displayed on frps dashboard. Use key=value."
|
||||
msgstr ""
|
||||
"AdminUser anger användarnamnet som administrationsservern använder för "
|
||||
"inloggning.<br />Som standard är värdet ”admin”."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:464
|
||||
msgid "Assets dir"
|
||||
@@ -409,7 +417,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1460
|
||||
msgid "General Settings"
|
||||
msgstr "Generella inställningar"
|
||||
msgstr "Allmänna inställningar"
|
||||
|
||||
#: applications/luci-app-frpc/root/usr/share/rpcd/acl.d/luci-app-frpc.json:3
|
||||
msgid "Grant access to LuCI app frpc"
|
||||
@@ -495,7 +503,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:530
|
||||
msgid "Heartbeat interval"
|
||||
msgstr "Hjärtslagsintervall"
|
||||
msgstr "Heartbeat-intervall"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:531
|
||||
msgid "Heartbeat interval in seconds."
|
||||
@@ -554,7 +562,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:659
|
||||
msgid "Local IP"
|
||||
msgstr "Lokal IP"
|
||||
msgstr "Lokal IP-adress"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:523
|
||||
msgid ""
|
||||
@@ -583,6 +591,8 @@ msgstr "Lokal port"
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:660
|
||||
msgid "Local service IP or host."
|
||||
msgstr ""
|
||||
"LocalIp anger IP-adressen eller värdnamnet som proxyn ska vidarebefordra "
|
||||
"till."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:664
|
||||
msgid "Local service port."
|
||||
@@ -598,7 +608,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:387
|
||||
msgid "Log level"
|
||||
msgstr "Logg-nivå"
|
||||
msgstr "Loggnivå"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:391
|
||||
msgid "Log max days"
|
||||
@@ -647,6 +657,9 @@ msgstr ""
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:197
|
||||
msgid "NAT hole STUN server"
|
||||
msgstr ""
|
||||
"LoginFailExit styr om klienten ska avslutas efter ett misslyckat "
|
||||
"inloggningsförsök. Om värdet är false försöker klienten igen tills en "
|
||||
"inloggning lyckas.<br />Som standard är värdet true."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1390
|
||||
msgid "NOT RUNNING"
|
||||
@@ -749,7 +762,7 @@ msgstr ""
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:909
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1463
|
||||
msgid "Plugin"
|
||||
msgstr "Insticksprogram"
|
||||
msgstr "Insticksmodul"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:1015
|
||||
msgid "Plugin HTTP/2"
|
||||
@@ -901,11 +914,11 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:153
|
||||
msgid "Run daemon as group"
|
||||
msgstr "Kör daemon som grupp"
|
||||
msgstr "Kör demonen som grupp"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:152
|
||||
msgid "Run daemon as user"
|
||||
msgstr "Kör daemon som användare"
|
||||
msgstr "Kör demonen som användare"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:943
|
||||
msgid "SOCKS5 password"
|
||||
@@ -933,7 +946,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:186
|
||||
msgid "Server address"
|
||||
msgstr "Server-adress"
|
||||
msgstr "Serveradress"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:847
|
||||
msgid "Server name"
|
||||
@@ -1054,14 +1067,20 @@ msgstr ""
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:560
|
||||
msgid "TLS trusted CA path"
|
||||
msgstr ""
|
||||
"TcpMux aktiverar eller inaktiverar multiplexering av TCP-strömmar. Det gör "
|
||||
"att flera begäranden från en klient kan dela en enda TCP-anslutning. Om "
|
||||
"värdet är true måste även servern ha TCP-multiplexering aktiverad.<br />Som "
|
||||
"standard är värdet true."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:483
|
||||
msgid "Timeout in seconds for connecting to frps."
|
||||
msgstr ""
|
||||
"Den här listan kan användas för att ange ytterligare parametrar som inte har "
|
||||
"tagits med i LuCI."
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:235
|
||||
msgid "Token"
|
||||
msgstr "Tecken"
|
||||
msgstr "Token"
|
||||
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:244
|
||||
#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:264
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2026-03-22 17:09+0000\n"
|
||||
"Last-Translator: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>\n"
|
||||
"PO-Revision-Date: 2026-08-13 09:16+0000\n"
|
||||
"Last-Translator: Jonatan Nyberg <nickwick@users.noreply.hosted.weblate.org>\n"
|
||||
"Language-Team: Swedish <https://hosted.weblate.org/projects/openwrt/"
|
||||
"luciapplicationsfrps/sv/>\n"
|
||||
"Language: sv\n"
|
||||
@@ -24,7 +24,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:144
|
||||
msgid "Additional configs"
|
||||
msgstr "Extra konfigurationer"
|
||||
msgstr "Ytterligare konfigurationer"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:257
|
||||
msgid "Additional scopes to include authentication information."
|
||||
@@ -72,7 +72,7 @@ msgstr "Bindningsadress"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:157
|
||||
msgid "Bind port"
|
||||
msgstr "Bind port"
|
||||
msgstr "Bindningsport"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:969
|
||||
msgid "Collecting data ..."
|
||||
@@ -81,12 +81,16 @@ msgstr "Samlar in data ..."
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:323
|
||||
msgid "Command arguments passed to token source exec."
|
||||
msgstr ""
|
||||
"BindAddr anger adressen som servern binds till.<br />Som standard är värdet ”"
|
||||
"0.0.0.0”."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:300
|
||||
msgid ""
|
||||
"Command used to obtain the token. The init script adds --allow-"
|
||||
"unsafe=TokenSourceExec when this source type is used."
|
||||
msgstr ""
|
||||
"BindKcpPort anger KCP-porten som servern lyssnar på. Om värdet är 0 lyssnar "
|
||||
"servern inte efter KCP-anslutningar.<br />Som standard är värdet 0."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:977
|
||||
msgid "Common Settings"
|
||||
@@ -95,18 +99,25 @@ msgstr "Vanliga inställningar"
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:368
|
||||
msgid "Configuration key: log.level."
|
||||
msgstr ""
|
||||
"BindPort anger porten som servern lyssnar på.<br />Som standard är värdet "
|
||||
"7000."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:538
|
||||
msgid "Configuration key: transport.quic.keepalivePeriod."
|
||||
msgstr ""
|
||||
"BindQuicPort anger QUIC-porten som servern lyssnar på. Om värdet är 0 "
|
||||
"lyssnar servern inte efter QUIC-anslutningar.<br />Som standard är värdet 0."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:542
|
||||
msgid "Configuration key: transport.quic.maxIdleTimeout."
|
||||
msgstr ""
|
||||
"BindUdpPort anger UDP-porten som servern lyssnar på. Om värdet är 0 lyssnar "
|
||||
"servern inte efter UDP-anslutningar.<br />Som standard är värdet 0."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:546
|
||||
msgid "Configuration key: transport.quic.maxIncomingStreams."
|
||||
msgstr ""
|
||||
"Konfigurationsfiler som inkluderas i den tillfälliga konfigurationsfilen"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:227
|
||||
msgid "Custom 404 page"
|
||||
@@ -131,6 +142,8 @@ msgstr "Inaktiverad"
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:220
|
||||
msgid "Do not update traffic when TCPMUX passthrough is enabled."
|
||||
msgstr ""
|
||||
"Dashboard TLS Key File anger sökvägen till filen med den privata TLS-nyckeln "
|
||||
"för att aktivera HTTPS-åtkomst.<br />Krävs om HTTPS är aktiverat."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:224
|
||||
msgid "Domain suffix for subdomain-based HTTP/HTTPS proxies."
|
||||
@@ -171,22 +184,30 @@ msgstr "Miljövariabel"
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:755
|
||||
msgid "Environment variable must use KEY=value format."
|
||||
msgstr ""
|
||||
"DashboardPort anger porten som instrumentpanelen lyssnar på. Om värdet är 0 "
|
||||
"startas inte instrumentpanelen.<br />Som standard är värdet 0."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:333
|
||||
msgid "Environment variables passed to token source exec. Use KEY=value."
|
||||
msgstr ""
|
||||
"DashboardPwd anger lösenordet som instrumentpanelen använder för "
|
||||
"inloggning.<br />Som standard är värdet ”admin”."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:464
|
||||
msgid ""
|
||||
"Export Prometheus metrics on webServer /metrics API. It only takes effect "
|
||||
"when web server port is set."
|
||||
msgstr ""
|
||||
"DashboardUser anger användarnamnet som instrumentpanelen använder för "
|
||||
"inloggning.<br />Som standard är värdet ”admin”."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:145
|
||||
msgid ""
|
||||
"Extra root-level configuration fragments included before generated HTTP "
|
||||
"plugin sections. Use raw settings for table-specific extra options."
|
||||
msgstr ""
|
||||
"DisableLogColor inaktiverar loggfärger när LogWay == ”console” om värdet är "
|
||||
"true.<br />Som standard är värdet false."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:521
|
||||
msgid "Force TLS"
|
||||
@@ -236,7 +257,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:161
|
||||
msgid "KCP bind port"
|
||||
msgstr ""
|
||||
msgstr "KCP-bindningsport"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:174
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:193
|
||||
@@ -260,7 +281,7 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:367
|
||||
msgid "Log level"
|
||||
msgstr "Logg-nivå"
|
||||
msgstr "Loggnivå"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:371
|
||||
msgid "Log max days"
|
||||
@@ -301,6 +322,9 @@ msgstr ""
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:561
|
||||
msgid "Maximum ports each client can use. 0 means no limit."
|
||||
msgstr ""
|
||||
"LogMaxDays anger det högsta antalet dagar som logginformation lagras innan "
|
||||
"den tas bort. Detta används endast om LogWay == ”file”.<br />Som standard är "
|
||||
"värdet 0."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:504
|
||||
msgid "Maximum time to wait for a work connection."
|
||||
@@ -309,6 +333,9 @@ msgstr ""
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:564
|
||||
msgid "NAT hole analysis reserve hours"
|
||||
msgstr ""
|
||||
"MaxPortsPerClient anger det högsta antalet portar som en enskild klient får "
|
||||
"proxyansluta till. Om värdet är 0 tillämpas ingen gräns.<br />Som standard "
|
||||
"är värdet 0."
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:942
|
||||
msgid "NOT RUNNING"
|
||||
@@ -470,11 +497,11 @@ msgstr ""
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:123
|
||||
msgid "Run daemon as group"
|
||||
msgstr "Kör daemon som grupp"
|
||||
msgstr "Kör demonen som grupp"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:122
|
||||
msgid "Run daemon as user"
|
||||
msgstr "Kör daemon som användare"
|
||||
msgstr "Kör demonen som användare"
|
||||
|
||||
#: applications/luci-app-frps/htdocs/luci-static/resources/view/frps.js:983
|
||||
msgid "SSH Tunnel"
|
||||
|
||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.8.12
|
||||
PKG_RELEASE:=217
|
||||
PKG_RELEASE:=218
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -332,7 +332,7 @@ run_socks() {
|
||||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file
|
||||
[ -n "$http_port" ] || http_port=0
|
||||
[ -n "$http_config_file" ] && [ -z "$(echo ${http_config_file} | grep $TMP_PATH)" ] && http_config_file=$TMP_PATH/$http_config_file
|
||||
if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
if [ -n "$log_file" ] && [ "$log_file" != "/dev/null" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
log_file=$TMP_PATH/$log_file
|
||||
else
|
||||
log_file="/dev/null"
|
||||
@@ -535,7 +535,7 @@ run_redir() {
|
||||
eval_set_val "$@"
|
||||
local tcp_node_socks_flag tcp_node_http_flag
|
||||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=${GLOBAL_ACL_PATH}/${config_file}
|
||||
if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
if [ -n "$log_file" ] && [ "$log_file" != "/dev/null" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
log_file=${GLOBAL_ACL_PATH}/${log_file}
|
||||
else
|
||||
log_file="/dev/null"
|
||||
@@ -2064,6 +2064,7 @@ get_config() {
|
||||
DNSMASQ_CONF_DIR="/tmp/dnsmasq.d"
|
||||
fi
|
||||
fi
|
||||
[ -d "$DNSMASQ_CONF_DIR" ] || mkdir -p "$DNSMASQ_CONF_DIR"
|
||||
set_cache_var GLOBAL_DNSMASQ_CONF ${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf
|
||||
set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d
|
||||
|
||||
|
||||
@@ -789,9 +789,11 @@ function add_rule(var)
|
||||
end
|
||||
if #conf_lines > 0 then
|
||||
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
|
||||
conf_out:write(table.concat(conf_lines, "\n"))
|
||||
conf_out:write("\n")
|
||||
conf_out:close()
|
||||
if conf_out then
|
||||
conf_out:write(table.concat(conf_lines, "\n"))
|
||||
conf_out:write("\n")
|
||||
conf_out:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=26.8.10
|
||||
PKG_RELEASE:=79
|
||||
PKG_VERSION:=26.8.14
|
||||
PKG_RELEASE:=80
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
module("luci.controller.passwall2", package.seeall)
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname -- not available
|
||||
local c_config = api.c_config -- not available
|
||||
local s_config = api.s_config -- not available
|
||||
local uci = api.uci -- in funtion index()
|
||||
local http = require "luci.http"
|
||||
local util = require "luci.util"
|
||||
@@ -20,12 +22,14 @@ function index()
|
||||
end
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname -- global definitions not available
|
||||
local c_config = api.c_config -- not available
|
||||
local s_config = api.s_config -- not available
|
||||
local uci = api.uci -- in function index()
|
||||
entry({"admin", "services", appname}).dependent = true
|
||||
entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true
|
||||
entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true
|
||||
local e
|
||||
if uci:get(appname, "@global[0]", "hide_from_luci") ~= "1" then
|
||||
if uci:get(c_config, "@global[0]", "hide_from_luci") ~= "1" then
|
||||
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("PassWall 2"), 0)
|
||||
else
|
||||
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, 0)
|
||||
@@ -193,7 +197,7 @@ function check_ip()
|
||||
end
|
||||
|
||||
function reset_config()
|
||||
uci:revert(appname)
|
||||
uci:revert(c_config)
|
||||
luci.sys.call("echo '' > /tmp/log/passwall2.log")
|
||||
luci.sys.call('/etc/init.d/passwall2 stop')
|
||||
luci.sys.call('[ -f "/usr/share/passwall2/0_default_config" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2')
|
||||
@@ -201,14 +205,14 @@ function reset_config()
|
||||
end
|
||||
|
||||
function show_menu()
|
||||
api.sh_uci_del(appname, "@global[0]", "hide_from_luci", true)
|
||||
api.sh_uci_del(c_config, "@global[0]", "hide_from_luci", true)
|
||||
luci.sys.call("rm -rf /tmp/luci-*")
|
||||
luci.sys.call("/etc/init.d/rpcd restart >/dev/null")
|
||||
http.redirect(api.url())
|
||||
end
|
||||
|
||||
function hide_menu()
|
||||
api.sh_uci_set(appname, "@global[0]", "hide_from_luci", "1", true)
|
||||
api.sh_uci_set(c_config, "@global[0]", "hide_from_luci", "1", true)
|
||||
luci.sys.call("rm -rf /tmp/luci-*")
|
||||
luci.sys.call("/etc/init.d/rpcd restart >/dev/null")
|
||||
http.redirect(luci.dispatcher.build_url("admin", "status", "overview"))
|
||||
@@ -244,10 +248,10 @@ function socks_autoswitch_add_node()
|
||||
local id = http.formvalue("id")
|
||||
local key = http.formvalue("key")
|
||||
if id and id ~= "" and key and key ~= "" then
|
||||
uci:set(appname, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(appname, id, "autoswitch_backup_node") or {}
|
||||
uci:set(c_config, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(c_config, id, "autoswitch_backup_node") or {}
|
||||
for i = #new_list, 1, -1 do
|
||||
if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then
|
||||
if (uci:get(c_config, new_list[i], "remarks") or ""):find(key) then
|
||||
table.remove(new_list, i)
|
||||
end
|
||||
end
|
||||
@@ -256,8 +260,8 @@ function socks_autoswitch_add_node()
|
||||
table.insert(new_list, e.id)
|
||||
end
|
||||
end
|
||||
uci:set_list(appname, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, appname)
|
||||
uci:set_list(c_config, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, c_config)
|
||||
end
|
||||
http.redirect(api.url("socks_config", id))
|
||||
end
|
||||
@@ -266,15 +270,15 @@ function socks_autoswitch_remove_node()
|
||||
local id = http.formvalue("id")
|
||||
local key = http.formvalue("key")
|
||||
if id and id ~= "" and key and key ~= "" then
|
||||
uci:set(appname, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(appname, id, "autoswitch_backup_node") or {}
|
||||
uci:set(c_config, id, "enable_autoswitch", "1")
|
||||
local new_list = uci:get(c_config, id, "autoswitch_backup_node") or {}
|
||||
for i = #new_list, 1, -1 do
|
||||
if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then
|
||||
if (uci:get(c_config, new_list[i], "remarks") or ""):find(key) then
|
||||
table.remove(new_list, i)
|
||||
end
|
||||
end
|
||||
uci:set_list(appname, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, appname)
|
||||
uci:set_list(c_config, id, "autoswitch_backup_node", new_list)
|
||||
api.uci_save(uci, c_config)
|
||||
end
|
||||
http.redirect(api.url("socks_config", id))
|
||||
end
|
||||
@@ -365,7 +369,7 @@ function socks_status()
|
||||
local id = http.formvalue("id")
|
||||
e.index = index
|
||||
e.socks_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v -E 'grep|acl/|acl_' | grep '%s/bin/' | grep '%s' > /dev/null", appname, id)) == 0
|
||||
local use_http = uci:get(appname, id, "http_port") or 0
|
||||
local use_http = uci:get(c_config, id, "http_port") or 0
|
||||
e.use_http = 0
|
||||
if tonumber(use_http) > 0 then
|
||||
e.use_http = 1
|
||||
@@ -435,9 +439,9 @@ function update_config()
|
||||
local data_t = jsonParse(data) or {}
|
||||
if next(data_t) then
|
||||
for k, v in pairs(data_t) do
|
||||
uci:set(appname, id, k, v)
|
||||
uci:set(c_config, id, k, v)
|
||||
end
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http_write_json_ok()
|
||||
return
|
||||
end
|
||||
@@ -449,20 +453,20 @@ function add_node()
|
||||
local redirect = http.formvalue("redirect")
|
||||
|
||||
local uid = api.gen_random_char()
|
||||
uci:section(appname, "nodes", uid)
|
||||
uci:section(c_config, "nodes", uid)
|
||||
|
||||
local group = http.formvalue("group")
|
||||
if group and group ~= "default" then
|
||||
uci:set(appname, uid, "group", group)
|
||||
uci:set(c_config, uid, "group", group)
|
||||
end
|
||||
|
||||
uci:set(appname, uid, "type", "Xray")
|
||||
uci:set(c_config, uid, "type", "Xray")
|
||||
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("node_config", uid))
|
||||
else
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
http_write_json({result = uid})
|
||||
end
|
||||
end
|
||||
@@ -471,67 +475,67 @@ function set_node()
|
||||
local type = http.formvalue("type")
|
||||
local config = http.formvalue("config")
|
||||
local section = http.formvalue("section")
|
||||
uci:set(appname, type, config, section)
|
||||
api.uci_save(uci, appname, true, true)
|
||||
uci:set(c_config, type, config, section)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
http.redirect(api.url("log"))
|
||||
end
|
||||
|
||||
function copy_node()
|
||||
local section = http.formvalue("section")
|
||||
local uid = api.gen_random_char()
|
||||
uci:section(appname, "nodes", uid)
|
||||
for k, v in pairs(uci:get_all(appname, section)) do
|
||||
uci:section(c_config, "nodes", uid)
|
||||
for k, v in pairs(uci:get_all(c_config, section)) do
|
||||
if not k:match("^%.") and k ~= "group" then
|
||||
if k == "remarks" then v = (v or "") .. "(1)" end
|
||||
uci:set(appname, uid, k, v)
|
||||
uci:set(c_config, uid, k, v)
|
||||
end
|
||||
end
|
||||
uci:set(appname, uid, "add_mode", 1)
|
||||
api.uci_save(uci, appname)
|
||||
uci:set(c_config, uid, "add_mode", 1)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("node_config", uid))
|
||||
end
|
||||
|
||||
function clear_all_nodes()
|
||||
uci:set(appname, '@global[0]', "enabled", "0")
|
||||
uci:set(appname, '@global[0]', "socks_enabled", "0")
|
||||
uci:set(appname, '@global_haproxy[0]', "balancing_enable", "0")
|
||||
uci:delete(appname, '@global[0]', "node")
|
||||
uci:foreach(appname, "socks", function(t)
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:set_list(appname, t[".name"], "autoswitch_backup_node", {})
|
||||
uci:set(c_config, '@global[0]', "enabled", "0")
|
||||
uci:set(c_config, '@global[0]', "socks_enabled", "0")
|
||||
uci:set(c_config, '@global_haproxy[0]', "balancing_enable", "0")
|
||||
uci:delete(c_config, '@global[0]', "node")
|
||||
uci:foreach(c_config, "socks", function(t)
|
||||
uci:delete(c_config, t[".name"])
|
||||
uci:set_list(c_config, t[".name"], "autoswitch_backup_node", {})
|
||||
end)
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:foreach(c_config, "haproxy_config", function(t)
|
||||
uci:delete(c_config, t[".name"])
|
||||
end)
|
||||
uci:foreach(appname, "acl_rule", function(t)
|
||||
uci:delete(appname, t[".name"], "node")
|
||||
uci:foreach(c_config, "acl_rule", function(t)
|
||||
uci:delete(c_config, t[".name"], "node")
|
||||
end)
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:delete(appname, node['.name'])
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
uci:delete(c_config, node['.name'])
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t)
|
||||
uci:delete(appname, t[".name"], "md5")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(appname, t[".name"], "preproxy_node")
|
||||
uci:delete(appname, t[".name"], "to_node")
|
||||
uci:foreach(c_config, "subscribe_list", function(t)
|
||||
uci:delete(c_config, t[".name"], "md5")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "preproxy_node")
|
||||
uci:delete(c_config, t[".name"], "to_node")
|
||||
end)
|
||||
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
|
||||
function delete_select_nodes()
|
||||
local ids = http.formvalue("ids")
|
||||
local redirect = http.formvalue("redirect")
|
||||
string.gsub(ids, '[^' .. "," .. ']+', function(w)
|
||||
if (uci:get(appname, "@global[0]", "node") or "") == w then
|
||||
uci:delete(appname, '@global[0]', "node")
|
||||
if (uci:get(c_config, "@global[0]", "node") or "") == w then
|
||||
uci:delete(c_config, '@global[0]', "node")
|
||||
end
|
||||
uci:foreach(appname, "socks", function(t)
|
||||
uci:foreach(c_config, "socks", function(t)
|
||||
if t["node"] == w then
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:delete(c_config, t[".name"])
|
||||
end
|
||||
local changed = false
|
||||
local auto_switch_node_list = uci:get(appname, t[".name"], "autoswitch_backup_node") or {}
|
||||
local auto_switch_node_list = uci:get(c_config, t[".name"], "autoswitch_backup_node") or {}
|
||||
for i = #auto_switch_node_list, 1, -1 do
|
||||
if w == auto_switch_node_list[i] then
|
||||
table.remove(auto_switch_node_list, i)
|
||||
@@ -539,31 +543,31 @@ function delete_select_nodes()
|
||||
end
|
||||
end
|
||||
if changed then
|
||||
uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
|
||||
uci:set_list(c_config, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:foreach(c_config, "haproxy_config", function(t)
|
||||
if t["lbss"] == w then
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:delete(c_config, t[".name"])
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "acl_rule", function(t)
|
||||
uci:foreach(c_config, "acl_rule", function(t)
|
||||
if t["node"] == w then
|
||||
uci:delete(appname, t[".name"], "node")
|
||||
uci:delete(c_config, t[".name"], "node")
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(c_config, "nodes", function(t)
|
||||
if t["preproxy_node"] == w then
|
||||
uci:delete(appname, t[".name"], "preproxy_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "preproxy_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
if t["to_node"] == w then
|
||||
uci:delete(appname, t[".name"], "to_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "to_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
local list_name = t["urltest_node"] and "urltest_node" or (t["balancing_node"] and "balancing_node")
|
||||
if list_name then
|
||||
local nodes = uci:get_list(appname, t[".name"], list_name)
|
||||
local nodes = uci:get_list(c_config, t[".name"], list_name)
|
||||
if nodes then
|
||||
local changed = false
|
||||
local new_nodes = {}
|
||||
@@ -575,48 +579,48 @@ function delete_select_nodes()
|
||||
end
|
||||
end
|
||||
if changed then
|
||||
uci:set_list(appname, t[".name"], list_name, new_nodes)
|
||||
uci:set_list(c_config, t[".name"], list_name, new_nodes)
|
||||
end
|
||||
end
|
||||
end
|
||||
if t["fallback_node"] == w then
|
||||
uci:delete(appname, t[".name"], "fallback_node")
|
||||
uci:delete(c_config, t[".name"], "fallback_node")
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(t)
|
||||
uci:foreach(c_config, "subscribe_list", function(t)
|
||||
if t["preproxy_node"] == w then
|
||||
uci:delete(appname, t[".name"], "preproxy_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "preproxy_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
if t["to_node"] == w then
|
||||
uci:delete(appname, t[".name"], "to_node")
|
||||
uci:delete(appname, t[".name"], "chain_proxy")
|
||||
uci:delete(c_config, t[".name"], "to_node")
|
||||
uci:delete(c_config, t[".name"], "chain_proxy")
|
||||
end
|
||||
end)
|
||||
if (uci:get(appname, w, "add_mode") or "0") == "2" then
|
||||
local group = uci:get(appname, w, "group") or ""
|
||||
if (uci:get(c_config, w, "add_mode") or "0") == "2" then
|
||||
local group = uci:get(c_config, w, "group") or ""
|
||||
if group ~= "" then
|
||||
uci:foreach(appname, "subscribe_list", function(t)
|
||||
uci:foreach(c_config, "subscribe_list", function(t)
|
||||
if t["remark"] == group then
|
||||
uci:delete(appname, t[".name"], "md5")
|
||||
uci:delete(c_config, t[".name"], "md5")
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
uci:delete(appname, w)
|
||||
uci:delete(c_config, w)
|
||||
end)
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("node_list"))
|
||||
else
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
end
|
||||
|
||||
function get_node()
|
||||
local id = http.formvalue("id")
|
||||
local result = {}
|
||||
local show_node_info = api.uci_get_type("global_other", "show_node_info", "0")
|
||||
local show_node_info = uci:get(c_config, "@global_other[0]", "show_node_info") or "0"
|
||||
|
||||
local function add_is_ipv6_key(o)
|
||||
if o and o.address and show_node_info == "1" then
|
||||
@@ -629,12 +633,12 @@ function get_node()
|
||||
end
|
||||
|
||||
if id then
|
||||
result = uci:get_all(appname, id)
|
||||
result = uci:get_all(c_config, id)
|
||||
add_is_ipv6_key(result)
|
||||
else
|
||||
local default_nodes = {}
|
||||
local other_nodes = {}
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(c_config, "nodes", function(t)
|
||||
add_is_ipv6_key(t)
|
||||
if not t.group or t.group == "" then
|
||||
default_nodes[#default_nodes + 1] = t
|
||||
@@ -653,12 +657,12 @@ function reassign_group()
|
||||
local group = http.formvalue("group") or "default"
|
||||
for id in ids:gmatch("([^,]+)") do
|
||||
if group ~="" and group ~= "default" then
|
||||
api.sh_uci_set(appname, id, "group", group)
|
||||
api.sh_uci_set(c_config, id, "group", group)
|
||||
else
|
||||
api.sh_uci_del(appname, id, "group")
|
||||
api.sh_uci_del(c_config, id, "group")
|
||||
end
|
||||
end
|
||||
api.sh_uci_commit(appname)
|
||||
api.sh_uci_commit(c_config)
|
||||
http_write_json({ status = "ok" })
|
||||
end
|
||||
|
||||
@@ -666,7 +670,7 @@ function save_node_list_opt()
|
||||
local option = http.formvalue("option") or ""
|
||||
local value = http.formvalue("value") or ""
|
||||
if option ~= "" then
|
||||
api.sh_uci_set(appname, "@global_other[0]", option, value, true)
|
||||
api.sh_uci_set(c_config, "@global_other[0]", option, value, true)
|
||||
end
|
||||
http_write_json({ status = "ok" })
|
||||
end
|
||||
@@ -688,7 +692,7 @@ function rollback_rules()
|
||||
return
|
||||
end
|
||||
local bak_dir = "/tmp/bak_v2ray/"
|
||||
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/")
|
||||
local geo_dir = (uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/")
|
||||
fs.move(bak_dir .. arg_type .. ".dat", geo_dir .. arg_type .. ".dat")
|
||||
fs.rmdir(bak_dir)
|
||||
http_write_json_ok()
|
||||
@@ -701,9 +705,9 @@ function server_update_config()
|
||||
local data_t = jsonParse(data) or {}
|
||||
if next(data_t) then
|
||||
for k, v in pairs(data_t) do
|
||||
uci:set(appname .. "_server", id, k, v)
|
||||
uci:set(c_config .. "_server", id, k, v)
|
||||
end
|
||||
api.uci_save(uci, appname .. "_server")
|
||||
api.uci_save(uci, c_config .. "_server")
|
||||
http_write_json_ok()
|
||||
return
|
||||
end
|
||||
@@ -814,7 +818,7 @@ function restore_backup()
|
||||
fp:write(decoded)
|
||||
fp:close()
|
||||
if chunk_index + 1 == total_chunks then
|
||||
uci:revert(appname)
|
||||
uci:revert(c_config)
|
||||
api.sys.call("echo '' > /tmp/log/passwall2.log")
|
||||
api.log(0, string.format(" * PassWall2 %s", i18n.translate("Configuration file uploaded successfully…")))
|
||||
local temp_dir = '/tmp/passwall2_bak'
|
||||
@@ -857,7 +861,7 @@ function geo_view()
|
||||
end
|
||||
local function get_rules(str, type)
|
||||
local rules_id = {}
|
||||
uci:foreach(appname, "shunt_rules", function(s)
|
||||
uci:foreach(c_config, "shunt_rules", function(s)
|
||||
local list
|
||||
if type == "geoip" then list = s.ip_list else list = s.domain_list end
|
||||
for line in string.gmatch((list or ""), "[^\r\n]+") do
|
||||
@@ -874,7 +878,7 @@ function geo_view()
|
||||
end)
|
||||
return rules_id
|
||||
end
|
||||
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geo_dir = (uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geosite_path = geo_dir .. "/geosite.dat"
|
||||
local geoip_path = geo_dir .. "/geoip.dat"
|
||||
local geo_type, file_path, cmd
|
||||
@@ -946,13 +950,13 @@ function subscribe_manual()
|
||||
http_write_json({ success = false, msg = "Missing section or URL, skip." })
|
||||
return
|
||||
end
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
local uci_url = api.sh_uci_get(c_config, section, "url")
|
||||
if not uci_url or uci_url == "" then
|
||||
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
|
||||
return
|
||||
end
|
||||
if uci_url ~= current_url then
|
||||
api.sh_uci_set(appname, section, "url", current_url, true)
|
||||
api.sh_uci_set(c_config, section, "url", current_url, true)
|
||||
end
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &")
|
||||
http_write_json({ success = true, msg = "Subscribe triggered." })
|
||||
@@ -969,7 +973,7 @@ function subscribe_manual_all()
|
||||
local url_list = util.split(urls, ",")
|
||||
-- Check if there are any unsaved configurations.
|
||||
for i, section in ipairs(section_list) do
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
local uci_url = api.sh_uci_get(c_config, section, "url")
|
||||
if not uci_url or uci_url == "" then
|
||||
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
|
||||
return
|
||||
@@ -978,9 +982,9 @@ function subscribe_manual_all()
|
||||
-- Save URLs that have changed.
|
||||
for i, section in ipairs(section_list) do
|
||||
local current_url = url_list[i] or ""
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
local uci_url = api.sh_uci_get(c_config, section, "url")
|
||||
if current_url ~= "" and uci_url ~= current_url then
|
||||
api.sh_uci_set(appname, section, "url", current_url, true)
|
||||
api.sh_uci_set(c_config, section, "url", current_url, true)
|
||||
end
|
||||
end
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &")
|
||||
@@ -991,10 +995,10 @@ function flush_set()
|
||||
local redirect = http.formvalue("redirect") or "0"
|
||||
local reload = http.formvalue("reload") or "0"
|
||||
if reload == "1" then
|
||||
uci:set(appname, '@global[0]', "flush_set", "1")
|
||||
api.uci_save(uci, appname, true, true)
|
||||
uci:set(c_config, '@global[0]', "flush_set", "1")
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
else
|
||||
api.sh_uci_set(appname, "@global[0]", "flush_set", "1", true)
|
||||
api.sh_uci_set(c_config, "@global[0]", "flush_set", "1", true)
|
||||
end
|
||||
if redirect == "1" then
|
||||
http.redirect(api.url("log"))
|
||||
@@ -1003,9 +1007,9 @@ end
|
||||
|
||||
function fetch_certsha256()
|
||||
local id = http.formvalue("id") or ""
|
||||
local address = (id ~= "") and uci:get(appname, id, "address") or ""
|
||||
local port = (id ~= "") and uci:get(appname, id, "port") or 0
|
||||
local sni = (id ~= "") and uci:get(appname, id, "tls_serverName") or ""
|
||||
local address = (id ~= "") and uci:get(c_config, id, "address") or ""
|
||||
local port = (id ~= "") and uci:get(c_config, id, "port") or 0
|
||||
local sni = (id ~= "") and uci:get(c_config, id, "tls_serverName") or ""
|
||||
sni = (sni ~= "") and sni or address
|
||||
if address == "" or port == 0 then
|
||||
http_write_json_error()
|
||||
@@ -1020,11 +1024,11 @@ function get_shunt_rules()
|
||||
local result = {}
|
||||
|
||||
if id then
|
||||
result = uci:get_all(appname, id)
|
||||
result = uci:get_all(c_config, id)
|
||||
else
|
||||
local default_items = {}
|
||||
local other_items = {}
|
||||
uci:foreach(appname, "shunt_rules", function(t)
|
||||
uci:foreach(c_config, "shunt_rules", function(t)
|
||||
if not t.group or t.group == "" then
|
||||
default_items[#default_items + 1] = t
|
||||
else
|
||||
@@ -1043,7 +1047,7 @@ function add_shunt_rule()
|
||||
|
||||
local uid = add_name
|
||||
if add_name then
|
||||
local has = uci:get(appname, uid)
|
||||
local has = uci:get(c_config, uid)
|
||||
if has then
|
||||
http_write_json_error({ message = i18n.translate("This ID already exists.") })
|
||||
return
|
||||
@@ -1051,18 +1055,18 @@ function add_shunt_rule()
|
||||
else
|
||||
uid = api.gen_random_char()
|
||||
end
|
||||
uci:section(appname, "shunt_rules", uid)
|
||||
uci:section(c_config, "shunt_rules", uid)
|
||||
|
||||
local group = http.formvalue("group")
|
||||
if group and group ~= "default" then
|
||||
uci:set(appname, uid, "group", group)
|
||||
uci:set(c_config, uid, "group", group)
|
||||
end
|
||||
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("shunt_rules", uid))
|
||||
else
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http_write_json_ok({uid = uid, redirect_url = api.url("shunt_rules", uid)})
|
||||
end
|
||||
end
|
||||
@@ -1071,17 +1075,17 @@ function delete_select_shunt_rules()
|
||||
local ids = http.formvalue("ids")
|
||||
local redirect = http.formvalue("redirect")
|
||||
string.gsub(ids, '[^' .. "," .. ']+', function(w)
|
||||
uci:foreach(appname, "nodes", function(s)
|
||||
uci:foreach(c_config, "nodes", function(s)
|
||||
if s["protocol"] and s["protocol"] == "_shunt" then
|
||||
uci:delete(appname, s[".name"], w)
|
||||
uci:delete(c_config, s[".name"], w)
|
||||
end
|
||||
end)
|
||||
uci:delete(appname, w)
|
||||
uci:delete(c_config, w)
|
||||
end)
|
||||
if redirect == "1" then
|
||||
api.uci_save(uci, appname)
|
||||
api.uci_save(uci, c_config)
|
||||
http.redirect(api.url("rule"))
|
||||
else
|
||||
api.uci_save(uci, appname, true, true)
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
end
|
||||
@@ -1,22 +1,16 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local sys = api.sys
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
s = m:section(TypedSection, "global", translate("ACLs"), "<font color='red'>" .. translate("ACLs is a tools which used to designate specific IP proxy mode.") .. "</font>")
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global[0]", "global", translate("ACLs"), "<font color='red'>" .. translate("ACLs is a tools which used to designate specific IP proxy mode.") .. "</font>")
|
||||
|
||||
o = s:option(Flag, "acl_enable", translate("Main switch"))
|
||||
o.rmempty = false
|
||||
o.default = false
|
||||
|
||||
-- [[ ACLs Settings ]]--
|
||||
local cfgname = "acl_rule"
|
||||
s = m:section(TypedSection, cfgname)
|
||||
s = m:section(TypedSection, "acl_rule")
|
||||
s.template = "cbi/tblsection"
|
||||
s.sortable = true
|
||||
s.anonymous = true
|
||||
@@ -38,7 +32,7 @@ o = s:option(Value, "remarks", translate("Remarks"))
|
||||
o.rmempty = true
|
||||
|
||||
local mac_t = {}
|
||||
sys.net.mac_hints(function(e, t)
|
||||
api.sys.net.mac_hints(function(e, t)
|
||||
mac_t[e] = {
|
||||
ip = t,
|
||||
mac = e
|
||||
@@ -81,9 +75,6 @@ i.cfgvalue = function(t, n)
|
||||
return translate("No Proxy")
|
||||
end
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.target_cfgname = cfgname
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,18 +1,13 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(api.url("acl"))
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
|
||||
local sys = api.sys
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local port_validate = function(self, value, t)
|
||||
return value:gsub("-", ":")
|
||||
@@ -44,6 +39,7 @@ local doh_validate = function(self, value, t)
|
||||
end
|
||||
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||
end
|
||||
|
||||
-- [[ ACLs Settings ]]--
|
||||
s = m:section(NamedSection, arg[1], translate("ACLs"), translate("ACLs"))
|
||||
s.addremove = false
|
||||
@@ -73,7 +69,7 @@ o.validate = function(self, value, section)
|
||||
end
|
||||
|
||||
local mac_t = {}
|
||||
sys.net.mac_hints(function(e, t)
|
||||
api.sys.net.mac_hints(function(e, t)
|
||||
mac_t[#mac_t + 1] = {
|
||||
ip = t,
|
||||
mac = e
|
||||
@@ -181,7 +177,7 @@ o:depends("mode", "1")
|
||||
o.validate = port_validate
|
||||
|
||||
o = s:option(DummyValue, "_hide_node_option", "")
|
||||
o.template = "passwall2/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends("mode", "0")
|
||||
o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" })
|
||||
@@ -199,13 +195,13 @@ else
|
||||
o.group = {}
|
||||
end
|
||||
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
|
||||
current_node_id = o:formvalue(arg[1])
|
||||
if not current_node_id then
|
||||
current_node_id = m.uci:get(appname, arg[1], "node")
|
||||
current_node_id = m:get(arg[1], "node")
|
||||
end
|
||||
current_node = current_node_id and m.uci:get_all(appname, current_node_id) or {}
|
||||
current_node = current_node_id and m:get(current_node_id) or {}
|
||||
|
||||
o = s:option(Flag, "log", translate("Enable Node Log"))
|
||||
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
|
||||
@@ -259,7 +255,7 @@ end
|
||||
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
|
||||
|
||||
o = s:option(DummyValue, "_hide_dns_option", "")
|
||||
o.template = "passwall2/cbi/hidevalue"
|
||||
o.template = m:template_path("/cbi/hidevalue")
|
||||
o.value = "1"
|
||||
o:depends({ node = "" })
|
||||
if GLOBAL_ENABLED == "1" and NODE then
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local com = require "luci.passwall2.com"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
local com = require "luci.passwall2.com"
|
||||
|
||||
m = Map()
|
||||
|
||||
-- [[ App Settings ]]--
|
||||
s = m:section(TypedSection, "global_app", translate("App Update"))
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_app[0]", "global_app", translate("App Update"))
|
||||
|
||||
local app_version = Template(appname .. "/app_update/app_version")
|
||||
app_version.api = api
|
||||
app_version.config = m.config
|
||||
app_version.com = com
|
||||
s:append(app_version)
|
||||
s:appendTemplate("/app_update/app_version", {com = com})
|
||||
|
||||
local k, v
|
||||
for k, v in pairs(com) do
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local fs = api.fs
|
||||
local uci = api.uci
|
||||
|
||||
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geo_dir = (uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
local geosite_path = geo_dir .. "/geosite.dat"
|
||||
local geoip_path = geo_dir .. "/geoip.dat"
|
||||
if fs.access(geosite_path) and fs.access(geoip_path) then
|
||||
f = SimpleForm(appname)
|
||||
f = SimpleForm(api.c_config)
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
f:append(Template(appname .. "/rule/geoview"))
|
||||
|
||||
local obj = Template(api.appname .. "/rule/geoview")
|
||||
obj.api = api
|
||||
f:append(obj)
|
||||
end
|
||||
|
||||
return f
|
||||
return f
|
||||
@@ -1,15 +1,12 @@
|
||||
api = require "luci.passwall2.api"
|
||||
appname = api.appname
|
||||
datatypes = api.datatypes
|
||||
has_singbox = api.finded_com("sing-box")
|
||||
has_xray = api.finded_com("xray")
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
nodes_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
@@ -40,7 +37,7 @@ for k, v in pairs(nodes_table) do
|
||||
end
|
||||
|
||||
local socks_list = {}
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s.enabled == "1" and s.node then
|
||||
socks_list[#socks_list + 1] = {
|
||||
id = s[".name"],
|
||||
@@ -72,13 +69,9 @@ local doh_validate = function(self, value, t)
|
||||
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/global/status"))
|
||||
m:appendTemplate("/global/status")
|
||||
|
||||
global_cfgid = (m:get("@global[0]") or {})[".name"] or ""
|
||||
|
||||
s = m:section(TypedSection, "global")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global[0]", "global")
|
||||
|
||||
s:tab("Main", translate("Main"))
|
||||
|
||||
@@ -88,12 +81,12 @@ o.rmempty = false
|
||||
|
||||
---- Node
|
||||
o = s:taboption("Main", ListValue, "node", "<a style='color: red'>" .. translate("Node") .. "</a>")
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o:value("", translate("Close"))
|
||||
o.group = {""}
|
||||
|
||||
current_node_id = m.uci:get(appname, global_cfgid, "node")
|
||||
current_node = current_node_id and m.uci:get_all(appname, current_node_id) or {}
|
||||
current_node_id = m:get(s.section, "node")
|
||||
current_node = current_node_id and m:get(current_node_id) or {}
|
||||
|
||||
-- Shunt Start
|
||||
if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
@@ -101,7 +94,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
if current_node.protocol == "_shunt" then
|
||||
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua")
|
||||
setfenv(shunt_lua, getfenv(1))(m, s, {
|
||||
s_cfgid = s:cfgsections()[1],
|
||||
s_cfgid = s.section,
|
||||
node_id = current_node_id,
|
||||
node = current_node,
|
||||
socks_list = socks_list,
|
||||
@@ -245,7 +238,7 @@ o = s:taboption("DNS", TextValue, "dns_hosts", translate("Domain Override"))
|
||||
o.rows = 5
|
||||
o.wrap = "off"
|
||||
o.remove = function(self, section)
|
||||
local node_value = s.fields["node"]:formvalue(global_cfgid)
|
||||
local node_value = s.fields["node"]:formvalue(section)
|
||||
if node_value then
|
||||
local node_t = m:get(node_value) or {}
|
||||
if node_t.type == "Xray" or node_t.type == "sing-box" then
|
||||
@@ -297,11 +290,11 @@ o:depends("log_node", "1")
|
||||
s:tab("faq", "FAQ")
|
||||
|
||||
o = s:taboption("faq", DummyValue, "")
|
||||
o.template = appname .. "/global/faq"
|
||||
o.template = m:template_path("/global/faq")
|
||||
|
||||
s:tab("maintain", translate("Maintain"))
|
||||
o = s:taboption("maintain", DummyValue, "")
|
||||
o.template = appname .. "/global/backup"
|
||||
o.template = m:template_path("/global/backup")
|
||||
|
||||
-- [[ Socks Server ]]--
|
||||
o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switch"))
|
||||
@@ -330,7 +323,7 @@ o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s2:option(ListValue, "node", translate("Socks Node"))
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {}
|
||||
|
||||
o = s2:option(DummyValue, "now_node", translate("Current Node"))
|
||||
@@ -346,7 +339,7 @@ o.cfgvalue = function(_, n)
|
||||
end
|
||||
|
||||
local n = 1
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s[".name"] == section then
|
||||
return false
|
||||
end
|
||||
@@ -382,12 +375,7 @@ for k, v in pairs(nodes_table) do
|
||||
end
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/global/footer")
|
||||
footer.api = api
|
||||
footer.global_cfgid = global_cfgid
|
||||
footer.shunt_list = api.jsonc.stringify(shunt_list)
|
||||
|
||||
m:append(footer)
|
||||
m:append(Template(appname .. "/global/status_bottom"))
|
||||
m:appendTemplate("/global/footer", {shunt_list = api.jsonc.stringify(shunt_list)})
|
||||
m:appendTemplate(Template("/global/status_bottom"))
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,7 +1,6 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local datatypes = api.datatypes
|
||||
local net = require "luci.model.network".init()
|
||||
api.set_default_cbi()
|
||||
|
||||
local nodes_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
@@ -15,18 +14,14 @@ for k, e in ipairs(api.get_valid_nodes()) do
|
||||
end
|
||||
end
|
||||
|
||||
api.set_default_cbi()
|
||||
m = Map()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_value_com"))
|
||||
m:appendTemplate("/cbi/nodes_value_com")
|
||||
|
||||
-- [[ Haproxy Settings ]]--
|
||||
s = m:section(TypedSection, "global_haproxy", translate("Basic Settings"))
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_haproxy[0]", "global_haproxy", translate("Basic Settings"))
|
||||
|
||||
s:append(Template(appname .. "/haproxy/status"))
|
||||
s:appendTemplate("/haproxy/status")
|
||||
|
||||
---- Balancing Enable
|
||||
o = s:option(Flag, "balancing_enable", translate("Enable Load Balancing"))
|
||||
@@ -69,9 +64,9 @@ o:depends("balancing_enable", true)
|
||||
|
||||
---- Health Check Type
|
||||
o = s:option(ListValue, "health_check_type", translate("Health Check Type"))
|
||||
o.default = "passwall_logic"
|
||||
o.default = "script_logic"
|
||||
o:value("tcp", "TCP")
|
||||
o:value("passwall_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement")))
|
||||
o:value("script_logic", translate("URL Test") .. string.format("(passwall2 %s)", translate("Inner implement")))
|
||||
o:depends("balancing_enable", true)
|
||||
|
||||
---- Passwall Inner implement Probe URL
|
||||
@@ -85,7 +80,7 @@ o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud
|
||||
o:value("https://wifi.vivo.com.cn/generate_204", "VIVO (CN)")
|
||||
o.default = o.keylist[3]
|
||||
o.description = translate("The URL used to detect the connection status.")
|
||||
o:depends("health_check_type", "passwall_logic")
|
||||
o:depends("health_check_type", "script_logic")
|
||||
|
||||
---- Health Check Inter
|
||||
o = s:option(Value, "health_check_inter", translate("Health Check Inter"))
|
||||
@@ -99,11 +94,10 @@ o.rawhtml = true
|
||||
o.cfgvalue = function(t, n)
|
||||
return string.format('<span style="color: red">%s</span>', translate("When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid."))
|
||||
end
|
||||
o:depends("health_check_type", "passwall_logic")
|
||||
o:depends("health_check_type", "script_logic")
|
||||
|
||||
-- [[ Balancing Settings ]]--
|
||||
local cfgname = "haproxy_config"
|
||||
s = m:section(TypedSection, cfgname, translate("Node List"))
|
||||
s = m:section(TypedSection, "haproxy_config", translate("Node List"))
|
||||
s.description = "<font color='red'>" ..
|
||||
translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "<br>" ..
|
||||
translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. "</font>"
|
||||
@@ -132,7 +126,7 @@ o.rmempty = false
|
||||
|
||||
---- Node Address
|
||||
o = s:option(Value, "lbss", translate("Node Address"))
|
||||
o.template = appname .. "/cbi/nodes_value"
|
||||
o.template = m:template_path("/cbi/nodes_value")
|
||||
o.group = {}
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
@@ -180,11 +174,8 @@ o:value(0, translate("Primary"))
|
||||
o:value(1, translate("Standby"))
|
||||
o.rmempty = false
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.target_cfgname = cfgname
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||
|
||||
m:append(Template(appname .. "/haproxy/js"))
|
||||
m:appendTemplate("/haproxy/js")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -9,7 +9,7 @@ local current_node_id = data.node_id
|
||||
local node_list = data.node_list or api.get_node_list()
|
||||
|
||||
local groups = {}
|
||||
m.uci:foreach(appname, "shunt_rules", function(s)
|
||||
m:foreach("shunt_rules", function(s)
|
||||
if s.group and s.group ~= "" then
|
||||
groups[s.group] = true
|
||||
end
|
||||
@@ -123,7 +123,7 @@ end
|
||||
local shunt_group_val = m:get(current_node_id, "shunt_group") or ""
|
||||
shunt_group_val = shunt_group_val:lower()
|
||||
local shunt_rules = {}
|
||||
m.uci:foreach(appname, "shunt_rules", function(e)
|
||||
m:foreach("shunt_rules", function(e)
|
||||
local group = e.group or ""
|
||||
group = group:lower()
|
||||
if group == shunt_group_val then
|
||||
@@ -146,7 +146,7 @@ table.insert(shunt_rules, {
|
||||
})
|
||||
|
||||
s2 = m:section(Table, shunt_rules, " ")
|
||||
s2.config = appname
|
||||
s2.config = m.config
|
||||
s2.sectiontype = "shunt_option_list"
|
||||
|
||||
o = s2:option(DummyValue, "remarks", translate("Rule"))
|
||||
@@ -160,7 +160,7 @@ o.cfgvalue = function(self, section)
|
||||
end
|
||||
|
||||
_node = s2:option(Value, "_node", translate("Node"))
|
||||
_node.template = appname .. "/cbi/nodes_listvalue"
|
||||
_node.template = m:template_path("/cbi/nodes_listvalue")
|
||||
_node.group = {"","","",""}
|
||||
_node:value("", translate("Close (Not use)"))
|
||||
_node:value("_default", translate("Use default node"))
|
||||
@@ -192,7 +192,7 @@ end
|
||||
proxy_tag_node = s2:option(ListValue, "_proxy_tag", string.format('<a style="color:red" title="%s">%s</a>',
|
||||
translate("Set the node to be used as a pre-proxy.") .. "\n" .. translate("Each rule has a separate switch that controls whether this rule uses the pre-proxy or not."),
|
||||
translate("Preproxy")))
|
||||
proxy_tag_node.template = appname .. "/cbi/nodes_listvalue"
|
||||
proxy_tag_node.template = m:template_path("/cbi/nodes_listvalue")
|
||||
proxy_tag_node.group = {""}
|
||||
proxy_tag_node:value("", translate("Close (Not use)"))
|
||||
proxy_tag_node.cfgvalue = function(self, section)
|
||||
@@ -217,10 +217,4 @@ for k1, v1 in pairs(node_list) do
|
||||
end
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/include/shunt_options")
|
||||
footer.api = api
|
||||
footer.config = m.config
|
||||
footer.id = current_node_id
|
||||
footer.s_cfgid = s_cfgid or current_node_id
|
||||
footer.normal_list = api.jsonc.stringify(node_list.normal_list)
|
||||
m:append(footer)
|
||||
m:appendTemplate("/include/shunt_options", {id = current_node_id, s_cfgid = s_cfgid or current_node_id, normal_list = api.jsonc.stringify(node_list.normal_list)})
|
||||
@@ -1,30 +1,22 @@
|
||||
api = require "luci.passwall2.api"
|
||||
appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname, translate("Node Config"))
|
||||
m = Map()
|
||||
m.redirect = api.url()
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(api.url("node_list"))
|
||||
end
|
||||
|
||||
fs = require "nixio.fs"
|
||||
formvalue_key = "cbid." .. appname .. "." .. arg[1] .. "."
|
||||
formvalue_key = "cbid." .. m.config .. "." .. arg[1] .. "."
|
||||
|
||||
local header = Template(appname .. "/node_config/header")
|
||||
header.api = api
|
||||
header.config = m.config
|
||||
header.section = arg[1]
|
||||
m:append(header)
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_multivalue_com"))
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/node_config/header", {section = arg[1]})
|
||||
m:appendTemplate("/cbi/nodes_multivalue_com")
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
groups = {}
|
||||
m.uci:foreach(appname, "nodes", function(s)
|
||||
m:foreach("nodes", function(s)
|
||||
if s[".name"] ~= arg[1] then
|
||||
if s.group and s.group ~= "" then
|
||||
groups[s.group] = true
|
||||
@@ -32,13 +24,13 @@ m.uci:foreach(appname, "nodes", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "nodes", "")
|
||||
s = m:section(NamedSection, arg[1], "nodes", translate("Node Config"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
o = s:option(DummyValue, "passwall2", " ")
|
||||
o.rawhtml = true
|
||||
o.template = "passwall2/node_config/link_share_man"
|
||||
o.template = m:template_path("/node_config/link_share_man")
|
||||
o.value = arg[1]
|
||||
|
||||
o = s:option(Value, "remarks", translate("Node Remarks"))
|
||||
@@ -67,10 +59,10 @@ o.write = function(self, section, value)
|
||||
m:set(section, self.option, value)
|
||||
end
|
||||
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/passwall2/client/type/"
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. api.appname .. "/client/type/"
|
||||
s.val = {}
|
||||
s.val["type"] = m.uci:get(appname, arg[1], "type")
|
||||
s.val["protocol"] = m.uci:get(appname, arg[1], "protocol")
|
||||
s.val["type"] = m:get(arg[1], "type")
|
||||
s.val["protocol"] = m:get(arg[1], "protocol")
|
||||
|
||||
if luci.http.formvalue("cbi.submit") == "1" then
|
||||
local formvalue_type = luci.http.formvalue(formvalue_key .. "type")
|
||||
@@ -92,10 +84,6 @@ for index, value in ipairs(type_table) do
|
||||
setfenv(p_func, getfenv(1))(m, s)
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/node_config/footer")
|
||||
footer.api = api
|
||||
footer.config = m.config
|
||||
footer.section = arg[1]
|
||||
m:append(footer)
|
||||
m:appendTemplate("/node_config/footer", {section = arg[1]})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,14 +1,10 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
-- [[ Other Settings ]]--
|
||||
s = m:section(TypedSection, "global_other")
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_other[0]", "global_other")
|
||||
|
||||
o = s:option(ListValue, "auto_detection_time", translate("Automatic detection delay"))
|
||||
o:value("0", translate("Close"))
|
||||
@@ -29,10 +25,7 @@ o:value("https://wifi.vivo.com.cn/generate_204", "VIVO (CN)")
|
||||
o.default = o.keylist[3]
|
||||
|
||||
if true then
|
||||
local o = Template(appname .. "/node_list/node_list")
|
||||
o.map = m
|
||||
o.api = api
|
||||
m:append(o)
|
||||
m:appendTemplate("/node_list/node_list")
|
||||
|
||||
if luci.http.formvalue("cbi.submit") == "1" then
|
||||
local group_order = {}
|
||||
@@ -45,7 +38,7 @@ if true then
|
||||
new_order[#new_order + 1] = w
|
||||
end)
|
||||
for idx, name in ipairs(new_order) do
|
||||
m.uci:reorder(appname, name, idx - 1)
|
||||
m.uci:reorder(m.config, name, idx - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local uci = api.uci
|
||||
api.set_default_cbi()
|
||||
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
@@ -38,20 +38,16 @@ if has_hysteria2 then
|
||||
table.insert(hysteria2_type, s)
|
||||
end
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
function m.on_before_save(self)
|
||||
self.uci:foreach(appname, "subscribe_list", function(e)
|
||||
self:foreach("subscribe_list", function(e)
|
||||
self:del(e[".name"], "md5")
|
||||
end)
|
||||
end
|
||||
|
||||
-- [[ Subscribe Settings ]]--
|
||||
s = m:section(TypedSection, "global_subscribe", "")
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_subscribe[0]", "global_subscribe")
|
||||
|
||||
o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode"))
|
||||
o:value("0", translate("Close"))
|
||||
@@ -126,8 +122,7 @@ o.cfgvalue = function(self, section)
|
||||
translate("Manual subscription All"))
|
||||
end
|
||||
|
||||
local cfgname = "subscribe_list"
|
||||
s = m:section(TypedSection, cfgname, "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
||||
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
||||
s.addremove = true
|
||||
s.anonymous = true
|
||||
s.sortable = true
|
||||
@@ -150,7 +145,7 @@ o.validate = function(self, value, section)
|
||||
return nil, translate("Remark cannot be empty.")
|
||||
end
|
||||
local duplicate = false
|
||||
m.uci:foreach(appname, cfgname, function(e)
|
||||
m:foreach(s.sectiontype, function(e)
|
||||
if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then
|
||||
duplicate = true
|
||||
return false
|
||||
@@ -164,9 +159,9 @@ end
|
||||
o.write = function(self, section, value)
|
||||
local old = m:get(section, self.option) or ""
|
||||
if old ~= value then
|
||||
m.uci:foreach(appname, "nodes", function(e)
|
||||
m:foreach("nodes", function(e)
|
||||
if e["group"] and e["group"]:lower() == old:lower() then
|
||||
m.uci:set(appname, e[".name"], "group", value)
|
||||
m:set(e[".name"], "group", value)
|
||||
end
|
||||
if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then
|
||||
local gs = ""
|
||||
@@ -178,7 +173,7 @@ o.write = function(self, section, value)
|
||||
end
|
||||
end
|
||||
gs = api.trim(gs)
|
||||
m.uci:set(appname, e[".name"], "node_group", gs)
|
||||
m:set(e[".name"], "node_group", gs)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -196,7 +191,7 @@ o.cfgvalue = function(t, n)
|
||||
end
|
||||
str = str ~= "" and "<br>" .. str or ""
|
||||
local num = 0
|
||||
m.uci:foreach(appname, "nodes", function(s)
|
||||
m:foreach("nodes", function(s)
|
||||
if s["group"] and s["group"]:lower() == remark:lower() then
|
||||
num = num + 1
|
||||
end
|
||||
@@ -225,11 +220,8 @@ o.cfgvalue = function(self, section)
|
||||
section, translate("Manual subscription"))
|
||||
end
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.target_cfgname = cfgname
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||
|
||||
m:append(Template(appname .. "/node_subscribe/js"))
|
||||
m:appendTemplate("/node_subscribe/js")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,11 +1,8 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
m = Map()
|
||||
m.redirect = api.url("node_subscribe")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
@@ -15,7 +12,7 @@ function m.on_before_save(self)
|
||||
self:del(arg[1], "md5")
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
@@ -79,7 +76,7 @@ o.validate = function(self, value, section)
|
||||
return nil, translate("Remark cannot be empty.")
|
||||
end
|
||||
local duplicate = false
|
||||
m.uci:foreach(appname, "subscribe_list", function(e)
|
||||
m:foreach("subscribe_list", function(e)
|
||||
if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then
|
||||
duplicate = true
|
||||
return false
|
||||
@@ -93,9 +90,9 @@ end
|
||||
o.write = function(self, section, value)
|
||||
local old = m:get(section, self.option) or ""
|
||||
if old ~= value then
|
||||
m.uci:foreach(appname, "nodes", function(e)
|
||||
m:foreach("nodes", function(e)
|
||||
if e["group"] and e["group"]:lower() == old:lower() then
|
||||
m.uci:set(appname, e[".name"], "group", value)
|
||||
self:set(e[".name"], "group", value)
|
||||
end
|
||||
if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then
|
||||
local gs = ""
|
||||
@@ -107,7 +104,7 @@ o.write = function(self, section, value)
|
||||
end
|
||||
end
|
||||
gs = api.trim(gs)
|
||||
m.uci:set(appname, e[".name"], "node_group", gs)
|
||||
self:set(e[".name"], "node_group", gs)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -298,13 +295,13 @@ descrStr = translate(descrStr) .. "<br>" .. translate("Only support a layer of p
|
||||
o1 = s:option(ListValue, "preproxy_node", translate("Preproxy Node"))
|
||||
o1:depends({ ["chain_proxy"] = "1" })
|
||||
o1.description = descrStr
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o1.group = {}
|
||||
|
||||
o2 = s:option(ListValue, "to_node", translate("Landing Node"))
|
||||
o2:depends({ ["chain_proxy"] = "2" })
|
||||
o2.description = descrStr
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o2.group = {}
|
||||
|
||||
o3 = s:option(Value, "outbound_iface", translate("Outbound Interface"))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
api.set_default_cbi()
|
||||
|
||||
local fs = api.fs
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
@@ -8,15 +9,10 @@ local port_validate = function(self, value, t)
|
||||
return value:gsub("-", ":")
|
||||
end
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
-- [[ Delay Settings ]]--
|
||||
s = m:section(TypedSection, "global_delay", translate("Delay Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global_delay[0]", "global_delay", translate("Delay Settings"))
|
||||
|
||||
---- Open and close Daemon
|
||||
o = s:option(Flag, "start_daemon", translate("Open and close Daemon"))
|
||||
@@ -72,9 +68,7 @@ for index, value in ipairs({"stop", "start", "restart"}) do
|
||||
end
|
||||
|
||||
-- [[ Forwarding Settings ]]--
|
||||
s = m:section(TypedSection, "global_forwarding", translate("Forwarding Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global_forwarding[0]", "global_forwarding", translate("Forwarding Settings"))
|
||||
|
||||
---- TCP No Redir Ports
|
||||
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
|
||||
@@ -205,9 +199,7 @@ o.validate = function(self, value)
|
||||
end
|
||||
|
||||
if has_xray then
|
||||
s_xray = m:section(TypedSection, "global_xray", "Xray " .. translate("Settings"))
|
||||
s_xray.anonymous = true
|
||||
s_xray.addremove = false
|
||||
s_xray = m:section(NamedSection, "@global_xray[0]", "global_xray", "Xray " .. translate("Settings"))
|
||||
|
||||
o = s_xray:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists."))
|
||||
o.default = 0
|
||||
@@ -245,7 +237,7 @@ if has_xray then
|
||||
o.default = 0
|
||||
o:depends("sniffing", true)
|
||||
|
||||
local domains_excluded = string.format("/usr/share/%s/domains_excluded", appname)
|
||||
local domains_excluded = string.format("/usr/share/%s/domains_excluded", m.config)
|
||||
o = s_xray:option(TextValue, "excluded_domains", translate("Excluded Domains"), translate("If the traffic sniffing result is in this list, the destination address will not be overridden."))
|
||||
o.rows = 15
|
||||
o.wrap = "off"
|
||||
@@ -268,11 +260,14 @@ if has_xray then
|
||||
end
|
||||
|
||||
s_xray_noise.remove = function(self, section)
|
||||
for k, v in pairs(self.children) do
|
||||
v.rmempty = true
|
||||
v.validate = nil
|
||||
local o = m:get(section) or {}
|
||||
if o[".type"] == self.sectiontype then
|
||||
for k, v in pairs(self.children) do
|
||||
v.rmempty = true
|
||||
v.validate = nil
|
||||
end
|
||||
TypedSection.remove(self, section)
|
||||
end
|
||||
TypedSection.remove(self, section)
|
||||
end
|
||||
|
||||
o = s_xray_noise:option(Flag, "enabled", translate("Enable"))
|
||||
@@ -296,9 +291,7 @@ if has_xray then
|
||||
end
|
||||
|
||||
if has_singbox then
|
||||
s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
s = m:section(NamedSection, "@global_singbox[0]", "global_singbox", "Sing-Box " .. translate("Settings"))
|
||||
|
||||
o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"),
|
||||
translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first."))
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
-- [[ Rule Settings ]]--
|
||||
s = m:section(TypedSection, "global_rules", translate("Rule status"))
|
||||
s.anonymous = true
|
||||
s = m:section(NamedSection, "@global_rules[0]", "global_rules", translate("Rule status"))
|
||||
|
||||
o = s:option(Value, "geoip_url", translate("GeoIP Update URL"))
|
||||
o:value("https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat", translate("Loyalsoldier/geoip"))
|
||||
@@ -86,12 +82,10 @@ for _, f in ipairs(flags) do
|
||||
o.rmempty = false
|
||||
end
|
||||
|
||||
s:append(Template(appname .. "/rule/rule_version"))
|
||||
s:appendTemplate("/rule/rule_version")
|
||||
|
||||
if true then
|
||||
local o = Template(appname .. "/rule/shunt_rule_list")
|
||||
o.api = api
|
||||
m:append(o)
|
||||
m:appendTemplate("/rule/shunt_rule_list")
|
||||
|
||||
if luci.http.formvalue("cbi.submit") == "1" then
|
||||
local group_order = luci.http.formvaluetable("group.order")
|
||||
@@ -103,7 +97,7 @@ if true then
|
||||
new_order[#new_order + 1] = w
|
||||
end)
|
||||
for idx, name in ipairs(new_order) do
|
||||
m.uci:reorder(appname, name, idx - 1)
|
||||
m.uci:reorder(m.config, name, idx - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local datatypes = api.datatypes
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule"))
|
||||
local datatypes = api.datatypes
|
||||
|
||||
m = Map()
|
||||
m.redirect = api.url("rule")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
function m.on_before_save(self)
|
||||
m:set("@global[0]", "flush_set", "1")
|
||||
self:set("@global[0]", "flush_set", "1")
|
||||
end
|
||||
|
||||
-- Add inline CSS to map description
|
||||
@@ -47,7 +45,7 @@ end
|
||||
|
||||
local remarks_lookup = {}
|
||||
local groups = {}
|
||||
m.uci:foreach(appname, "shunt_rules", function(s)
|
||||
m:foreach("shunt_rules", function(s)
|
||||
if s[".name"] ~= arg[1] then
|
||||
if s.remarks then
|
||||
remarks_lookup[s.remarks] = s[".name"]
|
||||
@@ -58,7 +56,7 @@ m.uci:foreach(appname, "shunt_rules", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map()
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(api.url())
|
||||
end
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_dynamiclist_com"))
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_dynamiclist_com")
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
@@ -49,14 +46,14 @@ socks_node = s:option(ListValue, "node", translate("Node"))
|
||||
if auto_switch_tip then
|
||||
socks_node.description = auto_switch_tip
|
||||
end
|
||||
socks_node.template = appname .. "/cbi/nodes_listvalue"
|
||||
socks_node.template = m:template_path("/cbi/nodes_listvalue")
|
||||
socks_node.group = {}
|
||||
|
||||
o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
|
||||
o.default = "0"
|
||||
|
||||
local n = 1
|
||||
m.uci:foreach(appname, "socks", function(s)
|
||||
m:foreach("socks", function(s)
|
||||
if s[".name"] == section then
|
||||
return false
|
||||
end
|
||||
@@ -90,7 +87,7 @@ o:value("batch", translate("Batch"))
|
||||
|
||||
o = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes"))
|
||||
o:depends("backup_node_add_mode", "manual")
|
||||
o.template = appname .. "/cbi/nodes_dynamiclist"
|
||||
o.template = m:template_path("/cbi/nodes_dynamiclist")
|
||||
o.group = {}
|
||||
o.write = function(self, section, value)
|
||||
local n = s.fields["node"]:formvalue(section)
|
||||
@@ -116,7 +113,7 @@ o:depends("backup_node_add_mode", "batch")
|
||||
o.widget = "checkbox"
|
||||
o:value("default", translate("default"))
|
||||
local groups = {}
|
||||
m.uci:foreach(appname, "nodes", function(s)
|
||||
m:foreach("nodes", function(s)
|
||||
if s.group and s.group ~= "" then
|
||||
groups[s.group] = true
|
||||
end
|
||||
@@ -164,7 +161,7 @@ o.default = o.keylist[3]
|
||||
o:depends("enable_autoswitch", true)
|
||||
|
||||
o = s:option(DummyValue, "btn")
|
||||
o.template = appname .. "/socks_auto_switch/btn"
|
||||
o.template = m:template_path("/socks_auto_switch/btn")
|
||||
o:depends("backup_node_add_mode", "manual")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -105,7 +105,7 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
o = s:option(MultiValue, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>document</a>"))
|
||||
o:depends({ [_n("node_add_mode")] = "manual" })
|
||||
o.widget = "checkbox"
|
||||
o.template = appname .. "/cbi/nodes_multivalue"
|
||||
o.template = m:template_path("/cbi/nodes_multivalue")
|
||||
o.group = {}
|
||||
for k1, v1 in pairs(node_list) do
|
||||
if k1 == "socks_list" or k1 == "normal_list" then
|
||||
@@ -171,7 +171,7 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
o:value("", translate("Close(Not use)"))
|
||||
o:value("_direct", translate("Direct Connection"))
|
||||
o:depends({ [_n("protocol")] = "_balancing" })
|
||||
o.template = appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
-- Maximum number of fallback nesting layers
|
||||
local MAX_FALLBACK_DEPTH = 3
|
||||
-- Check if a loop will form.
|
||||
@@ -863,7 +863,7 @@ if not load_shunt_options then
|
||||
|
||||
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
|
||||
o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false })
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o1.group = {}
|
||||
|
||||
o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface"))
|
||||
@@ -875,7 +875,7 @@ if not load_shunt_options then
|
||||
|
||||
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
|
||||
o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false })
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o2.group = {}
|
||||
|
||||
for k1, v1 in pairs(node_list) do
|
||||
@@ -898,7 +898,7 @@ end
|
||||
api.luci_types(arg[1], m, s, type_name, option_prefix)
|
||||
|
||||
if load_shunt_options then
|
||||
local current_node = m.uci:get_all(appname, arg[1]) or {}
|
||||
local current_node = m:get(arg[1]) or {}
|
||||
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua")
|
||||
setfenv(shunt_lua, getfenv(1))(m, s, {
|
||||
node_id = arg[1],
|
||||
|
||||
@@ -107,7 +107,7 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
o = s:option(MultiValue, _n("urltest_node"), translate("URLTest node list"), translate("List of nodes to test, <a target='_blank' href='https://sing-box.sagernet.org/configuration/outbound/urltest'>document</a>"))
|
||||
o:depends({ [_n("node_add_mode")] = "manual" })
|
||||
o.widget = "checkbox"
|
||||
o.template = appname .. "/cbi/nodes_multivalue"
|
||||
o.template = m:template_path("/cbi/nodes_multivalue")
|
||||
o.group = {}
|
||||
for k1, v1 in pairs(node_list) do
|
||||
if k1 == "socks_list" or k1 == "normal_list" then
|
||||
@@ -937,7 +937,7 @@ if not load_shunt_options then
|
||||
|
||||
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
|
||||
o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false })
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o1.group = {}
|
||||
|
||||
o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface"))
|
||||
@@ -949,7 +949,7 @@ if not load_shunt_options then
|
||||
|
||||
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
|
||||
o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false })
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o2.group = {}
|
||||
|
||||
for k1, v1 in pairs(node_list) do
|
||||
@@ -972,7 +972,7 @@ end
|
||||
api.luci_types(arg[1], m, s, type_name, option_prefix)
|
||||
|
||||
if load_shunt_options then
|
||||
local current_node = m.uci:get_all(appname, arg[1]) or {}
|
||||
local current_node = m:get(arg[1]) or {}
|
||||
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua")
|
||||
setfenv(shunt_lua, getfenv(1))(m, s, {
|
||||
node_id = arg[1],
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map("passwall2_server", translate("Server-Side"))
|
||||
api.set_apply_on_parse(m)
|
||||
m = Map(api.s_config)
|
||||
|
||||
t = m:section(NamedSection, "global", "global")
|
||||
t = m:section(NamedSection, "global", "global", translate("Server-Side"))
|
||||
t.anonymous = true
|
||||
t.addremove = false
|
||||
|
||||
@@ -88,17 +85,9 @@ e = s_server:option(Flag, "log", translate("Log"))
|
||||
e.default = "1"
|
||||
e.rmempty = false
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.appname = m.config
|
||||
sortable.target_cfgname = s_server.sectiontype
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s_server.sectiontype})
|
||||
|
||||
local server_list_status = Template(appname .. "/server/server_list_status")
|
||||
server_list_status.api = api
|
||||
server_list_status.appname = m.config
|
||||
server_list_status.sectiontype = s_server.sectiontype
|
||||
m:append(server_list_status)
|
||||
m:appendTemplate("/server/server_list_status", {sectiontype = s_server.sectiontype})
|
||||
|
||||
s_user = m:section(TypedSection, "user", translate("Users Manager"))
|
||||
s_user.anonymous = true
|
||||
@@ -114,7 +103,7 @@ end
|
||||
s_user.remove = function(self, section)
|
||||
local o = m:get(section) or {}
|
||||
if o[".type"] == self.sectiontype then
|
||||
m.uci:foreach(m.config, "server", function(o)
|
||||
m:foreach("server", function(o)
|
||||
if o.user and section == o.user then
|
||||
m:set(o[".name"], "user", "")
|
||||
end
|
||||
@@ -144,12 +133,8 @@ e.width = "25%"
|
||||
e = s_user:option(DummyValue, "uuid", "UUID")
|
||||
e.width = "25%"
|
||||
|
||||
local sortable = Template(appname .. "/cbi/sortable")
|
||||
sortable.api = api
|
||||
sortable.appname = m.config
|
||||
sortable.target_cfgname = s_user.sectiontype
|
||||
m:append(sortable)
|
||||
m:appendTemplate("/cbi/sortable", {sectiontype = s_user.sectiontype})
|
||||
|
||||
m:append(Template(appname .. "/server/log"))
|
||||
m:appendTemplate("/server/log")
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -1,35 +1,27 @@
|
||||
api = require "luci.passwall2.api"
|
||||
appname = api.appname
|
||||
fs = api.fs
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map("passwall2_server", translate("Server Config"))
|
||||
m = Map(api.s_config)
|
||||
m.redirect = api.url("server")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
local header = Template(appname .. "/server/config_header")
|
||||
header.api = api
|
||||
header.config = m.config
|
||||
header.section = arg[1]
|
||||
m:append(header)
|
||||
m:appendTemplate("/server/config_header", {section = arg[1]})
|
||||
|
||||
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
|
||||
m:appendTemplate("/cbi/nodes_listvalue_com")
|
||||
|
||||
user_list = {}
|
||||
m.uci:foreach(m.config, "user", function(s)
|
||||
m:foreach("user", function(s)
|
||||
user_list[#user_list + 1] = s
|
||||
end)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "server", "")
|
||||
s = m:section(NamedSection, arg[1], "server", translate("Server Config"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
|
||||
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. api.appname .. "/server/type/"
|
||||
s.val = m:get(arg[1]) or {}
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
@@ -43,7 +35,7 @@ o.rmempty = false
|
||||
o = s:option(ListValue, "type", translate("Type"))
|
||||
|
||||
local type_table = {}
|
||||
for filename in fs.dir(types_dir) do
|
||||
for filename in api.fs.dir(types_dir) do
|
||||
table.insert(type_table, filename)
|
||||
end
|
||||
table.sort(type_table, function(a, b)
|
||||
@@ -55,10 +47,6 @@ for index, value in ipairs(type_table) do
|
||||
setfenv(p_func, getfenv(1))(m, s)
|
||||
end
|
||||
|
||||
local footer = Template(appname .. "/server/config_footer")
|
||||
footer.api = api
|
||||
footer.config = m.config
|
||||
footer.section = arg[1]
|
||||
m:append(footer)
|
||||
m:appendTemplate("/server/config_footer", {section = arg[1]})
|
||||
|
||||
return api.return_map(m)
|
||||
@@ -446,7 +446,7 @@ o:value("", translate("Close"))
|
||||
o:value("_socks", translate("Custom Socks"))
|
||||
o:value("_http", translate("Custom HTTP"))
|
||||
o:value("_iface", translate("Custom Interface"))
|
||||
o.template = api.appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {"","","",""}
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
|
||||
@@ -424,7 +424,7 @@ o:value("", translate("Close"))
|
||||
o:value("_socks", translate("Custom Socks"))
|
||||
o:value("_http", translate("Custom HTTP"))
|
||||
o:value("_iface", translate("Custom Interface"))
|
||||
o.template = api.appname .. "/cbi/nodes_listvalue"
|
||||
o.template = m:template_path("/cbi/nodes_listvalue")
|
||||
o.group = {"","","",""}
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
api = require "luci.passwall2.api"
|
||||
appname = api.appname
|
||||
fs = api.fs
|
||||
|
||||
api.set_default_cbi()
|
||||
|
||||
m = Map("passwall2_server", translate("User Config"))
|
||||
m = Map(api.s_config)
|
||||
m.redirect = api.url("server")
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
if not arg[1] or not m:get(arg[1]) then
|
||||
luci.http.redirect(m.redirect)
|
||||
end
|
||||
|
||||
s = m:section(NamedSection, arg[1], "user", "")
|
||||
s = m:section(NamedSection, arg[1], "user", translate("User Config"))
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
o = s:option(Value, "username", translate("Username"))
|
||||
o.datatype = "and(uciname,maxlength(24))"
|
||||
o.rmempty = false
|
||||
function o.validate(self, value, section)
|
||||
local exists = false
|
||||
m:foreach("user", function(s)
|
||||
if s[".name"] ~= section and s.username == value then
|
||||
exists = true
|
||||
return false
|
||||
end
|
||||
end)
|
||||
if exists then
|
||||
return nil, translate("This username already exists.")
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.rmempty = false
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module("luci.passwall2.api", package.seeall)
|
||||
appname = "passwall2"
|
||||
c_config = "passwall2"
|
||||
s_config = "passwall2_server"
|
||||
local com = require "luci.passwall2.com"
|
||||
nixio = require "nixio"
|
||||
fs = require "nixio.fs"
|
||||
@@ -22,7 +24,7 @@ TMP_IFACE_PATH = TMP_PATH .. "/iface"
|
||||
|
||||
local lang = uci:get("luci", "main", "lang") or "auto"
|
||||
if lang == "auto" then
|
||||
local auto_lang = uci:get(appname, "@global[0]", "auto_lang")
|
||||
local auto_lang = uci:get(c_config, "@global[0]", "auto_lang")
|
||||
if auto_lang then lang = auto_lang end
|
||||
end
|
||||
if lang == "auto" then
|
||||
@@ -234,7 +236,7 @@ function curl_direct(url, file, args)
|
||||
end
|
||||
|
||||
function curl_auto(url, file, args)
|
||||
local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1"
|
||||
local localhost_proxy = uci:get(c_config, "@global[0]", "localhost_proxy") or "1"
|
||||
if localhost_proxy == "1" then
|
||||
return curl_base(url, file, args)
|
||||
else
|
||||
@@ -493,7 +495,7 @@ function get_node_name(node_id)
|
||||
if type(node_id) == "table" then
|
||||
e = node_id
|
||||
else
|
||||
e = uci:get_all(appname, node_id)
|
||||
e = uci:get_all(c_config, node_id)
|
||||
end
|
||||
if e then
|
||||
if e.type and e.remarks then
|
||||
@@ -509,11 +511,11 @@ function get_node_name(node_id)
|
||||
end
|
||||
|
||||
function get_valid_nodes()
|
||||
local show_node_info = uci_get_type("global_other", "show_node_info") or "0"
|
||||
local show_node_info = uci:get(c_config, "@global_other[0]", "show_node_info") or "0"
|
||||
local nodes = {}
|
||||
local default_nodes = {}
|
||||
local other_nodes = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
uci:foreach(c_config, "nodes", function(e)
|
||||
e.id = e[".name"]
|
||||
if e.type and e.remarks then
|
||||
local type_name = e.type
|
||||
@@ -586,7 +588,7 @@ function get_node_list()
|
||||
socks_list = {},
|
||||
normal_list = {},
|
||||
}
|
||||
uci:foreach(appname, "socks", function(s)
|
||||
uci:foreach(c_config, "socks", function(s)
|
||||
if s.enabled == "1" and s.node then
|
||||
node_list.socks_list[#node_list.socks_list + 1] = {
|
||||
id = s[".name"],
|
||||
@@ -685,22 +687,6 @@ function gen_random_char(length)
|
||||
return sys.exec("echo -n $(head /dev/urandom | tr -dc A-Za-z0-9 | head -c %s)" % length)
|
||||
end
|
||||
|
||||
function uci_get_type(type, config, default)
|
||||
local value = uci:get_first(appname, type, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. ".@" .. type .."[0]." .. config .. ")")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function uci_get_type_id(id, config, default)
|
||||
local value = uci:get(appname, id, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. "." .. id .. "." .. config .. ")")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function chmod_755(file)
|
||||
if file and file ~= "" then
|
||||
if not fs.access(file, "rwx", "rx", "rx") then
|
||||
@@ -710,7 +696,7 @@ function chmod_755(file)
|
||||
end
|
||||
|
||||
function get_customed_path(e)
|
||||
return uci_get_type("global_app", e .. "_file")
|
||||
return uci:get(c_config, "@global_app[0]", e .. "_file")
|
||||
end
|
||||
|
||||
function finded_com(e)
|
||||
@@ -769,7 +755,7 @@ end
|
||||
function get_app_path(app_name)
|
||||
if com[app_name] then
|
||||
local def_path = com[app_name].default_path
|
||||
local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file")
|
||||
local path = uci:get(c_config, "@global_app[0]", app_name:gsub("%-","_") .. "_file")
|
||||
path = path and (#path>0 and path or def_path) or def_path
|
||||
return path
|
||||
end
|
||||
@@ -1345,53 +1331,91 @@ function is_js_luci()
|
||||
return sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0
|
||||
end
|
||||
|
||||
function set_apply_on_parse(map)
|
||||
if not map then
|
||||
return
|
||||
end
|
||||
local lang = uci:get("luci", "main", "lang") or "auto"
|
||||
if lang == "auto" then
|
||||
local http = require "luci.http"
|
||||
local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or ""
|
||||
for lpat in aclang:gmatch("[%w-]+") do
|
||||
lpat = lpat and lpat:gsub("-", "_")
|
||||
if uci:get("luci", "languages", lpat) then
|
||||
lang = lpat
|
||||
break
|
||||
end
|
||||
lpat = lpat and lpat:lower()
|
||||
if uci:get("luci", "languages", lpat) then
|
||||
lang = lpat
|
||||
break
|
||||
end
|
||||
end
|
||||
if lang ~= "auto" then
|
||||
sh_uci_set(appname, "@global[0]", "auto_lang", lang, true)
|
||||
end
|
||||
end
|
||||
if is_js_luci() == true then
|
||||
local hide_popup_box = nil
|
||||
if hide_popup_box == true then
|
||||
map.apply_on_parse = false
|
||||
map.on_after_apply = function(self)
|
||||
if self.redirect then
|
||||
os.execute("sleep 1")
|
||||
luci.http.redirect(self.redirect)
|
||||
end
|
||||
end
|
||||
else
|
||||
apply_redirect(map)
|
||||
local old = map.on_after_save
|
||||
map.on_after_save = function(self)
|
||||
if old then old(self) end
|
||||
map:set("@global[0]", "timestamp", os.time())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function set_default_cbi()
|
||||
local cbi = require "luci.cbi"
|
||||
if true then
|
||||
--Map
|
||||
local Map = cbi.Map
|
||||
local original_init = Map.__init__
|
||||
function Map.__init__(self, config, ...)
|
||||
if not config then config = c_config end
|
||||
original_init(self, config, ...)
|
||||
self.api = require "luci.passwall2.api"
|
||||
end
|
||||
function Map.foreach(self, stype, func)
|
||||
self.uci:foreach(self.config, stype, func)
|
||||
end
|
||||
function Map.template_path(self, template)
|
||||
return appname .. template
|
||||
end
|
||||
function Map.appendTemplate(self, template, data)
|
||||
local obj = cbi.Template(self:template_path(template))
|
||||
obj.map = self
|
||||
if data and next(data) then
|
||||
for k, v in pairs(data) do
|
||||
obj[k] = v
|
||||
end
|
||||
end
|
||||
self:append(obj)
|
||||
return obj
|
||||
end
|
||||
|
||||
local lang = uci:get("luci", "main", "lang") or "auto"
|
||||
if lang == "auto" then
|
||||
local http = require "luci.http"
|
||||
local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or ""
|
||||
for lpat in aclang:gmatch("[%w-]+") do
|
||||
lpat = lpat and lpat:gsub("-", "_")
|
||||
if uci:get("luci", "languages", lpat) then
|
||||
lang = lpat
|
||||
break
|
||||
end
|
||||
lpat = lpat and lpat:lower()
|
||||
if uci:get("luci", "languages", lpat) then
|
||||
lang = lpat
|
||||
break
|
||||
end
|
||||
end
|
||||
if lang ~= "auto" then
|
||||
sh_uci_set(c_config, "@global[0]", "auto_lang", lang, true)
|
||||
end
|
||||
end
|
||||
if is_js_luci() == true then
|
||||
local hide_popup_box = nil
|
||||
if hide_popup_box == true then
|
||||
Map.apply_on_parse = false
|
||||
Map.on_after_apply = function(self)
|
||||
if self.redirect then
|
||||
os.execute("sleep 1")
|
||||
luci.http.redirect(self.redirect)
|
||||
end
|
||||
end
|
||||
else
|
||||
apply_redirect(Map)
|
||||
local old = Map.on_after_save
|
||||
Map.on_after_save = function(self)
|
||||
if old then old(self) end
|
||||
self:set("@global[0]", "timestamp", os.time())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if true then
|
||||
--AbstractSection
|
||||
local AbstractSection = cbi.AbstractSection
|
||||
function AbstractSection.appendTemplate(self, template, data)
|
||||
local obj = cbi.Template(self.map:template_path(template))
|
||||
obj.map = self.map
|
||||
obj.section = self
|
||||
if data and next(data) then
|
||||
for k, v in pairs(data) do
|
||||
obj[k] = v
|
||||
end
|
||||
end
|
||||
self:append(obj)
|
||||
return obj
|
||||
end
|
||||
end
|
||||
if true then
|
||||
--TextValue
|
||||
local TextValue = cbi.TextValue
|
||||
@@ -1428,18 +1452,15 @@ function return_map(map)
|
||||
if true then
|
||||
-- header
|
||||
local header = cbi.Template(appname .. "/cbi/header")
|
||||
header.api = api
|
||||
header.config = map.config
|
||||
header.map = map
|
||||
table.insert(map.children, 1, header)
|
||||
end
|
||||
if true then
|
||||
-- footer
|
||||
local footer = cbi.Template(appname .. "/cbi/footer")
|
||||
footer.api = api
|
||||
footer.config = map.config
|
||||
footer.map = map
|
||||
map:append(footer)
|
||||
end
|
||||
|
||||
return map
|
||||
end
|
||||
|
||||
@@ -1570,7 +1591,7 @@ function format_go_time(input, default)
|
||||
end
|
||||
|
||||
function apply_redirect(m)
|
||||
local tmp_uci_file = "/etc/config/" .. appname .. "_redirect"
|
||||
local tmp_uci_file = "/etc/config/" .. c_config .. "_redirect"
|
||||
if m.redirect and m.redirect ~= "" then
|
||||
if fs.access(tmp_uci_file) then
|
||||
local redirect
|
||||
@@ -1588,7 +1609,7 @@ function apply_redirect(m)
|
||||
m.on_after_save = function(self)
|
||||
local redirect = self.redirect
|
||||
if redirect and redirect ~= "" then
|
||||
uci:set(appname .. "_redirect", "@redirect[0]", "url", redirect)
|
||||
uci:set(c_config .. "_redirect", "@redirect[0]", "url", redirect)
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -1693,7 +1714,7 @@ end
|
||||
function get_socks_backup_nodes(id)
|
||||
id = trim(id)
|
||||
if id == "" then return "" end
|
||||
local socks = uci:get_all(appname, id)
|
||||
local socks = uci:get_all(c_config, id)
|
||||
local nodes
|
||||
if socks.backup_node_add_mode and socks.backup_node_add_mode == "batch" then
|
||||
local node = {}
|
||||
@@ -1714,7 +1735,7 @@ function get_socks_backup_nodes(id)
|
||||
end
|
||||
|
||||
function get_core(field, candidates)
|
||||
local v = uci:get(appname, "@global_subscribe[0]", field)
|
||||
local v = uci:get(c_config, "@global_subscribe[0]", field)
|
||||
if v and v ~= "" then
|
||||
for _, c in ipairs(candidates) do
|
||||
if c[2] == v and c[1] then
|
||||
|
||||
@@ -6,7 +6,7 @@ local sys = api.sys
|
||||
local uci = api.uci
|
||||
local jsonc = api.jsonc
|
||||
|
||||
local CONFIG = "passwall2_server"
|
||||
local CONFIG = api.s_config
|
||||
local CONFIG_PATH = "/tmp/etc/" .. CONFIG
|
||||
local NFT_INCLUDE_FILE = CONFIG_PATH .. "/" .. CONFIG .. ".nft"
|
||||
local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log"
|
||||
|
||||
@@ -9,7 +9,7 @@ function gen_config_server(node)
|
||||
if node.users and #node.users > 0 then
|
||||
users = {}
|
||||
for i, v in ipairs(node.users) do
|
||||
local user = uci:get_all("passwall2_server", v) or {}
|
||||
local user = uci:get_all(api.s_config, v) or {}
|
||||
if user[".type"] == "user" then
|
||||
users[user.username] = user.password
|
||||
end
|
||||
@@ -74,7 +74,7 @@ function gen_config(var)
|
||||
print("node Cannot be empty!")
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall2", node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local local_socks_address = var["local_socks_address"] or "0.0.0.0"
|
||||
local local_socks_port = var["local_socks_port"]
|
||||
local local_socks_username = var["local_socks_username"]
|
||||
|
||||
@@ -9,7 +9,7 @@ function gen_config(var)
|
||||
print("node Cannot be empty!")
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall2", node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local run_type = var["run_type"]
|
||||
local local_addr = var["local_addr"]
|
||||
local local_port = var["local_port"]
|
||||
|
||||
@@ -6,7 +6,7 @@ local jsonc = api.jsonc
|
||||
function gen_config_server(node)
|
||||
local user = nil
|
||||
if node.user then
|
||||
user = uci:get_all("passwall2_server", node.user)
|
||||
user = uci:get_all(api.s_config, node.user)
|
||||
end
|
||||
|
||||
local config = {}
|
||||
@@ -41,7 +41,7 @@ function gen_config(var)
|
||||
print("node Cannot be empty!")
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall2", node_id)
|
||||
local node = uci:get_all(api.c_config, node_id)
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
local local_addr = var["local_addr"]
|
||||
|
||||
@@ -34,7 +34,7 @@ function check_geoview()
|
||||
if GEO_VAR.OK == 0 then
|
||||
api.log(0, "!!! Note: Geo rules cannot be used if the Geoview component is missing or the version is too low.")
|
||||
else
|
||||
GEO_VAR.DIR = GEO_VAR.DIR or (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
GEO_VAR.DIR = GEO_VAR.DIR or (uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
|
||||
GEO_VAR.SITE_PATH = GEO_VAR.SITE_PATH or (GEO_VAR.DIR .. "/geosite.dat")
|
||||
GEO_VAR.IP_PATH = GEO_VAR.IP_PATH or (GEO_VAR.DIR .. "/geoip.dat")
|
||||
if not fs.access(GEO_VAR.TO_SRS_PATH) then
|
||||
@@ -794,7 +794,7 @@ function gen_config_server(node)
|
||||
if node.users and #node.users > 0 then
|
||||
users = {}
|
||||
for i, v in ipairs(node.users) do
|
||||
local user = uci:get_all("passwall2_server", v) or {}
|
||||
local user = uci:get_all(api.s_config, v) or {}
|
||||
if user[".type"] == "user" then
|
||||
local u = {}
|
||||
if node.protocol == "mixed" or node.protocol == "socks" or node.protocol == "http" or node.protocol == "naive" then
|
||||
@@ -1030,7 +1030,7 @@ function gen_config_server(node)
|
||||
}
|
||||
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
|
||||
else
|
||||
local outbound_node_t = uci:get_all("passwall2", node.outbound_node)
|
||||
local outbound_node_t = uci:get_all(api.c_config, node.outbound_node)
|
||||
if node.outbound_node == "_socks" or node.outbound_node == "_http" then
|
||||
outbound_node_t = {
|
||||
type = node.type,
|
||||
@@ -1132,7 +1132,7 @@ function gen_config(var)
|
||||
|
||||
local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt"
|
||||
|
||||
local singbox_settings = uci:get_all(appname, "@global_singbox[0]") or {}
|
||||
local singbox_settings = uci:get_all(api.c_config, "@global_singbox[0]") or {}
|
||||
|
||||
local route = {
|
||||
rules = {}
|
||||
@@ -1195,7 +1195,7 @@ function gen_config(var)
|
||||
|
||||
local node = nil
|
||||
if node_id then
|
||||
node = uci:get_all(appname, node_id)
|
||||
node = uci:get_all(api.c_config, node_id)
|
||||
end
|
||||
|
||||
if local_socks_port then
|
||||
@@ -1290,7 +1290,7 @@ function gen_config(var)
|
||||
|
||||
function get_node_by_id(node_id)
|
||||
if not node_id or node_id == "" or node_id == "nil" then return nil end
|
||||
local section = uci:get_all(appname, node_id) or {}
|
||||
local section = uci:get_all(api.c_config, node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
local result = {
|
||||
[".name"] = node_id,
|
||||
@@ -1569,7 +1569,7 @@ function gen_config(var)
|
||||
end
|
||||
|
||||
--shunt rule
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
uci:foreach(api.c_config, "shunt_rules", function(e)
|
||||
if node["shunt_group"] ~= e.group then
|
||||
return
|
||||
end
|
||||
@@ -1835,16 +1835,16 @@ function gen_config(var)
|
||||
if dns_listen_port then
|
||||
local dns_host = ""
|
||||
if flag == "global" then
|
||||
dns_host = uci:get(appname, "@global[0]", "dns_hosts") or ""
|
||||
dns_host = uci:get(api.c_config, "@global[0]", "dns_hosts") or ""
|
||||
else
|
||||
flag = flag:gsub("acl_", "")
|
||||
local dns_hosts_mode = uci:get(appname, flag, "dns_hosts_mode") or "default"
|
||||
local dns_hosts_mode = uci:get(api.c_config, flag, "dns_hosts_mode") or "default"
|
||||
if dns_hosts_mode == "default" then
|
||||
dns_host = uci:get(appname, "@global[0]", "dns_hosts") or ""
|
||||
dns_host = uci:get(api.c_config, "@global[0]", "dns_hosts") or ""
|
||||
elseif dns_hosts_mode == "disable" then
|
||||
dns_host = ""
|
||||
elseif dns_hosts_mode == "custom" then
|
||||
dns_host = uci:get(appname, flag, "dns_hosts") or ""
|
||||
dns_host = uci:get(api.c_config, flag, "dns_hosts") or ""
|
||||
end
|
||||
end
|
||||
if #dns_host > 0 then
|
||||
|
||||
@@ -501,7 +501,7 @@ function gen_config_server(node)
|
||||
if node.users and #node.users > 0 then
|
||||
users = {}
|
||||
for i, v in ipairs(node.users) do
|
||||
local user = uci:get_all("passwall2_server", v) or {}
|
||||
local user = uci:get_all(api.s_config, v) or {}
|
||||
if user[".type"] == "user" then
|
||||
local u = {}
|
||||
if node.protocol == "socks" or node.protocol == "http" then
|
||||
@@ -633,7 +633,7 @@ function gen_config_server(node)
|
||||
}
|
||||
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
|
||||
else
|
||||
local outbound_node_t = uci:get_all("passwall2", node.outbound_node)
|
||||
local outbound_node_t = uci:get_all(api.c_config, node.outbound_node)
|
||||
if node.outbound_node == "_socks" or node.outbound_node == "_http" then
|
||||
outbound_node_t = {
|
||||
type = node.type,
|
||||
@@ -906,7 +906,7 @@ function gen_config(var)
|
||||
|
||||
local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt"
|
||||
|
||||
local xray_settings = uci:get_all(appname, "@global_xray[0]") or {}
|
||||
local xray_settings = uci:get_all(api.c_config, "@global_xray[0]") or {}
|
||||
|
||||
if xray_settings.fragment == "1" then
|
||||
local lengths, delays = {}, {}
|
||||
@@ -931,7 +931,7 @@ function gen_config(var)
|
||||
|
||||
if xray_settings.noise == "1" then
|
||||
local noises = {}
|
||||
uci:foreach(appname, "xray_noise_packets", function(n)
|
||||
uci:foreach(api.c_config, "xray_noise_packets", function(n)
|
||||
if n.enabled == "1" then
|
||||
local noise = {
|
||||
rand = (n.type == "rand" and n.packet) and (n.packet:find("-", 1, true) and n.packet or tonumber(n.packet)) or nil,
|
||||
@@ -948,7 +948,7 @@ function gen_config(var)
|
||||
} or nil
|
||||
end
|
||||
|
||||
local node = node_id and uci:get_all(appname, node_id) or nil
|
||||
local node = node_id and uci:get_all(api.c_config, node_id) or nil
|
||||
local balancers = {}
|
||||
local rules = {}
|
||||
|
||||
@@ -1000,7 +1000,7 @@ function gen_config(var)
|
||||
|
||||
function get_node_by_id(node_id)
|
||||
if not node_id or node_id == "" or node_id == "nil" then return nil end
|
||||
local section = uci:get_all(appname, node_id) or {}
|
||||
local section = uci:get_all(api.c_config, node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
local result = {
|
||||
[".name"] = node_id,
|
||||
@@ -1394,7 +1394,7 @@ function gen_config(var)
|
||||
end
|
||||
|
||||
--shunt rule
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
uci:foreach(api.c_config, "shunt_rules", function(e)
|
||||
if node["shunt_group"] ~= e.group then
|
||||
return
|
||||
end
|
||||
@@ -1590,16 +1590,16 @@ function gen_config(var)
|
||||
|
||||
local dns_host = ""
|
||||
if flag == "global" then
|
||||
dns_host = uci:get(appname, "@global[0]", "dns_hosts") or ""
|
||||
dns_host = uci:get(api.c_config, "@global[0]", "dns_hosts") or ""
|
||||
else
|
||||
flag = flag:gsub("acl_", "")
|
||||
local dns_hosts_mode = uci:get(appname, flag, "dns_hosts_mode") or "default"
|
||||
local dns_hosts_mode = uci:get(api.c_config, flag, "dns_hosts_mode") or "default"
|
||||
if dns_hosts_mode == "default" then
|
||||
dns_host = uci:get(appname, "@global[0]", "dns_hosts") or ""
|
||||
dns_host = uci:get(api.c_config, "@global[0]", "dns_hosts") or ""
|
||||
elseif dns_hosts_mode == "disable" then
|
||||
dns_host = ""
|
||||
elseif dns_hosts_mode == "custom" then
|
||||
dns_host = uci:get(appname, flag, "dns_hosts") or ""
|
||||
dns_host = uci:get(api.c_config, flag, "dns_hosts") or ""
|
||||
end
|
||||
end
|
||||
if #dns_host > 0 then
|
||||
@@ -1977,7 +1977,7 @@ function gen_config(var)
|
||||
if inbounds or outbounds then
|
||||
local config = {
|
||||
env = (function()
|
||||
local asset_location = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local asset_location = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
return { XRAY_LOCATION_ASSET = asset_location }
|
||||
end)(),
|
||||
log = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<div id="app_version">
|
||||
<%
|
||||
local api = self.api
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local com = self.com
|
||||
-%>
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<%
|
||||
local map = self.map
|
||||
-%>
|
||||
<!-- map footer -->
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<!-- map header -->
|
||||
<script src="<%=resource%>/view/<%=self.api.appname%>/cbi.js"></script>
|
||||
<script src="<%=resource%>/view/<%=self.api.appname%>/func.js"></script>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/cbi.js"></script>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/func.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function update_config(cfgid, data, redirect_url) {
|
||||
XHR.get('<%=self.api.url("update_config")%>', {
|
||||
XHR.get('<%=api.url("update_config")%>', {
|
||||
id: cfgid,
|
||||
data: JSON.stringify(data)
|
||||
},
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = self.appname or api.appname
|
||||
local target_cfgname = self.target_cfgname
|
||||
local map = self.map
|
||||
local sectiontype = self.sectiontype
|
||||
local api = map.api
|
||||
local appname = self.appname or map.config
|
||||
-%>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js"></script>
|
||||
<style>
|
||||
@@ -37,7 +38,7 @@ local target_cfgname = self.target_cfgname
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
#cbi-<%=appname%>-<%=target_cfgname%> .cbi-section-table-titles {
|
||||
#cbi-<%=appname%>-<%=sectiontype%> .cbi-section-table-titles {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +48,7 @@ local target_cfgname = self.target_cfgname
|
||||
//Add drag-and-drop sorting
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
function initSortableForTable() {
|
||||
var section = document.getElementById("cbi-<%=appname%>-<%=target_cfgname%>");
|
||||
var section = document.getElementById("cbi-<%=appname%>-<%=sectiontype%>");
|
||||
if (!section) return;
|
||||
|
||||
// === insert drag handle ===
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<div class="cbi-section">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<style>
|
||||
.dns-con {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local appname = map.config
|
||||
local sid = "@global[0]"
|
||||
-%>
|
||||
<style>
|
||||
#cbi-<%=appname%>-socks .td.cbi-value-field > div {
|
||||
@@ -35,15 +37,17 @@ local appname = api.appname
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let global_id = "<%=sid%>";
|
||||
const shunt_list = JSON.parse('<%=self.shunt_list%>');
|
||||
|
||||
function to_edit_node(btn) {
|
||||
function to_edit_node(btn, stype) {
|
||||
if (!btn) return;
|
||||
const idReg = /^cbid\..*\..*node$/;
|
||||
if (!stype) return;
|
||||
let hidden_select = null;
|
||||
const container = btn.closest('#cbi-<%=appname%>-global') || btn.closest('#cbi-<%=appname%>-socks');
|
||||
if (!container) return null;
|
||||
const selects = container.querySelectorAll('select[id^="cbid."][id*="."][id$="node"]');
|
||||
const stype_dom = document.getElementById("cbi-<%=appname%>-" + stype);
|
||||
if (!stype_dom) return;
|
||||
const selects = stype_dom.querySelectorAll('select[id^="cbid."][id*="."][id$="node"]');
|
||||
const idReg = /^cbid\..*\..*node$/;
|
||||
for (const sel of selects) {
|
||||
if ( idReg.test(sel.id) && getComputedStyle(sel).display === "none" && (sel.compareDocumentPosition(btn) & Node.DOCUMENT_POSITION_FOLLOWING)) {
|
||||
hidden_select = sel;
|
||||
@@ -94,8 +98,7 @@ local appname = api.appname
|
||||
);
|
||||
}
|
||||
|
||||
let global_id = null;
|
||||
const global = document.getElementById("cbi-<%=appname%>-global");
|
||||
const global = document.getElementById("cbi-<%=appname%>-" + global_id);
|
||||
if (global) {
|
||||
// Add an "Edit" placeholder to the routing rule node in advance to ensure left alignment of the node list.
|
||||
document.querySelectorAll('.td[data-widget="nodes_listvalue"][data-name="_node"] > div').forEach(container => {
|
||||
@@ -109,10 +112,7 @@ local appname = api.appname
|
||||
|
||||
await delay(100);
|
||||
|
||||
const node = global.getElementsByClassName("cbi-section-node")[0];
|
||||
const node_id = node.getAttribute("id");
|
||||
global_id = node_id;
|
||||
const all_node = node.querySelectorAll("[id]");
|
||||
const all_node = global.querySelectorAll("[id]");
|
||||
const reg1 = /^cbid\..*node\.main$/;
|
||||
//const reg1 = /^cbid\..*\.(node)\.main$/;
|
||||
|
||||
@@ -129,7 +129,7 @@ local appname = api.appname
|
||||
continue;
|
||||
}
|
||||
|
||||
let html = '<a href="#" onclick="return to_edit_node(this);"><%:Edit%></a>';
|
||||
let html = '<a href="#" onclick="return to_edit_node(this, global_id);"><%:Edit%></a>';
|
||||
|
||||
const m = cbid.match(/\.node$/);
|
||||
if (m) {
|
||||
@@ -149,7 +149,7 @@ local appname = api.appname
|
||||
|
||||
const socks = document.getElementById("cbi-<%=appname%>-socks");
|
||||
if (socks) {
|
||||
const socks_enabled_dom = document.getElementById(global_id + "-socks_enabled");
|
||||
const socks_enabled_dom = document.getElementById("cbi-<%=appname%>-" + global_id + "-socks_enabled");
|
||||
const descr = socks.getElementsByClassName("cbi-section-descr")[0];
|
||||
descr.replaceWith(socks_enabled_dom);
|
||||
const rows = socks.getElementsByClassName("cbi-section-table-row");
|
||||
@@ -164,7 +164,7 @@ local appname = api.appname
|
||||
const node_select = document.getElementById(dom_id);
|
||||
if (!node_select) continue;
|
||||
|
||||
let html = '<a href="#" onclick="return to_edit_node(this);"><%:Edit%></a>';
|
||||
let html = '<a href="#" onclick="return to_edit_node(this, \'socks\');"><%:Edit%></a>';
|
||||
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_socks_log")%>?name=' + id.replace("cbi-<%=appname%>-", "") + '\', \'_blank\')"><%:Log%></a>';
|
||||
|
||||
node_select.insertAdjacentHTML("afterend",
|
||||
@@ -200,7 +200,7 @@ local appname = api.appname
|
||||
})();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => setTimeout(() => {
|
||||
const hiddenSelect = document.getElementById("cbid.<%=appname%>.<%=self.global_cfgid%>.node");
|
||||
const hiddenSelect = document.getElementById("cbid.<%=appname%>.<%=sid%>.node");
|
||||
let o_val = hiddenSelect.value
|
||||
const o_hasItem = shunt_list.find(element => element.id == o_val);
|
||||
hiddenSelect.addEventListener("change", function(el){
|
||||
@@ -208,7 +208,7 @@ local appname = api.appname
|
||||
const new_hasItem = shunt_list.find(element => element.id == new_val);
|
||||
if (new_hasItem) {
|
||||
XHR.get('<%=api.url("update_config")%>', {
|
||||
id: "<%=self.global_cfgid%>",
|
||||
id: "<%=sid%>",
|
||||
data: JSON.stringify({
|
||||
node: new_val
|
||||
})
|
||||
@@ -223,8 +223,8 @@ local appname = api.appname
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
document.getElementById("tab.<%=appname%>.<%=self.global_cfgid%>.Shunt").classList.add('shunt-tab-hidden');
|
||||
document.getElementById("tab.<%=appname%>.<%=self.global_cfgid%>.Shunt").style.display = "none";
|
||||
document.getElementById("tab.<%=appname%>.<%=sid%>.Shunt").classList.add('shunt-tab-hidden');
|
||||
document.getElementById("tab.<%=appname%>.<%=sid%>.Shunt").style.display = "none";
|
||||
} catch (error) {}
|
||||
try {
|
||||
document.querySelector('li[data-tab*="Shunt"]').classList.add('shunt-tab-hidden');
|
||||
@@ -232,7 +232,7 @@ local appname = api.appname
|
||||
} catch (error) {}
|
||||
}
|
||||
});
|
||||
let shunt_taboption = document.getElementById("container.<%=appname%>.<%=self.global_cfgid%>.Shunt");
|
||||
let shunt_taboption = document.getElementById("container.<%=appname%>.<%=sid%>.Shunt");
|
||||
if (shunt_taboption) {
|
||||
let shunt_option_list = document.getElementById("cbi-<%=appname%>-shunt_option_list");
|
||||
if (shunt_option_list) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local appname = map.config
|
||||
-%>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local haproxy_enable = api.uci_get_type("global_haproxy", "balancing_enable", "0")
|
||||
local console_port = api.uci_get_type("global_haproxy", "console_port", "")
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local haproxy_enable = map:get("@global_haproxy[0]", "balancing_enable") or "0"
|
||||
local console_port = map:get("@global_haproxy[0]", "console_port") or ""
|
||||
-%>
|
||||
<p id="_status"></p>
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local config = map.config
|
||||
local id = self.id
|
||||
local s_cfgid = self.s_cfgid
|
||||
-%>
|
||||
<style>
|
||||
.hidden {
|
||||
display: none !important;
|
||||
@@ -54,15 +61,15 @@
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="shunt_group"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="shunt_group"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
if (o_val != el.value) {
|
||||
let save = true;
|
||||
if (save) {
|
||||
update_config("<%=self.id%>", {
|
||||
shunt_group: getOption("<%=self.config%>", "<%=self.s_cfgid%>", "shunt_group").value,
|
||||
update_config("<%=id%>", {
|
||||
shunt_group: getOption("<%=config%>", "<%=s_cfgid%>", "shunt_group").value,
|
||||
}, get_current_url());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local sid = self.section
|
||||
local config = map.config
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let node_id = "<%=self.section%>";
|
||||
let node_config_url = '<%=self.api.url("node_config")%>/' + node_id;
|
||||
let node_id = "<%=sid%>";
|
||||
let node_config_url = '<%=api.url("node_config")%>/' + node_id;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="type"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
@@ -18,16 +24,16 @@
|
||||
}
|
||||
*/
|
||||
update_config(node_id, {
|
||||
remarks: getOption("<%=self.config%>", "<%=self.section%>", "remarks").value,
|
||||
group: getOption("<%=self.config%>", "<%=self.section%>", "group").value,
|
||||
type: getOption("<%=self.config%>", "<%=self.section%>", "type").value,
|
||||
remarks: getOption("<%=config%>", "<%=sid%>", "remarks").value,
|
||||
group: getOption("<%=config%>", "<%=sid%>", "group").value,
|
||||
type: getOption("<%=config%>", "<%=sid%>", "type").value,
|
||||
protocol: ''
|
||||
}, node_config_url);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="protocol"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="protocol"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
@@ -43,9 +49,9 @@
|
||||
}
|
||||
*/
|
||||
update_config(node_id, {
|
||||
remarks: getOption("<%=self.config%>", "<%=self.section%>", "remarks").value,
|
||||
group: getOption("<%=self.config%>", "<%=self.section%>", "group").value,
|
||||
protocol: getOption("<%=self.config%>", "<%=self.section%>", name).value,
|
||||
remarks: getOption("<%=config%>", "<%=sid%>", "remarks").value,
|
||||
group: getOption("<%=config%>", "<%=sid%>", "group").value,
|
||||
protocol: getOption("<%=config%>", "<%=sid%>", name).value,
|
||||
}, node_config_url);
|
||||
} else {
|
||||
window.location.href = node_config_url + "?select_proto=" + encodeURIComponent(el.value);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local sid = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function fetchCertSha256(el) {
|
||||
@@ -5,7 +10,7 @@
|
||||
el.setAttribute("data-loading", "1");
|
||||
el.style.pointerEvents = "none";
|
||||
el.style.color = "red";
|
||||
XHR.get('<%=self.api.url("fetch_certsha256")%>', { id: "<%=self.section%>" }, function(x, res) {
|
||||
XHR.get('<%=api.url("fetch_certsha256")%>', { id: "<%=sid%>" }, function(x, res) {
|
||||
el.setAttribute("data-loading", "0");
|
||||
el.style.pointerEvents = "";
|
||||
el.style.color = "";
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local appname = map.config
|
||||
|
||||
local default_node_type = ""
|
||||
local shunt_rule_list = {}
|
||||
local node = api.uci_get_type("global", "node")
|
||||
local node = map:get("@global[0]", "node")
|
||||
if node then
|
||||
local node_type = api.uci_get_type_id(node, "type")
|
||||
local node_protocol = api.uci_get_type_id(node, "protocol")
|
||||
local node_type = map:get(node, "type")
|
||||
local node_protocol = map:get(node, "protocol")
|
||||
if (node_type == "Xray" or node_type == "sing-box") and node_protocol == "_shunt" then
|
||||
default_node_type = node_protocol
|
||||
local node_shunt_group = api.uci_get_type_id(node, "shunt_group")
|
||||
map.uci:foreach(appname, "shunt_rules", function(e)
|
||||
local node_shunt_group = map:get(node, "shunt_group")
|
||||
map:foreach("shunt_rules", function(e)
|
||||
if e[".name"] and e.remarks and e.group == node_shunt_group then
|
||||
shunt_rule_list[#shunt_rule_list + 1] = e
|
||||
end
|
||||
@@ -431,8 +431,8 @@ table td, .table .td {
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let auto_detection_time = "<%=api.uci_get_type("global_other", "auto_detection_time", "0")%>"
|
||||
let show_node_info = "<%=api.uci_get_type("global_other", "show_node_info", "0")%>"
|
||||
let auto_detection_time = "<%=map:get("@global_other[0]", "auto_detection_time") or "0"%>"
|
||||
let show_node_info = "<%=map:get("@global_other[0]", "show_node_info") or "0"%>"
|
||||
|
||||
var ajax = {
|
||||
list: [],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local api = self.api
|
||||
-%>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local fs = api.fs
|
||||
local has_old_geoip = fs.access("/tmp/bak_v2ray/geoip.dat")
|
||||
local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local appname = api.appname
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local appname = map.config
|
||||
-%>
|
||||
<script src="<%=resource%>/view/<%=appname%>/Sortable.min.js"></script>
|
||||
<style>
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local config = map.config
|
||||
local section = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
let node_id = "<%=self.section%>";
|
||||
let node_id = "<%=section%>";
|
||||
let node_config_url = '<%=api.url("server_config")%>/' + node_id;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
|
||||
waitForElement('select[name*="<%=config%>"][name*="type"]', function(el) {
|
||||
let o_val = el.value;
|
||||
el.addEventListener("change", () => {
|
||||
el.blur();
|
||||
@@ -16,9 +19,9 @@ local api = self.api
|
||||
if (save) {
|
||||
//document.getElementsByClassName('cbi-button-save')[0].click();
|
||||
server_update_config(node_id, {
|
||||
enable: getOption("<%=self.config%>", node_id, "enable").value,
|
||||
remarks: getOption("<%=self.config%>", node_id, "remarks").value,
|
||||
type: getOption("<%=self.config%>", node_id, "type").value,
|
||||
enable: getOption("<%=config%>", node_id, "enable").value,
|
||||
remarks: getOption("<%=config%>", node_id, "remarks").value,
|
||||
type: getOption("<%=config%>", node_id, "type").value,
|
||||
protocol: ''
|
||||
}, node_config_url);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<%
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local section = self.section
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function server_update_config(cfgid, data, redirect_url) {
|
||||
XHR.get('<%=self.api.url("server_update_config")%>', {
|
||||
XHR.get('<%=api.url("server_update_config")%>', {
|
||||
id: cfgid,
|
||||
data: JSON.stringify(data)
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<%
|
||||
local api = self.api
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
local config = map.config
|
||||
local sectiontype = self.sectiontype
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
@@ -19,7 +22,7 @@ local api = self.api
|
||||
);
|
||||
}
|
||||
|
||||
var edit_btn = document.getElementById("cbi-<%=self.appname%>-<%=self.sectiontype%>").getElementsByClassName("cbi-button cbi-button-edit");
|
||||
var edit_btn = document.getElementById("cbi-<%=config%>-<%=sectiontype%>").getElementsByClassName("cbi-button cbi-button-edit");
|
||||
for (var i = 0; i < edit_btn.length; i++) {
|
||||
try {
|
||||
var onclick_str = edit_btn[i].getAttribute("onclick");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%
|
||||
local api = require "luci.passwall2.api"
|
||||
local map = self.map
|
||||
local api = map.api
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -1378,24 +1378,6 @@ msgstr "<br />none: پیشفرض، بدون استتار، دادههای
|
||||
msgid "Use it together with the DNS disguised type. You can fill in any domain."
|
||||
msgstr "از آن همراه با نوع استتار DNS استفاده کنید. میتوانید هر دامنهای را وارد کنید."
|
||||
|
||||
msgid "Auth"
|
||||
msgstr "احراز هویت"
|
||||
|
||||
msgid "Socks for authentication"
|
||||
msgstr "Socks برای احراز هویت"
|
||||
|
||||
msgid "Socks protocol authentication, support anonymous and password."
|
||||
msgstr "احراز هویت پروتکل Socks، پشتیبانی از ناشناس و رمز عبور."
|
||||
|
||||
msgid "anonymous"
|
||||
msgstr "ناشناس"
|
||||
|
||||
msgid "User Password"
|
||||
msgstr "رمز عبور کاربر"
|
||||
|
||||
msgid "Username and Password must be used together!"
|
||||
msgstr "نام کاربری و رمز عبور باید با هم استفاده شوند!"
|
||||
|
||||
msgid "Prefer firewall tools"
|
||||
msgstr "ترجیح ابزارهای فایروال"
|
||||
|
||||
@@ -1405,18 +1387,6 @@ msgstr "IPv6 TProxy"
|
||||
msgid "Experimental feature. Make sure that your node supports IPv6."
|
||||
msgstr "ویژگی آزمایشی. مطمئن شوید که گره شما از IPv6 پشتیبانی میکند."
|
||||
|
||||
msgid "Status info"
|
||||
msgstr "اطلاعات وضعیت"
|
||||
|
||||
msgid "Big icon"
|
||||
msgstr "آیکون بزرگ"
|
||||
|
||||
msgid "Show node check"
|
||||
msgstr "نمایش بررسی گره"
|
||||
|
||||
msgid "Show Show IP111"
|
||||
msgstr "نمایش نمایش IP111"
|
||||
|
||||
msgid "Destination protocol"
|
||||
msgstr "پروتکل مقصد"
|
||||
|
||||
@@ -2452,3 +2422,6 @@ msgstr "سوئیتهای رمزدار"
|
||||
|
||||
msgid "Configures the list of supported cipher suites."
|
||||
msgstr "فهرست مجموعههای رمز پشتیبانیشده را پیکربندی میکند."
|
||||
|
||||
msgid "This username already exists."
|
||||
msgstr "این نام کاربری از قبل وجود دارد."
|
||||
@@ -1379,24 +1379,6 @@ msgstr "<br />none: по умолчанию, без маскировки, дан
|
||||
msgid "Use it together with the DNS disguised type. You can fill in any domain."
|
||||
msgstr "Используется вместе с типом маскировки DNS. Можно указать любой домен."
|
||||
|
||||
msgid "Auth"
|
||||
msgstr "Аутентификация"
|
||||
|
||||
msgid "Socks for authentication"
|
||||
msgstr "Аутентификация SOCKS"
|
||||
|
||||
msgid "Socks protocol authentication, support anonymous and password."
|
||||
msgstr "Метод аутентификации SOCKS: анонимный или по логину/паролю."
|
||||
|
||||
msgid "anonymous"
|
||||
msgstr "анонимно"
|
||||
|
||||
msgid "User Password"
|
||||
msgstr "Логин и пароль"
|
||||
|
||||
msgid "Username and Password must be used together!"
|
||||
msgstr "Логин и пароль должны быть указаны вместе!"
|
||||
|
||||
msgid "Prefer firewall tools"
|
||||
msgstr "Предпочтительный инструмент фаервола"
|
||||
|
||||
@@ -1406,18 +1388,6 @@ msgstr "IPv6 TProxy"
|
||||
msgid "Experimental feature. Make sure that your node supports IPv6."
|
||||
msgstr "Экспериментальная функция. Убедитесь, что ваш сервер поддерживает IPv6."
|
||||
|
||||
msgid "Status info"
|
||||
msgstr "Информация о статусе"
|
||||
|
||||
msgid "Big icon"
|
||||
msgstr "Крупный значок"
|
||||
|
||||
msgid "Show node check"
|
||||
msgstr "Показывать проверку серверов"
|
||||
|
||||
msgid "Show Show IP111"
|
||||
msgstr "Показывать IP111"
|
||||
|
||||
msgid "Destination protocol"
|
||||
msgstr "Целевой протокол"
|
||||
|
||||
@@ -2450,3 +2420,6 @@ msgstr "Наборы шифров"
|
||||
|
||||
msgid "Configures the list of supported cipher suites."
|
||||
msgstr "Задает список поддерживаемых наборов шифров."
|
||||
|
||||
msgid "This username already exists."
|
||||
msgstr "Это имя пользователя уже существует."
|
||||
@@ -1370,24 +1370,6 @@ msgstr "<br />none:默认值,不进行伪装,发送的数据是没有特
|
||||
msgid "Use it together with the DNS disguised type. You can fill in any domain."
|
||||
msgstr "配合伪装类型 DNS 使用,可随便填一个域名。"
|
||||
|
||||
msgid "Auth"
|
||||
msgstr "身份认证"
|
||||
|
||||
msgid "Socks for authentication"
|
||||
msgstr "Socks认证方式"
|
||||
|
||||
msgid "Socks protocol authentication, support anonymous and password."
|
||||
msgstr "Socks 协议的认证方式,支持匿名方式和账号密码方式。"
|
||||
|
||||
msgid "anonymous"
|
||||
msgstr "匿名"
|
||||
|
||||
msgid "User Password"
|
||||
msgstr "账号密码"
|
||||
|
||||
msgid "Username and Password must be used together!"
|
||||
msgstr "账号和密码必须同时使用!"
|
||||
|
||||
msgid "Prefer firewall tools"
|
||||
msgstr "首选防火墙工具"
|
||||
|
||||
@@ -1397,18 +1379,6 @@ msgstr "IPv6透明代理(TProxy)"
|
||||
msgid "Experimental feature. Make sure that your node supports IPv6."
|
||||
msgstr "实验特性,请确保你的节点支持IPv6"
|
||||
|
||||
msgid "Status info"
|
||||
msgstr "状态信息"
|
||||
|
||||
msgid "Big icon"
|
||||
msgstr "大图标"
|
||||
|
||||
msgid "Show node check"
|
||||
msgstr "显示节点检测"
|
||||
|
||||
msgid "Show Show IP111"
|
||||
msgstr "显示IP111"
|
||||
|
||||
msgid "Destination protocol"
|
||||
msgstr "目标协议"
|
||||
|
||||
@@ -2438,3 +2408,6 @@ msgstr "密码套件"
|
||||
|
||||
msgid "Configures the list of supported cipher suites."
|
||||
msgstr "配置支持的密码套件列表。"
|
||||
|
||||
msgid "This username already exists."
|
||||
msgstr "该用户名已存在。"
|
||||
@@ -1370,24 +1370,6 @@ msgstr "<br />none:默認值,不进行伪装,發送的數据是沒有特
|
||||
msgid "Use it together with the DNS disguised type. You can fill in any domain."
|
||||
msgstr "配合伪装類型 DNS 使用,可随便填一個域名。"
|
||||
|
||||
msgid "Auth"
|
||||
msgstr "身份認證"
|
||||
|
||||
msgid "Socks for authentication"
|
||||
msgstr "Socks認證方式"
|
||||
|
||||
msgid "Socks protocol authentication, support anonymous and password."
|
||||
msgstr "Socks 協議的認證方式,支持匿名方式和账号密碼方式。"
|
||||
|
||||
msgid "anonymous"
|
||||
msgstr "匿名"
|
||||
|
||||
msgid "User Password"
|
||||
msgstr "账号密碼"
|
||||
|
||||
msgid "Username and Password must be used together!"
|
||||
msgstr "账号和密碼必須同時使用!"
|
||||
|
||||
msgid "Prefer firewall tools"
|
||||
msgstr "首選防火牆工具"
|
||||
|
||||
@@ -1397,18 +1379,6 @@ msgstr "IPv6透明代理(TProxy)"
|
||||
msgid "Experimental feature. Make sure that your node supports IPv6."
|
||||
msgstr "實驗特性,請確保你的節點支持IPv6"
|
||||
|
||||
msgid "Status info"
|
||||
msgstr "状態信息"
|
||||
|
||||
msgid "Big icon"
|
||||
msgstr "大图標"
|
||||
|
||||
msgid "Show node check"
|
||||
msgstr "顯示節點檢測"
|
||||
|
||||
msgid "Show Show IP111"
|
||||
msgstr "顯示IP111"
|
||||
|
||||
msgid "Destination protocol"
|
||||
msgstr "目標協議"
|
||||
|
||||
@@ -2444,3 +2414,6 @@ msgstr "密碼套件"
|
||||
|
||||
msgid "Configures the list of supported cipher suites."
|
||||
msgstr "配置支援的密碼套件列表。"
|
||||
|
||||
msgid "This username already exists."
|
||||
msgstr "該用戶名已存在。"
|
||||
-16
@@ -8,19 +8,11 @@
|
||||
EEOF
|
||||
}
|
||||
|
||||
[ "`which nft`" ] && {
|
||||
uci -q set passwall2.@global_forwarding[0].use_nft=1
|
||||
uci -q commit passwall2
|
||||
}
|
||||
|
||||
if [ -e "/etc/config/ucitrack" ]; then
|
||||
uci -q batch <<-EOF
|
||||
delete ucitrack.@passwall2[-1]
|
||||
add ucitrack passwall2
|
||||
set ucitrack.@passwall2[-1].init=passwall2
|
||||
delete ucitrack.@passwall2_server[-1]
|
||||
add ucitrack passwall2_server
|
||||
set ucitrack.@passwall2_server[-1].init=passwall2_server
|
||||
commit ucitrack
|
||||
EOF
|
||||
fi
|
||||
@@ -31,11 +23,6 @@ uci -q batch <<-EOF
|
||||
set firewall.passwall2.type='script'
|
||||
set firewall.passwall2.path='/var/etc/passwall2.include'
|
||||
|
||||
delete firewall.passwall2_server
|
||||
set firewall.passwall2_server=include
|
||||
set firewall.passwall2_server.type='script'
|
||||
set firewall.passwall2_server.path='/var/etc/passwall2_server.include'
|
||||
|
||||
set dhcp.@dnsmasq[0].localuse=1
|
||||
commit dhcp
|
||||
|
||||
@@ -45,12 +32,9 @@ EOF
|
||||
|
||||
if [ -x "/sbin/fw3" ]; then
|
||||
uci -q set firewall.passwall2.reload='1'
|
||||
uci -q set firewall.passwall2_server.reload='1'
|
||||
else
|
||||
uci -q delete firewall.passwall2.reload
|
||||
uci -q delete firewall.passwall2.fw4_compatible
|
||||
uci -q delete firewall.passwall2_server.reload
|
||||
uci -q delete firewall.passwall2_server.fw4_compatible
|
||||
fi
|
||||
uci commit firewall
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
[ ! -f "/usr/share/ucitrack/luci-app-passwall2_server.json" ] && {
|
||||
cat > /usr/share/ucitrack/luci-app-passwall2_server.json << EEOF
|
||||
{
|
||||
"config": "passwall2_server",
|
||||
"init": "passwall2_server"
|
||||
}
|
||||
EEOF
|
||||
}
|
||||
|
||||
if [ -e "/etc/config/ucitrack" ]; then
|
||||
uci -q batch <<-EOF
|
||||
delete ucitrack.@passwall2_server[-1]
|
||||
add ucitrack passwall2_server
|
||||
set ucitrack.@passwall2_server[-1].init=passwall2_server
|
||||
commit ucitrack
|
||||
EOF
|
||||
fi
|
||||
|
||||
uci -q batch <<-EOF
|
||||
delete firewall.passwall2_server
|
||||
set firewall.passwall2_server=include
|
||||
set firewall.passwall2_server.type='script'
|
||||
set firewall.passwall2_server.path='/var/etc/passwall2_server.include'
|
||||
EOF
|
||||
|
||||
if [ -x "/sbin/fw3" ]; then
|
||||
uci -q set firewall.passwall2_server.reload='1'
|
||||
else
|
||||
uci -q delete firewall.passwall2_server.reload
|
||||
uci -q delete firewall.passwall2_server.fw4_compatible
|
||||
fi
|
||||
uci commit firewall
|
||||
|
||||
rm -f /tmp/luci-indexcache /tmp/luci-indexcache.*
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
|
||||
exit 0
|
||||
@@ -351,7 +351,7 @@ run_socks() {
|
||||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file
|
||||
[ -n "$http_port" ] || http_port=0
|
||||
[ -n "$http_config_file" ] && [ -z "$(echo ${http_config_file} | grep $TMP_PATH)" ] && http_config_file=$TMP_PATH/$http_config_file
|
||||
if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
if [ -n "$log_file" ] && [ "$log_file" != "/dev/null" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
log_file=$TMP_PATH/$log_file
|
||||
else
|
||||
log_file="/dev/null"
|
||||
|
||||
@@ -21,11 +21,11 @@ local haproxy_conf = var["-conf"]
|
||||
local haproxy_dns = "127.0.0.1"
|
||||
|
||||
local cpu_thread = sys.exec('echo -n $(cat /proc/cpuinfo | grep "processor" | wc -l)') or "1"
|
||||
local health_check_type = uci:get(appname, "@global_haproxy[0]", "health_check_type") or "tcp"
|
||||
local health_check_inter = uci:get(appname, "@global_haproxy[0]", "health_check_inter") or "20"
|
||||
local balancingStrategy = uci:get(appname, "@global_haproxy[0]", "balancingStrategy") or "roundrobin"
|
||||
local console_port = uci:get(appname, "@global_haproxy[0]", "console_port")
|
||||
local bind_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0"
|
||||
local health_check_type = uci:get(api.c_config, "@global_haproxy[0]", "health_check_type") or "tcp"
|
||||
local health_check_inter = uci:get(api.c_config, "@global_haproxy[0]", "health_check_inter") or "20"
|
||||
local balancingStrategy = uci:get(api.c_config, "@global_haproxy[0]", "balancingStrategy") or "roundrobin"
|
||||
local console_port = uci:get(api.c_config, "@global_haproxy[0]", "console_port")
|
||||
local bind_local = uci:get(api.c_config, "@global_haproxy[0]", "bind_local") or "0"
|
||||
local bind_address = "0.0.0.0"
|
||||
if bind_local == "1" then bind_address = "127.0.0.1" end
|
||||
|
||||
@@ -92,15 +92,15 @@ f_out:write(haproxy_config)
|
||||
|
||||
local listens = {}
|
||||
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:foreach(api.c_config, "haproxy_config", function(t)
|
||||
if t.enabled == "1" then
|
||||
local server_remark
|
||||
local server_address
|
||||
local server_port
|
||||
local lbss = t.lbss
|
||||
local listen_port = tonumber(t.haproxy_port) or 0
|
||||
local server_node = uci:get_all(appname, lbss)
|
||||
local hop = (health_check_type == "passwall_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil
|
||||
local server_node = uci:get_all(api.c_config, lbss)
|
||||
local hop = (health_check_type == "script_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil
|
||||
hop = hop and hop:gsub(":", "-") or nil
|
||||
if server_node and server_node.address and (server_node.port or hop) then
|
||||
server_remark = server_node.address .. ":" .. (server_node.port or hop)
|
||||
@@ -108,7 +108,7 @@ uci:foreach(appname, "haproxy_config", function(t)
|
||||
server_port = server_node.port or hop
|
||||
t.origin_address = server_address
|
||||
t.origin_port = server_port
|
||||
if health_check_type == "passwall_logic" then
|
||||
if health_check_type == "script_logic" then
|
||||
if server_node.type ~= "Socks" then
|
||||
local relay_port = server_node.port
|
||||
local new_port = api.get_new_port()
|
||||
@@ -170,7 +170,7 @@ listen %s
|
||||
balance %s
|
||||
]], port, bind_address, port, balancingStrategy))
|
||||
|
||||
if health_check_type == "passwall_logic" then
|
||||
if health_check_type == "script_logic" then
|
||||
f_out:write(string.format([[
|
||||
option external-check
|
||||
external-check command "/usr/share/%s/haproxy_check.sh"
|
||||
@@ -212,8 +212,8 @@ listen %s
|
||||
end
|
||||
|
||||
-- Console config
|
||||
local console_user = uci:get(appname, "@global_haproxy[0]", "console_user")
|
||||
local console_password = uci:get(appname, "@global_haproxy[0]", "console_password")
|
||||
local console_user = uci:get(api.c_config, "@global_haproxy[0]", "console_user")
|
||||
local console_password = uci:get(api.c_config, "@global_haproxy[0]", "console_password")
|
||||
local str = [[
|
||||
listen console
|
||||
bind 0.0.0.0:%s
|
||||
@@ -228,8 +228,8 @@ f_out:write("\n" .. string.format(str, console_port, (console_user and console_u
|
||||
f_out:close()
|
||||
|
||||
-- Built-in health check URL
|
||||
if health_check_type == "passwall_logic" then
|
||||
local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204"
|
||||
if health_check_type == "script_logic" then
|
||||
local probeUrl = uci:get(api.c_config, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204"
|
||||
local f_url = io.open(haproxy_path .. "/Probe_URL", "w")
|
||||
f_url:write(probeUrl)
|
||||
f_url:close()
|
||||
|
||||
@@ -25,7 +25,7 @@ end
|
||||
local function backup_servers()
|
||||
local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server")
|
||||
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
|
||||
uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
|
||||
uci:set(api.c_config, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
|
||||
api.uci_save(uci, appname, true)
|
||||
end
|
||||
end
|
||||
@@ -38,12 +38,12 @@ local function restore_servers()
|
||||
tinsert(dns_table, v)
|
||||
end
|
||||
end
|
||||
local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers")
|
||||
local OLD_SERVER = uci:get(api.c_config, "@global[0]", "dnsmasq_servers")
|
||||
if OLD_SERVER and #OLD_SERVER > 0 then
|
||||
for k, v in ipairs(OLD_SERVER) do
|
||||
tinsert(dns_table, v)
|
||||
end
|
||||
uci:delete(appname, "@global[0]", "dnsmasq_servers")
|
||||
uci:delete(api.c_config, "@global[0]", "dnsmasq_servers")
|
||||
api.uci_save(uci, appname, true)
|
||||
end
|
||||
if dns_table and #dns_table > 0 then
|
||||
@@ -268,7 +268,7 @@ function add_rule(var)
|
||||
-- Always use domestic DNS to resolve node domain names
|
||||
if true then
|
||||
fwd_dns = LOCAL_DNS
|
||||
uci:foreach(appname, "nodes", function(t)
|
||||
uci:foreach(api.c_config, "nodes", function(t)
|
||||
local function process_address(address)
|
||||
address = (address or ""):lower()
|
||||
if address == "engage.cloudflareclient.com" then return end
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
local api = require "luci.passwall2.api"
|
||||
local name = api.appname
|
||||
local c_config = api.c_config
|
||||
local fs = api.fs
|
||||
local log = api.log
|
||||
local sys = api.sys
|
||||
local uci = api.uci
|
||||
local jsonc = api.jsonc
|
||||
|
||||
local arg1 = arg[1]
|
||||
local arg2 = arg[2]
|
||||
@@ -16,9 +16,9 @@ local reboot = 0
|
||||
local geoip_update = "0"
|
||||
local geosite_update = "0"
|
||||
|
||||
local geoip_url = uci:get(name, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat"
|
||||
local geosite_url = uci:get(name, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
local asset_location = uci:get(name, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
local geoip_url = uci:get(c_config, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat"
|
||||
local geosite_url = uci:get(c_config, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
local asset_location = uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
|
||||
asset_location = asset_location:match("/$") and asset_location or (asset_location .. "/")
|
||||
local backup_path = "/tmp/bak_v2ray/"
|
||||
|
||||
@@ -134,7 +134,7 @@ local function fetch_geofile(geo_name, geo_type, url)
|
||||
reboot = 1
|
||||
log(1, api.i18n.translatef("%s update success.", geo_type))
|
||||
else
|
||||
log(1, api.i18n.translatef("%s update failed, please try again later.", geo_type))
|
||||
log(1, api.i18n.translatef("%s update failed, please try again later or change URL.", geo_type))
|
||||
return 1
|
||||
end
|
||||
else
|
||||
@@ -148,7 +148,7 @@ local function fetch_geofile(geo_name, geo_type, url)
|
||||
log(1, api.i18n.translatef("%s update success.", geo_type))
|
||||
end
|
||||
else
|
||||
log(1, api.i18n.translatef("%s update failed, please try again later.", geo_type))
|
||||
log(1, api.i18n.translatef("%s update failed, please try again later or change URL.", geo_type))
|
||||
return 1
|
||||
end
|
||||
return 0
|
||||
@@ -177,8 +177,8 @@ if arg2 then
|
||||
end
|
||||
end)
|
||||
else
|
||||
geoip_update = uci:get(name, "@global_rules[0]", "geoip_update") or "1"
|
||||
geosite_update = uci:get(name, "@global_rules[0]", "geosite_update") or "1"
|
||||
geoip_update = uci:get(c_config, "@global_rules[0]", "geoip_update") or "1"
|
||||
geosite_update = uci:get(c_config, "@global_rules[0]", "geosite_update") or "1"
|
||||
end
|
||||
if geoip_update == "0" and geosite_update == "0" then
|
||||
os.exit(0)
|
||||
@@ -233,9 +233,9 @@ if geosite_update == "1" then
|
||||
remove_tmp_geofile("geosite")
|
||||
end
|
||||
|
||||
uci:set(name, "@global_rules[0]", "geoip_update", geoip_update)
|
||||
uci:set(name, "@global_rules[0]", "geosite_update", geosite_update)
|
||||
api.uci_save(uci, name, true)
|
||||
uci:set(c_config, "@global_rules[0]", "geoip_update", geoip_update)
|
||||
uci:set(c_config, "@global_rules[0]", "geosite_update", geosite_update)
|
||||
api.uci_save(uci, c_config, true)
|
||||
|
||||
if reboot == 1 then
|
||||
if arg3 == "cron" then
|
||||
@@ -245,8 +245,8 @@ if reboot == 1 then
|
||||
end
|
||||
|
||||
log(1, api.i18n.translate("Restart the service and apply the new rules."))
|
||||
uci:set(name, "@global[0]", "flush_set", "1")
|
||||
api.uci_save(uci, name, true, true)
|
||||
uci:set(c_config, "@global[0]", "flush_set", "1")
|
||||
api.uci_save(uci, c_config, true, true)
|
||||
end
|
||||
log(0, api.i18n.translate("The rules have been updated..."))
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
require 'luci.util'
|
||||
require 'luci.jsonc'
|
||||
require 'luci.sys'
|
||||
local appname = 'passwall2'
|
||||
local api = require ("luci.passwall2.api")
|
||||
local api = require "luci.passwall2.api"
|
||||
local appname = api.appname
|
||||
local c_config = api.c_config
|
||||
local datatypes = require "luci.cbi.datatypes"
|
||||
|
||||
-- these global functions are accessed all the time by the event handler
|
||||
@@ -31,9 +32,9 @@ local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_hysteria2 = api.finded_com("hysteria")
|
||||
local DEFAULT_ALLOWINSECURE = true
|
||||
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
|
||||
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(c_config, "@global_subscribe[0]", "filter_keyword_mode") or "0"
|
||||
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(c_config, "@global_subscribe[0]", "filter_discard_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(c_config, "@global_subscribe[0]", "filter_keep_list") or {}
|
||||
-- Nodes should be retrieved using the core type (if not set on the node subscription page, the default type will be used automatically).
|
||||
local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
|
||||
local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
|
||||
@@ -130,13 +131,13 @@ do
|
||||
local szType = "@global[0]"
|
||||
local option = "node"
|
||||
|
||||
local node_id = uci:get(appname, szType, option)
|
||||
local node_id = uci:get(c_config, szType, option)
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
remarks = i18n.translatef("Node"),
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, szType, option, server)
|
||||
uci:set(c_config, szType, option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -145,7 +146,7 @@ do
|
||||
if true then
|
||||
local i = 0
|
||||
local option = "node"
|
||||
uci:foreach(appname, "socks", function(t)
|
||||
uci:foreach(c_config, "socks", function(t)
|
||||
i = i + 1
|
||||
local id = t[".name"]
|
||||
local node_id = t[option]
|
||||
@@ -153,14 +154,14 @@ do
|
||||
log = true,
|
||||
id = id,
|
||||
remarks = i18n.translatef("Socks node list [%s]", i),
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
if not server or server == "" then
|
||||
if #nodes_table > 0 then
|
||||
server = nodes_table[1][".name"]
|
||||
end
|
||||
end
|
||||
uci:set(appname, t[".name"], option, server)
|
||||
uci:set(c_config, t[".name"], option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -170,7 +171,7 @@ do
|
||||
local newNodes = {}
|
||||
for k, asb_node_id in ipairs(t.autoswitch_backup_node) do
|
||||
if asb_node_id then
|
||||
local currentNode = uci:get_all(appname, asb_node_id) or {}
|
||||
local currentNode = uci:get_all(c_config, asb_node_id) or {}
|
||||
if currentNode[".type"] == "nodes" then
|
||||
currentNodes[#currentNodes + 1] = {
|
||||
log = true,
|
||||
@@ -192,7 +193,7 @@ do
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, id, "autoswitch_backup_node", newNodes or {})
|
||||
uci:set_list(c_config, id, "autoswitch_backup_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -208,25 +209,25 @@ do
|
||||
local ip, port = str:match("^([%d%.]+):(%d+)$")
|
||||
return ip and datatypes.ipaddr(ip) and tonumber(port) and tonumber(port) <= 65535
|
||||
end
|
||||
uci:foreach(appname, "haproxy_config", function(t)
|
||||
uci:foreach(c_config, "haproxy_config", function(t)
|
||||
i = i + 1
|
||||
local node_id = t[option]
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
id = t[".name"],
|
||||
remarks = i18n.translatef("HAProxy node list [%s]", i),
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
-- Modify the LBS value only if it is not in IP:Port format.
|
||||
if not is_ip_port(t[option]) then
|
||||
uci:set(appname, t[".name"], option, server)
|
||||
uci:set(c_config, t[".name"], option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
end,
|
||||
delete = function(o)
|
||||
-- Deletion is only performed if the current LBS value is not in IP:port format.
|
||||
if not is_ip_port(t[option]) then
|
||||
uci:delete(appname, t[".name"])
|
||||
uci:delete(c_config, t[".name"])
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -235,7 +236,7 @@ do
|
||||
|
||||
if true then
|
||||
local i = 0
|
||||
uci:foreach(appname, "acl_rule", function(t)
|
||||
uci:foreach(c_config, "acl_rule", function(t)
|
||||
i = i + 1
|
||||
local option = "node"
|
||||
local node_id = t[option]
|
||||
@@ -243,20 +244,20 @@ do
|
||||
log = true,
|
||||
id = t[".name"],
|
||||
remarks = i18n.translatef("ACL list [%s]", i),
|
||||
currentNode = node_id and uci:get_all(appname, node_id) or nil,
|
||||
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, t[".name"], option, server)
|
||||
uci:set(c_config, t[".name"], option, server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
local node_id = node[".name"]
|
||||
if node.protocol and node.protocol == '_shunt' then
|
||||
local rules = {}
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
uci:foreach(c_config, "shunt_rules", function(e)
|
||||
if e[".name"] and e.remarks then
|
||||
table.insert(rules, e)
|
||||
table.insert(rules, {
|
||||
@@ -277,7 +278,7 @@ do
|
||||
for k, e in pairs(rules) do
|
||||
local _node_id = node[e[".name"]] or nil
|
||||
if _node_id then
|
||||
local section = uci:get_all(appname, _node_id) or {}
|
||||
local section = uci:get_all(c_config, _node_id) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
@@ -285,7 +286,7 @@ do
|
||||
remarks = i18n.translatef("Shunt [%s] node", e.remarks),
|
||||
set = function(o, server)
|
||||
if not server then server = "" end
|
||||
uci:set(appname, node_id, e[".name"], server)
|
||||
uci:set(c_config, node_id, e[".name"], server)
|
||||
o.newNodeId = server
|
||||
end
|
||||
}
|
||||
@@ -302,7 +303,7 @@ do
|
||||
log = true,
|
||||
node = b_node_id,
|
||||
currentNode = (function()
|
||||
local section = uci:get_all(appname, b_node_id) or {}
|
||||
local section = uci:get_all(c_config, b_node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
return { Socks = b_node_id }
|
||||
end
|
||||
@@ -324,15 +325,15 @@ do
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, node_id, "balancing_node", newNodes or {})
|
||||
uci:set_list(c_config, node_id, "balancing_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
-- Backup Node
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
local currentNode = uci:get_all(c_config, node_id) or nil
|
||||
if currentNode and currentNode.fallback_node then
|
||||
local section = uci:get_all(appname, currentNode.fallback_node) or {}
|
||||
local section = uci:get_all(c_config, currentNode.fallback_node) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
@@ -340,11 +341,11 @@ do
|
||||
remarks = i18n.translatef("Xray Load Balancing node [%s] backup node", node_id),
|
||||
currentNode = section,
|
||||
set = function(o, server)
|
||||
uci:set(appname, node_id, "fallback_node", server)
|
||||
uci:set(c_config, node_id, "fallback_node", server)
|
||||
o.newNodeId = server
|
||||
end,
|
||||
delete = function(o)
|
||||
uci:delete(appname, node_id, "fallback_node")
|
||||
uci:delete(c_config, node_id, "fallback_node")
|
||||
end
|
||||
}
|
||||
end
|
||||
@@ -359,7 +360,7 @@ do
|
||||
log = true,
|
||||
node = u_node_id,
|
||||
currentNode = (function()
|
||||
local section = uci:get_all(appname, u_node_id) or {}
|
||||
local section = uci:get_all(c_config, u_node_id) or {}
|
||||
if section[".type"] == "socks" then
|
||||
return { Socks = u_node_id }
|
||||
end
|
||||
@@ -381,47 +382,47 @@ do
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, node_id, "urltest_node", newNodes or {})
|
||||
uci:set_list(c_config, node_id, "urltest_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
else
|
||||
-- Preproxy Node
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
local currentNode = uci:get_all(c_config, node_id) or nil
|
||||
if currentNode and currentNode.preproxy_node then
|
||||
local section = uci:get_all(appname, currentNode.preproxy_node) or {}
|
||||
local section = uci:get_all(c_config, currentNode.preproxy_node) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
id = node_id,
|
||||
remarks = i18n.translatef("Node [%s] preproxy node", node_id),
|
||||
currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil,
|
||||
currentNode = uci:get_all(c_config, currentNode.preproxy_node) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, node_id, "preproxy_node", server)
|
||||
uci:set(c_config, node_id, "preproxy_node", server)
|
||||
o.newNodeId = server
|
||||
end,
|
||||
delete = function(o)
|
||||
uci:delete(appname, node_id, "preproxy_node")
|
||||
uci:delete(c_config, node_id, "preproxy_node")
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
-- Landing node
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
local currentNode = uci:get_all(c_config, node_id) or nil
|
||||
if currentNode and currentNode.to_node then
|
||||
local section = uci:get_all(appname, currentNode.to_node) or {}
|
||||
local section = uci:get_all(c_config, currentNode.to_node) or {}
|
||||
if section[".type"] == "nodes" then
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
id = node_id,
|
||||
remarks = i18n.translatef("Node [%s] landing node", node_id),
|
||||
currentNode = uci:get_all(appname, currentNode.to_node) or nil,
|
||||
currentNode = uci:get_all(c_config, currentNode.to_node) or nil,
|
||||
set = function(o, server)
|
||||
uci:set(appname, node_id, "to_node", server)
|
||||
uci:set(c_config, node_id, "to_node", server)
|
||||
o.newNodeId = server
|
||||
end,
|
||||
delete = function(o)
|
||||
uci:delete(appname, node_id, "to_node")
|
||||
uci:delete(c_config, node_id, "to_node")
|
||||
end
|
||||
}
|
||||
end
|
||||
@@ -2083,19 +2084,19 @@ local function truncate_nodes(group)
|
||||
end
|
||||
end
|
||||
end
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
if node.add_mode == "2" then
|
||||
if (not group) or (group:lower() == (node.group or ""):lower()) then
|
||||
uci:delete(appname, node['.name'])
|
||||
uci:delete(c_config, node['.name'])
|
||||
end
|
||||
end
|
||||
end)
|
||||
uci:foreach(appname, "subscribe_list", function(o)
|
||||
uci:foreach(c_config, "subscribe_list", function(o)
|
||||
if (not group) or (group:lower() == (o.remark or ""):lower()) then
|
||||
uci:delete(appname, o['.name'], "md5")
|
||||
uci:delete(c_config, o['.name'], "md5")
|
||||
end
|
||||
end)
|
||||
api.uci_save(uci, appname, true)
|
||||
api.uci_save(uci, c_config, true)
|
||||
end
|
||||
|
||||
local function select_node(nodes, config, parentConfig)
|
||||
@@ -2238,10 +2239,10 @@ local function update_node(manual)
|
||||
end
|
||||
|
||||
if manual == 0 and next(group) then
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
-- Do not delete nodes if no new nodes are found or nodes were manually imported...
|
||||
if node.add_mode == "2" and (node.group and group[node.group:lower()] == true) then
|
||||
uci:delete(appname, node['.name'])
|
||||
uci:delete(c_config, node['.name'])
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -2254,9 +2255,9 @@ local function update_node(manual)
|
||||
-- Subscription Group Chain Agent
|
||||
local function valid_chain_node(node)
|
||||
if not node then return "" end
|
||||
local cp = uci:get(appname, node, "chain_proxy") or ""
|
||||
local am = uci:get(appname, node, "add_mode") or "0"
|
||||
chain_node_type = (cp == "" and am ~= "2") and (uci:get(appname, node, "type") or "") or ""
|
||||
local cp = uci:get(c_config, node, "chain_proxy") or ""
|
||||
local am = uci:get(c_config, node, "add_mode") or "0"
|
||||
chain_node_type = (cp == "" and am ~= "2") and (uci:get(c_config, node, "type") or "") or ""
|
||||
if chain_node_type ~= "Xray" and chain_node_type ~= "sing-box" then
|
||||
chain_node_type = ""
|
||||
return ""
|
||||
@@ -2274,42 +2275,42 @@ local function update_node(manual)
|
||||
chain_node_type = (outbound_iface_group ~= "") and "iface" or chain_node_type
|
||||
end
|
||||
for _, vv in ipairs(list) do
|
||||
local cfgid = uci:section(appname, "nodes", api.gen_random_char())
|
||||
local cfgid = uci:section(c_config, "nodes", api.gen_random_char())
|
||||
for kkk, vvv in pairs(vv) do
|
||||
if type(vvv) == "table" and next(vvv) ~= nil then
|
||||
uci:set_list(appname, cfgid, kkk, vvv)
|
||||
uci:set_list(c_config, cfgid, kkk, vvv)
|
||||
else
|
||||
if kkk ~= "group" or vvv ~= "default" then
|
||||
uci:set(appname, cfgid, kkk, vvv)
|
||||
uci:set(c_config, cfgid, kkk, vvv)
|
||||
end
|
||||
-- Sing-Box Node Domain resolver
|
||||
if kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then
|
||||
if domain_resolver then
|
||||
uci:set(appname, cfgid, "domain_resolver", domain_resolver)
|
||||
uci:set(c_config, cfgid, "domain_resolver", domain_resolver)
|
||||
if domain_resolver_dns then
|
||||
uci:set(appname, cfgid, "domain_resolver_dns", domain_resolver_dns)
|
||||
uci:set(c_config, cfgid, "domain_resolver_dns", domain_resolver_dns)
|
||||
elseif domain_resolver_dns_https then
|
||||
uci:set(appname, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https)
|
||||
uci:set(c_config, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https)
|
||||
end
|
||||
end
|
||||
if domain_strategy then
|
||||
if vvv == "sing-box" then
|
||||
domain_strategy = (domain_strategy == "UseIPv4" and "ipv4_only") or (domain_strategy == "UseIPv6" and "ipv6_only") or domain_strategy
|
||||
end
|
||||
uci:set(appname, cfgid, "domain_strategy", domain_strategy)
|
||||
uci:set(c_config, cfgid, "domain_strategy", domain_strategy)
|
||||
end
|
||||
end
|
||||
-- Subscription Group Chain Agent
|
||||
if chain_node_type ~= "" and kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then
|
||||
if preproxy_node_group ~="" then
|
||||
uci:set(appname, cfgid, "chain_proxy", "1")
|
||||
uci:set(appname, cfgid, "preproxy_node", preproxy_node_group)
|
||||
uci:set(c_config, cfgid, "chain_proxy", "1")
|
||||
uci:set(c_config, cfgid, "preproxy_node", preproxy_node_group)
|
||||
elseif to_node_group ~= "" then
|
||||
uci:set(appname, cfgid, "chain_proxy", "2")
|
||||
uci:set(appname, cfgid, "to_node", to_node_group)
|
||||
uci:set(c_config, cfgid, "chain_proxy", "2")
|
||||
uci:set(c_config, cfgid, "to_node", to_node_group)
|
||||
elseif outbound_iface_group ~= "" then
|
||||
uci:set(appname, cfgid, "chain_proxy", "3")
|
||||
uci:set(appname, cfgid, "outbound_iface", outbound_iface_group)
|
||||
uci:set(c_config, cfgid, "chain_proxy", "3")
|
||||
uci:set(c_config, cfgid, "outbound_iface", outbound_iface_group)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2320,16 +2321,16 @@ local function update_node(manual)
|
||||
for cfgid, info in pairs(subscribe_info) do
|
||||
for key, value in pairs(info) do
|
||||
if value ~= "" then
|
||||
uci:set(appname, cfgid, key, value)
|
||||
uci:set(c_config, cfgid, key, value)
|
||||
else
|
||||
uci:delete(appname, cfgid, key)
|
||||
uci:delete(c_config, cfgid, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if next(CONFIG) then
|
||||
local nodes = {}
|
||||
uci:foreach(appname, "nodes", function(node)
|
||||
uci:foreach(c_config, "nodes", function(node)
|
||||
nodes[#nodes + 1] = node
|
||||
end)
|
||||
|
||||
@@ -2351,7 +2352,7 @@ local function update_node(manual)
|
||||
end
|
||||
end
|
||||
|
||||
api.uci_save(uci, appname, true)
|
||||
api.uci_save(uci, c_config, true)
|
||||
|
||||
if arg[3] == "cron" then
|
||||
if not fs.access("/var/lock/" .. appname .. ".lock") then
|
||||
@@ -2484,10 +2485,10 @@ local execute = function()
|
||||
local fail_list = {}
|
||||
if arg[2] ~= "all" then
|
||||
string.gsub(arg[2], '[^' .. "," .. ']+', function(w)
|
||||
subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {}
|
||||
subscribe_list[#subscribe_list + 1] = uci:get_all(c_config, w) or {}
|
||||
end)
|
||||
else
|
||||
uci:foreach(appname, "subscribe_list", function(o)
|
||||
uci:foreach(c_config, "subscribe_list", function(o)
|
||||
subscribe_list[#subscribe_list + 1] = o
|
||||
end)
|
||||
end
|
||||
@@ -2530,7 +2531,7 @@ local execute = function()
|
||||
log(1, i18n.translatef("Subscription: [%s] No changes, no update required.", remark))
|
||||
else
|
||||
parse_link(raw_data, "2", remark, value)
|
||||
uci:set(appname, cfgid, "md5", new_md5)
|
||||
uci:set(c_config, cfgid, "md5", new_md5)
|
||||
end
|
||||
else
|
||||
fail_list[#fail_list + 1] = value
|
||||
@@ -2564,7 +2565,7 @@ local function check_instance(action)
|
||||
os.exit(0)
|
||||
else
|
||||
luci.sys.call("touch " .. sub_lock)
|
||||
uci:revert(appname)
|
||||
uci:revert(c_config)
|
||||
end
|
||||
elseif action == "end" then
|
||||
luci.sys.call("rm -f " .. sub_lock)
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-xwan
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -17,7 +17,7 @@ LUCI_NAME:=luci-theme-footstrap
|
||||
FOOTSTRAP_VERSION?=
|
||||
ifneq ($(FOOTSTRAP_VERSION),)
|
||||
PKG_VERSION:=$(FOOTSTRAP_VERSION)
|
||||
PKG_RELEASE:=16
|
||||
PKG_RELEASE:=17
|
||||
endif
|
||||
|
||||
LUCI_TITLE:=Footstrap Theme
|
||||
|
||||
@@ -88,10 +88,10 @@ function clearViewIntervals() {
|
||||
/* ONE line per document whatever went wrong: this runs on every navigation, and a router that
|
||||
* cannot read L.Poll cannot read it on the next click either — a message per click would bury the
|
||||
* console the user is reading it in. */
|
||||
let _pollTimerWarned = false;
|
||||
let _pollWarned = false;
|
||||
function warnPollUnreadable(msg) {
|
||||
if (_pollTimerWarned) return;
|
||||
_pollTimerWarned = true;
|
||||
if (_pollWarned) return;
|
||||
_pollWarned = true;
|
||||
console.error(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -301,11 +301,13 @@ function adoptMarkup(t, head) {
|
||||
*
|
||||
* The heading is COPIED, not invented: it is the text of the header cell in the same position, so
|
||||
* the card says exactly what the column header says. Never overwrites an existing data-title — if
|
||||
* the app set one, that is the app's answer and it knows more than a positional guess. Cheap enough
|
||||
* to re-run on every fit pass (it is skipped entirely once the cells carry the attribute), which
|
||||
* matters because these tables are POLLED: the rows are replaced wholesale every few seconds, and
|
||||
* the fresh ones arrive without it. */
|
||||
* the app set one, that is the app's answer and it knows more than a positional guess. Re-run on
|
||||
* every fit pass, because these tables are POLLED: the rows are replaced wholesale every few
|
||||
* seconds and the fresh ones arrive without the attribute. What keeps that affordable is the
|
||||
* PER-ROW skip below: a captioned row is recognised from one cell instead of all of them, so a
|
||||
* table LuCI captioned itself costs one attribute test per row and nothing else. */
|
||||
function labelCells(t, head) {
|
||||
const rows = t.querySelectorAll('.tr, tbody tr');
|
||||
/* A `<thead>` that was WRITTEN as markup nests a real `<tr>` — the parser inserts one even where
|
||||
* the author left it out — while one built by E() holds the `<th>`s directly (see above). Reading
|
||||
* `head.children` blind therefore captioned every cell of a parsed table with the header row's
|
||||
@@ -315,9 +317,30 @@ function labelCells(t, head) {
|
||||
const titleRow = (head.firstElementChild && head.firstElementChild.tagName === 'TR') ? head.firstElementChild : head;
|
||||
const titles = [ ...titleRow.children ].map((c) => (c.textContent || '').trim());
|
||||
if (!titles.some(Boolean)) return;
|
||||
for (const row of t.querySelectorAll('.tr, tbody tr')) {
|
||||
for (const row of rows) {
|
||||
if (row === head) continue;
|
||||
const cells = row.children;
|
||||
/* ---- SKIP A ROW THAT IS ALREADY CAPTIONED, ASKED OF THE ROW AND OF NOTHING ELSE ----
|
||||
*
|
||||
* A claimed table is revisited on every fit pass — a MUTATION pass, not a once-a-second one —
|
||||
* so the common case has to be answered cheaply: everything LuCI renders is captioned by
|
||||
* `ui.Table` as it builds it, and the walk could never find work there. Testing the row's FIRST
|
||||
* cell answers that in one attribute read instead of one per cell.
|
||||
*
|
||||
* The row, rather than the table, is what carries the answer, and that is the whole point: a
|
||||
* poll appends or replaces rows one at a time, and a table can hold captioned and bare rows at
|
||||
* once. A table-level probe has to guess WHICH row speaks for the rest, and every choice is
|
||||
* wrong for some shape — asking the last row stalls forever on a `<tfoot>` of per-column
|
||||
* totals, which is captioned once and then never bare again while fresh rows keep arriving in
|
||||
* the `<tbody>` above it (`t.rows` spans thead, tbody and tfoot, and the query above is in
|
||||
* document order). Asked per row, there is nothing to guess: a fresh row has no caption and is
|
||||
* walked, a captioned one is skipped, and cells replaced INSIDE a surviving row arrive bare and
|
||||
* are walked too.
|
||||
*
|
||||
* A first cell that can never take a caption — one that spans columns, or whose header text is
|
||||
* empty — leaves its row walked on every pass. That is the safe direction and it is bounded by
|
||||
* the row, not the table: the walk is idempotent and writes nothing it has not been asked to. */
|
||||
if (cells.length && cells[0].hasAttribute('data-title')) continue;
|
||||
/* COLUMN cursor, not the cell index: a cell that spans N columns occupies N of the header's
|
||||
* slots while advancing the cell index by one, so keying titles off `i` captioned every cell
|
||||
* AFTER a spanning one with the heading of the column to its left — "Hostname" over an IP
|
||||
|
||||
@@ -172,13 +172,30 @@
|
||||
.fs-themerow:hover {
|
||||
background: var(--fs-panel2); color: var(--fs-text); opacity: 1;
|
||||
}
|
||||
.fs-sidebar ul.nav > li.active > a,
|
||||
.fs-sidebar ul.nav > li > a.active,
|
||||
.fs-sidebar ul.nav ul a.active,
|
||||
.fs-themerow[aria-expanded="true"],
|
||||
.fs-modemenu li.active a {
|
||||
background: var(--fs-accent-soft); color: var(--fs-accent);
|
||||
}
|
||||
/* ---- THE FILL MARKS THE PAGE, AND A CATEGORY IS NOT A PAGE ----
|
||||
*
|
||||
* `li.active` is set on the SECTION that contains the current page as well as on the page's own
|
||||
* row, so `li.active > a` used to hand the same accent plate to both — on System -> System that
|
||||
* is two identical plates, one above the other, both reading "System" (issue #37). Measured
|
||||
* before this rule: the open category and the current leaf were the same fill, the same ink and
|
||||
* the same 13px/600, differing in 2px of padding.
|
||||
*
|
||||
* The markup already says which is which and this only makes the paint agree with it:
|
||||
* menu-footstrap.js puts `aria-current="page"` on the LEAF alone, because a section header is a
|
||||
* disclosure control rather than a link to where you are. So the plate stays with the page and
|
||||
* the ancestor keeps the accent INK — still visibly the branch you are in, without competing
|
||||
* with the page for the same signal — while an ancestor that is also the page itself is matched
|
||||
* by `a.active` above and keeps the plate.
|
||||
*
|
||||
* Unscoped, like the rule above it: the accordion, the bar's dropdown and the rail's flyout all
|
||||
* render one markup, and a per-layout copy is what the "one look, every layout" note is about. */
|
||||
.fs-sidebar ul.nav > li.active > a:not(.active) { color: var(--fs-accent); }
|
||||
|
||||
/* Keyboard focus for the chrome controls. Covers the buttons/links the theme itself renders,
|
||||
* which had only the UA default (menu links: base's thin dotted outline).
|
||||
|
||||
@@ -378,7 +378,13 @@
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav > li > a {
|
||||
display: flex; align-items: center; gap: var(--fs-space-3);
|
||||
padding: var(--fs-space-2-5) var(--fs-space-3);
|
||||
font-size: var(--fs-type); white-space: normal;
|
||||
/* BOLD is the root level's own signal, and it is the one the type scale can promise:
|
||||
* `--fs-weight-bold` has a face everywhere, while `--fs-weight-normal` is documented in
|
||||
* 02-tokens.css as having none of its own — so lightening the CHILDREN instead would
|
||||
* look like hierarchy on a system stack and like nothing at all on a router whose admin
|
||||
* installed a 600/700 subset. Only the accordion is deep enough to need the distinction;
|
||||
* the bar keeps one level of items and is left alone. */
|
||||
font-size: var(--fs-type); font-weight: var(--fs-weight-bold); white-space: normal;
|
||||
line-height: 1.1;
|
||||
}
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav > li > a .fs-ico { display: block; }
|
||||
@@ -407,7 +413,22 @@
|
||||
* (below) is a popup again but flies its panel out sideways, and brings its own
|
||||
* horizontal bridge (li.has-sub::after). */
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav > li.has-sub > ul::before { content: none; }
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav > li.open > ul { display: flex; margin: var(--fs-space-0-5) 0 var(--fs-space-1-5) var(--fs-space-7); }
|
||||
/* ---- THE OPEN SECTION IS A GROUP, AND IT HAS TO LOOK LIKE ONE ----
|
||||
*
|
||||
* An indent alone did not say where a long section ended: after ten children, the next root
|
||||
* category read as an eleventh child (issue #37). A hairline down the group's reading edge
|
||||
* draws that boundary, and the wider bottom margin separates the last child from the next
|
||||
* category — the two cues cost nothing but a border and 6px.
|
||||
*
|
||||
* No `:not([data-rail="true"])` guard: in the rail this same `ul` becomes a flyout card,
|
||||
* whose rule (below) restates `border` and `margin` as shorthands at higher specificity, so
|
||||
* neither declaration here survives into it. Checked in place rather than assumed. */
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav > li.open > ul {
|
||||
display: flex;
|
||||
margin: var(--fs-space-1) 0 var(--fs-space-3) var(--fs-space-7);
|
||||
padding-inline-start: var(--fs-space-1);
|
||||
border-inline-start: 1px solid var(--fs-border);
|
||||
}
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav > li.has-sub.open > ul { display: flex; }
|
||||
:root[data-layout="sidebar"]:not([data-narrow]) .fs-sidebar ul.nav ul a { padding: var(--fs-space-2) var(--fs-space-3); }
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mihomo-alpha
|
||||
PKG_VERSION:=2026.07.08
|
||||
PKG_RELEASE:=18
|
||||
PKG_VERSION:=2026.08.13
|
||||
PKG_RELEASE:=19
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
|
||||
PKG_SOURCE_VERSION:=cbd11db1e13a75d8e680e0fe7742c95be4cba2be
|
||||
PKG_SOURCE_VERSION:=3cac869656f8ce2793afced148ebd5d4280b3e08
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL3.0+
|
||||
@@ -18,7 +18,7 @@ PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_BUILD_FLAGS:=no-mips16
|
||||
|
||||
PKG_BUILD_VERSION:=alpha-cbd11db
|
||||
PKG_BUILD_VERSION:=alpha-3cac869
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_BUILD_TIME:=$(shell date -u -Iseconds)
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=fastfetch
|
||||
PKG_VERSION:=2.67.0
|
||||
PKG_RELEASE:=13
|
||||
PKG_VERSION:=2.67.1
|
||||
PKG_RELEASE:=14
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/fastfetch-cli/fastfetch/tar.gz/$(PKG_VERSION)?
|
||||
|
||||
Reference in new issue
Block a user