22 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 | ใช้สำหรับ |
|---|---|---|
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 |
| POST | /api/exrank/toggle |
สลับการปลดล็อก EX rank |
| POST | /api/avatar/rank |
เปลี่ยน rank ตัวละคร |
| POST | /api/avatar/max_all |
ปรับข้อมูลตัวละครตามการทำงานของ handler |
| POST | /api/teleport |
อัปเดตข้อมูลจุดหมาย teleport |
รูปแบบ 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 รอบใหม่ |
| วาร์ปแมพใหม่ | ปรับลำดับ response/notify และข้อมูล scene ตาม upstream; ยังต้องยืนยันปลายทางในเกม |
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 ผู้ใช้ยืนยันหน้าตัวละครหายค้างหลังเปิดเกมใหม่
โครงสร้างซอร์ส
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 ที่ใช้งานจริง