Files
GaCy-GO/README.md
T
2026-10-07 13:56:04 +07:00

7.0 KiB

GaC hkrpg GO — StarRail 4.6.51 Private Server (ภาษา Go)

โอนย้าย (port) จากโปรเจกต์ Rust GaC-hkrpg-ps มาเป็นภาษา Go ทั้งหมด พร้อม แก้บัคกล้องหลุดจากตัวละครตอนกดตี (SceneCastSkill) ตั้งแต่ต้นทาง


บัคกล้องหลุด (SceneCastSkill) — สาเหตุและวิธีแก้

อาการ: กดตีใน overworld แล้วกล้องหลุดออกจากตัวละคร

สาเหตุ (จาก gameserver/src/net/handlers/battle.rs เดิม): handler ของ SceneCastSkillCsReq ตอบ battle_info + monster_battle_info ให้ client เข้าสู่การต่อสู้กับ target ที่ผ่าน filter แบบหลวม:

filter เดิม: id > 30_000 (monster) || id < 1_000 (avatar entity ของผู้เล่นเอง!)

เมื่อ client ส่ง hit target เป็น prop / NPC / ตัวผู้เล่นเอง server จะสั่งเข้า battle กับ "monster" ที่ไม่มีอยู่จริง → battle transition โหลดไม่สำเร็จ → กล้อง battle ไม่มี target ให้ตาม → กล้องหลุดจากตัวละคร นอกจากนี้ถ้าอยู่ใน arena (entry >= 3000000) โค้ดเดิมยัง "หลอก" target เป็น 30001 เสมอ

วิธีแก้ (ใน internal/gameserver/handlers_battle.go):

  1. ตอนโหลดฉาก server เก็บรายการ monster entity จริง ไว้ใน Session.MonsterEntities (entity_id → event_id)
  2. SceneCastSkill ยอมรับเฉพาะ hit target ที่เป็น monster จริงเท่านั้น
  3. ถ้าไม่มี monster จริงถูกตี → ตอบ retcode 0 + cast_entity_id เฉยๆ ไม่เข้า battle client เล่นแอนิเมชันตีปกติ กล้องค้างกับตัวละคร
  4. ตีโดน monster จริง (รวมบอสใน arena 30001) → เข้า battle ตามปกติ

ยืนยันด้วย test อัตโนมัติ: internal/gameserver/smoke_test.go (จำลอง client เต็มรูปแบบ: handshake → login → กดตี ทั้งกรณี ผ่าน UDP จริง)

สถาปัตยกรรม

cmd/gameserver        เกมเซิร์ฟเวอร์ (UDP :23301, KCP)
cmd/sdkserver         dispatch + login + SRTools (HTTP :21000)
protocol/proto        StarRail.pb.go — generate จาก proto 4.6.51 (4,932 messages)
protocol/proto/cmdid.go — ตาราง CmdID (2,114 ids) generate จาก "// CmdID:" comments
pkg/kcp               KCP สาย mihoyo (header 28 ไบต์: conv+token) — port จาก kcp.rs 1:1
internal/common       FreesrData / persistent / res.json / teleports.json + proto converters
internal/gameserver   gateway, packet framing, session, dispatch, handlers ทั้งหมด
internal/sdkserver    query_dispatch / query_gateway / auth / srtools / versions.json

ไฟล์ข้อมูลใช้ชุดเดิมกับ Rust PS ทุกไฟล์ (freesr-data.json, persistent, res.json, teleports.json, challenge_data.json, mission_unlocks.json, versions.json) — save เดิมใช้ได้ทันที

การใช้งาน

run_go.bat          เมนู 1/2/3/4 เหมือนเดิม
gameserver-go.exe   เกมเซิร์ฟเวอร์
sdkserver-go.exe    SDK/dispatch

ต้องแก้ hosts ของเครื่อง client แบบเดียวกับ Rust PS (หรือใช้ Fiddler/proxy เดิม)

Build จากซอร์ส

ต้องมี Go 1.27+ และ protoc + protoc-gen-go (เฉพาะตอนแก้ proto):

go build -o gameserver-go.exe ./cmd/gameserver
go build -o sdkserver-go.exe  ./cmd/sdkserver
go test ./...                 # รวม smoke test จำลอง client จริง

สิ่งที่พอร์ตครบแล้ว

  • Network: mihoyo KCP (conv+token), NetOperation handshake (0xFF/0x145/0x194), packet framing (0x9D74C714/0xD7A152C8), freesr-data.json hot-reload watcher
  • Login flow ครบ (GetToken/PlayerLogin/GetBasicInfo/PlayerLoginFinish + ContentPackage)
  • ฉาก: GetCurSceneInfo/EnterScene (โหลด props/NPCs/monsters จาก res.json, teleport resolution, fallback จุดเกิด), SceneEntityMove (บันทึกตำแหน่ง), InteractProp, GetNpcTakenReward, GetSceneMapInfo, GetEnteredScene, GetUnlockTeleport
  • ทีม: GetAllLineupData/GetCurLineupData/JoinLineup/ReplaceLineup/SwapLineup/ SwitchLineupIndex/ChangeLineupLeader + SceneGroupRefresh/SyncLineup notify
  • ตัวละคร/ไอเทม: GetAvatarData (+skin), สวม/ถอด lightcone/relic, RankUpAvatar, GetBag
  • ภารกิจ: GetMissionStatus (curversion finished), GetMissionData, GetQuestData, GetMainMissionCustomValue, UpdateTrackMainMission (จาก mission_unlocks.json)
  • บทเรียน: ปดล็อคครบ 1249 tutorials + 855 guides (กันกล้อง/อินพุตค้าง)
  • ต่อสู้: SceneCastSkill (แก้บัคกล้องหลุดแล้ว), StartCocoonStage, StartQuickCocoonStage, SceneEnterStage, PVEBattleResult, GetCurBattleInfo, SceneCastSkillCostMp, บัฟ global (Castorice/SW/Aha 151104)
  • Challenge: GetChallenge, GetCurChallenge, GetChallengePeakData, GetCurChallengePeak, GetActivityScheduleConfig, StartChallengePeak (cmd 8948 → arena 3000101), StartChallenge → 1787 layout 4.6.51, Tierce (8973) + ทุก raw reply ที่ตอบค้าง (1708/1716/1781/1704/8997/8999/8923/8920/... ครบตาม packet.rs เดิม)
  • Dummy ปลอดภัย: ตอบว่างเฉพาะรายการที่ปลอดภัย ที่เหลือ drop เงียบ (บทเรียนจาก Rust: ตอบว่างมั่วทำให้ client NRE จอดำ)

ต่างจาก Rust ที่ควรรู้

  • นาฬิกา KCP เป็นมิลลิวินาที (Rust ใช้วินาที — ทำให้ RTT/เวลา retransmit เพี้ยน)
  • มี ticker ขับ KCP ทุก 50ms ต่อ session (retransmission ทำงานจริง)
  • ชื่อ message ใช้ตาม proto 4.6.51 จริง (แก้ปัญหาชื่อเก่าที่หายไป)
  • StartChallenge ยังไม่รองรับ challenge_id ที่อยู่นอก challenge_data.json (fallback arena 3014101 ทำงานเหมือนเดิม)