Releases: eleutherifer/LxBox
Release list
LxBox v2.25.9
L×Box v2.25.9
A patch on top of v2.25.8.
Core v1.14.2-lx.11: Tailscale nodes pass traffic to peers over a direct path
again and reach the coordination server over port 443 from the start. Repeats
of one server in a subscription are merged with a note on the node that stays.
Preset rules follow the template contract more strictly: a rule written
without conditions is kept, a rule that lost its conditions is dropped. Xray
JSON arrays with a balancer name pool servers by selector. Protocol contract
1.1.107.
Патч поверх v2.25.8.
Ядро v1.14.2-lx.11: узлы Tailscale снова передают трафик пирам по прямому
пути и с первого соединения ходят к серверу координации через порт 443.
Повторы одного сервера в подписке схлопываются с пометкой на оставшемся узле.
Правила пресетов строже следуют контракту шаблонов: правило, написанное без
условий, остаётся, правило, потерявшее условия, выпадает. Xray JSON-массивы с
балансировщиком собирают пул по selector. Контракт протоколов 1.1.107.
🇬🇧 English
🔄 Changed
-
Core
v1.14.2-lx.11. Two Tailscale fixes. A node that found a direct UDP
path to a peer (for example, both on the same Wi-Fi) could see and ping the
peer, but TCP connections to it timed out; traffic now goes over the direct
path, and WireGuard and AmneziaWG nodes send the same bytes as before. The
channel to the Tailscale coordination server now always uses HTTPS on port
443: behind DPI that freezes port 80, a node no longer loses the
coordination server for about 15 minutes after every start.
Synced with sing-boxstable: stricter checks of incoming protocol data
(sniffers, FakeIP, the TUN stack, transports), and a UDP checksum that
comes out as 0 is written as0xffff, so such packets are no longer
dropped. -
Repeated servers in a subscription. Providers often list one server many
times under different names. The app keeps one node, as before, and now
marks it with an info note «Repeats of this server in the subscription: N»
that names the merged entries. The subscription summary shows «M duplicates
merged into K nodes» on its own line; «entries dropped» no longer counts
them. -
Preset rules without conditions. A route or DNS rule of a preset that
the author wrote without conditions (for example, a bare
{"action": "sniff"}) now goes into the config, with the build warning
«Rule from … matches everything». A rule whose conditions were removed by a
failure is still dropped with «Entry … left out»: a variable without a value,
an undeclared variable name, or rule sets none of which made it into the
config. The same applies to sub-rules of a logical rule at any depth: one
sub-rule that lost its conditions drops the whole logical rule. -
Rule sets that were not downloaded. Your own DNS rule whose every
rule_setpoints to a set missing from the config (for example, a remote
.srsthat was not downloaded) is left out with a build warning instead of
going to the core without its condition. A missing name next to live ones
is removed from the list. A DNS rule by an.srsfile without a cached
copy is reported the same way instead of being skipped silently. -
Preset variables are optional by default. A variable without
required
is no longer required, as in the launcher. The built-in template marks its
required variables explicitly, so presets behave as before. -
Xray JSON arrays with a balancer. The group keeps the element's
remarks; each server of the pool is namedremarks tag. A name already
taken in the element (by the group or by an earlier server) gets the
server's number in the pool:pool p,pool p 2,pool 3. Pool members
are the servers the balancer'sselectorpicks by tag prefix; a server it
does not pick stays a separate node.leastLoadwithoutexpectedselects
the fastest server. When one server of the element is merged with another,
the group points to the node that stays.
🔧 Under the hood
- Contract with the launcher: 1.1.107. Its copy is now in the repository, so
CI checks the parsing corpus and the schemas on every push. - Feature specifications rewritten from the code (EN+RU).
🇷🇺 Русский
🔄 Изменено
-
Ядро
v1.14.2-lx.11. Два исправления Tailscale. Узел, нашедший прямой
UDP-путь к пиру (например, оба в одной Wi-Fi), видел и пинговал пира, но
TCP-соединения к нему обрывались по таймауту; теперь трафик идёт по прямому
пути, а узлы WireGuard и AmneziaWG отправляют те же байты, что и раньше.
Канал к серверу координации Tailscale теперь всегда идёт по HTTPS на порт
443: за DPI, который замораживает порт 80, узел больше не теряет
координатора примерно на 15 минут после каждого старта.
Синхронизировано соstablesing-box: строже проверка входящих данных
протоколов (сниферы, FakeIP, TUN-стек, транспорты), а контрольная сумма
UDP, равная 0, пишется как0xffff, и такие пакеты больше не
отбрасываются. -
Повторы сервера в подписке. Провайдеры часто кладут один сервер много
раз под разными именами. Приложение, как и раньше, оставляет один узел и
теперь ставит на нём info-пометку «Повторов этого сервера в подписке: N» с
именами схлопнутых записей. Сводка подписки показывает «M duplicates merged
into K nodes» отдельной строкой; «entries dropped» их больше не считает. -
Правила пресетов без условий. Правило маршрута или DNS из пресета,
которое автор написал без условий (например, голый{"action": "sniff"}),
теперь попадает в конфиг с предупреждением сборки «Rule from … matches
everything». Правило, условия которого снял сбой, по-прежнему выпадает с
«Entry … left out»: переменная без значения, необъявленное имя переменной
или наборы правил, ни один из которых не попал в конфиг. То же для
под-правил логического правила на любой глубине: одно под-правило,
потерявшее условия, снимает всё логическое правило. -
Нескачанные наборы правил. Своё DNS-правило, все
rule_setкоторого
указывают на наборы, не попавшие в конфиг (например, нескачанный remote
.srs), не включается в конфиг и даёт предупреждение сборки, а не уходит в
ядро без условия. Отсутствующее имя рядом с живыми убирается из списка.
DNS-правило по файлу.srsбез скачанной копии отмечается так же, а не
пропускается молча. -
Переменные пресета по умолчанию необязательны. Переменная без
requiredбольше не обязательна, как в лаунчере. Встроенный шаблон помечает
обязательные переменные явно, поэтому пресеты ведут себя как прежде. -
Xray JSON-массивы с балансировщиком. Группа сохраняет
remarks
элемента, каждый сервер пула называетсяremarks tag. Имя, уже занятое в
элементе (группой или предыдущим сервером), получает номер сервера в пуле:
pool p,pool p 2,pool 3. Члены пула — серверы, которыеselector
балансировщика выбирает по префиксу тега; невыбранный сервер остаётся
отдельным узлом.leastLoadбезexpectedвыбирает самый быстрый сервер.
Когда сервер элемента схлопнут с другим, группа ссылается на оставшийся
узел.
🔧 Под капотом
- Контракт с лаунчером: 1.1.107. Его копия теперь в репозитории, и CI
проверяет корпус разбора и схемы на каждом push. - Спецификации фич переписаны по коду (EN+RU).
Install / Установка
adb install -r LxBox-v2.25.9-arm64-v8a.apkБез uninstall! Поверх существующей установки. Настройки и подписки сохранятся.
No uninstall needed — install over the existing one. Settings and subscriptions
are preserved.
Previous release / Предыдущий релиз: v2.25.8.
LxBox v2.25.8
L×Box v2.25.8
A patch on top of 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.
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.
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.
🇬🇧 English
⚠️ 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
theTailscale networkspreset, added once to existing installs and on by
default. A record or a backup with a leftoversectionsfield loads without
error; the field is dropped
(§575). - 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 AmneziaWGmtuabove 1280, atls.fragmentnext 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 unsupportedflow, an invalid
port, TLS fieldsnaivedoes not take) are still applied
(§577). - 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).
✨ Added
- Tailscale preset.
Tailscale networksserves 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). - Skip presets on a node. A server or a folder member can opt out of
presets that serve nodes one by one: theSkip presetsswitch 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. FromNETWORKSthe node opens on this tab
(task 581). - NETWORKS on Home. While the VPN is on, Tailscale nodes without an exit
node are listed underNETWORKS, the last entry of the Direction list.
Instead of a delay the row shows the node state:running,
sign-in needed,stoppedorstarting
(task 579). - 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). - 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). - OpenVPN endpoints as sing-box JSON.
openvpn-clientis 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.ovpnimport
(task 586). - 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). - Template language. A preset can repeat its rules and DNS servers for
every matching node withfor_each, and read the node's tag, record and body
through@nodeand#tpl.
🔄 Changed
- Core
v1.14.2-lx.8. Synced with sing-boxstable. 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: autogoes 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 anxmuxsection (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. Anxmuxsection with any field set is taken as
written. - A hand-written node the core would reject is dropped. A TUIC node with a
uuidthat 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
REALITYshort_idlonger than 16 characters is removed; a REALITY block with
an invalidpublic_keyis removed whole. A MASQUE body without keys is read
instead of being rejected
(task 582). - 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). - A node that goes through another node (a chain or a subscription detour) no
longer carries TLS fragmentation
(§574). - Node notifications with the same code are grouped into one entry; Xray nodes
show fewer «field not read» notices
(§572).
v2.25.6
- Turn a WireGuard/AmneziaWG node off and on without restarting the tunnel
(§557). - Replace a folder or a subscription with a group: Manual, Auto or Both
(§568). - A
selectorgroup from a subscription or a backup stays manual and keeps
its chosen server
(§565). - 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,
§569). - Imported nodes keep what the provider sent:
multiplex,udp_over_tcp,
dial options, WireGuardworkersand more
(§560). - A preset rule left without conditions is dropped instead of matching all
traffic (§571). - Dropped subscription entries show in the subscription summary, not on a
working node (§561). - A chain with a REALITY hop saves when uTLS is stripped; links to a chain
open the chain
(§556,
§558). - 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).
🇷🇺 Русский
⚠️ Прочтите до обновления
- Секций узла больше нет. Узел не несёт собственных правил маршрутов и
записей DNS. Связка Tailscale, которая раньше...
LxBox v2.25.7
L×Box v2.25.7
A patch on top of 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.
Патч поверх v2.25.6.
Узлы Xray, у которых фрагментация TLS задана в finalmask.tcp, получают
фрагментацию ядра; раньше эти поля не читались. Узел, который идёт через другой
узел (цепочка или detour подписки), больше не несёт фрагментацию TLS. У узлов
Xray меньше уведомлений «field not read», а уведомления с одним кодом собраны в
одну запись. Парсер и сборка конфига следуют контракту протоколов 1.1.84.
🇬🇧 English
⚠️ 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.fragmentis taken off that node and the node shows an info
notice. This also applies to nodes whose sing-box JSON setstls.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.
Adetourwritten in the
sing-box JSON itself does not count, since it never reaches the core
(§574).
✨ Added
- TLS fragmentation from Xray subscriptions. An Xray node that sets
ClientHello fragmentation instreamSettings.finalmask.tcp(an item with
type: fragment) now gets the core'stls.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 (afreedom
outbound throughdialerProxy) worked before and is unchanged
(§573).
🔄 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). - TLS fragmentation with a system TLS engine. With
tls.engineset to
appleorwindows, fragmentation is removed with a warning instead of the
config failing to start; the engine stays. These engines are not used on
Android (§574).
🩹 Fixes
- Fewer "field not read" notifications on Xray nodes. An empty
tcpSettingsand themode/path/hostfields inside
xhttpSettings.extrano longer produce a notification. Xray always replaces
those three with the outer values, so there is nothing to report
(§573).
🔧 Under the hood
- Contract with the launcher: 1.1.84.
- GitHub Actions moved to Node 24.
🇷🇺 Русский
⚠️ Прочтите до обновления
- С узла, который идёт через другой узел, снимается фрагментация TLS. Если
сборка пускает узел через промежуточный (цепочка или detour подписки),
tls.fragmentс него снимается, и узел показывает информационное
уведомление. Это касается и узлов, у которыхtls.fragmentпрописан в
sing-box JSON. Через промежуточный узел фрагментация не помогает: ядро
выжидает 500 мс после каждого сегмента и отключает собственную защиту от
потери большого ClientHello.detour, записанный в самом sing-box JSON, не
считается: до ядра он не доходит (§574).
✨ Добавлено
- Фрагментация TLS из Xray-подписок. Узел Xray, у которого фрагментация
ClientHello задана вstreamSettings.finalmask.tcp(элемент с
type: fragment), получает фрагментацию ядраtls.fragment. Раньше эти поля
не читались, и узел работал без фрагментации. Параметры Xray (length,
delay,maxSplit) не переносятся: ядро режет ClientHello по меткам домена
в SNI. Старая форма (outboundfreedomчерезdialerProxy) работала и
раньше и не менялась
(§573).
🔄 Изменено
- Уведомления узла сгруппированы по коду. Несколько уведомлений одного
уровня с одинаковым кодом показываются одной записью: счётчик, список полей
и один общий разбор. Код, который встречается один раз, выглядит как раньше
(§572). - Фрагментация TLS и системный TLS-движок. При
tls.engine=appleили
windowsфрагментация снимается с предупреждением, а не роняет старт
конфига; движок остаётся. На Android такие движки не используются
(§574).
🩹 Исправления
- Меньше уведомлений «field not read» у узлов Xray. Пустой
tcpSettingsи
поляmode/path/hostвнутриxhttpSettings.extraбольше не дают
уведомлений. Xray всегда заменяет эти три поля внешними значениями, так что
сообщать не о чем
(§573).
🔧 Под капотом
- Контракт с лаунчером: 1.1.84.
- GitHub Actions переведены на Node 24.
Install / Установка
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.
LxBox v2.25.6
Merge branch 'Leadaxe:main' into main
LxBox v2.25.5
Merge branch 'Leadaxe:main' into main
LxBox v2.25.4
L×Box v2.25.4
A patch on top of 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.
Патч поверх v2.25.3.
Ядро обновлено до v1.14.2-lx.1. Серверы WireGuard и AmneziaWG больше не
держат память, пока через них не пошёл трафик, и этим управляют две новые
настройки. Пресет «Ru internet segment» теперь ведёт российские приложения
по имени пакета. На планшете список серверов идёт в две колонки. Подписка,
повторяющая один и тот же сервер, больше не показывает его дважды.
🇬🇧 English
⚠️ 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
markedduplicatewith a “Duplicate of ” 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 showERRon 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). - 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). - 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 oneper-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. Thedisabled UDP GSOlines that filled the log of a
working AmneziaWG server are gone; connectivity was never affected
(#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,
sleepordowninstead 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, includingsecurity=reality(other Xray clients read its absence
as “no encryption”). NaiveProxy keeps port443. AnyTLS writesinsecure
instead ofallowInsecure. Shadowsocks has no trailing=. VLESS drops the
defaultfp=random; other fingerprints are kept. TUIC writes
reduce_rtt=trueinstead ofreduce_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). - Duplicate servers in one subscription. A subscription sent the same AWG
server twice, as anamneziawg://line and as avpn://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/ehfields
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=noneno 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
/statereturnsendpoint_states.
🇷🇺 Русский
⚠️ Прочтите до обновления
- Повторы сервера в одной подписке схлопываются. Если подписка перечисляет
один и тот же сервер несколько раз под разными именами, в списке остаётся
по одному серверу на конфигурацию (первый). Остальные отбрасываются и
помечаются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). - Две колонки серверов на широком экране. От 600 dp ширины окна список
серверов на главном экране идёт в две колонки, уже — в одну. Раскладка
меняется на лету при повороте и split-screen. Ручная сортировка остаётся в
одну колонку: перетаскивание работает только в ней
(#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, лимит — ещё и ленивой сборки. Применяется при следующем
подключении.
🔄 Изменено
- ...
LxBox v2.25.3
L×Box v2.25.3
A patch on top of v2.25.2.
The main body of changes is in
v2.25.0 — one parsing
engine shared with
singbox-launcher 2.0.0,
and the Start insurance when the core refuses a server. Read those first;
this patch does not repeat them.
This patch is mostly about the core and about connecting. Diagnostics on a
NaiveProxy server no longer closes the app. A WireGuard or AmneziaWG server whose
address is a name rather than an IP connects in about a second instead of five.
A tunnel built from several such servers is no longer switched off by its own
safety net fifteen seconds in. And the Servers screen finally keeps one list:
servers, subscriptions, folders and chains are entries of one kind, in one order.
Патч поверх v2.25.2.
Основной корпус изменений — в
v2.25.0: один движок
разбора с
лаунчером 2.0.0
и страховка кнопки Start, когда ядро отказывается от сервера. Сначала
читайте их — этот патч их не повторяет.
Этот патч в основном про ядро и про подключение. Диагностика узла NaiveProxy
больше не закрывает приложение. Сервер WireGuard или AmneziaWG, чей адрес задан
именем, а не IP, соединяется примерно за секунду вместо пяти. Туннель из
нескольких таких серверов больше не гасится собственной страховкой через
пятнадцать секунд. А экран Servers наконец держит один список: серверы,
подписки, папки и цепочки — записи одного рода, в одном порядке.
🇬🇧 English
🩹 Fixes
The core — v1.14.1-lx.10
- Diagnostics on a NaiveProxy server no longer closes the app. With the
tunnel up, opening Diagnostics on anaiveserver shut the app down on the
spot: the core read the connection's address, which a connection of that kind
does not have. Diagnostics now returns status, response and timing for such a
server like any other, and the address field stays empty — which is how it
should be. Traffic through those servers and the latency check were never
affected. - WireGuard and AmneziaWG servers addressed by name connect in a second
instead of five. When the server address is a domain rather than an IP, the
first handshake used to be lost and the connection took an extra five seconds.
It now goes through on the first attempt. - XHTTP connections are no longer marked as failed when you switch servers.
When you changed server, or the core closed an XHTTP connection it no longer
needed, it took its own closure for a break from the server's side: a line
about a closed response body landed in the log on every request, and a
perfectly good XMUX session was marked unusable and rebuilt from scratch. A
local cancellation is now recognised for what it is — the log of a working
XHTTP server is clean, and switching servers costs no extra session rebuild. A
real break on the server's side is still reported as before
(#148). - Synced with upstream sing-box — fixes around DNS, IPv6 and shutdown.
The config schema, the set of fields and the behaviour of other servers did not
change.
Connecting
- A VPN built from several WireGuard/AmneziaWG servers no longer switches
itself off after 15 seconds. The core brings such servers up one at a time,
7–9 seconds each, while the safety net against a stuck start waited a fixed 15
seconds for any configuration. On four servers or more it managed to kill a
connection that was already established: the handshake had happened, the
tunnel was up — and immediately put out. No reason was visible either; from the
outside it looked like "I pressed Connect and nothing happened". The allowance
now grows with the number of such servers, and if the safety net does fire it
names the reason and the threshold instead of switching off in silence. For
configurations without WireGuard servers the threshold is unchanged.
Servers screen
- One list of entries of every kind. Servers, subscriptions, folders and
chains are now a single ordered list rather than three different mechanisms:
the screen used to assemble the list from three separate places on every
frame, and one drag wrote the settings twice. Deleting and dragging are now one
entry, one record. - Chains travel with servers in a backup. In the export a chain used to be
ticked under Routing — together with routing rules rather than with the
servers it stands next to in the list. It now goes under "Server lists". Older
archives where chains were exported as Routing still read as before; restore
those with the Routing tick. - The Debug API sees every kind.
GET /subsnow returns the same list you
see on screen, chains included.
The settings file, the backup format and the settings themselves did not change;
servers, routes and list order stay as they were.
Config editor
- The Cut/Copy/Paste menu no longer piles up or hangs around after you clear
the selection. Several menus could end up on screen at once — two or three
stacked, the last one clipped by the screen edge — and tapping an empty spot to
clear the selection did not dismiss them. The editor was rebuilding the menu's
controlling object on every repaint of the screen, leaving an already-shown
menu with no owner and nobody to close it. The editor now keeps one such object
for the lifetime of the screen, and the menu closes when the selection is
cleared, when you tap away, when you scroll, and when you leave the screen.
Tapping the menu's own buttons still does not drop the selection: what gets
copied is exactly what you selected.
DNS
- DNS preset Shield: the Yandex server over DoT really takes part in the
group. It used to drop out silently — it was listed as a member, but the
server entry itself was missing from the template, so on every config build the
member disappeared with a warning and the "shield" polled five providers
instead of six. This was most visible to people behind a whitelist: Yandex
answers on such a network and the other members do not, so resolution did not
work at all. The server is now declared: Yandex over DNS-over-TLS, direct,
outside the tunnel — so it works even when the tunnel is down, and queries
still go encrypted, with no leak into plain UDP. Existing configurations are
not migrated: the group's membership is taken from the template on the next
config build.
Stability
- "Check all servers" no longer runs out of memory on lists with several
WireGuard/AmneziaWG servers. The check starts the core, and the core reserves
buffers in advance for every WireGuard server in the configuration rather than
only the one being measured: around 17 MB per server, so close to 200 MB on a
dozen. The check broke the memory limit and the app closed instead of showing
the latencies. Such servers are now checked four at a time: between batches the
core restarts and the buffers are released. Every server is still measured and
the list order does not change — the check simply takes a little longer. Lists
with no WireGuard servers work as before. - The diagnostic report on server problems no longer skips servers with
identical names. Providers often call every server the same thing — plainly
proxy, say — and one and the same server can arrive twice under different
protocols with a shared name. In the parsing problem report such servers
overlaid one another: only the last survived and the notes on the rest
vanished. There was no way to notice, because the server count shown next to
them was right: twelve servers, eight lines of notes. Namesake servers are now
told apart the same way they are in the server list, and no note is lost.
🔧 Under the hood
A corpus of real public subscriptions now guards the parser: snapshots of 68
public lists — about 74,000 servers as text, exactly as the sources hand them
over — plus the machinery to run parsing across them. Every change to the
protocol registry is checked against a reference: if the number of parsed servers
drops or the rejection codes change, it shows immediately and per subscription
rather than after a complaint. The run only reads text — not one server from the
corpus is connected to or checked for reachability, no config is built and the
core is never started. Contract 1.1.52 (unchanged). Core v1.14.1-lx.10.
🧪 Tests
The release gate is CI checks (analyze, the full test set, four l10n checkers,
docs parity). Added by this patch: the start threshold against the number of
WireGuard endpoints, namesake servers in the warnings report, the config editor
menu against duplicate overlays and every dismissal path, the single sources[]
list round-trip, the dns_shield preset membership, and probe batching on
WireGuard servers.
📚 Documentation
The trial methodology for the public-subscriptions corpus is written down, along
with the specs for this patch's changes. The Debug API reference records that
GET /subs returns every kind of entry.
🇷🇺 Русский
🩹 Исправления
Ядро — v1.14.1-lx.10
- Диагностика узла NaiveProxy больше не закрывает приложение. При живом
туннеле Диагностика узлаnaiveзакрывала приложение сразу же: ядро читало
адрес соединения, которого у соединения этого типа нет. Теперь Диагностика
такого узла отдаёт статус, ответ и время, как у любого другого, а поле адреса
остаётся пустым — так и должно быть. Трафик через такие узлы и проверка
задержки не страдали и раньше. - **Серверы WireGuard и AmneziaWG с адресом по имени подключаются за секунду
вместо пяти...
LxBox v2.25.2
L×Box v2.25.2
A patch on top of v2.25.1.
The main body of changes is in
v2.25.0 — one parsing
engine shared with
singbox-launcher 2.0.0,
and the Start insurance when the core refuses a server. Read those first;
this patch does not repeat them.
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.
Основной корпус изменений — в
v2.25.0: один движок
разбора с
лаунчером 2.0.0
и страховка кнопки Start, когда ядро отказывается от сервера. Сначала
читайте их — этот патч их не повторяет.
Этот патч про подписки, которые приезжали короче, чем есть, — и про то, чтобы
не оставлять в тишине, когда так вышло. Ссылки в том написании, в котором их
пишут провайдеры, читаются, а не исчезают молча; строка, которую приложение не
может использовать, называет причину. Баннер-обманка истёкшей подписки больше
не выдаётся за сервер, а транспорт, которого ядро не знает, честно
отбраковывается вместо соединения в никуда.
🇬🇧 English
🩹 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 thewg-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. Theup/downspelling 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/quicused 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 thehttptransport, 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. Realhttptransport (spelled out astype=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,socksandhttpelements 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
alpnorserver_portsno 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, c2you would delete the chainc1and getu1, 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_shieldDNS preset no longer resolves in the clear. The group was
set tomode: 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_udpandyandex_udpare out of the group; the
first three already had an encrypted twin there, and anopendns_dohentry
was added for OpenDNS. The*_udpservers 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 compositio...
LxBox v2.25.1
L×Box v2.25.1
Three fixes on top of v2.25.0.
That release is the main body of changes: one parsing engine with
singbox-launcher 2.0.0
(contract 1.1.46), and the Start insurance when the core refuses a server
(#147). Read it first — this
patch does not repeat it.
This patch: Stats → Memory breakdown shows PSS figures again; XHTTP extra keeps
sessionIDPlacement / sessionIDKey; a hop chain on Servers stays between the
rows you drop it among.
Три правки поверх v2.25.0.
Основной корпус изменений — там: один движок разбора с
лаунчером 2.0.0
(контракт 1.1.46) и страховка кнопки Start, когда ядро отказывается от
сервера (#147). Сначала читайте
2.25.0 — этот патч его не повторяет.
В этом патче: в Stats → Memory разбивка PSS снова с цифрами; XHTTP extra
сохраняет sessionIDPlacement / sessionIDKey; цепочка на Servers остаётся
между строками, куда её поставили.
🇬🇧 English
🩹 Fixes
| § | Before | Now |
|---|---|---|
| 507 | 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 | 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) |
| 509 | 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.
🇷🇺 Русский
🩹 Исправления
| § | Было | Стало |
|---|---|---|
| 507 | После 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 | Живая vless+xhttp ссылка разбиралась, seqPlacement из extra доезжал, а proto-имена Xray sessionIDPlacement / sessionIDKey терялись. Ядро клало session id в path (свой дефолт), сервер искал cookie с кастомным ключом |
Алиасы мапятся в session_placement / session_key (в extra и в плоском query). Канон сильнее proto-имени. sessionIDLength / sessionIDTable не мапятся: "0" без таблицы — «не задано». Оверлей, пока реестр лаунчера не заберёт алиас (лаунчер #131) |
| 509 | Servers рисует подписки, серверы, папки и цепочки одним списком, но drop писал два блока: цепочки сохранялись хвостом sources[] и возвращались вниз |
Смешанный drag пишет массив как на экране. Записи цепочек держат свои слоты среди остальных родов. Инвариант «хоп ссылается только на цепочку выше» не менялся — он считается по взаимному порядку цепочек |
🧪 Тесты
Релизный гейт — CI checks (analyze, полный набор тестов, четыре l10n-чекера,
паритет доков). Локально: xhttp_test на proto-алиасы, chains_storage_test и
lx_backup_test на смешанный порядок sources[].
Install / Установка
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.
The main body of changes is there / Основной корпус изменений — там:
GitHub Release v2.25.0.
LxBox v2.25.0
L×Box v2.25.0
One parsing engine with the desktop launcher 2.0.0. The desktop
singbox-launcher 2.0.0
and L×Box now share one protocol registry (contract 1.1.46). Share links,
Xray JSON, WireGuard .conf files and Copy link are parsed and built by the
same table-driven engine on both sides; the handwritten per-protocol parsers
are gone. Warning texts come from the same registry too. If one app could read a
node, the other reads it the same way. Core: v1.14.1-lx.8.
Second: when you press Start and the core refuses because of one bad
server, that server is disabled automatically with the core's reason
(#147); the VPN comes up on the
rest.
Десктопный лаунчер 2.0.0 и телефон — один движок разбора. У обоих
приложений теперь общий реестр протоколов (контракт 1.1.46). Ссылки,
Xray-JSON, WireGuard .conf и Copy link разбираются и собираются одной
таблицей на обеих сторонах; рукописные парсеры сняты. Тексты предупреждений —
из того же реестра. Узел, который прочитала одна сторона, читает и другая
одинаково. Ядро: v1.14.1-lx.8.
Второе: по кнопке Start, если ядро отказывается стартовать из‑за одного
негодного сервера, этот сервер выключается сам с причиной от ядра
(#147); VPN поднимается на
остальных.
🇬🇧 English
🔗 Parsing aligned with singbox-launcher 2.0.0
| Before | Now |
|---|---|
| Thirteen handwritten link parsers, a separate Xray parser, a separate WireGuard INI parser and a separate link builder | One registry-driven engine for all schemes |
| A fix on the phone did not reach the desktop until someone patched both sides | Rules live in the shared registry; both apps pick them up from the same table |
| Warning texts for some codes lived only in the app | All warning titles, explanations and advice come from warnings.json in the registry |
| A node read on one side could differ on the other after Copy link | Parse and emit use the same table |
WireGuard and AmneziaWG .conf files are a first-class input (not converted to an
internal wireguard:// link first). Invalid WireGuard keys, masked panel keys
and overlapping AmneziaWG magic headers are no longer dropped silently — the node
gets a named warning or is rejected with a reason.
socks4:// and socks4a:// links are recognised; the scheme carries the SOCKS
version.
A few schemes still differ from the desktop on Copy link (Shadowsocks padding,
some XHTTP / VMess spellings). Those remaining overlays are tracked, not silent
phone-only patches.
🛡 Core rejection insurance (#147)
| Before | Now |
|---|---|
| One bad server in a large subscription blocked the whole VPN; the core message named an index, not a node you recognise | Start parses the core's refusal, finds the named server and disables it — the same switch you would use yourself |
| No way to see which servers were turned off | After a clean start, a banner shows how many were disabled; Show lists each with the core's text; a tap opens that node's Diagnostics (notifications at the bottom) |
| A disabled-by-core server stayed disabled after a subscription refresh even if the provider fixed it | When the node's body changes on refresh, it is enabled again for a new check |
| — | Up to ten silent checks of the remaining servers before the app asks whether to continue; Start turns into Stop while the cycle runs |
Servers you disabled yourself are never touched. Updating the core alone does not
clear a core verdict — toggle the switch or refresh the subscription. The banner
on the home screen goes away after Stop (the verdicts on the nodes stay).
This automatic disable runs on the Start button. Quick Settings, boot
auto-start and the watchdog raise the last saved config as before.
🩹 Visible fixes (parsing and Copy link)
| Situation | Before | Now |
|---|---|---|
Xray JSON pasted as a single outbound, a full config with outbounds, an array of outbounds, or an array of configs |
Only an array of configs was accepted; preview showed zero nodes | All four shapes are accepted; preview shows the real count |
| Base64 subscription text pasted from the clipboard | Worked only as a URL | The wrapper is stripped on paste too |
type=splithttp in a share link |
Node was built with no transport — dead TCP on an HTTP port, silently | Read as xhttp; same node as the canonical name |
Hysteria2 mport with a port range |
Server address landed in the port list → core fatal «bad port range», whole VPN down | Only a number pair is a port-range element; a lone port stays on the server |
REALITY pbk in standard base64 (not URL-safe) |
Whole config refused to start | Key is rewritten to the alphabet the core expects — same key, different spelling |
naive+quic:// after Copy link |
Scheme fell back to naive+https://; QUIC was lost |
naive+quic:// survives the round-trip |
| VMess over gRPC (Copy link) | gRPC service name from v2rayN (path in the JSON container) was lost on copy |
Emitted back with serviceName mapped from path |
TUIC link with empty password (tuic://uuid:@host) |
Node disappeared or passed silently | Node stays; a warning marks the empty password |
Xray outbound element without port |
App silently used 443 or 1080 | Element is dropped, as in Xray-core — no fake node |
| Unknown query parameter on a link | Dropped with a generic message or silently | Named by the parameter |
WireGuard [Peer] without Endpoint |
Became a node with nowhere to connect | Rejected |
Disabled TLS object tls: {"enabled": false} in a JSON body |
Could crash the core on first dial | Removed on input on every path, like links already were |
| Invalid CIDR on a WireGuard address | Whole VPN failed to start | Bad prefix is stripped from that node |
Fractional port in JSON (443.9) |
Truncated to 443 |
Node is rejected |
Xray dialerProxy pointing at a freedom fragment outbound |
Whole node dropped as a bad hop | Node stays direct; TLS fragment is set |
Naive link password@host (no colon in userinfo) |
Read as a username with an empty password — auth failed | Read as the password, same as NekoBox / NaiveGUI |
📋 Notifications and the lists
| Before | Now |
|---|---|
| One long warning line under a node; info drowned real problems | Error ✖ / warning ⚠ show text; info ⓘ is an icon only — tap opens the full list |
| No structured explanation | Expandable cards What happened / Why it happens / What you can do; Details opens offline contract docs |
| Home screen and a cold start hid badges that Servers already showed | The same badge (highest level) on the home node list, including after a cold start and on a standalone server |
| A rejected paste on Servers was a red line under the field | The red line stays; a sheet with the same card opens at once |
| A new source on Servers was easy to miss | The list scrolls to the new row and highlights it as New for a few seconds |
| Probe bar labelled «Test servers» | Bulk switch sits with the row toggles; no extra label when idle |
In node details the cards live at the bottom of Diagnostics, under the live
Check / Run output. The Diagnostics tab shows a yellow dot when there is
something to read (red on error). There is no separate Notifications tab.
Copy link on a node whose link carries a private key (SSH, WireGuard/AWG,
MASQUE) now asks with Link contains a private key / Copy anyway, instead
of refusing or copying silently.
⚙️ Core
v1.14.1-lx.4 → v1.14.1-lx.8. A REALITY short_id that is too long is an
error, not a process panic. Init errors name the record type and tag — Start
uses that to find the bad server. A gRPC service_name is passed through as
written.
⚠️ What may change for you
| Situation | What happens |
|---|---|
Xray subscription element with no port that used to appear as port 443 or 1080 |
The element is dropped — it is not turned into a node anymore |
REALITY public key in URL-safe base64 (pbk with - and _) |
Rewritten to standard base64 in the link the app stores and emits — the key bytes are the same; re-import on another client may show a different spelling |
| Donate | Boosty is removed; crypto addresses are unchanged |
🧪 Tests
CI checks (analyze, the full test suite, four l10n checkers, docs parity)
is the release gate.
🇷🇺 Русский
🔗 Сближение с singbox-launcher 2.0.0
| Было | Стало |
|---|---|
| Тринадцать рукописных разборщиков ссылок, отдельный разбор Xray, отдельный разбор WireGuard INI и отдельная сборка ссылки | Один движок по таблицам общего реестра для всех схем |
| Починка на телефоне не доезжала до десктопа, пока не правили обе стороны | Правила живут в общем реестре; оба приложения читают одну таблицу |
| Тексты части предупреждений держались только в коде приложения | Заголовки, объяснения и советы — из warnings.json реестра |
| Узел после Copy link на одной стороне мог отличаться на другой | Разбор и сборка — одна таблица |
Файлы WireGuard и AmneziaWG .conf — полноценный вход (без перевода во
внутреннюю ссылку wireguard://). Негодные ключи WireGuard, замаскированные
панелью ключи и пересекающиеся magic-заголовки AmneziaWG больше не исчезают
молча — узел получает названное предупреждение или отбраковывается с причиной.
Ссылки socks4:// и socks4a:// распознаются; версию протокола несёт схема.
На части схем Copy link всё ещё расходится с десктопом (паддинг Shadowsocks,
некоторые написания XHTTP / VMess). Это учтённые оверлеи, а не тихие заплаты
только на телефоне.
🛡 Страховка от отказа ядра (#147)
| Было | Стало |
|---|---|
| Один негодный се... |