Nebula invasion receiver: decode get-state lineup into Incident#370
Merged
Conversation
Validated against production get-state: the opponent's active pokemon has its species revealed but the reserves carry PokedexId 0 at the opening state. The old code wrote those as pokemon id 0; write NULL instead so an unknown reserve isn't mistaken for "pokemon #0". Slot 1 (the lead) is reliably populated. Also de-provisionalises the opponent-selection comment now that NPC/NPC_BOSS is confirmed correct against real payloads. Adds a hidden-reserve test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BattlePokemonProto carries Display.Form; the legacy OpenInvasion lineup path set slot_N_form from it but updateFromBattleState only set the pokemon id. Set the form alongside the species (form 0 = default form is a valid value), restoring parity with the old flow. Only set when the species is known. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Print the resolved slot pokemon/form after extraction so the decoded lineup is visible in logs during validation without a DB round-trip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The invasion webhook emitted all three slots whenever slot 1 was set, so
nebula lineups (which know only the lead pokemon) produced
{"slot":2,"pokemon_id":null,"form":null} noise. Build the lineup from only
the slots with a known pokemon. Full lineups (old OpenInvasion flow) are
unchanged; partial ones drop the null reserves.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7fe204f to
5a80876
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Receiver side of Invasion Scanning V2: decode Nebula HTTP battle responses (forwarded by Dragonite) into the existing invasion-lineup storage.
NebulaContentmessage +nebula_contentsfield togrpc/raw_receiver.proto(byte-identical to the Dragonite copy), with aoneof context { InvasionContext invasion }.nebula_contentsfrom both the gRPC (SubmitRawProto) and HTTP (/raw) inbound paths into a typedNebulaData.decodeNebularoutes on the contextoneofcase (invasion now; raid/max are logged no-ops until built) and the endpoint;get-statedecodesBattleStateOutProto, extracts the opponent actor's roster, and writes the existingIncidentfields (slot_1/2/3_pokemon_id+confirmed) via the existing write-behind path. No DB schema changes — reuses the columns/webhook/API already in place.Notes for reviewers
get-statepayload yet, it matches actors of typeNPC/NPC_BOSSand orders slots best-effort. The decoder emits verbose debug logging of every actor (id/type/team/active/roster) precisely so this can be validated/corrected against production data before relying on the lineups.Test Plan
go build ./...cleango test . ./decoder/ ./grpc/pass (context dispatch,BattleStateOutProto→ Incident slot extraction, proto wire round-trip)get-statepayload from the debug logs and confirm the opponent/slot mapping is correct🤖 Generated with Claude Code