302 lines
25 KiB
Markdown
302 lines
25 KiB
Markdown
# ข้อมูลและวิธีเพิ่มตู้กาชาให้ GLM — Client Beta ปัจจุบัน
|
|
|
|
อัปเดต: 24 ตุลาคม 2026 (Asia/Bangkok)
|
|
|
|
อ่านคู่กับ [GLM-BETA-DATA.md](GLM-BETA-DATA.md) และ [ZCODE-HANDOFF.md](ZCODE-HANDOFF.md)
|
|
|
|
## 1. เป้าหมายผู้ใช้และสถานะจริง
|
|
|
|
ผู้ใช้ต้องการเลือกตู้ตัวละคร โดยแต่ละตู้มีตัวเด่นหนึ่งตัว และผลสุ่มตรงกับตัวที่แสดงบนตู้ ไม่ได้ต้องการแค่หน้า Standard ที่เปิดดูได้แต่สุ่มไม่ได้
|
|
|
|
ตอนนี้ backend มีโค้ด featured-only sandbox สำหรับสุ่ม 1/10 ครั้ง และจัดการ duplicate material แต่ **ยังไม่มี featured banner ที่เปิดใช้งานจริง** Policy เปิดเพียง Standard เพื่อหลีกเลี่ยง Client crash จึงยังไม่ตรงคำขอ
|
|
|
|
เอกสารนี้ให้ข้อมูลที่ตรวจแล้วและลำดับพัฒนาต่อ ไม่ได้อ้างว่าการเพิ่ม path ใน JSON จะทำให้ตู้ใช้งานได้ หรือว่าดึง asset ที่หายกลับมาแล้ว
|
|
|
|
Client ที่อ้างอิงใน capture นี้: `GameAssembly.dll` SHA-256
|
|
|
|
```text
|
|
4aa08a0706f27d2cf9951b61920c179140ece9ea94f7e34422c18e46922939b6
|
|
```
|
|
|
|
เป็น Client Beta .54 ที่ตรวจ runtime จริง ไม่ใช้ hash/RVA ของ CW capture .53 แทน
|
|
|
|
## 2. ตารางตู้จริงที่ดึงไว้แล้ว
|
|
|
|
`resources/PreviewGameplayCatalog.json` → `tables.gacha` มี `GachaBasicInfoConfigRow` ครบ 6 แถวของ capture นี้:
|
|
|
|
| GachaID | GachaType | SortID | PrefabPath | ผลตรวจ asset |
|
|
| ---: | ---: | ---: | --- | --- |
|
|
| 1001 | 1 | 99 | `UI/Drawcard/GachaPanel/StandardGacha_1001.prefab` | มี |
|
|
| 4001 | 2 | 1 | `UI/Drawcard/GachaPanel/NoviceGacha_4001.prefab` | มี |
|
|
| 2001 | 11 | 2 | `UI/Drawcard/GachaPanelLimited/AvatarGacha_1102.prefab` | ไม่มี |
|
|
| 2002 | 11 | 3 | `UI/Drawcard/GachaPanelLimited/AvatarGacha_1204.prefab` | ไม่มี |
|
|
| 3001 | 12 | 4 | `UI/Drawcard/GachaPanelLimited/LightConeGacha_23001.prefab` | ไม่มี |
|
|
| 3002 | 12 | 5 | `UI/Drawcard/GachaPanelLimited/LightConeGacha_23010.prefab` | ไม่มี |
|
|
|
|
ชื่อ enum ที่พบใน Lua คือ `Normal`, `Newbie`, `AvatarUp`, `WeaponUp` การจับคู่เลขข้างบนมาจาก captured rows ไม่ใช่การสร้างเลขเพิ่ม
|
|
|
|
แถวเหล่านี้ยังเก็บ `PoolLabelIcon`, `PoolLabelIconSelected`, `PoolName`, `PoolDesc`, `TypeTitle` และ TextID/hash64 ให้ใช้ original numbers ห้ามอ่านผ่านเครื่องมือที่ทำ uint64 เกิน 2^53 สูญเสีย precision
|
|
|
|
**ข้อจำกัด:** แถวในตารางไม่ได้พิสูจน์ว่ามี bundle ใน installation ผล `AssetMgr.Exists` ยืนยันแล้วว่า limited ทั้ง 4 path ข้างบนไม่มี
|
|
|
|
หลักฐาน: `battle_diagnostics/gacha-asset-exists-20261024.log` มีผลครบ 6 path และ `END` Policy เก็บผลพร้อม hash ไว้ใน `resources/GachaSandboxPolicy.json`
|
|
|
|
Seele prefab ที่ไม่มีเคยทำ `UIPrefabLoader._HandleLoadResult` ArgumentNullException ระหว่าง `GachaMainPage._create_pools_panel` แล้วออกกลับโลกจอดำ ห้ามเพิ่มกลับ allowlist เพื่อให้หน้าตู้ดูเยอะขึ้นทั้งที่ asset ยังไม่มี
|
|
|
|
## 3. Generic/group prefab ที่พบใหม่ — ตรวจแล้วไม่มีเช่นกัน
|
|
|
|
ถอดจาก bytecode ของ GachaMainPage ปัจจุบัน พบ group presentation ที่มี path จริงดังนี้:
|
|
|
|
| Group enum และค่าที่ capture จริง | Path ที่อ้างถึง | ผลตรวจใน Client ปัจจุบัน |
|
|
| --- | --- | --- |
|
|
| `MultiAvatarUp=1` / `MultiWeaponUp=2` | `UI/Drawcard/GachaPanel/MultiAvatarGacha.prefab` | ไม่มี |
|
|
| `Collaboration=3` | `UI/Drawcard/CollaborationGacha/CollaborationGacha.prefab` | ไม่มี |
|
|
| `CollaborationMerge=4` | `UI/Drawcard/CollaborationGacha0440/CollaborationGacha0440.prefab` | ไม่มี |
|
|
|
|
หลักฐานรอบล่าสุด: `battle_diagnostics/glm-beta-targeted-metadata.log`
|
|
|
|
```text
|
|
ASSET UI/Drawcard/GachaPanel/MultiAvatarGacha.prefab true false
|
|
ASSET UI/Drawcard/CollaborationGacha/CollaborationGacha.prefab true false
|
|
ASSET UI/Drawcard/CollaborationGacha0440/CollaborationGacha0440.prefab true false
|
|
END
|
|
```
|
|
|
|
ใน log นี้ boolean แรกคือการเรียกตรวจสำเร็จ ส่วน boolean ที่สองคือผล Exists จึงหมายถึง **ตรวจสำเร็จและไม่มี asset** ไม่ใช่พบ asset แล้ว
|
|
|
|
Group path เป็นข้อมูลสำหรับเข้าใจโครงสร้าง UI ไม่ใช่ fallback ที่พร้อมเปิดใช้ อย่าเสนอว่าเปลี่ยนมาใช้ MultiAvatarGacha แล้วจะหายทันที
|
|
|
|
ผลตรวจ paths แยกเป็น machine-readable data ใน `battle_diagnostics/glm-gacha-group-assets.json` ส่วนผลอ่าน **ตาราง group จริง** ล่าสุดอยู่ใน `battle_diagnostics/glm-gacha-groups-current.json`: `BEGIN count=0` จน `END count=0` จึงเป็นตารางว่างที่อ่านจบแล้ว ไม่ใช่ยังไม่ได้ capture ห้ามสร้าง GroupID หรือ pool-to-group mapping โดยเอาค่า enum 1–4 มาใช้เป็น IDs
|
|
|
|
## 4. การเพิ่มตู้มีสองกรณี
|
|
|
|
### กรณี A: มี config และ asset ของตู้จริงครบใน Client
|
|
|
|
1. ใช้แถว `GachaBasicInfoConfigRow` และ group/type ที่มี provenance ตรงรุ่น ปัจจุบัน group table อ่านครบแล้วเป็น 0 แถว จึงไม่มี original group mapping ให้เปิดใช้ และยังต้องอ่าน type data ที่จำเป็นให้ครบ
|
|
2. ตรวจ prefab, tab icon ทั้งสองสถานะ และ dependency ที่ controller ใช้ ให้มีจริงใน installation
|
|
3. ประกาศตู้ผ่าน resource catalog และ verified policy ไม่ใส่ game ID/path เจาะจงลง handler
|
|
4. ส่ง GetGachaInfo ให้ใช้ ID เดียวกับแถวที่ Client resolve ได้ และ prize/detail data ตรงกับตัวที่หน้าตู้แสดง
|
|
5. ให้ DoGacha ใช้ banner mapping เดียวกัน ตรวจ request/count และจัดการ grant/sync/persistence ให้ครบ
|
|
6. ตรวจ entry/exit และ animation state จาก callback จริง ไม่แก้ด้วยการปิด Canvas หรือกล้องทุกตัว
|
|
|
|
**กรณีนี้ยังทำไม่ได้กับ limited 4 แถวปัจจุบัน เพราะผลตรวจยืนยันว่า prefab ไม่มี**
|
|
|
|
### กรณี B: ไม่มี original banner asset — ต้องทำ custom presentation
|
|
|
|
นี่เป็นทางพัฒนาที่ตรงคำขอได้ แต่ยังไม่มี implementation สำเร็จใน source ปัจจุบัน:
|
|
|
|
1. กำหนด extension catalog แยกจาก raw captured tables โดยระบุว่าเป็น custom presentation ไม่ปลอมว่าเป็น original Client data
|
|
2. ใช้ avatar/item metadata และภาพที่ตรวจว่ามีจริงเป็นรายตัว ต้องแสดงชื่อ/ภาพตรงกับผล draw ห้ามใช้ภาพ Standard ค้างไว้แต่สุ่มเป็นตัวอื่น
|
|
3. ทำ UI/controller/binder ที่ใช้ asset ที่มีจริง อาจประกอบจากส่วนย่อยที่ตรวจแล้ว หรือทำ presentation ใหม่ที่เข้ากับระบบ UI; ไม่ใช่เพียงเปลี่ยน `Row.PrefabPath` เป็น Standard แล้วคาดว่า limited binder จะทำงาน
|
|
4. ต่อ pool/group/tab data และ selection state เข้ากับ Client โดยใช้ชนิด/enum/schema ที่ยืนยันแล้ว เก็บ custom ID mapping ใน resource ที่ตรวจความถูกต้องได้
|
|
5. ให้ Client และ server resolve ตู้เดียวกันจาก catalog เดียวกัน ก่อนรับการสุ่ม
|
|
6. ส่งผล Item/GachaItem/duplicate materials ให้ครบ และคืน transition กลับโลกเมื่อปิด
|
|
|
|
การส่ง GachaID ใหม่ที่ Client ไม่มี config **ไม่พอ**: Client ต้องสร้าง/resolve pool, type และ group ได้ด้วย การส่ง GachaID 1001 ซ้ำหลายแถวจะชน key ไม่ได้กลายเป็นตู้แยกทุกตัวละคร
|
|
|
|
ห้ามใช้สูตร `bannerID = avatarID + ค่าคงที่` หรือเดา path ของทุกตัวละครขึ้นเอง แล้วอ้างว่าเป็นตาราง Beta ให้กำหนด custom extension อย่างชัดเจนถ้าจำเป็นต้องสร้าง namespace ใหม่
|
|
|
|
## 5. สิ่งที่ Client ใช้สร้างหน้า — มีหลักฐานแล้ว
|
|
|
|
`battle_diagnostics/gacha-main-page.json` เป็นผลอ่าน bytecode ที่ไม่ execute ของ:
|
|
|
|
```text
|
|
@BakedLua/Ui/Gacha/GachaMainPage.bytes
|
|
```
|
|
|
|
### `_create_pools_panel` — prototype 26 / source line 308
|
|
|
|
ลำดับชื่อที่พบใน bytecode:
|
|
|
|
```text
|
|
GetSortedGachaGroupDatas
|
|
IsValid / IsFeatureClosed / IsSinglePoolGachaGroup
|
|
DefaultGachaPoolData.PrefabPath
|
|
sync_load_prefab
|
|
_gachaType2tabItem
|
|
create_panel / set_tab_data
|
|
```
|
|
|
|
แยกสองเส้นทาง:
|
|
|
|
- Single-pool group: โหลด `DefaultGachaPoolData.PrefabPath` แล้วสร้าง tab item ด้วย panel/binder ตาม `GachaType`
|
|
- Group: เลือกจาก `_groupID2GroupPrefab` / `_groupType2GroupPrefab` และ `_groupID2TabItem` / `_groupType2TabItem` พร้อม binder ของ group
|
|
|
|
ไม่ควรดูเพียง GetGachaInfoScRsp แล้วมองข้าม group data ที่หน้า UI ใช้จริง
|
|
|
|
### ฟังก์ชันสำคัญอื่น
|
|
|
|
- `_init_type2tab_table` prototype 8: ผูก `Normal`, `AvatarUp`, `WeaponUp`, `Newbie` กับ tab item/binder
|
|
- `_init_group_tab_prefab` prototype 9: กำหนด group prefab/controller/binder maps
|
|
- `_get_group_tab_prefab_config` prototype 10: เลือก override ด้วย GroupID แล้วจึง GroupType
|
|
- `_on_group_tab_change` prototype 31 และ `_on_tab_change` prototype 32: cache selected pool และ setup main page
|
|
- `_setup_main_page` prototype 33: setup draw/decide/top bar และ `Row.PoolName` ผ่าน `SafeSetTextID`
|
|
|
|
### Native/data types ที่ตรวจพบ
|
|
|
|
`BaseGachaPoolData` มี:
|
|
|
|
- `Row` getter/setter ชนิด `GachaBasicInfoConfigRow`
|
|
- `TypeBasicInfoRow`, `PrizeItemDatas`, `DetailItemDatas`
|
|
- `SingleDrawData`, `MultiDrawData`, `GachaTokenData`, `DecideData`
|
|
- `SyncGachaPoolData`, `_InitPrizeItemsRow`, `_InitDetailItemsRow`, `IsValid`, `IsFeatureClosed`, `PrefabPath`
|
|
|
|
`BaseGachaGroupData` มี:
|
|
|
|
- `_GachaGroupDataRow`, `_GachaPoolDataList`, `GroupID`, `GroupType`
|
|
- `AddGachaPoolData`, `GetSortedGachaPoolData`, `Sort`, `IsValid`, `IsFeatureClosed`, `HasGachaPool`
|
|
|
|
Capture ล่าสุดยืนยัน **shape** ของ `RPG.GameCore.GachaGroupDataRow`:
|
|
|
|
```text
|
|
PoolLabelIcon System.String
|
|
PoolLabelIconSelected System.String
|
|
GachaIDList System.UInt32[]
|
|
GroupType RPG.GameCore.GachaGroupType
|
|
GroupID System.UInt32
|
|
FromBinary(reader, GachaGroupDataRow byref)
|
|
```
|
|
|
|
ต่อจาก metadata ได้ตาม native chain และอ่าน flat GetAll ของตารางนี้ครบแล้ว:
|
|
|
|
```text
|
|
GachaGroupDataRow.FromBinary RVA 0x1e853750
|
|
-> wrapper RVA 0x1e853700
|
|
-> Add dictionary RVA 0x1e853950
|
|
-> flat GetAll RVA 0x1e852f20
|
|
BEGIN count=0
|
|
END count=0
|
|
```
|
|
|
|
หลักฐาน `ev_551674df9f28f4fc92485a8b8f3490795a8296564ee586fe356b16bca00e0b8b`, ข้อมูล `battle_diagnostics/glm-gacha-groups-current.json` และ assembler files `glm-gacha-group-add.asm`, `glm-gacha-group-dictionary.asm`, `glm-gacha-group-flat-getall.asm` ผูกกับ SHA ปัจจุบัน
|
|
|
|
**ตาราง group ที่ตรวจนี้ว่างจริง ณ capture** ไม่ได้แปลว่า Lua/UI ไม่มีโค้ดรองรับ groups แต่ไม่มี GroupIDs หรือ GachaIDList ให้ใช้เป็น original mapping อย่าอ่านค่า enum เป็น GroupID หรือเอาข้อมูลของ reference รุ่นเก่ามาเติมแล้วเรียกว่า Beta ปัจจุบัน
|
|
|
|
RVAs ข้างบนใช้บันทึกเส้นทางหลักฐานของ assembly hash นี้เท่านั้น ไม่ใช่ค่าที่ให้ฝังใน production MethodHandle/addresses ใน log ใช้ได้เฉพาะโปรเซสที่ capture ห้ามนำ pointer เดิมกลับไปใช้หลังเปิดเกมใหม่
|
|
|
|
`GachaTypeBasicInfoRow` มี `GachaTypeID`, `GachaBar`, `DiamondID`, `ItemPrice`, `ItemCosume`, `UpPropability`, `BuyPos` ต้องอ่านค่าจริงของ type ที่ใช้ ไม่เดาค่า currency/token หรือราคา
|
|
|
|
### Lua modules ที่ควรอ่านต่อแบบเจาะจง
|
|
|
|
- `Ui.Gacha.GachaPool.DefaultGachaPoolTabItem` และ binder
|
|
- `Ui.Gacha.GachaPool.DefaultGachaAvatarGroupTabItem` และ binder
|
|
- `Ui.Gacha.GachaPool.GachaSubAvatarGroupPanel`
|
|
- `Ui.Gacha.GachaPool.GachaSubAvatarItemIconPanel`
|
|
- `Ui.Gacha.GachaPool.DefaultGachaAvatarPanel`
|
|
- `Ui.Gacha.GachaPool.DefaultGachaUpAvatarPanel`
|
|
|
|
UpAvatarPanel มี `_init_imgs`, `_setup_up_avatar_img`, `setup_view`, `_on_load` แต่การมีชื่อ module ไม่ได้พิสูจน์ว่ามี prefab ที่ใช้งานได้
|
|
|
|
## 6. Protocol fields ที่ใช้อ้างอิงได้
|
|
|
|
ต้นฉบับ `protocol/proto/StarRail.proto` แถวประมาณ 20415 เป็นต้นไป:
|
|
|
|
| Message | Field ที่มีชื่อชัด | Wire tag |
|
|
| --- | --- | ---: |
|
|
| GachaInfo | end_time / gacha_id / gacha_ceiling / begin_time | 1 / 2 / 3 / 5 |
|
|
| GachaInfo | prize_item_list / item_detail_list | 10 / 11 |
|
|
| GetGachaInfoScRsp | retcode / gacha_info_list | 1 / 15 |
|
|
| DoGachaCsReq | gacha_id / gacha_num | 4 / 15 |
|
|
| DoGachaScRsp | retcode / gacha_item_list / gacha_num / gacha_id | 1 / 2 / 6 / 13 |
|
|
| GachaItem | transfer_item_list / is_new / token_item / gacha_item | 5 / 7 / 10 / 15 |
|
|
|
|
`GachaInfo` ยังมี fields obfuscated และ GetGachaInfoScRsp มี `AKMDBPNEHDE` ชนิด `NEIMLKNMDBM` อย่าอ้างว่าเป็น group payload แน่นอนหรือเติม tag ตามการคาดเดา ต้องตาม native consumer ก่อน
|
|
|
|
ตาราง command ที่เช็กใน source อยู่ที่ `protocol/proto/upstream_cmdids.go`:
|
|
|
|
```text
|
|
CommandSourceRevision = 005d2c12db4781071f4b5b68e8f364587886a710
|
|
GetGachaInfoCsReq 1974 -> GetGachaInfoScRsp 1919
|
|
DoGachaCsReq 1931 -> DoGachaScRsp 1987
|
|
```
|
|
|
|
เลขนี้ให้เป็นหลักฐานอ้างอิงในเอกสารเท่านั้น implementation ต้องใช้ named resolver ของโปรเจกต์ ห้ามฝังตัวเลขแทนชื่อหรือรับ aliases หลายรุ่น และ source revision ไม่ใช่หลักฐานว่า native schema .54 ทุก field ยืนยันครบแล้ว
|
|
|
|
## 7. โค้ด backend ปัจจุบันและการแก้ต่อ
|
|
|
|
### จุดอ่าน catalog
|
|
|
|
`internal/common/gacha_catalog.go`:
|
|
|
|
- `LoadBrowsableGachaBanners` ใช้ verified prefabs สำหรับ GetInfo
|
|
- `LoadFeaturedGachaBanners` ยอมรับเฉพาะ basename `AvatarGacha_<avatarID>.prefab` ที่อยู่ใน policy
|
|
- ไม่สร้าง GachaID หรือ prefab paths เพิ่มเอง
|
|
- ปัจจุบันพบ Standard ได้ แต่มี `AvatarID=0` จึงไม่เปิด featured draw
|
|
|
|
ข้อควรระวังสำหรับ custom presentation: logic ที่อนุมาน avatar จาก basename ใช้กับ extension catalog ใหม่ไม่ได้เสมอไป ต้องออกแบบ explicit mapping พร้อมตรวจ provenance/asset availability แทนการเปลี่ยน regex ให้รับทุกชื่อ
|
|
|
|
### จุดตอบ GetInfo/Draw
|
|
|
|
`internal/gameserver/handlers_gacha.go`:
|
|
|
|
- GetInfo ใช้ activity schedule จาก runtime config ส่ง non-null `GachaCeiling`
|
|
- ถ้ามี featured avatar จึงส่ง prize/detail lists
|
|
- DoGacha ตรวจ banner/count และ reject ระหว่าง Battle
|
|
- ต้องมี avatar ใน imported roster และมี Eidolon resource ที่ตรง
|
|
- duplicate ให้ material ตาม configured first Eidolon cost ไม่ใช่ตัวละคร/ไอเท็มสลับมั่ว
|
|
- ส่ง material delta ใน PlayerSync และ GachaItem ตามจำนวน draws
|
|
|
|
### Persistence ที่ต้องรักษา
|
|
|
|
`GrantGachaDuplicate` อ่าน latest `freesr-data.json` ใต้ shared process/file locks แล้ว merge เฉพาะ materials ไม่สร้าง avatar ใหม่ ไม่เปลี่ยน rank/EX/Traces ไม่เขียน inventory ทับทั้งก้อน
|
|
|
|
Sandbox policy ปัจจุบัน:
|
|
|
|
```text
|
|
allowed_draw_counts: 1, 10
|
|
charge_currency: false
|
|
duplicate_reward: configured_first_eidolon_cost
|
|
```
|
|
|
|
นี่ไม่ใช่ official probability/price model หากจะเปิด acquisition ของ avatar ที่ยังไม่มี ต้องทำ valid avatar/item sync และ targeted persistence เพิ่ม ยังไม่มีเส้นทางนั้นในโค้ดนี้
|
|
|
|
ไม่ควรเปลี่ยน DoGacha ให้ตอบ success พร้อมผลว่างเพื่อให้ spinner หยุด เพราะจะไม่ตรงจำนวน draws และ state ของ Client
|
|
|
|
## 8. อ่าน bytecode ต่ออย่างไร
|
|
|
|
Client นี้ใช้ `xluau.dll` มี Luau v4/type1 bytecode ไม่ใช่ LuaJIT:
|
|
|
|
- `string.dump` ไม่มี และ `jit.util` ใช้ไม่ได้
|
|
- มี `debug.getupvalue`, `debug.getinfo`, `debug.info`, `package.loaders`
|
|
- รอบที่เก็บ GachaMainPage ใช้ package loader เพื่อรับ closure โดย **ไม่ execute closure และไม่แทน package.loaded** แล้ว passive hook `xluaL_loadbuffer` เก็บ bytes
|
|
- อย่าเอา callback/module execution ไปปนกับการอ่านข้อมูล หรือ reload หน้าขณะผู้ใช้สู้
|
|
|
|
เก็บไว้แล้ว:
|
|
|
|
```text
|
|
battle_diagnostics/gacha-main-page.luau
|
|
battle_diagnostics/gacha-main-page.hex
|
|
battle_diagnostics/gacha-main-page.json
|
|
tools/inspect_luau_v4.py
|
|
```
|
|
|
|
ตัวอย่างอ่านไฟล์ capture offline จาก root โปรเจกต์:
|
|
|
|
```text
|
|
python tools/inspect_luau_v4.py battle_diagnostics/gacha-main-page.luau --output battle_diagnostics/gacha-main-page.json
|
|
```
|
|
|
|
Parser อ่าน version/type ที่รองรับเท่านั้น และตรวจว่าใช้ bytes ครบ ไม่ execute chunk เป็นเครื่องมือวิเคราะห์ ไม่ใช่ gameplay test และไม่ใช่ decompiler ที่ยืนยันความหมายทุกคำสั่ง
|
|
|
|
Layout reference: Luau upstream `VM/src/lvmload.cpp`, `Common/include/Luau/Bytecode.h` สำเนาอยู่ใน diagnostics ประกอบการตรวจ format
|
|
|
|
REA evidence ของ capture: `ev_57f147cb094af2060be82f5110e378d25ff2179f0390c56348368a855e7658b8` ขนาด GachaMainPage 23630 bytes ไม่มี message truncation ใน capture นี้
|
|
|
|
ทุก `.lua` ใน `scripts/` ถูกส่งเข้า Client อัตโนมัติ temporary probes ต้องอยู่ใน `tools/` เมื่อไม่ได้ใช้งาน จำกัดเฉพาะ types/functions ที่ระบุและ pause ระหว่าง Battle ห้ามสแกนทุก assembly type/method บน main thread
|
|
|
|
ณ จุดส่งต่อ probes ที่ใช้รอบนี้ถูกถอดจาก `scripts/` และ Frida sessions ปิด/detach แล้ว ไม่ได้ kill Client
|
|
|
|
## 9. เช็กลิสต์รับงานต่อ
|
|
|
|
- [ ] อ่าน package/manifest คู่กับ GLM-BETA-DATA เพื่อไม่ปน .53 และ .54
|
|
- [ ] ตัดสินทาง custom presentation โดยยอมรับว่า limited และ generic group prefabs ที่เช็กทั้งหมดไม่มีใน installation นี้
|
|
- [ ] ใช้ผล group table ที่อ่านจบแล้ว 0 แถวเป็นข้อจำกัดของ original config; อ่าน type data และ consumer ของ fields obfuscated ที่ยังจำเป็น ก่อนออกแบบ custom mapping
|
|
- [ ] ทำ explicit banner/avatar/presentation mapping ให้ Client และ backend ตรงกัน
|
|
- [ ] ตรวจ selected portrait/tab/icon/material dependencies เป็นราย resource ไม่เดาชื่อไฟล์
|
|
- [ ] รองรับ 1/10 draws และ duplicate/acquisition ตามขอบเขตที่ประกาศ
|
|
- [ ] รักษา progression/EX false/material delta และป้องกัน stale session ทับ API
|
|
- [ ] ทำ close/exit ให้คืน world/UI transition ไม่ค้างดำ
|
|
- [ ] ตามคำสั่งผู้ใช้ล่าสุด: ไม่เพิ่มหรือรัน tests และไม่วนให้ผู้ใช้ลองทีละ handler; ระบุส่วนที่ยังไม่มี Client confirmation ตามจริง
|
|
|
|
**จุดสรุปให้ GLM:** Backend ส่วนหนึ่งพร้อมแล้ว แต่การเปิดตู้ตัวละครจริงใน Beta นี้ติด presentation/config mapping และ assets ที่ไม่อยู่ใน installation การมี GachaInfo response หรือเพิ่ม allowlist อย่างเดียวไม่ใช่การทำฟีเจอร์เสร็จ
|