docs(readme): M130 补微软登录的 client id 前提,删「十四页」计数,把 i18n 守门边界与产物名写成实测口径

- Accounts:发布版二进制不含 Azure 公共客户端 id(CI 0 处注入),需设 ULL_MSA_CLIENT_ID;
  没配时点登录只拿到通用「登录失败 / Code: other」。
- 删「feature-complete: fourteen pages」:代码里 Route 8 个变体、Screen::ALL 5 个,没有读法得到 14;
  改成按 Route 列举并说明 Screen::ALL 为何更小。
- i18n:删「视图层没有硬编码字符串」,改成白名单守门抓英文、中文与其它页扫不到的已知边界。
- 自报名例子改成 argv[0] 实测口径;翻牌措辞区分「cargo bin 名未翻」与「产物名已翻」。
- 中文版补「一壳两形」highlight,账户与 auth 模块行补第三方社区服 / 本地档案。
- 顺手改掉「ull 能跑在 Termux」:Linux 资产 glibc ≥ 2.35,Termux 不在发布矩阵内。
This commit is contained in:
AskaEth committed 2026-11-05 18:05:38 +08:00
1 parent 7092469f90
commit 95131d856e
2 files changed
+79 -39

No files matched your search

+40 -19
View File
@@ -33,7 +33,11 @@ attached to other agent tooling as an MCP server.
- **Java management**: a Temurin → Oracle → Microsoft → Zulu fallback chain, region-aware.
- **Accounts**: Microsoft sign-in over OAuth 2.0 device code flow → Xbox Live → XSTS →
`api.minecraftservices.com`; third-party community auth servers; local offline profiles for
isolated testing. Account tokens are kept on this machine only.
isolated testing. Account tokens are kept on this machine only. **Microsoft sign-in needs an Azure
public client id, and no release binary carries one** — the id is not in this repo and CI injects
none, so set `ULL_MSA_CLIENT_ID` before launching, or build with it. Without one, pressing sign-in
only raises a generic "Sign-in failed" alert with `Code: other`; nothing on that screen tells you
the id is what is missing. Community auth servers and local profiles need no id.
- **Engine**: multi-source download (health scoring, mirrors, chunked transfers, hash while
downloading) and a YAML rule-based crash diagnosis engine.
- **License**: Apache-2.0 © AskaEth (YeiJ).
@@ -44,14 +48,23 @@ attached to other agent tooling as an MCP server.
Slint tag. `v0.2.0` is the first tag after the rewrite — the iced line, which is what the release
pipeline builds now. Everything described below lives on that line.
- **The iced UI is feature-complete**: fourteen pages — instances, version management (three-column
rail layout with search), content library (modpacks / mods / resource packs / shaders with source
and version filters), logs, settings (general / appearance / Java / downloads), accounts
(Microsoft device code, third-party community servers, local profiles), the AI rail and the
installer flows — on top of one component library and one token set.
- **What the iced UI has**: instances (list-detail), version management (three-column rail layout
with search), content library (modpacks / mods / resource packs / shaders with source and version
filters), logs, settings (general / appearance / Java / downloads), accounts (Microsoft device
code, third-party community servers, local profiles), the AI rail and the installer flows — all on
one component library and one token set. The page list is the one in `presenter::router::Route` —
instances, version management, content library, logs, settings, accounts, instance detail, the AI
page; `pages::Screen::ALL`, the smaller set that has a slug (`--screen=` and the page test matrix,
`crates/app-iced/src/pages/tests.rs`), leaves out accounts, instance detail and the AI page, which
are routed but opened from the nav rail or an instance tile.
- **Localisation follows the system language**: detection, an explicit override in settings, and
persistence across restarts. UI copy goes through a single message catalogue; there is no
hard-coded string in the view layer.
persistence across restarts. UI copy goes through one message catalogue (`crates/i18n`).
- **What the copy guard catches, and what it does not**: a test reads the instances page sources and
fails on any string literal that contains an ASCII word unless it is on a short whitelist, so a
newly hard-coded English string turns red as it lands
(`crates/app-iced/src/pages/instances/tests/i18n.rs`). Known boundary: that scan covers the
instances page rather than every screen, and a hard-coded Chinese literal has no ASCII word to
match, so nothing catches it — that class relies on review and the screenshot run.
- **Appearance**: window background image, per-panel transparency and whole-window transparency
(Windows), light / dark / follow-system, and system window corners where the platform grants them.
On CPU rendering the translucent layers are switched off and the UI says so.
@@ -66,16 +79,21 @@ Binaries you may run into, so you can tell them apart:
| Binary | Crate | State |
|--------|-------|-------|
| `unlucky-launcher-iced` | `crates/app-iced` (iced 0.14) | the GUI binary the workspace builds; the release pipeline stages it under the public name `unlucky-launcher`; the same binary answers every CLI subcommand |
| `unlucky-launcher-iced` | `crates/app-iced` (iced 0.14) | the GUI binary the workspace builds; the release pipeline stages the file as `unlucky-launcher_<version>_<platform>_<arch>[.exe]`, and the binary inside each archive is named `unlucky-launcher`; the same binary answers every CLI subcommand |
| `unlucky-launcher` | `crates/app` (Slint) | **historical**: that crate is excluded from the workspace, so this binary is no longer built or shipped; the v0.1.0 assets are the last Slint builds |
| `ull` | `crates/cli` | the zero-UI build of the same command set, shipped as its own asset |
`unlucky-launcher` (the GUI) and `ull` are not duplicates. The GUI binary needs the graphics stack
when it opens a window (it `dlopen`s X11 / Wayland / GL, and links `libfontconfig` at load); `ull`
needs nothing beyond glibc, so it runs on a server, a CI container or Termux where no window can
exist. Pick `ull` when there is no desktop, `unlucky-launcher <command>` when there is. Both print the
same CLI text and name themselves after the binary you invoked: `unlucky-launcher --help` starts with
`unlucky-launcher ·`, `ull --help` starts with `ull ·`.
The GUI binary (`unlucky-launcher` once extracted or downloaded) and `ull` are not duplicates. The GUI
binary needs the graphics stack when it opens a window (it `dlopen`s X11 / Wayland / GL, and links
`libfontconfig` at load); `ull` needs nothing beyond glibc, so it runs on a server or a CI container
where no window can exist. That floor is glibc ≥ 2.35 (the Linux slots build on Ubuntu 22.04), so an
older distribution — and Android/Termux, which is not a released slot at all — needs a source build
(`packaging/README.md` §4, §9). Pick `ull` when there is no desktop, `unlucky-launcher <command>` when
there is. Both print the same CLI text, and each names itself after the file you ran — `argv[0]` with
its directory and a trailing `.exe` removed, and nothing else (`crates/cli/src/cli/program.rs`). So
`ull` prints `ull ·`, the `unlucky-launcher` inside an archive prints `unlucky-launcher ·`, a local
`cargo build` prints `unlucky-launcher-iced ·`, and the bare Windows asset, whose file name keeps the
version segment, prints `unlucky-launcher_<version>_windows_x64 ·`.
### Subcommand dispatch
@@ -163,9 +181,11 @@ that crate is kept as source-only reference and can no longer be built as a work
What the build produces:
- `unlucky-launcher-iced` — the GUI (iced). It is also the CLI: the same binary answers every
subcommand listed above. The name is temporary — it becomes `unlucky-launcher` at the flip. The
release artifacts already carry the public name: the pipeline builds this bin and
`packaging/make_artifacts.py` stages it as `unlucky-launcher[.exe]`, so download links never change.
subcommand listed above. The `iced` in this name is cargo's, not the download's: renaming the bin
is what the "flip" still owes. The release file name carries no implementation detail — the
pipeline builds this bin and `packaging/make_artifacts.py` stages it as
`unlucky-launcher_<version>_<platform>_<arch>[.exe]`, with the binary inside each archive named
`unlucky-launcher`, so download links never carry `iced`.
- `unlucky-launcher` — **historical**: no workspace build produces this binary any more; it belonged
to `crates/app`, which is excluded. The v0.1.0 assets are the last builds under this name.
- `ull` — the CLI as a standalone, UI-free binary. Same command set, no graphics stack, smaller, and
@@ -207,7 +227,8 @@ Minimum baseline: **Windows 10**; Windows 8.1 / 8 / 7 are not supported.
X11 is the preferred path today and Wayland is the long-term direction. macOS builds are unsigned,
so the first launch needs the Gatekeeper quarantine attribute cleared
(`xattr -d com.apple.quarantine`)
- Android Termux is experimental and not promised: CLI only, GUI unverified
- Android Termux is experimental and not promised: no released asset targets it (build from source
there), and the GUI is unverified
- Each platform runs its own test matrix; capability differences use feature gates with runtime
probing.