Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f969cd6
feat(ui): introduce Atlas workspace
MrJoiny Jul 29, 2026
46072ba
fix(ui): polish Atlas workspace
MrJoiny Jul 29, 2026
19f0b51
refactor(ui): simplify Atlas workspace
MrJoiny Jul 29, 2026
f54b1a1
refactor(ui): trim Atlas abstractions
MrJoiny Jul 29, 2026
c6e2595
refactor: remove unused abstractions
MrJoiny Jul 30, 2026
d03b616
feat(ui): add Chromium 87-safe dark mode
MrJoiny Aug 15, 2026
c577d23
Merge branch 'master' into atlas-ui and convert new tabs to Atlas UI …
MrJoiny Aug 31, 2026
4755bb9
fix(ui): harmonize account sidebar navigation with Atlas theme
MrJoiny Aug 31, 2026
04b8262
fix(ui): polish inspector config layout and function input styling
MrJoiny Aug 31, 2026
96d32f5
feat(ui): implement full dark mode as default theme across the UI
MrJoiny Sep 1, 2026
0f974f1
feat(ui): add quick theme toggle button to top header bar
MrJoiny Sep 1, 2026
05e4d8a
feat(cheats,ui): restyle in-game overlay buttons to Atlas style and p…
MrJoiny Sep 1, 2026
2224f02
refactor(ui): resolve standards and architectural review findings
MrJoiny Sep 2, 2026
b62690e
fix(ui): polish sidebar typography, currency toggles, outpost card, a…
MrJoiny Sep 2, 2026
70d6384
Merge branch 'master' into atlas-ui
MrJoiny Sep 2, 2026
3c72e96
style: trim trailing whitespace in config.js
MrJoiny Sep 2, 2026
1639ee9
feat(ui): restore and style original injector brand logo in header
MrJoiny Sep 2, 2026
79b5d35
fix(ui): add dark mode support to search workspace
MrJoiny Sep 2, 2026
f7e5f4a
fix(ui): add inert polyfill and harden CSS fallback for Chromium 87
MrJoiny Sep 3, 2026
84a8143
fix(cheats,ui): position overlay below game title bar and mark header…
MrJoiny Sep 3, 2026
bbcd751
fix(ui): make sidebar scrollable and prevent lower controls cut-off o…
MrJoiny Sep 3, 2026
d61bfaa
fix(cheats): ensure title bar and child layers are draggable
MrJoiny Sep 3, 2026
7fdf3c3
fix(ui): make atlas header draggable while keeping controls interactive
MrJoiny Sep 3, 2026
8aed566
fix(cheats,ui): revert title bar modifications while keeping WebUI be…
MrJoiny Sep 3, 2026
f21b96a
fix(ui): preserve plural cheat namespace keys in flattenCheatStates s…
MrJoiny Sep 3, 2026
abe429f
refactor(ui): clean dead code, resolve standards findings, and harden…
MrJoiny Sep 3, 2026
506b510
Fix Atlas inspector reactivity and saved parameter editing
MrJoiny Sep 7, 2026
bb09331
Restrict UI server access to loopback and trusted origins
MrJoiny Sep 7, 2026
ff0abb7
Centralize frontend live monitoring ownership
MrJoiny Sep 7, 2026
9d9b49e
Centralize API game evaluation and response handling
MrJoiny Sep 7, 2026
7cc7d54
Add Chromium 87 fallbacks for outpost styling
MrJoiny Sep 7, 2026
552245a
Remove unused account and outpost CSS selectors
MrJoiny Sep 7, 2026
bd58b4d
fix(ui): support ChromeDebug in the in-game iframe
MrJoiny Sep 8, 2026
023de32
Merge branch 'master' of https://github.com/MrJoiny/Idleon-Injector i…
MrJoiny Sep 8, 2026
838687a
fix(ui): allow embedded access and target saved favorites correctly
MrJoiny Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Need help or want to share feedback? Join the community on Discord:
- **Steam/Web Injection**: Injects JavaScript into the Steam client or web
session using a configurable Chromium-based browser profile.
- **Web Dashboard ([VanJS](https://vanjs.org/))**: Local UI at
`http://localhost:8080` for cheats, state inspection, and DevTools.
`http://localhost:8080` with Atlas workspaces for cheats, account editing,
configuration, Search, and DevTools.
- **Live State Sync**: WebSocket updates keep cheat state in sync without
polling.
- **Value Monitor**: Track in-game values with history in the Web UI.
Expand Down Expand Up @@ -64,7 +65,8 @@ The recommended way to interact is via the [VanJS](https://vanjs.org/)-powered W
- Toggle cheats on/off.
- View active cheat status.
- Modify account configs.
- Monitor specific game values (manual path or from Search).
- Save and monitor game values from Search.
- Review success/error activity without leaving the active workspace.
- Access Chrome DevTools.
- Apply config changes to RAM or save them to disk.

Expand Down
4 changes: 3 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ exports.cheatConfig = {
StatueUpgOdds: (t) => t * 2, // double the odds of statue upgrade
Statue_CanAfford: (t) => 1, // free statue upgrades
StatueBon: (t) => t * 2, // double statue bonus
ArmoryUpgCost: (t) => t / 2, // half cost armory upgrades
ArmoryUpgCost: (t) => t / 2, // half cost armory upgrades
RatDMG: (t) => t * 2, // double rat dmg
ParchmentDrop: (t) => t * 2, // double parchment drop
MarbleDrop: (t) => t * 2, // double marble drop
Expand Down Expand Up @@ -892,6 +892,8 @@ exports.injectorConfig = {
interceptPattern: "*N.js",
enableUI: true,
webPort: 8080,
webHost: "127.0.0.1",
webAllowedOrigins: [], // exact remote UI origins; requires a non-loopback webHost
onLinuxTimeout: 60000,
target: "web", // "web" or "steam"
webUrl: "https://www.legendsofidleon.com/ytGl5oc/",
Expand Down
Binary file modified docs/UI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 7 additions & 14 deletions docs/account-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Read these files before adding or changing an Account feature tab:
- `src/ui/components/views/account/W1Tab.js` ... `W7Tab.js`
World tab shells and sub-tab registries.
- `src/ui/components/views/account/tabShared.js`
Shared tab navigation, lazy panes, persistent panes, and coming-soon placeholders.
Shared world/nested tab factories, tab navigation, lazy panes, and persistent panes.
- `src/ui/components/views/account/accountLoadPolicy.js`
`useAccountLoad()` for standardized load state and load failure logging.
- `src/ui/components/views/account/accountShared.js`
Expand All @@ -24,8 +24,7 @@ Read these files before adding or changing an Account feature tab:
Current structure:

- Top-level Account tabs include Account Options, Upgrade Vault, and W1-W7.
- W1-W3 contain implemented feature tabs.
- W4-W7 currently use `createWorldComingSoonTab(...)`.
- W1-W7 contain implemented feature tabs.
- W2 has a nested Alchemy panel: Brewing, Liquid, Vials, Pay 2 Win, Sigils.
- W3 has a nested Construction panel: Buildings, Cogs.

Expand All @@ -34,8 +33,7 @@ Current structure:
### Page chrome

- Prefer `PersistentAccountListPage(...)` for most editable Account features.
- Use `AccountPageShell(...)` directly only when the wrapper needs behavior not exposed by `PersistentAccountListPage`.
- Use `AccountTabHeader`, `RefreshButton`, `WarningBanner`, `NoticeBanner`, `AccountSection`, and `AccountRow` before adding tab-local chrome.
- Use `RefreshButton`, `WarningBanner`, `NoticeBanner`, `AccountSection`, and `AccountRow` before adding tab-local chrome.
- Keep tab-specific selectors out of shared CSS unless they define a reusable primitive.

### Loading
Expand Down Expand Up @@ -107,7 +105,7 @@ export const MyFeatureTab = () => {

Use when the tab is small, mostly read-only, and remounting content after load is acceptable.

Use `AccountPageShell` with `loadState` and `renderBody`, or pass a small reactive `body` to `PersistentAccountListPage` when the surrounding page should still use persistent Account chrome.
Pass a small reactive `body` to `PersistentAccountListPage` when the surrounding page should keep persistent Account chrome.

### Pattern C: Cached collection or card UI

Expand Down Expand Up @@ -194,7 +192,7 @@ Prefer `EditableNumberRow` when this pattern fits; it already handles draft text

1. Find the nested registry, such as `ALCHEMY_SUBTABS` in `W2Tab.js` or `CONSTRUCTION_SUBTABS` in `W3Tab.js`.
2. Add the new tab to that nested array.
3. Reuse the existing `renderTabNav(...)` and `renderLazyPanes(...)` panel structure.
3. Keep the registry wired through the existing `createNestedTab(...)` component.
4. Keep panel-specific CSS near the world's existing tab CSS.

### Add a top-level Account tab
Expand All @@ -208,13 +206,8 @@ Prefer `EditableNumberRow` when this pattern fits; it already handles draft text

1. Create `src/ui/components/views/account/WNTab.js`.
2. Register it in `src/ui/components/views/Account.js` with `isWorld: true` and `worldNum`.
3. Add world-specific styles and imports.
4. If the world is not implemented yet, prefer `createWorldComingSoonTab(...)`.

### Placeholder behavior

- For unimplemented sub-tabs, use `component: null` and `createComingSoonPlaceholder(...)`.
- Do not attach write behavior or load behavior to placeholders.
3. Define its sub-tab registry and export it with `createWorldTab(...)`.
4. Add world-specific styles and imports.

## 7) CSS rules

Expand Down
5 changes: 5 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ exports.injectorConfig = {

`config.custom.js` can omit any export; only provided keys override defaults.

The web UI is local-only by default. Remote access requires a non-loopback
`injectorConfig.webHost` and the exact browser origins in `webAllowedOrigins`.
Restart the injector after changing these settings. Remote access grants command
execution and game-state editing without a login, so use it only on a trusted network.

## Startup cheats

`startupCheats` is an array of command strings run after injection.
Expand Down
77 changes: 38 additions & 39 deletions docs/ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ How the VanJS-based UI is structured, syncs to the backend, and how to extend it

- `src/ui/entry/`: HTML entry point and CSS imports.
- `src/ui/components/`: UI building blocks and view containers.
- `src/ui/components/views/`: Cheats, Config, Account, Search, Monitor, DevTools tabs.
- `src/ui/components/views/`: Cheats, Config, Account, Search, and DevTools workspaces.
- `src/ui/services/`: API and WebSocket clients.
- `src/ui/state/`: Reactive store and constants.
- `src/ui/styles/`: CSS partials (imported by `entry/style.css`).
Expand All @@ -27,24 +27,24 @@ van.add(document.body, App());

`src/ui/entry/style.css` is the CSS entry. Add new partials in `src/ui/styles/` and import there.

`src/ui/components/App.js` initializes heartbeat monitoring, keyboard shortcuts, and mounts the tab content.
`src/ui/components/App.js` initializes heartbeat monitoring and keyboard shortcuts, mounts workspace content, and keeps global Toast, Activity, and update surfaces available.

## State management

`src/ui/state/store.js` uses VanX reactivity (`vanX.reactive`) and exposes a simple service-style API.

State buckets:

- `store.app`: UI state (active tab, loading state, heartbeat, toast, view mode).
- `store.app`: UI state (active workspace, loading state, heartbeat, toast, drawers, and update state).
- `store.data`: data from the backend (cheats, config, account options, cheat states, monitor values).

Notable `store.app` UI flags include `configForcedPath` (focused config path from cheat gear icon) and `configDrawerOpen` (side drawer state while on Cheats).

Persisted UI settings:

- Sidebar collapsed state and cheat view mode (tabs/list) are stored in `localStorage`.
- Favorites and recents are stored in `localStorage` via the Cheats view.
- Config drawer open/closed state is session-only (not persisted).
- Sidebar collapsed state is stored in `localStorage`.
- Cheat favorites, recent commands, Search key favorites, selected Search keys, and saved Search results are stored in `localStorage`.
- Config, Activity, Search key, and Search inspector drawers are session-only.

Core flows:

Expand Down Expand Up @@ -83,41 +83,40 @@ WebSocket client auto-reconnects every 10s in all runtimes.

### Cheats view

`src/ui/components/views/Cheats.js` is the main cheat explorer.
`src/ui/components/views/AtlasCheats.js` is the main cheat explorer.

Features:

- Favorites and recents stored in `localStorage`.
- Quick-access section surfaces favorites and recents for one-click execution.
- Categories ordered by `CATEGORY_ORDER` in `src/ui/state/constants.js`.
- `SearchBar` filters by command value or description.
- Supports list and tab layouts (stored in `store.app.cheatsViewMode`).
- Tabs view paginates with "Load more" (50 items per page).
- List view uses lazy `<details>` categories, auto-expands on search.
- Parameterized cheats render inline input ("Val"); missing values block execution.
- Favorites support parameterized commands by storing full action string.
- Includes a Config drawer toggle so Cheat commands stay visible while editing Config side-by-side.
- Scope navigation covers all, active, favorite, recent, and category-filtered commands.
- The command table filters by command, description, or category and paginates at 50 rows.
- Row selection is available by pointer, Enter/Space, and table Arrow/J/K navigation.
- Execution remains separate from selection; stateful commands use switches and one-shot commands use Run.
- Parameterized commands collect their value in the inspector and block execution until it is supplied.
- Favorites and recents preserve complete parameterized command strings in `localStorage`.
- The inspector exposes command details and linked config without hiding the command table.
- Linked config can also open the shared Config drawer beside the Cheats workspace.

Useful helpers:

- `store.executeCheat(action, message)` triggers `/api/toggle` and shows toast feedback.
- `API.executeCheatAction(action)` triggers `/api/toggle`; Atlas records the result through `store.notify()`.
- `store.navigateToCheatConfig(cheatValue)` focuses Config for that cheat path (opens the side drawer when on Cheats, otherwise switches to full Config tab).
- `store.getActiveCheats()` flattens active cheat state into a display list.
- `store.data.activeCheatStates` receives WebSocket state updates that Atlas flattens for its switches and Active scope.

### Config view

`src/ui/components/views/Config.js` edits `startupCheats`, `cheatConfig`, and `injectorConfig`.
`src/ui/components/views/Config.js` edits `startupCheats`, `cheatConfig`, and `injectorConfig` through the shared draft in `views/config/configDraft.js`.

Key behaviors:

- Builds a local `draft` via `vanX.reactive` to avoid direct edits on live config.
- Uses one reactive draft and separate RAM/disk baselines to avoid direct edits on live config.
- Sub-tabs: Cheat Config, Startup Cheats, Injector Config.
- Startup Cheats auto-show a separate `Value` input when a selected command has `needsParam`.
- Supports category filtering and search on cheat config keys.
- Uses `ConfigNode` to recursively render object trees.
- Uses forced-path mode when coming from Cheats gear icon, with "SHOWING" banner.
- Can run as a right-side drawer while Cheats stays open; close from drawer header or toggle button in Cheats.
- Saves apply to RAM (`/api/config/update`) or persist to disk (`/api/config/save`).
- Saves explicitly apply the cheat config to RAM (`/api/config/update`) or persist the full draft to disk (`/api/config/save`).
- `Ctrl+S` saves the shared config draft from the Cheats or Config workspace.
- Injector config shows "restart required" warning banner.

Function values (like `(t) => t * 2`) are edited through `FunctionInput`:
Expand Down Expand Up @@ -148,42 +147,44 @@ Save behavior:
Features:

- **Key Whitelist**: Select top-level game attribute categories to search (e.g., `PlayerDATABASE`, `SkillLevels`).
- **Favorites**: Quick-select common data categories.
- **Favorites**: Curated defaults and user-edited key favorites persist independently; an intentionally empty list stays empty.
- **Value Matching**:
- Supports strings (case-insensitive contains).
- Supports numbers (exact or rounding tolerance for floats).
- Supports ranges (e.g., `100-200`).
- Supports `true`, `false`, `null`, `undefined`.
- **Path Copying**: Clicking a result copies the full Haxe access path to clipboard.
- **Send to Monitor**: The eye icon subscribes the path in the Monitor view.
- **Result inspector**: Selecting a result exposes its path, value editor, and monitor state.
- **Path Copying**: Copy actions produce the full Haxe access path and immediate toast feedback.
- **Saved monitors**: Saved results can subscribe or pause their live monitor in the Search inspector.
- **Performance**: "Load more" pattern handles large result sets without freezing.

### Monitor view
### Activity drawer

`src/ui/components/views/Monitor.js` tracks values over WebSocket and displays history.
`src/ui/components/ActivityDrawer.js` keeps notifications and active value monitors available from every workspace.

Features:

- Add watchers by entering a path (e.g., `gga.GemsOwned`) or sending a Search result.
- Shows current value and last 10 updates per watch.
- Remove watchers with Unwatch action.
- Activity lists the same success and error events shown immediately by Toast.
- Monitors show current values and recent updates received over WebSocket.
- Monitor subscriptions are owned by saved Search results and can be paused or removed there.

### DevTools view

`src/ui/components/views/DevTools.js` embeds or launches Chrome DevTools:

- Calls `/api/devtools-url` and loads it in an iframe.
- When embedded in the in-game UI, prompts for pop-out to avoid crashes.
- Embedded mode can open Web UI or DevTools in external window via `/api/open-url`.
The in-game inspector supports console evaluation and inspection of the main game.
Pauses are skipped while it is connected. Use **Open externally** for breakpoints,
child frames, and workers. Opening externally disconnects the embedded inspector;
**Reconnect here** returns to in-game inspection.

## Components and patterns

Common components in `src/ui/components/`:

- `Sidebar`: tab navigation and quick actions.
- `AtlasHeader` + `Sidebar`: global status, workspace navigation, and workspace-specific context.
- `WorkspaceContext`: contextual navigation supplied by the active workspace.
- `ActivityDrawer`: notification history and live monitor output.
- `SearchBar`: shared filter input used by Cheats and Account.
- `ConfigNode`: recursive config renderer with tooltips.
- `Toast` + `Tooltip`: global UI helpers.
- `Toast` + `Tooltip`: global immediate feedback helpers.

Typical component pattern:

Expand Down Expand Up @@ -218,5 +219,3 @@ const viewFactories = {
## Embedded vs desktop behavior

`IS_ELECTRON` in `src/ui/state/constants.js` handles Electron-specific UI behavior (like external link handling). WebSocket updates available in Electron and browser modes.

`window.parent !== window` detects embedded mode for DevTools view, forcing pop-out workflow.
10 changes: 0 additions & 10 deletions src/cheats/api/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,3 @@ export function searchGga(query, keys, options = null) {

return { results, totalCount: results.length, truncated };
}

/**
* Classify a query string into a value type (any/range/number/string/etc.).
* @param {string} query
* @returns {string} The detected type tag
*/
export function detectQueryType(query) {
const parsed = parseQuery(query);
return parsed.type;
}
19 changes: 1 addition & 18 deletions src/cheats/core/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* The Stencyl game engine reference.
* @type {object|null}
*/
export let bEngine = null;
let bEngine = null;

/**
* Game attributes map from the game.
Expand Down Expand Up @@ -134,28 +134,11 @@ export function registerCommonVariables(context) {
});
}

/**
* Get the current game context.
* @returns {object|null}
*/
export function getGameContext() {
return gameContext;
}

/**
* Check if game globals are initialized.
* @returns {boolean}
*/
export function isGameReady() {
return bEngine !== null && itemDefs !== null;
}

// Individual accessor functions for backwards compatibility
export const getBEngine = () => bEngine;
export const getItemDefs = () => itemDefs;
export const getMonsterDefs = () => monsterDefs;
export const getCList = () => cList;
export const getBehavior = () => behavior;
export const getEvents = () => events;
export const getActorModel = () => ActorModel;
export const getGGA = () => gga;
2 changes: 1 addition & 1 deletion src/cheats/core/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ export async function setup() {
*
* @returns {string[]} Array of result messages
*/
export function runStartupCheats() {
function runStartupCheats() {
return startupCheats.map((c) => cheat(c, gameContext));
}
7 changes: 0 additions & 7 deletions src/cheats/core/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,3 @@ export let setupDone = false;
export function markSetupDone() {
setupDone = true;
}

/**
* Reset setup state (used for re-initialization).
*/
export function resetSetupState() {
setupDone = false;
}
10 changes: 0 additions & 10 deletions src/cheats/helpers/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export function getAllBundles() {

return allBundles;
}

/**
* Return the current bundle catalog with live ownership flags.
*
Expand All @@ -49,12 +48,3 @@ export function getBundleCatalog() {
owned: Number(bundlesReceived[code]) === 1 ? 1 : 0,
}));
}

/**
* Get a map from bundle code to display name.
*
* @returns {Map<string, string>} Map of bundleCode -> displayName
*/
export function getBundleCodeToNameMap() {
return new Map(getAllBundles().map(([name, code]) => [code, name]));
}
Loading