L×Box

com.leadaxe.lxbox
by Zapstore _@zapstore.dev

Republished from GitHub / F-Droid by the Zapstore main account.

L×Box is a high-performance proxy client with no compromises. You choose the servers. You set the rules. You control the traffic. L×Box does exactly what you told it to. 12+ protocols, advanced routing, full DNS control, detour chains, per-app split tunneling and built-in diagnostics. No account, no ads, no analytics. No server network of our own. THE CORE IS OURS L×Box runs on sing-box-lx, our own fork of sing-box, developed together with the app. On top of stock sing-box the core adds: • AmneziaWG 2.0 — obfuscated WireGuard; • XHTTP — Xray transport, including stream-one; • VLESS + ML-KEM-768 — post-quantum protection; • MASQUE — Cloudflare WARP as a full node and a chain link. And it is tuned for real life on a phone: • DNS groups — several resolvers with failover; • smart urltest — pools, sticky selection, lazy health checks; • load balancing — connections spread across the pool; • self-healing of stuck connections; • idle tunnel sleep — less memory, less battery; • observability — DNS, connections and chains visible from the app. The core stays in sync with upstream; changes are verified on real devices. 12+ PROTOCOLS VLESS, VMess, Trojan, Shadowsocks, Hysteria2, TUIC v5, NaiveProxy, AnyTLS, SSH, SOCKS, WireGuard, AmneziaWG 2.0, MASQUE over QUIC/HTTP-3. Cloudflare WARP in one tap: registration right in the app, the private key is generated on your device and never leaves it — Cloudflare receives only the public half. WireGuard or MASQUE, optional AmneziaWG obfuscation. Import any familiar format: subscriptions and links, Base64, Xray arrays, WireGuard URI/INI, Amnezia vpn://, sing-box JSON configs, local files, plain text. SUBSCRIPTIONS WITHOUT MANUAL WORK Add a subscription — L×Box parses it and creates nodes with no duplicates. Unwanted nodes can be switched off and stay off through every update, even if the provider renames them. Processing rules with regex and capture groups rename, rewrite or disable nodes on every refresh — and show in advance which nodes a rule will hit. Coming from another sing-box client? Import the whole config — with auto-select groups and detour chains. ROUTING YOU ACTUALLY CONTROL Shape your internet exit around your life. One device can host several environments at once: work, travel, safe browsing and acceleration, the open internet. Each with its own rules and its own route. Conditions: domain, IP and CIDR, port, protocol, app, network type. DNS UNDER YOUR CONTROL Several resolvers at once. A separate DNS per rule. FakeIP. You decide where every query goes. FULL DIAGNOSTICS ON BOARD Ping and speed-test a node, a folder or the whole subscription — with the tunnel up or down. One-way connections get flagged. Full log right in the app. In real time the built-in tools show: which app opened a connection, where to, how much it transferred, which DNS it used, which route it took. Speed and traffic per app and per connection. AUTOMATION Works with automation tools (such as Tasker or MacroDroid): start, stop, switch node, query state. Your phone reshapes the setup to your scenarios — at home, on the road, when Wi-Fi changes. WE SEND YOUR DATA NOWHERE No account. No ads, no analytics, no advertising ID, no crash reporters. L×Box connects only to the servers and update endpoints you configured. Full backup and restore moves your setup to a new device. A CLIENT, NOT A VPN SERVICE L×Box provides no servers and sells no access to anyone's network — you choose your servers and subscriptions. OPEN SOURCE Free software under GPLv3. English and Russian UI, light and dark themes. GitHub: github.com/Leadaxe/LxBox

First release: Sep 9, 2026, 10 total releases.

Most recent release: Sep 28, 2026.

Website Repo

Appears in 0 app stacks.

0 sats / 0 zaps received in the past year.

Sats Received

Underlying data available via MCP: app_zaps, app_releases.

Zap Count

Underlying data available via MCP: app_zaps, app_releases.

Releases

  • Sep 28, 2026 2.25.8
    # L×Box v2.25.8 **A patch on top of [v2.25.7](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.7).** Tailscale is now served by a routing preset instead of per-node sections, and a Tailscale node gets a Network tab with devices and exit node switching on the fly. Home lists Tailscale nodes without an exit under `NETWORKS`. A node written by hand as sing-box JSON goes to the core as written; nodes of a type the app does not know and `openvpn-client` endpoints are accepted. The DNS screen gets cache settings. Core `v1.14.2-lx.8`, protocol contract 1.1.99.
    More…
    Google Play last shipped v2.25.5: the section «Since v2.25.5» at the end of each language lists what v2.25.6 and v2.25.7 brought. **Патч поверх [v2.25.7](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.7).** Tailscale теперь обслуживает пресет маршрутизации, а не секции узла; у узла Tailscale появилась вкладка Network с устройствами и сменой exit node на ходу. Главный экран показывает узлы Tailscale без выхода в `NETWORKS`. Узел, записанный вручную как sing-box JSON, уходит в ядро как написан; узлы незнакомого приложению типа и endpoint `openvpn-client` принимаются. На экране DNS появились настройки кэша. Ядро `v1.14.2-lx.8`, контракт протоколов 1.1.99. В Google Play последней была v2.25.5: раздел «С v2.25.5» в конце каждого языка перечисляет, что принесли v2.25.6 и v2.25.7. --- <details open> <summary><h2>🇬🇧 English</h2></summary> ## ⚠️ Read before updating - **Node sections are gone.** A node no longer carries route rules or DNS records of its own. The Tailscale bundle that used to live in a node is now the `Tailscale networks` preset, added once to existing installs and on by default. A record or a backup with a leftover `sections` field loads without error; the field is dropped ([§575](docs/spec/tasks/575-remove-node-sections.md)). - **A hand-written node is no longer fixed by the app.** A sing-box JSON node saved as your own server or a folder member goes to the core as written: an extra key, an AmneziaWG `mtu` above 1280, a `tls.fragment` next to a detour stay. The node card still lists each rule, says nothing was changed and what to do. Rules the core cannot start with (an unsupported `flow`, an invalid port, TLS fields `naive` does not take) are still applied ([§577](docs/spec/tasks/577-authored-json-registry-reports-only.md)). - **A node's source keeps the node only.** Saving a sing-box document or an array in the node editor keeps the first node and says once that the rest is not kept; a document with no node is refused. Records saved earlier this way are read as the node's body, the config does not change ([§576](docs/spec/tasks/576-node-source-is-bare-body.md)). ## ✨ Added - **Tailscale preset.** `Tailscale networks` serves every Tailscale node in the config, subscription nodes included: tailnet names go to the node's own DNS, addresses and names the node claims (`preferred_by`) go through the node. Deleting the preset keeps it deleted. The preset row on the Routing and DNS screens lists the nodes it serves ([§578](docs/spec/tasks/578-tailscale-preset-template-for-each.md)). - **Skip presets on a node.** A server or a folder member can opt out of presets that serve nodes one by one: the `Skip presets` switch on the node screen, stored in the record and in backups. It shows only when the template has such a preset for the node's type. - **Tailscale node: Network tab.** Node state, sign in and log out, this device, the network's devices with a ping, and the exit node list. Picking an exit node switches it on the fly without touching the node; `Save choice` writes it into the node. From `NETWORKS` the node opens on this tab ([task 581](docs/spec/tasks/581-tailscale-network-tab.md)). - **NETWORKS on Home.** While the VPN is on, Tailscale nodes without an exit node are listed under `NETWORKS`, the last entry of the Direction list. Instead of a delay the row shows the node state: `running`, `sign-in needed`, `stopped` or `starting` ([task 579](docs/spec/tasks/579-networks-pseudo-direction.md)). - **DNS cache settings.** Next to Clear DNS cache: `DNS cache size` (1024 to 65535 entries, default 4000), `Serve stale answers` (on by default) and `Keep DNS cache after restart` (on by default). The settings travel in backups ([task 580](docs/spec/tasks/580-dns-cache-settings.md)). - **Nodes of a type the app does not know.** A sing-box node added by hand (Add server, paste, file, folder member, node editor) is accepted even if the app has no model for its type; it goes to the core as written with one info notice. Subscriptions still drop such entries. Pasted JSON with `//` and `/* */` comments is accepted; the comments are removed ([task 585](docs/spec/tasks/585-unknown-node-type-accepted.md)). - **OpenVPN endpoints as sing-box JSON.** `openvpn-client` is a known type: it is accepted as your own record, inside a document and from a subscription, and goes to the core as written. There is no form and no `.ovpn` import ([task 586](docs/spec/tasks/586-endpoint-types-from-registry.md)). - **Home: press back twice to exit.** The first press shows «Press back again to exit», a second press within 2 seconds closes the app. An open menu, dialog or sheet closes on back as before ([task 583](docs/spec/tasks/583-home-back-press-twice-to-exit.md)). - **Template language.** A preset can repeat its rules and DNS servers for every matching node with `for_each`, and read the node's tag, record and body through `@node` and `#tpl`. ## 🔄 Changed - **Core `v1.14.2-lx.8`.** Synced with sing-box `stable`. Idle connections of nodes and DNS servers nothing refers to any more are closed, also when the device pauses. WireGuard, AmneziaWG and MASQUE inside another tunnel really allow fragmentation of the outer UDP datagram on Android; before, oversized datagrams were dropped. Hysteria, Hysteria2 and TUIC no longer allow it by default, QUIC finds the path MTU itself. - **MASQUE no longer hangs without an error.** `vhttp: auto` goes back to h3 when the remembered h2 stops working (before, only a restart helped); closing an h2 tunnel does not wait minutes for a stalled write; an h3 endpoint that never answers no longer holds every dial of the node. - **XHTTP without `xmux`.** An XHTTP node without an `xmux` section (or with an empty one) keeps at most three connections to the server and shares them between streams. Before, every stream opened its own TLS connection: dozens to hundreds of parallel connections to one IP, a pattern reported to be cut on mobile networks in Russia. An `xmux` section with any field set is taken as written. - **A hand-written node the core would reject is dropped.** A TUIC node with a `uuid` that is not a UUID, or a WireGuard node with invalid peer `allowed_ips`, is dropped with the reason in the list of dropped nodes. A REALITY `short_id` longer than 16 characters is removed; a REALITY block with an invalid `public_key` is removed whole. A MASQUE body without keys is read instead of being rejected ([task 582](docs/spec/tasks/582-authored-body-go-dart-parity.md)). - **Default emoji of a Tailscale node is 🕸️** (was 🪢). Existing node tags do not change. ## 🩹 Fixes - Bottom sheet and padding rules in the new screens; waiting for MASQUE parsing. ## 🔧 Under the hood - Contract with the launcher: 1.1.99. Which types are endpoints now comes from the contract registry. ## 📦 Since v2.25.5 (for Google Play users) **v2.25.7** - TLS fragmentation from Xray `finalmask.tcp`; these fields used to be ignored ([§573](docs/spec/tasks/573-xray-finalmask-tcp-fragment.md)). - A node that goes through another node (a chain or a subscription detour) no longer carries TLS fragmentation ([§574](docs/spec/tasks/574-tls-fragment-yields-to-detour.md)). - Node notifications with the same code are grouped into one entry; Xray nodes show fewer «field not read» notices ([§572](docs/spec/tasks/572-notifications-group-by-code.md)). **v2.25.6** - Turn a WireGuard/AmneziaWG node off and on without restarting the tunnel ([§557](docs/spec/tasks/557-kernel-lx4-wg-endpoint-toggle.md)). - Replace a folder or a subscription with a group: Manual, Auto or Both ([§568](docs/spec/tasks/568-source-replace-fold.md)). - A `selector` group from a subscription or a backup stays manual and keeps its chosen server ([§565](docs/spec/features/565%20selector-group-genus/spec.md)). - Wi-Fi rules read the network name the way Android 12+ expects and say why the name cannot be read (approximate location, Location off) ([§567](docs/spec/tasks/567-wifi-ssid-read-preflight-and-diagnostics.md), [§569](docs/spec/tasks/569-wifi-ssid-transport-info-api31.md)). - Imported nodes keep what the provider sent: `multiplex`, `udp_over_tcp`, dial options, WireGuard `workers` and more ([§560](docs/spec/tasks/560-xray-body-parse-gaps.md)). - A preset rule left without conditions is dropped instead of matching all traffic ([§571](docs/spec/tasks/571-rule-conditions-allowlist.md)). - Dropped subscription entries show in the subscription summary, not on a working node ([§561](docs/spec/tasks/561-dropped-only-in-source-summary.md)). - A chain with a REALITY hop saves when uTLS is stripped; links to a chain open the chain ([§556](docs/spec/tasks/556-registry-debt-1157-1170.md), [§558](docs/spec/tasks/558-chain-owner-navigation.md)). - A `vpn://` line gives every WireGuard/AmneziaWG container of the profile; template variables with a list of values are chips with an optional own value ([§570](docs/spec/tasks/570-close-open-tails.md)). Full lists: [v2.25.6](docs/releases/v2.25.6.md), [v2.25.7](docs/releases/v2.25.7.md). </details> <details open> <summary><h2>🇷🇺 Русский</h2></summary> ## ⚠️ Прочтите до обновления - **Секций узла больше нет.** Узел не несёт собственных правил маршрутов и записей DNS. Связка Tailscale, которая раньше жила в узле, теперь пресет `Tailscale networks`: в существующие установки он добавляется один раз и включён по умолчанию. Запись или бэкап с оставшимся полем `sections` читаются без ошибки, поле отбрасывается ([§575](docs/spec/tasks/575-remove-node-sections.md)). - **Узел, записанный вручную, приложение больше не правит.** Узел sing-box JSON, сохранённый как свой сервер или член папки, уходит в ядро как написан: лишний ключ, `mtu` AmneziaWG больше 1280, `tls.fragment` рядом с detour остаются. Карточка узла по-прежнему перечисляет каждое правило, пишет, что ничего не изменено, и что делать. Правила, без которых ядро не стартует (неподдерживаемый `flow`, неверный порт, поля TLS, которых не принимает `naive`), применяются как раньше ([§577](docs/spec/tasks/577-authored-json-registry-reports-only.md)). - **Источник узла хранит только узел.** При сохранении sing-box документа или массива в редакторе узла остаётся первый узел, а приложение один раз говорит, что остальное не сохранено; документ без узла отклоняется. Записи, сохранённые так раньше, читаются как тело узла, конфиг не меняется ([§576](docs/spec/tasks/576-node-source-is-bare-body.md)). ## ✨ Добавлено - **Пресет Tailscale.** `Tailscale networks` обслуживает каждый узел Tailscale в конфиге, включая узлы подписок: имена tailnet идут в DNS самого узла, адреса и имена, которые узел объявляет своими (`preferred_by`), идут через узел. Удалённый пресет остаётся удалённым. Строка пресета на экранах Routing и DNS перечисляет обслуживаемые узлы ([§578](docs/spec/tasks/578-tailscale-preset-template-for-each.md)). - **Skip presets на узле.** Свой сервер или член папки может отказаться от пресетов, которые обслуживают узлы поштучно: переключатель `Skip presets` на экране узла, хранится в записи и в бэкапах. Виден, только если в шаблоне есть такой пресет для типа узла. - **Вкладка Network узла Tailscale.** Состояние узла, вход и выход, это устройство, устройства сети с пингом и список exit node. Выбор exit node переключает его на ходу, не трогая узел; `Save choice` записывает выбор в узел. Из `NETWORKS` узел открывается сразу на этой вкладке ([задача 581](docs/spec/tasks/581-tailscale-network-tab.md)). - **NETWORKS на главном экране.** При включённом VPN узлы Tailscale без exit node перечислены в `NETWORKS`, последнем пункте списка направлений. Вместо задержки строка показывает состояние узла: `running`, `sign-in needed`, `stopped` или `starting` ([задача 579](docs/spec/tasks/579-networks-pseudo-direction.md)). - **Настройки кэша DNS.** Рядом с Clear DNS cache: `DNS cache size` (от 1024 до 65535 записей, по умолчанию 4000), `Serve stale answers` (включено) и `Keep DNS cache after restart` (включено). Настройки переносятся в бэкапах ([задача 580](docs/spec/tasks/580-dns-cache-settings.md)). - **Узлы незнакомого приложению типа.** Узел sing-box, добавленный вручную (Add server, вставка, файл, член папки, редактор узла), принимается, даже если у приложения нет модели для его типа; он уходит в ядро как написан с одним информационным уведомлением. Подписки такие записи по-прежнему отбрасывают. Вставленный JSON с комментариями `//` и `/* */` принимается, комментарии снимаются ([задача 585](docs/spec/tasks/585-unknown-node-type-accepted.md)). - **OpenVPN как sing-box JSON.** `openvpn-client` — известный тип: принимается своей записью, внутри документа и из подписки и уходит в ядро как написан. Формы и импорта `.ovpn` нет ([задача 586](docs/spec/tasks/586-endpoint-types-from-registry.md)). - **Главный экран: выход двойным «назад».** Первое нажатие показывает «Press back again to exit», второе в течение 2 секунд закрывает приложение. Открытое меню, диалог или лист закрываются как раньше ([задача 583](docs/spec/tasks/583-home-back-press-twice-to-exit.md)). - **Язык шаблонов.** Пресет может повторять свои правила и DNS-серверы для каждого подходящего узла через `for_each` и читать тег, запись и тело узла через `@node` и `#tpl`. ## 🔄 Изменено - **Ядро `v1.14.2-lx.8`.** Синхронизировано со `stable` sing-box. Простаивающие соединения узлов и DNS-серверов, на которые больше ничто не ссылается, закрываются, в том числе когда устройство засыпает. WireGuard, AmneziaWG и MASQUE внутри другого туннеля действительно разрешают фрагментацию внешней UDP-датаграммы на Android; раньше слишком большие датаграммы терялись. Hysteria, Hysteria2 и TUIC по умолчанию её больше не разрешают, QUIC сам находит MTU пути. - **MASQUE больше не зависает без ошибки.** `vhttp: auto` возвращается к h3, когда запомненный h2 перестал работать (раньше помогал только рестарт); закрытие h2-туннеля не ждёт минутами зависшую запись; h3-эндпоинт, который не отвечает, больше не держит все dial узла. - **XHTTP без `xmux`.** Узел XHTTP без секции `xmux` (или с пустой) держит не больше трёх соединений с сервером и делит их между потоками. Раньше каждый поток открывал своё TLS-соединение: десятки и сотни параллельных соединений на один IP, и такой рисунок, по сообщениям, режут в мобильных сетях в России. Секция `xmux` хотя бы с одним полем берётся как написана. - **Ручной узел, который ядро отвергло бы, отбрасывается.** Узел TUIC с `uuid`, который не UUID, или WireGuard с неверными `allowed_ips` пира отбрасывается с причиной в списке отброшенных. `short_id` REALITY длиннее 16 символов снимается; блок REALITY с неверным `public_key` снимается целиком. Тело MASQUE без ключей читается, а не отклоняется ([задача 582](docs/spec/tasks/582-authored-body-go-dart-parity.md)). - **Знак узла Tailscale по умолчанию 🕸️** (был 🪢). Теги существующих узлов не меняются. ## 🩹 Исправления - Правила нижнего листа и отступов в новых экранах; ожидание разбора MASQUE. ## 🔧 Под капотом - Контракт с лаунчером: 1.1.99. Какие типы являются endpoint, теперь решает реестр контракта. ## 📦 С v2.25.5 (для пользователей Google Play) **v2.25.7** - Фрагментация TLS из Xray `finalmask.tcp`; раньше эти поля не читались ([§573](docs/spec/tasks/573-xray-finalmask-tcp-fragment.md)). - Узел, который идёт через другой узел (цепочка или detour подписки), больше не несёт фрагментацию TLS ([§574](docs/spec/tasks/574-tls-fragment-yields-to-detour.md)). - Уведомления узла с одним кодом собраны в одну запись; у узлов Xray меньше уведомлений «field not read» ([§572](docs/spec/tasks/572-notifications-group-by-code.md)). **v2.25.6** - Узел WireGuard/AmneziaWG выключается и включается без перезапуска туннеля ([§557](docs/spec/tasks/557-kernel-lx4-wg-endpoint-toggle.md)). - Папку или подписку можно заменить группой: Manual, Auto или Both ([§568](docs/spec/tasks/568-source-replace-fold.md)). - Группа `selector` из подписки или бэкапа остаётся ручной и помнит выбранный сервер ([§565](docs/spec/features/565%20selector-group-genus/spec.md)). - Правила по Wi-Fi читают имя сети так, как ждёт Android 12+, и объясняют, почему имя не прочитать (приблизительная геолокация, выключенная Location) ([§567](docs/spec/tasks/567-wifi-ssid-read-preflight-and-diagnostics.md), [§569](docs/spec/tasks/569-wifi-ssid-transport-info-api31.md)). - Импортированные узлы сохраняют то, что прислал провайдер: `multiplex`, `udp_over_tcp`, параметры подключения, `workers` WireGuard и другое ([§560](docs/spec/tasks/560-xray-body-parse-gaps.md)). - Правило пресета, оставшееся без условий, отбрасывается, а не ловит весь трафик ([§571](docs/spec/tasks/571-rule-conditions-allowlist.md)). - Отброшенные записи подписки видны в сводке подписки, а не на рабочем узле ([§561](docs/spec/tasks/561-dropped-only-in-source-summary.md)). - Цепочка с REALITY-хопом сохраняется, когда uTLS снят; ссылка на цепочку открывает цепочку ([§556](docs/spec/tasks/556-registry-debt-1157-1170.md), [§558](docs/spec/tasks/558-chain-owner-navigation.md)). - Строка `vpn://` даёт все контейнеры WireGuard/AmneziaWG профиля; переменные шаблона со списком значений — чипы с возможностью своего значения ([§570](docs/spec/tasks/570-close-open-tails.md)). Полные списки: [v2.25.6](docs/releases/v2.25.6.md), [v2.25.7](docs/releases/v2.25.7.md). </details> --- ## Install / Установка ```bash adb install -r LxBox-v2.25.8-arm64-v8a.apk ``` Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся. No uninstall needed — install over the existing one. Settings and subscriptions are preserved. --- Previous release / Предыдущий релиз: [v2.25.7](docs/releases/v2.25.7.md).
  • Sep 27, 2026 2.25.7
    # L×Box v2.25.7 **A patch on top of [v2.25.6](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.6).** Xray nodes that set TLS fragmentation in `finalmask.tcp` now get the core's fragmentation; before, these fields were ignored. A node that goes through another node (a chain or a subscription detour) no longer carries TLS fragmentation. Xray nodes show fewer "field not read" notifications, and notifications with the same code are grouped into one entry. The parser and the config build follow the protocol contract 1.1.84.
    More…
    **Патч поверх [v2.25.6](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.6).** Узлы Xray, у которых фрагментация TLS задана в `finalmask.tcp`, получают фрагментацию ядра; раньше эти поля не читались. Узел, который идёт через другой узел (цепочка или detour подписки), больше не несёт фрагментацию TLS. У узлов Xray меньше уведомлений «field not read», а уведомления с одним кодом собраны в одну запись. Парсер и сборка конфига следуют контракту протоколов 1.1.84. --- <details open> <summary><h2>🇬🇧 English</h2></summary> ## ⚠️ Read before updating - **TLS fragmentation is removed from a node that goes through another node.** When the build sends a node through a hop (a chain, or a subscription's detour), `tls.fragment` is taken off that node and the node shows an info notice. This also applies to nodes whose sing-box JSON sets `tls.fragment`. Under a hop fragmentation does not help: the core pauses 500 ms after every segment and turns off its own protection against a lost large ClientHello. A `detour` written in the sing-box JSON itself does not count, since it never reaches the core ([§574](docs/spec/tasks/574-tls-fragment-yields-to-detour.md)). ## ✨ Added - **TLS fragmentation from Xray subscriptions.** An Xray node that sets ClientHello fragmentation in `streamSettings.finalmask.tcp` (an item with `type: fragment`) now gets the core's `tls.fragment`. These fields used to be ignored, and the node went out without fragmentation. The Xray parameters (`length`, `delay`, `maxSplit`) are not carried over: the core splits the ClientHello at the domain labels of the SNI. The older form (a `freedom` outbound through `dialerProxy`) worked before and is unchanged ([§573](docs/spec/tasks/573-xray-finalmask-tcp-fragment.md)). ## 🔄 Changed - **Node notifications are grouped by code.** Several notifications with the same code within a level are shown as one entry with a count, the list of fields and a single explanation. A code that occurs once is shown as before ([§572](docs/spec/tasks/572-notifications-group-by-code.md)). - **TLS fragmentation with a system TLS engine.** With `tls.engine` set to `apple` or `windows`, fragmentation is removed with a warning instead of the config failing to start; the engine stays. These engines are not used on Android ([§574](docs/spec/tasks/574-tls-fragment-yields-to-detour.md)). ## 🩹 Fixes - **Fewer "field not read" notifications on Xray nodes.** An empty `tcpSettings` and the `mode` / `path` / `host` fields inside `xhttpSettings.extra` no longer produce a notification. Xray always replaces those three with the outer values, so there is nothing to report ([§573](docs/spec/tasks/573-xray-finalmask-tcp-fragment.md)). ## 🔧 Under the hood - Contract with the launcher: 1.1.84. - GitHub Actions moved to Node 24. </details> <details open> <summary><h2>🇷🇺 Русский</h2></summary> ## ⚠️ Прочтите до обновления - **С узла, который идёт через другой узел, снимается фрагментация TLS.** Если сборка пускает узел через промежуточный (цепочка или detour подписки), `tls.fragment` с него снимается, и узел показывает информационное уведомление. Это касается и узлов, у которых `tls.fragment` прописан в sing-box JSON. Через промежуточный узел фрагментация не помогает: ядро выжидает 500 мс после каждого сегмента и отключает собственную защиту от потери большого ClientHello. `detour`, записанный в самом sing-box JSON, не считается: до ядра он не доходит ([§574](docs/spec/tasks/574-tls-fragment-yields-to-detour.md)). ## ✨ Добавлено - **Фрагментация TLS из Xray-подписок.** Узел Xray, у которого фрагментация ClientHello задана в `streamSettings.finalmask.tcp` (элемент с `type: fragment`), получает фрагментацию ядра `tls.fragment`. Раньше эти поля не читались, и узел работал без фрагментации. Параметры Xray (`length`, `delay`, `maxSplit`) не переносятся: ядро режет ClientHello по меткам домена в SNI. Старая форма (outbound `freedom` через `dialerProxy`) работала и раньше и не менялась ([§573](docs/spec/tasks/573-xray-finalmask-tcp-fragment.md)). ## 🔄 Изменено - **Уведомления узла сгруппированы по коду.** Несколько уведомлений одного уровня с одинаковым кодом показываются одной записью: счётчик, список полей и один общий разбор. Код, который встречается один раз, выглядит как раньше ([§572](docs/spec/tasks/572-notifications-group-by-code.md)). - **Фрагментация TLS и системный TLS-движок.** При `tls.engine` = `apple` или `windows` фрагментация снимается с предупреждением, а не роняет старт конфига; движок остаётся. На Android такие движки не используются ([§574](docs/spec/tasks/574-tls-fragment-yields-to-detour.md)). ## 🩹 Исправления - **Меньше уведомлений «field not read» у узлов Xray.** Пустой `tcpSettings` и поля `mode` / `path` / `host` внутри `xhttpSettings.extra` больше не дают уведомлений. Xray всегда заменяет эти три поля внешними значениями, так что сообщать не о чем ([§573](docs/spec/tasks/573-xray-finalmask-tcp-fragment.md)). ## 🔧 Под капотом - Контракт с лаунчером: 1.1.84. - GitHub Actions переведены на Node 24. </details> --- ## Install / Установка ```bash adb install -r LxBox-v2.25.7-arm64-v8a.apk ``` Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся. No uninstall needed — install over the existing one. Settings and subscriptions are preserved. --- Previous release / Предыдущий релиз: [v2.25.6](docs/releases/v2.25.6.md).
  • Sep 25, 2026 2.25.5
    # L×Box v2.25.5 **A patch on top of [v2.25.4](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.4).** The core moves to `v1.14.2-lx.3`: VLESS servers with Vision and VLESS Encryption connect on any transport, including XHTTP, and XHTTP picks the HTTP version from `alpn`. hysteria2 links from 3x-ui with gecko keep their packet sizes, XHTTP with `uplinkDataPlacement` `body`/`auto` keeps the setting. Servers from sing-box JSON and the latency check now go through the protocol registry, like links and the working config. Subscription parsing and the
    More…
    registry guard are about twice as fast. JSON gets syntax highlighting in the config editor and on the JSON viewing screens. **Патч поверх [v2.25.4](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.4).** Ядро обновлено до `v1.14.2-lx.3`: серверы VLESS с Vision и VLESS-шифрованием подключаются на любом транспорте, включая XHTTP, а XHTTP выбирает версию HTTP по `alpn`. Ссылки hysteria2 из 3x-ui с gecko больше не теряют размеры пакетов, XHTTP с `uplinkDataPlacement` `body`/`auto` не теряет настройку. Серверы из sing-box JSON и проверка задержки теперь проходят через реестр протоколов, как ссылки и рабочий конфиг. Разбор подписок и гард реестра примерно вдвое быстрее. JSON подсвечивается в редакторе конфига и на экранах просмотра JSON. --- <details open> <summary><h2>🇬🇧 English</h2></summary> ## ✨ Added - **JSON syntax highlighting.** The config editor and the JSON field of the add-server wizard highlight keys, strings, numbers and brackets; the light or dark scheme follows the app theme. The JSON tab in node settings, the node view screen and the subscription node inspector show JSON in the same highlighted read-only viewer. ## 🔄 Changed - **Core v1.14.2-lx.3.** VLESS servers with both Vision and VLESS Encryption connect on any transport, including XHTTP; previously every such server failed with `vision: not a valid supported TLS connection` ([sing-box-lx#29](https://github.com/Leadaxe/sing-box-lx/issues/29)). XHTTP picks HTTP/1.1, HTTP/2 or HTTP/3 from `tls.alpn`, as Xray does: h3-only servers work, and an `alpn` that XHTTP servers used to ignore silently now changes the HTTP version. - **Faster registry guard.** The guard that checks servers when the config and latency-check batches are built takes ~31 µs per server instead of ~63: schemas and field relations are parsed once, a base64 key is decoded once. - **Faster link parsing.** A link takes ~147 µs instead of ~395 on a mixed corpus: the scheme route and the declared parameter names are computed once per section set instead of on every subscription line, and an Xray outbound is serialized once. Measured on a desktop host; behaviour does not change. ## 🩹 Fixes - **hysteria2 links from 3x-ui with gecko keep their packet sizes.** 3x-ui writes the gecko obfuscation range as `minPacketSize`/`maxPacketSize` and adds `security=tls` to every link. All three used to be reported as unread, and the server came up with gecko but with the core's default sizes. Now the sizes reach `obfs`, `security=tls` is accepted silently, and any other `security` value only adds a warning. - **VLESS with Vision and VLESS Encryption over XHTTP keeps `flow`.** Such a server arrived without `flow`, and a Vision server dropped the connection. With encryption, Vision runs on top of the encryption layer and the transport does not get in its way, so `flow` now stays. Without encryption it is still removed when a transport is set. - **XHTTP keeps `uplinkDataPlacement=body`/`auto`.** A server with `body` or `auto` got `packet-up` added, and with an explicit `stream-one`/`stream-up` lost the placement with a false "XHTTP parameter reset" warning. Now `body`/`auto` pass as is with any mode, on every input (link, Xray, sing-box JSON); `packet-up` is required only for `header`/`cookie`. - **Latency checks no longer fail a whole batch because of one bad server.** The latency check and server diagnostics now pass the same registry guard as the working config. A server the guard would drop is marked invalid with the registry codes, the rest are checked as usual; a server whose detour was dropped is not checked. - **A server without an address is dropped on every input.** A server with an empty `server` was dropped, one without the `server` key passed. Now both are dropped with `field_missing` on parsing, in the build guard and in the latency check. ## 🔧 Under the hood - Contract with the launcher: 1.1.56. - Servers from sing-box JSON (subscription, JSON editor, Smart-Paste, detour hops) are built from the entry the registry cleaned, like links and Xray configs. The original object is kept verbatim: what the author sent still goes to the core, and backups and re-parsing see the original. - The sing-box emitters and parsing no longer keep their own copies of registry rules (`flow`, hysteria2 `obfs`, XHTTP enums and placement↔mode, uTLS/Reality on QUIC, Reality `key_share`, VLESS `encryption=none`, Shadowsocks `plugin_opts`↔`plugin`): the registry decides on parsing and in the build guard. Behaviour on normal input does not change; the `obfs` warning on a sing-box JSON server now uses the registry text, the same as for a link. - Named references in the registry schemas are resolved on load, as in the launcher. - `SECURITY.md`: private vulnerability reporting policy (EN+RU). </details> <details open> <summary><h2>🇷🇺 Русский</h2></summary> ## ✨ Добавлено - **Подсветка синтаксиса JSON.** Редактор конфига и JSON-поле мастера добавления сервера подсвечивают ключи, строки, числа и скобки; светлая или тёмная схема — по теме приложения. Вкладка JSON в настройках узла, экран просмотра узла и инспектор узлов подписки показывают JSON в том же просмотрщике с подсветкой, только чтение. ## 🔄 Изменено - **Ядро v1.14.2-lx.3.** Серверы VLESS с Vision и VLESS-шифрованием одновременно подключаются на любом транспорте, включая XHTTP; раньше каждый такой сервер падал с `vision: not a valid supported TLS connection` ([sing-box-lx#29](https://github.com/Leadaxe/sing-box-lx/issues/29)). XHTTP выбирает HTTP/1.1, HTTP/2 или HTTP/3 по `tls.alpn`, как Xray: серверы только с h3 работают, а `alpn`, который XHTTP-сервер раньше молча игнорировал, теперь меняет версию HTTP. - **Гард реестра быстрее.** Проверка серверов при сборке конфига и батчей проверки задержки занимает ~31 мкс на сервер вместо ~63: схемы и связи полей разбираются один раз, ключ base64 декодируется один раз. - **Разбор ссылок быстрее.** Ссылка разбирается за ~147 мкс вместо ~395 на смешанном корпусе: маршрут схемы и объявленные имена параметров считаются один раз на состав секций, а не на каждой строке подписки, outbound Xray сериализуется один раз. Замер на десктопе; поведение не меняется. ## 🩹 Исправления - **Ссылки hysteria2 из 3x-ui с gecko не теряют размеры пакетов.** 3x-ui пишет диапазон gecko-обфускации парой `minPacketSize`/`maxPacketSize` и добавляет `security=tls` в каждую ссылку. Раньше все три параметра шли в «не прочитан», и сервер поднимался с gecko, но с размерами по умолчанию из ядра. Теперь размеры доезжают до `obfs`, `security=tls` принимается молча, а иное значение `security` только добавляет предупреждение. - **VLESS с Vision и VLESS-шифрованием поверх XHTTP сохраняет `flow`.** Такой сервер приезжал без `flow`, и сервер с Vision рвал соединение. С шифрованием Vision работает поверх его слоя, и транспорт ему не мешает, поэтому `flow` теперь остаётся. Без шифрования он по-прежнему снимается, если задан транспорт. - **XHTTP сохраняет `uplinkDataPlacement=body`/`auto`.** Серверу с `body` или `auto` дописывался `packet-up`, а при явном `stream-one`/`stream-up` placement снимался с ложным предупреждением «параметр XHTTP сброшен». Теперь `body`/`auto` доезжают как есть при любом режиме, на всех входах (ссылка, Xray, sing-box JSON); `packet-up` обязателен только для `header`/`cookie`. - **Проверка задержки больше не падает целым батчем из-за одного плохого сервера.** Проверка задержки и диагностика сервера теперь проходят тот же гард реестра, что и рабочий конфиг. Сервер, который гард снял бы, помечается невалидным с кодами реестра, остальные проверяются как обычно; сервер со снятым detour не проверяется. - **Сервер без адреса снимается на всех входах.** Сервер с пустым `server` снимался, без ключа `server` — проходил. Теперь оба снимаются с `field_missing` на разборе, в гарде сборки и в проверке задержки. ## 🔧 Под капотом - Контракт с лаунчером: 1.1.56. - Серверы из sing-box JSON (подписка, редактор JSON, Smart-Paste, звенья detour) строятся по записи, которую очистил реестр, как ссылки и Xray-конфиги. Исходный объект хранится дословно: в ядро по-прежнему идёт то, что прислал автор, бэкап и повторный разбор видят оригинал. - Эмиттеры sing-box и разбор больше не держат своих копий правил реестра (`flow`, `obfs` у hysteria2, enum-поля и связь placement↔mode у XHTTP, uTLS/Reality на QUIC, `key_share` у Reality, `encryption=none` у VLESS, `plugin_opts`↔`plugin` у Shadowsocks): решает реестр — на разборе и в гарде сборки. На штатных входах поведение не меняется; предупреждение про `obfs` у сервера из sing-box JSON теперь с текстом из реестра, тем же, что у ссылки. - Именованные ссылки в схемах реестра разворачиваются при загрузке, как у лаунчера. - `SECURITY.md`: политика приватных сообщений об уязвимостях (EN+RU). </details> --- ## Install / Установка ```bash adb install -r LxBox-v2.25.5-arm64-v8a.apk ``` Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся. No uninstall needed — install over the existing one. Settings and subscriptions are preserved. --- Previous release / Предыдущий релиз: [v2.25.4](docs/releases/v2.25.4.md).
  • Sep 24, 2026 2.25.4
    # L×Box v2.25.4 **A patch on top of [v2.25.3](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.3).** The core moves to `v1.14.2-lx.1`. WireGuard and AmneziaWG servers no longer hold memory until traffic actually goes through them, and two new settings control this. The Ru internet segment preset now routes Russian apps by package name. The server list uses two columns on a tablet. A subscription that repeats the same server no longer shows it twice.
    More…
    **Патч поверх [v2.25.3](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.3).** Ядро обновлено до `v1.14.2-lx.1`. Серверы WireGuard и AmneziaWG больше не держат память, пока через них не пошёл трафик, и этим управляют две новые настройки. Пресет «Ru internet segment» теперь ведёт российские приложения по имени пакета. На планшете список серверов идёт в две колонки. Подписка, повторяющая один и тот же сервер, больше не показывает его дважды. --- <details open> <summary><h2>🇬🇧 English</h2></summary> ## ⚠️ Read before updating - **Duplicate servers in one subscription are collapsed.** If a subscription lists the same server several times under different names, the list keeps one server per configuration (the first one). The rest are skipped and marked `duplicate` with a “Duplicate of <name>” note. Only entries inside one subscription or one import are compared. - **At most 5 WireGuard/AmneziaWG tunnels are kept built at a time by default.** A server over the limit may show `ERR` on a latency check while it waits for a free slot, and the selected server may be torn down to free a slot. VPN Settings → System → WireGuard connections → **Built tunnels limit** → `0 (no limit)` removes the cap. ## ✨ Added - **Russian apps by package in the Ru internet segment preset.** A fourth rule set, `ru-app-list` (by legiz-ru), matches a connection by the Android package name rather than by domain or IP. Banking and government apps that go through third-party CDNs or by bare IP used to miss both the domain and the IP sets and ended up in the tunnel; now they go direct. The checkbox **Russian apps by package** is on by default; the set is downloaded when first enabled. Unchecking it leaves domains and IPs as they are ([#116](https://github.com/Leadaxe/LxBox/issues/116)). - **Two columns of servers on wide screens.** From 600 dp of window width the server list on the home screen goes into two columns; narrower screens keep one. The layout follows rotation and split screen on the fly. Manual sort stays in one column, since drag and drop only works there ([#134](https://github.com/Leadaxe/LxBox/issues/134)). - **Appearance tab in App Settings.** Theme, language and **Allow rotation** moved here from General. The Layout section also has **Two columns on wide screens** (on by default). Changes apply immediately and are included in the backup. - **Per-app summary in the log with Verbose on.** When Verbose (TRACE/DEBUG) is enabled on the Diagnostics tab, each tunnel start writes one `per-app:` line to Logs: allow or deny mode, `allow_bypass`, the packages applied and the ones not installed on the device. - **Lazy tunnel build and Built tunnels limit.** VPN Settings → System → WireGuard connections. **Lazy tunnel build** (on by default) builds a WireGuard/AmneziaWG tunnel on first use. **Built tunnels limit** sets how many stay built at once: `0 (no limit)`, 3, 5, 8, 12; default 5. Both need **Suspend idle tunnels** on; the limit also needs lazy build. Applied on the next connect. ## 🔄 Changed - **Core v1.14.2-lx.1.** A network change (Wi-Fi ↔ mobile) no longer resets the tunnel on every system notification, only on a real interface change: fewer drops on the move. The `disabled UDP GSO` lines that filled the log of a working AmneziaWG server are gone; connectivity was never affected ([#95](https://github.com/Leadaxe/LxBox/issues/95)). - **WireGuard/AmneziaWG servers take no memory until used.** Previously every WG/AWG server in storage got a device with about 17.5 MB of receive buffers at tunnel start. Now a server starts unbuilt and is built on first use. On a test setup with eleven AWG servers the core's live memory fell from 113 MB to 53 MB. The cost is half a second to a second on the first switch to a server. The Auto group probes all its members at start and builds them, so there the saving comes from the limit. - **WireGuard/AmneziaWG server state in one word.** The server row shows `up`, `sleep` or `down` instead of “Node asleep” / “Node not built yet”. The full core state and idle time are in **Endpoint state** on the Details screen from the server menu. - **Copy link follows the common scheme format.** VLESS always carries `security`, including `security=reality` (other Xray clients read its absence as “no encryption”). NaiveProxy keeps port `443`. AnyTLS writes `insecure` instead of `allowInsecure`. Shadowsocks has no trailing `=`. VLESS drops the default `fp=random`; other fingerprints are kept. TUIC writes `reduce_rtt=true` instead of `reduce_rtt=1`. Reading has not changed: links saved earlier or received from other clients parse as before. - **The preset “Russian domains & IPs” is renamed “Ru internet segment”.** The preset id is the same, saved rules expand as before. ## 🩹 Fixes - **Proxy mode no longer asks about another active VPN.** In Proxy mode (local port only, no tunnel) Start showed “Another VPN is active. Switch to L×Box?”, although the other VPN is not revoked in this mode. The question now appears only in VPN and VPN+Proxy modes ([#126](https://github.com/Leadaxe/LxBox/issues/126)). - **Duplicate servers in one subscription.** A subscription sent the same AWG server twice, as an `amneziawg://` line and as a `vpn://` link, and the list showed two identical servers. See the warning above. - **An unchecked rule set in the Ru internet segment preset no longer switches off the whole rule.** The **GeoIP IP-range fallback** and **Russian apps by package** checkboxes were only honoured by config build; the Routing screen, download and background update ignored them. An unchecked set was still downloaded, and if its file was missing, opening Routing switched off the whole preset rule. Now all of them follow the checkbox. A rule already switched off by the old behaviour stays off — turn it on once. - **Xray subscriptions parse closer to Xray itself.** WebSocket `ed`/`eh` fields that Xray does not declare there are no longer read; the proxy address is no longer put into the TLS server name when the author did not set one; the WebSocket host written as a separate field is no longer lost; negative keep-alive intervals are read as Xray reads them. An Xray element with a foreign protocol version no longer yields a server the provider did not send. - **VMess Copy link without a transport** lost the server address; fixed. - **`proxy-https://…?security=none`** no longer keeps a TLS block and goes out as a plain HTTP proxy, including in Copy link. ## 🔧 Under the hood - Contract with the launcher: 1.1.53. The protocol registry engine runs three primitives exactly as the reference does; server bodies and identities did not change. - Debug API `/state` returns `endpoint_states`. </details> <details open> <summary><h2>🇷🇺 Русский</h2></summary> ## ⚠️ Прочтите до обновления - **Повторы сервера в одной подписке схлопываются.** Если подписка перечисляет один и тот же сервер несколько раз под разными именами, в списке остаётся по одному серверу на конфигурацию (первый). Остальные отбрасываются и помечаются `duplicate` с пояснением «Duplicate of <имя>». Сравниваются только записи внутри одной подписки или одного импорта. - **По умолчанию собранными держатся не больше 5 туннелей WireGuard/AmneziaWG.** Сервер сверх лимита, ожидающий слота, может показать `ERR` при проверке задержки, а выбранный сервер может быть разобран ради слота. VPN Settings → System → WireGuard connections → **Built tunnels limit** → `0 (no limit)` снимает потолок. ## ✨ Добавлено - **Российские приложения по имени пакета в пресете «Ru internet segment».** Четвёртый набор правил, `ru-app-list` (автор legiz-ru), сопоставляет соединение с именем Android-пакета, а не с доменом или IP. Банковские и государственные приложения, которые ходят через сторонние CDN или по голому IP, промахивались мимо наборов доменов и IP и уходили в туннель; теперь идут напрямую. Галка **Russian apps by package** по умолчанию включена, набор скачивается при первом включении. Снятая галка не трогает домены и IP ([#116](https://github.com/Leadaxe/LxBox/issues/116)). - **Две колонки серверов на широком экране.** От 600 dp ширины окна список серверов на главном экране идёт в две колонки, уже — в одну. Раскладка меняется на лету при повороте и split-screen. Ручная сортировка остаётся в одну колонку: перетаскивание работает только в ней ([#134](https://github.com/Leadaxe/LxBox/issues/134)). - **Вкладка Appearance в App Settings.** Тема, язык и **Allow rotation** переехали сюда из General. В секции Layout там же **Two columns on wide screens** (по умолчанию включено). Применяется сразу и попадает в бэкап. - **Сводка per-app в логе при Verbose.** При включённом Verbose (TRACE/DEBUG) на вкладке Diagnostics каждый подъём туннеля пишет в Logs одну строку `per-app:`: режим белого или чёрного списка, `allow_bypass`, применённые пакеты и те, что не установлены на устройстве. - **Lazy tunnel build и Built tunnels limit.** VPN Settings → System → WireGuard connections. **Lazy tunnel build** (по умолчанию включён) собирает туннель WireGuard/AmneziaWG при первом использовании. **Built tunnels limit** задаёт, сколько туннелей держать собранными одновременно: `0 (no limit)`, 3, 5, 8, 12; по умолчанию 5. Оба пункта требуют включённого **Suspend idle tunnels**, лимит — ещё и ленивой сборки. Применяется при следующем подключении. ## 🔄 Изменено - **Ядро v1.14.2-lx.1.** Смена сети (Wi-Fi ↔ мобильная) больше не сбрасывает туннель на каждом системном оповещении — только при настоящей смене интерфейса: меньше разрывов на ходу. Строки `disabled UDP GSO`, которыми был забит лог работающего AmneziaWG-сервера, ушли; на связь они не влияли ([#95](https://github.com/Leadaxe/LxBox/issues/95)). - **Серверы WireGuard/AmneziaWG не занимают память, пока не используются.** Раньше при старте туннеля каждый WG/AWG-сервер в хранении получал устройство с приёмными буферами около 17,5 МБ. Теперь сервер стартует разобранным и собирается при первом обращении. На стенде с одиннадцатью AWG-серверами живая память ядра упала со 113 до 53 МБ. Плата — полсекунды-секунда на первом переключении на сервер. Группа Auto при старте проверяет всех членов и этим их собирает, так что в ней экономию даёт лимит. - **Состояние сервера WireGuard/AmneziaWG одним словом.** Строка сервера пишет `up`, `sleep` или `down` вместо «Node asleep» / «Node not built yet». Полное состояние ядра и время простоя — в строке **Endpoint state** на экране Details из меню сервера. - **Copy link приведён к общему формату схем.** VLESS всегда несёт `security`, в том числе `security=reality` (чужие Xray-клиенты читают его отсутствие как «без шифрования»). NaiveProxy не опускает порт `443`. AnyTLS пишет `insecure` вместо `allowInsecure`. Shadowsocks — без хвостовых `=`. VLESS не пишет дефолтный `fp=random`, прочие отпечатки остаются. TUIC пишет `reduce_rtt=true` вместо `reduce_rtt=1`. Чтение не изменилось: ссылки, сохранённые раньше или присланные другими клиентами, разбираются как прежде. - **Пресет «Russian domains & IPs» переименован в «Ru internet segment».** Идентификатор прежний, сохранённые правила разворачиваются как раньше. ## 🩹 Исправления - **В режиме Proxy приложение больше не спрашивает про другой VPN.** В режиме Proxy (только локальный порт, без туннеля) Start показывал «Another VPN is active. Switch to L×Box?», хотя соседний VPN в этом режиме не отзывается. Теперь вопрос задаётся только в режимах VPN и VPN+Proxy ([#126](https://github.com/Leadaxe/LxBox/issues/126)). - **Повторы сервера в одной подписке.** Подписка присылала один AWG-сервер дважды — строкой `amneziawg://` и ссылкой `vpn://`, и в списке стояли два одинаковых сервера. См. предупреждение выше. - **Снятая галка набора в пресете «Ru internet segment» больше не выключает всё правило.** Галки **GeoIP IP-range fallback** и **Russian apps by package** слушала только сборка конфига; экран Routing, скачивание и фоновое обновление их не видели. Набор со снятой галкой всё равно скачивался, а если его файла не было — при открытии Routing выключалось всё правило пресета. Теперь галку слушают все. Правило, уже выключенное прежним поведением, само не включится — включите его один раз. - **Подписки Xray разбираются ближе к самому Xray.** Поля WebSocket `ed`/`eh`, которых Xray в этом месте не объявляет, больше не читаются; адрес прокси не подставляется в имя сервера TLS, если автор его не задал; хост WebSocket, записанный отдельным полем, не теряется; отрицательные интервалы keep-alive читаются так же, как у Xray. Элемент Xray с чужой версией протокола больше не даёт сервер, которого провайдер не присылал. - **Copy link у VMess без транспорта** терял адрес сервера; исправлено. - **`proxy-https://…?security=none`** больше не сохраняет блок TLS и уходит обычным HTTP-прокси, в том числе по Copy link. ## 🔧 Под капотом - Контракт с лаунчером: 1.1.53. Движок реестра протоколов исполняет три примитива так же, как эталон; тела и подписи серверов не изменились. - Debug API `/state` отдаёт `endpoint_states`. </details> --- ## Install / Установка ```bash adb install -r LxBox-v2.25.4-arm64-v8a.apk ``` Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся. No uninstall needed — install over the existing one. Settings and subscriptions are preserved. --- Previous release / Предыдущий релиз: [v2.25.3](docs/releases/v2.25.3.md).
  • Sep 24, 2026 2.25.2
    # L×Box v2.25.2 **A patch on top of [v2.25.1](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.1).** The main body of changes is in [v2.25.0](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.0) — one parsing engine shared with [singbox-launcher 2.0.0](https://github.com/Leadaxe/singbox-launcher/releases/tag/v2.0.0), and the **Start** insurance when the core refuses a server. Read those first; this patch does not repeat them.
    More…
    This patch is about subscriptions that used to come back short — and about not being left in the dark when they do. Links providers actually write are read instead of silently vanishing; a line the app cannot use says why. A decoy banner from an expired subscription is no longer offered as a server, and a transport the core does not speak is refused honestly instead of connecting to nothing. **Патч поверх [v2.25.1](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.1).** Основной корпус изменений — в [v2.25.0](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.0): один движок разбора с [лаунчером 2.0.0](https://github.com/Leadaxe/singbox-launcher/releases/tag/v2.0.0) и страховка кнопки **Start**, когда ядро отказывается от сервера. Сначала читайте их — этот патч их не повторяет. Этот патч про подписки, которые приезжали короче, чем есть, — и про то, чтобы не оставлять в тишине, когда так вышло. Ссылки в том написании, в котором их пишут провайдеры, читаются, а не исчезают молча; строка, которую приложение не может использовать, называет причину. Баннер-обманка истёкшей подписки больше не выдаётся за сервер, а транспорт, которого ядро не знает, честно отбраковывается вместо соединения в никуда. --- <details open> <summary><h2>🇬🇧 English</h2></summary> ## 🩹 Fixes ### Subscriptions and links - **`amneziawg://` links no longer disappear.** Panels spell the AmneziaWG scheme out in full, and lines written that way used to vanish whole — every field in them was already readable, but the list of known schemes lived in the code as literals and did not include the long spelling. - **A `vpn://` link holding a plain WireGuard config gives a server.** Under the wrapper there may be not only an Amnezia profile but the `wg-quick` / AmneziaWG config itself. Such a link used to yield zero servers with a message about zlib that sent you looking for a fault that was not there. - **A subscription that is a single Xray configuration** — one object rather than a list — is read as one server instead of yielding nothing. - **Hysteria2 keeps its bandwidth and its Salamander obfuscation.** A speed written as a string with a unit (`"100mbps"`) was dropped without a word, and the obfuscation was lost together with its password, so the server arrived and would not come up. The `up` / `down` spelling the official client uses now arrives too. - **A provider panel's decoy banner is no longer taken for a server.** When a subscription has expired, panels return not an empty body but a syntactically valid link to nowhere (`0.0.0.0:1`, `127.0.0.1:1080`) with the explanation in the remark after `#` — and when the traffic quota is used up, that entry can be the only one. What is judged now is the destination: an entry whose address cannot belong to a server stays out of the list, and the provider's own text reaches you as the reason. - **A transport the core does not speak is refused instead of being swapped out.** `network: kcp` / `quic` used to reach the core verbatim, the sanitiser stripped the transport silently, and the server came out as working plain TCP — a server expecting mKCP will not accept that connection, and you saw no reason why. - **TCP header obfuscation (`headerType=http`) refuses the server.** It used to be carried over into the `http` transport, which for the core means HTTP/2 — a different protocol on the wire: a server expecting camouflage received an h2 handshake and dropped the connection. The server looked healthy and did not work. Real `http` transport (spelled out as `type=http`) is unaffected. - **A socks password is no longer lost.** v2rayN always writes a socks link as `base64("user:pass")`, and parsing split the string on a `:` that is not there: the name became the whole base64 string and the password vanished silently. - **`wireguard`, `socks` and `http` elements inside an Xray configuration are no longer dropped.** No section recognised them and the server disappeared entirely, even though the core has every field they need. - **ALPN from an Xray configuration reaches the server.** It is part of the handshake: a server with nothing to pick from what was offered drops the connection, so a node facing an h2-only server simply did not work. - **A number in `alpn` or `server_ports` no longer takes down the whole configuration.** A node from sing-box JSON with `"alpn": [443, "h2"]` reached the core as written and the core refused to start at all. A non-string element is now removed with a warning on that server, and its valid neighbours stay. - **"No servers found" no longer keeps the reason to itself.** A subscription line whose protocol the app does not know, a link over the allowed length, and a body that could not be read at all now each name their reason in the notifications list, with the protocol spelled out instead of an empty list. An unknown scheme and an unreadable body no longer both report themselves as "protocol" — each has its own reason now. - **Service lines that provider panels add are skipped quietly.** Routing commands addressed to neighbouring clients (`incy://routing/…`, `happ://routing/…`) are not servers: a healthy subscription used to show five refusals alongside working servers. ### Workspaces - **Switching a workspace no longer overwrites the subscriptions in all of them.** If a subscription refresh was in flight at the moment of the switch — by hand from ⟳, on the hourly timer, on return from the background, or after the VPN was turned off — the outgoing workspace's screen would write its own subscriptions into the workspace that had just loaded. Every workspace was left with a single subscription, the last one refreshed, and the loss was committed to disk. A refresh is now halted before the switch, and a write from the outgoing workspace is rejected. Workspaces already overwritten are not restored by this fix — only a backup can do that. ### Start insurance - **Servers with the same name no longer cut the run short.** Two unusable servers sharing a name were being switched off one per press: after the first went off its name passed to the second, the state machine read that as "the same server again", and the VPN never came up. A repeat is now recognised by the server itself, not by its name. - **Stop during a server check no longer brings the VPN back.** A stop that did not come from the main screen's button — Debug API, the Quick Settings tile, the Intent API, Tasker/Locale — left the check running, and a few seconds later the insurance raised the tunnel by itself. Any Stop now cancels it. - **The "disabled by insurance" list opens the server you tapped.** When several servers shared a refusal reason, or two servers in a folder shared a name, tapping a row could open a different server's screen. ### Servers screen - **Deleting a row no longer shifts its neighbours.** From a list of `u1, c1, u2, c2` you would delete the chain `c1` and get `u1, c2, u2`: a record of the same kind slid into the freed slot and jumped over a server. Slots are now matched by key, not by position. - **Drag works when the storage holds a record the app cannot read.** Any drag used to roll back silently — the row jumped home. The visible records now reorder, and the unreadable one keeps its slot. - **A new row at the end of a long list is no longer hidden under the SnackBar.** A new record is appended at the tail, and the tail only scrolled as far as the bottom padding, so the "New" row was covered by the config-rebuild message. The list now keeps room below. - **The highlight on a new row is dropped when the row is deleted.** Deleting within the seven seconds after adding — from the menu, or on a subscription refresh — left the highlight bound to a dead record, and the screen kept accumulating keys of deleted rows until it was closed. - **LX Backup: importing keeps the source order from the file.** A hop chain sitting between servers in the file moved to the head of the list after import, because chains and sources were written separately. New records now take the file's order. ### Config editor and DNS - **Config editor: a selection no longer collapses when the menu appears.** A long tap on the text opened the menu through a modal route, which took focus away from the editor: the selection collapsed to a caret, and Copy put the line under the caret into the clipboard instead of the fragment you had selected. The menu now lives in an overlay bound to the editor — the selection survives while the menu is on screen, and Cut / Copy / Paste / Select all work on the real range. Both screens with an editor are covered: the shared config and the add-server wizard. - **The `dns_shield` DNS preset no longer resolves in the clear.** The group was set to `mode: fastest` — the query goes to every member at once, and plain UDP with no TLS handshake almost always wins the race against DoH/DoT: the "shield" regularly answered from an open resolver, and the UDP query was visible to an observer even when an encrypted member won. `google_udp`, `cloudflare_udp`, `opendns_udp` and `yandex_udp` are out of the group; the first three already had an encrypted twin there, and an `opendns_doh` entry was added for OpenDNS. The `*_udp` servers themselves stay in the list — hints and resolver defaults point at them and you can still pick them. Existing configurations are not rewritten automatically: the new composition applies to fresh installs and on the next config build. ### Stability - **"Check all servers" no longer crashes the app on naive servers.** The check gathered every server in the list into one temporary configuration and raised it in one go. For naive that is disproportionately expensive: the core builds a full Chromium network stack for each such server, in the same process as the interface — a list with several naive servers hit the core's memory ceiling and the process was killed, which from outside looked like the app crashing. Naive servers are now checked in batches, one per configuration: the session is shut down after each batch and the engines are freed before the next. Other protocols are checked as before, in a single configuration; the order and completeness of the check are unchanged. ## 🔧 Under the hood Contract mirror 1.1.49 → 1.1.52: six parsing norms became executable, and the scheme set is now taken from the contract registry rather than from literals in the code — so a spelling that arrives with the contract works without a code change. A manually chosen member of an imported `selector` group survives the import → backup → import round trip, and an unread key inside `settings` / `streamSettings` now gets a note instead of vanishing without a trace. The socks4 link form changed to `userid:@host` — version 4 has no password by protocol, but clients always write the separator, and some of them read its absence as "no name". ## 🧪 Tests CI `checks` (analyze, the full test suite, four l10n checkers, docs parity) is the release gate. This patch's additions: parsing without a silent loss on any path, seven regression tests on the workspace switch, the insurance identity tests, mixed `sources[]` order on import, and the widget test for the new-row highlight. ## 📚 Documentation The diagnostics and Debug API pages, the guard list and the architecture notes were brought back in line with the code after the v2.25.1 review. Google Play's "edge-to-edge display" recommendation was traced to its source: the app makes no calls to the APIs disabled on Android 15 — the references the static scanner finds come from the Flutter embedding, where they already sit behind an `SDK_INT < 35` runtime gate. No code changed. </details> <details open> <summary><h2>🇷🇺 Русский</h2></summary> ## 🩹 Исправления ### Подписки и ссылки - **Ссылки `amneziawg://` больше не теряются.** Панели пишут полное имя схемы AmneziaWG, и такие строки исчезали целиком: все их поля приложение читать умело, но список схем лежал в коде литералами и полного написания не знал. - **`vpn://` с голым `.conf` внутри даёт узел.** Под обёрткой бывает не только профиль Amnezia, но и сам конфиг `wg-quick` / AmneziaWG — прежде такая ссылка давала ноль узлов с сообщением про zlib, которое уводило искать несуществующую поломку. - **Подписка из одного конфига Xray** — одного объекта, а не списка — читается как один сервер, а не даёт ноль. - **Hysteria2 сохраняет полосу и обфускацию Salamander.** Скорость, записанную строкой с единицей (`"100mbps"`), узел терял молча, а обфускацию вместе с паролём — целиком, из-за чего узел приезжал и не поднимался. Написание `up` / `down` официального клиента теперь тоже доезжает. - **Баннер-обманка панели провайдера больше не считается сервером.** При истёкшей подписке панели отдают не пустое тело, а синтаксически валидную ссылку в никуда (`0.0.0.0:1`, `127.0.0.1:1080`) и кладут объяснение в ремарку после `#`; при исчерпанном трафике такая запись бывает единственной. Теперь судится цель: запись с адресом, который сервером не бывает, в список не идёт, а текст провайдера доезжает до человека причиной. - **Узел с транспортом, которого ядро не знает, отбраковывается вместо подмены.** `network: kcp` / `quic` уезжал в ядро дословно, санитайзер снимал транспорт молча, и узел выходил рабочим plain-TCP — сервер, который ждёт mKCP, такое соединение не примет, а причины человек не видел. - **Обфускация TCP-заголовком (`headerType=http`) отбраковывает узел.** Прежде она переносилась в транспорт `http`, а у ядра это HTTP/2 — на проводе другой протокол: сервер, ждущий камуфляж, получал h2-рукопожатие и обрывал соединение. Узел выглядел рабочим и не работал. Настоящий транспорт `http` (`type=http` прямым текстом) не затронут. - **Пароль socks больше не теряется.** v2rayN пишет socks-ссылку как `base64("user:pass")` всегда, а разбор резал строку по `:`, которого в ней нет: имя становилось всей base64-строкой, пароль исчезал молча. - **Элементы `wireguard`, `socks` и `http` внутри конфига Xray больше не пропадают.** Ни одна секция их не опознавала, и узел исчезал целиком — при том, что все нужные поля у ядра есть. - **ALPN из конфига Xray доезжает до узла.** Он есть часть рукопожатия: сервер, которому нечего выбрать из предложенного, соединение обрывает, то есть узел с h2-only сервером просто не работал. - **Число в `alpn` или `server_ports` больше не роняет весь конфиг.** Узел из sing-box JSON с `"alpn": [443, "h2"]` уезжал в ядро как есть, и ядро отказывалось стартовать целиком. Нестроковый элемент теперь снимается с предупреждением на узле, годные соседи остаются. - **«Серверов не найдено» больше не молчит о причине.** Строка подписки, чей протокол приложение не знает, ссылка сверх допустимой длины и тело, которое не удалось разобрать вовсе, теперь называют причину в списке уведомлений — с именем протокола, а не пустым списком. Незнакомая схема и нераспознанное тело больше не сообщают о себе одним словом «протокол»: у каждого своя причина. - **Служебные строки панелей пропускаются молча.** Команды маршрутизации соседним клиентам (`incy://routing/…`, `happ://routing/…`) узлами не являются: у исправной подписки человек читал пять отказов при живых узлах. ### Workspaces - **Переключение пространства больше не подменяет подписки во всех пространствах.** Если в момент переключения шло обновление подписок — вручную по ⟳, по часовому таймеру, на возврате из фона или после отключения VPN, — экран прежнего пространства успевал записать свои подписки в уже загруженное новое. Во всех пространствах оставалась одна подписка, последняя обновлённая, и потеря закреплялась на диске. Обновление теперь прерывается до переключения, а запись от прежнего пространства отклоняется. Уже перезаписанные пространства фикс не восстанавливает — только бэкап. ### Страховка Start - **Узлы-тёзки больше не обрывают прогон.** Два негодных сервера с одним именем выключались по одному за нажатие: после выключения первого имя доставалось второму, автомат принимал его за «тот же сервер повторно», и VPN не поднимался. Повтор теперь опознаётся по самому серверу, а не по имени. - **Stop во время проверки серверов больше не поднимает VPN обратно.** Остановка не кнопкой на главном экране — Debug API, плитка Quick Settings, Intent API, Tasker/Locale — не отменяла идущую проверку, и через несколько секунд страховка сама запускала туннель. Теперь любой Stop её отменяет. - **Лист «выключено страховкой» открывает тот сервер, по которому тапнули.** При одинаковой причине отказа у нескольких серверов или у одноимённых серверов в папке тап по строке открывал экран другого сервера. ### Экран Servers - **Удаление записи больше не сдвигает соседей.** Из списка `u1, c1, u2, c2` удаляли цепочку `c1` и получали `u1, c2, u2`: запись того же рода съезжала в освободившийся слот и перепрыгивала сервер. Слоты теперь сопоставляются по ключу, а не по позиции. - **Перетаскивание работает при нечитаемой записи в хранилище.** Любой drag молча откатывался — строка прыгала на старое место. Теперь видимые записи переставляются, нечитаемая остаётся в своём слоте. - **Новая запись в конце длинного списка больше не под SnackBar.** Запись добавляется в хвост, а хвост прокручивался только до нижнего отступа — строку с меткой «New» закрывало сообщение о пересборке конфига. Теперь у списка есть запас снизу. - **Подсветка новой записи снимается, если запись удалили.** Удаление в течение семи секунд после добавления (из меню или при обновлении подписки) оставляло подсветку привязанной к мёртвой записи, а экран копил ключи удалённых строк до закрытия. - **LX Backup: импорт сохраняет порядок источников из файла.** Цепочка, стоявшая в файле между серверами, после импорта уезжала в голову списка: цепочки и источники записывались по отдельности. Новые записи теперь встают в порядке файла. ### Редактор конфига и DNS - **Редактор конфига: выделение больше не слетает при показе меню.** Долгий тап по тексту открывал меню через модальный маршрут — тот забирал у редактора фокус, выделение схлопывалось в каретку, и Copy уносил в буфер не выделенный фрагмент, а строку под кареткой. Меню переехало в оверлей, привязанный к редактору: выделение живёт, пока меню на экране, а Cut / Copy / Paste / Select all работают с настоящим диапазоном. Затронуты оба экрана с редактором — общий конфиг и мастер добавления сервера. - **Пресет DNS `dns_shield` больше не резолвит открытым текстом.** В группе стоял `mode: fastest` — запрос уходит всем членам сразу, а открытый UDP без TLS-рукопожатия почти всегда выигрывает гонку у DoH/DoT: «щит» регулярно отвечал из открытого резолвера, и запрос по UDP всё равно был виден наблюдателю, даже когда побеждал шифрованный член. Из группы убраны `google_udp`, `cloudflare_udp`, `opendns_udp` и `yandex_udp`; у первых трёх шифрованный двойник в группе уже был, для OpenDNS добавлена запись `opendns_doh`. Сами серверы `*_udp` остались в списке — на них ссылаются подсказки и дефолты резолверов, выбрать их по-прежнему можно. Существующие конфиги автоматически не переписываются: новый состав применяется к новым установкам и при следующей сборке конфига. ### Стабильность - **«Проверка на всех серверах» больше не роняет приложение на naive-узлах.** Проверка собирала все узлы списка в один временный конфиг и поднимала его разом. У naive это несоразмерно дорого: ядро создаёт полный сетевой стек Chromium на каждый такой узел, в том же процессе, что интерфейс, — список с несколькими naive-узлами упирался в лимит памяти ядра и процесс убивало, снаружи это выглядело как падение приложения. Теперь naive-узлы проверяются порциями, по одному на конфиг: сессия гасится после каждой порции и движки освобождаются до следующей. Остальные протоколы проверяются как прежде, одним конфигом; порядок и полнота проверки не изменились. ## 🔧 Под капотом Зеркало контракта 1.1.49 → 1.1.52: шесть норм разбора стали исполняемыми, а набор схем берётся из реестра контракта, а не из литералов в коде — поэтому написание, приехавшее контрактом, работает без правки кода. Выбранный вручную член импортированной группы `selector` доживает круг «импорт → бэкап → импорт», а непрочитанный ключ внутри `settings` / `streamSettings` получает ноту вместо исчезновения без следа. Вид ссылки socks4 сменился на `userid:@host`: пароля у версии 4 нет по протоколу, но разделитель клиенты пишут всегда, и его отсутствие часть из них читает как «имени нет». ## 🧪 Тесты Релизный гейт — CI `checks` (analyze, полный набор тестов, четыре l10n-чекера, паритет доков). Добавленное этим патчем: разбор без молчаливой потери на любом пути, семь регресс-тестов на переключение пространства, тесты идентичности в страховке, смешанный порядок `sources[]` при импорте и виджет-тест подсветки новой записи. ## 📚 Документация Страницы диагностики и Debug API, список гардов и заметки по архитектуре приведены в соответствие с кодом после ревью v2.25.1. Рекомендация Google Play «Отображение от края до края» разобрана до причины: своих вызовов отключённых на Android 15 API у приложения нет — ссылки, которые находит статический сканер, приходят из эмбеддинга Flutter, и там они уже закрыты рантайм-гейтом `SDK_INT < 35`. Кода не меняли. </details> --- ## Install / Установка ```bash adb install -r LxBox-v2.25.2-arm64-v8a.apk ``` Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся. No uninstall needed — install over the existing one. Settings and subscriptions are preserved. --- Previous release / Предыдущий релиз: [v2.25.1](docs/releases/v2.25.1.md). The main body of changes is in / Основной корпус изменений — [v2.25.0](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.0).
  • Sep 20, 2026 2.25.1
    # L×Box v2.25.1 **Three fixes on top of [v2.25.0](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.0).** That release is the main body of changes: one parsing engine with [singbox-launcher 2.0.0](https://github.com/Leadaxe/singbox-launcher/releases/tag/v2.0.0) (contract 1.1.46), and the **Start** insurance when the core refuses a server ([#147](https://github.com/Leadaxe/LxBox/issues/147)). Read it first — this patch does not repeat it. This patch: Stats → Memory breakdown shows PSS figures again; XHTTP extra keeps
    More…
    `sessionIDPlacement` / `sessionIDKey`; a hop chain on Servers stays between the rows you drop it among. **Три правки поверх [v2.25.0](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.0).** Основной корпус изменений — там: один движок разбора с [лаунчером 2.0.0](https://github.com/Leadaxe/singbox-launcher/releases/tag/v2.0.0) (контракт 1.1.46) и страховка кнопки **Start**, когда ядро отказывается от сервера ([#147](https://github.com/Leadaxe/LxBox/issues/147)). Сначала читайте 2.25.0 — этот патч его не повторяет. В этом патче: в Stats → Memory разбивка PSS снова с цифрами; XHTTP extra сохраняет `sessionIDPlacement` / `sessionIDKey`; цепочка на Servers остаётся между строками, куда её поставили. --- <details open> <summary><h2>🇬🇧 English</h2></summary> ## 🩹 Fixes | § | Before | Now | |---|---|---| | [507](docs/spec/tasks/507-stats-memory-breakdown-zeros.md) | After v2.25.0 the Stats → Memory sheet still showed RSS and native-heap malloc counters, but the Breakdown section (Java / Native / Graphics / Code / Stack / System / Other) was all `0 B`. `Debug.getMemoryInfo` no longer fills `summary.*` PSS categories on Android 10+ | The snapshot comes from `ActivityManager.getProcessMemoryInfo`. If AMS is empty, the old call is the fallback; empty `summary.*` categories fall back to `dalvikPss` / `nativePss` / `otherPss` / `totalPss` | | [508](docs/spec/tasks/508-xhttp-sessionid-aliases.md) | A live vless+xhttp link parsed, and `seqPlacement` from `extra` arrived, but Xray proto names `sessionIDPlacement` / `sessionIDKey` were dropped. The core then put the session id in the path (its default), while the server looked for a cookie with a custom key | Those aliases map to `session_placement` / `session_key` (in `extra` and as flat query params). Canonical names still win. `sessionIDLength` / `sessionIDTable` are not mapped — `"0"` without a table means unset. Overlay until the launcher registry takes the alias ([launcher #131](https://github.com/Leadaxe/singbox-launcher/issues/131)) | | [509](docs/spec/tasks/509-mixed-source-reorder.md) | Servers draws subscriptions, servers, folders and hop chains in one list, but a drop wrote two blocks: chains were saved at the tail of `sources[]` and jumped back down | A mixed drag writes the array as shown. Chain records keep their slots among the other kinds. The “a hop may only point at a chain above” rule is unchanged — it is computed over the chains’ mutual order | ## 🧪 Tests CI `checks` (analyze, the full test suite, four l10n checkers, docs parity) is the release gate. Locally: `xhttp_test` for the proto aliases, `chains_storage_test` and `lx_backup_test` for mixed `sources[]` order. </details> <details open> <summary><h2>🇷🇺 Русский</h2></summary> ## 🩹 Исправления | § | Было | Стало | |---|---|---| | [507](docs/spec/tasks/507-stats-memory-breakdown-zeros.md) | После v2.25.0 шторка Stats → Memory по-прежнему показывала RSS и malloc-счётчики native heap, а секция Breakdown (Java / Native / Graphics / Code / Stack / System / Other) была сплошными `0 B`. `Debug.getMemoryInfo` на Android 10+ больше не заполняет категории PSS `summary.*` | Снимок берётся у `ActivityManager.getProcessMemoryInfo`. Если AMS пуст — запасной прежний вызов; пустые `summary.*` подставляют `dalvikPss` / `nativePss` / `otherPss` / `totalPss` | | [508](docs/spec/tasks/508-xhttp-sessionid-aliases.md) | Живая vless+xhttp ссылка разбиралась, `seqPlacement` из `extra` доезжал, а proto-имена Xray `sessionIDPlacement` / `sessionIDKey` терялись. Ядро клало session id в path (свой дефолт), сервер искал cookie с кастомным ключом | Алиасы мапятся в `session_placement` / `session_key` (в `extra` и в плоском query). Канон сильнее proto-имени. `sessionIDLength` / `sessionIDTable` не мапятся: `"0"` без таблицы — «не задано». Оверлей, пока реестр лаунчера не заберёт алиас ([лаунчер #131](https://github.com/Leadaxe/singbox-launcher/issues/131)) | | [509](docs/spec/tasks/509-mixed-source-reorder.md) | Servers рисует подписки, серверы, папки и цепочки одним списком, но drop писал два блока: цепочки сохранялись хвостом `sources[]` и возвращались вниз | Смешанный drag пишет массив как на экране. Записи цепочек держат свои слоты среди остальных родов. Инвариант «хоп ссылается только на цепочку выше» не менялся — он считается по взаимному порядку цепочек | ## 🧪 Тесты Релизный гейт — CI `checks` (analyze, полный набор тестов, четыре l10n-чекера, паритет доков). Локально: `xhttp_test` на proto-алиасы, `chains_storage_test` и `lx_backup_test` на смешанный порядок `sources[]`. </details> --- ## Install / Установка ```bash adb install -r LxBox-v2.25.1-arm64-v8a.apk ``` Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся. No uninstall needed — install over the existing one. Settings and subscriptions are preserved. --- Previous release / Предыдущий релиз: [v2.25.0](docs/releases/v2.25.0.md). The main body of changes is there / Основной корпус изменений — там: [GitHub Release v2.25.0](https://github.com/Leadaxe/LxBox/releases/tag/v2.25.0).
  • Sep 17, 2026 2.24.0
  • Sep 16, 2026 2.23.2
  • Sep 11, 2026 2.23.1
  • Sep 9, 2026 2.23.0