add sTGWS

This commit is contained in:
StressOzz authored and GitHub committed 2026-09-16 19:43:51 +05:00
1 parent d347c47271
commit c5dd32c1f9
1 file changed
+213 -4
+213 -4
View File
@@ -1455,6 +1455,8 @@ exclusions_clear() {
TG_MTPROTO_VER="0.10"
TGWS_INSTALL_URL="https://gitlab.com/xyzmean/brb/-/raw/main/install-tgws.sh"
TGWS_VERSION_URL="https://gitlab.com/xyzmean/brb/-/raw/main/VERSION"
TG_GO_VER="1.4.1"
TG_RS_VER="2.3.3"
TG_BIN_GO="/usr/bin/tg-ws-proxy-go"
@@ -1639,9 +1641,124 @@ tg_restart_all() {
[ -x /etc/init.d/tg-ws-proxy ] && /etc/init.d/tg-ws-proxy restart >/dev/null 2>&1
[ -x "$TG_INIT_GO" ] && "$TG_INIT_GO" restart >/dev/null 2>&1
[ -x "$TG_INIT_RS" ] && "$TG_INIT_RS" restart >/dev/null 2>&1
[ -x /etc/init.d/tgws ] && /etc/init.d/tgws restart >/dev/null 2>&1
printf '{"ok":true}\n'
}
_tgws_domain() {
tgws status 2>/dev/null | sed -n 's/^[[:space:]]*домен:[[:space:]]*//p' | head -n1
}
tgws_status() {
local installed="not_installed" ver="" domain="" running="false" latest=""
if [ "$PKG" = "apk" ]; then
ver=$(apk info -v 2>/dev/null | grep '^tgws-' | sed -E 's/^tgws-([0-9.]+).*/\1/')
else
ver=$(opkg list-installed 2>/dev/null | awk '$1=="tgws"{print $3}' | sed 's/-r[0-9]\+$//')
fi
if [ -x /etc/init.d/tgws ]; then
installed="installed"
[ -n "$(tgws status 2>/dev/null)" ] && running="true"
domain=$(_tgws_domain)
fi
latest=$(curl -fsSL --connect-timeout 4 --max-time 6 "$TGWS_VERSION_URL" 2>/dev/null | tr -d '[:space:]')
printf '{"installed":"%s","running":%s,"version":"%s","latest":"%s","domain":"%s"}\n' "$installed" "$running" "$(esc "$ver")" "$(esc "$latest")" "$(esc "$domain")"
}
do_tgws_install() {
echo "==> Устанавливаем sTGWS"
rm -f /tmp/tgws_install.sh
wget -q -U "Mozilla/5.0" -O /tmp/tgws_install.sh "$TGWS_INSTALL_URL" || { echo "ОШИБКА: не удалось скачать установщик sTGWS"; rm -f /tmp/tgws_install.sh; return 1; }
sh /tmp/tgws_install.sh >/dev/null 2>&1
rm -f /tmp/tgws_install.sh
if [ ! -x /etc/init.d/tgws ]; then
echo "ОШИБКА: установка sTGWS не удалась"
return 1
fi
echo "==> Подбираем домен"
/etc/init.d/tgws enable >/dev/null 2>&1
/etc/init.d/tgws restart >/dev/null 2>&1
tgws pick >/dev/null 2>&1
local i started=0
for i in $(seq 1 20); do
if [ -n "$(tgws status 2>/dev/null)" ]; then
started=1
break
fi
sleep 5
done
if [ "$started" != "1" ]; then
echo "ОШИБКА: не удалось подобрать домен"
return 1
fi
local domain
domain=$(_tgws_domain)
echo "==> Используем домен: ${domain:-не определён}"
echo "==> Готово, sTGWS установлен и запущен"
}
do_tgws_remove() {
echo "==> Удаляем sTGWS"
/etc/init.d/tgws disable >/dev/null 2>&1
/etc/init.d/tgws stop >/dev/null 2>&1
$DELETE tgws >/dev/null 2>&1
/usr/sbin/stgws apply --spec /dev/null --state-dir /var/lib/stgws >/dev/null 2>&1
/usr/sbin/tgws apply --spec /dev/null --state-dir /var/lib/tgws >/dev/null 2>&1
killall tgws >/dev/null 2>&1
killall stgws >/dev/null 2>&1
nft delete table inet stgws >/dev/null 2>&1
nft delete table inet tgws >/dev/null 2>&1
rm -rf /etc/*tgws*
rm -rf /var/lib/*tgws*
rm -rf /var/lock/*tgws*
rm -rf /etc/rc.d/*tgws*
rm -rf /etc/init.d/*tgws*
rm -rf /usr/sbin/*tgws*
rm -rf /usr/bin/*tgws*
rm -rf /etc/config/*tgws*
echo "==> Готово, sTGWS удалён"
}
do_tgws_restart() {
[ -x /etc/init.d/tgws ] || { echo "ОШИБКА: sTGWS не установлен"; return 1; }
echo "==> Перезапускаем sTGWS"
/etc/init.d/tgws restart >/dev/null 2>&1
sleep 5
if [ -z "$(tgws status 2>/dev/null)" ]; then
echo "ОШИБКА: sTGWS не запущен после перезапуска"
return 1
fi
echo "==> Готово, sTGWS перезапущен"
}
do_tgws_reconfigure() {
[ -x /etc/init.d/tgws ] || { echo "ОШИБКА: sTGWS не установлен"; return 1; }
echo "==> Подбираем новый домен"
tgws pick >/dev/null 2>&1
sleep 6
/etc/init.d/tgws restart >/dev/null 2>&1
sleep 3
local domain
domain=$(_tgws_domain)
if [ -z "$(tgws status 2>/dev/null)" ] || [ -z "$domain" ]; then
echo "ОШИБКА: не удалось подобрать домен"
return 1
fi
echo "==> Новый домен: $domain"
echo "==> Готово, домен перенастроен"
}
tgws_action() {
local action="$1"
case "$action" in
install|update) job_start tgws_install do_tgws_install ;;
remove) job_start tgws_remove do_tgws_remove ;;
restart) job_start tgws_restart do_tgws_restart ;;
reconfigure) job_start tgws_reconfigure do_tgws_reconfigure ;;
*) echo '{"error":"неизвестное действие"}' ;;
esac
}
_doh_file="/etc/config/https-dns-proxy"
@@ -1779,6 +1896,8 @@ case "$cmd" in
tg_status) tg_status ;;
tg_action) tg_action "$1" "$2" ;;
tg_restart_all) tg_restart_all ;;
tgws_status) tgws_status ;;
tgws_action) tgws_action "$1" ;;
hosts_status) hosts_status ;;
hosts_toggle) hosts_toggle "$1" ;;
hosts_replace_geohide) hosts_replace_geohide "$1" ;;
@@ -1837,6 +1956,8 @@ list_methods() {
json_add_object "tg_status"; json_close_object
json_add_object "tg_action"; json_add_string "variant" "string"; json_add_string "action" "string"; json_close_object
json_add_object "tg_restart_all"; json_close_object
json_add_object "tgws_status"; json_close_object
json_add_object "tgws_action"; json_add_string "action" "string"; json_close_object
json_add_object "hosts_status"; json_close_object
json_add_object "hosts_toggle"; json_add_string "block" "string"; json_close_object
json_add_object "hosts_replace_geohide"; json_add_string "region" "string"; json_close_object
@@ -1890,6 +2011,8 @@ call_method() {
tg_status) "$BACKEND" tg_status ;;
tg_action) json_get_var variant variant; json_get_var action action; "$BACKEND" tg_action "$variant" "$action" ;;
tg_restart_all) "$BACKEND" tg_restart_all ;;
tgws_status) "$BACKEND" tgws_status ;;
tgws_action) json_get_var action action; "$BACKEND" tgws_action "$action" ;;
hosts_status) "$BACKEND" hosts_status ;;
hosts_toggle) json_get_var block block; "$BACKEND" hosts_toggle "$block" ;;
hosts_replace_geohide) json_get_var region region; "$BACKEND" hosts_replace_geohide "$region" ;;
@@ -1921,7 +2044,7 @@ cat > '/usr/share/rpcd/acl.d/luci-app-zapret-manager.json' << 'ZM_INSTALLER_EOF'
"status", "job_status", "log_tail", "system_info",
"strategy_list_v", "strategy_list_flowseal", "strategy_list_youtube",
"discord_status", "hosts_status", "doh_status", "game_status",
"system_status", "mirror_status", "exclusions_status", "tg_status",
"system_status", "mirror_status", "exclusions_status", "tg_status", "tgws_status",
"zapret_latest_version"
]
}
@@ -1937,7 +2060,7 @@ cat > '/usr/share/rpcd/acl.d/luci-app-zapret-manager.json' << 'ZM_INSTALLER_EOF'
"system_check_connectivity", "system_toggle_quic", "system_toggle_ipv6",
"system_toggle_flow_offloading_fix", "system_toggle_expert_mode", "system_uninstall_panel",
"mirror_set", "exclusions_toggle", "exclusions_clear",
"tg_action", "tg_restart_all"
"tg_action", "tg_restart_all", "tgws_action"
]
}
}
@@ -2051,6 +2174,8 @@ var callExclusionsClear = rpc.declare({ object: 'zapret-manager', method: 'exclu
var callTgStatus = rpc.declare({ object: 'zapret-manager', method: 'tg_status', expect: {} });
var callTgAction = rpc.declare({ object: 'zapret-manager', method: 'tg_action', params: ['variant', 'action'], expect: {} });
var callTgRestartAll = rpc.declare({ object: 'zapret-manager', method: 'tg_restart_all', expect: {} });
var callTgwsStatus = rpc.declare({ object: 'zapret-manager', method: 'tgws_status', expect: {} });
var callTgwsAction = rpc.declare({ object: 'zapret-manager', method: 'tgws_action', params: ['action'], expect: {} });
var callHostsStatus = rpc.declare({ object: 'zapret-manager', method: 'hosts_status', expect: {} });
var callHostsToggle = rpc.declare({ object: 'zapret-manager', method: 'hosts_toggle', params: ['block'], expect: {} });
var callHostsReplaceGeohide = rpc.declare({ object: 'zapret-manager', method: 'hosts_replace_geohide', params: ['region'], expect: {} });
@@ -2246,6 +2371,8 @@ return baseclass.extend({
tgStatus: callTgStatus,
tgAction: callTgAction,
tgRestartAll: callTgRestartAll,
tgwsStatus: callTgwsStatus,
tgwsAction: callTgwsAction,
hostsStatus: callHostsStatus,
hostsToggle: callHostsToggle,
hostsReplaceGeohide: callHostsReplaceGeohide,
@@ -3684,11 +3811,13 @@ function fallbackCopy(text) {
return view.extend({
load: function() {
zm.injectCss();
return zm.tgStatus();
return Promise.all([ zm.tgStatus(), zm.tgwsStatus().catch(function() { return {}; }) ]);
},
render: function(data) {
render: function(all) {
var view = this;
var data = all[0];
var tgwsData = all[1] || {};
var wrap = E('div', { 'class': 'zm-wrap' });
var cards = E('div', { 'class': 'zm-cards' });
var linksWrap = E('div', {});
@@ -3800,6 +3929,85 @@ return view.extend({
wrap.appendChild(cards);
wrap.appendChild(logEl);
var tgwsCard = E('div', { 'class': 'zm-card' });
var tgwsBusy = false;
function renderTgws(d) {
var installed = d.installed === 'installed';
var actions = [];
if (installed) {
actions.push(E('button', {
'class': 'cbi-button cbi-button-remove',
'click': function() { doTgwsAction('remove'); }
}, 'Удалить'));
if (d.version && d.latest && d.version !== d.latest) {
actions.push(E('button', {
'class': 'cbi-button',
'click': function() { doTgwsAction('update'); }
}, 'Обновить до ' + d.latest));
}
actions.push(E('button', {
'class': 'cbi-button',
'click': function() { doTgwsAction('restart'); }
}, 'Перезапустить'));
actions.push(E('button', {
'class': 'cbi-button',
'click': function() { doTgwsAction('reconfigure'); }
}, 'Подобрать новый домен'));
} else {
actions.push(E('button', {
'class': 'cbi-button cbi-button-positive',
'click': function() { doTgwsAction('install'); }
}, 'Установить'));
}
tgwsCard.innerHTML = '';
tgwsCard.appendChild(E('h3', {}, 'sTGWS (бета)'));
tgwsCard.appendChild(E('p', { 'class': 'zm-hint' }, 'Бета-версия. В отдельных случаях может потребоваться сброс роутера до заводских настроек. Не устанавливайте, если не уверены, что сможете устранить возможные проблемы — рекомендуется использовать другие варианты TG WS Proxy выше.'));
tgwsCard.appendChild(E('div', { 'class': 'zm-row' }, [
E('span', { 'class': 'zm-label' }, 'Статус'),
installed ? zm.badge(d.running === true, 'запущен', 'остановлен') : zm.badge(false, '', 'не установлен')
]));
if (installed && d.version) {
tgwsCard.appendChild(E('div', { 'class': 'zm-row' }, [
E('span', { 'class': 'zm-label' }, 'Версия'), E('span', {}, d.version)
]));
}
if (installed && d.domain) {
tgwsCard.appendChild(E('div', { 'class': 'zm-row' }, [
E('span', { 'class': 'zm-label' }, 'Домен'), E('span', {}, d.domain)
]));
}
tgwsCard.appendChild(E('div', { 'class': 'zm-actions' }, actions));
}
function doTgwsAction(action) {
if (tgwsBusy) { zm.toast('Дождитесь завершения текущей операции', 'warning'); return; }
tgwsBusy = true;
var job = action === 'remove' ? 'tgws_remove'
: action === 'restart' ? 'tgws_restart'
: action === 'reconfigure' ? 'tgws_reconfigure' : 'tgws_install';
var label = action === 'remove' ? 'Удаляем sTGWS'
: action === 'restart' ? 'Перезапускаем sTGWS'
: action === 'reconfigure' ? 'Подбираем новый домен sTGWS'
: action === 'update' ? 'Обновляем sTGWS' : 'Устанавливаем sTGWS';
zm.toast(label, 'warning');
zm.tgwsAction(action).then(function(res) {
if (res.error) { tgwsBusy = false; zm.toast(res.error, 'error'); return; }
if (res.started) {
zm.pollJob(job, logEl, function(ok) {
tgwsBusy = false;
zm.toast(ok ? 'Готово' : 'Ошибка', ok ? 'info' : 'error');
zm.tgwsStatus().then(function(d) { renderTgws(d); });
});
} else {
tgwsBusy = false;
}
}).catch(function() { tgwsBusy = false; });
}
renderTgws(tgwsData);
wrap.appendChild(tgwsCard);
var restartBusy = false;
wrap.appendChild(E('div', { 'class': 'zm-card' }, [
E('h3', {}, 'Общие действия'),
@@ -3813,6 +4021,7 @@ return view.extend({
zm.tgRestartAll().then(function() {
restartBusy = false;
zm.toast('Все запущенные TG WS Proxy перезапущены', 'info');
zm.tgwsStatus().then(function(d) { renderTgws(d); });
}).catch(function() { restartBusy = false; });
}
}, 'Перезапустить все')