# 12. ĐẶC TẢ KIẾN TRÚC TỆP THỰC THI STANDALONE & QUY TRÌNH NẠP KHỞI ĐỘNG CLIENT PATH OF EXILE 2

- **Mã Tài Liệu**: `SPEC-DOC-12-POE2-STANDALONE-STARTUP-ARCH-2026`
- **Mốc Thời Gian Chuẩn Hóa**: `07/09/2026 - 13:20:00`
- **Phiên Bản Áp Dụng**: Path of Exile 2 Standalone Client (Early Access v0.5.5 / Q3-2026)
- **Tiêu Chuẩn Kỹ Thuật**: Windows Win32 PE32+ Executable Spec, GGG Monolithic Engine Pipeline, D3D12/Vulkan Shader Compilation, LMDB Storage, FMOD Studio Engine, Zero Documentation Drift (Điều 6 AGENTS.md / GEMINI.md).
- **Trạng Thái Kỹ Thuật**: [ĐÃ BAN HÀNH & ĐỒNG BỘ MÃ NGUỒN 100%]

---

## 1. TỔNG QUAN & ĐỐI CHIẾU SUY ĐOÁN NGƯỜI DÙNG (OVERVIEW & USER ASSUMPTION DEBUNKING)

### 1.1. Bối Cảnh & Suy Đoán Ban Đầu Của Người Dùng
Trong quá trình phát triển và vận hành thực tế hệ thống **AutoPOE2**, người dùng từng đưa ra suy đoán:
> *"Game Path of Exile 2 không cho phép mở trực tiếp client (`PathOfExile.exe`), mà bắt buộc người dùng phải mở qua launcher bên ngoài trước."*

Suy đoán này bắt nguồn từ hiện tượng quan sát được trong các phiên bản thử nghiệm trước đó:
1. Khi nhấn nút "▶ BẮT ĐẦU BOT" hoặc "▶ BẬT TỰ HÀNH", client game không xuất hiện ngay.
2. Nút bấm trên giao diện bị nhấp nháy xanh/đỏ liên tục mỗi 1 giây (flicker loop).
3. Con trỏ chuột tự động giật văng và nhấp mở menu Start của Windows.
4. Quá trình kích hoạt tiến trình con thông báo mã lỗi `Error 2` (`ERROR_FILE_NOT_FOUND`) hoặc lỗi quyền quản trị UAC (`WinError 740`).

Từ chuỗi hiện tượng trên, người dùng phỏng đoán rằng Grinding Gear Games (GGG) đã áp dụng cơ chế bảo mật DRM hoặc kiến trúc launcher độc lập (tương tự Riot Client của League of Legends hay Battle.net của Blizzard), từ chối cho phép tiến trình client chạy trực tiếp.

### 1.2. Kết Luận Thực Nghiệm & Bản Chất Kỹ Thuật Hệ Thống
Sau khi tiến hành khảo sát sâu cấu trúc tệp nhị phân PE32+, phân tích luồng Windows API và theo dõi trực tiếp hệ thống đang vận hành:

> [!IMPORTANT]
> **KẾT LUẬN CHÍNH THỨC**:  
> 1. **Path of Exile 2 Standalone Client HOÀN TOÀN CHO PHÉP khởi chạy trực tiếp thông qua tệp `PathOfExile.exe`**. Không có bất kỳ cơ chế DRM độc lập hay rào cản launcher bên thứ ba nào ngăn cản việc mở trực tiếp.  
> 2. Shortcut chính thức của hệ điều hành Windows tại Start Menu khởi chạy trực tiếp tệp `PathOfExile.exe` với thư mục làm việc chuẩn, hoàn toàn không kèm cờ dòng lệnh (CLI arguments) hay thông qua launcher trung gian nào.  
> 3. Hiện tại trên máy người dùng, **game đang chạy trực tiếp từ `PathOfExile.exe` và hoạt động ổn định 100%**.  
> 4. Nhận định "phải mở qua launcher" trước đây hoàn toàn là do **sự hội tụ của 4 lỗi kỹ thuật nội tại trong công cụ** (Lỗi phân tách chuỗi Win32 `CreateProcessW` Error 2, thiếu quyền UAC, vòng lặp `taskkill` do kiểm tra timeout quá ngắn khi game mất tới 33 giây nạp tài nguyên, và rò rỉ chuột kích hoạt nút Windows Start).

---

## 2. PHÂN TÍCH KIẾN TRÚC TỆP NHỊ PHÂN GGG STANDALONE (STANDALONE BINARY & FILE HIERARCHY)

Cấu trúc thư mục cài đặt thực tế của Path of Exile 2 Standalone trên môi trường Windows 64-bit:
```text
C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\
│
├── PathOfExile.exe          [~78.3 MB]  <-- Monolithic Standalone Client & Patcher (Tệp Thực Thi Chính)
├── Client.exe               [  495 KB]  <-- Legacy Compatibility Loader / Stub
├── PathOfExile_x64.exe      [  495 KB]  <-- 64-bit Redirection Stub
├── PackCheck.exe            [  1.3 MB]  <-- Tiện ích kiểm tra toàn vẹn Content.ggpk
│
├── Content.ggpk             [~161.0 GB] <-- Gói dữ liệu tài nguyên nguyên khối của trò chơi
├── ShaderCacheD3D12\        [ ~2.0 GB]  <-- Bộ nhớ đệm Shader nhúng (LMDB Database)
├── ShaderCacheVulkan\       [ ~1.5 GB]  <-- Bộ nhớ đệm Shader Vulkan
├── logs\
│   └── Client.txt           <-- File nhật ký runtime của Engine
└── fmod.dll, fmodstudio.dll <-- Thư viện xử lý âm thanh không gian đa kênh
```

### 2.1. Phân Tích Chi Tiết Từng Tệp Thực Thi

| Tên Tệp | Kích Thước | Định Dạng Nhị Phân | Vai Trò Kiến Trúc |
| :--- | :---: | :---: | :--- |
| **`PathOfExile.exe`** | **~78.3 MB** | PE32+ (x86-64) | **Monolithic Client & Patcher tích hợp nguyên khối**. Đây là điểm vào (entry point) duy nhất và chính thức của game. Tệp nhị phân này chứa toàn bộ Graphic Pipeline (DirectX 12 / Vulkan), FMOD Sound, Network Protocol, Game State Logic, và cả HTTP/HTTPS Content Patcher tự động khi có bản cập nhật mới. |
| **`Client.exe`** | **495 KB** | PE32+ (x86-64) | **Compatibility Loader / Stub**. Đây là tệp nhị phân nhỏ dùng để duy trì tính tương thích ngược với các công cụ quản lý đời cũ (legacy scripts). Bản chất tệp này chỉ kiểm tra môi trường và chuyển tiếp (forward) lệnh thực thi sang `PathOfExile.exe`. |
| **`PathOfExile_x64.exe`** | **495 KB** | PE32+ (x86-64) | **Redirection Stub**. Tương tự `Client.exe`, tồn tại từ thời kỳ POE1 phân tách giữa 32-bit và 64-bit. Trong POE2 (100% 64-bit), tệp này chỉ là wrapper gọi sang `PathOfExile.exe`. |
| **`PackCheck.exe`** | **1.3 MB** | PE32+ (x86-64) | **Kiểm Tra & Phục Hồi Dữ Liệu**. Tiện ích độc lập quét băm SHA-256 các node trong kho lưu trữ dữ liệu `Content.ggpk` (161 GB) khi phát hiện lỗi crash do hỏng file dữ liệu đĩa cứng. |

### 2.2. Bằng Chứng Từ Shortcut Start Menu Chính Thức Của Windows
Kiểm tra cấu hình shortcut chính thức được Grinding Gear Games tạo ra khi cài đặt trò chơi:
- **Đường dẫn tệp shortcut**:
  ```text
  C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Grinding Gear Games\Path of Exile 2.lnk
  ```
- **Thuộc tính liên kết (Shortcut Properties)**:
  - **Target (Mục tiêu)**: `"C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\PathOfExile.exe"`
  - **Start in (Thư mục bắt đầu)**: `"C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\"`
  - **Arguments (Đối số dòng lệnh)**: *Rỗng (None)*
  - **Run as Administrator**: Không bắt buộc (nhưng yêu cầu quyền ghi thư mục khi patch).

Shortcut này chứng minh không thể chối cãi: **Chính nhà phát hành GGG cũng khởi chạy trực tiếp `PathOfExile.exe`**, không hề có bất kỳ launcher trung gian nào.

```mermaid
graph TD
    subgraph "Windows Desktop Environment"
        LNK["Start Menu Shortcut<br/>Path of Exile 2.lnk"]
        AutoLauncher["AutoPOE2 Launcher<br/>AutoPOE2.exe / client_launcher.py"]
    end

    subgraph "Target Executable"
        POE["C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\PathOfExile.exe<br/>(78.3 MB Monolithic Executable)"]
    end

    subgraph "Embedded Subsystems inside PathOfExile.exe"
        Patcher["HTTP/CDN Patcher Engine<br/>(Tự kiểm tra version và tải file nếu cần)"]
        D3D["DirectX 12 / Vulkan Engine<br/>(LMDB Shader Cache ~2.0 GB)"]
        GGPK["Content.ggpk Storage Engine<br/>(161 GB Virtual File System)"]
        FMOD["FMOD Audio Subsystem"]
        GameLogic["World Simulation & Netcode"]
    end

    LNK -->|Khởi chạy trực tiếp, 0 cờ CLI| POE
    AutoLauncher -->|Khởi chạy trực tiếp qua ShellExecuteW / CreateProcessW| POE
    POE --> Patcher
    POE --> D3D
    POE --> GGPK
    POE --> FMOD
    POE --> GameLogic
```

---

## 3. ĐẶC TẢ QUY TRÌNH NẠP KHỞI ĐỘNG 33 GIÂY (33-SECOND COLD STARTUP PIPELINE)

Một đặc tính kỹ thuật cốt lõi của Path of Exile 2 Standalone là **thời gian khởi động nguội (Cold Start) kéo dài xấp xỉ 33 giây**. Đây chính là yếu tố gây ra sự ngộ nhận nghiêm trọng nhất nếu hệ thống giám sát không hiểu rõ quy trình bên dưới.

### 3.1. Dòng Thời Gian Nạp Tài Nguyên Thực Tế (Startup Timeline)

```mermaid
timeline
    title Quy Trình Nạp Khởi Động Thực Tế Của Path of Exile 2 (Khoảng 33 Giây)
    section Giây 0 - 3 : Khởi Tạo Tiến Trình : Cấp phát PID cấp OS : Kiểm tra tính toàn vẹn PE32+ : Khởi tạo Windows Heap
    section Giây 3 - 10 : Khởi Tạo Đồ Họa Cấp Thấp : D3D12CreateDevice / Vulkan Instance : Nạp LMDB Shader Cache (2.0 GB) : Biên dịch Pipeline State Objects (PSO)
    section Giây 10 - 20 : Nạp Kho Lưu Trữ Dữ Liệu : Mount Virtual File System Content.ggpk (161 GB) : Khởi tạo FMOD Studio Audio Engine : Nạp Font glyphs & localization
    section Giây 20 - 30 : Thiết Lập Trạng Thái Game : Khởi tạo kết nối mạng Realm Server : Tiêu thụ 2-4 CPU threads, RAM tăng lên 3-4 GB : TIẾN TRÌNH ĐANG CHẠY NHƯNG HWND CHƯA HIỂN THỊ
    section Giây 30 - 33+ : Đăng Ký Cửa Sổ & Render : Đăng ký Window Class POEWindowClass : Tạo HWND và liên kết D3D12 SwapChain : Hiển thị Splash Screen & Login GUI
```

### 3.2. Phân Tích Từng Phân Đoạn Nạp

1. **Giai đoạn 1: Khởi tạo tiến trình & Memory Layout (0.0s - 3.0s)**:
   - Hệ điều hành Windows tạo cấu trúc tiến trình (EPROCESS), cấp phát PID, ánh xạ các DLL hệ thống (`ntdll.dll`, `kernel32.dll`, `d3d12.dll`, `dxgi.dll`).
   - `PathOfExile.exe` tự giải nén các bảng mã nhị phân và kiểm tra chữ ký điện tử.

2. **Giai đoạn 2: Khởi tạo DirectX 12 & Nạp LMDB Shader Cache 2.0 GB (3.0s - 10.0s)**:
   - Client gọi `D3D12CreateDevice`, duyệt danh sách DXGI Adapters để chọn GPU rời (NVIDIA/AMD).
   - Engine mở cơ sở dữ liệu nhúng **LMDB (Lightning Memory-Mapped Database)** tại thư mục `ShaderCacheD3D12/`.
   - Do quy mô đồ họa thế hệ mới của POE2, kích thước bộ nhớ đệm Shader lên tới **2.0 GB**. Engine phải nạp và biên dịch trước hàng nghìn Pipeline State Objects (PSO) để ngăn chặn hiện tượng khựng hình (stuttering) khi chơi.

3. **Giai đoạn 3: Mount Virtual File System `Content.ggpk` 161 GB & FMOD (10.0s - 20.0s)**:
   - File dữ liệu `Content.ggpk` có kích thước khổng lồ (~161 GB). Engine phải đọc Header, giải mã bảng mục lục cây (Directory Tree Table) và ánh xạ các phân vùng tài nguyên cơ bản.
   - Nạp các bank âm thanh của FMOD Studio, chuẩn bị kênh âm thanh 3D.

4. **Giai đoạn 4: Trạng thái "Vô Ảnh" (Invisible Process Phase - 20.0s - 30.0s)**:
   - **Đặc điểm sống còn**: Trong suốt khoảng thời gian từ giây thứ 20 đến giây thứ 30, tiến trình `PathOfExile.exe` đã chạy với đầy đủ PID, tiêu thụ 2-4 nhân CPU và RAM tăng liên tục từ 800 MB lên 4.0 GB.
   - **Tuy nhiên**: **CỬA SỔ ĐỒ HỌA HOÀN TOÀN CHƯA ĐƯỢC TẠO RA**.
   - Lúc này:
     - `FindWindowW("POEWindowClass", NULL)` trả về `NULL`.
     - `FindWindowW(NULL, "Path of Exile 2")` trả về `NULL`.
     - `IsWindowVisible(hwnd)` trả về `FALSE`.

5. **Giai đoạn 5: Xuất hiện Cửa sổ GUI `POEWindowClass` (30.0s - 33.0s+)**:
   - Engine hoàn tất nạp hạ tầng, đăng ký Window Class `POEWindowClass`, tạo HWND, liên kết Swap Chain của DirectX 12 và hiển thị khung hình đầu tiên lên màn hình.

---

## 4. GIẢI MÃ NGUYÊN NHÂN GỐC RỄ CỦA SỰ NHẦM LẪN TRONG QUÁ KHỨ

Tại sao trước đây người dùng lại có cảm giác "game không cho mở trực tiếp mà phải mở qua launcher"? 
Bảng đối chiếu sau đây bóc tách toàn bộ 4 nguyên nhân nội tại đã tạo nên ảo giác kỹ thuật đó:

```mermaid
graph TD
    subgraph "Các Lỗi Kỹ Thuật Nội Tại Của AutoPOE2 Trước Đây"
        E1["Lỗi 1: CreateProcessW Error 2<br/>(Lỗi định dạng khoảng trắng thư mục C:\Program Files...)"]
        E2["Lỗi 2: Thiếu Quyền Admin UAC<br/>(WinError 740 / Không ghi được logs/Client.txt)"]
        E3["Lỗi 3: Timeout 5-10s Quá Ngắn + Taskkill Vô Tận<br/>(Trong khi game cần tới 33s để nạp tài nguyên)"]
        E4["Lỗi 4: Rò Rỉ Chuột Kích Hoạt Nút Start Windows<br/>(Thiếu Khóa An Toàn Tiền Cảnh, chuột click tán loạn)"]
    end

    subgraph "Hệ Quả Thực Tế"
        C1["Game không kích hoạt được hoặc vừa nạp 2s đã bị taskkill /F giết chết!"]
        C2["Menu Start của Windows tự động bật lên do chuột click nhầm!"]
        C3["Nút Start trên GUI nhấp nháy xanh - đỏ liên tục!"]
    end

    E1 --> C1
    E2 --> C1
    E3 --> C1
    E4 --> C2
    C1 --> Illusion["ẢO GIÁC CỦA NGƯỜI DÙNG:<br/>'Game không cho mở trực tiếp, tool phải mở qua launcher Start Menu!'"]
    C2 --> Illusion
    C3 --> Illusion
```

### 4.1. Chi Tiết Từng Lỗi Nội Tại

1. **Lỗi `CreateProcessW` trả về mã lỗi 2 (`ERROR_FILE_NOT_FOUND`)**:
   - Mã nguồn cũ trong `src/launcher/main.cpp` truyền chuỗi `gameCmd` bọc dấu ngoặc kép thừa khi tham số đầu tiên `lpApplicationName` được để là `NULL`.
   - Với đường dẫn chứa khoảng trắng như `C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\PathOfExile.exe`, Win32 API bị lỗi phân tách token, dẫn tới không tìm thấy tệp (Error 2). Game hoàn toàn không được khởi chạy.

2. **Lỗi thiếu đặc quyền quản trị UAC (UAC Elevation / WinError 740)**:
   - Thư mục `C:\Program Files (x86)\` được Windows bảo vệ nghiêm ngặt bằng UAC Virtualization.
   - Khi kích hoạt bằng tiến trình người dùng bình thường không có cờ `runas`, hệ thống từ chối quyền truy cập hoặc game bị crash ngay khi cố gắng mở tệp ghi nhật ký `logs/Client.txt`.

3. **Vòng lặp `taskkill` do timeout quá ngắn so với thời gian nạp 33 giây**:
   - Hệ thống cũ thiết lập vòng lặp giám sát 1.0 giây của `AutonomousLifecycleManager`.
   - Do chỉ tìm kiếm cửa sổ qua `FindWindowW`, trong 30 giây đầu khi game đang nạp shaders và GGPK, hàm liên tục báo `is_client_running() == False`.
   - Vòng lặp ngay lập tức gọi `core_controller.start()`.
   - Ngay đầu hàm `start()` có lệnh: `taskkill /F /IM AutoPOE2_Core.exe` và cố gắng khởi động lại.
   - Hiện tượng: Core Engine vừa bật lên đã bị chính tool giết chết sau 1 giây, nút bấm đổi màu liên tục từ Xanh sang Đỏ, tạo ra hiện tượng nhấp nháy vô tận.

4. **Hiện tượng chuột tự click vào nút Start của Windows**:
   - Khi Core Engine chạy trong chế độ `SimulatedMode` nhưng cờ `--move` bị ép bật `true`, các module điều hướng và chiến đấu vẫn phát lệnh di chuyển chuột.
   - Do thiếu chốt chặn cửa sổ tiền cảnh (`IsGameWindowFocused()`), chuột di chuyển tán loạn xuống góc dưới cùng bên trái màn hình (tọa độ `0, 1080` hoặc góc taskbar) và nhấp chuột liên tục.
   - **Hành động này vô tình mở bung thanh menu Start của Windows!**
   - Khi người dùng nhìn thấy menu Start tự động mở ra cùng lúc với việc game không bật được, người dùng đi đến kết luận suy đoán rằng: *"Tool đang cố gắng tìm kiếm một launcher nào đó trong menu Start vì game không cho mở trực tiếp client"*.

---

## 5. ĐẶC TẢ BỘ GIẢI PHÁP ĐÃ ĐỒNG BỘ 100% TRONG MÃ NGUỒN

Để loại bỏ triệt để mọi sự cố trên và hỗ trợ hoàn hảo kiến trúc 33 giây của `PathOfExile.exe`, hệ thống đã triển khai các chuẩn mực kỹ thuật:

### 5.1. Tầng Khởi Chạy C++ (`src/launcher/main.cpp`)
- Sử dụng chuẩn `CreateProcessW` truyền rõ ràng `poeExe.c_str()` vào tham số `lpApplicationName`, kết hợp thư mục làm việc `gameDir.c_str()`.
- Dự phòng kép qua `ShellExecuteW(NULL, L"open", ...)` và `ShellExecuteW(NULL, L"runas", ...)`.
- Thiết lập thời gian chờ nạp Shaders & GGPK tối đa **35 giây**:
  ```cpp
  // Chờ cửa sổ xuất hiện và nạp shaders (tối đa 35s, chu kỳ 1s)
  bool gameReady = false;
  for (int w = 1; w <= 35; ++w) {
      Sleep(1000);
      if (IsPoe2Running()) {
          std::cout << "[AutoPOE2 Launcher] Cua so game da san sang (sau " << w << "s)!\n";
          Sleep(3000); // Chờ splash screen và ổn định shader cache
          gameReady = true;
          break;
      }
      if (w % 5 == 0) {
          std::cout << "[AutoPOE2 Launcher] Dang cho game khoi dong va nap shaders... (" << w << "/35s)\n";
      }
  }
  ```

### 5.2. Tầng Quản Lý Python (`src/assistant_tool/client_launcher.py`)
- **Phát hiện đa tầng**:
  1. Tầng tiến trình OS (Toolhelp32 Snapshot & psutil): Kiểm tra `cls.TARGET_PROCESS_NAMES` (`pathofexile.exe`). Bất kể cửa sổ đã hiển thị hay chưa, chỉ cần có tiến trình là nhận diện ngay lập tức sau 1-2 giây.
  2. Tầng cửa sổ DWM: Kiểm tra `POEWindowClass` và kích thước thực tế `> 200x200`.
- **Cơ chế chống khởi chạy trùng lặp (Instance Deduplication)**:
  ```python
  if cls.is_client_running():
      print("[ClientLauncher] Client POE2 đã đang chạy. Không khởi chạy thêm instance mới.", flush=True)
      return True
  ```
- **Thời gian chờ thích ứng (Adaptive Timeout 35s)**:
  Chờ đủ 35 giây cho đến khi `is_client_window_ready() == True` hoặc tiến trình đã chạy ổn định `> 5s`.

### 5.3. Khóa An Toàn Phần Cứng 4 Tầng (Foreground Interlock)
- Triệt tiêu 100% việc rò rỉ input ra Desktop và thanh Start menu: Mọi lệnh chuột/phím chỉ được phát khi `GetForegroundWindow()` thực sự là cửa sổ của Path of Exile 2.

---

## 6. HƯỚNG DẪN VẬN HÀNH & NGUYÊN TẮC BẢO TRÌ BẤT BIẾN (ZERO DRIFT GUIDELINES)

1. **Nguyên tắc 1 - Tôn Trọng Bản Chất Monolithic**:
   - Tuyệt đối không tìm kiếm hay viết mã giả định sự tồn tại của một launcher độc lập ngoài `PathOfExile.exe`. Mọi cơ chế tự động mở game đều trỏ trực tiếp vào `PathOfExile.exe`.
2. **Nguyên tắc 2 - Tuân Thủ Ngưỡng Chờ Nạp 33-35 Giây**:
   - Khi khởi động game từ trạng thái tắt hoàn toàn (cold start), không được phép hạ thấp ngưỡng timeout dưới 35 giây.
3. **Nguyên tắc 3 - Ưu Tiên Kiểm Tra Tiến Trình Trước Khi Kiểm Tra HWND**:
   - Luôn sử dụng Toolhelp32 Snapshot để xác nhận `PathOfExile.exe` có đang sống hay không trước khi đưa ra quyết định xử lý tiếp theo.
4. **Nguyên tắc 4 - Không Can Thiệp Khi Game Đang Chạy Bình Thường**:
   - Nếu `is_client_running()` trả về `True`, hệ thống tuyệt đối không can thiệp vào tiến trình game, đảm bảo trải nghiệm liền mạch cho người dùng.

---
*Tài liệu này được biên soạn bởi Sub-Agent Chuyên Trách Tài Liệu & Kiến Trúc Dự Án (`TASK-DOCS-LAUNCHER-ANALYSIS`), tuân thủ tuyệt đối Điều 6 của AGENTS.md / GEMINI.md, loại bỏ hoàn toàn nguy cơ lệch pha tài liệu (zero documentation drift).*
