UI 樹
ui 把 JSON UI 和 Ore UI 界面讀成文本,每個控件一行,並用 input 操作的虛擬鼠標、按鍵和文字對 ref 執行動作。在
bedboo 操作之後使用(順序)。配置 ui(true)同時控制 oreui 和帶 ref 的 mouse。
設計:#21。
1600x900 下的字符數:標題界面 519(舊 JSON 20,569),世界列表 ~860(原始 DOM ~48,000),暫停 ~600,背包 ~950。
視圖
screen start_screen
- button "Play" [e1]
- button "Settings" [e2]
- text "v26.60/LeviLamina-26.60.5"
under: toast_screen, debug_screen, cubemap_background_screen| 行 | |
|---|---|
screen <name> | 每個讀取的界面一行;Ore UI:screen <route> (Ore UI),如 screen /play/all (Ore UI)。後綴 (not ready: read again) 或 (page not read: <why>) |
- <role> "<text>" / - <role> <name> | 然後是 = <value> 或 checked/ unchecked、 disabled、 focused、 selected,可執行動作時再加 [<ref>]。縮進 = 嵌套 |
- button hotbar_slot_button x9 [in e29] | 連續 6 行以上相似的行;{op:"ui", ref:"e29"} 列出它們 |
... <n> lines cut: ... | 超過 maxNodes;保留前 3/4 和後 1/4 |
under: a, b | 最前面界面之下的界面(僅 scope:"active") |
(nothing read on this page) / (no match) | Ore UI 頁面為空 / find 無命中 |
角色:button、toggle、text_input、slider、scroll、text、item(集合格子,如背包格)、group。
輸出內容(compact):能看到、能讀或能操作的。按鈕讀作其第一個可見標籤;重複其控件的文字被丟棄;分組僅在可點擊且
不含其他行時輸出;名為 button、default、panel、image、label、content、control 或其角色名的 JSON UI 控件
顯示所在分組的名字。
Ref(e1、...):每個控件(場景 + 路徑)一個,在其界面留在棧上期間由所有讀取和連接共用;從不重新分配。snapshot
字段被忽略。
讀取
| 請求 | 回覆 |
|---|---|
{op:"ui"} | {view, screen(最前面), truncated} |
{op:"ui", find:"quit"} | 文字、名字或值包含該串(不分大小寫)的行,平鋪 |
{op:"ui", ref} | {view, truncated}:該控件(帶 ref)及其下全部,不折疊 |
{op:"ui", ref, detail:true} | {node}:全部節點字段 + ref、ancestors(文字或名字,由近及遠) |
{op:"ui", format:"json"} | snapshot(僅供參考)、tick、screens、active、roots、按 ref 的 nodes(+parent、children)、truncated、client{w,h} |
| 字段 | 默認 | |
|---|---|---|
scope | active | active、all、界面名或 scene-… id |
maxNodes | 80 行;json:uiMaxNodes(1000) | 1..100000 |
depth | 全部 | 每個界面根以下的層數 |
includeInvisible | false | 也包括隱藏控件 |
compact | true | false:全部控件 |
timeoutMs | 3000 | 100..30000,之後 not_ready |
debug | false | json/detail:組件、虛表、可見性位 |
| 節點字段 | |
|---|---|
role、name、text | name:JSON UI 控件名;Ore UI 的 aria-label/title/alt/placeholder/name/data-testid |
value | 文本框文字、滑塊 0..1、開關狀態 |
state | visible, enabled, hovered, focused, selected, pressed, editable, scrollable, checked(null:非開關) |
bounds、boundsNorm | 客戶區像素(x/y);比例(rx/ry) |
actions | click、setText、scroll |
surface | 界面 id |
source | kind jsonui|oreui(整個頁面)|dom;path(同名兄弟用 name[k])、type(JSON UI 類型或標籤)、collectionName/collectionIndex(如 inventory_items/9)、url、route |
hash | 由 role、name、text、path、type、kind、url、route 計算 |
screens[]:{id, kind jsonui|oreui|unknown, screen, interactive, modal},設置時另有 rawScreen、route、ready:false、
pageError、debug。unknown 場景(in_game_play_screen)不讀取。
操作
{"op": "ui", "action": "click", "ref": "e1"}
{"ok": true, "action": "click", "ref": "e1", "point": {"x": 800, "y": 428}, "changed": true,
"target": "- button \"Play\" [e1]", "screen": "/play/all", "view": "screen /play/all (Ore UI)\n- button ..."}action | 字段(默認) | 輸入 |
|---|---|---|
click | button(left)、holdMs、settleMs、afterMs | mouse click |
setText | text、clear(true)、submit(false)、delayMs | 點擊;CTRL+A、BACK;text;ENTER |
scroll | notches(1,正數 = 向下) | mouse wheel |
全部動作:anchor(center、top_left、top、top_right、left、right、bottom_left、bottom、bottom_right)、offsetX/offsetY、
force、timeoutMs、observeMs(150,≤5000:讀取結果前等待)。
回覆:point;changed(任何文字、狀態、值、位置或最前面界面變化);target(其當前行,消失則為 null);screen
(最前面);view 僅在另一個界面或 Ore UI 路由來到最前面時返回。
引用上的 mouse
{"op":"mouse", "action":"move", "ref":"e68"}:mouse 瞄準一個 ref(anchor、offsetX/offsetY、force;action
默認 move);回覆附加動作回覆的字段。只有 click/down 檢查遮擋控件。
錯誤
控件必須保持其角色和名字(JSON UI)或文字(Ore UI)。
code | |
|---|---|
stale_ref | 未知 ref、界面已關閉、控件消失或已改變。candidates:≤5 行角色和名字/文字相同的控件(其自身界面已關閉時取自最前面界面) |
occluded | 隱藏;在窗口外(point);或在該點被遮擋(occludedBy、point),遮擋者為其界面上更晚的輸入控件(JSON UI)或上方接收輸入的界面。≥ 半個窗口的控件不計。force:true 強制執行 |
not_ready | timeoutMs 內無應答、無場景,或 Ore UI 頁面無響應 |
unsupported | ref 是整個 Ore UI 頁面,或無法讀取 UI |
bad_args | maxNodes/depth/timeoutMs 不是整數、format 不是 text/json、find/ref 不是字符串 |
bad_request | 動作缺 ref、未知 action、setText 缺 text |
1.26.60
JSON UI:標題(start_screen)、HUD(hud_screen)、聊天、暫停、背包、退出對話框;未見滑塊或開關。Ore UI:世界列表
(/play/all)、設置(/oreui-settings/...)。懸停命中最內層控件(背包:grid_item_for_inventory 中的
item_button_ref)。等入場動畫結束後再讀。
實現
| 部分 | |
|---|---|
| JSON UI | SceneStack → UIScene::mScreenView → VisualTree::mRootControl → UIControl::mChildren/mComponents,在客戶端線程(ClientInstance::update 鉤子)。按虛表判斷類型(無 RTTI)(文字:導出的 render;文本框/滑塊/滾動:ScreenView 的列表;按鈕/開關:4/8 個狀態 weak_ptr)。SEH:佈局異常 → unsupported |
| Ore UI | 最上層 Ore UI 頁面的 DOM,經 oreui 腳本(≤4000 節點,120 字符),角色按標籤、input type 和 ARIA role 判斷(domRole,src/UiView.cpp)。無文字的控件取其內部文字;與有文字控件相鄰的無文字 act 2 元素視為其一層 |
Ore UI 界面:oreui
原始 Ore UI DOM,無 ref(調試用)。
| 字段 | 默認 | |
|---|---|---|
url | 任意 | 等待 location.href(如 ui://./hbui/index.html)包含該串的視圖;不是路由 |
maxNodes | 2000 | 1..50000 |
maxText | 200 | 8..4096 |
timeoutMs | 3000 | 100..30000,之後 not_ready |
force | false | 允許 9 以外的 V8 主版本 |
回覆:url、title、width、height、nodes(文檔順序)、truncated、findings(method、gameface、v8、jsCalls、
contextsSeen、missingExports)。節點:tag、id、class、testId、role、type、act、name、text(自身)、
value、state(disabled, checked, selected, expanded, hidden, focused, invisible)、bounds(客戶區像素)、children
(索引)。act:1 = 按標籤、ARIA role、tabindex、test id 或 React/Preact 處理函數可點擊;2 = 僅有 -interactive 懸停樣式
(且不在 act 祖先內)。
鉤住 v8.dll 中的 v8::Function::Call/v8::Object::CallAsFunction(V8 9.4;首次使用時),在頁面下一次調用時(~300/s)
運行只讀腳本;同一時間一個請求。unsupported(findings):其他 V8 主版本、導出缺失、腳本錯誤、DOM > 15 MiB。V8 崩潰
(SEH)或腳本不結束會禁用 oreui 和 ui 中的 Ore UI,直到重啟。