Files
G-Launcher/Doc/game-selection-persistence.md
T

3.6 KiB

🛡️ สัญญาทางเทคนิค: การบันทึกพาธเกมแบบทนทานต่อ Crash (Game Selection Persistence)

เอกสารนี้ระบุสถาปัตยกรรมการบันทึกและอ่านพาธที่ตั้งของไฟล์ตัวเกม (StarRail.exe) ใน 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:\ ในโค้ด