40 KiB
GaC hkrpg GO
เซิร์ฟเวอร์จำลอง Honkai: Star Rail ภาษา Go พอร์ตจาก GaC-hkrpg-ps และอ้างอิงการทำงานจาก PearlSR ประกอบด้วย game server, SDK/dispatch server และ REST API สำหรับ GaC-Srtool
โปรเจกต์อยู่ระหว่างพัฒนา โดยกำลังตรวจการใช้งานกับ Client 4.6.53 OS ตารางคำสั่งและ handler ที่แก้ล่าสุดอ้างอิง PearlSR commit 005d2c12db4781071f4b5b68e8f364587886a710 รายละเอียดอยู่ใน บันทึกอัปเดต protocol การตรงกันของ schema ไม่ได้ยืนยันว่าเกมทุกระบบทำงานครบ
เริ่มใช้งานบน Windows
- ติดตั้ง Go 1.27.0 ขึ้นไป ตาม
go.modและตรวจด้วยgo version - เตรียม Client, launcher/proxy และการ redirect dispatch ให้เชื่อมต่อเซิร์ฟเวอร์ที่กำหนดใน
server.json - เก็บไฟล์ข้อมูลและโฟลเดอร์
resourcesไว้ใน root ของโปรเจกต์ และตั้งค่า launcher ตามหัวข้อ config ด้านล่าง - เปิด
run.batแล้วเลือกเมนูที่ต้องการ
| เมนู | การทำงาน |
|---|---|
1 หรือ Enter |
Build ทั้งสองเซิร์ฟเวอร์ แล้วเปิดเซิร์ฟเวอร์และเกม |
2 |
เปิดทั้งสองเซิร์ฟเวอร์จาก .exe ที่มีอยู่ |
3 |
เปิดเฉพาะ SDK server |
4 |
เปิดเฉพาะ game server |
5 |
เปิดทั้งสองเซิร์ฟเวอร์จาก .exe ที่มีอยู่ และเรียก Gay Proxy |
6 |
Build ทั้งสอง .exe อย่างเดียว |
7 |
ออก |
8 หรือ stop |
หยุดเซิร์ฟเวอร์ของโปรเจกต์นี้ |
เมนู 1 และ 6 หยุดเมื่อ build ไม่ผ่าน ส่วนเมนู 2–5 ใช้ binary ที่มีอยู่ หลังแก้ซอร์สจึงต้อง build ใหม่ก่อนใช้เมนูเหล่านั้น
run.bat เรียก run.ps1 ผ่าน PowerShell โดยอ่าน path เกม/Proxy จาก config ไม่มีการเดา Desktop, ไดรฟ์ หรือชื่อโฟลเดอร์ตามเวอร์ชัน ต้องตั้ง launcher.client_path เป็นไฟล์ launcher/เกมที่จะเปิด และ launcher.proxy_path เป็นไฟล์ Proxy ที่ต้องการ ถ้าเว้นว่างจะเปิดเซิร์ฟเวอร์และแสดงวิธีตั้งค่า
SDK และ game server เปิดหน้าต่างคอนโซลแยกกันให้เห็น log โดยตรง หลังทำเมนูที่เลือกเสร็จ หน้าต่าง run.bat จะปิดเองใน 5 วินาที ส่วนหน้าต่างเซิร์ฟเวอร์ยังเปิดอยู่ ใช้ run.bat stop เพื่อหยุด หรือปิดหน้าต่างเซิร์ฟเวอร์ที่ต้องการ สคริปต์หยุดเฉพาะ process ที่ path executable ตรงกับ root นี้ ก่อนเริ่มใหม่หรือแทนที่ binary ที่ build สำเร็จ การเรียกด้วย argument เช่น run.bat build จะคืนค่าทันทีเมื่อทำงานเสร็จโดยไม่รอ 5 วินาที
Config และกฎห้าม hardcode
AGENTS.md กำหนดให้ค่าที่เปลี่ยนตามเครื่อง/deployment/เวอร์ชันต้องมาจาก config, environment หรือ resource ห้ามฝัง path, IP, port หรือ fallback เฉพาะเครื่องใน source และ startup scripts
ลำดับความสำคัญ: environment > local config > config หลัก
server.json: ค่าเครือข่ายและเวอร์ชันที่แชร์กันระหว่าง launcher, game server และ SDK serverserver.local.json: override เฉพาะเครื่อง ไฟล์นี้ถูก ignore โดย Git คัดลอกserver.local.example.jsonแล้วใส่ path ของเครื่องได้GAC_CONFIG: เลือกไฟล์หลักอื่น โดย local override ใช้ชื่อเดียวกันลงท้าย.local.json- path แบบ relative ใน launcher อ้างอิง root ของโปรเจกต์
| ค่าใน config | Environment override | ใช้สำหรับ |
|---|---|---|
player_uid |
GAC_PLAYER_UID |
UID ผู้เล่น ใช้ร่วมกันทั้ง SDK และ game server; ต้องเป็นจำนวนเต็ม 1–4294967295 |
client_version |
GAC_CLIENT_VERSION |
เวอร์ชันที่แสดงใน log/API |
game_host, game_port |
GAC_GAME_HOST, GAC_GAME_PORT |
ที่อยู่ bind ของ game server |
sdk_host, sdk_port |
GAC_SDK_HOST, GAC_SDK_PORT |
ที่อยู่ bind ของ SDK server |
public_game_host |
GAC_PUBLIC_GAME_HOST |
ที่อยู่ game server ที่ gateway แจ้ง Client |
public_sdk_url |
GAC_PUBLIC_SDK_URL |
Base URL ที่ dispatch แจ้ง Client |
launcher.client_path |
GAC_CLIENT_PATH |
ไฟล์ launcher/เกมที่จะเปิด |
launcher.proxy_path |
GAC_PROXY_PATH |
ไฟล์ Proxy ที่จะเปิด |
launcher.go_command |
GAC_GO_COMMAND |
คำสั่ง Go จาก PATH หรือ path ที่กำหนด |
เมื่อเปลี่ยนเครือข่ายให้ตั้งทั้ง bind และค่าที่ประกาศให้ Client เข้าถึงได้ โดยเฉพาะ port ใน public_sdk_url เมื่อ SDK รับการเชื่อมต่อโดยตรง ค่าเหล่านี้มีค่าเริ่มต้นอยู่ในไฟล์ config และไม่มี fallback เครือข่ายในโค้ด ต้องรีสตาร์ตเซิร์ฟเวอร์หลังเปลี่ยน config การเปลี่ยน client_version ไม่ได้แปลง protocol หรือทรัพยากรของเกมให้อัตโนมัติ
ตรวจ config โดยไม่เปิดเกมหรือเซิร์ฟเวอร์:
.\run.bat check
ทำไมมี executable สองตัว
| ไฟล์ | หน้าที่ | พอร์ต |
|---|---|---|
gameserver-go.exe |
รับการเชื่อมต่อเกมผ่าน KCP และจัดการผู้เล่น ฉาก และ battle | UDP ตาม game_port |
sdkserver-go.exe |
Dispatch, login, ข้อมูล hotfix และ REST API | HTTP ตาม sdk_port |
การเปิดระบบครบต้องรันทั้งสองตัว .exe ที่ build เสร็จจะอยู่ใน root ของโปรเจกต์ ให้เปิดจาก root เพื่อให้เซิร์ฟเวอร์หาไฟล์ข้อมูลและบันทึก log ได้ถูกตำแหน่ง
Build และรันเอง
รันคำสั่งจาก root ของโปรเจกต์:
go build -o gameserver-go.exe ./cmd/gameserver
go build -o sdkserver-go.exe ./cmd/sdkserver
เปิดคนละ terminal:
.\sdkserver-go.exe
.\gameserver-go.exe
ซอร์สมีไฟล์ protobuf ที่ generate แล้ว การ build ปกติไม่ต้องใช้ protoc หากแก้ schema จึงต้องติดตั้ง protoc และ protoc-gen-go เพื่อ generate ใหม่
สำหรับนักพัฒนาที่ต้องการรันชุดทดสอบ:
go test ./...
ผลทดสอบฝั่ง Go และการ build สำเร็จไม่ได้ยืนยันว่า Client โหลดฉากหรือเข้า battle สำเร็จ ต้องตรวจในเกมและอ่าน Player.log ประกอบด้วย
ไฟล์ข้อมูล
| ไฟล์หรือโฟลเดอร์ | ใช้สำหรับ |
|---|---|
freesr-data.json |
ตัวละคร, lightcone, relic และ battle_config |
persistent |
ทีม, ตำแหน่ง, ฉาก และค่าผู้เล่นที่บันทึกไว้ |
res.json |
ข้อมูลฉากหลักในรูปแบบที่ Go loader ใช้ |
resources/ |
ข้อมูลฉากและตารางประกอบ เช่น MapEntrance, MazePlane, Anchor และ StageConfig |
teleports.json |
ตำแหน่ง teleport แยกตาม floor |
challenge_data.json |
ข้อมูล challenge |
mission_unlocks.json |
ข้อมูลภารกิจและการปลดล็อก |
hotfix.json, versions.json |
ข้อมูลเวอร์ชันและทรัพยากร Client สำหรับ SDK server |
scripts/ |
Lua ที่ส่งให้ Client ผ่าน heartbeat |
สำรอง freesr-data.json และ persistent ก่อนเปลี่ยนชุดข้อมูล res.json ใน root กับ resources/res.json มีโครงสร้างต่างกันและ loader ใช้ร่วมกัน จึงควรเก็บไว้ตามตำแหน่งเดิม
Calyx ใช้ battle_config ใน freesr-data.json เป็นข้อมูลจำลองการต่อสู้ จึงอาจได้ StageID และมอนสเตอร์ต่างจากดอกไม้ที่กดในเกม
REST API / GaC-Srtool
เมื่อ SDK server ทำงาน เปิด URL ที่ตั้งใน public_sdk_url เพื่อดูรายการ endpoint หน้า root และ /dashboard ตอบข้อมูล JSON ของ API gateway
| Method | Endpoint | หน้าที่ |
|---|---|---|
| GET | /api/status |
อ่านสถานะและข้อมูลผู้เล่น |
| GET, POST | /api/freesr |
อ่านหรืออัปเดต FreeSR data |
| GET, POST | /api/freesr/avatars |
อ่านหรืออัปเดตข้อมูลตัวละคร |
| GET, POST | /api/persistent |
อ่านหรืออัปเดตข้อมูล persistent |
| GET, POST | /api/battle_report |
อ่านสถิติดาเมจ/การต่อสู้ล่าสุด หรือบันทึกรายงานการต่อสู้ |
| POST | /api/battle_report/reset |
ล้างสถิติรายงานการต่อสู้ |
| POST | /api/exrank/toggle |
สลับการปลดล็อก EX rank |
| POST | /api/avatar/rank |
เปลี่ยน rank ตัวละคร |
| POST | /api/avatar/max_all |
ปรับข้อมูลตัวละครตามการทำงานของ handler |
| POST | /api/teleport |
อัปเดตข้อมูลจุดหมาย teleport |
| POST | /api/command |
ส่งคำสั่ง GM ไปยังเซิร์ฟเวอร์ |
| GET | /api/data-in-game |
อ่านข้อมูลเกมที่แคชไว้ในเซิร์ฟเวอร์ |
รูปแบบ request และเงื่อนไขการอัปเดตอยู่ใน internal/sdkserver/api.go การอัปเดตข้อมูลผ่าน API ยังต้องตรวจผลการโหลดข้อมูลของ Client ด้วย
สถานะและปัญหาที่กำลังตรวจ
มี handler สำหรับ login, ทีม, ตัวละคร, ไอเทม, ฉาก, teleport, ภารกิจ, Calyx และ challenge แต่ความครบของ handler ไม่ได้หมายถึงรองรับทุกกรณีใน Client
| รายการ | สถานะ |
|---|---|
| Error 2000 ตอน login | แก้ GetCurBattleInfo ให้ตอบสำเร็จพร้อมข้อมูลว่างเมื่อไม่มี battle; รอยืนยันในเกม |
| Calyx | ผู้ใช้ยืนยันว่าเข้า Battle ได้แล้ว 17 ต.ค. หลังแก้เส้นทาง BattleInfo |
| ตีมอนแล้วค้างหน้า Weakness | ผู้ใช้ยืนยัน Stagnant Shadow ที่เรียกมอนออกมาให้ตีเข้าสู้ได้แล้ว 17 ต.ค.; log มี PVEBattleResult ส่วนมอนทั่วไปยังไม่ได้ยืนยันแยก |
| เปิดหน้าตัวละครแล้วค้าง | ผู้ใช้ยืนยันว่าหายหลังเปิดเกมใหม่; ไม่พบ PlayerBoard/Inventory error ใน log รอบใหม่ |
| วาร์ปแมพใหม่ | ผู้ใช้ยืนยัน Starfroster/Ferry Relay Station และ Moment of Joy วาร์ปได้แล้ว 17 ต.ค.; กรองกลุ่มที่ Client ระบุ IsDelete=true ด้วย SceneMetadata จากตาราง Client |
| Endgame | ตรวจข้อมูลทุกด่านที่ติดตั้ง 1,747 รายการห้อง/node บน 34 floors; เพิ่มจุดเกิดจริง, PF 4 cycles และ flow เปลี่ยนทีม/ห้อง/สรุปผลสำหรับด่านหลัก, Tierce และ Peak แล้ว รอผลใน Client ดู ผล audit และข้อจำกัด |
SceneCastSkill |
ใช้รายการ monster entity ที่ server สร้างเพื่อตรวจเป้าหมายก่อนส่ง battle |
ข้อมูลล่าสุดที่ตรวจในซอร์สและเอกสาร: 17 ตุลาคม 2026
เก็บข้อมูลเมื่อพบปัญหา
| ไฟล์ | ข้อมูลที่ช่วยวิเคราะห์ |
|---|---|
gameserver.log |
คำขอและแพ็กเก็ตตอบกลับ |
server_debug.log |
รายละเอียด battle, scene และ teleport |
battle_last.json |
Payload battle ล่าสุดที่สร้างสำหรับ Calyx หรือการตีมอน |
battle_last_response.bin, battle_last.bin |
ไบต์ response ที่ส่งจริง และ nested battle_info ที่ตัดจาก response นั้น |
battle_last_capture.json, battle_diagnostics/ |
CmdID, เวลา, SHA-256 และ snapshot ของแต่ละรอบ |
Player.log ของ Client |
Exception และจุดที่ Client โหลดข้อมูลไม่สำเร็จ |
ตำแหน่ง Player.log บน Windows สำหรับ Client ที่ใช้ในงานนี้:
%USERPROFILE%\AppData\LocalLow\Cognosphere\Star Rail\Player.log
เมื่อรายงานปัญหาให้ระบุเวอร์ชัน Client, เวลาที่เกิด, การกระทำก่อนค้าง และรหัส Cocoon/Entry/Teleport ถ้ามี พร้อม log ช่วงเดียวกันทั้ง server และ Client ข้อความ sent packet ยืนยันเพียงว่า server ส่งแพ็กเก็ตแล้ว ส่วนการโหลดสำเร็จต้องดูฝั่ง Client
สำหรับการตรวจ battle ทีละส่วน ดู บันทึกเทียบ upstream ค่า battle_diagnostics.client_battle_type ใน local config เปิด probe ที่อ่าน payload ด้วย protobuf parser ของ Client และเขียน [GAC_BATTLE_WIRE] ลง Player.log ชื่อ class ต้องอ้างอิง stack trace ของ Client รุ่นนั้น ตั้งค่าว่างเพื่อปิด probe
ประวัติรอบ 16 ต.ค. พบ main affix ผิดใน inventory ชุดเดิมและแก้ข้อมูลไปแล้ว ผลนั้นไม่ใช่หลักฐานว่า inventory ที่นำเข้าภายหลังหรือการเข้า Battle ปัจจุบันผ่าน ดูผลแต่ละรอบในบันทึกตรวจสอบ
การแก้ Battle รอบ 17 ตุลาคม 2026
SceneCastSkillอ่านทั้ง hit targets, assist IDs และ assist groups และตอบMonsterBattleType=TRIGGER_BATTLEตาม enum ของต้นฉบับ; ค่าเริ่มต้นศูนย์หมายถึงNONE- โหลดธาตุตัวละครจาก
resources/AvatarConfig.jsonเพิ่มเติม เพราะavatarConfigsในres.jsonอาจว่าง - กฎบัฟเฉพาะตัวละคร, global passive, entry attack และ invasion อยู่ใน
resources/BattleRules.jsonพร้อม upstream revision ต้องนำไฟล์นี้ไปด้วยเมื่อแจก binary; ไม่มีการฝัง ID ของกฎเหล่านี้เป็น fallback ในตัว executable - Battle SP แปลงจากอัตราส่วนในข้อมูลที่นำเข้าเป็นสเกล 10000 และ HP มอนที่เป็นศูนย์คงศูนย์ตามรูปแบบ upstream
- Invasion ใช้สถานะ challenge ที่โหลดจริง
battle_config.enable_invasion_supportเปิดบัฟ support เพิ่มได้ (ค่าเริ่มต้น false) - เลิกสร้าง Material ID ด้วยสูตร
130000 + AvatarIDซึ่ง Client หาไม่พบ และไม่ตอบข้อมูลว่างให้โมดูล RogueTourn/ChenLing ที่ยังไม่รองรับ
สถานะรอบนี้: build ผ่าน วาง binary ที่ root แล้ว ผู้ใช้ยืนยันทั้ง Calyx และ Stagnant Shadow เข้า Battle ได้ โดย log ของเส้นทางตีมอนเวลา 11:53:08 มี BattleInfo และเวลา 11:53:16 มี PVEBattleResult ผลนี้ยังไม่ใช่การรับรองโหมดต่อสู้ทุกประเภท
แก้โปรไฟล์เพิ่มเติม: field 4 ของ GetPlayerBoardDataScRsp คือการ์ดส่วนตัว, field 8 คือรูปโปรไฟล์ และ field 9 คือตัวละครช่วยเหลือ โค้ดเดิมใส่ ID ผิดประเภทและไม่มี head frame/display data ปรับให้ใช้ resources/AvatarPlayerIcon.json, resources/ProfileConfig.json และทีมจริง พร้อมเติม ArchiveData ทั้งสอง response ผู้ใช้ยืนยันหน้าตัวละครหายค้างหลังเปิดเกมใหม่
Eidolon และ EX: การแจกไอเท็มและซิงก์
resources/EidolonConfig.json กำหนดรายการแจกของ Jing Yuan, Dan Heng IL และ Acheron:
| ตัวละคร | ก้อน E1–E6 | ก้อน EX |
|---|---|---|
| Jing Yuan | 11204 | 131204 |
| Dan Heng IL | 11213 | 131213 |
| Acheron | 11308 | 131308 |
ก้อนปกติแจกเท่ากับต้นทุน rank ที่ยังไม่ปลด (E0 ได้ 6 ชิ้น) อ้างอิง AvatarRankConfig.UnlockCost และ ItemConfigAvatarRank จาก ชุดข้อมูล revision ที่บันทึกไว้ และเทียบ RankIDList กับ AvatarConfig ในโปรเจกต์ ก้อน EX ใช้สาม ID ที่ผู้ใช้ระบุ แจกหนึ่งชิ้นเมื่อ EX ปิดอยู่ ไม่สร้าง ID ด้วยสูตรจาก AvatarID ผู้ใช้ยืนยันรายการใหม่และการกดปลดใน Client แล้ว
GetBagส่งรายการแจกเมื่อเข้าเกม ก้อนลดตาม rank/EX ที่บันทึกไว้ ไม่รีเซ็ต progression เมื่อเปิดเกมใหม่- RankUpAvatar เซฟ rank ลง freesr-data.json โดยแก้เฉพาะค่า rank และเก็บฟิลด์นำเข้าอื่นไว้ E1–E6 ไม่เปิด EX ให้เอง
- EX ทั้งสามคนเริ่มปิดไว้ตามคำขอ
falseเก็บชัดเจนใน persistent; การเปิดจากในเกมบันทึกและส่ง AvatarSync/MaterialList เฉพาะส่วน - เกมอ่าน EX จาก persistent ทุกประมาณ 1 วินาที แล้วส่งข้อมูลตัวละครที่เปลี่ยน ใช้เส้นทางนี้ร่วมกับ API เดิมโดยไม่แก้ source เว็บ GaC srtool
- ระหว่าง Battle เลื่อนการนำเข้า EX และ freesr-data ไปหลัง PVEBattleResult เพื่อไม่เปลี่ยนอุปกรณ์หรือข้อมูล actor กลางการต่อสู้
- โหลดข้อมูลไม่เซฟกลับอัตโนมัติอีกแล้ว SavePersistent รวมเฉพาะค่าที่เปลี่ยนจาก snapshot ของผู้เขียน รักษาฟิลด์อื่นที่ API แก้ พร้อม lock ข้าม process และเขียนไฟล์แบบ atomic ต้องใช้ SDK/Game server build ใหม่ทั้งคู่
สถานะรอบ progression: build ทั้งสองตัวผ่าน ผู้ใช้ยืนยันว่าก้อนขึ้น ปลด E1/EX ได้ และยังเข้า Calyx ได้ ตรวจไฟล์ระหว่างลองพบ Dan Heng IL rank=1 และ EX=true ต่อมาผู้ใช้เปิด EX ทั้งสามคนแล้ว จึงเก็บค่า true ตามการกดปลดจริง ผลนี้ไม่ได้รับรองว่าเว็บ GaC srtool ที่แก้แยกอยู่ได้ทดสอบ integration แล้ว
รอบโหลดกระเป๋า 12:18 ส่ง GetBagScRsp ขนาด 56663 ไบต์แล้ว ไม่พบ TryCreateItemData/Inventory error ใน log ณ เวลาตรวจ และอ่าน API status แล้ว hash ของ persistent ไม่เปลี่ยน EX ยัง false ทั้งสามคน หลังจากนั้นรับ RankUpAvatar เวลา 12:18:23 และคำขอ EX เวลา 12:18:28 สำเร็จ พร้อม PlayerSyncScNotify ขนาด 234/237 ไบต์ แสดงว่าใช้การอัปเดตเฉพาะส่วนและไม่ได้ล้าง inventory ทั้งชุด
โครงสร้างซอร์ส
cmd/gameserver/ จุดเริ่ม game server
cmd/sdkserver/ จุดเริ่ม SDK/dispatch server
internal/common/ โมเดลข้อมูล, resource loader และ protobuf converters
internal/gameserver/ Gateway, session, dispatch และ game handlers
internal/sdkserver/ HTTP dispatch, login และ REST API
protocol/proto/ Schema, generated protobuf และตาราง CmdID
pkg/kcp/ KCP transport
resources/ ข้อมูลประกอบ
scripts/ Client Lua
อัปเดต protocol และ handler
ใช้ checkout ของ PearlSR ที่ตรวจ revision แล้วเป็นแหล่งข้อมูล ไม่แก้ generated Go ด้วยมือ:
python tools/sync_protocol_commands.py "<path-to-pearl-sr-checkout>"
protoc --go_out=. --go_opt=paths=source_relative protocol/proto/StarRail.proto protocol/proto/current_handlers.proto
python tools/audit_protocol_handlers.py "<path-to-pearl-sr-checkout>"
คำสั่ง sync อัปเดตตารางชื่อ/CmdID ส่วนการแก้ field ต้องตรวจจาก schema ต้นฉบับแล้วแก้ .proto ก่อน generate ใหม่ ตัว audit ตรวจ CmdID, คู่ request/response และชุดหมายเลข field ของ message ที่มีชื่อร่วมกัน ไม่ตรวจชนิด field, default values, asset หรือผลใน Client
ClientDownloadDataLuaVersion = 51 เป็นค่า version ของ payload ที่ upstream ปัจจุบันยังใช้ส่ง Lua จึงไม่เปลี่ยนเป็น 53 ตาม client_version โดยไม่มีหลักฐานรองรับ ส่วน Tutorial อ่าน ID จาก resources/TutorialData.json และ resources/TutorialGuideGroup.json หลังเปลี่ยน resource ให้รีสตาร์ต server
ที่มา
พอร์ตจาก GaC-hkrpg-ps ภาษา Rust โดยใช้แนวทางและข้อมูลประกอบจาก HonkaiSlopRail/pearl-sr ภาษา Zig การแก้ใน Go ต้องตรวจเทียบทั้ง handler, payload และเวอร์ชัน Client ที่ใช้งานจริง
Traces: หน้าตัวละครและ GaC-Srtool
AvatarPathData.avatar_path_skill_tree.point_idสำหรับหน้า Traces ใช้เลขAnchorTypeจากAvatarSkillTreeConfig.jsonส่วนBattleAvatar.skilltree_list.point_idใช้PointIDเต็ม อ้างอิง PearlSR commit005d2c12db4781071f4b5b68e8f364587886a710ในavatar_mgr.createSkillTreeและbattle_mgr.createBattleAvatar- แปลง
data.skillsในเซฟเป็นเลข Anchor เฉพาะตอนส่งข้อมูลหน้าตัวละคร ไม่เปลี่ยน ID ในเซฟหรือ Battle และไม่บังคับอัป Traces ให้เต็ม - GaC-Srtool บันทึก Traces ผ่านการส่ง
freesr-dataทั้งชุด ไม่ใช่/api/freesr/avatarsซึ่งรับเฉพาะข้อมูลทั่วไปของตัวละคร โค้ดเว็บที่แก้ในโปรเจกต์ GaC-srtool เพิ่มพารามิเตอร์closeModal = trueให้saveAvatarDetailsเพื่อแก้ ReferenceError ก่อนถึงขั้นส่งเซฟ ต้องใช้เว็บฉบับที่มีการแก้นี้ด้วย - การแก้เซฟจากเว็บถูกนำเข้าเกมโดย watcher; ระหว่าง Battle จะรอจนจบก่อนส่ง sync การยืนยันผลหน้า Traces และการบันทึกจากเว็บยังต้องตรวจใน Client
Technique points และอาหาร
resources/TechniqueRules.jsonเก็บค่า MP, cap ของทีม, ค่าใช้ Technique ตามตารางMazeSkillของ Client และอาหารที่ฟื้น MP โดยไม่มีผลลด HP มี revision ต้นทางและ hash ของ GameAssembly ที่อ่านข้อมูล- Phainon / Himeko Nova ใช้ cap 7 ตาม
lineup_mgr.buildLineupของ PearlSR revision ที่ระบุใน resource ตัวโหลดตรวจสมาชิกจาก ค่า AvatarID ในช่องทีม ไม่ใช่ key ของช่อง ไม่มีการบวก cap ทั้งสองตัวทับกันตาม upstream - แจกอาหารใน resource ชนิดละ
initial_food_countหนึ่งครั้งเมื่อเปิดกระเป๋า บันทึกจำนวนคงเหลือในpersistent.technique_food_stockกินด้วยUseItemหรือกินอัตโนมัติเมื่อแต้มไม่พอใช้ Technique; ห้ามกินระหว่าง Battle persistent.auto_technique_foodเปิดโหมด auto; ค่าเริ่มต้นมาจากauto_food_defaultใน resource ปิด/เปิดได้ผ่านPOST /api/techniqueด้วย{"auto_food":false}/{"auto_food":true}และอ่านสถานะด้วยGET /api/techniqueใช้ SDK URL จาก config ตัวเฝ้าดูนำสวิตช์ใหม่เข้า session หลัง Battle โดยไม่ล้าง inventory- MP ที่ใช้แล้วเก็บใน session; เริ่มห้อง Challenge ใหม่คืนค่าเริ่มต้นตาม resource การเปลี่ยนตัวละคร/วาร์ปไม่เติม MP เต็มโดยอัตโนมัติ
- Technique ที่ไม่เปิด Battle อ้างอิง
IgnoreBattleและgetBattleTypeของ PearlSR ตอบผลNO_BATTLEให้มอนที่โดน ไม่บังคับเข้า Battle จากการแปะ debuff
สถานะ: ผู้ใช้ยืนยัน PF ปกติเข้าสู้และเปลี่ยนห้องได้ ก่อนรอบแก้ Technique/อาหาร ส่วนรอบนี้ยังต้องยืนยัน Traces, แต้ม, อาหาร/auto และ Starward ห้อง 3 จาก Client ห้ามถือว่า build ผ่านเป็นผลยืนยันการเล่น
Starward: ทีมและคะแนนที่เซฟไว้
- ผู้ใช้ยืนยันว่า PF Starward เล่นจบครบ 3 ห้องได้แล้ว
- เก็บทีมและบัฟรายห้องใน
persistent.tierce_progressตอนตั้งทีม/เริ่มเล่น อ่านกลับใน GetChallengeTierceData และเริ่มห้องที่เลือกด้วยทีมของห้องนั้น ไม่ใช้ทีมแรกแทนเมื่อเล่นแยกห้อง - บันทึกคะแนนจริงจาก PVEBattleResult แยกแต่ละ node พร้อมผลที่ดีที่สุด การลองห้องเดียวใช้ผลที่เซฟของห้องอื่นประกอบ; การเล่นครบชุดเริ่มคะแนนของรอบใหม่จากศูนย์
resources/ChallengeTargetConfig.jsonเป็นข้อมูลเกณฑ์จาก Client: TOTAL_SCORE ใช้ตัดสินดาวสำหรับ PF/AS Starward พร้อมส่ง FinishedTargetList ทั้งหน้าสรุปและข้อมูลที่อ่านกลับ คะแนน 97,000 ได้เกณฑ์ PF 60,000 / 75,000 / 90,000 แต่ยังไม่ถึงเกณฑ์พิเศษ 99,000- รอบนี้ยังไม่เพิ่มการแจก reward, การจัดอันดับออนไลน์ หรือการประเมิน target ประเภท ROUNDS_LEFT/DEAD_AVATAR ของ MoC ส่วนข้อมูลประวัติ Endgame ปกติ/Peak เดิมยังมีรายการสำเร็จรูปตามข้อจำกัดในเอกสาร audit
- ต้องตรวจใน Client ว่ากลับมาแล้วทีมยังอยู่ เลือกเล่นห้องเดียวได้ และหน้าสรุปดาวตรงกับคะแนน Build ไม่ใช่การยืนยันผลเล่น
วาร์ป MoC จากสมุดผ่านฉากรถไฟ
แก้ GetPamSkinData ที่เคยส่งสกินปอมปอม ID0 ซึ่งไม่มีในตาราง Client และทำให้ NPC โหลดล้ม อ่าน default/รายการที่ปลดจาก ProfileConfig และตรวจ ConfigEntityPath กับ PamSkinConfig.json แทน ค่าต้นทางมี revision/assembly hash ตรวจสอบได้ ยังรอผู้ใช้ยืนยันการวาร์ปรอบแก้สกินนี้
Preset ทีมในเกม
- เปิดไว้ 20 ช่องผ่าน
resources/TeamPresetConfig.json(preset_countเป็นนโยบายจำนวนทีมที่ผู้ใช้ขอเพิ่ม; ขอบเขตสมาชิก 4 และชื่อ 14 ตัวอักษรอ้างอิง Client) - GetAllLineupData ส่งรายการครบพร้อม index ปัจจุบัน รองรับสลับทีม ตั้งชื่อ เพิ่ม/ถอด/สลับสมาชิก และ MarkPresetLineup สำหรับทีมโปรด/Quick Lineup
- บันทึกใน
persistent.team_presetsและactive_team_presetเก็บlineupsเดิมเป็นสมาชิกทีมที่กำลังใช้อยู่เพื่อใช้กับ API เดิม ไม่เขียนไฟล์ตอนอ่านเพื่อสร้าง preset เปล่า - เริ่มใช้ด้วยทีมเดิมในช่องแรก ช่องอื่นยังว่างจนจัดสมาชิกครั้งแรก จากนั้นเลือกทีมที่เซฟไว้ได้โดยไม่ต้องจัดใหม่ทุกครั้ง ปฏิเสธการสลับไปทีมว่างและการแก้ทีมระหว่าง Battle
- เมื่อมีการเซฟ preset การสู้ทั่วไป/Calyx ใช้สมาชิกทีมที่เลือก แต่คง stage/waves จากข้อมูลเดิม ห้อง Endgame ใช้ทีมประจำห้องของ ChallengeRun
- Build ผ่านยังไม่ยืนยันว่า UI ของ Client แสดงครบ 20 ช่องและใช้งาน Quick Lineup ได้ทุกหน้า ต้องตรวจเพิ่มในเกม การจัดทีม Endgame โดย request ExtraLineupType ยังคงเป็นคนละเส้นทางกับการแก้ preset ทีมเดินโลก
Freecam
Tab: เปิด/ปิด Freecam; ลูกศร: เลื่อนกล้อง; กดเมาส์ขวาค้างแล้วขยับเมาส์เพื่อหันกล้องPage Up/Page Down: ขึ้น/ลง;+/-: เพิ่ม/ลดความเร็ว ไม่ใช้ E/Q หรือ I/J/K/L คุมกล้อง- ขณะเปิด Freecam ใน Battle ซ่อนการรับคลิก UI ด้วย
InControlInputModule.allowMouseInputและพักเฉพาะ mouse binding ซ้าย/ขวาของคำสั่งเกมในหน่วยความจำ คีย์บอร์ดยังกดสกิลได้ ส่วนกล้องอ่านเมาส์ผ่าน Unity Input โดยตรง - คืนค่าตอนปิด Freecam/ออก Battle หลังปล่อยปุ่มเมาส์ และก่อนปิด Client ไม่มีการลบ/เพิ่ม binding ผ่าน OnBindingsChanged ชื่อ field ตรวจจาก Client โดยตรง ผลป้องกันคลิกใน Battle ยังรอยืนยันการเล่นจริง
- สคริปต์อัปเดตผ่าน heartbeat โดยไม่ต้อง build หรือรีสตาร์ตเซิร์ฟเวอร์
Hide UI
Backslash ซ่อนเฉพาะ HUD ที่ระบุชื่อไว้ใน scripts/hide_ui.lua เช่น HUD เดินโลก/ต่อสู้ ตัวเลขลอยและ waypoint โดยไม่ปิด UIRoot, กล้อง UI หรือ Canvas ทั้งฉาก จึงเหลือหน้าตัวละคร หน้ารายละเอียด EX Eidolon และหน้าต่างรางวัลไว้ ปิดโหมดแล้วคืนค่า CanvasGroup เดิมของ HUD ที่แก้ ถ้าเคยใช้สคริปต์ซ่อนทั้ง UI รุ่นเก่า แนะนำเปิดเกมใหม่หนึ่งครั้ง เพราะรุ่นเก่าไม่ได้เก็บค่า alpha/interactable เดิมทั้งหมดไว้ ผลหน้า EX ยังรอยืนยันจาก Client
Hide UI ซ่อนเมนู รายละเอียด รายชื่อตัวละคร และปุ่มปิด/แถบบนที่ตรวจพบในหน้า Character เพิ่มด้วย โดยเว้น AvatarRankPanel และ Dialog ไว้เพื่อรักษาภาพ Eidolon; ส่วนควบคุมภายในหน้า Rank ยังไม่ได้แยกซ่อนและรอตรวจ Client