Viewer importer: import ALL compatible settings and preference files, not a hard-coded whitelist #231

Closed
opened 2026-10-01 22:33:04 +00:00 by sky_line · 2 comments
Owner

Problem

The viewer importer (slfloaterviewerimport.cpp, Settings section) only offers a hard-coded whitelist:

  • GLOBAL_SETTINGS: ~26 debug settings (UI scale, fonts, pie menu, chat bubbles, camera offsets...);
  • ACCOUNT_SETTINGS: 4 per-account settings.

Users coming from Firestorm / Alchemy / SL expect all of their compatible preferences to come across.

Goal

Import every compatible setting, not a curated handful:

  1. All settings files, not only debug settings, from the source viewer's user_settings/settings.xml and each account's settings_per_account.xml. A setting is compatible when:
    • the key exists in our control groups;
    • the Type matches;
    • the value is valid for our control (range / enum where we know it).
  2. Other preference stores in the source profile, where the format matches ours (or we can convert it):
    • colors (colors.xml), toolbars (toolbars.xml);
    • ignorable dialogs / notification settings;
    • autoreplace and spellcheck custom dictionaries;
    • camera and graphics presets;
    • saved searches / teleport history / favourites, if stored locally;
    • chat / IM preferences that live outside settings.xml.
  3. A denylist, not an allowlist. Exclude settings that are machine-, install- or session-specific, or unsafe to carry over:
    • GPU / renderer and Vulkan-specific settings, and any Render* that only makes sense for the source's pipeline;
    • window size / position, cache locations, last-run / crash markers;
    • login / grid credentials, update channels, version stamps;
    • anything our defaults deliberately changed (e.g. VK-specific defaults);
    • FS-only keys with no meaning here (no matching control: skipped automatically).
  4. UX for hundreds of rows:
    • grouped by category (UI, chat, camera, graphics...);
    • search box, select all / none per group;
    • show current vs. imported value, as today;
    • nothing applied without the user's tick (keep today's "values differ" filter).
  5. Safety:
    • back up settings.xml / settings_per_account.xml before writing (as backupOnce does for key bindings);
    • log every applied key;
    • offer an undo (restore the .pre-import backup).
  • The keybind import bug (filed alongside): any file-level import must merge, never overwrite blindly.
## Problem The viewer importer (`slfloaterviewerimport.cpp`, Settings section) only offers a **hard-coded whitelist**: - `GLOBAL_SETTINGS`: ~26 debug settings (UI scale, fonts, pie menu, chat bubbles, camera offsets...); - `ACCOUNT_SETTINGS`: 4 per-account settings. Users coming from Firestorm / Alchemy / SL expect *all* of their compatible preferences to come across. ## Goal Import **every compatible setting**, not a curated handful: 1. **All settings files, not only debug settings**, from the source viewer's `user_settings/settings.xml` and each account's `settings_per_account.xml`. A setting is compatible when: - the key exists in our control groups; - the `Type` matches; - the value is valid for our control (range / enum where we know it). 2. **Other preference stores** in the source profile, where the format matches ours (or we can convert it): - colors (`colors.xml`), toolbars (`toolbars.xml`); - ignorable dialogs / notification settings; - autoreplace and spellcheck custom dictionaries; - camera and graphics presets; - saved searches / teleport history / favourites, if stored locally; - chat / IM preferences that live outside settings.xml. 3. **A denylist**, not an allowlist. Exclude settings that are machine-, install- or session-specific, or unsafe to carry over: - GPU / renderer and Vulkan-specific settings, and any `Render*` that only makes sense for the source's pipeline; - window size / position, cache locations, last-run / crash markers; - login / grid credentials, update channels, version stamps; - anything our defaults deliberately changed (e.g. VK-specific defaults); - FS-only keys with no meaning here (no matching control: skipped automatically). 4. **UX for hundreds of rows:** - grouped by category (UI, chat, camera, graphics...); - search box, select all / none per group; - show current vs. imported value, as today; - nothing applied without the user's tick (keep today's "values differ" filter). 5. **Safety:** - back up `settings.xml` / `settings_per_account.xml` before writing (as `backupOnce` does for key bindings); - log every applied key; - offer an undo (restore the `.pre-import` backup). ## Related - The keybind import bug (filed alongside): any file-level import must merge, never overwrite blindly.
Author
Owner

Implemented on branch vimport (commits c57b2a76da..3a5343d16d, not built yet: syntax-checked only).

What changed

  • Data map app_settings/viewer_import_map.xml, generated by scripts/viewer_import/gen_viewer_import_map.py. It holds 67 verified Firestorm / Black Dragon renames, 14 of them with value conversions:

    • FS chat commands gain our leading /;
    • MouseWarpMode -> DisableMouseWarp;
    • FS ad-hoc ignore (+ "allow friends") -> AlchemyIgnoreAdHocSessions 0 / 1 / 2;
    • DebugLookAt* -> AlchemyLookAt*, NaCl preprocessor -> AlchemyPreProc*, FS autoresponse / rejection -> Alchemy*, and others.

    The map also has a denylist (exact names, regex patterns, and credential substrings: password / token / secret / oauth ...), a renderer allowlist (39 Render* settings that mean something on Vulkan), ranges / enums scraped from our preference XUI, toolbar and key command renames, and notes on what can't be mapped.

  • Settings: every key in their settings.xml / settings_per_account.xml is checked. It is offered when:

    • it exists here, by name or through the map;
    • the type is compatible;
    • the value is in range (clamped, with a note) or is an offered enum value;
    • it is not denied, and it differs from ours.

    Each setting goes to whichever group holds it here. Against their declared settings that is about 1218 FS and 1140 BD keys by name, plus the renames.

  • Other stores:

    • notifications (ignorable_dialogs.xml);
    • colours and window positions (both off by default);
    • toolbars: commands renamed, unknown ones dropped and listed, live reload;
    • key bindings: merged, see #232;
    • contact sets and teleport history: merged live;
    • graphics presets (Vulkan-compatible keys only) and camera presets (Black Dragon camera presets converted to CameraOffsetRearView / FocusOffsetRearView);
    • FS poser poses, font sets and legacy Windlight files;
    • auto-replace lists and custom dictionaries;
    • chat (unchanged merge).
  • Floater:

    • a category list with tickboxes and counts, and the selected category's rows (now / imported / note);
    • filter, "show unchanged and skipped" with the reason for each, All / None;
    • Preview (dry-run summary), Import (report, plus a restart notice where needed), Undo last import.
  • Safety:

    • every import first writes user_settings/import_backups/<date_time>/ with copies of the files it changes, reference copies of the settings, and an undo.xml journal (previous values, restored files, created files, added teleports). Undo replays it;
    • settings are saved immediately after an import;
    • re-import is a no-op: rows read "same";
    • every imported, refused or skipped row is logged under the ViewerImport tag.
  • Docs: doc/viewer_import.md, covering the per-OS profile paths, the category table, the rules, and what is not imported and why (AO, LSL bridge, quick prefs, FS area-search filters, BD poses, favourites order (server-side), logins and grids, blocklists).

To test: import from a real FS and a real BD profile, logged in. Run Preview, then Import. Restart and check the settings and toolbars. Import again: nothing should be offered. Then Undo.

Implemented on branch `vimport` (commits c57b2a76da..3a5343d16d, not built yet: syntax-checked only). **What changed** - **Data map** `app_settings/viewer_import_map.xml`, generated by `scripts/viewer_import/gen_viewer_import_map.py`. It holds 67 verified Firestorm / Black Dragon renames, 14 of them with value conversions: - FS chat commands gain our leading `/`; - `MouseWarpMode` -> `DisableMouseWarp`; - FS ad-hoc ignore (+ "allow friends") -> `AlchemyIgnoreAdHocSessions` 0 / 1 / 2; - `DebugLookAt*` -> `AlchemyLookAt*`, NaCl preprocessor -> `AlchemyPreProc*`, FS autoresponse / rejection -> `Alchemy*`, and others. The map also has a **denylist** (exact names, regex patterns, and credential substrings: password / token / secret / oauth ...), a **renderer allowlist** (39 `Render*` settings that mean something on Vulkan), ranges / enums scraped from our preference XUI, toolbar and key command renames, and notes on what can't be mapped. - **Settings**: every key in their `settings.xml` / `settings_per_account.xml` is checked. It is offered when: - it exists here, by name or through the map; - the type is compatible; - the value is in range (clamped, with a note) or is an offered enum value; - it is not denied, and it differs from ours. Each setting goes to whichever group holds it here. Against their declared settings that is about 1218 FS and 1140 BD keys by name, plus the renames. - **Other stores**: - notifications (`ignorable_dialogs.xml`); - colours and window positions (both off by default); - toolbars: commands renamed, unknown ones dropped and listed, live reload; - key bindings: merged, see #232; - contact sets and teleport history: merged live; - graphics presets (Vulkan-compatible keys only) and camera presets (Black Dragon camera presets converted to `CameraOffsetRearView` / `FocusOffsetRearView`); - FS poser poses, font sets and legacy Windlight files; - auto-replace lists and custom dictionaries; - chat (unchanged merge). - **Floater**: - a category list with tickboxes and counts, and the selected category's rows (now / imported / note); - filter, "show unchanged and skipped" with the reason for each, All / None; - **Preview** (dry-run summary), **Import** (report, plus a restart notice where needed), **Undo last import**. - **Safety**: - every import first writes `user_settings/import_backups/<date_time>/` with copies of the files it changes, reference copies of the settings, and an `undo.xml` journal (previous values, restored files, created files, added teleports). Undo replays it; - settings are saved immediately after an import; - re-import is a no-op: rows read "same"; - every imported, refused or skipped row is logged under the `ViewerImport` tag. - **Docs**: `doc/viewer_import.md`, covering the per-OS profile paths, the category table, the rules, and what is not imported and why (AO, LSL bridge, quick prefs, FS area-search filters, BD poses, favourites order (server-side), logins and grids, blocklists). **To test**: import from a real FS and a real BD profile, logged in. Run Preview, then Import. Restart and check the settings and toolbars. Import again: nothing should be offered. Then Undo.
Author
Owner

Verified done: viewer importer imports every compatible setting/preference file (data map with renames, conversions, deny/allow lists, range checks), with categories, review list, preview and undo. Commits: bafa583924, edb1c51b50, d4aff26d1c, 3a5343d16d. Shipped in v1.0.0-beta.1.

Verified done: viewer importer imports every compatible setting/preference file (data map with renames, conversions, deny/allow lists, range checks), with categories, review list, preview and undo. Commits: bafa583924, edb1c51b50, d4aff26d1c, 3a5343d16d. Shipped in v1.0.0-beta.1.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream#231
No description provided.