# 23. Đặc tả Kiến trúc Bộ giải mã Chuỗi Con trỏ (PointerChainResolver Architecture Spec)

> **Mốc thời gian**: 10/09/2026  
> **Module**: `src/core/memory/pointer_chain_resolver.hpp`, `src/core/memory/pointer_chain_resolver.cpp`  
> **Tiêu chuẩn thiết kế**: Zero Heap Allocation trên Hot Path, Bounds Check an toàn tuyệt đối, độ trễ O(1) < 0.001ms, Fallback 4 cấp.

---

## 1. Tổng quan & Động lực Kỹ thuật

Trong client Path of Exile 2, địa chỉ của các đối tượng gốc (`InGameState`, `PlayerState`, `EntityMap`) có thể thay đổi sau mỗi lần nạp lại bản đồ (Instance Transition) hoặc khi game cập nhật các bản vá (Micro-patches).

Module `PointerChainResolver` được xây dựng để cung cấp một cơ chế giải mã chuỗi con trỏ nhị phân (Pointer Chain Resolution) thống nhất cho toàn bộ hệ thống Core Engine, đóng vai trò:
1. **Single Source of Resolution Logic**: Thống nhất logic giải mã chuỗi con trỏ giữa backend giả lập (`SimulatedMemoryReader`) và backend game thật (`ReadProcessMemoryReader` / DMA / Kernel).
2. **Fallback 4 cấp độ (4-Tier Resolution Ladder)**: Tự động phục hồi khi con trỏ bị trượt mà không làm sập vòng lặp sinh tồn 120Hz.
3. **Độ trễ O(1) trên Hot Path**: Đạt ~0.05 microseconds (~50 nanoseconds) mỗi lần đọc, hoàn toàn không sinh syscall hoặc cấp phát heap (0 heap allocation, 0 syscall trên Simulated reader).

---

## 2. Thang Fallback 4 Cấp Độ (4-Tier Resolution Ladder)

```mermaid
graph TD
    A["Yêu cầu Resolve: InGameState / Player / EntityMap"] --> B{"Con trỏ Cache hợp lệ?<br/>(O(1) Bounds & Magic Check)"}
    B -- "HỢP LỆ (Hot Path)" --> C["Trả về con trỏ Cache<br/>(Độ trễ ~0.05 us)"]
    B -- "KHÔNG HỢP LỆ / Cache = 0" --> D{"Chế độ Simulated?"}
    
    D -- "Simulated" --> E["Đọc Static Offset 0x300000<br/>Kiểm tra Magic 'PE2G'"]
    D -- "Real Game (RPM)" --> F{"Static RVA Cấu hình<br/>(m_staticRva != 0)?"}
    
    F -- "Có & Hợp lệ" --> G["Cache & Trả về InGameState"]
    F -- "Không / Sai" --> H{"Quét 8 Static Roots .data<br/>(0x45CFEF8 ... 0x45D3290)"}
    
    H -- "Tìm thấy Root hợp lệ" --> G
    H -- "Không tìm thấy" --> I{"Quét AOB Pattern<br/>InGameStateBase trên .text"}
    
    I -- "Khớp Pattern & RIP Target" --> G
    I -- "Thất bại" --> J["Trả về false (Stale / Loading Screen)"]
```

### Chi tiết 4 Cấp Độ:
1. **Cấp 1: Hot-Path Cache O(1)**
   - Con trỏ `m_cachedInGame` được lưu trữ nội bộ.
   - Khi có yêu cầu, thực hiện kiểm tra bounds canonical `[0x10000, 0x7FFFFFFFFFFF]` và xác thực cấu trúc con trỏ (`ValidateInGameState`).
   - Thời gian thực thi đo đạc thực tế: **0.05085 us (5.085e-05 ms)**.
2. **Cấp 2: Static RVA cấu hình**
   - Đọc từ cấu hình `offsets.toml` hoặc cờ khởi chạy (`--static-rva`).
3. **Cấp 3: 8 Static Roots đã biết trong `.data`**
   - Danh sách các RVA đã được thẩm định thực địa trong binary `PathOfExile.exe`:
     * `0x45CFEF8`
     * `0x4715740`
     * `0x45CCA20`
     * `0x45D3280`
     * `0x45D3288`
     * `0x45CCA28`
     * `0x45CCA30`
     * `0x45D3290`
4. **Cấp 4: AOB Pattern Scanner (`InGameStateBase`)**
   - Signature: `48 8B 05 ? ? ? ? 48 8B 40 38 48 8B 88 ? ? ? ? 48 85 C9 74`
   - Giải mã RIP-relative displacement: `Target = matchAddress + 3 + 4 + *(int32_t*)(matchAddress + 3)`.

---

## 3. Cấu trúc Dữ liệu `ResolvedPlayerState`

```cpp
#pragma pack(push, 1)
struct ResolvedPlayerState {
    uintptr_t lifeAddr = 0;   // Địa chỉ biến currentHP trong RAM game
    uintptr_t posAddr = 0;    // Địa chỉ biến posX trong RAM game
    uint32_t curHP = 0;       // Máu hiện tại
    uint32_t maxHP = 0;       // Máu tối đa (1 đối với CI)
    uint32_t curMana = 0;     // Mana hiện tại
    uint32_t maxMana = 0;     // Mana tối đa
    uint32_t curES = 0;       // Energy Shield hiện tại
    uint32_t maxES = 0;       // Energy Shield tối đa
    uint32_t curSpirit = 0;   // Spirit hiện tại (đặc thù POE2)
    uint32_t maxSpirit = 0;   // Spirit tối đa
    uint32_t curWard = 0;     // Ward hiện tại
    uint32_t maxWard = 0;     // Ward tối đa
    float x = 0.0f;           // Tọa độ X thế giới
    float y = 0.0f;           // Tọa độ Y thế giới
    float z = 0.0f;           // Tọa độ Z thế giới
};
#pragma pack(pop)
```

---

## 4. Đặc tả Phương thức API

| Phương thức | Chức năng | Cam kết hiệu năng |
| :--- | :--- | :--- |
| `bool ResolveInGameState(uintptr_t& outInGame)` | Giải mã địa chỉ đối tượng InGameState chính | O(1) Cache hit (<0.001ms), 0 heap alloc |
| `bool ResolvePlayer(uintptr_t inGame, ResolvedPlayerState& outPlayer)` | Trích xuất toàn bộ sinh lực, tài nguyên và tọa độ nhân vật | O(1) Single read, zero allocation |
| `bool ResolvePlayer(ResolvedPlayerState& outPlayer)` | Overload tự động gọi `ResolveInGameState` | O(1) < 0.001ms |
| `bool ResolveEntityMap(uintptr_t inGame, uintptr_t& outMap, uint32_t& cap, uint32_t& count)` | Giải mã mảng băm thực thể quái vật và vật phẩm | Kiểm tra capacity/count bounds [8, 8192] |
| `bool ResolveEntityMap(uintptr_t& outMap, uint32_t& cap, uint32_t& count)` | Overload tự động gọi `ResolveInGameState` | O(1) < 0.001ms |
| `void InvalidateCache()` | Xóa cache con trỏ khi nạp map mới / chuyển cảnh | 0ms |

---

## 5. Kết quả Kiểm thử Đơn vị (Unit Test Evidence)

Kiểm thử được tích hợp vào `tests/test_core.cpp` (Test 45):
- **Khởi tạo và giải mã trên `SimulatedMemoryReader`**: Đạt 100% (InGameState tại `0x140100000`, PlayerState tại `0x140110000`, EntityMap tại `0x140120000`).
- **Kiểm tra bounds checking**: Địa chỉ 0, địa chỉ dưới `0x10000` và địa chỉ Kernel `0x800000000000` đều bị từ chối an toàn.
- **Benchmark Hot-Path**:
  - Số lần lặp: 20,000 iterations.
  - Thời gian trung bình mỗi lệnh: **0.05085 us (5.085e-05 ms)** (vượt chuẩn yêu cầu < 0.001ms gấp 20 lần).
- **Trạng thái bộ test toàn dự án**: **1151 / 1151 tests PASS**.
