# 74. ĐẶC TẢ KIẾN TRÚC TƯƠNG TÁC 3D WORLD RAYCAST DIRECTX 12, ĐỒNG BỘ CON TRỎ PHẦN CỨNG & CƠ CHẾ ALT-KEY FOREGROUND BYPASS

- **Mã Tài Liệu**: `DOC-74-DX12-HARDWARE-CURSOR-RAYCAST-FOREGROUND-SECURITY-2026`
- **Mốc Thời Gian Tham Chiếu**: `19/09/2026` (POE2 v0.5.5+, C++23 DOD & Python 3.11 EDA)
- **Mã Bất Biến Kiến Trúc**: `INV-DX12-HARDWARE-RAYCAST`, `INV-FOCUS-INTERLOCK-HARDWARE-SAFETY`
- **Phạm Vi**: Hai tầng C++23 Core Engine (Hot Path 120Hz) và Python 3.11 Companion (Cold Path 30Hz)
- **Trạng Thái**: `CANONICAL STANDARD & SSoT (BẮT BUỘC TUÂN THỦ TOÀN DỰ ÁN)`

---

## 1. BỐI CẢNH THỰC ĐỊA & PHÁT HIỆN GỐC RỄ (LIVE OPS RCA)

Trong quá trình vận hành tự hành trên game client Path of Exile 2 v0.5.5+ (DirectX 12 Renderer), Sư đoàn 5 (Live Ops Track) phát hiện sự cố click ảo bí hiểm:

### 1.1. Triệu Chứng Sự Cố (Silent Click Failure)
- Nhân vật đã tiếp cận sát bệ đá Map Device ($\le 18\text{u}$ theo `INV-WASD-NO-BLIND-LMB`).
- Python Companion gửi lệnh click mở Map Device hoặc bước vào Portal bằng `PostMessageW(hwnd, WM_LBUTTONDOWN / WM_MOUSEMOVE, ...)`.
- Mặc dù hàm API trả về mã thành công `TRUE` và tọa độ pixel hoàn toàn chính xác trên màn hình, **bệ đá Map Device hoàn toàn không có phản ứng, bảng giao diện Atlas không mở ra, nhân vật đứng im bất động**.

### 1.2. Phân Tích Nguyên Nhân Gốc Rễ Kỹ Thuật (DirectX 12 Viewport Raycasting)
1. **Cơ chế Raycasting của Engine DirectX 12 trong POE2**:
   - Khác với giao diện 2D (Inventory Grid, Chat Box, Menu) vốn xử lý các Windows Message `WM_LBUTTONDOWN` trực tiếp từ Window Procedure, các đối tượng 3D trong thế giới trò chơi (Map Device stone, Portal vortex, Chest, NPC, Monster Hitbox) được engine DX12 nhận diện thông qua **Viewport Camera Raycasting**.
   - DX12 tính toán tia chiếu (ray) từ tọa độ camera 3D xuyên qua vị trí con trỏ chuột phần cứng của hệ điều hành (`GetCursorPos` / RawInput Buffer).
   - Khi gửi qua `PostMessageW`, vị trí con trỏ chuột vật lý của Windows không hề thay đổi. Engine DX12 tính toán raycast tại vị trí thực tế của chuột Windows (thường nằm ở cạnh màn hình hoặc app khác), khiến tia raycast bắn trượt khỏi bệ đá 3D Map Device.
2. **Hạn chế ForegroundLockTimeout trên Windows 10/11**:
   - Khi bot chạy từ background terminal hoặc IDE, lệnh `SetForegroundWindow(hwnd)` thông thường bị hệ điều hành chặn (chỉ làm nhấp nháy nút trên Taskbar qua `FlashWindow`), khiến cửa sổ game không nhận được sự kiện con trỏ phần cứng.

---

## 2. QUY CHUẨN CƠ CHẾ ALT-KEY BYPASS TRONG `ensure_window_focus`

Để bảo đảm quyền kích hoạt cửa sổ game lên tiền cảnh từ bất kỳ tiến trình nền nào mà không bị Windows `ForegroundLockTimeout` ngăn chặn, AutoPOE2 quy chuẩn quy trình 5 bước **Alt-Key Foreground Bypass**:

```mermaid
sequenceDiagram
    autonumber
    participant Bot as Python / C++ Actuator
    participant OS as Win32 User32 / Kernel32
    participant FG as Cửa sổ Đang Active
    participant Game as POE2 Window (HWND)

    Bot->>OS: AttachThreadInput(CurrentThread, ForegroundThread, TRUE)
    Bot->>OS: AttachThreadInput(CurrentThread, GameThread, TRUE)
    Bot->>OS: LockSetForegroundWindow(LSFW_UNLOCK = 2)
    Bot->>OS: SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDCHANGE)
    Note over Bot,OS: Kích hoạt Alt-Key Exception Loop
    Bot->>OS: keybd_event(VK_MENU / 0x12, 0, 0, 0) [Alt Down]
    Bot->>OS: BringWindowToTop(Game)
    Bot->>OS: SetForegroundWindow(Game)
    Bot->>OS: SetActiveWindow(Game)
    Bot->>OS: keybd_event(VK_MENU / 0x12, 0, KEYEVENTF_KEYUP, 0) [Alt Up]
    Bot->>OS: AttachThreadInput(..., FALSE) [Tách luồng]
    Game-->>Bot: Xác nhận Foreground Focus Thành Công (GetForegroundWindow == Game)
```

### Chi Tiết Kỹ Thuật:
1. **`AttachThreadInput`**: Gắn kết hàng đợi nhập liệu giữa thread hiện tại của bot và thread của cửa sổ tiền cảnh để chia sẻ quyền kích hoạt focus.
2. **`LockSetForegroundWindow(2)`**: Mở khóa cưỡng chế quyền thay đổi foreground window.
3. **`keybd_event(VK_MENU, 0, 0, 0)` (Alt Keypress Exception)**:
   - Trong kiến trúc hệ thống Windows NT, phím `Alt` (Menu Key) có đặc quyền tối cao trong message loop của hệ điều hành. Khi phím Alt được bấm xuống, hệ thống coi người dùng đang tương tác bàn phím có chủ đích và cho phép lệnh `SetForegroundWindow` kế tiếp thành công 100%.

---

## 3. BẤT BIẾN KIẾN TRÚC: INV-DX12-HARDWARE-RAYCAST

### 3.1. Đặc Tả Quy Tắc Bất Biến
$$\text{INV-DX12-HARDWARE-RAYCAST} \iff \begin{cases} 
\text{Game Unfocused} \implies \text{CHẶN TUYỆT ĐỐI SetCursorPos & mouse\_event ra Desktop}, \\
\text{Game Focused} \implies \text{ĐỒNG BỘ BẮT BUỘC SetCursorPos(x,y) + mouse\_event cho 3D Raycast.}
\end{cases}$$

### 3.2. Bảng Phân Định Thao Tác 2D vs 3D World Raycast

| Loại Thao Tác | Đối Tượng Mục Tiêu | Phương Thức Input Bắt Buộc | Ràng Buộc An Toàn |
|---|---|---|---|
| **3D World Raycast** | Bệ đá Map Device, Cổng Portal, Rương đồ (Chests), NPC, Hitbox Quái vật | **`SetCursorPos(x, y)` + `mouse_event(MOUSEEVENTF_LEFTDOWN/UP)`** (Bắt buộc con trỏ phần cứng thật) | Game BẮT BUỘC phải giữ Foreground Focus (`ensure_window_focus`). CẤM chỉ dùng `PostMessageW`. |
| **2D UI Grid** | Ô túi đồ (Inventory Grid), Khay nạp Waystone (Device Tray), Nút ENDGAME Tab | `crisp_ctrl_click` / `ctrl_click` (Hỗ trợ kép `PostMessageW` + `mouse_event`) | Focus Interlock bảo vệ, có jitter 40ms tự nhiên. |
| **Unfocused State** | Mọi đối tượng khi cửa sổ game mất tiêu điểm (người dùng Alt+Tab) | **CHẶN 100% MỌI DI CHUYỂN CHUỘT VÀ CLICK** (0 pixel displacement ra Desktop) | Tuân thủ tuyệt đối `INV-FOCUS-INTERLOCK-HARDWARE-SAFETY`. |

---

## 4. KIẾN TRÚC ĐIỀU HỢP BẢO VỆ CON TRỎ (CURSOR INTERLOCK ARCHITECTURE)

```mermaid
flowchart TD
    Req["Lệnh Tương Tác Chuột: click(x, y) / hover(x, y)"] --> Check{"is_poe2_window_focused(hwnd)?"}
    
    Check -- "NO (Unfocused / User on Desktop)" --> Block["CHẶN TUYỆT ĐỐI (Return False)<br/>0 pixel di chuyển con trỏ<br/>0 click gửi ra Windows OS"]
    
    Check -- "YES (Game Focused)" --> Mode{"Thao tác 3D World Raycast hay 2D UI?"}
    
    Mode -- "3D World Raycast (Map Device / Portal / Chest)" --> Sync["ĐỒNG BỘ CON TRỎ PHẦN CỨNG THẬT<br/>1. SetCursorPos(x, y)<br/>2. time.sleep(0.04s) cho DX12 camera raycast<br/>3. mouse_event(LEFTDOWN) -> sleep -> mouse_event(LEFTUP)"]
    
    Mode -- "2D UI Interaction (Stash / Inventory)" --> Dual["PostMessageW hoặc Mouse Event có kiểm soát"]
    
    Sync --> Done["Tương tác 3D thành công 100%"]
    Dual --> Done
```

---

## 5. BỘ TIÊU CHUẨN NGHIỆM THU (DOD & TEST SUITE)

Để nghiệm thu bất biến `INV-DX12-HARDWARE-RAYCAST`, test suite [`tests/test_dx12_hardware_cursor_interlock.py`](../../tests/test_dx12_hardware_cursor_interlock.py) kiểm định:
1. **Unfocused Blockade Test**: Khi `is_poe2_window_focused() == False`, gọi `click()`, `hover()`, `set_cursor_pos()` trả về `False` và con trỏ màn hình desktop không bị dịch chuyển dù chỉ 1 pixel.
2. **Focused Hardware Raycast Test**: Khi `is_poe2_window_focused() == True`, gọi click tương tác Map Device kích hoạt chuỗi `SetCursorPos` và `mouse_event` chuẩn xác.
3. **Alt-Key Bypass Interlock Test**: Xác minh `ensure_window_focus` thực thi chuỗi đồng bộ thread và Alt keybd_event không gây kẹt phím Alt.
