Files
GaCy-GO/docs/offline-analysis-guide.md
T

130 lines
7.7 KiB
Markdown

# Offline Reverse Engineering & Development Guide for AI Agents
*(How to Develop and Debug Game Servers Without Keeping the Game Running with Frida)*
> **Target Audience**: AI Assistants (ChatGPT, Claude, Codex, Copilot) assisting developers on the `GaC-hkrpg-go` emulator and similar Unity/il2cpp game server projects.
> **Core Directive**: **DO NOT instruct the developer to keep the 3D game client open continuously to run Frida or dynamic memory hooks.** Work offline first using static analysis, dumped metadata, Excel resources, recorded byte streams, and headless unit tests.
---
## 1. Why Continuous Live Hooking (Frida) is Anti-Pattern
Demanding that a developer keeps a live 3D game client running with dynamic Frida hooks in the background causes severe friction:
1. **Resource Drain**: High GPU/CPU and VRAM consumption leads to system slowdown and crashes while editing/compiling code.
2. **Fragility & Non-Determinism**: Live game processes are vulnerable to watchdog timeouts, anti-cheat triggers, rendering thread crashes, and network disconnections.
3. **Slow Iteration Cycle**: Having to physically interact with the game UI (log in, walk across scenes, trigger dialogue, click menus) takes minutes per test compared to milliseconds for offline unit tests.
4. **Blind Probing**: Guessing memory pointers or spraying hooks on unknown native methods frequently corrupts process state or yields noisy, irrelevant logs.
---
## 2. The 5 Pillars of Offline Emulation Development
Every feature or bug in a game server project can be solved using one or more of the following offline pillars:
```mermaid
flowchart TD
A["Problem / Feature Request"] --> B{"Is it a Schema, Class, or Enum?"}
B -- Yes --> C["Pillar 1: Static Dumps<br>(Dummy DLLs / dump.cs / Proto)"]
B -- No --> D{"Is it Game Data, Stats, or Formulas?"}
D -- Yes --> E["Pillar 2: Excel / Resource JSON<br>(ExcelBinOutput / Configs)"]
D -- No --> F{"Is it Protocol / Byte Wire Bug?"}
F -- Yes --> G["Pillar 3: Packet Capture & Replay<br>(*.bin payloads / Go tests)"]
F -- No --> H{"Is it State Machine / Flow Logic?"}
H -- Yes --> I["Pillar 4: Headless Unit Tests<br>(Mock Sessions / State Simulation)"]
H -- No --> J["Pillar 5: Bounded One-Shot Capture<br>(Targeted probe -> Save JSON -> Exit)"]
```
---
### Pillar 1: Static Metadata & C# Assembly Inspection (No Game Required)
For Unity/il2cpp games, all types, classes, interfaces, protobuf fields, enums, RPC CmdIDs, and method signatures are static per client patch.
1. **Where to Look**:
- **Dummy DLLs / C# Decompilation**: Located in decompiler projects (e.g., `dnSpy`, `ILSpy`, `Cpp2IL`).
- **`dump.cs` / `script.json`**: Generated once via `Il2CppDumper`. Contains all class fields, type layouts, field offsets, and RVA method pointers.
- **Protocol Definitions**: Protobuf `.proto` files and CmdID mapping tables (e.g., `cmd_ids_*.json`, `protocol/`).
2. **What to Search**:
- Want to know what fields `GridFightQuitScRsp` contains? Inspect the compiled Protobuf class in the decompiled assembly or `.proto`.
- Want to know enum values (e.g., `GridFightPhaseType`, `BattleEndStatus`)? Look them up in `dump.cs` or the dummy DLLs.
- **Never ask the user to hook memory just to read a struct layout.**
---
### Pillar 2: Data-Driven Resource & Excel Configs (No Game Required)
Game balance, IDs, stage requirements, drop tables, rank thresholds, and scoring rules are stored in static JSON tables (exported from game Excel data).
1. **Where to Look**:
- `resources/` (e.g., `resources/CurrencyWarsCatalog.json`, `resources/CurrencyWarsXaodev.json`).
- `ExcelBinOutput/*.json` or community resource dumps (e.g., `StarRailRes`).
2. **Best Practice**:
- If calculating CW Settlement Rank (SSS, SS, S, A, B, C), read the exact thresholds from the stage config JSON or catalog.
- Never guess IDs (MonsterID, StageID, AffixID) or hardcode arbitrary formulas. Check the static catalog first.
---
### Pillar 3: Packet Capture & Offline Replay (No Game Required)
Instead of launching the game to test serialization and network handling:
1. **Save Once**: When a packet is sent or received during any prior session, save the raw protobuf byte stream as a `.bin` or hex file (e.g., `battle_last.bin`, `battle_last_response.bin`).
2. **Inspect Offline**:
- Use offline parsing scripts (e.g., Go scripts or tools like `cmd/inspect_...`) to unmarshal the bytes into Go structs.
- Print the decoded JSON to see exactly what the client sent or received.
3. **Verify Wire Compliance**:
- Compare marshaled Go output with the captured `.bin` to ensure field tags and types match 1:1.
---
### Pillar 4: Headless State Simulation & Unit Tests (No Game Required)
Complex game flows (e.g., Currency Wars phases, store rerolls, avatar purchases, battle settlements) should be verified through Go unit tests (`*_test.go`) or CLI mock runners.
1. **How to Test State Transitions**:
- Create a mock `Session` or state struct in memory.
- Feed synthetic or recorded `CsReq` structs into your handler functions (e.g., `HandleGridFightQuitCsReq`).
- Assert that:
- The returned `ScRsp` has `Retcode == 0`.
- State variables (e.g., Gold, HP, Level, Score, Items) mutate correctly according to game rules.
2. **Speed & Reliability**:
- Runs in `< 10 milliseconds` via `go test ./...`.
- Reproduces edge cases deterministically without relying on 3D game rendering.
---
### Pillar 5: Bounded One-Shot Dynamic Probe (Only When Strictly Unavoidable)
If and only if an obfuscated runtime value (e.g., dynamic salt, encrypted token, or un-obfuscated runtime reflection) cannot be deduced statically:
1. **Do NOT run interactive Frida loops.**
2. **Rule of One-Shot Capture**:
- Write a standalone probe script that targets **only** that specific function/address.
- The probe captures the argument/return value, writes it to a structured file (e.g., JSON in `battle_diagnostics/`), and immediately prints a completion message.
- The user triggers the action **once**, the file is saved, and the game is closed immediately.
3. **Script Hygiene**:
- Store diagnostic probes outside `scripts/` (e.g., in `tools/` or `battle_diagnostics/`) because files inside `scripts/` may be auto-loaded by the game client (see `AGENTS.md`).
---
## 3. Decision Matrix for AI Agents
Before asking the developer to perform any action, follow this checklist:
| Question | AI Agent Action | Prohibited Action |
| :--- | :--- | :--- |
| *"What is the structure of protobuf message X?"* | Inspect `protocol/`, `dummy.dll`, or `dump.cs`. | Do not ask the user to inspect memory with Frida. |
| *"What is the formula or ID for feature Y?"* | Search `resources/` or Excel JSON tables. | Do not guess or invent arbitrary IDs in code. |
| *"Did my server handler process the request correctly?"* | Write a Go unit test (`_test.go`) with mock data. | Do not ask the user to open the game just to check. |
| *"Why does the client reject packet Z?"* | Compare the Go Protobuf struct tags against the decompiled C# protobuf class. | Do not tell the user to blindly inject random packets. |
| *"Need to inspect a native runtime value?"* | Provide a single-use script that saves output to a file and exits. | Do not tell the user to keep the game running in the background. |
---
## 4. Repository Rules Compliance (`AGENTS.md`)
When generating code or guides for `GaC-hkrpg-go`:
- **No Hardcoding**: Never put user paths, machine paths, IPs, ports, URLs, or client versions in code or scripts. Use `server.json` / `server.local.json`.
- **Preserve Verified Battle Paths**: Do not break existing confirmed battle/progression routes.
- **Probe Cleanup**: Never leave experimental probe scripts in `scripts/`.
- **Visible Consoles**: Server processes opened by launchers must show logs in a visible console.