3.6 KiB
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:\ในโค้ด