Files
GaCy-GO/README.md
T

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

  1. ติดตั้ง Go 1.27.0 ขึ้นไป ตาม go.mod และตรวจด้วย go version
  2. เตรียม Client, launcher/proxy และการ redirect dispatch ให้เชื่อมต่อเซิร์ฟเวอร์ที่กำหนดใน server.json
  3. เก็บไฟล์ข้อมูลและโฟลเดอร์ resources ไว้ใน root ของโปรเจกต์ และตั้งค่า launcher ตามหัวข้อ config ด้านล่าง
  4. เปิด 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 server
  • server.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 ที่ใช้งานจริง