Update version to 1.96 and enhance rpcd handling
Zapret Manager 1.96 — исправления - Исправлена ошибка «Object not found» после обновления (LuCI: «RPC call to zapret-manager/status failed with error -32000», Web UI: «Роутер не отвечает: Object not found»). - Установщик теперь проверяет, что rpcd подхватил панель и новый список методов, и при необходимости сам перезапускает rpcd. - Сторож (раз в 2 минуты) следит не только за входом в LuCI, но и за самой панелью: если rpcd её потерял, он перезапускает rpcd. - LuCI и Web UI при «Object not found» больше не показывают ошибку сразу, а повторяют запрос несколько секунд, пока rpcd запускается. - После обновления больше не нужно сбрасывать кэш браузера: панель сама замечает новую сборку, обновляет свои файлы в кэше и один раз перезагружает страницу. - Файлы панели при обновлении заменяются целиком за один шаг — открытая страница больше не может запустить наполовину записанный скрипт. - На странице входа Web UI вместо «Object not found» выводится понятное сообщение, что rpcd ещё запускается.
This commit is contained in:
1 parent
1f0e5b377c
commit
a6b2437326
1 file changed
+142
-9
+142
-9
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Version: 1.95
|
# Version: 1.96
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
GREEN="\033[1;32m"; CYAN="\033[1;36m"; YELLOW="\033[1;33m"; MAGENTA="\033[1;35m"; BLUE="\033[0;34m"; NC="\033[0m"; DGRAY="\033[38;5;244m"
|
GREEN="\033[1;32m"; CYAN="\033[1;36m"; YELLOW="\033[1;33m"; MAGENTA="\033[1;35m"; BLUE="\033[0;34m"; NC="\033[0m"; DGRAY="\033[38;5;244m"
|
||||||
@@ -45,12 +45,12 @@ rm -f \
|
|||||||
|
|
||||||
mkdir -p /opt/zapret-manager-luci
|
mkdir -p /opt/zapret-manager-luci
|
||||||
chmod 0755 /opt/zapret-manager-luci
|
chmod 0755 /opt/zapret-manager-luci
|
||||||
cat > '/opt/zapret-manager-luci/backend.sh' << 'ZM_INSTALLER_EOF'
|
cat > '/opt/zapret-manager-luci/backend.sh.zm-new' << 'ZM_INSTALLER_EOF'
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
umask 022
|
umask 022
|
||||||
|
|
||||||
CONF="/etc/config/zapret"
|
CONF="/etc/config/zapret"
|
||||||
ZM_VERSION="1.95"
|
ZM_VERSION="1.96"
|
||||||
ZM_SCRIPT_URL="https://raw.githubusercontent.com/StressOzz/Zapret-Manager/refs/heads/main/ZapretManager_LuCI.sh"
|
ZM_SCRIPT_URL="https://raw.githubusercontent.com/StressOzz/Zapret-Manager/refs/heads/main/ZapretManager_LuCI.sh"
|
||||||
GH_RAW="https://raw.githubusercontent.com"
|
GH_RAW="https://raw.githubusercontent.com"
|
||||||
GH_MAIN="https://github.com"
|
GH_MAIN="https://github.com"
|
||||||
@@ -661,10 +661,49 @@ rpcd_watch() {
|
|||||||
if [ "$rc" = 7 ]; then
|
if [ "$rc" = 7 ]; then
|
||||||
logger -t zapret-manager "rpcd завис — перезапускаем, чтобы вернуть вход в LuCI"
|
logger -t zapret-manager "rpcd завис — перезапускаем, чтобы вернуть вход в LuCI"
|
||||||
/etc/init.d/rpcd restart >/dev/null 2>&1
|
/etc/init.d/rpcd restart >/dev/null 2>&1
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
|
_rpcd_plugin_watch
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rpcd_plugin_watch() {
|
||||||
|
local pl=/usr/libexec/rpcd/zapret-manager want have sig st stamp=/tmp/zm-rpcd-plugin.stamp
|
||||||
|
[ -x "$pl" ] || return 0
|
||||||
|
_rpcd_plugin_state "$pl" && { rm -f "$stamp"; return 0; }
|
||||||
|
sleep 5
|
||||||
|
_rpcd_plugin_state "$pl"
|
||||||
|
st=$?
|
||||||
|
[ "$st" = 0 ] && { rm -f "$stamp"; return 0; }
|
||||||
|
sig="$(date -r "$pl" +%s 2>/dev/null)"
|
||||||
|
if [ "$st" = 1 ]; then
|
||||||
|
case "$(cat "$stamp" 2>/dev/null)" in
|
||||||
|
"$sig.x3") return 0 ;;
|
||||||
|
"$sig.x2") echo "$sig.x3" > "$stamp" ;;
|
||||||
|
"$sig.x1") echo "$sig.x2" > "$stamp" ;;
|
||||||
|
*) echo "$sig.x1" > "$stamp" ;;
|
||||||
|
esac
|
||||||
|
logger -t zapret-manager "rpcd не видит панель (Object not found) — перезапускаем rpcd"
|
||||||
|
else
|
||||||
|
[ "$(cat "$stamp" 2>/dev/null)" = "$sig.m" ] && return 0
|
||||||
|
echo "$sig.m" > "$stamp"
|
||||||
|
logger -t zapret-manager "rpcd держит старый список методов панели — перезапускаем rpcd"
|
||||||
|
fi
|
||||||
|
/etc/init.d/rpcd restart >/dev/null 2>&1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_rpcd_plugin_state() {
|
||||||
|
local want have
|
||||||
|
ubus -t 5 list zapret-manager >/dev/null 2>&1 || return 1
|
||||||
|
want="$(grep -c 'json_add_object' "$1" 2>/dev/null)"
|
||||||
|
have="$(ubus -v list zapret-manager 2>/dev/null | grep -c '^[[:space:]]*"')"
|
||||||
|
[ "${want:-0}" -gt 0 ] 2>/dev/null || return 0
|
||||||
|
[ "${have:-0}" -gt 0 ] 2>/dev/null || return 0
|
||||||
|
[ "$have" = "$want" ] && return 0
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
ui_theme_get() {
|
ui_theme_get() {
|
||||||
local t
|
local t
|
||||||
t="$(cat "$ZM_STATE_DIR/ui.theme" 2>/dev/null)"
|
t="$(cat "$ZM_STATE_DIR/ui.theme" 2>/dev/null)"
|
||||||
@@ -11929,7 +11968,8 @@ case "$cmd" in
|
|||||||
*) echo '{"error":"неизвестная команда"}'; exit 1 ;;
|
*) echo '{"error":"неизвестная команда"}'; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
ZM_INSTALLER_EOF
|
ZM_INSTALLER_EOF
|
||||||
chmod 0755 '/opt/zapret-manager-luci/backend.sh'
|
chmod 0755 '/opt/zapret-manager-luci/backend.sh.zm-new'
|
||||||
|
mv -f '/opt/zapret-manager-luci/backend.sh.zm-new' '/opt/zapret-manager-luci/backend.sh'
|
||||||
cat > '/opt/zapret-manager-luci/forkop.uc' << 'ZM_INSTALLER_EOF'
|
cat > '/opt/zapret-manager-luci/forkop.uc' << 'ZM_INSTALLER_EOF'
|
||||||
let fs = require("fs");
|
let fs = require("fs");
|
||||||
let uci = require("uci");
|
let uci = require("uci");
|
||||||
@@ -12720,7 +12760,7 @@ chmod 0644 '/opt/zapret-manager-luci/forkop.uc'
|
|||||||
|
|
||||||
mkdir -p /usr/libexec/rpcd
|
mkdir -p /usr/libexec/rpcd
|
||||||
chmod 0755 /usr/libexec/rpcd
|
chmod 0755 /usr/libexec/rpcd
|
||||||
cat > '/usr/libexec/rpcd/zapret-manager' << 'ZM_INSTALLER_EOF'
|
cat > '/opt/zapret-manager-luci/rpcd-plugin.zm-new' << 'ZM_INSTALLER_EOF'
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. /usr/share/libubox/jshn.sh
|
. /usr/share/libubox/jshn.sh
|
||||||
@@ -12943,7 +12983,8 @@ case "$1" in
|
|||||||
*) echo '{"error":"usage: zapret-manager {list|call <method>}"}'; exit 1 ;;
|
*) echo '{"error":"usage: zapret-manager {list|call <method>}"}'; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
ZM_INSTALLER_EOF
|
ZM_INSTALLER_EOF
|
||||||
chmod 0755 '/usr/libexec/rpcd/zapret-manager'
|
chmod 0755 '/opt/zapret-manager-luci/rpcd-plugin.zm-new'
|
||||||
|
mv -f '/opt/zapret-manager-luci/rpcd-plugin.zm-new' '/usr/libexec/rpcd/zapret-manager'
|
||||||
|
|
||||||
mkdir -p /usr/share/rpcd/acl.d
|
mkdir -p /usr/share/rpcd/acl.d
|
||||||
chmod 0755 /usr/share/rpcd/acl.d
|
chmod 0755 /usr/share/rpcd/acl.d
|
||||||
@@ -13169,7 +13210,19 @@ function zmDeclare(o) {
|
|||||||
if (typeof r === 'number') return r === 0 ? {} : { error: 'Роутер: ' + (UBUS_TEXT[r] || ('ошибка ubus ' + r)), ubus: r };
|
if (typeof r === 'number') return r === 0 ? {} : { error: 'Роутер: ' + (UBUS_TEXT[r] || ('ошибка ubus ' + r)), ubus: r };
|
||||||
return r == null ? {} : r;
|
return r == null ? {} : r;
|
||||||
};
|
};
|
||||||
return rpc.declare(o);
|
var fn = rpc.declare(o);
|
||||||
|
return function() {
|
||||||
|
var self = this, args = arguments, left = 6;
|
||||||
|
if (document.body.classList.contains('zmw-body')) return fn.apply(self, args);
|
||||||
|
function go() {
|
||||||
|
return fn.apply(self, args).catch(function(e) {
|
||||||
|
if (left-- > 0 && /Object not found/i.test(String((e && e.message) || e)))
|
||||||
|
return new Promise(function(ok) { setTimeout(ok, 1500); }).then(go);
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return go();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var callStatus = zmDeclare({ object: 'zapret-manager', method: 'status', expect: {} });
|
var callStatus = zmDeclare({ object: 'zapret-manager', method: 'status', expect: {} });
|
||||||
@@ -13319,7 +13372,41 @@ function detectMissingThemeVar() {
|
|||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cacheGuardDone = false;
|
||||||
|
function cacheGuard() {
|
||||||
|
if (cacheGuardDone) return;
|
||||||
|
cacheGuardDone = true;
|
||||||
|
try {
|
||||||
|
if (document.body.classList.contains('zmw-body') || !window.fetch || !window.localStorage) return;
|
||||||
|
var base = String(L.env.base_url || L.resource('x').replace(/\/x$/, '')), ver = L.env.resource_version;
|
||||||
|
fetch(base + '/zapret-manager/build.txt?t=' + Date.now(), { cache: 'no-store' }).then(function(r) { return r.ok ? r.text() : ''; }).then(function(t) {
|
||||||
|
var lines = String(t || '').split(/\r?\n/).map(function(x) { return x.trim(); }).filter(Boolean);
|
||||||
|
var build = lines.shift(), had = null, stale = false;
|
||||||
|
if (!/^[0-9]{6,}$/.test(build || '')) return;
|
||||||
|
try { had = localStorage.getItem('zm.build'); } catch (e) { return; }
|
||||||
|
if (had === build) return;
|
||||||
|
function grab(url, mode) {
|
||||||
|
return fetch(url, { cache: mode }).then(function(r) { return r.ok ? r.text() : null; }).catch(function() { return null; });
|
||||||
|
}
|
||||||
|
return lines.filter(function(p) { return /^[A-Za-z0-9_\/.-]+\.(js|css)$/.test(p) && p.indexOf('..') < 0; }).reduce(function(pr, p) {
|
||||||
|
var url = base + '/' + p + (/\.js$/.test(p) && ver != null ? '?v=' + ver : '');
|
||||||
|
return pr.then(function() {
|
||||||
|
return grab(url, 'force-cache').then(function(a) {
|
||||||
|
return grab(url, 'reload').then(function(b) { if (a != null && b != null && a !== b) stale = true; });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, Promise.resolve()).then(function() {
|
||||||
|
try { localStorage.setItem('zm.build', build); if (localStorage.getItem('zm.build') !== build) return; } catch (e) { return; }
|
||||||
|
if (!stale) return;
|
||||||
|
toast('Панель обновлена — загружаем новую версию', 'info');
|
||||||
|
setTimeout(function() { location.reload(); }, 700);
|
||||||
|
});
|
||||||
|
}).catch(function() {});
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
function injectCss() {
|
function injectCss() {
|
||||||
|
cacheGuard();
|
||||||
detectMissingThemeVar();
|
detectMissingThemeVar();
|
||||||
if (document.getElementById('zm-css')) return;
|
if (document.getElementById('zm-css')) return;
|
||||||
var l = document.createElement('link');
|
var l = document.createElement('link');
|
||||||
@@ -21414,7 +21501,7 @@ return view.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function routeVerdict(r) {
|
function routeVerdict(r) {
|
||||||
var lines = [], via = cfg && cfg.mode === 'iface' ? 'интерфейс ' + (cfg.iface || '') : 'прокси';
|
var lines = [], via = cfg && cfg.mode === 'iface' ? 'интерфейс ' + (cfg.iface || '') : 'VPN';
|
||||||
if (r.verdict === 'off') return { tone: 'off', cls: 'zm-off', label: 'Forkozz не работает', title: 'запрос пойдёт напрямую', note: 'Запустите Forkozz и проверьте ещё раз.' };
|
if (r.verdict === 'off') return { tone: 'off', cls: 'zm-off', label: 'Forkozz не работает', title: 'запрос пойдёт напрямую', note: 'Запустите Forkozz и проверьте ещё раз.' };
|
||||||
if (r.addr && !r.ip) lines.push([ 'Адрес', r.how === 'fakeip' ? [ r.addr, ' (подменный — домен есть в списках Forkozz)' ] : r.addr ]);
|
if (r.addr && !r.ip) lines.push([ 'Адрес', r.how === 'fakeip' ? [ r.addr, ' (подменный — домен есть в списках Forkozz)' ] : r.addr ]);
|
||||||
if (r.how === 'subnet') lines.push([ 'Совпадение', 'адрес входит в подсети Forkozz' ]);
|
if (r.how === 'subnet') lines.push([ 'Совпадение', 'адрес входит в подсети Forkozz' ]);
|
||||||
@@ -22867,7 +22954,40 @@ ZM_INSTALLER_EOF
|
|||||||
chmod 0644 '/www/luci-static/resources/view/zapret-manager/bytetube.js'
|
chmod 0644 '/www/luci-static/resources/view/zapret-manager/bytetube.js'
|
||||||
|
|
||||||
rm -f /tmp/luci-indexcache* /tmp/luci-modulecache/* 2>/dev/null || true
|
rm -f /tmp/luci-indexcache* /tmp/luci-modulecache/* 2>/dev/null || true
|
||||||
|
ZM_BUILD_ID="$(date +%s)"
|
||||||
|
{
|
||||||
|
echo "$ZM_BUILD_ID"
|
||||||
|
for _zm_f in /www/luci-static/resources/zapret-manager/*.js /www/luci-static/resources/bytetube/*.js /www/luci-static/resources/view/zapret-manager/*.js /www/luci-static/resources/view/zapret-manager/*.css /www/luci-static/resources/view/bytetube/*.css; do
|
||||||
|
[ -f "$_zm_f" ] && echo "${_zm_f#/www/luci-static/resources/}"
|
||||||
|
done
|
||||||
|
} > /www/luci-static/resources/zapret-manager/build.txt.zm-new 2>/dev/null || true
|
||||||
|
mv -f /www/luci-static/resources/zapret-manager/build.txt.zm-new /www/luci-static/resources/zapret-manager/build.txt 2>/dev/null || true
|
||||||
|
chmod 0644 /www/luci-static/resources/zapret-manager/build.txt 2>/dev/null || true
|
||||||
|
|
||||||
|
ZM_RPC_WANT="$(grep -c 'json_add_object' /usr/libexec/rpcd/zapret-manager 2>/dev/null || true)"
|
||||||
|
_zm_rpcd_ready() {
|
||||||
|
ubus -t 5 list zapret-manager >/dev/null 2>&1 || return 1
|
||||||
|
_zm_have="$(ubus -v list zapret-manager 2>/dev/null | grep -c '^[[:space:]]*"' || true)"
|
||||||
|
[ "$_zm_have" = "$ZM_RPC_WANT" ] || [ "$_zm_have" = 0 ]
|
||||||
|
}
|
||||||
|
_zm_rpcd_wait() {
|
||||||
|
_zm_i=0
|
||||||
|
while [ "$_zm_i" -lt "$1" ]; do
|
||||||
|
if _zm_rpcd_ready; then return 0; fi
|
||||||
|
sleep 1
|
||||||
|
_zm_i=$((_zm_i + 1))
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
/etc/init.d/rpcd reload >/dev/null 2>&1 || /etc/init.d/rpcd restart >/dev/null 2>&1 || true
|
/etc/init.d/rpcd reload >/dev/null 2>&1 || /etc/init.d/rpcd restart >/dev/null 2>&1 || true
|
||||||
|
if [ -x /etc/init.d/rpcd ] && command -v ubus >/dev/null 2>&1; then
|
||||||
|
if ! _zm_rpcd_wait 10; then
|
||||||
|
/etc/init.d/rpcd restart >/dev/null 2>&1 || true
|
||||||
|
if ! _zm_rpcd_wait 15; then
|
||||||
|
echo -e "${YELLOW}rpcd не подхватил панель — если страница покажет «Object not found», выполните: /etc/init.d/rpcd restart${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if grep -qx 'steer-spec' /etc/zm-steer/owned 2>/dev/null && /etc/init.d/steer enabled 2>/dev/null; then
|
if grep -qx 'steer-spec' /etc/zm-steer/owned 2>/dev/null && /etc/init.d/steer enabled 2>/dev/null; then
|
||||||
/etc/init.d/steer reload >/dev/null 2>&1 || true
|
/etc/init.d/steer reload >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
@@ -22996,6 +23116,18 @@ var UBUS_ERR = [ 'OK', 'неверная команда', 'неверный ар
|
|||||||
var rpcSeq = 0;
|
var rpcSeq = 0;
|
||||||
|
|
||||||
function ubus(object, method, params, useSid) {
|
function ubus(object, method, params, useSid) {
|
||||||
|
var left = 6;
|
||||||
|
function go() {
|
||||||
|
return ubusOnce(object, method, params, useSid).catch(function (e) {
|
||||||
|
if (left-- > 0 && e && e.rpcCode === -32000 && /Object not found/i.test(e.message || ''))
|
||||||
|
return new Promise(function (ok) { setTimeout(ok, 1500); }).then(go);
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return go();
|
||||||
|
}
|
||||||
|
|
||||||
|
function ubusOnce(object, method, params, useSid) {
|
||||||
var ac = window.AbortController ? new AbortController() : null;
|
var ac = window.AbortController ? new AbortController() : null;
|
||||||
var tm = ac ? setTimeout(function () { ac.abort(); }, 60000) : 0;
|
var tm = ac ? setTimeout(function () { ac.abort(); }, 60000) : 0;
|
||||||
return fetch('/ubus', {
|
return fetch('/ubus', {
|
||||||
@@ -23932,7 +24064,8 @@ function showLogin(note, noteKind) {
|
|||||||
startApp();
|
startApp();
|
||||||
});
|
});
|
||||||
}).catch(function (e) {
|
}).catch(function (e) {
|
||||||
fail(e && e.noUbus ? e.message : ('Роутер не отвечает: ' + ((e && e.message) || e)));
|
if (e && e.rpcCode === -32000 && /Object not found/i.test(e.message || '')) fail('Служба rpcd на роутере ещё запускается — подождите минуту и нажмите «Войти» снова');
|
||||||
|
else fail(e && e.noUbus ? e.message : ('Роутер не отвечает: ' + ((e && e.message) || e)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user