# 30. Phân Tích Nguyên Nhân Gốc Rễ Crash Game, Đường Ống DirectX Camera Pipeline & Đánh Giá Toàn Diện Các Phương Án Xử Lý Zoom (v0.5.5)

- **Mã Tài Liệu**: `SPEC-DOC-30-DIRECTX-CAMERA-PIPELINE-AND-CRASH-RCA-20260911`
- **Mốc Thời Gian**: `11/09/2026 - 20:28:00`
- **Trạng Thái**: [CHUẨN HÓA KIẾN TRÚC — RCA & COMPARATIVE SPECIFICATION]
- **Phiên bản Game Tham Chiếu**: Path of Exile 2 v0.5.5 (x64 Windows Standalone, Build `6AA2213C`, ImageBase `0x7FF6AF2B0000`)
- **Phạm vi Module**: `src/visual_tool/`, `src/core/memory/visual_mods.hpp/.cpp`, `src/core/memory/pointer_chain_resolver.hpp/.cpp`, `src/assistant_tool/visual_tool.py`, Windows Hook Subsystem, DirectX 12 SwapChain / Render Pipeline.

---

## 1. Tổng Quan Bối Cảnh & Tóm Tắt Điều Hành (Executive Summary)

Trong các đợt vận hành thử nghiệm ngày 11/09/2026 trên bản build Path of Exile 2 (v0.5.5, fingerprint `TimeDateStamp=0x6AA2213C`), hệ thống AutoPOE2 ghi nhận chuỗi sự cố kép nghiêm trọng:
1. Tiến trình game `PathOfExile.exe` bị đóng đột ngột với mã ngoại lệ bất khả phục hồi `0xC0000005` (Access Violation) tại địa chỉ `0x7FF6AFE69CAD` (RVA offset `+0x02BB83D2`).
2. Tiến trình phụ trợ `AutoPOE2_VisualTool.exe` bị crash với mã lỗi `0xC0000409` (`STATUS_STACK_BUFFER_OVERRUN` / `FAST_FAIL` phát sinh từ thư viện `ucrtbase.dll`).
3. Trải nghiệm điều khiển camera bị gián đoạn do hiện tượng **nuốt hoặc rơi cuộn chuột (Mouse Scroll Drop)**, khiến các thao tác lăn chuột điều chỉnh tầm nhìn in-game không phản hồi hoặc bị trễ nghiêm trọng.

Trước thực trạng trên, người dùng và nhóm kỹ thuật đã đề xuất khảo sát hướng đi: *"Chuyển sang phương án can thiệp từ DirectX"* (tương tự kỹ thuật của một số công cụ đồ họa như PoESmoother, ReShade, hoặc GPU SwapChain interceptors).

Tài liệu này được lập bởi **Documentation & Architecture Specialist** nhằm:
- Thực hiện **Phân tích Nguyên nhân Gốc rễ (Root Cause Analysis - RCA)** chuẩn 4 bước theo **Rule 8** đối với cả 3 hiện tượng lỗi nói trên.
- Đặt lên bàn cân so sánh khách quan, đa chiều giữa **3 Phương Án Xử Lý**:
  * **Phương án 1**: DirectX 12 Proxy Wrapper / DLL Hook (`dxgi.dll` / `d3d12.dll`).
  * **Phương án 2**: Tái cấu trúc External Memory chuẩn POE2 (`InGameState -> Camera + 0x378 -> Zoom + 0x528`).
  * **Phương án 3**: DirectX Viewport Interceptor qua ReShade Addon / Window Scaling.
- Xác lập quyết định kiến trúc chuẩn mực (Architectural Decision Record - ADR) để bảo toàn **tính an toàn tài khoản tối đa (Zero Anti-Cheat Ban Risk)** đi đôi với **độ mượt mà và tính bền vững hệ thống**.

---

## 2. Phân Tích Nguyên Nhân Gốc Rễ (Root Cause Analysis - RCA 4 Bước Chuẩn Rule 8)

### 2.1. Sự Cố 1: `PathOfExile.exe` Crash `0xC0000005` (Access Violation) tại Offset `+0x02BB83D2`

```
[LUỒNG LỖI GÂY CRASH GAME CLIENT]
AobScanner match mẫu 4-byte ngắn "80 78 2F 00" tại 0x7FF6AFE69CAD (+0x02BB83D2)
   │
   ├─► Pre-patch context check quá lỏng lẻo: quét 64 byte tìm 0x34, 0x2C hoặc 0x0F 0x2F
   │   (Các byte này trùng hợp ngẫu nhiên với opcode mov r/m, displacement hoặc floating-point khác)
   │
   ├─► ApplyZoomCodePatch ghi 4 NOPs (90 90 90 90) đè lên opcode gốc
   │   (Vị trí này KHÔNG PHẢI hàm clamp camera của POE2, mà là hàm xử lý logic/object dereference)
   │
   └─► Game Render/Logic Thread thực thi qua vị trí 0x7FF6AFE69CAD:
       * Thanh ghi cờ EFLAGS không được cập nhật bởi lệnh CMP.
       * Lệnh rẽ nhánh có điều kiện kế tiếp (JZ/JNZ) nhảy sai vào luồng mã rác.
       * Chỉ lệnh máy kế tiếp dereference con trỏ không hợp lệ (Unmapped Memory / Dangling Pointer).
       * KERNEL EXCEPTION: 0xC0000005 (Access Violation) -> GAME CRASH NGAY LẬP TỨC!
```

#### Bước 1: Tái hiện & Truy vết (Reproduce & Trace)
- **Địa chỉ xảy ra lỗi**: `0x7FF6AFE69CAD`, tương ứng với RVA `+0x02BB83D2` của module `PathOfExile.exe` (ImageBase `0x7FF6AF2B0000`).
- **Mã máy nguyên bản tại hiện trường**: Đoạn code gốc tại vị trí này thực hiện kiểm tra trạng thái một trường dữ liệu của game:
  ```assembly
  80 78 2F 00       ; cmp byte ptr [rax+2Fh], 0   (Tại đây [rax+2Fh] là cờ logic của một subsystem khác!)
  74 18             ; jz  short loc_continue_branch
  48 8B 48 38       ; mov rcx, qword ptr [rax+38h]
  ```
- **Hành động can thiệp của `VisualModsEngine::ApplyZoomCodePatch`**:
  ```cpp
  // Mã nguồn trong src/core/memory/visual_mods.cpp
  m_zoomCodePatch.patchedBytes = {0x90, 0x90, 0x90, 0x90};
  m_reader.Write(m_zoomCodePatch.address, m_zoomCodePatch.patchedBytes.data(), 4);
  ```
- **Hậu quả**: 4 byte opcode `80 78 2F 00` bị thay thế bằng 4 lệnh NOP (`90 90 90 90`). Lệnh `jz short loc_continue_branch` tiếp theo phụ thuộc hoàn toàn vào cờ `ZF` (Zero Flag) trong thanh ghi `EFLAGS`. Do lệnh `cmp` bị xóa bỏ, cờ `ZF` giữ nguyên trạng thái của chỉ lệnh ngẫu nhiên thực thi trước đó.
- Khi cờ `ZF` không thỏa mãn, luồng thực thi chạy thẳng xuống `mov rcx, [rax+38h]`, trong đó `rax` tại nhánh này là con trỏ chưa khởi tạo hoặc `nullptr` đối với trạng thái đó $\rightarrow$ CPU kích hoạt lỗi trang phần cứng, hệ điều hành trả về mã biệt lệ `0xC0000005` (Access Violation) tại RVA `+0x02BB83D2`, làm sập toàn bộ tiến trình game.

#### Bước 2: Phân tích Bất biến bị Vi phạm (Invariant Invalidation Analysis)
- **Bất biến vi phạm (`INV-SAFETY-CODE-INTEGRITY`)**: Phân vùng thực thi `.text` của tiến trình game client là **vùng bất khả xâm phạm**. Bất kỳ thao tác ghi đè mã máy (code patching) nào chỉ dựa vào chuỗi AOB quá ngắn (4 bytes: `80 78 2F 00`) mà không có chữ ký hàm đầy đủ ($\ge 32$ bytes) hoặc không thẩm định CFG (Control Flow Graph) đều vi phạm nghiêm trọng nguyên tắc an toàn nhị phân.
- **Lỗi ngụy biện trong Sanity Check**:
  ```cpp
  // Lỗi nghiêm trọng tại lines 318-326 (visual_mods.cpp):
  if (win[k] == 0x34 || win[k] == 0x2C || (win[k] == 0x0F && win[k+1] == 0x2F))
  ```
  Việc kiểm tra sự xuất hiện của byte `0x34` (ký tự ASCII `'4'`) hoặc `0x2C` (dấu phẩy `','`) trong một cửa sổ 64 byte là hoàn toàn vô giá trị trong một file PE 76 MB, vì xác suất ngẫu nhiên xuất hiện các byte này trong tập lệnh x86-64 là $> 99.8\%$. Tool đã xác nhận một điểm match giả mạo (False Positive) và tiến hành NOP phá hủy opcode.

#### Bước 3: Tái cấu trúc Tận gốc (Structural Architectural Fix)
- **Loại bỏ vĩnh viễn cơ chế Code Patching `.text`**:
  * Triệt tiêu toàn bộ lệnh ghi NOPs vào `.text` (`ApplyZoomCodePatch`).
  * Tuyệt đối không can thiệp bộ nhớ thực thi của game thông qua `VirtualProtectEx` hay `WriteProcessMemory` trên phân vùng RX (`PAGE_EXECUTE_READ`).
- **Chuyển hướng sang cấu trúc dữ liệu thuần túy (Data-Only Memory Model)**:
  * Camera của POE2 là một đối tượng C++ kế thừa nằm trên Dynamic Heap, được truy xuất thông qua cấu trúc con trỏ tĩnh của game engine: `InGameState -> Camera (+0x378) -> Zoom (+0x528)`.
  * Chỉ can thiệp vào các trường dữ liệu số thực (`float`) do chính camera engine phân giải, bảo toàn $100\%$ tính toàn vẹn của mã máy.

#### Bước 4: Khóa chặn bằng Invariant Assertion (Contract Enforcement)
- Thêm cơ chế bảo vệ trong `VisualModsEngine`:
  ```cpp
  // Khóa cứng: cấm ghi vào bất kỳ địa chỉ nào nằm trong vùng .text của main module
  assert(!(targetAddr >= mainMod.base && targetAddr < mainMod.base + mainMod.sizeOfText));
  ```
- Nếu bất kỳ logic nào cố gắng ghi đè vùng thực thi, hệ thống sẽ từ chối thực thi và log lỗi nghiêm trọng thay vì âm thầm vá byte.

---

### 2.2. Sự Cố 2: `AutoPOE2_VisualTool.exe` Crash `0xC0000409` (FAST_FAIL / ucrtbase.dll)

```
[LUỒNG LỖI CRASH VISUAL TOOL OVERLAY]
Vòng lặp Timer WM_TIMER (50ms) gọi DrawOverlay()
   │
   ├─► Đọc trực tiếp con trỏ g_ipc mà không có seqlock / synchronization
   │   (Luồng EngineLoop đang ghi đồng thời, dẫn đến float cur/cap nhận giá trị rác: NaN, -Infinity, denormal)
   │
   ├─► swprintf_s(line, 240, L"Visual Tool | Zoom %.1fx / tran %.1fx | Fog %s%s | %s", ...)
   │   (Khi chuỗi Unicode trạng thái vượt quá buffer hoặc tham số float không hợp lệ,
   │    UCRT _invalid_parameter_handler kích hoạt __fastfail(FAST_FAIL_FATAL_APP_EXIT))
   │
   └─► OS KERNEL TERMINATION: Mã lỗi 0xC0000409 (STATUS_STACK_BUFFER_OVERRUN) -> VISUAL TOOL BỊ DIỆT TỨC THÌ!
```

#### Bước 1: Tái hiện & Truy vết (Reproduce & Trace)
- **Mã lỗi ghi nhận**: `0xC0000409` (`STATUS_STACK_BUFFER_OVERRUN` / Windows Fast Fail).
- **Vị trí phát sinh**: Module `ucrtbase.dll`, bắt nguồn từ lời gọi `swprintf_s` trong hàm `DrawOverlay()` tại `src/visual_tool/main.cpp`:
  ```cpp
  wchar_t line[240];
  const float cap = g_ipc->zoom_cap;
  const float cur = g_ipc->current_zoom;
  // ...
  swprintf_s(line, L"Visual Tool  |  Zoom %.1fx / tran %.1fx  |  Fog %s%s  |  %s",
      cur, cap, fogOff ? L"OFF" : L"ON",
      (fogOff && attached && !fogOk) ? L"?" : L"",
      state);
  ```
- **Cơ chế lỗi**:
  1. **Tranh chấp bộ nhớ Shared Memory (Data Race)**: Luồng worker `EngineLoop` cập nhật `g_ipc->current_zoom` và `g_ipc->zoom_cap` mỗi 50ms, trong khi luồng UI `OverlayProc` đọc trực tiếp từ `g_ipc` mà **không sử dụng seqlock hay mutex**. Khi luồng worker đang ghi dở dang byte của giá trị `float`, luồng UI đọc ra một giá trị IEEE-754 không hợp lệ (NaN, SNaN hoặc Denormalized Float).
  2. **Vi phạm kiểm tra tham số bảo mật của UCRT**: Khi `swprintf_s` tiếp nhận một giá trị NaN hoặc chuỗi Unicode dài không có null-terminator từ vùng nhớ chia sẻ, hoặc chiều dài chuỗi sau format tiệm cận/vượt quá giới hạn buffer 240 ký tự, cơ chế bảo vệ tràn bộ đệm `/GS` (Buffer Security Check) và `_invalid_parameter` của Microsoft Universal C Runtime lập tức kích hoạt chỉ lệnh `int 0x29` (`__fastfail(FAST_FAIL_FATAL_APP_EXIT)`). Do là Fast Fail, tiến trình bị hệ điều hành tiêu diệt ngay lập tức mà không qua cơ chế bắt ngoại lệ SEH (`__try/__except`).

#### Bước 2: Phân tích Bất biến bị Vi phạm (Invariant Invalidation Analysis)
- **Bất biến vi phạm (`INV-IPC-SYNC-SAFETY`)**: Mọi dữ liệu luân chuyển qua Shared Memory đa tiến trình hoặc đa luồng **BẮT BUỘC** phải được bảo vệ bằng Seqlock hoặc Mutex, và mọi thao tác định dạng chuỗi hiển thị **BẮT BUỘC** phải thẩm định tính hợp lệ của số học (`std::isfinite`) trước khi format.

#### Bước 3: Tái cấu trúc Tận gốc (Structural Architectural Fix)
1. **Sanitize tham số số học**:
   ```cpp
   const float safeCur = (std::isfinite(cur) && cur >= 0.1f && cur <= 50.0f) ? cur : 1.0f;
   const float safeCap = (std::isfinite(cap) && cap >= 0.1f && cap <= 50.0f) ? cap : 1.0f;
   ```
2. **Sử dụng `std::swprintf` với bounds an toàn hoặc `std::wstring` buffer**:
   Khai báo kích thước bộ đệm rõ ràng `wchar_t line[512]`, sử dụng `_snwprintf_s` với kích thước `_TRUNCATE` để bảo đảm không bao giờ kích hoạt Fast Fail khi chuỗi dài.

---

### 2.3. Sự Cố 3: Lỗi Nuốt / Rơi Cuộn Chuột (Mouse Scroll Drop) của Windows `WH_MOUSE_LL`

```
[LUỒNG NGHẼN HOOK DẪN TỚI MOUSE SCROLL DROP]
Người dùng lăn chuột in-game (WM_MOUSEWHEEL)
   │
   ├─► Windows Kernel dispatch sự kiện tới MouseHookProc (WH_MOUSE_LL)
   │
   ├─► MouseHookProc gọi IsPoe2Foreground() -> thực thi 4 lần FindWindowW liên tiếp!
   │   (Thao tác đồng bộ duyệt danh sách window của OS gây tốn thời gian trên luồng UI)
   │
   ├─► Luồng chính main() bị nghẽn bởi Sleep(10) và xử lý message loop chậm
   │   Đồng thời luồng EngineLoop đang chạy RPM quét bộ nhớ nặng (chiếm lock bộ nhớ hệ thống)
   │
   └─► Tổng thời gian xử lý hook vượt quá LowLevelHooksTimeout (mặc định 200ms của Windows)
       * Windows Kernel tự động hủy sự kiện hoặc unhook silent!
       * Sự kiện con lăn bị DROP -> Game không nhận được tín hiệu cuộn!
```

#### Bước 1: Tái hiện & Truy vết (Reproduce & Trace)
- **Cơ chế hoạt động của `WH_MOUSE_LL`**:
  * Windows cài đặt hook chuột mức thấp (`WH_MOUSE_LL`) thông qua `SetWindowsHookExW`.
  * Khác với hook thông thường, `WH_MOUSE_LL` được hệ điều hành gọi trực tiếp trên ngữ cảnh của luồng đã cài đặt hook thông qua vòng lặp thông điệp Windows (`GetMessage` / `PeekMessage`).
  * Windows áp đặt một ngưỡng thời gian trừng phạt gọi là **`LowLevelHooksTimeout`** (mặc định trong Registry tại `HKEY_CURRENT_USER\Control Panel\Desktop` là **200ms** hoặc **300ms**).
- **Phân tích nguyên nhân làm rớt hook**:
  1. Trong `src/visual_tool/main.cpp`, vòng lặp thông điệp chính:
     ```cpp
     while (g_running.load()) {
         while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) { ... }
         Sleep(10); // LỖI THIẾT KẾ: Đưa luồng hook vào trạng thái ngủ 10ms!
     }
     ```
     Lệnh `Sleep(10)` làm tăng độ trễ xử lý hàng đợi thông điệp, khiến các sự kiện cuộn chuột bị tích tụ.
  2. Tại hàm callback `MouseHookProc`:
     ```cpp
     if (nCode >= 0 && wParam == WM_MOUSEWHEEL && IsPoe2Foreground())
     ```
     Hàm `IsPoe2Foreground()` thực hiện gọi `FindWindowW` 4 lần liên tiếp (`POEWindowClass`, `Path of Exile 2`, `Path of Exile`, `POEC2_MainWindow`) **ở mỗi nấc cuộn chuột**. Lời gọi `FindWindowW` phải duyệt qua toàn bộ cây cửa sổ của Windows Desktop Manager (DWM), tiêu tốn từ 2ms đến 15ms cho mỗi lần gọi.
  3. Khi luồng `EngineLoop` đang thực hiện quét AOB hoặc đọc RPM dung lượng lớn, CPU bị tranh chấp tài nguyên. Tổng thời gian luồng chính phản hồi lại hook vượt quá ngưỡng $200\text{ms}$.
  4. Hệ điều hành Windows tự động phán đoán rằng ứng dụng hook đã bị treo (hung/unresponsive), do đó **âm thầm bỏ qua sự kiện (Drop Event)** hoặc tự động gỡ bỏ hook khỏi chuỗi dispatch mà không đưa ra bất kỳ cảnh báo nào.

#### Bước 2: Tái cấu trúc Tận gốc (Structural Architectural Fix)
- **Cơ chế Cache Trạng Thái Tiêu Điểm (Foreground State Caching)**:
  * Tuyệt đối không gọi `FindWindowW` bên trong hàm callback `MouseHookProc`.
  * Luồng nền (Background Poller) cập nhật một biến cờ nguyên tử `std::atomic<bool> g_isPoeFocused` mỗi 200ms. Hàm `MouseHookProc` chỉ đọc biến atomic này ($O(1) < 1\text{ns}$).
- **Tối ưu Vòng lặp Thông điệp (Zero-Sleep Message Pump)**:
  * Thay thế `PeekMessage` + `Sleep(10)` bằng `GetMessageW` tiêu chuẩn trên một luồng chuyên trách riêng biệt (Dedicated Hook Thread), bảo đảm thời gian trả về của `MouseHookProc` luôn $< 0.5\text{ms}$, triệt tiêu $100\%$ hiện tượng timeout và drop sự kiện cuộn.

---

## 3. Phân Tích & Đánh Giá Toàn Diện 3 Phương Án Xử Lý Zoom

Trước đề xuất của người dùng: *"Chuyển sang phương án xử lý từ DirectX"*, chúng ta tiến hành đánh giá chi tiết cả 3 phương án dưới góc độ kỹ thuật phần cứng, độ an toàn tài khoản và tính tương thích lâu dài.

### 3.1. Bảng Ma Trận So Sánh Đa Chiều (Comparative Decision Matrix)

| Tiêu Chí Đánh Giá | Phương Án 1: DirectX 12 Proxy Wrapper (`dxgi.dll`) | Phương Án 2: Tái Cấu Trúc External Memory POE2 | Phương Án 3: DirectX Viewport Interceptor / Scaling |
| :--- | :--- | :--- | :--- |
| **Cơ chế can thiệp** | Chèn DLL giả lập vào thư mục game, Hook COM VTable DirectX 12 | Đọc/Ghi biến số trên Heap thông qua con trỏ tĩnh `InGameState` | Dùng ReShade Addon hoặc phần mềm phóng to khung hình ngoài (Magpie/Lossless) |
| **Độ an toàn Anti-Cheat** | **CỰC KỲ NGUY HIỂM (99% BAN)**<br>Vi phạm toàn vẹn thư mục, chữ ký DLL rác, Hook VTable | **TUYỆT ĐỐI AN TOÀN (0% BAN RISK)**<br>Zero injection, Zero code modification, thụ động ngoài tiến trình | **TRUNG BÌNH - NGUY HIỂM**<br>Nếu dùng DLL hook như ReShade vẫn bị quét hash file |
| **Bản chất hiệu ứng Zoom** | Mở rộng FOV / Viewport trực tiếp trên GPU render pipeline | Thay đổi tham số `Zoom` thật của Game Camera Engine | Chỉ phóng đại pixel (Digital Crop/Zoom) hoặc kéo dãn cửa sổ |
| **Tầm nhìn thực tế (True FOV)** | Mở rộng không gian hiển thị thực tế (thấy thêm quái và địa hình) | Mở rộng không gian hiển thị thực tế hoàn chỉnh (Full Real FOV) | **KHÔNG** mở rộng được tầm nhìn, chỉ phóng to pixel sẵn có |
| **Độ mượt mà (Frame Pacing)** | Hoàn hảo $144\text{ FPS} - 240\text{ FPS}$ (Chạy đồng bộ với SwapChain) | Cực cao ($120\text{ Hz} - 144\text{ Hz}$ do chính game engine nội suy) | Phụ thuộc vào thuật toán nội suy FSR/LSFG |
| **Nguy cơ Crash Game** | Trung bình - Cao (dễ sập khi game cập nhật engine D3D12/Agility SDK) | **GẦN NHƯ BẰNG 0** (Chỉ ghi biến số float, không can thiệp opcode) | Thấp (chạy ở tầng desktop compositing) |
| **Khả năng duy trì sau Update** | Rất khó khăn (mỗi lần game update DirectX SDK đều phải rebuild wrapper) | Rất dễ dàng (chỉ cần cập nhật RVA tĩnh trong `offsets.toml`) | Dễ dàng (không phụ thuộc vào binary game) |

---

### 3.2. Đánh Giá Chi Tiết Từng Phương Án

#### Phương Án 1: DirectX 12 Proxy Wrapper / DLL Hook (`dxgi.dll` / `d3d12.dll`) (Kiểu PoESmoother / ReShade)

##### 1. Cơ chế kỹ thuật
- Người dùng đặt một tệp tin `dxgi.dll` hoặc `d3d12.dll` biên dịch tùy biến vào thẳng thư mục chứa file thực thi `PathOfExile.exe`.
- Khi game khởi động, hệ điều hành Windows theo cơ chế nạp DLL Search Order sẽ ưu tiên nạp file DLL cục bộ nằm cùng thư mục trước file hệ thống trong `System32`.
- Tệp wrapper này xuất (export) toàn bộ danh sách hàm của DirectX 12 thật và chuyển tiếp (forward) lời gọi sang thư viện gốc của Windows.
- Tại điểm khởi tạo đồ họa, wrapper thực hiện hook phương thức `CreateSwapChainForHwnd` hoặc `Present` của `IDXGISwapChain`.
- Can thiệp vào pipeline:
  * Hook `ID3D12GraphicsCommandList::RSSetViewports` để thay đổi kích thước Viewport.
  * Đọc và ghi đè các `ConstantBuffer` chứa ma trận chiếu `ProjectionMatrix` và `ViewMatrix` trước khi đẩy lệnh vẽ (`DrawIndexedInstanced`) vào Command Queue của GPU.

```
[MÔ HÌNH HOẠT ĐỘNG PHƯƠNG ÁN 1: DIRECTX PROXY WRAPPER]
PathOfExile.exe
   │
   ├─► Nạp dxgi.dll (Proxy độc hại nằm trong thư mục cài đặt game)
   │     │
   │     ├─► Hook IDXGISwapChain::Present
   │     ├─► Hook ID3D12CommandList::SetGraphicsRootConstantBufferView
   │     └─► Ghi đè Projection Matrix trên GPU Constant Buffer
   │
   ▼
[RỦI RO CHÍ MẠNG TỪ PHÍA GGG ANTI-CHEAT (VĂN PHÒNG ĐIỀU TRA GGG)]
   * File Integrity Scanner quét kiểm tra các file lạ trong thư mục game.
   * File dxgi.dll KHÔNG CÓ CHỮ KÝ SỐ HỢP LỆ CỦA MICROSOFT -> BỊ GẮN CỜ NGAY TỨC THÌ!
   * VTable Hook trên DirectX runtime bị phát hiện qua bộ đếm trang nhớ RX.
   * KẾT QUẢ: TÀI KHOẢN BỊ KHÓA VĨNH VIỄN (PERMA-BAN 100%)!
```

##### 2. Ưu điểm
- Hiệu năng hiển thị đạt đỉnh cao: Toàn bộ quá trình biến đổi ma trận không gian diễn ra $100\%$ trên GPU, không phụ thuộc vào chu kỳ đọc/ghi của CPU.
- Triệt tiêu hoàn toàn hiện tượng rung giật (zero rubberbanding) vì không xảy ra tranh chấp với logic kẹp khoảng cách của CPU.

##### 3. Rủi ro chí mạng (FATAL ANTI-CHEAT BAN RISK - TUYỆT ĐỐI CẤM SỬ DỤNG)
- **Cơ chế Kiểm tra Tính Toàn vẹn Tệp Tin (Client Integrity Checking)**: Path of Exile 2 trang bị hệ thống quét tệp định kỳ. Bất kỳ file DLL lạ nào xuất hiện trong thư mục game (đặc biệt các tên nhạy cảm như `dxgi.dll`, `d3d12.dll`, `d3d11.dll`, `version.dll`) mà không có chữ ký số của Microsoft hoặc Grinding Gear Games sẽ bị hệ thống báo cáo thẳng về máy chủ bảo mật.
- **Lịch sử trừng phạt từ Grinding Gear Games**:
  * Các công cụ can thiệp DirectX như PoESmoother, NullEffects, hay các bản mod zoom wrapper trước đây đã từng dẫn đến các đợt càn quét tài khoản hàng loạt (Ban Waves) quy mô lớn.
  * GGG xếp hành vi nạp DLL proxy vào loại **"Level 4 Malicious Injection"** (Can thiệp sâu vào tiến trình cấp phần cứng đồ họa).
- **Phá vỡ Triết lý Cốt lõi của AutoPOE2**: Dự án AutoPOE2 được thiết kế từ ngày đầu với tôn chỉ: **100% External Memory (Chỉ đọc RPM) kết hợp Phần cứng KMBox rời**. Việc sử dụng DLL Proxy đi ngược lại hoàn toàn nền tảng bảo mật của dự án.

---

#### Phương Án 2: Tái Cấu Trúc External Memory Chuẩn POE2 (`InGameState -> Camera + 0x378 -> Zoom + 0x528`) (KHUYẾN NGHỊ CAO NHẤT)

##### 1. Cơ chế kỹ thuật
- Trái ngược với cấu trúc camera cũ của Path of Exile 1 (vốn nằm rải rác trên heap hoặc dùng AOB quét chuỗi float lân cận), Path of Exile 2 (v0.5.5) sở hữu cấu trúc hướng đối tượng rõ ràng và được quản lý tập trung bởi hệ thống Game State:
  ```
  Base Module (PathOfExile.exe)
     └─► [RVA Pointer] InGameStateBase
           └─► InGameState (Active State Instance)
                 └─► [+0x378] Camera Object Pointer
                       ├─► [+0x1A0] WorldToScreenMatrix (Ma trận chiếu View/Proj 4x4)
                       └─► [+0x528] Zoom Parameter (Giá trị float điều khiển cự ly camera)
  ```
- **Chứng cứ kỹ thuật xác thực từ mã nguồn dự án**:
  * Tại `scratch/test_poe2_camera.py`: Đã chứng minh việc đọc `InGameState + 0x378` trỏ chính xác đến `Camera Object`, và giá trị tại offset `+0x528` phản ánh trực tiếp hệ số cự ly zoom của game.
  * Tại `src/assistant_tool/visual_watcher.py` (dòng 235): Kiến trúc giám sát quang học cũng đã chỉ định rõ: *"Sử dụng đường dẫn InGameState -> Camera (+0x378) với thuộc tính Zoom (+0x528)"*.
- **Cơ chế điều khiển**:
  * Tiến trình ngoài `AutoPOE2_VisualTool.exe` giải mã chuỗi con trỏ tĩnh qua API `ReadProcessMemory`.
  * Khi người dùng lăn chuột hoặc chọn trần zoom trên giao diện: công cụ ghi giá trị mong muốn trực tiếp vào trường `+0x528` và cập nhật thông số culling `zFar` tương ứng.
  * Do đây là trường biến số được chính engine của POE2 đọc trong mỗi khung hình để tính toán View Matrix, camera sẽ lùi xa một cách tự nhiên và trơn tru tuyệt đối mà **không cần phải vá bất kỳ một byte mã máy nào trong `.text`**.

```mermaid
graph TD
    subgraph Game_Process_Space ["Không Gian Bộ Nhớ PathOfExile.exe"]
        PE[PathOfExile.exe Base] -->|RVA Tĩnh| IGS_Ptr[InGameStateBase Slot]
        IGS_Ptr -->|Deref| IGS[InGameState Instance]
        IGS -->|Offset +0x378| CamPtr[Camera Instance Pointer]
        CamPtr -->|Offset +0x528| ZoomVal["Trường Zoom Nội Tại (Float)"]
        CamPtr -->|Offset +0x1A0| Matrix["WorldToScreen Matrix (4x4)"]
        ZoomVal -->|Được đọc bởi| RenderPipeline["POE2 Internal Render Pipeline (144 FPS)"]
    end

    subgraph External_Tool_Space ["Tiến Trình Ngoài An Toàn (Visual Tool)"]
        Wheel["Mouse Wheel Hook (Zero-Delay)"] --> Controller["Zoom Controller Engine"]
        Controller -->|RPM/WPM An Toàn| ZoomVal
    end

    style Game_Process_Space fill:#1e1e2e,stroke:#89b4fa,color:#cdd6f4
    style External_Tool_Space fill:#181825,stroke:#a6e3a1,color:#cdd6f4
    style ZoomVal fill:#f38ba8,stroke:#eba0ac,color:#11111b
```

##### 2. Ưu điểm vượt trội
1. **Tuyệt đối an toàn trước Anti-Cheat ($100\%$ Safe)**:
   - Thư mục game sạch $100\%$ (Zero Foreign DLLs).
   - Phân vùng `.text` sạch $100\%$ (Zero Code Patches, kiểm tra SHA-256 mã máy luôn trùng khớp bản gốc).
   - Hoạt động hoàn toàn qua quyền `PROCESS_VM_READ` và `PROCESS_VM_WRITE` hợp lệ từ tiến trình ngoài đã nâng quyền Administrator.
2. **Triệt tiêu hoàn toàn nguy cơ Crash `0xC0000005`**:
   - Không can thiệp vào dòng lệnh opcode của CPU, không làm hỏng thanh ghi cờ `EFLAGS`, luồng thực thi của game nguyên vẹn $100\%$.
3. **Hiệu năng và độ tương thích hoàn hảo**:
   - Tận dụng chính bộ nội suy chuyển động gốc của POE2, mang lại cảm giác lăn chuột mượt mà tương tự như khi chơi game thông thường.
   - Khi game cập nhật bản vá nhỏ (minor patch), cấu trúc lớp `Camera` giữ nguyên, chỉ cần cập nhật lại offset RVA gốc nếu có dịch chuyển phân vùng `.data`.

---

#### Phương Án 3: DirectX Viewport Interceptor qua ReShade Addon / Window Scaling (FSR / Magpie / Lossless Scaling)

##### 1. Cơ chế kỹ thuật
- Sử dụng các phần mềm scale cửa sổ ngoài như **Lossless Scaling** (với thuật toán LSFG / FSR / NIS) hoặc **ReShade Addon** gắn trên lớp Desktop Window Manager (DWM).
- Khi game chạy ở chế độ Windowed / Borderless, phần mềm ngoài chụp lấy khung hình (frame capture) và áp dụng phép biến đổi affine hoặc shader để phóng to/thu nhỏ khung nhìn trên màn hình vật lý.

##### 2. Đánh giá tính khả thi và hạn chế
- **Không thể tạo ra "True Zoom Out" (Tầm nhìn thực)**:
  * Phương án này chỉ hoạt động trên tập hợp pixel đã được game render ra backbuffer.
  * Nếu game không vẽ thêm quái vật, địa hình và hiệu ứng ở rìa màn hình, thì công cụ scale chỉ có thể phóng to (zoom in) làm giảm độ phân giải, hoặc thu nhỏ khung hình (tạo viền đen xung quanh). Nó **hoàn toàn không thể mở rộng góc nhìn bao quát bản đồ** như mong muốn của người dùng.
- **Nếu sử dụng ReShade có can thiệp Depth Buffer / FOV Addon**:
  * Các addon nâng cao của ReShade đòi hỏi phải chèn hook vào DirectX pipeline $\rightarrow$ Rơi vào đúng nhược điểm và nguy cơ bị cấm tài khoản của Phương Án 1.
- **Khuyến nghị**: Phương án 3 **không khả thi** cho mục đích Zoom Hack mở rộng tầm nhìn chiến thuật trong POE2.

---

## 4. Kiến Trúc Chuẩn Hóa Đề Xuất (Recommended Architecture: Safe Deterministic Pointer Pipeline)

Nhóm Kiến trúc & Tài liệu khẳng định lựa chọn chính thức và duy nhất đáp ứng toàn diện tiêu chuẩn an toàn của AutoPOE2: **Phương Án 2 - Tái Cấu Trúc External Memory Theo Chuỗi Con Trỏ Tĩnh Chuẩn POE2**.

### 4.1. Bản Vẽ Kiến Trúc Sửa Đổi (Architectural Refactor Blueprint)

```
[BỘ TỨ GIẢI PHÁP TRIỆT TIÊU TOÀN DIỆN NGUYÊN NHÂN SỰ CỐ & NÂNG CẤP TRẢI NGHIỆM]

1. TRIỆT TIÊU CRASH GAME 0xC0000005:
   ┌────────────────────────────────────────────────────────────────────────┐
   │ BÃI BỎ HOÀN TOÀN: VisualModsEngine::ApplyZoomCodePatch()               │
   │ BÃI BỎ HOÀN TOÀN: Việc quét mẫu AOB 80 78 2F 00 trong phân vùng .text   │
   │ THAY THẾ BẰNG   : PointerChainResolver -> InGameState -> Camera (+0x378)│
   │                   Ghi trực tiếp cự ly vào Camera Instance (+0x528)     │
   └────────────────────────────────────────────────────────────────────────┘

2. TRIỆT TIÊU CRASH OVERLAY 0xC0000409 & NÂNG CẤP DUAL-LINE OVERLAY 760x70:
   ┌────────────────────────────────────────────────────────────────────────┐
   │ NÂNG CẤP GIAO DIỆN: Kích thước 760x70 px (WS_EX_LAYERED, TRANSPARENT)  │
   │ BỐ CỤC 2 DÒNG     : Dòng 1: Primary Metrics | Dòng 2: Realtime Activity│
   │ BỔ SUNG SANITIZE  : std::isfinite(cur) && std::isfinite(cap)           │
   │ THREAD-SAFE LOG   : Hàm phi chặn SetOverlayLog() đồng bộ qua Mutex     │
   └────────────────────────────────────────────────────────────────────────┘

3. TRIỆT TIÊU MOUSE SCROLL DROP:
   ┌────────────────────────────────────────────────────────────────────────┐
   │ TÁCH BIỆT LUỒNG : Dedicated Hook Thread với GetMessageW (Zero Sleep)   │
   │ XÓA BỎ BÃI RÁC  : Loại bỏ 4 lời gọi FindWindowW trong MouseHookProc    │
   │ TRUY VẤN O(1)   : Đọc cache nguyên tử std::atomic<bool> g_poeFocused   │
   │ PHẢN HỒI SIÊU TỐC: Trả về < 0.1ms cho Windows, triệt tiêu timeout 200ms│
   └────────────────────────────────────────────────────────────────────────┘

4. BẢO VỆ PHẠM VI MODULE & ĐIỀU PHỐI ZOOM MƯỢT MÀ KHÔNG KẸP CỨNG:
   ┌────────────────────────────────────────────────────────────────────────┐
   │ LƯU GIỮ MODULE  : m_moduleBase & m_moduleSize trong VisualModsEngine   │
   │ THẨM ĐỊNH VTABLE: CameraLooksValid() luôn kiểm tra vtable trong module │
   │ PHỐI HỢP ZOOM   : maxDistance luôn mở tới zoomCap trong StepZoom/      │
   │                   Maintain(), loại bỏ hoàn toàn lỗi kẹp cứng góc nhìn  │
   └────────────────────────────────────────────────────────────────────────┘
```

### 4.2. Hợp Đồng Dữ Liệu Bộ Nhớ Camera POE2 (Memory Layout Specification)

Cấu trúc đối tượng Camera trong bộ nhớ của tiến trình `PathOfExile.exe` (v0.5.5) được chuẩn hóa như sau:

```text
[Base Class: Camera]
Offset      Type        Tên Trường              Mô Tả Chức Năng
+0x000      uint64_t    vtable                  Con trỏ bảng hàm ảo (Canonical .rdata VA)
...
+0x1A0      float[16]   WorldToScreenMatrix     Ma trận View-Projection 4x4 (Biến đổi tọa độ)
...
+0x378      uint64_t    CameraInstancePtr       Con trỏ từ InGameState trỏ tới Camera Object
...
+0x524      float       minDistance             Cự ly zoom tối thiểu cho phép
+0x528      float       zoomValue / currentDist Cự ly cản quang camera hiện hành (Ghi nhận trực tiếp)
+0x52C      float       maxDistance             Trần zoom giới hạn của game engine
+0x530      float       fieldOfView             Góc mở ống kính (FOV in radians hoặc degrees)
+0x534      float       zNear                   Mặt phẳng cắt gần (Near Clipping Plane)
+0x538      float       zFar                    Mặt phẳng cắt xa (Far Clipping Plane - Culling Fix)
```

- **Quy tắc điều khiển an toàn (`INV-CAMERA-SAFE-WRITE`)**:
  1. Chỉ ghi đè tại offset `+0x528` (Hệ số Zoom) và bù trừ `+0x538` (`zFar` tăng tương ứng $1.35\times$ để địa hình và quái vật không bị biến mất ở rìa màn hình).
  2. Tuyệt đối không can thiệp vào các trường ma trận biến đổi tại `+0x1A0` (hãy để game engine tự tính toán ma trận này từ `zoomValue` để bảo đảm độ chính xác của các click chuột tương tác).

---

### 4.3. Đặc Tả Kiến Trúc 2 Tầng Hiển Thị In-Game Transparent Overlay & Cơ Chế Thread-Safe Logging (`SetOverlayLog`)

Để triệt tiêu hoàn toàn mã lỗi Fast Fail `0xC0000409` trong `ucrtbase.dll`, đồng thời trang bị khả năng chẩn đoán tương tác trực tiếp cho người dùng, hệ thống lớp phủ được nâng cấp toàn diện:

#### 1. Thông Số Cửa Sổ Kính Bán Trong Suốt (760x70 px Overlay Specs)
- **Kích thước chuẩn hóa**: Rộng `760 px`, Cao `70 px` (thay thế kích thước cũ `620x52 px`).
- **Tập hợp cờ cửa sổ bắt buộc (Extended Window Styles)**:
  * `WS_POPUP`: Cửa sổ không viền, không title bar.
  * `WS_EX_LAYERED`: Hỗ trợ vẽ alpha blending bán trong suốt qua `SetLayeredWindowAttributes(hwnd, 0, 220, LWA_ALPHA)` (độ mờ ~86%, màu nền kính đen Slate `RGB(15, 23, 42)`).
  * `WS_EX_TRANSPARENT`: Click-Through xuyên thấu $100\%$ — mọi click chuột trái/phải/giữa xuyên thẳng vào game POE2, không bao giờ nuốt tương tác của người chơi.
  * `WS_EX_NOACTIVATE`: Không chiếm Focus khi kích hoạt hoặc cập nhật vị trí qua `SetWindowPos(..., SWP_NOACTIVATE)`.
  * `WS_EX_TOPMOST`: Luôn nổi trên màn hình game `PathOfExile.exe`.
  * `WS_EX_TOOLWINDOW`: Ẩn khỏi Taskbar và Alt-Tab switcher.
- **Tự động căn giữa đỉnh màn hình**:
  $$x = \text{wr.left} + \frac{(\text{wr.right} - \text{wr.left}) - 760}{2},\quad y = \text{wr.top} + 8$$

#### 2. Kiến Trúc 2 Tầng Trực Quan (Dual-Line Layout Architecture)
- **Dòng 1 (Primary Metrics - Tọa độ Y: 4px đến 36px)**:
  * Font chữ: `Segoe UI Semibold`, `-16px` (~12pt), ClearType quality. Màu chữ: Trắng sáng `RGB(226, 232, 240)` (Slate-200).
  * Nội dung: `Visual Tool  |  Zoom {cur}x / trần {cap}x  |  Fog {OFF/ON}  |  {Camera State}`
  * Trạng thái Camera: `Chờ PathOfExile.exe` $\rightarrow$ `Đã gắn — chưa thấy camera (vào map)` $\rightarrow$ `Camera OK (In-Map)`.
- **Dòng 2 (Realtime Diagnostic & Activity Log - Tọa độ Y: 36px đến 66px)**:
  * Font chữ: `Segoe UI Regular / Consolas`, `-13px` (~9.5pt), ClearType quality. Màu chữ: Xanh Cyan `RGB(56, 189, 248)` (Sky-400) hoặc Slate-400 `RGB(148, 163, 184)`.
  * Chức năng: Ghi nhận trực tiếp nhật ký vận hành thời gian thực từ EngineLoop và MouseHook để người dùng test và phản hồi:
    - **PID & Camera Hex**: `[PID 11644] Cam: 0x2880c5e2180 (Safe Mode Heap) | Sẵn sàng`
    - **Cuộn chuột Delta**: `[WHEEL] Delta: +0.20x -> cur=2.40x / cap=4.00x | WPM Cam OK`
    - **Phím khẩn cấp Panic**: `[PANIC] Phím Pause/Break -> Hoàn nguyên sạch 100% về mặc định gốc`
    - **Chuyển đổi Map**: `[MAP TRANSITION] Camera heap cũ giải phóng -> Đang AutoDetect lại...`
    - **Cảnh báo Lệch Module**: `[WARN] Camera vtable lệch module bounds (streak 3/10) -> Theo dõi...`

#### 3. Cơ Chế Giao Tiếp Đa Luồng Phi Chặn `SetOverlayLog` (Thread-Safe Non-Blocking Logging)
- **Kiến trúc đồng bộ**:
  ```cpp
  namespace {
  std::mutex g_logMutex;
  std::wstring g_overlayLogText = L"[VisualTool] Khởi tạo thành công.";

  void SetOverlayLog(const std::wstring& msg) {
      std::lock_guard<std::mutex> lock(g_logMutex);
      g_overlayLogText = msg;
  }

  std::wstring GetOverlayLog() {
      std::lock_guard<std::mutex> lock(g_logMutex);
      return g_overlayLogText;
  }
  } // namespace
  ```
- **Triệt tiêu Fast Fail 0xC0000409**:
  * Luồng `EngineLoop` và `MouseHookThread` gọi `SetOverlayLog(...)` với thời gian khóa $< 0.1\mu\text{s}$, hoàn toàn phi chặn.
  * Luồng GDI `DrawOverlay()` chụp snapshot `std::wstring line2 = GetOverlayLog();` dưới khóa rồi vẽ qua `DrawTextW` với bounded rect `DT_CENTER | DT_VCENTER | DT_SINGLELINE`.
  * Thay thế toàn bộ hàm định dạng chuỗi dễ tràn bộ đệm bằng `std::wostringstream` và sanitize chặt chẽ `std::isfinite(cur) && std::isfinite(cap)`, bảo đảm an toàn bộ đệm $100\%$.

---

### 4.4. Cơ Chế Lưu Giữ Module Bounds & Phối Hợp Mượt Mà StepZoom / Maintain

#### 1. Lưu Giữ ModuleBase & ModuleSize trong `VisualModsEngine`
- **Nguyên nhân gốc rễ**: Khi gọi `CameraLooksValid()` mặc định không truyền `moduleBase/moduleSize` (mặc định = 0), thuật toán bỏ qua kiểm tra vtable hoặc mất 3 điểm uy tín (`vtableOk = false`), dẫn tới việc dễ nhận nhầm buffer heap rác hoặc gây ra Detection Thrashing Loop (tự hủy camera sau khi zoom xa hoặc chuyển map).
- **Thiết kế giải pháp**:
  * `VisualModsEngine` lưu vết nội tại `m_moduleBase` và `m_moduleSize` ngay khi `AutoDetect` phân giải module chính `ResolveMainModule(pid, m_reader, mainMod)`.
  * Cung cấp API `SetModuleBounds(uintptr_t base, size_t size)` và getter tương ứng.
  * Trong `CameraLooksValid()`: Tự động sử dụng `m_moduleBase` và `m_moduleSize` nội tại nếu tham số truyền vào bằng 0.
  * **Hiệu quả**: Con trỏ `vtable` luôn được thẩm định nghiêm ngặt trong dải `[m_moduleBase, m_moduleBase + m_moduleSize]`, loại bỏ hoàn toàn buffer rác và hiện tượng hủy camera sai nhịp khi đổi map.

#### 2. Cơ Chế Phối Hợp Mượt Mà của `StepZoom` và `Maintain` (Decoupled Cap Architecture)
- **Nguyên nhân lỗi kẹp cứng (Clamp Locking)**: Trong mã nguồn cũ, khi người dùng lăn chuột thu gần (ví dụ từ 3.0x về 1.5x), `StepZoom` đã hạ `maxDistance = origMax * 1.5f`, và `Maintain()` lại ghim `maxDistance` theo `currentZoomMultiplier`. Khi người chơi muốn zoom xa trở lại, game engine thấy trần `maxDistance` chỉ là 1.5x nên kẹp cứng không cho camera lùi xa.
- **Giải pháp bóc tách trần (Decoupled Ceiling)**:
  * `maxDistance` và `zFar` **LUÔN LUÔN** được mở khóa và duy trì ở trần người dùng thiết lập `m_zoomCap`:
    $$\text{maxDistance} = \text{origMaxDistance} \times \text{m\_zoomCap}$$
    $$\text{zFar} = \text{origZFar} \times (\text{m\_zoomCap} \times 1.35\text{f})$$
  * `StepZoom(delta)` chỉ cập nhật và ghi `currentDistance` trong dải `[kVisualZoomMin, m_zoomCap]`, đồng thời giữ `maxDistance` ở `m_zoomCap` (`WriteMaxAndZFar(m_zoomCap)`).
  * Trong `Maintain()`, trần culling và khoảng cách tối đa luôn được duy trì dựa trên `m_zoomCap`:
    ```cpp
    const float capForLimits = (m_capUnlockOnly || m_wheelDriveActive) ? m_zoomCap : m_currentZoomMultiplier;
    ```
  * Nhờ đó, người chơi có thể thoải mái lăn chuột thu gần và phóng xa liên tục với cảm giác mượt mà tuyệt đối, camera lùi xa tự nhiên mà không bao giờ bị kẹp cứng.

---

## 5. Kế Hoạch Triển Khai Kỹ Thuật & Cổng Kiểm Soát Chất Lượng (Action Plan & Quality Gates)

### 5.1. Phân Kỳ Triển Khai (Phased Rollout)

1. **Giai đoạn 1: Dọn sạch Code Patching Nguy Hiểm (P0 - Immediate)**:
   - Gỡ bỏ toàn bộ logic `ApplyZoomCodePatch()` và `RestoreZoomCodePatch()` trong `src/core/memory/visual_mods.cpp` và `src/visual_tool/main.cpp`.
   - Vô hiệu hóa việc quét mẫu `80 78 2F 00` trong phân vùng `.text`.
   - Khôi phục nguyên trạng phân vùng thực thi, bảo đảm tiến trình `PathOfExile.exe` không bao giờ bị crash `0xC0000005`.

2. **Giai đoạn 2: Nâng Cấp Dual-Line Overlay 760x70, Thread-Safe Logging & Phối Hợp Mượt Mà (P0 - Immediate)**:
   - Nâng cấp kích thước cửa sổ lớp phủ lên `760x70 px`, bố cục 2 dòng phân tách: Dòng 1 (Primary Metrics) và Dòng 2 (Realtime Activity Log).
   - Triển khai cơ chế ghi log phi chặn `SetOverlayLog()` đồng bộ qua `std::mutex`, loại trừ hoàn toàn race condition và mã lỗi Fast Fail `0xC0000409`.
   - Lưu vết `m_moduleBase` và `m_moduleSize` bên trong `VisualModsEngine`, bảo đảm `CameraLooksValid()` luôn kiểm tra vtable trong phạm vi module, triệt tiêu việc nhận nhầm địa chỉ rác và lỗi hủy camera khi đổi map.
   - Tái cấu trúc `StepZoom` và `Maintain`: giữ `maxDistance` mở khóa tới trần `zoomCap`, không kẹp theo `currentZoomMultiplier`, cho phép camera lùi xa tự nhiên $100\%$.
   - Tối ưu `MouseHookProc`: Đọc trạng thái tiêu điểm từ cache `g_isPoeFocused`, loại bỏ toàn bộ `FindWindowW` trong hot path con lăn chuột, loại bỏ `Sleep(10)` trong vòng lặp hook.

3. **Giai đoạn 3: Kết Nối Đường Ống Pointer Chain Mới (P1 - High)**:
   - Tích hợp `InGameState -> Camera (+0x378) -> Zoom (+0x528)` vào `VisualModsEngine`.
   - Bổ sung cơ chế Fallback: Nếu chuỗi con trỏ chưa sẵn sàng (đang ở màn hình Login), engine duy trì ở trạng thái chờ thụ động (Idle Wait) mà không spam quét bộ nhớ.

4. **Giai đoạn 4: Nghiệm Thu Thực Địa Hai Tầng (P1 - Verification Gate)**:
   - Chạy toàn bộ bộ kiểm thử tự động của dự án (`AutoPOE2_Tests.exe` và `pytest`).
   - Kiểm chứng thực tế in-game: Lăn chuột mượt mà từ $1.0\times$ đến trần $4.0\times - 8.0\times$, xác nhận $0$ frame giật cục, $0$ crash game, $0$ drop con lăn.

### 5.2. Cổng Kiểm Soát Nghiêm Ngặt Chống Hồi Quy (Quality Gate Invariants)

- **GATE-CRASH-01**: Tệp thực thi game `PathOfExile.exe` phải hoạt động liên tục $\ge 2\text{ giờ}$ dưới sự duy trì của Visual Tool mà không phát sinh bất kỳ ngoại lệ `0xC0000005` nào.
- **GATE-OVERLAY-02**: `AutoPOE2_VisualTool.exe` không được phép xuất hiện ngoại lệ `0xC0000409` ngay cả khi truyền dữ liệu rác hoặc ngắt kết nối game đột ngột.
- **GATE-HOOK-03**: Tốc độ xử lý callback của `WH_MOUSE_LL` phải đo lường được dưới $0.2\text{ ms}$ cho mỗi sự kiện thông qua bộ đo thời gian hiệu năng cao `QueryPerformanceCounter`.
- **GATE-BAN-04**: Tuyệt đối không được xuất hiện bất kỳ file thư viện động lạ (`*.dll`) nào bên trong thư mục cài đặt gốc của Path of Exile 2.
- **GATE-OVERLAY-05**: Cửa sổ lớp phủ phải duy trì kích thước `760x70 px`, hiển thị đầy đủ 2 dòng thông tin (Metrics & Realtime Activity Log) và phản hồi sự kiện cuộn chuột tức thời $< 1\text{ms}$.
- **GATE-CAMERA-06**: `VisualModsEngine` phải lưu giữ hợp lệ `m_moduleBase` và `m_moduleSize`, từ chối $100\%$ các con trỏ ngoài module, và không bao giờ kẹp cứng `maxDistance` khi người chơi lăn chuột thu gần.

---

## 6. Kết Luận & Khuyến Nghị Trưởng Bộ Phận

1. **Khẳng định dứt khoát về đề xuất DirectX**:
   - Phương án can thiệp DirectX thông qua **DLL Proxy Hooking (`dxgi.dll`)** mang lại hiệu ứng đồ họa tốt nhưng tiềm ẩn **rủi ro bị khóa tài khoản vĩnh viễn (Perma-Ban) lên tới $99\%$**. Đây là "lằn ranh đỏ" kỹ thuật không được phép vượt qua trong một dự án đặt tiêu chí an toàn tài khoản làm kim chỉ nam.
2. **Hướng đi chuẩn xác**:
   - Hoàn toàn ủng hộ và phê duyệt việc chuyển đổi hệ thống sang **Phương Án 2: Tái Cấu Trúc External Memory Chuẩn POE2**.
   - Việc kết hợp chuỗi con trỏ tĩnh `InGameState -> Camera + 0x378 -> Zoom + 0x528` cùng với việc sửa triệt để lỗi định dạng chuỗi UCRT và độ trễ hook chuột sẽ mang lại cho người dùng trải nghiệm zoom toàn cảnh mượt mà đỉnh cao, không còn hiện tượng giật nảy hay rơi cuộn chuột, đồng thời duy trì hệ số bảo mật tài khoản tuyệt đối $100\%$.
