Initial NTE history exporter
Initial NTE history exporter Add a Windows live-capture exporter for NTE pull history with support for Permanent Monopoly, Limited Monopoly, and Arc Miracle Box histories. Included: - live packet capture via Windows raw sockets - CSV and JSON export generation - normalized reward and banner mapping files - Monopoly v7 Points Gift / Chase Reward classification - Arc Miracle Box decoding with shared pity metadata - timestamp grouping and UID generation - Windows launcher scripts with admin prompting - docs for usage, export format, limitations, and packet notes - tests covering decoder behaviour and mapping consistency Generated exports, captures, briefs, and local data are ignored for privacy.
This commit is contained in:
commit
bb3fe3b19a
35 changed files with 2439 additions and 0 deletions
53
docs/export-format.md
Normal file
53
docs/export-format.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Export Format
|
||||
|
||||
The sanitized JSON export uses:
|
||||
|
||||
```json
|
||||
{
|
||||
"format": "nte-history-export",
|
||||
"format_version": 1,
|
||||
"game": "Neverness to Everness",
|
||||
"source": "packet_capture",
|
||||
"exporter": {
|
||||
"name": "nte-history-exporter",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"banner": {
|
||||
"id": "Lottery_Permanent",
|
||||
"name": "Standard Board",
|
||||
"system": "Monopoly",
|
||||
"shared_pity": false
|
||||
},
|
||||
"scan": {
|
||||
"mode": "stable_only",
|
||||
"boundary_policy": "drop_incomplete_timestamp_groups",
|
||||
"decoded_records": 0,
|
||||
"exported_records": 0,
|
||||
"skipped_records": 0,
|
||||
"warnings": []
|
||||
},
|
||||
"records": []
|
||||
}
|
||||
```
|
||||
|
||||
Record UIDs are deterministic:
|
||||
|
||||
Monopoly:
|
||||
|
||||
```text
|
||||
nte|monopoly|Lottery_Permanent|timestamp_raw|timestamp_group_ordinal|roll_result|reward_key_hex|quantity
|
||||
```
|
||||
|
||||
Limited character records use `Lottery_LimitedCharacter` in the same UID source position.
|
||||
|
||||
Arc:
|
||||
|
||||
```text
|
||||
nte|gashapon|Arc_MiracleBox|timestamp_raw|timestamp_group_ordinal|reward_key_hex
|
||||
```
|
||||
|
||||
The final UID is `sha256(source).hexdigest()[0:32]`.
|
||||
|
||||
Each record includes `pool_group_id`. Arc records use the shared `reward_*` fields and include `source_type: "miracle_box"`.
|
||||
|
||||
Normal JSON exports do not include raw packets or capture-only metadata.
|
||||
17
docs/limitations.md
Normal file
17
docs/limitations.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Limitations
|
||||
|
||||
This is a prototype and supports `Lottery_Permanent`, `Lottery_LimitedCharacter`, and `Arc_MiracleBox`.
|
||||
|
||||
Known limitations:
|
||||
|
||||
- Other NTE banners are not implemented yet.
|
||||
- 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.
|
||||
- Boundary timestamp groups may be skipped to avoid exporting unstable data.
|
||||
- Page gaps are ignored outside the longest continuous run and reported as warnings.
|
||||
- Live capture currently uses Windows raw sockets and requires administrator permission.
|
||||
- The file adapter reads mitmproxy `.flows` captures for research and testing.
|
||||
- The more stable and reliable Npcap/libpcap capture is not implemented yet.
|
||||
- Reward mappings are research mappings and should be expanded as more samples are decoded.
|
||||
|
||||
Privacy guardrail: raw packet data must not be included in sanitized exports.
|
||||
40
docs/packet-format.md
Normal file
40
docs/packet-format.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Packet Format Notes
|
||||
|
||||
This prototype supports separate Monopoly and Arc/Gashapon history decoders.
|
||||
|
||||
## Monopoly
|
||||
|
||||
- History is fetched over the UDP game connection.
|
||||
- Client history-page requests are 45 bytes.
|
||||
- History request constant: `4220` / `0x107c`.
|
||||
- Request selector `4`: `Lottery_Permanent`.
|
||||
- Request selector `8`: `Lottery_LimitedCharacter`.
|
||||
- Request page cursor: `page_number * 4`.
|
||||
- Normal server responses contain 5 history records.
|
||||
- The final page may contain fewer than 5 records.
|
||||
|
||||
Decoded fields:
|
||||
|
||||
- `roll_result = first u32 / 4`
|
||||
- `roll_result = 0` means Points Gift
|
||||
- Some page-first records have a short prefix before the record body. For these, a hidden signed source flag immediately after the visible dice field overrides the visible dice:
|
||||
- `source_flag = 0` means Points Gift
|
||||
- `source_flag = -4` means Chase Reward
|
||||
- Timestamp is an 8-byte little-endian value
|
||||
- `unix_seconds = little_endian_u64(timestamp_raw) / 40000000 - 62135596800`
|
||||
- Rewards are identified by stable binary keys
|
||||
|
||||
Page and row numbers are research metadata only. They must not be used for permanent dedupe because they shift when new history appears.
|
||||
|
||||
Timestamp groups keep all records with the same raw timestamp together for UID ordinal generation. For boundary/group-size detection, only `result_type = dice` rows count as pull-set members; Points Gift and Chase Reward rows stay in the group but do not increase the dice-only group count.
|
||||
|
||||
## Arc / Gashapon
|
||||
|
||||
- Arc history uses a separate 34-byte request.
|
||||
- Request constant: `2060` / `0x080c`.
|
||||
- Cursor step: `2`.
|
||||
- Pool: `Arc_MiracleBox`.
|
||||
- Each response page normally contains 5 records.
|
||||
- Arc timestamps use `unix_seconds = little_endian_u64(timestamp_raw) / 20000000 - 62135596800`.
|
||||
- Arc pulls are treated as 10-pull timestamp groups; incomplete groups are skipped by default.
|
||||
- Arc rows use the same `reward_type`, `reward_id`, `reward_name`, `reward_rank`, and `reward_key_hex` fields as Monopoly rows.
|
||||
Loading…
Add table
Add a link
Reference in a new issue