Commit Graph

17 Commits

Author SHA1 Message Date
gamer147
b3df361f6d feat(loader): add EnableSpinProbe diagnostic for the spin investigation
Logs {event,uri,spin,count} per battle frame to spin-rng.ndjson, where
count is BattleManagerBase.stableRandomCount (cumulative shared-RNG draws,
read before the spin crank). Lets us compare per-turn local draw deltas
against the inbound spin to determine whether prod authors spin from
server-side simulation or it is wire-derivable bookkeeping.

- SpinProbe.cs: HarmonyPrefix on OperateReceive.StartOperate (receive,
  pre-crank) and NetworkBattleSender.EmitMsg (send); stableRandomCount
  read reflectively via AccessTools.
- CaptureWriter.AppendSpinProbe -> spin-rng.ndjson.
- SvSimConfig.EnableSpinProbe + Plugin.cs Config.Bind (default off).

See docs/audits/battle-node-spin-rng-model-2026-06-04.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 13:24:24 -04:00
gamer147
620ae31582 style(loader): file-scoped namespace + silence Harmony003 false positive 2026-06-03 09:17:37 -04:00
gamer147
800e40344b feat(loader): mutex-skip + per-instance identity + synthetic Steam identity patches
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 09:14:36 -04:00
gamer147
5bc7d6f184 feat(loader): read SVSIM_INSTANCE_ID and derive per-instance identity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 09:12:49 -04:00
gamer147
f0c422aa8f feat(loader): file-backed per-instance identity store 2026-06-03 09:11:13 -04:00
gamer147
44c370d7a8 docs(svsimloader): update data_dumps path references for reorg
Mirror of the outer-repo data_dumps/ reorganization: README now points
at data_dumps/captures/ for traffic_prod.ndjson; the GachaExchangeSweep
comment naming the tradeables capture follows the same path rewrite.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 01:22:59 -04:00
gamer147
d4c4a1386f Merge branch 'progression-import-export'
Brings four feature commits onto master:
- export owned cards, decks, items; fix rupy currency key
- descend into envelope data key in user-data dump
- skip empty deck slots in user-data export
- GachaExchangeSweep over full master pack list

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 19:09:18 -04:00
gamer147
6426c0af77 feat(loader): GachaExchangeSweep over full master pack list
Replaces LeaderSkinPoolSweep. The old sweep drove from /pack/info's
pack_config_list (35 in-catalog packs), missing the off-catalog families
(Throwback, Rotation Select, Premium, anniversary) where the drawrates
parser still has 75 ambiguous card_id joins. The new sweep drives from
Wizard.Data.Master.CardSetNameMgr.GetList() — the full 279 client-master
pack ids — and persists a miss ledger at
BepInEx/svsim-captures/gacha-sweep-misses.json so re-runs skip known-dead
ids. Adds SweepDryRunIds for smoke-testing on a handful of ids before
committing the session to a full ~5min sweep. Capture path unchanged.

Design: docs/superpowers/specs/2026-05-30-gacha-exchange-sweep-design.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 18:04:02 -04:00
gamer147
3832a20aed feat(loader): skip empty deck slots in user-data export
A /load/index response carries every deck slot, mostly empty placeholders;
emit only the real (non-empty) decks so the dump is a handful of decks
instead of ~100 empty slots.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 21:03:12 -04:00
gamer147
d96a5e42c7 fix(loader): descend into envelope data key in user-data dump
WriteUserDataFromLoadIndex received the full response envelope
{ data_headers, data } but read viewer fields from the top level, so
every SafeGet missed and the dump contained only steam_id. Descend into
the inner data key first (mirrors TryExtractSpecialBattleSettings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 20:35:09 -04:00
gamer147
b454d58cf2 feat(loader): export owned cards, decks, items; fix rupy currency key
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 19:01:06 -04:00
gamer147
8c79725869 fix(loader): narrow IdentityWipe to UDID/VIEWER_ID/SHORT_UDID only
Calling PlayerPrefs.DeleteAll() in IdentityWipe.Execute wiped more
than the three account-keyed entries: it also took out RES_VER (the
Akamai manifest version path), the asset layer's cache-index metadata
in PlayerPrefs, language/sound prefs, and anything else CodeStage
ObscuredPrefs had stashed.

Two observable symptoms on every nuked launch against either a local
or a prod server:

- The client lost track of which asset bundles it had on disk, so
  ResourceDownloader.CheckAndStartNeedDownload prompted "Do you want
  to download the tutorial data? (15.8 MB)" even when the bundles
  were already cached.
- After saying yes, the follow-up
  ShowTutorialBgDownloadDialog prompted "Download data in background?
  (497.1 MB)" for the same reason against the post-tutorial assets.

Narrow IdentityWipe to call ObscuredPrefs.DeleteKey on exactly
"UDID", "VIEWER_ID", and "SHORT_UDID" — the three keys
Cute/Certification.InitializeFileds would clear in the game itself.
Everything else in PlayerPrefs survives, the cache index stays in
sync with the on-disk bundles, and a nuked relaunch behaves like a
Steam-account switch (fresh signup, intact downloads).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 18:04:44 -04:00
gamer147
8f2ddeab96 Additional functionality 2026-05-28 11:21:37 -04:00
gamer147
b1206c874d loader: patch GetDeckBuilderServerURL to point at the app server
Redirects shadowverse-portal.com deck-builder calls to SvSimConfig.ApplicationUrl
so the GenerateDeckCodeTask / GetDeckDataFromCodeTask URLs land on the emulator's
DeckBuilderController routes (/deck_code, /deck). Both client call sites already
pass encrypt:false to NetworkManager.Connect, so no additional encryption-side
patch is needed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 09:11:33 -04:00
gamer147
76b7e59489 loader: emit traffic body as nested JSON, not escaped string
Body field in traffic.ndjson / battle-traffic.ndjson is now a real nested
JSON object instead of an escaped JSON string. Parse-on-write is wrapped in
ParseBodyOrKeep with a string-fallback so a future non-JSON caller doesn't
crash the line write.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 17:42:55 -04:00
gamer147
34a17a2b6b Cleanup, addition of new captures, readme 2026-05-25 21:52:20 -04:00
gamer147
f22cc19bfc Initial commit 2024-09-08 10:32:52 -04:00