docs: enrich Doc/ with deep-dive technical contracts, traps, and handoff
This commit is contained in:
1 parent
3411e5b058
commit
fc262f8331
9 files changed
+502
-8
No files matched your search
@@ -0,0 +1,112 @@
|
||||
# ส่งต่องาน G-Launcher (G-LAUNCHER-HANDOFF)
|
||||
> เอกสารส่งต่อสถานะทางเทคนิค ฉบับสมบูรณ์สำหรับ AI Agent และนักพัฒนา
|
||||
> อ้างอิงมาตรฐานการบันทึกสถานะตามแบบฉบับ `GaC-hkrpg-go/docs`
|
||||
|
||||
---
|
||||
|
||||
> **อ่านหัวข้อนี้ก่อนเริ่มงานทุกครั้ง (CRITICAL NOTICE):**
|
||||
> - **Active Branch:** ทำงานบนสาขา **`Dev`** เท่านั้น (ห้ามแตะต้องหรือ push ตรงเข้า main)
|
||||
> - **Remote URL:** `https://gaytea.cod-algieba.ts.net/GaCy/G-Launcher.git`
|
||||
> - **หลักการตัดสินใจ:** แยกคำว่า **“มีโค้ดใน source”**, **“build ผ่าน”**, **“วางไฟล์แล้ว”** และ **“ผู้ใช้ยืนยันผลจริงแล้ว”** ออกจากกันอย่างเด็ดขาด
|
||||
> - **กฎเหล็กสถาปัตยกรรม:**
|
||||
> 1. แก้ที่ Go Backend (`internal/`, `pkg/`) ก่อน Frontend UI เสมอ และต้องรัน `go vet ./...` ผ่าน 100% ก่อนแตะ UI
|
||||
> 2. ห้าม Hardcode IP, URL, Port, หรือ Drive Letter ใดๆ ทั้งสิ้น (รวมไว้ที่ [`pkg/constant/constant.go`](../pkg/constant/constant.go))
|
||||
> 3. วงจรอัปเดต: **โหลดลง Temp -> Build ใน Temp -> แทนที่ไฟล์เดิม -> ลบ Temp ทิ้ง 100%**
|
||||
|
||||
อัปเดตล่าสุด: 30 ตุลาคม 2026 (Asia/Bangkok) | สถานะ Git: Branch `Dev` สะอาด (All clean)
|
||||
|
||||
---
|
||||
|
||||
## 1. ตารางสรุปสถานะระบบ (System Implementation & Verification Matrix)
|
||||
|
||||
| ระบบย่อย (Subsystem) | โค้ดใน Source | Build ผ่าน | Deploy/Run | ยืนยันผลจริง | รายละเอียดทางเทคนิค / ไฟล์อ้างอิง |
|
||||
| :--- | :---: | :---: | :---: | :---: | :--- |
|
||||
| **Go Backend Core Services** | ✅ | ✅ | ✅ | ✅ | บริการ 5 ตัวลงทะเบียนใน `main.go` ผ่าน `app.RegisterService` |
|
||||
| **Wails v3 TypeScript Bindings** | ✅ | ✅ | ✅ | ✅ | สร้างผ่าน `wails3 generate bindings` ลงที่ `frontend/bindings/` |
|
||||
| **Frontend UI (React 19 + DaisyUI)** | ✅ | ✅ | ✅ | ✅ | React 19 + Vite + Tailwind v4 + DaisyUI v5 คอมไพล์ผ่าน 100% |
|
||||
| **Auto-Updater & Bootstrap Script** | ✅ | ✅ | ✅ | ✅ | `scripts/bootstrap.ps1` ทำงานแบบ Temp Build + Cleanup 100% |
|
||||
| **One-Click Batch Launcher** | ✅ | ✅ | ✅ | ✅ | `update-and-build.bat` เรียกใช้ PowerShell Bypass UTF-8 BOM |
|
||||
| **Go Backend Source Updater** | ✅ | ✅ | ✅ | ⚠️ รอ UI เรียก | `BuildAndUpdateFromSource` ใน `internal/git-service/launcher.go` |
|
||||
| **Portable MinGit Runtime** | ✅ | ✅ | ✅ | ✅ | `internal/git-service/git_runtime.go` ดึง MinGit x64 อัตโนมัติ |
|
||||
| **Atomic Game Path Persistence** | ✅ | ✅ | ✅ | ✅ | `internal/fs-service/game-selection.go` ใช้ Windows `MoveFileEx` |
|
||||
| **Zift Archive Patching (.ziff)** | ✅ | ✅ | ✅ | ⚠️ รอด่านทดสอบ | `internal/diff-service/ziff.go` ครอบ `zift.exe` |
|
||||
| **HPatchz Delta Patching (.hdiff)** | ✅ | ✅ | ✅ | ⚠️ รอด่านทดสอบ | `internal/diff-service/hpatchz.go` ครอบ `hpatchz.exe` |
|
||||
| **Thai Mod Engine (ExcelData)** | ✅ | ✅ | ✅ | ⚠️ รอเกมจริง | `internal/language-service/thai-patch.go` มีระบบ `.backup` |
|
||||
| **Multi-Language (i18n)** | ✅ | ✅ | ✅ | ✅ | 6 ภาษา (`th`, `en`, `ja`, `ko`, `vi`, `zh`) ใน `frontend/public/locales/` |
|
||||
| **Standalone Tool Extraction** | ✅ | ✅ | ✅ | ✅ | แตกไฟล์ `assets/` (`7za.exe`, `hpatchz.exe`, `zift.exe`) ลง `bin/` |
|
||||
|
||||
---
|
||||
|
||||
## 2. กับดักและบทเรียนทางเทคนิคที่ห้ามพลาด (Technical Traps & Pitfalls)
|
||||
|
||||
### กับดักที่ 1: Wails v3 Embed Directive ขาดไม่ได้
|
||||
* **อาการ:** `go build` หรือ `go vet` ฟ้อง `pattern all:frontend/dist: no matching files found`
|
||||
* **สาเหตุ:** `main.go` มีการประกาศ `//go:embed all:frontend/dist` ซึ่ง Compiler ของ Go จะปฏิเสธการคอมไพล์ทันทีหากโฟลเดอร์ `frontend/dist` ว่างเปล่าหรือไม่มีอยู่จริง
|
||||
* **แนวทางแก้ไข:** ต้องรัน `npm --prefix frontend run build` ก่อน หรือมีไฟล์ `.gitkeep` วางอยู่ใน `frontend/dist/` เสมอ
|
||||
|
||||
### กับดักที่ 2: Windows PowerShell 5.1 กับปัญหา UTF-8 Encoding
|
||||
* **อาการ:** รัน `powershell -File script.ps1` แล้วพังด้วยข้อผิดพลาดไวยากรณ์ เช่น `Unexpected token '}'` หรือ `You must provide a value expression following the '-' operator`
|
||||
* **สาเหตุ:** `powershell.exe` (เวอร์ชัน 5.1 เดิมของ Windows) จะอ่านไฟล์ข้อความภาษาไทยด้วย System ANSI Code Page (CP874 หรือ Windows-1252) หากไฟล์ถูกบันทึกเป็น UTF-8 แบบไม่มี BOM ไบต์อักขระภาษาไทยบางตัวจะถูกตีความเป็นเครื่องหมายคำพูด (`"`) หรือเครื่องหมายลบ (`-`) ทำให้ Parser พัง
|
||||
* **แนวทางแก้ไข:** ไฟล์ `.ps1` ที่มีอักขระสองไบต์หรือภาษาไทย **ต้องบันทึกด้วย UTF-8 with BOM (`[System.Text.Encoding]::UTF8`) เสมอ**
|
||||
|
||||
### กับดักที่ 3: Windows Process Lock ขณะอัปเดตตัวเอง
|
||||
* **อาการ:** `go build` หรือการคัดลอกไฟล์ทับ `bin/G-Launcher.exe` ล้มเหลวด้วย `Access is denied`
|
||||
* **สาเหตุ:** Windows ห้ามเขียนทับหรือลบ Executable (`.exe`) ที่โปรเซสกำลังทำงานอยู่
|
||||
* **แนวทางแก้ไข:** **เปลี่ยนชื่อไฟล์เดิมแทน (Rename)** โดยเปลี่ยนชื่อ `G-Launcher.exe` ที่กำลังรันอยู่เป็น `G-Launcher.exe.old` (Windows อนุญาตให้ rename process executable ที่กำลังรันได้) จากนั้นจึงย้ายไฟล์ executable ตัวใหม่เข้ามาเสียบแทนที่ แล้วจึงสั่งเปิดตัวใหม่และลบตัวเก่า
|
||||
|
||||
### กับดักที่ 4: Wails v3 Binding Crash หากแก้ UI ก่อน Backend
|
||||
* **อาการ:** หน้าต่าง Launcher เปิดขึ้นมาแล้วขาวสนิท จอดำ หรือ DevTools คอนโซลขึ้น `Cannot read properties of undefined`
|
||||
* **สาเหตุ:** Frontend ฝั่ง React เรียกใช้งาน IPC method ผ่าน `@bindings/...` หาก Backend ยังไม่ได้ประกาศ method นั้น หรือ type signature ไม่ตรงกัน Wails IPC Gateway จะเกิด Unhandled Exception
|
||||
* **แนวทางแก้ไข:** ปฏิบัติตาม **System-First Rule** โดยแก้ Go service ให้เสร็จ -> รัน `go vet ./...` -> รัน `wails3 generate bindings` -> ตรวจดู TypeScript interface -> จึงค่อยเริ่มเขียน UI
|
||||
|
||||
### กับดักที่ 5: Git Interactive Terminal Freeze
|
||||
* **อาการ:** รัน `git push` หรือ `git clone` ผ่านสคริปต์อัตโนมัติแล้วโปรเซสค้าง (Hang) ไม่ยอมสิ้นสุด
|
||||
* **สาเหตุ:** Git พยายามเปิด Interactive Prompt เพื่อถาม Username/Password ในเทอร์มินัลที่ไม่มี TTY
|
||||
* **แนวทางแก้ไข:** ต้องตั้งค่า `$env:GIT_TERMINAL_PROMPT = "0"` ใน PowerShell หรือ `os.Setenv("GIT_TERMINAL_PROMPT", "0")` ใน Go ก่อนเรียกคำสั่ง Git เสมอ
|
||||
|
||||
---
|
||||
|
||||
## 3. รายละเอียดสถาปัตยกรรมระบบอัปเดต (Isolated Updater Architecture)
|
||||
|
||||
กระบวนการอัปเดตทั้งใน [`scripts/bootstrap.ps1`](../scripts/bootstrap.ps1) และ [`internal/git-service/launcher.go`](../internal/git-service/launcher.go) ปฏิบัติตามกฎ 4 ขั้นตอน:
|
||||
|
||||
```
|
||||
[ผู้ใช้สั่งอัปเดต]
|
||||
│
|
||||
▼
|
||||
1. โหลดลงโฟลเดอร์ชั่วคราว (Temp Workspace)
|
||||
├── สร้างโฟลเดอร์: temp/build_workspace หรือ os.MkdirTemp
|
||||
└── Clone ซอร์สโค้ด: git clone --depth 1 --branch Dev <RepoUrl> <TempDir>
|
||||
│
|
||||
▼
|
||||
2. คอมไพล์ในโฟลเดอร์ชั่วคราว (Isolated Build)
|
||||
├── npm install --no-audit --no-fund
|
||||
├── npm run build (คอมไพล์ React 19 Frontend)
|
||||
├── go mod tidy
|
||||
├── wails3 generate syso (สร้าง Windows Manifest & Application Icon)
|
||||
└── go build -tags production -trimpath -ldflags="-w -s -H windowsgui" -o <TempDir>/bin/G-Launcher.exe .
|
||||
│
|
||||
▼
|
||||
3. สลับไฟล์ไบนารี (Atomic Swap & Rollback)
|
||||
├── ตรวจสอบว่าไฟล์ไบนารีใหม่มีขนาด > 0 ไบต์
|
||||
├── เปลี่ยนชื่อ: bin/G-Launcher.exe -> bin/G-Launcher.exe.old
|
||||
├── ย้ายไฟล์ใหม่: <TempDir>/bin/G-Launcher.exe -> bin/G-Launcher.exe
|
||||
├── หากล้มเหลว: ย้าย .old กลับมาทันที (Atomic Rollback)
|
||||
└── หากสำเร็จ: ลบไฟล์ .old ทิ้ง
|
||||
│
|
||||
▼
|
||||
4. ทำลายโฟลเดอร์ชั่วคราว 100% (Purge Temp)
|
||||
└── บล็อก finally / defer os.RemoveAll ทำลายโฟลเดอร์ Temp ทิ้งทั้งหมด ห้ามทิ้งไฟล์ขยะ
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Checklist สำหรับการตรวจสอบก่อน Commit / Push
|
||||
|
||||
ก่อนจะบันทึก Commit ใดๆ ในโปรเจกต์นี้ ให้ตรวจสอบ Checklist ต่อไปนี้ให้ครบ 100%:
|
||||
|
||||
1. [ ] อยู่บน Git branch **`Dev`** (`git branch --show-current` คืนค่า `Dev`)
|
||||
2. [ ] ไม่มี URL, IP Address, หรือ Absolute Path (`C:\...`) ฮาร์ดโค้ดอยู่ในไฟล์ logic ใดๆ
|
||||
3. [ ] ฝั่ง Go Backend: รัน `go vet ./...` ผ่าน 100% ไม่มีข้อผิดพลาด
|
||||
4. [ ] ฝั่ง TypeScript/React: รัน `npm --prefix frontend run build` ผ่าน 100%
|
||||
5. [ ] รัน `git status` แล้วไม่มีไฟล์ขยะ เช่น `tools/`, `node_modules/`, `bin/`, `temp/`, หรือ `*.old` ติดเข้ามาใน Staging Area
|
||||
+27
-8
@@ -21,14 +21,33 @@
|
||||
|
||||
## 📑 สารบัญเอกสารในโฟลเดอร์นี้
|
||||
|
||||
1. [**ARCHITECTURE.md**](./ARCHITECTURE.md)
|
||||
* สถาปัตยกรรมโครงสร้างโปรเจกต์ Wails v3, Frontend React 19, และ Backend Services ทั้ง 5 ตัว
|
||||
2. [**DEVELOPMENT_RULES.md**](./DEVELOPMENT_RULES.md)
|
||||
* กฎ 6 ข้อในการพัฒนา และบทเรียนจาก Horoyoi-san & โปรเจกต์เดิม (Ananta / GaC-hkrpg-go)
|
||||
3. [**UPDATER_SYSTEM.md**](./UPDATER_SYSTEM.md)
|
||||
* กลไกและวงจรชีวิตของระบบ Auto-Updater และ Local Build (Temp Isolation, Rollback, Cleanup)
|
||||
4. [**HISTORY_AND_LOGS.md**](./HISTORY_AND_LOGS.md)
|
||||
* ไทม์ไลน์และประวัติการพัฒนาตั้งแต่เริ่มรวม 2 Repos จนถึงฟีเจอร์ปัจจุบัน
|
||||
### 📌 เอกสารส่งต่อสถานะหลักและสัญญาทางเทคนิค (Core Handoff & Technical Contracts)
|
||||
1. [**G-LAUNCHER-HANDOFF.md**](./G-LAUNCHER-HANDOFF.md)
|
||||
* 🌟 **เอกสารหลักที่ต้องอ่านเป็นไฟล์แรกหลัง Compact:** สรุปสถานะงานแบบแยกชั้น (โค้ด/บิลด์/ดีพลอย/ยืนยันผล), กับดัก 5 ข้อที่ห้ามพลาด, และ Checklist ก่อน Commit
|
||||
2. [**updater-temp-lifecycle.md**](./updater-temp-lifecycle.md)
|
||||
* สัญญาทางเทคนิคของระบบอัปเดต 4 ขั้นตอน: การจัดการ Temp Workspace, การเลี่ยง Windows Process Lock, และระบบ Atomic Rollback
|
||||
3. [**wails3-ipc-bindings-contract.md**](./wails3-ipc-bindings-contract.md)
|
||||
* สัญญาการสื่อสาร Wails v3 IPC, ระบบ Type-Safe Bindings, และเหตุผลทางสถาปัตยกรรมที่ต้องทำ Go Backend ก่อน Frontend UI
|
||||
4. [**diff-patching-engine.md**](./diff-patching-engine.md)
|
||||
* กลไกการแพตช์ไฟล์ตัวเกมด้วย HPatchz (`.hdiff`), Zift (`.ziff`), การสกัดเครื่องมือจาก Embed Assets, และระบบ Safe Backup
|
||||
5. [**git-runtime-mingit.md**](./git-runtime-mingit.md)
|
||||
* สถาปัตยกรรม Portable MinGit: การตรวจจับและดาวน์โหลดอัตโนมัติโดยไม่ต้องใช้สิทธิ์ Administrator และการป้องกัน Terminal Hang
|
||||
6. [**game-selection-persistence.md**](./game-selection-persistence.md)
|
||||
* ระบบบันทึกพาธตัวเกมแบบทนทานต่อ Crash ด้วย Windows API `MoveFileEx` เพื่อป้องกันปัญหาไฟล์ JSON กลายเป็น 0 ไบต์
|
||||
7. [**thai-localization-mod.md**](./thai-localization-mod.md)
|
||||
* ระบบแปลภาษาไทย 2 ระดับ: Launcher UI (i18next) และ Game Modding (การแพตช์ไบต์ใน ExcelData พร้อมระบบกู้คืน)
|
||||
8. [**upstream-merge-audit.md**](./upstream-merge-audit.md)
|
||||
* ตารางแจกแจงที่มาของโค้ด (File Attribution Matrix) จากทั้ง Firefly Launcher และ Horoyoi-san
|
||||
|
||||
### 🏛️ เอกสารสถาปัตยกรรมและกฎการพัฒนาทั่วไป
|
||||
9. [**ARCHITECTURE.md**](./ARCHITECTURE.md)
|
||||
* สถาปัตยกรรมโครงสร้างโปรเจกต์ระดับสูง Wails v3, Frontend React 19, และ Backend Services ทั้ง 5 ตัว
|
||||
10. [**DEVELOPMENT_RULES.md**](./DEVELOPMENT_RULES.md)
|
||||
* กฎ 6 ข้อในการพัฒนา และบทเรียนจาก Horoyoi-san & โปรเจกต์เดิม (Ananta / GaC-hkrpg-go)
|
||||
11. [**UPDATER_SYSTEM.md**](./UPDATER_SYSTEM.md)
|
||||
* ภาพรวมและ Sequence Diagram ของระบบ Auto-Updater และ Local Build
|
||||
12. [**HISTORY_AND_LOGS.md**](./HISTORY_AND_LOGS.md)
|
||||
* ไทม์ไลน์และประวัติการพัฒนาตั้งแต่เริ่มรวม 2 Repos จนถึงปัจจุบัน
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# 🧩 สัญญาทางเทคนิค: กลไกการแพตช์ไฟล์ตัวเกม (Diff & Patching Engine)
|
||||
|
||||
เอกสารนี้ระบุรายละเอียดการทำงานของระบบประมวลผลไฟล์ส่วนต่าง (Delta Patching) และการขยายแพ็กเกจข้อมูลเกมใน G-Launcher ซึ่งผสานเทคโนโลยีจาก Firefly Launcher และ Sunbringer เข้าด้วยกัน
|
||||
|
||||
---
|
||||
|
||||
## 1. ภาพรวมของเครื่องมือและฟอร์แมตที่รองรับ
|
||||
|
||||
| รูปแบบไฟล์ | เครื่องมือประมวลผล | ที่มาของโค้ด | หน้าที่และการทำงาน |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **`.hdiff`** | `bin/hpatchz.exe` | Firefly / Hoyoverse | ใช้สำหรับอัปเดตไฟล์เกมแบบไบนารีเดลต้า (Byte-level Delta Patch) |
|
||||
| **`.ziff`** | `bin/zift.exe` | Horoyoi-san (Sunbringer) | อัปเดตไฟล์เกมแบบบีบอัดพิเศษ Zift archive สำหรับม็อดและไฟล์แพตช์เฉพาะ |
|
||||
| **`.zip` / `.7z`** | `bin/7za.exe` | 7-Zip Portable | คลายไฟล์ข้อมูลเกม แพตช์เสียง และแพ็กเกจเซิร์ฟเวอร์/พร็อกซี |
|
||||
| **Protobuf Chunk** | `pkg/firefly/` | Firefly Engine | อ่านและถอดรหัส Hoyoverse manifest chunk สำหรับตรวจสอบความสมบูรณ์ของไฟล์ |
|
||||
|
||||
---
|
||||
|
||||
## 2. กลไกการสกัดเครื่องมือจาก Embed Assets (Tool Extraction Lifecycle)
|
||||
|
||||
เพื่อบรรลุเป้าหมาย **Zero-Dependency** ผู้ใช้ปลายทางไม่จำเป็นต้องมี 7-Zip หรือ HDiffz ติดตั้งในเครื่องล่วงหน้า:
|
||||
1. ไบนารีของเครื่องมือทั้งหมดถูกฝัง (Embed) อยู่ในโค้ด Go ผ่าน `//go:embed assets/*` ใน [`main.go`](../main.go)
|
||||
2. เมื่อ Launcher เริ่มทำงาน ฟังก์ชันตรวจสอบจะสแกนโฟลเดอร์ `bin/`:
|
||||
* หากตรวจไม่พบ `bin/7za.exe`, `bin/hpatchz.exe` หรือ `bin/zift.exe`
|
||||
* ระบบจะดึงไบต์จากหน่วยความจำออกมาเขียนเป็นไฟล์ executable ในโฟลเดอร์ `bin/` อัตโนมัติ พร้อมตั้งสิทธิ์การรัน
|
||||
3. ไฟล์ที่ได้รับการดูแล:
|
||||
* `bin/7za.exe`, `bin/7za.dll`, `bin/7zxa.dll`
|
||||
* `bin/hpatchz.exe`
|
||||
* `bin/zift.exe`
|
||||
|
||||
---
|
||||
|
||||
## 3. กฎความปลอดภัยของข้อมูลตัวเกม (Safe Backup & Atomic Rollback)
|
||||
|
||||
ไฟล์ตัวเกมมีขนาดใหญ่หลายสิบกิกะไบต์และเสียหายได้ง่าย หากการแพตช์ล้มเหลวระหว่างทาง ห้ามทิ้งไฟล์ให้อยู่ในสภาพพัง:
|
||||
|
||||
```
|
||||
[เริ่มต้นแพตช์ไฟล์: StarRailBase.dll]
|
||||
│
|
||||
▼
|
||||
1. สำรองไฟล์เดิม (Safe Backup)
|
||||
└── คัดลอก StarRailBase.dll -> StarRailBase.dll.backup
|
||||
│
|
||||
▼
|
||||
2. ดำเนินการแพตช์ด้วย HPatchz หรือ Zift
|
||||
└── hpatchz.exe StarRailBase.dll patch.hdiff StarRailBase.dll.tmp
|
||||
│
|
||||
▼
|
||||
3. ตรวจสอบความถูกต้อง (Checksum Verification)
|
||||
├── หากผลลัพธ์ตรงกับ Checksum ที่กำหนด:
|
||||
│ ├── สลับ StarRailBase.dll.tmp -> StarRailBase.dll
|
||||
│ └── ลบไฟล์สำรอง StarRailBase.dll.backup ทิ้ง
|
||||
│
|
||||
└── หากเกิดข้อผิดพลาด / Checksum ไม่ตรง:
|
||||
├── ลบไฟล์ชั่วคราว StarRailBase.dll.tmp ทิ้งทันที
|
||||
├── Atomic Rollback: กู้คืนไฟล์จาก StarRailBase.dll.backup
|
||||
└── ส่งข้อความแจ้งเตือนความล้มเหลวให้ผู้ใช้ทราบอย่างชัดเจน
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. สถานะการทดสอบและข้อจำกัด
|
||||
* **ความพร้อมของระบบ:** โครงสร้าง Service และ Command Execution เขียนเสร็จสมบูรณ์ 100% ใน `internal/diff-service/`
|
||||
* **ขอบเขตที่รอการยืนยัน:** การทดสอบด้วยไฟล์ `.ziff` และ `.hdiff` ขนาดใหญ่ของตัวเกมจริง ต้องรอการทดสอบร่วมกับไฟล์แพตช์จริงในสภาพแวดล้อมของผู้ใช้
|
||||
@@ -0,0 +1,38 @@
|
||||
# 🛡️ สัญญาทางเทคนิค: การบันทึกพาธเกมแบบทนทานต่อ Crash (Game Selection Persistence)
|
||||
|
||||
เอกสารนี้ระบุสถาปัตยกรรมการบันทึกและอ่านพาธที่ตั้งของไฟล์ตัวเกม (`StarRail.exe`) ใน [`internal/fs-service/game-selection.go`](../internal/fs-service/game-selection.go)
|
||||
|
||||
---
|
||||
|
||||
## 1. ที่มาและปัญหาความเสียหายของไฟล์คอนฟิก (The Corruption Problem)
|
||||
|
||||
ในโปรเจกต์ต้นแบบเดิม การบันทึกพาธของเกมใช้ฟังก์ชันมาตรฐาน `os.WriteFile` ซึ่งมีจุดอ่อนร้ายแรงบนระบบปฏิบัติการ Windows:
|
||||
* หากเครื่องคอมพิวเตอร์ดับกะทันหัน ไฟตก หรือ Launcher เกิด Crash ในเสี้ยววินาทีที่กำลังเขียนไฟล์
|
||||
* ไฟล์ `game-selection.json` จะกลายเป็น **ไฟล์ว่างเปล่าขนาด 0 ไบต์ (Zero-Byte Corrupted File)**
|
||||
* เมื่อเปิด Launcher ขึ้นมาใหม่ โปรแกรมจะไม่สามารถอ่าน JSON ได้ ส่งผลให้ผู้ใช้ต้องค้นหาและเลือกพาธเกมใหม่ซ้ำซาก
|
||||
|
||||
---
|
||||
|
||||
## 2. โซลูชัน: Atomic Write ผ่าน Windows API `MoveFileEx`
|
||||
|
||||
เพื่อแก้ไขปัญหานี้ G-Launcher จึงนำรูปแบบ **Atomic Write** ที่ผสานมาจาก Sunbringer มาใช้งานอย่างเคร่งครัด:
|
||||
|
||||
```
|
||||
[ผู้ใช้เลือกพาธเกม: C:\Games\StarRail.exe]
|
||||
│
|
||||
▼
|
||||
1. เขียนข้อมูล JSON ลงในไฟล์ชั่วคราว (.tmp)
|
||||
└── %APPDATA%\g-launcher\game-selection.json.tmp
|
||||
│
|
||||
▼
|
||||
2. Flush ข้อมูลลงดิสก์จริง (Sync to Storage)
|
||||
└── file.Sync() เพื่อให้แน่ใจว่าข้อมูลถูกเขียนลงฮาร์ดดิสก์/SSD จริง ไม่ค้างใน OS Cache
|
||||
│
|
||||
▼
|
||||
3. สลับไฟล์ด้วย Windows Native API MoveFileEx
|
||||
└── MoveFileExW(tempPath, targetPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)
|
||||
```
|
||||
|
||||
### คุณสมบัติของ `MoveFileEx`:
|
||||
* **Atomic Operation:** บนระบบไฟล์ NTFS การสลับไฟล์ด้วย `MoveFileEx` ถือเป็น Atomic Operation กล่าวคือ ไฟล์จะเปลี่ยนเป็นเวอร์ชันใหม่ทันที หรือหากเกิดเหตุขัดข้อง ไฟล์เดิมก็จะยังคงอยู่สมบูรณ์ 100% ไม่มีทางเกิดไฟล์ 0 ไบต์
|
||||
* **No Hardcoding:** ตำแหน่งไฟล์คอนฟิกถูกสร้างขึ้นโดยใช้ `os.UserConfigDir()` ร่วมกับ `filepath.Join(...)` ซึ่งจะได้พาธมาตรฐาน `%APPDATA%\g-launcher\game-selection.json` โดยไม่ฝังชื่อไดรฟ์ `C:\` ในโค้ด
|
||||
@@ -0,0 +1,54 @@
|
||||
# 🧰 สัญญาทางเทคนิค: ระบบจัดการ Portable MinGit Runtime
|
||||
|
||||
เอกสารนี้อธิบายกลไกของ **Portable MinGit** ใน G-Launcher ซึ่งช่วยให้ระบบสามารถรันคำสั่ง Git (เช่น Git Clone, Git Fetch, Git Checkout) ได้บนคอมพิวเตอร์ของผู้ใช้ทั่วไป แม้ว่าในเครื่องจะไม่ได้ติดตั้งโปรแกรม Git หรือไม่มีสิทธิ์ Administrator ก็ตาม
|
||||
|
||||
---
|
||||
|
||||
## 1. ที่มาและปัญหาเดิม (Background & Problem Statement)
|
||||
|
||||
1. ผู้เล่นเกมทั่วไปส่วนใหญ่ไม่มีโปรแกรม Git สำหรับนักพัฒนาติดตั้งอยู่ในเครื่อง
|
||||
2. ตัวติดตั้ง Git for Windows ปกติต้องการสิทธิ์ Administrator (UAC Prompt) ซึ่งสร้างความยุ่งยากให้แก่ผู้ใช้งาน
|
||||
3. ตัวอัปเดต Launcher และระบบดาวน์โหลดเซิร์ฟเวอร์/พร็อกซี จำเป็นต้องใช้ Git ในการดึงข้อมูล
|
||||
|
||||
---
|
||||
|
||||
## 2. ลำดับการตรวจสอบและเตรียม Git Runtime (Discovery Order)
|
||||
|
||||
ใน [`internal/git-service/git_runtime.go`](../internal/git-service/git_runtime.go) ฟังก์ชัน `ensureGit()` ทำงานตามลำดับความสำคัญดังนี้:
|
||||
|
||||
```
|
||||
[ร้องขอ Git Executable]
|
||||
│
|
||||
▼
|
||||
1. ตรวจสอบ System PATH (exec.LookPath("git"))
|
||||
├── พบ -> คืนพาธของ Git ในเครื่องทันที (เช่น C:\Program Files\Git\cmd\git.exe)
|
||||
│
|
||||
└── ไม่พบ -> เข้าสู่ขั้นตอนที่ 2
|
||||
│
|
||||
▼
|
||||
2. ตรวจสอบโฟลเดอร์พกพาภายใน (tools/mingit/cmd/git.exe)
|
||||
├── พบ -> นำพาธนี้ไปใช้งานทันที
|
||||
│
|
||||
└── ไม่พบ -> เข้าสู่ขั้นตอนที่ 3
|
||||
│
|
||||
▼
|
||||
3. ดาวน์โหลด Portable MinGit x64 อัตโนมัติ
|
||||
├── ดึงข้อมูล Release ล่าสุดจาก GitHub API:
|
||||
│ https://api.github.com/repos/git-for-windows/git/releases/latest
|
||||
├── กรองหาไฟล์แพ็กเกจ: MinGit-*-64-bit.zip
|
||||
├── ดาวน์โหลดลงไฟล์ชั่วคราว os.CreateTemp
|
||||
├── แตกไฟล์ Zip ลงโฟลเดอร์เป้าหมาย
|
||||
└── คืนค่าพาธ git.exe พร้อมใช้งาน
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. การป้องกัน Terminal Freeze (Non-Interactive Terminal Execution)
|
||||
|
||||
เมื่อโปรแกรม Launcher หรือสคริปต์อัตโนมัติเรียกใช้คำสั่ง Git หาก Git ตรวจพบว่าต้องการรหัสผ่านหรือการยืนยันตัวตน มันจะพยายามเปิด Interactive TTY Prompt ซึ่งส่งผลให้โปรเซสของ Launcher **ค้างอย่างถาวร (Hang/Freeze)**:
|
||||
|
||||
### แนวทางป้องกันที่นำมาใช้:
|
||||
1. **ตั้งค่าตัวแปรสภาพแวดล้อม:**
|
||||
* ใน Go Backend: `cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")`
|
||||
* ใน PowerShell: `$env:GIT_TERMINAL_PROMPT = "0"`
|
||||
2. **ผลลัพธ์:** หาก Git ต้องการการยืนยันตัวตนแต่ไม่สามารถทำได้ Git จะ Return Error ออกมาทันทีแทนที่จะค้าง ทำให้ระบบสามารถดักจับและส่ง Error ไปแจ้งเตือนบน UI ได้อย่างถูกต้อง
|
||||
@@ -0,0 +1,24 @@
|
||||
# 🇹🇭 สัญญาทางเทคนิค: ระบบแปลภาษาไทยและม็อดตัวเกม (Thai Localization & Game Modding)
|
||||
|
||||
เอกสารนี้ระบุรายละเอียดของระบบแปลภาษาไทย 2 ระดับใน G-Launcher:
|
||||
1. **Launcher UI Localization:** การแปลภาษาบนหน้าจอและปุ่มควบคุมของตัว Launcher
|
||||
2. **Game Asset Modding:** ระบบติดตั้งและถอนการติดตั้งแพตช์ภาษาไทยลงในไฟล์ข้อมูลของตัวเกม
|
||||
|
||||
---
|
||||
|
||||
## 1. การแปลภาษาบนหน้าต่าง Launcher (UI Localization)
|
||||
|
||||
* **เครื่องมือ:** `i18next` + `react-i18next`
|
||||
* **ไฟล์ข้อมูลคำแปลภาษาไทย:** [`frontend/public/locales/th.json`](../frontend/public/locales/th.json)
|
||||
* **การเปลี่ยนภาษาแบบทันที:** คอมโพเนนต์ [`LanguageSwitcher`](../frontend/src/components/languageSwitcher/) ช่วยให้ผู้ใช้สามารถสลับระหว่างภาษาไทย (`th`), อังกฤษ (`en`), จีน (`zh`), ญี่ปุ่น (`ja`), เกาหลี (`ko`), และเวียดนาม (`vi`) ได้ทันทีโดยไม่ต้องรีสตาร์ตโปรแกรม
|
||||
|
||||
---
|
||||
|
||||
## 2. ระบบติดตั้งม็อดภาษาไทยลงในตัวเกม (Game Asset Modding)
|
||||
|
||||
ใน [`internal/language-service/thai-patch.go`](../internal/language-service/thai-patch.go) บริการ `LanguageService` จัดการการแก้ไขไฟล์ไบนารี `ExcelData` ของเกม:
|
||||
|
||||
### กฎความปลอดภัยในการแก้ไขไฟล์เกม (Mandatory Safety Rules):
|
||||
1. **การสำรองไฟล์เดิม (Safe Backup):** ก่อนจะเริ่มเขียนหรือแก้ไขไบต์ในไฟล์ข้อมูลเกม ระบบจะทำการคัดลอกไฟล์ต้นฉบับเก็บไว้เป็นนามสกุล `.backup` เสมอ
|
||||
2. **การกู้คืนอัตโนมัติ (Atomic Restore):** หากการเขียนไบต์ล้มเหลว หรือผู้ใช้กดปุ่ม "ถอนการติดตั้งม็อด" ระบบจะนำไฟล์ `.backup` กลับมาทับไฟล์เดิมทันที ทำให้ไฟล์ตัวเกมกลับสู่สถานะของแท้ 100%
|
||||
3. **การตรวจสอบสถานะ (Status Probe):** ตรวจสอบว่ามีไฟล์ `.backup` หรือมาร์กเกอร์ของม็อดอยู่หรือไม่ เพื่อแสดงสถานะบน UI ว่าเกมนี้ลงม็อดภาษาไทยแล้วหรือยัง
|
||||
@@ -0,0 +1,74 @@
|
||||
# 🔄 สัญญาทางเทคนิค: วงจรชีวิตของระบบอัปเดต (Updater Temp Lifecycle Contract)
|
||||
|
||||
เอกสารนี้ระบุข้อตกลงและสัญญาทางเทคนิค (Contract) สำหรับระบบอัปเดตและบิลด์ในเครื่องของ G-Launcher ซึ่งครอบคลุมทั้งสคริปต์ PowerShell ([`scripts/bootstrap.ps1`](../scripts/bootstrap.ps1)) และบริการ Go Backend ([`internal/git-service/launcher.go`](../internal/git-service/launcher.go))
|
||||
|
||||
---
|
||||
|
||||
## 1. วัตถุประสงค์และข้อจำกัดของระบบปฏิบัติการ (Operating System Constraints)
|
||||
|
||||
### ปัญหาข้อจำกัดของ Windows:
|
||||
1. **Windows Executable Locking:** เมื่อโปรเซส `.exe` กำลังทำงานอยู่ ระบบปฏิบัติการจะเปิดแฮนเดิลไฟล์ด้วยการล็อกแบบแชร์การอ่าน (`FILE_SHARE_READ`) แต่ไม่อนุญาตให้เขียน (`GENERIC_WRITE`) หรือลบทิ้ง (`DELETE`) โดยตรง
|
||||
2. **ข้อยกเว้นการเปลี่ยนชื่อ (Rename Privilege):** บน Windows อนุญาตให้ **เปลี่ยนชื่อ (Rename/Move)** ไฟล์ executable ที่กำลังทำงานอยู่ได้ ตราบใดที่ยังอยู่บนโวลุม (Volume/Drive) เดียวกัน
|
||||
3. **การหลีกเลี่ยง Build In-Place:** การรัน `git pull` หรือ `go build` ทับโฟลเดอร์หลักของ Launcher ขณะที่ตัว Launcher รันอยู่ จะทำให้เกิด Exception `Access is denied` ทันที และอาจทำให้โฟลเดอร์ซอร์สโค้ดค้างอยู่ในสถานะไม่สมบูรณ์
|
||||
|
||||
---
|
||||
|
||||
## 2. ขั้นตอนทั้ง 4 ของวงจรชีวิต (The 4 Lifecycle Phases)
|
||||
|
||||
### Phase 1: การจัดเตรียมพื้นที่ชั่วคราวและการดาวน์โหลด (Download to Temp)
|
||||
* **PowerShell:**
|
||||
* โฟลเดอร์เป้าหมาย: `$tempBuildDir = Join-Path $rootDir "temp\build_workspace"`
|
||||
* หากมีโฟลเดอร์ตกค้างจากรอบก่อน ให้สั่งลบทิ้งก่อนสร้างใหม่เสมอ
|
||||
* สั่ง `git clone --depth 1 --branch Dev https://gaytea.cod-algieba.ts.net/GaCy/G-Launcher.git $tempBuildDir`
|
||||
* หากการ Clone ผ่านเน็ตเวิร์กล้มเหลว (เช่น ทำงานแบบออฟไลน์) สคริปต์จะสลับไป Clone จากโฟลเดอร์ท้องถิ่น (`$rootDir`) เข้าสู่ `$tempBuildDir` แทน
|
||||
* **Go Backend:**
|
||||
* ใช้ `tempDir, err := os.MkdirTemp("", "g-launcher-build-*")`
|
||||
* สั่งงาน Git ผ่านฟังก์ชัน `ensureGit()` เพื่อรับประกันว่ามี Portable MinGit ทำงานได้โดยไม่ต้องพึ่งสิทธิ์ Administrator
|
||||
|
||||
### Phase 2: การคอมไพล์แบบแยกส่วนในโฟลเดอร์ชั่วคราว (Isolated Build)
|
||||
* สวิตช์ Working Directory เข้าสู่โฟลเดอร์ชั่วคราว (`Push-Location $tempBuildDir` หรือ `cmd.Dir = tempDir`)
|
||||
* ลำดับการคอมไพล์:
|
||||
1. `npm --prefix frontend install --no-audit --no-fund` (ติดตั้ง dependencies ของ React 19)
|
||||
2. `npm --prefix frontend run build` (คอมไพล์ assets ผ่าน Vite 8 ได้ผลลัพธ์ลง `frontend/dist/`)
|
||||
3. `go mod tidy` (จัดระเบียบ Go modules)
|
||||
4. `wails3 generate syso` (สร้าง Windows PE Resource, Manifest, DPI awareness, และ Icon)
|
||||
5. `go build -tags production -trimpath -buildvcs=false -ldflags="-w -s -H windowsgui" -o bin/G-Launcher.exe .`
|
||||
* ตรวจสอบว่าไฟล์ไบนารีผลลัพธ์ถูกสร้างขึ้นจริง และมีขนาดมากกว่า 0 ไบต์
|
||||
* สลับกลับสู่ Working Directory เดิม (`Pop-Location`) ก่อนเริ่มขั้นตอนถัดไป
|
||||
|
||||
### Phase 3: การสลับไฟล์ไบนารีอย่างปลอดภัยและการ Rollback (Atomic Swap & Safe Rollback)
|
||||
* หากไฟล์เป้าหมาย `bin/G-Launcher.exe` มีอยู่เดิม:
|
||||
1. เปลี่ยนชื่อไฟล์เดิมเป็น `bin/G-Launcher.exe.old`
|
||||
2. ย้ายไฟล์ใหม่จากโฟลเดอร์ Temp มาวางที่ `bin/G-Launcher.exe`
|
||||
3. หากการย้ายไฟล์ล้มเหลว (เกิด Exception):
|
||||
* **Rollback ทันที:** ย้าย `bin/G-Launcher.exe.old` กลับมาเป็น `bin/G-Launcher.exe` เพื่อให้ผู้ใช้ยังสามารถเปิดโปรแกรมเดิมได้
|
||||
* แจ้งข้อผิดพลาดและยุติการทำงาน
|
||||
4. หากการย้ายไฟล์สำเร็จ:
|
||||
* ลบไฟล์ `bin/G-Launcher.exe.old` (หากโปรแกรมเดิมกำลังรันอยู่และยังลบไม่ได้ ไฟล์นี้จะถูกเพิกเฉยและรอการลบในรอบถัดไป)
|
||||
* ในฝั่ง Go Backend ใช้ไลบรารี `github.com/minio/selfupdate`:
|
||||
* ฟังก์ชัน `selfupdate.Apply(newBinaryReader, selfupdate.Options{})` ดำเนินการ Rename & Swap แบบ Atomic ในระดับ Native Windows API
|
||||
|
||||
### Phase 4: การทำลายโฟลเดอร์ชั่วคราว (Guaranteed Temp Purge)
|
||||
* **PowerShell:**
|
||||
* ครอบกระบวนการทั้งหมดด้วยบล็อก `try { ... } finally { ... }`
|
||||
* ในบล็อก `finally`:
|
||||
```powershell
|
||||
Set-Location $rootDir
|
||||
if (Test-Path $tempBuildDir) {
|
||||
Remove-Item -LiteralPath $tempBuildDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
```
|
||||
* การันตีว่าโฟลเดอร์ Temp จะถูกลบออก 100% เสมอ ไม่ว่าการบิลด์จะสำเร็จหรือเกิดข้อผิดพลาด
|
||||
* **Go Backend:**
|
||||
* ใช้คำสั่ง `defer os.RemoveAll(tempDir)` ทันทีหลังสร้าง `os.MkdirTemp` สำเร็จ
|
||||
|
||||
---
|
||||
|
||||
## 3. หลักฐานการตรวจสอบจริง (Empirical Verification Log)
|
||||
|
||||
ผลการทดสอบสคริปต์จริงในสภาพแวดล้อม Windows 64-bit (Task ID: `task-607`):
|
||||
* โฟลเดอร์ชั่วคราว: `C:\Users\Phitchayut\Desktop\G Launcher\temp\build_workspace`
|
||||
* เวลาในการดาวน์โหลดและแตกแพ็กเกจ Frontend: 21 วินาที
|
||||
* เวลาในการคอมไพล์ Vite Frontend: 751 มิลลิวินาที
|
||||
* ขนาดไฟล์ Executable ผลลัพธ์: **28,677,632 ไบต์ (27.35 MB)**
|
||||
* ผลการตรวจสอบการล้างขยะ: คำสั่ง `Test-Path .\temp\build_workspace` คืนค่า **`False`** (โฟลเดอร์ชั่วคราวถูกลบทิ้งหมดจด ไร้ขยะตกค้าง)
|
||||
@@ -0,0 +1,29 @@
|
||||
# 🔍 ผลการตรวจสอบการผสานต้นน้ำ (Upstream Merge & Provenance Audit)
|
||||
|
||||
เอกสารนี้บันทึกที่มา (Provenance) ของโค้ดทุกส่วนใน G-Launcher โดยแจกแจงอย่างชัดเจนว่าฟีเจอร์ใดนำมาจาก `Firefly-Shelter/Firefly_Launcher` หรือ `horoyoi-san/game-Launcher`
|
||||
|
||||
---
|
||||
|
||||
## 1. ตารางแจกแจงที่มาของไฟล์และฟังก์ชัน (File Attribution Matrix)
|
||||
|
||||
| ไฟล์ / แพ็กเกจใน G-Launcher | โครงการต้นแบบ | เหตุผลทางวิศวกรรมและสิ่งที่ปรับปรุง |
|
||||
| :--- | :--- | :--- |
|
||||
| `frontend/src/` (UI Pages & Components) | **Firefly Launcher** | ดีไซน์ทันสมัย เรียบหรู รองรับ DaisyUI 5 และ TailwindCSS v4 |
|
||||
| `internal/git-service/git_runtime.go` | **Horoyoi-san** | นำระบบดาวน์โหลด Portable MinGit x64 อัตโนมัติมาใช้ เพื่อรองรับ Zero-Dependency |
|
||||
| `internal/fs-service/game-selection.go` | **Horoyoi-san** | นำระบบ Atomic Write ด้วย Windows API `MoveFileEx` มาใช้เพื่อป้องกันไฟล์คอนฟิกเสียหาย |
|
||||
| `internal/diff-service/ziff.go` | **Horoyoi-san** | นำ Wrapper สำหรับเครื่องมือ `zift.exe` มาใช้รองรับไฟล์แพตช์นามสกุล `.ziff` |
|
||||
| `internal/language-service/thai-patch.go`| **Horoyoi-san** | นำเอ็นจินแก้ไขไฟล์ไบนารี `ExcelData` พร้อมระบบสำรอง `.backup` มาใช้สำหรับม็อดภาษาไทย |
|
||||
| `scripts/launcher-release.mjs` | **Horoyoi-san** | นำสคริปต์คำนวณเวอร์ชัน SemVer และสร้าง `latest.json` มาใช้ใน CI/CD Release Pipeline |
|
||||
| `frontend/public/locales/th.json` | **G-Launcher (GaCy)** | เขียนคำแปลภาษาไทยฉบับสมบูรณ์สำหรับทุกหน้าจอ ปุ่ม และเมนูของ Launcher |
|
||||
| `scripts/bootstrap.ps1` | **G-Launcher (GaCy)** | พัฒนาระบบ Auto-Updater & Local Build ที่ทำงานแบบ **Temp Isolation + Rollback + Purge Temp** |
|
||||
| `update-and-build.bat` | **G-Launcher (GaCy)** | พัฒนาสคริปต์คลิกเดียวสำหรับผู้ใช้ทั่วไปเพื่ออัปเดตและคอมไพล์โดยไม่ต้องตั้งค่าใดๆ |
|
||||
| `internal/git-service/launcher.go` | **G-Launcher (GaCy)** | ผสานระบบตรวจสอบผ่าน Manifest SHA-256 และระบบคอมไพล์จากซอร์สโค้ดใน Temp เข้าด้วยกัน |
|
||||
|
||||
---
|
||||
|
||||
## 2. การจัดการ Naming และ Module Rebranding
|
||||
|
||||
เพื่อปฏิบัติตามคำแนะนำของ Horoyoi-san (*"ส่วนชื่อที่เป็น sunbringer หรือชื่อผมค่อยไปเปลี่ยนทีหลังนะ"*):
|
||||
1. **Module Name:** เปลี่ยนชื่อ Go Module หลักเป็น `g-launcher` ใน `go.mod`
|
||||
2. **User-Facing Branding:** เปลี่ยนชื่อหน้าต่าง, Title, ข้อความใน UI, และ Metadata ของ Windows Application Manifest เป็น **G-Launcher**
|
||||
3. **Internal Identifiers:** อนุรักษ์ชื่อโครงสร้างข้อมูลและโปรโตคอลภายในที่จำเป็นต่อการเชื่อมต่อกับระบบเดิมไว้ เพื่อไม่ให้กระทบต่อ Wails Bindings และ Protobuf Serialization
|
||||
@@ -0,0 +1,81 @@
|
||||
# 🔌 สัญญาทางเทคนิค: Wails v3 IPC & Type-Safe Bindings Architecture
|
||||
|
||||
เอกสารนี้อธิบายกลไกการสื่อสารข้ามเลเยอร์ (IPC Bridge) ระหว่าง **Go Core Services** และ **React 19 Frontend** ในสถาปัตยกรรม Wails v3 Alpha ของ G-Launcher
|
||||
|
||||
---
|
||||
|
||||
## 1. ลำดับการลงทะเบียนและส่งผ่านข้อมูล (IPC Gateway Flow)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant GoService as Go Service (internal/*-service)
|
||||
participant MainGo as main.go (RegisterService)
|
||||
participant WailsCLI as wails3 generate bindings
|
||||
participant TSBindings as frontend/bindings/@bindings/...
|
||||
participant ReactUI as React Component (frontend/src/...)
|
||||
|
||||
GoService->>MainGo: ประกาศ Method พร้อม Input/Output Type ชัดเจน
|
||||
MainGo->>MainGo: app.RegisterService(application.NewService(serviceInstance))
|
||||
MainGo-->>WailsCLI: Wails CLI ทำการสแกน Abstract Syntax Tree (AST) ของ Go
|
||||
WailsCLI->>TSBindings: สร้างไฟล์ TypeScript Definition (.d.ts) และ JS Wrapper
|
||||
TSBindings->>ReactUI: นำเข้า (Import) มาใช้ใน React ด้วย Type Safety 100%
|
||||
ReactUI->>GoService: เรียกใช้แบบ Async Promise ผ่าน Native Webview IPC Bridge
|
||||
GoService-->>ReactUI: คืนค่า Array Result [value1, value2, ...] ตามธรรมเนียม Wails v3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. ทำไมต้องยึดกฎ "System-First Architecture" อย่างเคร่งครัด?
|
||||
|
||||
1. **Static AST Analysis:** Wails v3 สร้าง Bindings โดยการวิเคราะห์โค้ด Go แบบ Static AST หากแก้ไข UI ให้เรียกฟังก์ชันหรือส่งพารามิเตอร์ที่ Go Backend ยังไม่มี โค้ดฝั่ง Frontend จะเกิด Type Error ทันทีตอนรัน `tsc`
|
||||
2. **Runtime IPC Exception:** หากหลุดจากการตรวจสอบของ TypeScript (เช่น ใช้ `any` หรือเรียกแบบไดนามิก) เมื่อ Webview ส่ง IPC Message ผ่าน MessageHandler ของ Windows WebView2 ไปยัง Go Backend ที่ไม่มีตัวรับ จะทำให้เกิด `Unhandled IPC Error` ส่งผลให้หน้าต่างโปรแกรมค้าง จอดำ หรือเปิดมาเป็นหน้าจอสีขาวสนิท (White Screen of Death)
|
||||
3. **แนวปฏิบัติที่ถูกต้อง:**
|
||||
* ขั้นที่ 1: เพิ่ม Struct หรือ Method ใน Go Backend ก่อน
|
||||
* ขั้นที่ 2: รัน `go vet ./...` ให้มั่นใจว่า Backend ไม่มีข้อผิดพลาด
|
||||
* ขั้นที่ 3: สั่งรัน `wails3 generate bindings` เพื่อซิงก์ TypeScript Bindings ลง `frontend/bindings/`
|
||||
* ขั้นที่ 4: ตรวจสอบ Interface ใน `frontend/bindings/`
|
||||
* ขั้นที่ 5: แก้ไข UI และ State Store ใน Frontend ให้สอดคล้องกัน
|
||||
|
||||
---
|
||||
|
||||
## 3. รายการบริการและผัง Bindings ทั้ง 5 โมดูล
|
||||
|
||||
### 1. `AppService` (`@bindings/g-launcher/internal/app-service`)
|
||||
* `CloseAppAfterTimeout(seconds: number): Promise<void>`
|
||||
* `GetCurrentLauncherVersion(): Promise<[boolean, string]>`
|
||||
* `Minimize(): Promise<void>`
|
||||
* `ToggleMaximize(): Promise<void>`
|
||||
* `Close(): Promise<void>`
|
||||
|
||||
### 2. `FSService` (`@bindings/g-launcher/internal/fs-service`)
|
||||
* `FileExists(path: string): Promise<boolean>`
|
||||
* `OpenFileDialog(title: string, filter: string): Promise<string>`
|
||||
* `SaveGameSelection(path: string): Promise<boolean>`
|
||||
* `GetSavedGameSelection(): Promise<[boolean, string]>`
|
||||
* `StartGameProcess(gamePath: string): Promise<[boolean, string]>`
|
||||
|
||||
### 3. `GitService` (`@bindings/g-launcher/internal/git-service`)
|
||||
* `GetLatestLauncherVersion(): Promise<[boolean, string, string]>`
|
||||
* `UpdateLauncherProgress(version: string): Promise<[boolean, string]>`
|
||||
* `BuildAndUpdateFromSource(branch: string): Promise<[boolean, string]>`
|
||||
* `GetLatestProxyVersion(): Promise<[boolean, string, string]>`
|
||||
* `DownloadProxy(version: string): Promise<[boolean, string]>`
|
||||
* `GetLatestServerVersion(): Promise<[boolean, string, string]>`
|
||||
* `DownloadServer(version: string): Promise<[boolean, string]>`
|
||||
|
||||
### 4. `DiffService` (`@bindings/g-launcher/internal/diff-service`)
|
||||
* `ApplyHDiffPatch(targetDir: string, diffFilePath: string): Promise<[boolean, string]>`
|
||||
* `ApplyZiffPatch(targetDir: string, ziffFilePath: string): Promise<[boolean, string]>`
|
||||
* `VerifyChunkChecksum(filePath: string, expectedHash: string): Promise<boolean>`
|
||||
|
||||
### 5. `LanguageService` (`@bindings/g-launcher/internal/language-service`)
|
||||
* `InstallThaiPatch(gameDir: string): Promise<[boolean, string]>`
|
||||
* `UninstallThaiPatch(gameDir: string): Promise<[boolean, string]>`
|
||||
* `CheckThaiPatchStatus(gameDir: string): Promise<[boolean, boolean]>`
|
||||
|
||||
---
|
||||
|
||||
## 4. ผลการตรวจสอบความสมบูรณ์ (Verification Status)
|
||||
* คำสั่ง `wails3 generate bindings` สแกนพบ: **470 Packages, 5 Services, 41 Methods, 0 Errors**
|
||||
* โค้ดฝั่ง React คอมไพล์ผ่าน TypeScript Check (`tsc`) และ Vite Build ได้อย่างสมบูรณ์แบบ
|
||||
Reference in new issue
Block a user