Save endgame progress, team presets, technique support and camera controls
This commit is contained in:
1 parent
a681affdb3
commit
639cef7d19
52 files changed
+11940
-766
No files matched your search
@@ -0,0 +1,79 @@
|
||||
# Endgame audit — 17 ตุลาคม 2026
|
||||
|
||||
## ตรวจข้อมูลทุกห้องใน resource ชุดที่ติดตั้ง
|
||||
|
||||
อ่าน RuntimeFloor และ RuntimeGroup ผ่าน GameCoreConfigLoader ของ Client แบบอ่านอย่างเดียว ครอบคลุมทุก MapEntrance ที่ ChallengeMazeConfig, ChallengeMazeTierceConfig และ ChallengePeakConfig อ้างถึง ไม่ได้สั่งเข้าแมพหรือแก้ actor/save ใน Client ข้อมูล SceneMetadata มี SHA-256 ของ GameAssembly และ capture ที่ใช้
|
||||
|
||||
| โหมด | รายการห้อง/node ที่ตรวจ |
|
||||
| --- | ---: |
|
||||
| Forgotten Hall / Memory / MoC | 1,268 |
|
||||
| Apocalyptic Shadow | 184 |
|
||||
| Pure Fiction | 224 |
|
||||
| Tierce / Starward ห้องที่สาม | 16 |
|
||||
| Anomaly Arbitration / Peak | 44 |
|
||||
| Peak Hard | 11 |
|
||||
| รวม | 1,747 |
|
||||
|
||||
มี 843 ด่านหลัก, 16 ด่าน Tierce, 44 ด่าน Peak และ Hard variants 11 รายการ ใช้ 37 entrances บน 34 floors นับรายการข้อมูลที่อ้างถึง ไม่ใช่จำนวนห้องกายภาพที่ต่างกันทั้งหมด SceneMetadata ยังเก็บอีกสอง floors ของ teleport ที่ผู้ใช้ยืนยันแล้ว รวมเป็น 36 floors
|
||||
|
||||
`tools/audit_endgame_resources.py` ตรวจ:
|
||||
|
||||
- entrance อ้างถึง floor จริงและมี metadata กลุ่มครบ
|
||||
- กลุ่มมอนเป็น Server group ที่ยังไม่ถูกลบ
|
||||
- มี start anchor ของ floor และตำแหน่ง monster instance ตาม ConfigList
|
||||
- ตัวโหลด Go มี scene monster source ของกลุ่มนั้น
|
||||
- event ของด่านมี StageConfig และทุก wave มีมอน
|
||||
|
||||
ผล audit **ไม่พบข้อมูลขาดตามเงื่อนไขข้างต้น** รันซ้ำได้ด้วย `python tools/audit_endgame_resources.py --output <report.json>` เครื่องมือนี้อ่านข้อมูล ไม่ใช่การลองเล่นทุกห้องในเกม
|
||||
|
||||
## ปัญหาที่พบจากการลอง PF
|
||||
|
||||
- Battle capture ของด่าน 30326041 ส่ง rounds_limit=0 เพราะ PF ไม่มี ChallengeCountDown ในตาราง แล้ว Go ไปใช้ cycle_count=0 ของ custom battle ผลใน Client จบหลัง cycle แรก
|
||||
- ย้าย mode round limits ไป resources/BattleRules.json: PF 4, AS/Default 30 ที่มาคือ PearlSR revision `005d2c12db4781071f4b5b68e8f364587886a710`, `ChallegeStageManager.createChallegeStage` ไม่ใช้ custom cycle เป็น fallback ของ Endgame
|
||||
- PF ธรรมดาส่งสอง LineupInfo ด้วย ExtraLineupType เดียวกัน แก้ทีมสองเป็น enum LineupChallenge2 และเก็บทั้งสองทีมใน run
|
||||
- PVEBattleResult เดิมตอบรับอย่างเดียว ไม่มีการเปลี่ยนห้องหรือแจ้งผล Challenge เพิ่ม run state ใน session พร้อม score/rounds ที่ Client ส่งจริง และป้องกันผลซ้ำหรือ stage ไม่ตรงกับ battle ที่ active
|
||||
- ด่านหลักสลับทีม/ห้องที่สองผ่าน SyncLineupNotify, ChallengeLineupNotify และ EnterSceneByServerScNotify แล้วแจ้ง ChallengeSettleNotify เมื่อจบ run
|
||||
- Tierce ใช้ OnStageSettle/OnBigSettle และ request StartNext/Restart พร้อม CurTierceChallenge ปัจจุบัน เก็บทีมกับ buff แยกแต่ละ session ไม่ใช้ cache รวมทุกผู้เล่น
|
||||
- Peak เปลี่ยนจาก arena/level/monster ที่กำหนดตายตัวเป็น Entrance, MazeGroupID, NpcMonsterIDList, EventIDList และ TagList ของ resource; Hard ใช้ HardEventIDList/HardTagList และสวิตช์ของ group นั้น เพิ่ม current-state/settle/confirm handlers
|
||||
- ออกจาก Challenge ล้าง run และกลับไปใช้ custom battle เดิม ไม่บันทึกทีม/wave ของ Endgame ทับ Freesr/persistent
|
||||
|
||||
## Protocol ที่ยังใช้ชื่อ obfuscated
|
||||
|
||||
ตรวจชื่อ callback/event จาก Client ที่กำลังรันผ่าน read-only reflection เพิ่มจาก schema ต้นฉบับ:
|
||||
|
||||
| ตาราง protocol | ความสัมพันธ์ที่ Client ระบุ |
|
||||
| --- | --- |
|
||||
| DOPHNDHILPA oneof field 9 / JCKGBFJJFFC | OnStageSettle |
|
||||
| DOPHNDHILPA oneof field 7 / GEKNAKDAMJF | OnBigSettle |
|
||||
| DOPHNDHILPA oneof field 3 / PEOKJEOOOJD | OnPendingStageSettle; ไม่เดาความหมายตัวเลขภายใน |
|
||||
| DOPHNDHILPA oneof field 8 / FLIPNFHAMPO | OnMedal ไม่ใช่การเปลี่ยน stage |
|
||||
| LHAKNKHBLBI | callback `<StartNext>b__25_0` |
|
||||
| JMPJCAPKNGI | callback `<Restart>b__21_0` |
|
||||
| OKEDFNJJGHB | callback `<ConfirmStageSettle>b__32_0` |
|
||||
|
||||
Handler resolve CmdID จากชื่อในตาราง revision เดียวกัน ไม่เพิ่ม alias ตัวเลขข้ามเวอร์ชัน ชื่อ request ฝั่ง Tierce ยังเป็นชื่อ obfuscated ของคู่ response ใน schema ความครบของ UI callback และลำดับ settlement หลังการเปลี่ยนนี้ยังต้องยืนยันใน Client ไม่ตีความ field ที่ยังไม่มีชื่อเพื่อแจกคะแนน/เหรียญหรือ reward สมมติ
|
||||
|
||||
## สถานะการยืนยัน
|
||||
|
||||
- ผู้ใช้ยืนยัน Starfroster/Ferry Relay Station และ Moment of Joy วาร์ปได้แล้ว
|
||||
- PF/Tierce build ก่อนหน้านี้มี PVEBattleResult และผู้ใช้เล่นได้ แต่ติดหนึ่ง cycle/ไม่ไปห้องต่อ ไม่ถือว่าผ่าน flow
|
||||
- Build ที่รวม cycle, run state และ settlement ชุดนี้ **รอผลลอง PF ธรรมดา, Tierce และโหมดอื่น** การตรวจ 1,747 รายการไม่ยืนยันว่าเล่นผ่านทั้งหมด
|
||||
- รายการปลดล็อก/ประวัติที่เมนู GetChallenge/GetChallengePeakData แสดง ยังมีข้อมูลจำลองของ implementation เดิม ส่วน reward, ดาว/เหรียญ และการเก็บผล Endgame ข้ามการเปิดเกมยังไม่ใช่ระบบ progression ที่ยืนยันครบ ตัว run ใหม่ไม่สร้างผลรางวัลหรือดาวจากการชนะเฉย ๆ
|
||||
|
||||
## ผลจากผู้ใช้และการแก้รอบ Technique
|
||||
|
||||
ผู้ใช้ยืนยัน PF ปกติเข้าสู้และเปลี่ยนทีม/ห้องได้แล้ว แต่ Starward ค้างตอนเข้าห้อง 3 Log Client ระบุ `TeamManager._CreateMemberEntity` เกิด `IndexOutOfRangeException` ระหว่างสร้าง leader ส่วน disassembly อ่าน `TeamData._leaderSlotIdId` ก่อนนำไป index `_MemberDatas` จึงตรวจเส้นทางติดตั้งทีมเป็นลำดับแรก
|
||||
|
||||
แก้ Tierce ให้ node 0/1/2 ส่ง ExtraLineupType `LineupChallenge` / `LineupChallenge2` / `LineupChallenge3` ตามชื่อ enum ใน protocol แทนการส่งทับทีมแรกทุก node และ GetCurLineupData คืนทีม Challenge ที่กำลังใช้อยู่ การเชื่อมโยงอาการกับทีมที่ว่างยังเป็นข้อสันนิษฐานจาก log/โค้ด ต้องยืนยันห้อง 3 ใน Client หลังเปลี่ยนนี้
|
||||
|
||||
Technique ไม่เปิด Battle อ้างอิงรายการ IgnoreBattle ของ PearlSR และตอบ MonsterBattleType.NO_BATTLE (4) จาก protocol ของ revision เดียวกัน ไม่สร้าง BattleInfo สำหรับผลนี้ ส่วนการโจมตีมอนปกติคงเส้นทาง resource stage เดิม
|
||||
|
||||
## Starward ผ่านห้อง 3 และการเซฟทีม/คะแนน
|
||||
|
||||
ผู้ใช้ยืนยันเล่นครบ 3 ห้องและจบรอบได้ ผล Client ที่ตรง server log ของ challenge 20275 คือ 33,000 + 28,500 + 35,500 = 97,000 การแยกประเภททีมแก้อาการห้อง 3 ในรอบที่ผู้ใช้ลองแล้ว
|
||||
|
||||
เพิ่ม persistent.tierce_progress สำหรับทีม บัฟ และ best result ของแต่ละ node เปลี่ยน GetChallengeTierceData จากข้อมูลทุกห้องชนะสำเร็จรูปเป็นทีม/ผลจริงที่เซฟไว้ รองรับ single-node retry โดยนำผลห้องอื่นที่เซฟแล้วมาประกอบ
|
||||
|
||||
อ่าน ChallengeTargetConfigRow ผ่าน Client lookup GBPODLFHCBI.LMBKNCAIDLC และเก็บตารางพร้อม assembly hash ใน ChallengeTargetConfig.json: TOTAL_SCORE enum7 มี PF targets 4001/4002/4003 = 60k/75k/90k และ target4000=99k; AS 5001/5002/5003=6000/7800/9900, target5000=10200 ไม่อนุมานดาวจากสถานะ WIN อย่างเดียว MoC targetประเภท ROUNDS_LEFT(6)/DEAD_AVATAR(2) ยังไม่ประเมินในรอบนี้
|
||||
|
||||
ทั้ง StageSettle และ BigSettle ส่ง FinishedTargetList เมื่อมีผลชนะครบทุก node ส่วน GetData คืน best record/targets ที่บันทึก การแจก reward และประวัติของโหมดปกติ/Peak ยังไม่รวมในส่วนนี้ การเก็บทีม/ดาวรอบใหม่ยังรอ Client ยืนยัน
|
||||
@@ -0,0 +1,69 @@
|
||||
# ตรวจ teleport และ Endgame — 17 ต.ค. 2026
|
||||
|
||||
## หลักฐานจาก Client
|
||||
|
||||
- `Player.log` แจ้ง `[HoyoGroupManager] 尝试激活的Group不存在, FloorID=20571001 FloorName=Starfroster GroupID=216` ก่อน `MapDef.InitServerGroups` เกิด NullReferenceException
|
||||
- เริ่ม Endgame มี NullReferenceException ที่ `ChallengeBossInstance._SyncExtraInfo` ผ่าน `_OnCmdStartChallengeScRsp`
|
||||
- จึงมีปัญหาหลัง Client ได้รับแพ็กเก็ต แม้ server จะส่ง response/notify สำเร็จ
|
||||
|
||||
## สิ่งที่แก้
|
||||
|
||||
เทียบซอร์ส PearlSR revision `005d2c12db4781071f4b5b68e8f364587886a710` ใน `scene_mgr.zig` และ `challenge_mgr.zig`:
|
||||
|
||||
- Go ใช้ `LevelOutputConfig.PlaneType` เป็น protocol `SceneInfo.GameModeType` ทั้งที่เป็นคนละ enum; supplementary scene ยังมีค่าเริ่มต้นเป็น 0 แก้ adventure เป็น mode 1 และ challenge เป็น mode 4 ตามต้นฉบับ
|
||||
- เติม world metadata จาก MapEntrance/MazePlane แทน world 0 ของ supplementary scene และนำการแทน world ด้วย ID เฉพาะออกจากสองตัวโหลดนี้
|
||||
- โหลด `FloorSavedValuesConfig.json` ซึ่งมีใน repository แต่ไม่ได้ถูกอ่าน เติมค่าที่ขาดตาม floor โดยรักษาค่าที่ root config ระบุไว้ ส่งให้ทั้ง adventure และ challenge ต้นฉบับใช้ MaxValue เป็นสถานะปลดล็อกเช่นเดียวกัน
|
||||
- เพิ่ม `CurChallenge.StageInfo.CurBossBuffs` สำหรับ AS และ `CurStoryBuffs` สำหรับ PF พร้อม buff ที่เลือกและ maze buff จาก challenge data; ก่อนหน้านี้ไม่มี StageInfo ทั้งที่ Client ใช้สร้าง instance
|
||||
- เปิด state ของ prop/monster group ใน challenge ตามต้นฉบับ และเพิ่ม log scene metadata / challenge state ที่ `server_debug.log`
|
||||
|
||||
## ขอบเขตและสิ่งที่ต้องยืนยัน
|
||||
|
||||
ยังไม่ได้ยืนยันผลใน Client หลังการแก้ เรายังไม่ทราบว่า Group 216 หายเพราะ scene initialization ที่ผิด หรือ resource/asset คนละ revision; `resources/res.json` ตรงกับ checkout PearlSR ข้างต้น จึงไม่ได้ลบหรือเปลี่ยนหมายเลขกลุ่มนี้เพื่อหลบ error
|
||||
|
||||
ต้องลองวาร์ป Starfroster และ Moment of Joy รวมทั้งเริ่ม Endgame แล้วอ่าน Player.log รอบใหม่ ถ้ายังมี missing group หลังแก้ metadata/saved values ต้องเทียบ floor asset ของ Client ต่อ การเปลี่ยนรอบนี้ไม่ได้รับรอง Peak/Tierce หรือการผ่านทุก node ของ Endgame และยังมี fallback arena/position เก่าใน handlers ที่ต้องตรวจแยก ไม่ได้อ้างว่าเอา hardcode ออกทั้ง repository
|
||||
|
||||
ไม่ได้แก้ battle converter, Calyx response, progression/EX หรือ inventory sync ในรอบนี้ จุดย้อนกลับที่ผู้ใช้ยืนยันก่อนเริ่มงานคือ tag `stable-2026-10-17-battle-eidolon` (commit `a681aff`)
|
||||
|
||||
## ผลลองรอบ 19:44 และการแก้ต่อ
|
||||
|
||||
ผู้ใช้ยืนยัน AS/PF บางห้องเข้าได้แต่เกิดใต้แมพ, Tierce 30225 ค้าง, PF Starward เข้าห้องได้แต่หลังตีมอนค้าง Weakness และ teleport ของแมพใหม่ยังไม่สำเร็จ ผลนี้ยังไม่ใช่การยืนยันว่ารอบแก้ก่อนสำเร็จ
|
||||
|
||||
พบข้อมูลผิดที่ตรวจซอร์สได้:
|
||||
|
||||
- root scene ของ entrance 3014003 ถูกตั้งชื่อ floor 30140001 แต่ MapEntrance ระบุ **30140003**; 3012602 ก็ถูกตั้งเป็น 30126001 แทน **30126002** เปลี่ยนให้ single-floor scene ใช้ plane/floor จาก MapEntrance จริง
|
||||
- Tierce 30225 ใน challenge_data ระบุ entrance 3012602, monster 2034012, event 420554 แต่ตาราง resource ปัจจุบันระบุ **3012402 / 3024012 / 420584** ตัวโหลดจึงให้ ChallengeMazeConfig, ChallengeMazeTierceConfig และ StageConfig ปัจจุบันมีลำดับความสำคัญเหนือข้อมูล compiled เก่า
|
||||
- อ่าน PreChallengeMazeID ของ Tierce จากตาราง: node 0/1 ใช้ข้อมูลสองฝั่งของด่านก่อนหน้า ส่วน node 2 ใช้ด่าน Tierce ไม่เลือกด่าน Tierce ตั้งแต่ node 0 และไม่เดา remap ตามเลข season
|
||||
- เปลี่ยน response Tierce ให้ส่งเฉพาะ lineup ของ node ที่ active ตาม upstream
|
||||
- นำสูตรตำแหน่งเดิมที่ยก Y ไปหา prop สูงสุดและเลื่อนเข้าหาจุดกำเนิดโลกออก ใช้ Anchor เมื่อมี; ถ้าตารางไม่มี Anchor ใช้ตำแหน่งมอนในกลุ่มจริงแทน ไม่สร้างกลุ่มหรือพิกัดสมมติ หากไม่มีตำแหน่งจะตอบ error พร้อมบันทึกเหตุผล การเกิดตรงจุดมอนนี้ยังต้องตรวจ Client โดยเฉพาะห้องที่ไม่มี Anchor
|
||||
- เก็บ BattleConfig ของ AS/PF/MoC/Tierce ใน session; ทีม มอน และ buff มาจาก node/stage ที่เลือก ไม่เขียนทับ custom config ใน persistent และไม่ถูก Freesr reload เปลี่ยน wave ไปกลางห้อง จำนวนรอบใช้ ChallengeCountDown เมื่อระบุไว้ มิฉะนั้นใช้ค่าตั้ง rounds ของผู้ใช้เช่นต้นฉบับ AS/PF ไม่ระบุ countdown ในตาราง
|
||||
- log PF Starward รอบสุดท้ายมี SceneCastSkill สอง request ที่ไม่มีทั้ง hit/assist targets เซิร์ฟเวอร์จึงส่ง response ว่างและ **ไม่ได้ส่ง BattleInfo** ในสอง request นั้น ยังไม่สรุปว่าเป็น error โหลดมอนของ Battle; เพิ่ม request detail เมื่อเกิดใน Challenge เพื่อแยกจากปัญหา wave
|
||||
|
||||
ตอนตรวจรอบนี้ Player.log เป็น session หลังเปิดเกมใหม่แล้ว ไม่มี exception ของการกด teleport รอบก่อน จึงยังต้องอ่าน log หลังทำซ้ำโดยไม่ออกเกมก่อน ไม่ได้ลบ Group 216 หรืออ้างว่าการเปลี่ยน floor ของ Challenge แก้ teleport ของ Starfroster/Moment of Joy แล้ว
|
||||
|
||||
Build ผ่านและวางที่ root ไม่เท่ากับ Client ผ่าน ยังรอลองหลังการแก้ข้างต้น Peak ยังมีเส้นทาง legacy แยกจาก session config ที่แก้ใน AS/PF/Tierce รอบนี้
|
||||
|
||||
## ยืนยันต้นเหตุจากตาราง Client หลังลองวาร์ปซ้ำ
|
||||
|
||||
หลังผู้ใช้กด Ferry Relay Station เก็บ exception `MapDef.InitServerGroups` ได้อีกครั้ง แม้ mode/world ถูกต้องแล้ว ตรวจแบบอ่านอย่างเดียวผ่าน `GameCoreConfigLoader.LoadRtLevelFloorInfo(MapDef.GetRtFloorInfoPath(plane, floor))` และ `GroupInstanceCommonMap` พบ:
|
||||
|
||||
- Starfroster floor 20571001 group 216 มี `LoadSide=Server`, `IsHoyoGroup=true`, **`IsDelete=true`**
|
||||
- floor 20572001 group 98 มี **`IsDelete=true`** เช่นกัน ทั้งสองกลุ่มยังถูกส่งใน resources/res.json จึงไม่ใช่หลักฐานว่า Client ขาด asset ทั้งแมพ
|
||||
- อ่าน StartGroupIndex/StartAnchorID และ AnchorList ของ runtime group ได้จุดเกิดจริงของห้อง Challenge ที่ Anchor.json เดิมไม่มี รวมทั้ง PF 30140003, Starward 30142001, AS 30141001/30132001 และ Tierce 30124002/30126002
|
||||
|
||||
เพิ่ม `resources/SceneMetadata.json` ครอบคลุม **8 floors ที่อ่านจริง** พร้อม SHA-256 ของ GameAssembly และ log capture ไม่มี path เครื่องใน resource ตัวโหลดใช้ metadata เฉพาะ Client version ที่ตรง runtime config และจำนวน group ครบ แล้วกรองกลุ่มที่ถูกลบ, เป็น Client-owned หรือไม่มีในตาราง floor นั้น ใช้กฎเดียวกันทุก floor ที่มี metadata ไม่มีเงื่อนไขเจาะจง group 216/98 ใน Go
|
||||
|
||||
เติม start anchor และตำแหน่งมอนจาก runtime group โดยแปลง group transform เข้า world และ metres/degrees เป็นหน่วย protocol จุดเกิดของห้องที่ครอบคลุมจึงใช้ Anchor จริง ไม่ต้องยืนตรงมอนหรือเดาความสูง prop ส่วน floor อื่นยังใช้ข้อมูลเดิมและไม่อ้างว่าตรวจทุกแมพแล้ว ตัวแปลง log เป็น resource อยู่ที่ `tools/export_scene_metadata.py`; รับ log, assembly, client version และ output เป็น arguments และปฏิเสธ group capture ที่ไม่ครบ
|
||||
|
||||
Script อ่านข้อมูลชั่วคราวถูกนำออกจาก scripts/ หลังเก็บข้อมูลเสร็จ ไม่เปลี่ยน scene/actor, patch method หรือ save ใน Client ผลวาร์ป/สู้หลัง build ที่รวม metadata **ยังรอผู้ใช้ยืนยัน**
|
||||
|
||||
### ผลยืนยันวาร์ปหลัง build ที่รวม metadata
|
||||
|
||||
ผู้ใช้ตอบคำถามลอง Ferry Relay Station และ Moment of Joy ว่า **ได้แล้ว** จึงยืนยันการวาร์ปสองปลายทางนี้ใน Client ได้จริง Log รอบเดียวกันมี entry 2057101 teleport 2057103/2057102 และ entry 2057201 teleport 2057202 โดย group list ไม่มีกลุ่มที่ถูกลบ 216/98 แล้ว ไม่พบ `MapDef.InitServerGroups`/missing-group error ใน Player.log รอบนี้ ผลนี้ยังไม่ยืนยัน PF/AS/Tierce หรือการตีมอนของ Endgame หลัง build ใหม่
|
||||
|
||||
## MoC จากสมุด: ค้างท้ายหน้าโหลดในฉากรถไฟ
|
||||
|
||||
คำขอ EnterScene ระบุ entrance 100000104, floor 10000000 และ teleport 2206 Client ล้มที่ `MapNpcDef.get_ConfigEntityPath` ขณะโหลด MapNPC 227-400001 ตาราง RuntimeGroup ของ Client ระบุ NPCID=3001 (ปอมปอม) ในกลุ่มนี้
|
||||
|
||||
GetPamSkinData ของ Go เดิมตอบ cur_skin=0 และ unlock_skin_list=[0] แต่ Client PamSkinConfigRow lookup ยืนยันว่า ID0 คืน nil ขณะที่ ID252000 มี ConfigEntityPath จริง และตรงกับค่าปกติใน PearlSR services/scene.zig revision005d2c12
|
||||
|
||||
แก้ handler ให้อ่านค่าจาก ProfileConfig.pam_skins/current_pam_skin และตรวจทุก ID กับ PamSkinConfig.json ที่ export จาก Client พร้อม SHA-256 ของ GameAssembly ไม่แก้กลุ่ม227ทิ้ง ไม่เปลี่ยนเส้นทาง Battle ผลการวาร์ปหลังแก้นี้ยังรอ Client ยืนยัน
|
||||
Reference in new issue
Block a user