# Đặc Tả Kiến Trúc Tiền Thực Thi: Giải Mã Chuỗi Con Trỏ Tất Định $O(1)$ (`InGameState -> AreaInstance -> LocalPlayer -> Components`) & Triệt Tiêu Vĩnh Viễn Logic Quét Heuristic Lỗi Thời

- **Mã Tài Liệu**: `DOC-DEV-23-DETERMINISTIC-POINTER-CHAIN-SPEC`
- **Mốc Thời Gian Báo Cáo**: 10/09/2026 07:38:00 (Bối cảnh Path of Exile 2 - Patch 0.5.5 Forbidden Rites League)
- **Trạng Thái**: `[PRE-IMPLEMENTATION SPECIFICATION / RATIFIED]`
- **Tác Giả**: Sub-Agent `[Documentation & Architecture Specialist]` (Tuân thủ nghiêm ngặt Rule 6 & Rule 10)
- **Đối Tượng Phối Hợp**: Tier 1 C++23 Low-Level Core Engine (`src/core/`) & Tier 2 Python 3.11 Passive Companion HUD (`src/assistant_tool/`)

---

## 1. Tuyên Ngôn Kiến Trúc & Tầm Nhìn Hệ Thống (Architectural Manifesto)

Dự án **AutoPOE2** được thiết kế dựa trên triết lý cốt lõi: **Hiệu năng cực cao (Zero-Latency), Độ ổn định tuyệt đối (Rock-Solid Resilience), và An toàn tài khoản tối đa (Passive Stealth & Zero-Detection)**.

Trong các giai đoạn sơ khai của dự án, khi cấu trúc bộ nhớ nội tại của Path of Exile 2 (v0.5.5 x64 Engine) chưa được dịch ngược hoàn chỉnh, hệ thống đã phải dựa vào một số giải pháp tình thế mang tính **Heuristic (phỏng đoán)**:
1. **Quét Vi Sai Biến Thiên Động Học (Differential Float Scanning)**: Chụp lại toàn bộ các biến `float` trên heap khi nhân vật đứng yên (`CAPTURING_STILL_BASELINE`), sau đó phát một xung di chuyển vi mô (`Micro-Step` tap W 45ms hoặc click chuột) rồi so sánh độ lệch delta float để tìm tọa độ XYZ.
2. **Quét Heap Vét Cạn Brute-Force 8GB RAM**: Khi không có địa chỉ con trỏ, hàm `AutoScanHP(0, 0, 0)` trong `PlayerFinder` quét mù quáng toàn bộ không gian bộ nhớ ảo $2^{64}-1$ từ đầu đến cuối nhằm tìm kiếm bộ ba số nguyên `(curHP, maxHP, reservedHP)`.
3. **Quái Vật Ảo Tưởng ("Phantom Monsters")**: Khi cơ chế quét mảng entity gặp khó khăn, các heuristic dự phòng đã quét mò raw float xung quanh `m_playerAddr` và tự tạo ra các thực thể giả định với máu `100/100` (`Hostile Monster`) để feed cho bot chiến đấu thử nghiệm.

Các giải pháp heuristic trên đã hoàn thành vai trò lịch sử trong giai đoạn nghiên cứu ban đầu, nhưng khi bước vào vận hành thương mại tự động dài hạn, chúng bộc lộ những khiếm khuyết chết người:
- **Độ trễ khổng lồ**: Quét 8GB RAM tốn từ $1500\text{ms}$ đến $4000\text{ms}$, gây đơ giật chu kỳ vòng lặp 120Hz của Core Engine.
- **Rủi ro bế tắc (Deadlock)**: Khi nhân vật bị kẹt Grace Period hoặc đứng yên trên đầm lầy Sandswept Marsh, vi sai không có delta float khiến hệ thống kẹt cứng vĩnh viễn ở trạng thái `WAITING_FIRST_STEP`.
- **Nguy cơ vi phạm an toàn tài khoản (Detection Risk)**: Việc tự ý phát xung phím/chuột `Micro-Step` vi phạm nghiêm trọng nguyên tắc **Passive Interlock**; bot có thể click nhầm vào nút UI, kỹ năng không mong muốn hoặc bị anti-cheat phát hiện do hành vi input cơ học lặp đi lặp lại.
- **Tấn công vào hư không (Ghost Combat)**: Quái vật ảo khiến bot xả chiêu vào khoảng trống, lãng phí mana và làm lộ rõ hành vi bất thường.

Tài liệu này xác lập **Cuộc Chuyển Đổi Kiến Trúc Toàn Diện (Paradigm Shift)**: Triệt tiêu vĩnh viễn toàn bộ các heuristic lỗi thời, thay thế bằng **Cơ Chế Giải Mã Chuỗi Con Trỏ Tất Định $O(1)$ (Deterministic Pointer Chain Traversal)** với thời gian truy xuất dưới **$0.001\text{ms}$** ($< 1.2\mu\text{s}$), bảo đảm tính bất biến, hiệu năng siêu việt và an toàn tuyệt đối.

---

## 2. Bảng Đối Chiếu Bản Chất: Quét Heuristic Cũ vs Chuỗi Con Trỏ Tất Định Mới

| Tiêu Chí Đánh Giá | Heuristic Cũ (Differential / Brute-Force Heap Scan) | Kiến Trúc Mới (Deterministic Pointer Chain $O(1)$) | Đánh Giá Cải Tiến |
| :--- | :--- | :--- | :--- |
| **Độ phức tạp thuật toán** | $O(N)$ (duyệt hàng chục triệu bytes heap) | $O(1)$ (đúng 4 lần dereference con trỏ) | **Tối ưu $10^6$ lần** |
| **Thời gian thực thi** | $1500\text{ms} - 4000\text{ms}$ (thậm chí bế tắc vô hạn) | $< 0.0012\text{ms}$ ($1.2\text{ microseconds}$) | **Tức thời (0ms perceived latency)** |
| **Số lần Syscall RPM** | $150 - 500$ syscalls `ReadProcessMemory` | Đúng $4$ syscalls (hoặc 1 Batch RPM) | **Giảm 99.2% tải CPU kernel** |
| **Phụ thuộc trạng thái nhân vật** | Bắt buộc phải di chuyển (`Micro-Step`) để sinh vi sai | Đọc trực tiếp struct, đứng yên $100\%$ vẫn đọc đúng | **Xóa bỏ hoàn toàn deadlock** |
| **Hành vi Input cơ học** | Tự ý giả lập phím W / click chuột phá Grace Period | $100\%$ Passive RAM Read (Zero Emulation / Zero Key) | **Triệt tiêu rủi ro Anti-Cheat** |
| **Xử lý Chuyển Map / Portal** | Bị đơ $2-4\text{s}$, phải quét lại baseline từ đầu | Tự động trỏ sang struct mới ngay tick $0\text{ms}$ | **Mượt mà tuyệt đối giữa các map** |
| **Độ chính xác Vitals & XYZ** | Dễ nhận diện nhầm Minion HP, UI Marker (778/779) | Đọc đúng $100\%$ từ `LifeComponent` & `PositionComponent` | **Triệt tiêu 100% False Positives** |
| **Độ tin cậy Radar Quái vật** | Nguy cơ sinh quái ảo 100/100 khi float trôi dạt | Đọc trực tiếp từ `EntityList` trong `AreaInstance` | **Zero Ghost Monsters** |

---

## 3. Đặc Tả Cấu Trúc Chuỗi Con Trỏ Tất Định (Deterministic Pointer Chain Architecture)

### 3.1. Sơ Đồ Cây Phân Cấp Dữ Liệu Bộ Nhớ (Hierarchical Object Tree)

Trong Game Engine của Path of Exile 2 (x64 Windows), toàn bộ thế giới game được quản lý theo mô hình Singleton phân cấp chặt chẽ:

```mermaid
graph TD
    subgraph PE_Module ["Module Bộ Nhớ PathOfExile.exe"]
        Base[".text / .data Base Address (0x140000000 + ASLR)"]
        RVA["Static Pointer / RVA (g_InGameStatePtr)"]
        Base --> RVA
    end

    subgraph Engine_Singleton ["Game Engine State Management"]
        RVA -->|"Dereference (RPM)"| InGame["InGameState Singleton (Heap)"]
        InGame -->|"+0x04 / +0x08"| AreaMeta["AreaId, AreaSeed, GameTick"]
        InGame -->|"+0x90 (OFF_AreaInstance)"| Area["Current AreaInstance (Heap)"]
    end

    subgraph Area_Data ["Area Context (Map / Sub-Instance)"]
        Area -->|"+0x188 (OFF_LocalPlayer)"| Player["LocalPlayer Entity (Heap)"]
        Area -->|"+0x3E8 (OFF_EntityList)"| EntMap["EntityList / EntityMap Root"]
        Area -->|"+0x220 (OFF_TerrainData)"| Terrain["TerrainGrid / NavMesh Data"]
    end

    subgraph Player_Components ["LocalPlayer Component Sub-System"]
        Player -->|"+0x48 (OFF_LifeComp)"| Life["LifeComponent"]
        Player -->|"+0x50 (OFF_PosComp)"| Pos["PositionComponent"]
        Player -->|"+0x78 (OFF_BuffComp)"| Buffs["Buffs / Auras Component"]
        Player -->|"+0x80 (OFF_StatComp)"| Stats["ActorStats Component"]
    end

    subgraph Vitals_Fields ["Vitals Data Fields"]
        Life --> HP["HP: Current, Max, Reserved"]
        Life --> Mana["Mana: Current, Max, Reserved"]
        Life --> ES["Energy Shield: Current, Max"]
        Life --> Ward["Ward: Current, Max"]
    end

    subgraph Coordinates_Fields ["Navigation Coordinate Fields"]
        Pos --> XYZ["World Pos: X, Y, Z (Floats)"]
        Pos --> Orientation["Yaw, Pitch, Rotation (Rad)"]
        Pos --> Grid["Grid Coords: GridX, GridY (Int)"]
    end
```

---

### 3.2. Đặc Tả Chi Tiết Từng Mắt Xích Giải Mã (Step-by-Step Resolution Specification)

#### Mắt Xích 0: Base Address & Static Root Pointer
- **Địa chỉ cơ sở**: `uintptr_t moduleBase = m_reader.GetModuleBase("PathOfExile.exe")`.
- **Static RVA InGameState**: Con trỏ toàn cục nằm trong phân vùng `.data` (hoặc con trỏ RIP-relative trong `.text`).
  - Giá trị tham chiếu chuẩn hóa POE2 Patch 0.5.5: `RVA_InGameState = 0x4434CE0` (với fallback danh sách RVAs đã định vị: `0x45CFEF8`, `0x4715740`, `0x45CCA20`, `0x45D3280`).
  - Hỗ trợ AOB Signature Scanning tự động phòng khi bản patch cập nhật RVA:
    `AOB: 48 8B 05 ?? ?? ?? ?? 48 8B 88 ?? ?? 00 00 48 85 C9`

#### Mắt Xích 1: `InGameState` Singleton
- **Công thức**:
  $$\text{InGameStatePtr} = *(\text{uintptr\_t}*)(\text{moduleBase} + \text{RVA\_InGameState})$$
- **Ràng buộc kiểm tra hợp lệ (Sanity Check)**:
  - $\text{InGameStatePtr} \ge \text{0x10000}$ và $\text{InGameStatePtr} \le \text{0x7FFFFFFEFFFF}$ (thuộc dải Virtual User Heap x64).
  - VTable của `InGameState` phải trỏ vào phân vùng `.rdata` của `PathOfExile.exe`.

#### Mắt Xích 2: `CurrentAreaInstance` (InGameData)
- **Công thức**:
  $$\text{AreaInstancePtr} = *(\text{uintptr\_t}*)(\text{InGameStatePtr} + \text{OFF\_AreaInstance})$$
  *(Với $\text{OFF\_AreaInstance} = \text{0x90}$ trong cấu trúc InGameState của POE2 v0.5.5)*.
- **Tính chất động học**:
  - `AreaInstancePtr` tự động thay đổi mỗi khi nhân vật đi qua portal, đổi map, chuyển vào Boss Arena hoặc đăng nhập lại.
  - Khi game đang tải màn hình chờ (`LoadingScreen`), `AreaInstancePtr` có thể tạm thời bằng `0x0`. Hệ thống phải nhận diện đây là trạng thái chuyển cảnh tự nhiên và giữ trạng thái `WAITING_ZONE_READY` mà không kích hoạt báo động sai.

#### Mắt Xích 3: `LocalPlayer` Entity Object
- **Công thức**:
  $$\text{LocalPlayerPtr} = *(\text{uintptr\_t}*)(\text{AreaInstancePtr} + \text{OFF\_LocalPlayer})$$
  *(Với $\text{OFF\_LocalPlayer} = \text{0x188}$)*.
- **Tính chất**:
  - Trỏ trực tiếp tới đối tượng người chơi cục bộ (`LocalPlayerEntity`).
  - Khác biệt hoàn toàn với các Entity quái vật hay NPC khác trong instance: `LocalPlayerEntity` được liên kết tĩnh tại offset `+0x188` của `AreaInstance`, không bao giờ bị nhầm lẫn với quái vật hoặc Minion!

#### Mắt Xích 4a: `LifeComponent` & Bản Đồ Vitals
- **Công thức**:
  $$\text{LifeComponentPtr} = *(\text{uintptr\_t}*)(\text{LocalPlayerPtr} + \text{OFF\_LifeComp})$$
  *(Với $\text{OFF\_LifeComp} = \text{0x48}$)*.
- **Cấu trúc trường dữ liệu bên trong `LifeComponent`**:
  ```cpp
  #pragma pack(push, 1)
  struct LifeComponentMemory {
      uint64_t vtable;              // +0x00
      uint8_t  padding_08_20[0x18]; // +0x08 -> +0x20
      uint32_t currentHP;           // +0x20: Máu hiện tại (Current Life)
      uint32_t maxHP;               // +0x24: Máu tối đa (Max Life)
      uint32_t reservedHPFlat;      // +0x28: Máu bị phong ấn cố định
      uint32_t reservedHPPercent;   // +0x2C: Máu bị phong ấn phần trăm (10000 = 100%)
      uint32_t currentMana;         // +0x30: Mana hiện tại
      uint32_t maxMana;             // +0x34: Mana tối đa
      uint32_t reservedManaFlat;    // +0x38: Mana phong ấn cố định
      uint32_t reservedManaPercent; // +0x3C: Mana phong ấn phần trăm
      uint32_t currentES;           // +0x40: Khiên năng lượng hiện tại (Energy Shield)
      uint32_t maxES;               // +0x44: Khiên năng lượng tối đa
      uint32_t currentWard;         // +0x48: Ward hiện tại
      uint32_t maxWard;             // +0x4C: Ward tối đa
  };
  #pragma pack(pop)
  ```

#### Mắt Xích 4b: `PositionComponent` & Bản Đồ Tọa Độ Không Gian
- **Công thức**:
  $$\text{PositionComponentPtr} = *(\text{uintptr\_t}*)(\text{LocalPlayerPtr} + \text{OFF\_PosComp})$$
  *(Với $\text{OFF\_PosComp} = \text{0x50}$)*.
- **Cấu trúc trường dữ liệu bên trong `PositionComponent`**:
  ```cpp
  #pragma pack(push, 1)
  struct PositionComponentMemory {
      uint64_t vtable;              // +0x00
      uint8_t  padding_08_2C[0x24]; // +0x08 -> +0x2C
      float    posX;                // +0x2C: World Coordinate X (Isometric East-West)
      float    posY;                // +0x30: World Coordinate Y (Isometric North-South)
      float    posZ;                // +0x34: World Coordinate Z (Elevation / Độ cao)
      float    yaw;                 // +0x38: Góc xoay mặt nhân vật (Orientation Angle)
      uint8_t  padding_3C_54[0x18]; // +0x3C -> +0x54
      int32_t  gridX;               // +0x54: Tọa độ lưới logic Grid X
      int32_t  gridY;               // +0x58: Tọa độ lưới logic Grid Y
  };
  #pragma pack(pop)
  ```

---

## 4. Danh Mục Các Logic Cũ Lỗi Thời BỊ XÓA BỎ VĨNH VIỄN (Obsolete Heuristics Elimination Inventory)

Để bảo đảm hệ thống vận hành tinh gọn, tuân thủ tuyệt đối quy tắc **Zero Technical Debt** và **Root-Cause-First (Rule 8)**, bốn danh mục logic phỏng đoán lỗi thời sau đây **BỊ KHAI TỬ VÀ XÓA BỎ VĨNH VIỄN** khỏi codebase AutoPOE2:

```mermaid
graph LR
    subgraph Obsolete_Heuristics ["DANH MỤC KHAI TỬ VĨNH VIỄN"]
        H1["1. Micro-Step Input<br>(tap W 45ms / click 15%)"]
        H2["2. AutoPositionState<br>(CAPTURING_STILL_BASELINE & WAITING_FIRST_STEP)"]
        H3["3. Quét Heap 8GB Brute-Force<br>(AutoScanHP 0,0,0)"]
        H4["4. Phantom Monsters 100/100<br>(Quái ảo do quét mò float)"]
    end

    subgraph Replacements ["GIẢI PHÁP TẤT ĐỊNH THAY THẾ"]
        R1["100% Passive Read-Only<br>(Zero Key / Zero Click)"]
        R2["Single-Step Instant Lock<br>(UNINITIALIZED -> RESOLVED in 0ms)"]
        R3["Smart Heap Filter +/-16MB<br>(Last-resort fallback duy nhất)"]
        R4["EntityList Từ AreaInstance<br>(100% Thực Thể Thật Của Game)"]
    end

    H1 -.->|"TRIỆT TIÊU"| R1
    H2 -.->|"TRIỆT TIÊU"| R2
    H3 -.->|"TRIỆT TIÊU"| R3
    H4 -.->|"TRIỆT TIÊU"| R4
```

---

### 4.1. Khai Tử Mục 1: Micro-Step (Tap W 45ms, Click Chuột 15% Trên Tâm Màn Hình)

- **Vị trí hiện diện trong codebase**:
  - `src/core/game_session.cpp`: Dòng 300 - 343 (`m_scheduledMicroStepMs`, `m_microStepDone`, các lệnh `m_kmbox->MoveMouse`, `m_kmbox->ClickMouse`, `m_kmbox->SendKey`, `keybd_event(0, 0x11, ...)`).
  - `src/core/game_session.cpp`: Dòng 1256, dòng 1297 (`[AutoScan] KHOI DONG calibration XYZ (startup): chup baseline + micro-step di chuyen...`).
  - `src/core/game_session.hpp`: Biến `m_microStepDone`, `m_scheduledMicroStepMs`, phương thức `SetMovementMode`.
  - `src/core/main.cpp`: Dòng 619, dòng 1122 (`gameSession.SetMovementMode(moveMode)`).
- **Nguyên lý cũ & Lý do ra đời**:
  - Thuật toán vi sai float cần nhân vật di chuyển để tạo sự thay đổi giữa 2 lần chụp RAM. Micro-step được sinh ra để ép nhân vật bước đi 1 bước ngắn nhằm "phá băng" cho thuật toán vi sai.
- **Tác hại kỹ thuật & Lý do loại bỏ vĩnh viễn**:
  1. *Vi phạm nguyên tắc Passive*: Tự ý phát input vật lý ngoài luồng điều khiển của người chơi, tăng nguy cơ bị anti-cheat gắn cờ bất thường.
  2. *Chặn luồng 45ms*: Lệnh `std::this_thread::sleep_for(std::chrono::milliseconds(45))` trong nhánh hardware scan code làm đóng băng vòng lặp điều khiển 120Hz của Core Engine.
  3. *Nguy cơ click nhầm*: Lệnh click chuột $15\%$ trên tâm màn hình có thể nhấp trúng NPC, hòm đồ, hoặc mở menu trong game khi độ phân giải màn hình hoặc tỷ lệ khung hình thay đổi.
  4. *Hoàn toàn thừa thãi*: Khi đã có `PositionComponentPtr`, tọa độ $X, Y, Z$ được đọc trực tiếp từ bộ nhớ trong **$0\text{ms}$** ngay cả khi nhân vật đứng yên bất động, đang ngủ gật hoặc bị đóng băng hoàn toàn.
- **Hành động code**:
  - Xóa toàn bộ khối logic kiểm tra `m_scheduledMicroStepMs` trong `GameSession::Update()`.
  - Gỡ bỏ cờ `m_microStepDone`, xóa các lời gọi `keybd_event` và click KMBox phục vụ micro-step.

---

### 4.2. Khai Tử Mục 2: AutoPositionState (`CAPTURING_STILL_BASELINE` & `WAITING_FIRST_STEP`)

- **Vị trí hiện diện trong codebase**:
  - `src/core/game_session.hpp`: Enum `AutoPositionState` (dòng 61 - 67).
  - `src/core/game_session.cpp`: Máy trạng thái dòng 1200 - 1370 (`m_autoPosState == AutoPositionState::CAPTURING_STILL_BASELINE`, `m_autoPosState == AutoPositionState::WAITING_FIRST_STEP`).
  - `src/core/main.cpp`: Kiểm tra điều kiện `AutoScanState() == GameSession::AutoPositionState::IDLE`.
- **Nguyên lý cũ & Lý do ra đời**:
  - Máy trạng thái 4 pha: `IDLE` $\rightarrow$ `CAPTURING_STILL_BASELINE` (quét toàn bộ heap lưu hàng triệu floats) $\rightarrow$ `WAITING_FIRST_STEP` (chờ người dùng hoặc micro-step di chuyển để so sánh delta) $\rightarrow$ `RESOLVED`.
- **Tác hại kỹ thuật & Lý do loại bỏ vĩnh viễn**:
  1. *Lãng phí RAM*: Cần cấp phát buffer hàng chục megabyte để lưu mảng baseline floats của tiến trình game.
  2. *Kẹt trạng thái vĩnh viễn (Deadlock)*: Nếu người chơi đứng yên nói chuyện với NPC, xem đồ trong rương hoặc trong Grace Period, hệ thống bị kẹt cứng ở `WAITING_FIRST_STEP` hàng giờ liền, không thể kích hoạt bất kỳ tính năng tự động nào.
  3. *Độ phức tạp thừa thãi*: Tạo ra nhiều nhánh điều kiện bất đồng bộ gây lỗi race condition.
- **Hành động code**:
  - Tối giản hóa enum `AutoPositionState` chỉ còn 2 trạng thái cơ bản:
    ```cpp
    enum class PositionResolutionState {
        UNINITIALIZED = 0,
        RESOLVED = 1
    };
    ```
  - Xóa bỏ vĩnh viễn các hàm snapshot baseline (`CaptureStillBaseline`, `FindMovedFromBaseline`).

---

### 4.3. Khai Tử Mục 3: Quét Brute-Force `AutoScanHP` Toàn Bộ 8GB RAM Trong `PlayerFinder`

- **Vị trí hiện diện trong codebase**:
  - `src/core/memory/player_finder.cpp`: Dòng 68 - 150 (`AutoScanHP(0, 0, targetMaxHP)` với `start = 0`, `end = 0xFFFFFFFFFFFFFFFFULL`).
  - `src/core/game_session.cpp`: Dòng 2096 (`found = m_finder->AutoScanHP(0, 0, m_expectedMaxHP)`).
- **Nguyên lý cũ & Lý do ra đời**:
  - Khi không biết địa chỉ `playerAddr`, hàm này duyệt qua toàn bộ các Memory Region kiểu `MEM_PRIVATE` trên toàn bộ không gian địa chỉ ảo của game (lên tới 8GB - 16GB RAM) để tìm bất kỳ ô nhớ nào chứa 3 số nguyên dương thỏa mãn điều kiện `hp <= maxHP`.
- **Tác hại kỹ thuật & Lý do loại bỏ vĩnh viễn**:
  1. *Tê liệt CPU*: Đọc hàng nghìn megabyte dữ liệu qua syscall `ReadProcessMemory`, chiếm dụng $100\%$ một lõi CPU trong $2 - 4\text{ giây}$.
  2. *Bẫy dữ liệu giả (False Positives)*: Quét vét 8GB RAM chắc chắn sẽ quét trúng các mảng vertex Direct3D 12, buffer âm thanh, danh sách minion hoặc các biến đếm ngẫu nhiên có giá trị vô tình khớp với `(curHP, maxHP)`.
  3. *Va chạm UI Marker 778/779*: Từng gây ra sự cố nghiêm trọng khóa nhầm vào con trỏ biến thể UI marker.
- **Hành động code**:
  - Cấm tuyệt đối việc gọi `AutoScanHP` với `window = 0` hoặc quét không giới hạn toàn bộ không gian bộ nhớ.
  - Chuỗi con trỏ tĩnh `InGameState -> AreaInstance -> LocalPlayer -> LifeComponent` là cơ chế giải mã **ƯU TIÊN SỐ 1**.
  - Nếu bản patch game làm lệch RVA con trỏ tĩnh, hệ thống chỉ kích hoạt `SmartHeapFilter` với phạm vi thu hẹp nghiêm ngặt ($\pm 16\text{MB}$ quanh vùng heap entity hợp lệ), tuyệt đối không bao giờ quét tràn toàn bộ 8GB.

---

### 4.4. Khai Tử Mục 4: Quái Vật Ảo Tưởng ("Phantom Monsters") Giả Lập 100/100 Trong `EntityManager`

- **Vị trí hiện diện trong codebase**:
  - `src/core/memory/entity_manager.cpp`: Dòng 445 - 531 (Khối quét raw float mở rộng quanh `m_playerAddr` khi chưa tìm thấy Entity Array, tự gán `m1 = 100`, `hp = 100`, `name = "Hostile Monster"`).
- **Nguyên lý cũ & Lý do ra đời**:
  - Khi chưa đồng bộ được cấu trúc mảng Entity Array, code cũ đã cố gắng quét tìm các cụm tọa độ float trôi nổi quanh người chơi rồi tự động "bịa" ra các đối tượng quái vật với lượng máu mặc định để bot có mục tiêu test kiting / combat.
- **Tác hại kỹ thuật & Lý do loại bỏ vĩnh viễn**:
  1. *Vi phạm nghiêm trọng Rule 8 & Rule 14*: Trực tiếp vi phạm lệnh cấm hardcode số ma thuật (`100/100`) và lệnh cấm sử dụng Mock / Synthetic Data trên môi trường live.
  2. *Tấn công vào hư không (Ghost Combat)*: Nhân vật tự động quay hướng, xả skill tầm xa hoặc ném bẫy vào các bãi đất trống không có quái, gây lãng phí tài nguyên và hành vi lộ liễu bất thường.
  3. *Nhiễu loạn hệ thống né chiêu*: Kiting Engine tính toán khoảng cách né tránh dựa trên quái vật ảo, khiến nhân vật chạy loạn xạ vào tường hoặc lao vào vùng nguy hiểm thật.
- **Hành động code**:
  - Xóa bỏ hoàn toàn khối quét float mò trong `EntityManager::ScanProximityMonsters()`.
  - Tuân thủ nguyên tắc **Fail-Silent**: Nếu chuỗi con trỏ tới `EntityList` trong `AreaInstance` chưa sẵn sàng, trả về danh sách thực thể rỗng (`m_entities.clear()`). Bot tuyệt đối không bao giờ tự bịa quái vật.

---

## 5. Hợp Đồng Bất Biến Kiến Trúc (Invariants Contract - Rule 8 & Rule 12)

Mọi dòng code được triển khai trong đợt tái cấu trúc này bắt buộc phải tuân thủ nghiêm ngặt bảng hợp đồng bất biến sau:

| Mã Bất Biến | Tên Bất Biến | Điều Kiện Ràng Buộc Kỹ Thuật | Hành Vi Bắt Buộc Khi Vi Phạm |
| :--- | :--- | :--- | :--- |
| `INV-PTR-01` | **Base Address Sanity** | `moduleBase >= 0x140000000ULL` và PE Header có signature hợp lệ `IMAGE_NT_SIGNATURE`. | Hủy bỏ chuỗi giải mã, ghi nhận lỗi kết nối tiến trình, không đọc bừa bãi. |
| `INV-PTR-02` | **InGameState Heap Bounds** | `inGame >= 0x10000ULL && inGame <= 0x7FFFFFFEFFFFULL`. VTable thuộc dải `.rdata`. | Báo cáo `InGameState` chưa sẵn sàng (đang tải game); không dereference con trỏ NULL. |
| `INV-PTR-03` | **AreaInstance State Binding** | `areaInstance` phải trỏ tới vùng heap hợp lệ khi `InGameState->gameTick > 0`. | Khi chuyển cảnh (`areaInstance == 0`), giữ nguyên trạng thái an toàn, không kích hoạt Panic. |
| `INV-PTR-04` | **LocalPlayer Singularity** | `localPlayer` tại `areaInstance + 0x188` phải là đối tượng duy nhất, khác biệt hoàn toàn với Entity List. | Cấm nhầm lẫn giữa người chơi và Minion / NPC. |
| `INV-PTR-05` | **Component Address Non-Zero** | `lifeComp != 0` và `posComp != 0`. Cả hai component phải nằm trong cùng không gian heap với `localPlayer`. | Kiểm tra `std::abs((intptr_t)lifeComp - (intptr_t)posComp) < 0x1000000`. |
| `INV-PTR-06` | **Zero-Input Navigation Invariant** | Việc giải mã tọa độ $X, Y, Z$ **tuyệt đối không được phát sinh bất kỳ phím hoặc click chuột nào**. | Khóa chặn bằng assertion: trong suốt hàm `ResolvePosition()`, biến đếm input phải bằng 0. |
| `INV-PTR-07` | **Standstill Reading Invariant** | Khi nhân vật đứng yên tuyệt đối ($V_x = 0, V_y = 0$), tọa độ $X, Y, Z$ đọc ra phải ổn định, độ lệch $\le 0.001\text{ units}$. | Không phụ thuộc vào vận tốc hoặc vi sai chuyển động. |
| `INV-PTR-08` | **Authentic Entity Provenance (Rule 14)** | $100\%$ quái vật trong `m_entities` phải có địa chỉ bộ nhớ thật từ `EntityList` của game. Max HP $\ne 100$ giả định. | Xóa bỏ ngay lập tức nếu entity không có VTable hoặc địa chỉ RAM hợp lệ. |

---

## 6. Kế Hoạch Tái Cấu Trúc Mã Nguồn (Refactoring Blueprint & Impacted Files)

### 6.1. Danh Sách Các Tệp Cần Chỉnh Sửa & Tái Cấu Trúc

```mermaid
graph TD
    subgraph Core_Memory ["Tầng Bộ Nhớ Core (src/core/memory/)"]
        GL["game_layout.hpp<br>(Đặc tả struct AreaInstance, LocalPlayer, Components)"]
        PCR["pointer_chain_resolver.hpp/.cpp<br>(Module mới: Bộ giải mã con trỏ O(1))"]
        EM["entity_manager.cpp<br>(Chuyển sang đọc EntityList, xóa Phantom Monsters)"]
        PF["player_finder.cpp<br>(Xóa brute-force 8GB, giữ SmartHeapFilter)"]
    end

    subgraph Core_Engine ["Tầng Điều Khiển Core (src/core/)"]
        GS_H["game_session.hpp<br>(Tối giản AutoPositionState, xóa micro-step)"]
        GS_C["game_session.cpp<br>(Xóa timer micro-step, tích hợp PointerChainResolver)"]
        MAIN["main.cpp<br>(Loại bỏ CLI flags liên quan đến micro-step)"]
    end

    subgraph Companion_HUD ["Tầng Python Companion (src/assistant_tool/)"]
        CC["control_center.py<br>(Cập nhật hiển thị trạng thái Pointer Chain O(1))"]
    end

    GL --> PCR
    PCR --> GS_C
    PCR --> EM
    GS_H --> GS_C
    MAIN --> GS_C
```

### 6.2. Đặc Tả Module Mới: `PointerChainResolver`

Tạo mới module dùng chung `src/core/memory/pointer_chain_resolver.hpp` và `.cpp`:
- **Nhiệm vụ**: Đóng gói toàn bộ logic giải mã con trỏ 4 cấp thành một hàm duy nhất ($O(1)$ Single Source of Truth).
- **Giao diện lập trình (API Interface)**:
  ```cpp
  #pragma once
  #include "memory/imemory_reader.hpp"
  #include <cstdint>

  struct ResolvedPlayerPointers {
      uintptr_t inGameState = 0;
      uintptr_t areaInstance = 0;
      uintptr_t localPlayer = 0;
      uintptr_t lifeComponent = 0;
      uintptr_t positionComponent = 0;
      uintptr_t entityList = 0;
      bool isValid = false;
  };

  class PointerChainResolver {
  public:
      explicit PointerChainResolver(IMemoryReader& reader);

      // Giải mã toàn bộ chuỗi con trỏ trong < 0.001ms
      bool Resolve(uintptr_t moduleBase, ResolvedPlayerPointers& outPointers);

      // Đọc trực tiếp Vitals (HP/Mana/ES) từ LifeComponent đã giải mã
      bool ReadVitals(uintptr_t lifeCompAddr, uint32_t& curHP, uint32_t& maxHP,
                      uint32_t& curMana, uint32_t& maxMana,
                      uint32_t& curES, uint32_t& maxES);

      // Đọc trực tiếp Tọa độ XYZ từ PositionComponent đã giải mã (đứng yên vẫn đọc đúng)
      bool ReadPosition(uintptr_t posCompAddr, float& outX, float& outY, float& outZ, float& outYaw);

  private:
      IMemoryReader& m_reader;
      uintptr_t m_cachedInGameRVA = 0x4434CE0;
  };
  ```

---

## 7. Cổng Kiểm Thử Đối Chiếu Nghiêm Ngặt & Tiêu Chí Nghiệm Thu (Verification Gate - Rule 9 & Rule 11)

Để tuân thủ triệt để **Rule 9 ("Untested code is broken code")** và **Rule 11 (Automated Regression Prevention via Mock Harness)**, đợt triển khai phải vượt qua 5 cổng kiểm thử độc lập:

### 7.1. Cổng 1: Benchmark Tốc Độ Giải Mã $O(1)$ Latency ($\le 0.005\text{ms}$)
- **Mục tiêu**: Đo thời gian thực thi của `PointerChainResolver::Resolve()`.
- **Tiêu chí nghiệm thu**:
  - Thời gian trung bình qua 10,000 lần lặp $\le 0.005\text{ms}$ ($5\text{ microseconds}$).
  - Độ biến động jitter $\le 0.002\text{ms}$.
  - Zero Heap Allocation trong suốt quá trình resolve.

### 7.2. Cổng 2: Kiểm Thử Đứng Yên Tuyệt Đối (Zero-Input Standstill Test)
- **Mục tiêu**: Khẳng định việc đọc tọa độ XYZ không cần bất kỳ chuyển động nào của nhân vật.
- **Kịch bản**:
  - Đặt nhân vật tại tọa độ $(X_0, Y_0, Z_0)$ bất kỳ.
  - Vận tốc nhân vật $V = 0$, không nhấn phím W, không click chuột, không gửi micro-step.
- **Tiêu chí nghiệm thu**:
  - Tọa độ $X, Y, Z$ được trả về chính xác ngay tại tick đầu tiên ($0\text{ms}$).
  - Không có bất kỳ lệnh input cơ học nào được gửi tới KMBox hoặc Windows Message Queue.

### 7.3. Cổng 3: Kiểm Thử Chuyển Cảnh & Đổi Map Tức Thời (Zone Transition Stress Test)
- **Mục tiêu**: Xác minh tính bền vững khi `AreaInstance` bị hủy và cấp phát lại.
- **Kịch bản**:
  - Giả lập 50 lần chuyển map liên tục: Map A $\rightarrow$ Loading Screen (`AreaInstance = 0`) $\rightarrow$ Map B (`AreaInstance` mới).
- **Tiêu chí nghiệm thu**:
  - Trong lúc Loading Screen: Hệ thống nhận diện an toàn, không crash, không báo lỗi giả.
  - Ngay khi Map B tải xong tick đầu tiên: Chuỗi con trỏ tự động khóa lại `LifeComponent` và `PositionComponent` mới trong $\le 0.002\text{ms}$.

### 7.4. Cổng 4: Kiểm Thử Tử Vong & Hồi Sinh Tại Checkpoint (Death & Respawn Resilience Test)
- **Mục tiêu**: Xác minh khả năng phục hồi khi nhân vật chết (`HP = 0`) và hồi sinh.
- **Kịch bản**:
  - Nhân vật nhận sát thương dẫn đến `currentHP = 0`.
  - Nhấn nút "Revive at Checkpoint".
- **Tiêu chí nghiệm thu**:
  - Không mất dấu con trỏ nhân vật.
  - Vitals và XYZ tự động cập nhật lại giá trị hồi sinh đầy máu trong vòng $1$ tick.

### 7.5. Cổng 5: Unit Tests Tự Động Trên Mock Harness (`SimulatedMemoryReader`)
- **Mục tiêu**: Kiểm chứng logic độc lập $100\%$ không cần mở game thật và không cần quyền Administrator.
- **Các test case bổ sung vào `tests/test_core.cpp`**:
  1. `TEST(DeterministicPointerChain, O1TraversalSuccess)`: Khởi tạo module ảo, kiểm chứng đọc đúng HP, Mana, ES, XYZ qua 4 cấp con trỏ.
  2. `TEST(ObsoleteHeuristicRemoval, NoMicroStepKeySent)`: Kiểm chứng hàm cập nhật tọa độ không bao giờ kích hoạt input vật lý.
  3. `TEST(EntityManager, AuthenticEntitiesOnly)`: Kiểm chứng `EntityManager` chỉ chứa quái vật thật từ `EntityList`, cấm tuyệt đối quái giả HP 100/100.
  4. `TEST(PlayerFinder, NoBruteForce8GB)`: Khẳng định `PlayerFinder` không còn duyệt không gian địa chỉ $0$ đến $2^{64}-1$.

---

## 8. Lộ Trình Triển Khai Thực Thi Chi Tiết (Implementation Roadmap)

1. **Giai đoạn 1 (Pre-Implementation Documentation - Rule 6)**:
   - [x] Hoàn thiện tài liệu kiến trúc `docs/development/23_deterministic_pointer_chain_and_obsolete_heuristic_elimination.md`.
   - [x] Đồng bộ các mốc tham chiếu kỹ thuật và hợp đồng bất biến.
2. **Giai đoạn 2 (Core Memory Structures & Resolver)**:
   - Cập nhật struct trong `src/core/memory/game_layout.hpp`.
   - Viết module mới `src/core/memory/pointer_chain_resolver.hpp/.cpp`.
   - Viết Unit Tests kiểm chứng trên Mock Harness trong `tests/test_core.cpp`.
3. **Giai đoạn 3 (Obsolete Heuristics Elimination & Code Refactoring)**:
   - Xóa bỏ Micro-Step và dọn dẹp `AutoPositionState` trong `src/core/game_session.hpp/.cpp` và `src/core/main.cpp`.
   - Gỡ bỏ quét brute-force 8GB trong `src/core/memory/player_finder.cpp`.
   - Gỡ bỏ logic quái vật ảo 100/100 trong `src/core/memory/entity_manager.cpp`.
4. **Giai đoạn 4 (Verification & Zero-Drift Audit - Rule 9 & Rule 10)**:
   - Chạy toàn bộ bộ kiểm thử tự động `AutoPOE2_Tests.exe` và `pytest`.
   - Cập nhật tài liệu hiện trạng trong `docs/` để bảo đảm Zero Documentation Drift.
   - Báo cáo nghiệm thu toàn diện cho người dùng.
