Added Mystery Box Support

Added the event specific Mystery Box support to the exporter. Closes #7
This commit is contained in:
Golumpa 2026-07-16 00:50:14 +01:00
parent 2b33ea63af
commit 9eae9b4a15
24 changed files with 627 additions and 19 deletions

View file

@ -15,7 +15,7 @@ decoder-only offsets.
"capture_source": "npcap",
"exporter": {
"name": "nte-history-exporter",
"version": "0.1.10"
"version": "0.1.11"
},
"banner": {
"id": "Lottery_Permanent",
@ -71,6 +71,8 @@ Current stable pool IDs:
- `Lottery_LimitedCharacter`: Limited Character Board. New limited character
banners should still use this ID while they share the same history/pity pool.
- `Arc_MiracleBox`: Arc Miracle Box.
- `Gashapon_MysteryBox`: Mystery Box. Records are single pulls and history is
not split into event rotations by the exporter.
Avoid using `banner.name`, `reward_name`, `reward_type` or `reward_rank` as primary IDs. They
are useful display fields, but may change when mapping files are updated.
@ -110,6 +112,9 @@ Arc source:
nte|gashapon|pool_group_id|timestamp_raw|timestamp_group_ordinal
```
Mystery Box uses the same Gashapon UID source. Reward quantity is preserved,
but each record represents exactly one pull and has `result_type = single_pull`.
## Example records
Monopoly:
@ -146,6 +151,24 @@ Arc:
}
```
Mystery Box:
```json
{
"uid": "2610c6e96afd64aa4a53fb9e8cebe031",
"pool_group_id": "Gashapon_MysteryBox",
"timestamp": "2026-07-08 19:09:33",
"timestamp_group_ordinal": 0,
"result_type": "single_pull",
"reward_type": "item",
"reward_id": "vehicle039",
"reward_name": "Draco",
"reward_rank": "S",
"quantity": 1,
"source_type": "mystery_box"
}
```
## CSV diagnostics
CSV exports are mainly for debugging the decoder. Tools should prefer JSON

View file

@ -1,10 +1,11 @@
# Limitations
This is a prototype and supports `Lottery_Permanent`, `Lottery_LimitedCharacter`, and `Arc_MiracleBox`.
This is a prototype and supports `Lottery_Permanent`, `Lottery_LimitedCharacter`, `Arc_MiracleBox`, and `Gashapon_MysteryBox`.
Known limitations:
- Other NTE banners are not implemented yet.
- Mystery Box history does not expose a semantic rotation ID in each decoded row. The exporter deliberately keeps one unsplit history stream and leaves rotation grouping to consumers.
- The game appears not to provide a unique server-side roll ID in the decoded record body.
- UIDs are generated deterministically from decoded fields and timestamp-group order.
- A partially captured oldest timestamp group is still exported; its captured prefix has stable UIDs, and a later deeper scan adds the rest with the same UIDs.

View file

@ -76,6 +76,13 @@ from the committed reward mappings. It still writes the staged artifacts.
- Other pull rewards are selected by `GachaIllustrate` and resolved to the
inventory tables for quality and localization keys. Appearance-table IDs
provide canonical casing for glider rewards.
- Mystery Box rewards are selected from every row in
`DT_GashaponLotteryGlobal`. No event IDs are hard-coded, so future rotations
are included automatically. Rewards resolve through the inventory, capital,
appearance, and vehicle-item tables using case-insensitive IDs.
- Fashion, avatar-frame, and business-card Mystery Box rewards are categorized
as cosmetics; other Mystery Box rewards, including vehicle keys and
currencies, are categorized as items.
- Names are resolved strictly through `Localization/en/game.json`. A missing or
ambiguous key fails the update instead of falling back to a DT value.
- Character-awakening illustration entries are not independent pull rewards

View file

@ -1,6 +1,6 @@
# Packet Format Notes
This prototype supports separate Monopoly and Arc/Gashapon history decoders.
This prototype supports separate Monopoly, Arc/Gashapon, and Mystery Box history decoders.
## Decoder strategy
@ -105,3 +105,15 @@ Pages are anchored to the continuous run starting at page 1 (history always load
- Arc timestamps use `unix_seconds = little_endian_u64(timestamp_raw) / 20000000 - 62135596800`.
- Arc pulls are treated as 10-pull timestamp groups. Like Monopoly, every captured group is exported, including the oldest one even if the scan stopped mid-10-pull (its captured prefix is ordinal-stable).
- Arc rows use the same `reward_type`, `reward_id`, `reward_name`, `reward_rank`, and `reward_key_hex` fields as Monopoly rows.
## Mystery Box
- Mystery Box requests use a 54-byte prefix.
- Request constant: `2060` / `0x080c` at offset 26.
- Request kind: `2110` / `0x083e` at offset 35.
- Request cursor: offset 31, with a step of `2`; page is `cursor / 2`.
- Responses contain an `FGashaponLotteryRecordData` structured block.
- Each row contains the reward ID, exact quantity, a record flag, and a standard .NET timestamp.
- Every row is one single pull regardless of its reward quantity.
- A full response page contains 5 rows; the final page may contain 1–4 rows.
- History is exported under `Gashapon_MysteryBox` without attempting to infer or split rotations.