20 KiB
ข้อมูลกิจกรรม Client Beta สำหรับ GLM
อัปเดต 24 ตุลาคม 2026 (Asia/Bangkok) — ตรวจจาก resource/capture ที่มีอยู่เท่านั้น ไม่ได้แก้ production code ไม่ส่ง probe ไม่รัน tests และไม่รีสตาร์ตเกมหรือเซิร์ฟเวอร์ในงานจัดทำเอกสารนี้
ตำแหน่งชุดข้อมูลรวมและ manifest ของไฟล์ให้ดู GLM-BETA-DATA.md ภายใน package มี:
derived/event-index.json— join panel/activity/modules พร้อมเงื่อนไขและสถานะ asset/policyderived/event-index.csv— รายการสำหรับค้น/กรองได้สะดวกderived/preview-schedules.json— schedules ที่ source/policy ปัจจุบันเลือกได้- raw
PreviewGameplayCatalog.json,PreviewAssetAvailability.jsonและ policy ที่ใช้ทำ index
1. สรุปสิ่งที่พบ
ข้อมูลกิจกรรมมีอยู่ใน Beta นี้แล้ว การหา type ชื่อหนึ่งไม่พบ หรือหน้ากิจกรรมยังไม่แสดง ไม่ได้แปลว่าไม่มีตารางกิจกรรมใน Client
ไฟล์หลักคือ resources/PreviewGameplayCatalog.json:
- Client assembly SHA-256:
4aa08a0706f27d2cf9951b61920c179140ece9ea94f7e34422c18e46922939b6 - Evidence:
ev_9ea0f171c212f18ef6442f116c0bd14dd3ba08a3c583141c9bad58a5d2c7bd27 panels: 181 แถว ของRPG.GameCore.ActivityPanelRowactivities: 361 แถว ของRPG.GameCore.ActivityConfigRow- ในไฟล์เดียวกันมี Gacha 6 แถว และ Parkour 13 แถว ซึ่งเป็นคนละระบบ
นี่เป็นข้อมูลทั้งหมดของ สี่ตารางที่ capture ชุดนั้นอ่านได้ ไม่ใช่การ extract ทุกตาราง/ทุก asset/ทุก script ของเกมทั้งชุด และไม่ใช่รายการ event ที่เปิดจริงในวันหนึ่งโดยอัตโนมัติ Client เก็บ historical/future rows ร่วมกันได้
ตารางที่ยืนยันว่ามีชื่อดังนี้:
RPG.GameCore.ActivityPanelRow
RPG.GameCore.ActivityConfigRow
RPG.Client.ActivityModule
การ probe RPG.GameCore.ActivityModuleRow เคยได้ nil เพราะเป็นชื่อที่ลองหา ข้อนี้ไม่ใช่หลักฐานว่า ActivityModuleIDList หรือระบบกิจกรรมหายไป
2. เหตุที่กิจกรรมยังไม่แสดง
internal/common/activity_preview.go ปัจจุบันกรองตาม ActivityPreviewPolicy.json ไม่ได้ส่งทุกแถวใน Client กลับไปเสมอ
เงื่อนไขก่อนประกาศ preview คือ:
- UIPrefab ต้องอยู่ใน policy-listed family และมี handler ที่รองรับ
PreviewAssetAvailability.jsonต้องระบุว่า UIPrefab และ TabIcon มีจริงทั้งคู่DisplayItemListต้องว่าง เพื่อไม่กลับไป trigger missing-item/invalid-item errors ที่เคยพบ- module ที่ถูกอ้างโดยหลายกิจกรรมต้อง resolve เป็น prefab/handler ที่ตรงกัน ไม่มี first-match เงียบ ๆ
ผลนับจาก resource และ source ปัจจุบัน:
| รายการ | จำนวน |
|---|---|
| Panel rows ทั้งหมด | 181 |
| Activity rows ทั้งหมด | 361 |
| Unique prefab/icon paths ที่เคยตรวจ | 290 |
| Panels ที่ prefab และ icon มีทั้งคู่ | 146 |
| Panels ที่ไม่มี prefab | 27 |
| Panels ที่ไม่มี icon | 30 |
| Prefab families ที่ policy อนุญาต | 19 |
| Panels ที่ผ่าน policy + assets + no display items | 56 |
| Unique preview module schedules | 121 |
| QuestState schedules | 111 |
| GetMultipleDropInfo schedules | 10 |
| Conflicting module-to-panel mappings ใน selected set | 0 |
| Activity rows ที่ไม่พบ effective panel row ใน capture นี้ | 99 |
จำนวนไม่มี prefab/ไม่มี icon มีบางแถวซ้ำกัน จึงห้ามนำ 27 กับ 30 มาบวกแล้วลบจาก 181 ตรง ๆ
146 panels ที่มี asset ครบ ไม่ได้แปลว่าเปิดเล่นได้ 146 กิจกรรม ยังมี reward dependencies, data proxies, entry handlers, unlock/finish checks และ state machine ของแต่ละระบบที่ต้องต่อ
3. รายการที่หาเจอและควรใช้เริ่มไล่ Beta features
ชื่อด้านล่างเป็น ชื่อเทคนิคจาก UIPrefab ไม่ใช่ชื่อภาษาอังกฤษ/ไทยที่ยืนยันแล้วจาก TextMap และเลข ID สูงไม่ได้พิสูจน์เองว่า event นั้นเปิดจริงใน Beta รอบปัจจุบัน
ทุกแถวในตารางยกเว้น BlindBox ตรวจพบทั้ง prefab และ icon ใน installed asset index แล้ว:
| Activity / Panel ID | Technical panel | ActivityModuleIDList | ResidentModuleList | EarlyAccessContentID | Asset |
|---|---|---|---|---|---|
| 50132 | QuestMechCraftPanel | 5013201 | 5013202 | 150132 | prefab + icon มี |
| 50142 | QuestComicDessertPanel | 5014201 | 5014202 | 150135 | prefab + icon มี |
| 50143 | QuestRealityShowPanel | 5014301–5014305 | 5014311–5014315 | 0 | prefab + icon มี |
| 50125 | QuestFinalityBattlePanel | 5012501–5012505 | ว่าง | 0 | prefab + icon มี |
| 50114 | QuestTeamTowerPanel | 5011401 | 5011402 | 150078 | prefab + icon มี |
| 50112 | QuestPixAirPanel | 5011201 | 5011202 | 150076 | prefab + icon มี |
| 50111 | QuestB51RacingPanel | 5011101 | 5011102 | 150079 | prefab + icon มี |
| 50107 | QuestChenLingFesPanel | 5010701 | ว่าง | 150077 | prefab + icon มี |
| 50092 | QuestChenLingBattlePanel | 5009201 | 5009202 | 150074 | prefab + icon มี |
| 50134 | QuestBlindBoxPanel | 5013401 | 5013402 | 150134 | prefab ไม่มี / icon มี |
รายการนี้ยังไม่อยู่ใน selected preview families ปัจจุบัน กลุ่มที่ assets มีถูกกันไว้เพราะ DisplayItemList และ event-specific data handlers ยังไม่ครบ จึงต้องแยกจากกรณี asset ไม่มีจริง
Exact paths ของสามรายการที่มีข้อมูลใหม่ชัดเจน:
UI/Quest/Widget/QuestMechCraftPanel.prefab
UI/Quest/Widget/QuestComicDessertPanel.prefab
UI/Quest/Widget/QuestRealityShowPanel.prefab
BlindBox แถวที่ capture ได้เก็บ path Assets/AsbRes/UI/Quest/Widget/QuestBlindBoxPanel.prefab ซึ่ง AssetMgr.Exists ให้ false อย่าเดาว่าถอด prefix หรือเปลี่ยน case แล้วจะใช้งานได้ ต้องตรวจ canonical loader/path ก่อน
เงื่อนไขที่อยู่ในแถวจริง
| Panel | UnlockConditions | FinishConditions ที่ต้องตามต่อ |
|---|---|---|
| 50132 MechCraft | [PlayerLevel:21] |
QuestClose ของ 6088098–6088120 ทุก ID ในช่วง |
| 50142 ComicDessert | [PlayerLevel:21] |
QuestClose ของ 6090001–6090005 และ 6090014 |
| 50143 RealityShow | [PlayerLevel:21] |
QuestClose ของ 6091004, 6091008, 6091012, 6091016, 6091020, 6091001, 6091005, 6091009, 6091013, 6091017 |
| 50134 BlindBox | [PlayerLevel:4] |
[QuestClose:6089009] |
อย่า complete quest เหล่านี้ทั้งหมดเพื่อให้หน้าเปิด เพราะบางตัวเป็น FinishConditions ซึ่งอาจทำให้หน้าถูกถือว่าจบหรือหายไปแทน ต้องอ่าน semantic ของ condition checker และตรงกับ state จริงก่อน
TextID สำหรับ resolve ชื่อหน้าจอแบบ targeted
| Panel | TabName.hash | TabName.hash64 |
|---|---|---|
| 50132 | 1880458566 | 6958762709850968366 |
| 50142 | -2011224203 | 143653261616862737 |
| 50143 | -2011224202 | 14823125606058724992 |
| 50134 | 1880458564 | 7162233255424057948 |
raw capture รักษา integer strings เดิมไว้ เลข hash64 หลายตัวเกิน exact integer range ของ JavaScript Number ห้าม parse แล้ว serialize ด้วย Number จนค่าเปลี่ยน ใช้ parser ที่รักษา int64/uint64 หรือเก็บเป็น string สำหรับ derived exports
4. ID mapping ของ schedule ต้องไม่สลับ
ใน internal/gameserver/handlers_challenge.go handler GetActivityScheduleConfig ส่ง:
ActivityScheduleData.ActivityId = ActivityModuleID
ActivityScheduleData.PanelId = ActivityPanelID
ตัวอย่าง MechCraft ตาม association ที่ capture มา:
ActivityConfig.ActivityID = 50132
ActivityConfig.ActivityPanelID = 50132
ActivityConfig.ActivityModuleIDList = [5013201]
ActivityConfig.ResidentModuleList = [5013202]
อย่าเอา 50132 ไปส่งเป็น module schedule แทน 5013201 เพียงเพราะ field ใน wire ชื่อ ActivityId การมี resident module ก็ไม่ได้พิสูจน์ว่าใช้เป็น active preview แบบเดียวกับ main module ได้ ต้องตรวจ proxy/phase behavior ของกิจกรรมนั้น
ActivityPanelID=0 บางแถวต้อง resolve ตาม Client behavior ที่ตรวจไว้ โดย loader ปัจจุบันใช้ fallback ActivityID แต่มี 99 activities ที่ยังไม่มี panel row ให้ match ใน capture นี้ อย่าส่งทุกแถวพร้อม panel 0 หรือสร้าง panel ID ขึ้นเอง
หลาย rerun activities อ้าง module เดียวกัน เช่น module 1002101 ถูกใช้กับ panel 10021/10113 ซึ่งเป็น prefab/handler เดียวกัน ปัจจุบันรวมเหลือรายการเดียวแบบ deterministic ถ้าเปลี่ยน policy แล้วพบต่าง prefab/handler loader จะ error แทนการเลือกแถวแรก
5. คำตอบ/data handlers ที่มีจริง กับที่ยังไม่มี
internal/gameserver/handlers_activity_preview.go มี:
GetMultipleDropInfo: สร้าง explicit panel entries แต่ counter เป็นศูนย์ เป็น preview ไม่ใช่แจก quota/reward เพิ่มGetActiveActivityData: มี handler แต่ policy ปัจจุบันไม่เปิด family ที่เคยเกิด invalid-item error กลับมาGetFiveDimMiniGameData: ยังตอบ list ว่าง ไม่ใช่ implementation ของ Stella Jump/gameplayQuestState: เป็นชื่อ policy grouping ที่อาศัย quest/mission handlers เดิม ไม่ใช่ generic handler ที่ทำ MechCraft/RealityShow ทุกระบบได้
ปัจจุบันยังไม่มีการพิสูจน์ event-specific data/entry callbacks ครบสำหรับ MechCraft, ComicDessert และ RealityShow อย่าส่ง null success response หรือ advertise ก่อนรู้ว่า Client จะขอ state อะไรต่อ
ตาราง CmdID ใน protocol/proto/upstream_cmdids.go ระบุ:
Source: https://git.xeondev.com/HonkaiSlopRail/pearl-sr protocol/src/root.zig
Revision: 005d2c12db4781071f4b5b68e8f364587886a710
มีชื่อชัดเจนบางระบบ เช่น PixAirGetData, GetChenLingFesData, StartFinalityBattleLevel, BlindBoxGetData แต่การมีชื่อในตารางยังไม่ใช่หลักฐานว่า handler ใช้งานครบ และ MechCraft/ComicDessert/RealityShow ยังไม่พบชื่อชัดเจนจากการค้นนี้ อาจยังใช้ obfuscated names ต้องผูกจาก sender/callback schema จริง ห้ามเดา aliases หรือใช้เลขหลาย revision
6. ไปหาต่อจากไหนโดยไม่สแกนทั้ง assembly
หลักฐาน named tables ที่มีแล้ว
tools/preview_catalog_metadata.lua ตรวจเฉพาะชื่อ type และ FromBinary ของ ActivityPanelRow/ActivityConfigRow แล้วนำไปตาม flat dictionary chain
tools/preview_flat_tables.js มี exact getter chain ของ assembly hash ข้างต้น:
| ตาราง | GetAll RVA สำหรับ hash ที่ระบุเท่านั้น |
|---|---|
| ActivityPanelRow | 0x1e4ca860 |
| ActivityConfigRow | 0x1dfbc4d0 |
getter traces อยู่ใน battle_diagnostics/preview-activity-getter.asm, preview-panels-getter.asm พร้อม preview-activity-{loader,add}.asm และ preview-activity-panel-{loader,add}.asm
Capture อ่านครั้งละ 16 แถวต่อ managed marker และตรวจ bounds ก่อน serialize ไม่ต้องเรียก scene/level factory tools/preview_capture_trigger.lua ส่ง marker GAC_PREVIEW_TICK แบบจำกัดครั้งและ pause ใน Battle
ข้อมูลถูก capture แล้ว ไม่จำเป็นต้องติด probe ซ้ำเพียงเพื่อเปิดดูตารางเดิม หากต้องอ่านใหม่ต้องตรวจ process/module hash ใหม่ก่อน RVA เป็นของ shipped binary เฉพาะรุ่น ไม่ใช่ production constants และ MethodHandle/pointer เก่าห้ามใช้ข้าม process
จุดเริ่ม event page/proxy
จาก named metadata ของ RPG.Client.ActivityModule พบ:
ActivityDataDict
ActivityPanelDataContainer
CustomizedPanelDataContainer
_PanelDataProxyFactory
_PanelID2TemplateIndexLUT
_PanelTemplates
_AvailablePanelDatas
_phaseMap / _phaseList
GetActivityData(UInt32)
_OnScheduleConfigRefresh(System.Object)
ข้อมูลนี้ใช้เลือก inspect object/proxy ของ panel ID เป้าหมาย ได้ ไม่ต้อง enumerate ทุก type ใน assembly
สำหรับ panel UI ให้ตาม prefab/binder registration ของ technical name ที่ระบุข้างบน เพื่อหา exact loaded Lua module/controller ก่อน เมื่อมี module name ที่ยืนยันแล้วค่อยอ่าน named functions/upvalues หรือ loader bytes ไม่สมมติ callback ชื่อ _refresh/GetData ว่าแต่ละ panel เหมือนกันหมด
มีตัวอย่างวิธีอ่าน Luau โดยไม่ execute closure ใน tools/gacha_load_only.lua และ bytecode reader tools/inspect_luau_v4.py สำหรับ GachaMainPage ที่ทำไว้ก่อน ใช้เป็นรูปแบบการวิเคราะห์เท่านั้น อย่า require/reload event controller หรือใช้ package loader ของชื่อที่เดาขึ้นเองระหว่าง gameplay
7. ลำดับงานที่แนะนำ
- เปิด
derived/event-index.json/CSV แล้วค้น panel 50132/50142/50143 ก่อน จะเห็น association, reward item IDs และ conditions โดยไม่ต้อง extract ใหม่ - Resolve TabName/TitleName/IntroDesc จาก TextID ที่เจาะจง เพื่อบอกผู้ใช้ได้ว่า technical event นี้ตรงกับชื่อใดจริง
- อ่าน exact UI controller/data proxy ของ panel หนึ่งระบบให้ครบ entry → data request → initialization → close/return map โดยไม่ execute action ระหว่างสำรวจ
- ตรวจ display-item dependencies ทุก ID กับ current Client item assets/config และดูว่า reward preview สร้าง ItemData ได้จริงก่อนแสดงหน้า
- ผูก main/resident modules และ early access state จาก schema ปัจจุบัน ไม่ตีความทุก module เป็น active event ชนิดเดียวกัน
- Implement data/entry path ของระบบนั้นแล้วค่อยขยาย policy และ schedule อย่าเปิดทุก prefab ที่มีแล้วตอบว่าง
- อัปเดตสถานะแยก asset present / source implemented / deployed / Client confirmed คำว่า “หาเจอ” ไม่ใช่คำว่า “เล่นได้แล้ว”
ข้อจำกัดที่ยังเหลือ
- ยังไม่มี export official per-event active schedule ชุดปัจจุบันจาก Client/service ต้นทาง เวลาใน server ใช้ operator
cfg.ActivityScheduleร่วมกับ Endgame - ยังไม่มี localized titles ที่ resolve ครบทุก panel
- raw catalog นี้ไม่รวมทุก event gameplay table, Lua/controller, stage/reward graph หรือ asset bundle ทั้งเกม
- เอกสารนี้ไม่ยืนยันว่า UI ใหม่เปิดได้หรือจอดำหาย ผู้ใช้ไม่ต้องถูกวนให้ลองทีละ handler ตามคำสั่งล่าสุด
ดังนั้นให้ใช้รายการนี้ช่วย GLM หา event และต่อข้อมูลที่ยังขาด แทนการสรุปว่า Beta นี้ไม่มี event เพราะชื่อ type หนึ่งหาไม่เจอ