Update GaCy-GO

This commit is contained in:
CAtlas0784 committed 2026-10-28 18:54:43 +07:00
1 parent da8a32f60d
commit 0cbe460e49
345 files changed
+98202 -77559

No files matched your search

+61 -9
View File
@@ -39,9 +39,9 @@ Catalog มีตารางเส้นทางจาก Client ครบช
`POST /api/freesr/data` รวมเฉพาะฟิลด์ที่ส่งมาและรวมรายการ avatar ตามรหัส ส่วน `PUT` ใช้แทนข้อมูลทั้งชุดและต้องมี `avatars`, `lightcones`, `relics`, `battle_config` ครบ การบันทึกตรวจ roster/ทีมก่อนเขียนแบบ atomic และไม่เขียน `persistent` กลับจากการอ่านข้อมูล ใช้ SDK และ Game server build ที่มีการป้องกันนี้ทั้งคู่
1. ใช้ Windows กับ PowerShell และอินเทอร์เน็ตสำหรับ build ครั้งแรก Launcher ตรวจ Go ตามเวอร์ชันขั้นต่ำใน `go.mod`; ถ้าไม่มีหรือเก่าเกินไป จะดาวน์โหลด ZIP จากรายการรุ่นทางการ ตรวจ SHA-256 แล้วติดตั้งใน `launcher.go_install.directory` โดยไม่ต้องใช้สิทธิ์ผู้ดูแล ดู [การติดตั้ง Go](https://go.dev/doc/install) และ [รายการไฟล์ทางการ](https://go.dev/dl/?mode=json)
1. ใช้ Windows กับ PowerShell และอินเทอร์เน็ตสำหรับ build ครั้งแรก Launcher ตรวจ Go ตามเวอร์ชันขั้นต่ำใน `go.mod`; ถ้าไม่มีหรือเก่าเกินไป จะถามก่อนดาวน์โหลด ZIP จากรายการรุ่นทางการ ตรวจ SHA-256 แล้วติดตั้งใน `launcher.go_install.directory` โดยไม่ต้องใช้สิทธิ์ผู้ดูแล ดู [การติดตั้ง Go](https://go.dev/doc/install) และ [รายการไฟล์ทางการ](https://go.dev/dl/?mode=json)
2. เตรียม Client, launcher/proxy และการ redirect dispatch ให้เชื่อมต่อเซิร์ฟเวอร์ที่กำหนดใน `server.json`
3. เก็บไฟล์ข้อมูลและโฟลเดอร์ `resources` ไว้ใน root ของโปรเจกต์ และตั้งค่า launcher ตามหัวข้อ config ด้านล่าง
3. สำหรับ binary ปกติ ให้เก็บไฟล์ข้อมูลและโฟลเดอร์ `resources` ไว้ใน root ของโปรเจกต์; ถ้าต้องการแพ็กส่ง ให้ใช้ binary ใน `for ship` ซึ่งฝัง runtime resources ไว้แล้ว
4. เปิด `run.bat` แล้วเลือกเมนูที่ต้องการ
| เมนู | การทำงาน |
@@ -54,6 +54,7 @@ Catalog มีตารางเส้นทางจาก Client ครบช
| `6` | Build ทั้งสอง `.exe` อย่างเดียว |
| `7` | ออก |
| `8` หรือ `stop` | หยุดเซิร์ฟเวอร์ของโปรเจกต์นี้ |
| `9` หรือ `requirements` | ตรวจ Go สำหรับ build และถามก่อนติดตั้งเมื่อไม่พบรุ่นที่รองรับ |
เมนู 1 และ 6 หยุดเมื่อ build ไม่ผ่าน ส่วนเมนู 2–5 ใช้ binary ที่มีอยู่ หลังแก้ซอร์สจึงต้อง build ใหม่ก่อนใช้เมนูเหล่านั้น
@@ -88,7 +89,7 @@ SDK และ game server เปิดหน้าต่างคอนโซล
เปลี่ยน username และ UID ได้ที่เดียวใน `server.json`: `account_name` คือชื่อทั้งบัญชีและในเกม ส่วน `player_uid` คือ UID (ปัจจุบัน `52022`) ถ้าต้องการค่าเฉพาะเครื่อง ให้ใส่สองคีย์นี้ใน `server.local.json` แทน หลังแก้ให้รีสตาร์ตทั้ง SDK และ game server แล้วออกจากบัญชีและ login ใหม่เพื่ออัปเดตชื่อที่ Client cache ไว้ ไม่ต้องแก้ซอร์สหรือไฟล์เซฟเพื่อเปลี่ยนสองค่านี้
`run.bat requirements` เตรียม Go อย่างเดียว ส่วนเมนู build เรียกขั้นตอนนี้อัตโนมัติ การรัน executable ที่ build แล้วไม่ต้องมี Go ติดตั้งในเครื่อง ตั้ง `launcher.go_install.enabled=false` เพื่อใช้ Go ที่ติดตั้งเองเท่านั้น URL ของ manifest/ดาวน์โหลดและโฟลเดอร์ติดตั้งอยู่ใน `server.json` และ override ผ่านไฟล์ local ได้ ไม่มี path โปรแกรมเฉพาะเครื่องฝังใน launcher โฟลเดอร์ `.runtime/` และ receipt ของ toolchain ไม่ถูก commit
`run.bat requirements` ตรวจ Go และถามก่อนดาวน์โหลด/ติดตั้งเมื่อไม่พบรุ่นที่รองรับ ส่วนเมนู build เรียกตรวจสอบนี้อัตโนมัติ การรัน executable ที่ build แล้วไม่ต้องมี Go ติดตั้งในเครื่อง ตั้ง `launcher.go_install.enabled=false` เพื่อใช้ Go ที่ติดตั้งเองเท่านั้น URL ของ manifest/ดาวน์โหลดและโฟลเดอร์ติดตั้งอยู่ใน `server.json` และ override ผ่านไฟล์ local ได้ ไม่มี path โปรแกรมเฉพาะเครื่องฝังใน launcher โฟลเดอร์ `.runtime/` และ receipt ของ toolchain ไม่ถูก commit
เมื่อเปลี่ยนเครือข่ายให้ตั้งทั้ง bind และค่าที่ประกาศให้ Client เข้าถึงได้ โดยเฉพาะ port ใน `public_sdk_url` เมื่อ SDK รับการเชื่อมต่อโดยตรง ค่าเหล่านี้มีค่าเริ่มต้นอยู่ในไฟล์ config และไม่มี fallback เครือข่ายในโค้ด ต้องรีสตาร์ตเซิร์ฟเวอร์หลังเปลี่ยน config การเปลี่ยน `client_version` ไม่ได้แปลง protocol หรือทรัพยากรของเกมให้อัตโนมัติ
@@ -103,13 +104,18 @@ SDK และ game server เปิดหน้าต่างคอนโซล
- เมื่อไม่ได้เชื่อมต่อ GaC-Srtool เซิร์ฟเวอร์จับคู่ EventID ของมอนในฉากกับ PlaneEvent ของ Client แล้วใช้ StageConfig ของด่านนั้น ทั้งตอนโจมตีมอนและตอนมอนโจมตีผู้เล่น ไม่มีการใช้รายการมอน Custom จากไฟล์เก่าเป็น fallback หากไม่มีข้อมูลตรงรุ่นจะคืน error พร้อม log
- `resources/WorldBattleConfig.json` เก็บ PlaneEvent/Cocoon ที่อ่านจาก Client พร้อมเวอร์ชันและ hash ของ assembly; `world_level` เป็นระดับบัญชีที่ใช้งานร่วมกันใน login/ฉาก/Battle ตารางนี้ต้องส่งออกใหม่เมื่อเปลี่ยน Client หรือชุด resource
- GaC-Srtool ส่ง `POST /api/tool-session` พร้อม `client: "GaC-Srtool"` และ `connected: true` แล้วต่ออายุตาม `srtool.lease_seconds` จึงเปิดใช้ Custom monsters ได้ การปิดเว็บ/ขาดการเชื่อมต่อทำให้ lease หมดอายุ โดยเก็บไฟล์ชั่วคราวตาม `srtool.lease_file` ต้องใช้เว็บฉบับที่รองรับการต่ออายุนี้และ reload เว็บหลังอัปเดต
- Challenge ที่กำลังเล่นใช้ config ของโหมดและห้องนั้น มีลำดับเหนือ Custom monsters
- หน้า Monster Setting แสดงชื่อกลุ่ม/มอนสเตอร์และรูปจาก Nanoka โดยดึงข้อมูลตาม `client_version` ใน runtime config พร้อม stage และ wave จาก `challenge_data.json`/`resources/StageConfig.json`; metadata จะรีเฟรชเป็นระยะและไม่สลับไปใช้ข้อมูล Client เวอร์ชันอื่นเมื่อแหล่งข้อมูลไม่พร้อม
- รายการ Monster Setting เป็นแบบอ่านอย่างเดียวสำหรับ Memory of Chaos, Pure Fiction, Apocalyptic Shadow และ Anomaly Arbitration; Aha's Help ตั้งค่าผ่าน API แยกในแท็บของตัวเอง ไม่ใช้ custom monster waves
- ตัวเลือกรอบ AA เก็บกลุ่มที่เลือกไว้ใน `persistent.aa_round_selection` จนกว่าจะเลือกกลุ่มอื่นหรือล้างค่า; heartbeat ขอข้อมูล Anomaly Arbitration ใหม่ผ่าน `ChallengePeakModule.SendGetChallengePeakDataRequest()` ของ Client เมื่ออยู่นอก Battle/รอบที่เล่นค้างไว้ และรอให้ `CurrentPeakGroupID` ตรงก่อนถือว่าซิงก์แล้ว ห้อง/บอสภายในรอบยังเลือกจาก UI ในเกม โดยไม่เปลี่ยน PeakID ของคำขอเก่าไปเป็นห้องอื่น
- `battle_config.monsters` จาก Srtool ใช้ได้เมื่อ tool-session lease ยัง active และ request เป็น CocoonType Calyx (Golden/Crimson) เท่านั้น Stagnant Shadow, Cavern of Corrosion, weekly bosses และ challenge stages ใช้ stage resources ของ Client ตามปกติ
- Quick Cocoon ที่ส่งจำนวน wave เป็นศูนย์ตีความเป็นหนึ่งชุดด่านตามพฤติกรรม request ที่เก็บได้ ยังต้องตรวจผลใน Client สำหรับ Calyx แต่ละประเภทหลังปรับเส้นทางนี้
`resources/PropInteractionConfig.json` ระบุวัตถุทำลายได้จาก Prop ของ Client ส่วนก้อนฟื้น Technique MP ใช้นโยบายเพิ่ม 2 จาก reference server ที่ระบุในไฟล์และจำกัดไม่เกินเพดานทีม ระบบฟื้น HP/สุ่ม buff จากวัตถุยังรอข้อมูลกราฟของ Client จึงยังไม่อ้างว่ารองรับครบ
Hide UI ใช้ปุ่ม Backslash เพื่อซ่อน HUD รวม CanvasGroup ย่อยใน Battle และเก็บชื่อเซิร์ฟเวอร์/UID ไว้ หน้าต่าง Eidolon ซ่อน controls โดยไม่ปิดกล้องหรือภาพประกอบ การเปลี่ยน Lua มีผลผ่าน heartbeat; ผลใน Battle และหน้าต่าง EX ต้องตรวจจาก Client อีกครั้ง
Ping colors อยู่ใน `scripts/ping_rainbow.lua` เปลี่ยนสีทั้งแท่งสัญญาณและตัวเลขโดยใช้ค่า ping จริง ภาพหลอดใช้ alpha จาก sprite เดิมและสีพื้นขาวเพื่อไม่ให้สีเพี้ยน ส่วนตัวเลขลงสีที่ glyph โดยไม่เขียนข้อความทับ จึงไม่กะพริบเมื่อค่าเปลี่ยน ผู้ใช้ยืนยันผลหน้าเดินแล้ว รายละเอียดและขอบเขตอยู่ใน `docs/ping-colors.md`
`resources/PlayerCosmetics.json` ใช้รายการ PlayerOutfit และ AvatarSkin ที่อ่านจาก Client การปลดของแต่งผู้บุกเบิกส่งไอเท็มเป็นเจ้าของครั้งละหนึ่งชิ้นใน GetBag ส่วนชุดที่เลือกผ่าน SetPlayerOutfit เก็บใน `persistent.player_outfits` และส่งกลับเมื่อ login ใหม่ ค่า Outfit ID ที่สวมรับจาก selector ของ Client โดยตรงและ sync ตามโครงสร้าง PearlSR; ยังไม่ได้ export ตารางจับคู่ OutfitID/ItemID จึงไม่แปลงเลขด้วยสูตร
ข้อมูลฉากที่ปรับรอบนี้จำกัดที่ Starfroster กับ Moment of Joy ใน `resources/SceneMetadata.json`: อัปเดตกลุ่ม/prop ที่ยังมีอยู่และเป็นของ Server พร้อม SavedValues จาก `RuntimeDimension.DefaultValue` จึงไม่ใช้ MaxValue เป็นค่าเริ่มต้นของสองแมพนี้ กลไกรถไฟเป็น prop ฝั่ง Client และมีตัวแปร FSV_Coaster ในตารางปัจจุบัน ผลการแสดงฉากและปุ่มรถไฟยังต้องยืนยันในเกม ส่วนแมพอื่นยังใช้ข้อมูลเดิม ไม่ได้อ้างว่าอัปเดตทั้ง resource แล้ว
@@ -125,7 +131,7 @@ Hide UI ใช้ปุ่ม Backslash เพื่อซ่อน HUD รว
| `gameserver-go.exe` | รับการเชื่อมต่อเกมผ่าน KCP และจัดการผู้เล่น ฉาก และ battle | UDP ตาม `game_port` |
| `sdkserver-go.exe` | Dispatch, login, ข้อมูล hotfix และ REST API | HTTP ตาม `sdk_port` |
การเปิดระบบครบต้องรันทั้งสองตัว `.exe` ที่ build เสร็จจะอยู่ใน root ของโปรเจกต์ ให้เปิดจาก root เพื่อให้เซิร์ฟเวอร์หาไฟล์ข้อมูลและบันทึก log ได้ถูกตำแหน่ง
การเปิดระบบครบต้องรันทั้งสองตัว `.exe` ปกติจะอยู่ใน root ของโปรเจกต์และอ่านไฟล์จาก root นั้น
## Build และรันเอง
@@ -136,6 +142,16 @@ go build -o gameserver-go.exe ./cmd/gameserver
go build -o sdkserver-go.exe ./cmd/sdkserver
```
การ build ผ่าน `run.bat` จะสร้าง binary ปกติไว้ที่ root และ binary แบบแพ็กส่งไว้ที่ `for ship/` ทุกครั้ง ส่วน build แบบแพ็กส่งด้วยมือใช้ `-tags ship`:
```powershell
New-Item -ItemType Directory -Force 'for ship' | Out-Null
go build -tags ship -o 'for ship/gameserver-go.exe' ./cmd/gameserver
go build -tags ship -o 'for ship/sdkserver-go.exe' ./cmd/sdkserver
```
โฟลเดอร์ `for ship` มีเฉพาะ `.exe` หลัง build; resource, Lua ที่ดูแลในโปรเจกต์ และไฟล์ตั้งต้น `server.json`, `freesr-data.json`, `persistent`, `hotfix.json`, `versions.json` ถูกฝังไว้ใน binary เมื่อเปิด executable จะใช้โฟลเดอร์ที่วาง executable เป็น working directory และสร้างไฟล์ตั้งต้นที่ยังไม่มี โดยไม่เขียนทับ config หรือเซฟที่มีอยู่แล้ว `server.local.json` ไม่ได้ฝังและยังใช้ override เฉพาะเครื่องได้ ไฟล์ resource ที่วางข้าง executable มีสิทธิ์ override ข้อมูลที่ฝังไว้ การตั้งค่าใน `server.json` ที่สร้างขึ้นมาจะยังเป็นค่าเริ่มต้นของโปรเจกต์ ให้แก้ host ที่ Client ต้องเชื่อมต่อก่อนเปิดให้เครื่องอื่นใช้
เปิดคนละ terminal:
```powershell
@@ -163,7 +179,7 @@ go test ./...
| `freesr-data.json` | ตัวละคร, lightcone, relic และ `battle_config` |
| `persistent` | ทีม, ตำแหน่ง, ฉาก และค่าผู้เล่นที่บันทึกไว้ |
| `res.json` | ข้อมูลฉากหลักในรูปแบบที่ Go loader ใช้ |
| `resources/` | ข้อมูลฉากและตารางประกอบ เช่น MapEntrance, MazePlane, Anchor และ StageConfig |
| `resources/` | ข้อมูลฉากและตารางประกอบ เช่น MapEntrance, MazePlane, Anchor และ StageConfig; ship build ฝังชุดนี้ไว้ |
| `teleports.json` | ตำแหน่ง teleport แยกตาม floor |
| `challenge_data.json` | ข้อมูล challenge |
| `mission_unlocks.json` | ข้อมูลภารกิจและการปลดล็อก |
@@ -242,7 +258,7 @@ Damage Analyst รับ snapshot ระหว่างสู้จาก `Battl
- `SceneCastSkill` อ่านทั้ง hit targets, assist IDs และ assist groups และตอบ `MonsterBattleType=TRIGGER_BATTLE` ตาม enum ของต้นฉบับ; ค่าเริ่มต้นศูนย์หมายถึง `NONE`
- โหลดธาตุตัวละครจาก `resources/AvatarConfig.json` เพิ่มเติม เพราะ `avatarConfigs` ใน `res.json` อาจว่าง
- กฎบัฟเฉพาะตัวละคร, global passive, entry attack และ invasion อยู่ใน `resources/BattleRules.json` พร้อม upstream revision ต้องนำไฟล์นี้ไปด้วยเมื่อแจก binary; ไม่มีการฝัง ID ของกฎเหล่านี้เป็น fallback ในตัว executable
- กฎบัฟเฉพาะตัวละคร, global passive, entry attack และ invasion อยู่ใน `resources/BattleRules.json` พร้อม upstream revision; ship build ฝัง resource นี้ทั้งไฟล์ ไม่ได้ฝัง ID ของกฎเหล่านี้เป็น fallback ใน source
- Battle SP แปลงจากอัตราส่วนในข้อมูลที่นำเข้าเป็นสเกล 10000 และ HP มอนที่เป็นศูนย์คงศูนย์ตามรูปแบบ upstream
- Invasion ใช้สถานะ challenge ที่โหลดจริง `battle_config.enable_invasion_support` เปิดบัฟ support เพิ่มได้ (ค่าเริ่มต้น false)
- เลิกสร้าง Material ID ด้วยสูตร `130000 + AvatarID` ซึ่ง Client หาไม่พบ และไม่ตอบข้อมูลว่างให้โมดูล RogueTourn/ChenLing ที่ยังไม่รองรับ
@@ -300,7 +316,7 @@ scripts/ Client Lua
```powershell
python tools/sync_protocol_commands.py "<path-to-pearl-sr-checkout>"
protoc --go_out=. --go_opt=paths=source_relative protocol/proto/StarRail.proto protocol/proto/current_handlers.proto
protoc --go_out=. --go_opt=paths=source_relative protocol/proto/StarRail.proto protocol/proto/current_handlers.proto protocol/proto/ungrouped.proto
python tools/audit_protocol_handlers.py "<path-to-pearl-sr-checkout>"
```
@@ -396,7 +412,7 @@ Damage Analyst ใช้ `StatisticsComponent` ของ Battle ปัจจุ
AA cycle: แยกเวลาจำกัดของ Peak ออกจากตาราง MoC แล้ว โดยใช้ค่าที่ capture จาก Client ใน `resources/PeakBattleConfig.json` ทั้ง Start และ Restart; เก็บแพ็กเก็ตผลเต็มเพื่อจับคู่ตัวนับ AA เพิ่มเติม การแก้เลข cycle/ดาวในหน้าผลยังรอตรวจ Client รอบใหม่ ดู [docs/peak-cycle-investigation.md](docs/peak-cycle-investigation.md)
`GetFriendRecommendLineup` ส่งทีม Prydwen สำหรับ MoC floor 12 ลงใน response ของหน้าแนะนำทีม โดย resolve AvatarID จาก `resources/AvatarConfig.json` ของ Client ปัจจุบัน ข้อมูล snapshot/แหล่งที่มาและข้อจำกัดของ enum ที่ยัง obfuscate อยู่ระบุใน [docs/prydwen-endgame-recommendations.md](docs/prydwen-endgame-recommendations.md) อัปเดต snapshot ได้ด้วย `python tools/update_prydwen_endgame_teams.py --floor 12 --stage-count 3`; ต้องตรวจหน้าใน Client จริงก่อนยืนยันผล
`GetFriendRecommendLineup` ส่งทีม Prydwen สำหรับ MoC, Pure Fiction, Apocalyptic Shadow และ Anomaly Arbitration โดย resolve AvatarID จาก `resources/AvatarConfig.json` ของ Client ปัจจุบัน และอ่าน Peak IDs ของ AA จาก `ChallengePeakGroupConfig.json` ข้อมูล snapshot แหล่งที่มา และข้อจำกัดของ enum ที่ยัง obfuscate อยู่ระบุใน [docs/prydwen-endgame-recommendations.md](docs/prydwen-endgame-recommendations.md) อัปเดตทุกโหมดด้วย `python tools/update_prydwen_endgame_teams.py` หรือเลือกโหมดด้วย `--mode` ต้องตรวจ route กับหน้าใน Client จริงก่อนยืนยันผล
### CW Preparation และคำสั่งจัดการรอบ (2026-10-20)
@@ -407,6 +423,36 @@ Client ยืนยันแล้วว่าเริ่มรอบ เปิ
- `/cw status` อ่านรอบ เงิน HP และเลเวลที่เซฟอยู่
- `/cw gold <จำนวนรวม>` ตั้งเงิน CW เช่น `/cw gold 1000`
- `/cw hp <จำนวนรวม>` ตั้ง HP ภายในค่าสูงสุดของรอบ
- `/cw exp <gain>` adds EXP and applies captured level/capacity/shop-weight rules.
- `/cw list role` lists captured RoleID, AvatarID and supported stars.
- `/cw role <RoleID> <star> [count]` adds bench roles with existing star merges; a full bench cancels the whole transaction.
- `/cw list equip` lists captured equipment IDs.
- `/cw equip <ItemID> [count]` adds equipment to the CW bag.
- `/cw help` shows command syntax.
Grant and queue acknowledgement commit together with the snapshot CAS and atomic file replacement, preventing duplicate grants after a disconnect. Rejected commands log `CW_GM rejected` without saving partial grants. These lists cover captured data, not every item in the Client.
- `/cw list orb|consumable|forge` lists captured reward IDs.
- `/cw orb|consumable|forge <ItemID> [count]` grants those items during Preparation.
- Forge currently supports equipment offers only. Role/Expert forges are rejected until their pending actions are implemented.
- Orb opening, automatic combat Orb drops and consumable effects are still incomplete. Granting an item does not establish that its use works in the Client.
### Aha's Help
GaC-Srtool's Persistent settings include an independent Aha's Help selector. Levels come from `resources/AhaHelpConfig.json`, based on the supplied buff table. `GET /api/aha-help` returns available levels; `POST /api/aha-help` accepts `{"level":1}`, zero to disable, or null to use the existing FreeSR invasion-support setting. The setting is stored atomically in `persistent.aha_help_level`, preserving CW and EX state.
The selected buff applies at the start of the next battle containing an actual Corruption buff from `BattleRules.json`'s invasion mapping. This includes srtool custom battles with imported Corruption buffs. Official challenges continue to resolve their Corruption from `StageInvasionConfig.json`; reusing a stage ID alone does not inject Corruption into a custom battle. The selected level replaces other Aha support levels; explicit zero removes support for that Corruption battle. Null follows FreeSR's `enable_invasion_support`; the web selector shows whether that legacy switch is enabled. This setting is separate from Aha Global and does not change an ongoing battle. `AHA_HELP` in `server_debug.log` records the corruption and support IDs sent. The table's `BuffLevel` selects the distinct buff ID; the existing protocol buff-level encoding is retained. Progress thresholds are metadata, not an invented dynamic key. Client behavior and animations still require gameplay verification.
### Stella Jump, event previews and featured gacha
`resources/StellaJumpConfig.json` contains the 16 ChenLing GameBoy cases captured from the current Client. The sandbox exposes each case's challenge packs and saves actual best times/completions under `persistent.stella_jump`. Opening a menu is read-only. Cheats have separate saved flags; their obfuscated request/response names remain tied to the checked-in command revision and require Client verification.
`resources/ActivityPreviewPolicy.json` selects event-panel prefabs from `PreviewGameplayCatalog.json`. Additional previews are currently withheld: Client logs showed missing reward assets and invalid item lookups in ActiveActivity. Re-enable individual panels only after validating their installed assets, module identity and reward dependencies. Event-specific battles and reward claims remain incomplete.
Featured gacha candidates come from captured character-banner prefab rows. The current capture has two candidates, but the installed Client could not load the Seele prefab and left the UI transition incomplete. Runtime `AssetMgr.Exists` checks confirmed Standard and Beginner assets, but none of the four captured limited assets. `GachaSandboxPolicy.json` currently exposes only the verified Standard panel for browsing; draws return `RET_GACHA_NOT_SUPPORT` until usable featured assets are verified. An empty verified list rejects entry as well. A table row alone is insufficient evidence of an installed asset; verify the Client bundle before adding a path to that list. The grant implementation returns the pictured character and configured duplicate Eidolon material, preserving rank/EX/Traces; it is not yet verified in the Client. An avatar absent from the imported roster is rejected. The sandbox policy uses free draws and does not reproduce official rates or conversion rules.
Runtime table captures and current verification limits are recorded in `docs/offline-gameplay-continuation.md`. Compiling these handlers does not confirm the corresponding Client screens or gameplay.
คำสั่งเปลี่ยนค่าถูกคิวไว้ตาม UID/รอบ และนำเข้าใน heartbeat ตอนอยู่หน้า Preparation ไม่แก้เงิน/กระเป๋า Adventure และไม่แทรกตอน Battle ข้อความ queued ยังไม่แปลว่าเกมใช้ค่าแล้ว; ตรวจ log `CW_GM applied` หรือ `/cw status` อีกครั้ง
@@ -419,3 +465,9 @@ Client ยืนยันแล้วว่าเริ่มรอบ เปิ
เพิ่มการรวมตัวชื่อเดียวกันและดาวเท่ากันครบ 3 ตัว โดยใช้แถวดาวของ Client ที่ตรวจ identity แล้ว สร้าง UID ใหม่และเก็บตำแหน่ง/อุปกรณ์ของตัวที่คงไว้ ตัวครบชุดที่ค้างจาก build เก่าจะรวมเมื่อกด Continue; การอ่านเซฟอย่างเดียวไม่แก้ไฟล์ ระบบพื้นฐานนี้ยังไม่ครอบคลุมตัวสลับร่างและข้อยกเว้น Spotlight/trait ที่เปลี่ยนกฎรวมดาว
เพิ่มการเซฟ/ซิงก์ติดตามอุปกรณ์และลำดับติดตามจากหน้า Preparation แล้ว ใช้ข้อมูลอุปกรณ์ตรงรุ่น ทั้งการรวมดาวและการติดตามอุปกรณ์ยังรอผลยืนยันจาก Client หลังเปลี่ยน build
เพิ่มทางเข้า Plot Armor/Spotlight: ส่งรายการให้เลือกเป็น pending action, ตรวจตัวละครที่มีและความเข้ากันได้, เซฟผลกับ UID ตัวในรอบ และปิดจุดเลือกของโหนดหลังเลือกสำเร็จ การรวมดาวย้าย binding ไปตัวใหม่ นโยบายสุ่มทางเลือกอยู่ใน `resources/CurrencyWarsSpotlightPolicy.json` เป็นนโยบายเซิร์ฟเวอร์ที่ระบุไว้ชัดเจน ยังไม่ได้ยืนยันน้ำหนักสุ่ม/ค่า reroll ของต้นฉบับ ส่วนผล Spotlight ใน Battle และ progression ห้องถัดไปยังทำต่ออยู่
ผู้ใช้ยืนยันว่าเลือก Protagonist ได้แล้ว ส่วน 6900 ตอน Battle ที่ตามมาพบว่าเป็นตัวพิเศษ CW ซึ่งไม่มีใน Adventure roster เพิ่ม resolver ตาม `SpecialAvatarID` และแถว SpecialAvatar ตรงรุ่นแล้ว ขณะนี้ capture ครอบคลุม fake-avatar trial ที่ world level ตาม resource ที่ใช้ โดยยังรอผล Battle จาก Client การปลดตัวใน Adventure ไม่ใช่เงื่อนไขของตัวพิเศษนี้
CW ล่าสุด: ผู้ใช้ยืนยัน Battle ห้อง 1-2 หลังเลือก Protagonist ผ่านแล้ว เพิ่ม handler เลือก Supply แจกตัว/อุปกรณ์จาก offer จริงพร้อมรวมดาวและเซฟก่อน sync; ยังรอผล Supply ใน Client ส่วน EliteBranch/การสร้างศัตรูตาม camp และโหมดตลอดรอบยังทำไม่ครบ