Files
GaCy-GO/docs/GLM-BETA-EVENTS.md
2026-10-28 18:54:43 +07:00

20 KiB
Raw Permalink Blame History

ข้อมูลกิจกรรม 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/policy
  • derived/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.ActivityPanelRow
  • activities: 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 คือ:

  1. UIPrefab ต้องอยู่ใน policy-listed family และมี handler ที่รองรับ
  2. PreviewAssetAvailability.json ต้องระบุว่า UIPrefab และ TabIcon มีจริงทั้งคู่
  3. DisplayItemList ต้องว่าง เพื่อไม่กลับไป trigger missing-item/invalid-item errors ที่เคยพบ
  4. 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/gameplay
  • QuestState: เป็นชื่อ 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. ลำดับงานที่แนะนำ

  1. เปิด derived/event-index.json/CSV แล้วค้น panel 50132/50142/50143 ก่อน จะเห็น association, reward item IDs และ conditions โดยไม่ต้อง extract ใหม่
  2. Resolve TabName/TitleName/IntroDesc จาก TextID ที่เจาะจง เพื่อบอกผู้ใช้ได้ว่า technical event นี้ตรงกับชื่อใดจริง
  3. อ่าน exact UI controller/data proxy ของ panel หนึ่งระบบให้ครบ entry → data request → initialization → close/return map โดยไม่ execute action ระหว่างสำรวจ
  4. ตรวจ display-item dependencies ทุก ID กับ current Client item assets/config และดูว่า reward preview สร้าง ItemData ได้จริงก่อนแสดงหน้า
  5. ผูก main/resident modules และ early access state จาก schema ปัจจุบัน ไม่ตีความทุก module เป็น active event ชนิดเดียวกัน
  6. Implement data/entry path ของระบบนั้นแล้วค่อยขยาย policy และ schedule อย่าเปิดทุก prefab ที่มีแล้วตอบว่าง
  7. อัปเดตสถานะแยก 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 หนึ่งหาไม่เจอ