Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 88 additions & 82 deletions decoder/api_gym.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,92 +14,98 @@ import (
// represented as pointers (nil => JSON null) without omitempty so every key is
// always present.
type ApiGymResult struct {
Id string `json:"id" doc:"Fort ID of the gym"`
Lat float64 `json:"lat" doc:"Latitude of the gym"`
Lon float64 `json:"lon" doc:"Longitude of the gym"`
Name *string `json:"name" doc:"Name of the gym"`
Url *string `json:"url" doc:"Image URL of the gym"`
LastModifiedTimestamp *int64 `json:"last_modified_timestamp" doc:"Unix timestamp when the gym was last modified in-game"`
RaidEndTimestamp *int64 `json:"raid_end_timestamp" doc:"Unix timestamp when the current raid ends"`
RaidSpawnTimestamp *int64 `json:"raid_spawn_timestamp" doc:"Unix timestamp when the current raid egg spawned"`
RaidBattleTimestamp *int64 `json:"raid_battle_timestamp" doc:"Unix timestamp when the current raid battle begins"`
Updated int64 `json:"updated" doc:"Unix timestamp when the record was last updated"`
RaidPokemonId *int64 `json:"raid_pokemon_id" doc:"Pokedex ID of the raid boss"`
GuardingPokemonId *int64 `json:"guarding_pokemon_id" doc:"Pokedex ID of the pokemon guarding the gym"`
GuardingPokemonDisplay *string `json:"guarding_pokemon_display" doc:"Display details of the guarding pokemon"`
AvailableSlots *int64 `json:"available_slots" doc:"Number of open defender slots"`
TeamId *int64 `json:"team_id" doc:"ID of the team controlling the gym"`
RaidLevel *int64 `json:"raid_level" doc:"Level/tier of the current raid"`
Enabled *int64 `json:"enabled" doc:"Whether the gym is enabled"`
ExRaidEligible *int64 `json:"ex_raid_eligible" doc:"Whether the gym is eligible for EX raids"`
InBattle *int64 `json:"in_battle" doc:"Whether the gym is currently in battle"`
RaidPokemonMove1 *int64 `json:"raid_pokemon_move_1" doc:"Fast move ID of the raid boss"`
RaidPokemonMove2 *int64 `json:"raid_pokemon_move_2" doc:"Charge move ID of the raid boss"`
RaidPokemonForm *int64 `json:"raid_pokemon_form" doc:"Form ID of the raid boss"`
RaidPokemonAlignment *int64 `json:"raid_pokemon_alignment" doc:"Alignment of the raid boss"`
RaidPokemonCp *int64 `json:"raid_pokemon_cp" doc:"Combat power of the raid boss"`
RaidIsExclusive *int64 `json:"raid_is_exclusive" doc:"Whether the current raid is exclusive (EX)"`
CellId *int64 `json:"cell_id" doc:"S2 cell ID the gym belongs to"`
Deleted bool `json:"deleted" doc:"Whether the gym has been deleted"`
TotalCp *int64 `json:"total_cp" doc:"Total combat power of the gym defenders"`
FirstSeenTimestamp int64 `json:"first_seen_timestamp" doc:"Unix timestamp when the gym was first seen"`
RaidPokemonGender *int64 `json:"raid_pokemon_gender" doc:"Gender of the raid boss"`
SponsorId *int64 `json:"sponsor_id" doc:"Sponsor ID of the gym, if sponsored"`
PartnerId *string `json:"partner_id" doc:"Partner ID of the gym, if partnered"`
RaidPokemonCostume *int64 `json:"raid_pokemon_costume" doc:"Costume ID of the raid boss"`
RaidPokemonEvolution *int64 `json:"raid_pokemon_evolution" doc:"Evolution ID of the raid boss (e.g. mega)"`
ArScanEligible *int64 `json:"ar_scan_eligible" doc:"Whether the gym is eligible for AR scanning"`
PowerUpLevel *int64 `json:"power_up_level" doc:"Power-up level of the gym"`
PowerUpPoints *int64 `json:"power_up_points" doc:"Power-up points accumulated for the gym"`
PowerUpEndTimestamp *int64 `json:"power_up_end_timestamp" doc:"Unix timestamp when the power-up ends"`
Description *string `json:"description" doc:"Description of the gym"`
Defenders *string `json:"defenders" doc:"Serialized defender pokemon data"`
Rsvps *string `json:"rsvps" doc:"Serialized raid RSVP data"`
Id string `json:"id" doc:"Fort ID of the gym"`
Lat float64 `json:"lat" doc:"Latitude of the gym"`
Lon float64 `json:"lon" doc:"Longitude of the gym"`
Name *string `json:"name" doc:"Name of the gym"`
Url *string `json:"url" doc:"Image URL of the gym"`
LastModifiedTimestamp *int64 `json:"last_modified_timestamp" doc:"Unix timestamp when the gym was last modified in-game"`
RaidEndTimestamp *int64 `json:"raid_end_timestamp" doc:"Unix timestamp when the current raid ends"`
RaidSpawnTimestamp *int64 `json:"raid_spawn_timestamp" doc:"Unix timestamp when the current raid egg spawned"`
RaidBattleTimestamp *int64 `json:"raid_battle_timestamp" doc:"Unix timestamp when the current raid battle begins"`
Updated int64 `json:"updated" doc:"Unix timestamp when the record was last updated"`
RaidPokemonId *int64 `json:"raid_pokemon_id" doc:"Pokedex ID of the raid boss"`
GuardingPokemonId *int64 `json:"guarding_pokemon_id" doc:"Pokedex ID of the pokemon guarding the gym"`
GuardingPokemonDisplay *string `json:"guarding_pokemon_display" doc:"Display details of the guarding pokemon"`
AvailableSlots *int64 `json:"available_slots" doc:"Number of open defender slots"`
TeamId *int64 `json:"team_id" doc:"ID of the team controlling the gym"`
RaidLevel *int64 `json:"raid_level" doc:"Level/tier of the current raid"`
Enabled *int64 `json:"enabled" doc:"Whether the gym is enabled"`
ExRaidEligible *int64 `json:"ex_raid_eligible" doc:"Whether the gym is eligible for EX raids"`
InBattle *int64 `json:"in_battle" doc:"Whether the gym is currently in battle"`
RaidPokemonMove1 *int64 `json:"raid_pokemon_move_1" doc:"Fast move ID of the raid boss"`
RaidPokemonMove2 *int64 `json:"raid_pokemon_move_2" doc:"Charge move ID of the raid boss"`
RaidPokemonForm *int64 `json:"raid_pokemon_form" doc:"Form ID of the raid boss"`
RaidPokemonAlignment *int64 `json:"raid_pokemon_alignment" doc:"Alignment of the raid boss"`
RaidPokemonCp *int64 `json:"raid_pokemon_cp" doc:"Combat power of the raid boss"`
RaidIsExclusive *int64 `json:"raid_is_exclusive" doc:"Whether the current raid is exclusive (EX)"`
CellId *int64 `json:"cell_id" doc:"S2 cell ID the gym belongs to"`
Deleted bool `json:"deleted" doc:"Whether the gym has been deleted"`
TotalCp *int64 `json:"total_cp" doc:"Total combat power of the gym defenders"`
FirstSeenTimestamp int64 `json:"first_seen_timestamp" doc:"Unix timestamp when the gym was first seen"`
RaidPokemonGender *int64 `json:"raid_pokemon_gender" doc:"Gender of the raid boss"`
SponsorId *int64 `json:"sponsor_id" doc:"Sponsor ID of the gym, if sponsored"`
PartnerId *string `json:"partner_id" doc:"Partner ID of the gym, if partnered"`
RaidPokemonCostume *int64 `json:"raid_pokemon_costume" doc:"Costume ID of the raid boss"`
RaidPokemonEvolution *int64 `json:"raid_pokemon_evolution" doc:"Evolution ID of the raid boss (e.g. mega)"`
RaidSeed *int64 `json:"raid_seed" doc:"Raid seed for the current raid"`
RaidPokemonStamina *int64 `json:"raid_pokemon_stamina" doc:"Stamina of the raid boss"`
RaidPokemonCpMultiplier *float64 `json:"raid_pokemon_cp_multiplier" doc:"CP multiplier of the raid boss"`
ArScanEligible *int64 `json:"ar_scan_eligible" doc:"Whether the gym is eligible for AR scanning"`
PowerUpLevel *int64 `json:"power_up_level" doc:"Power-up level of the gym"`
PowerUpPoints *int64 `json:"power_up_points" doc:"Power-up points accumulated for the gym"`
PowerUpEndTimestamp *int64 `json:"power_up_end_timestamp" doc:"Unix timestamp when the power-up ends"`
Description *string `json:"description" doc:"Description of the gym"`
Defenders *string `json:"defenders" doc:"Serialized defender pokemon data"`
Rsvps *string `json:"rsvps" doc:"Serialized raid RSVP data"`
}

func buildGymResult(gym *Gym) ApiGymResult {
return ApiGymResult{
Id: gym.Id,
Lat: gym.Lat,
Lon: gym.Lon,
Name: gym.Name.Ptr(),
Url: gym.Url.Ptr(),
LastModifiedTimestamp: gym.LastModifiedTimestamp.Ptr(),
RaidEndTimestamp: gym.RaidEndTimestamp.Ptr(),
RaidSpawnTimestamp: gym.RaidSpawnTimestamp.Ptr(),
RaidBattleTimestamp: gym.RaidBattleTimestamp.Ptr(),
Updated: gym.Updated,
RaidPokemonId: gym.RaidPokemonId.Ptr(),
GuardingPokemonId: gym.GuardingPokemonId.Ptr(),
GuardingPokemonDisplay: gym.GuardingPokemonDisplay.Ptr(),
AvailableSlots: gym.AvailableSlots.Ptr(),
TeamId: gym.TeamId.Ptr(),
RaidLevel: gym.RaidLevel.Ptr(),
Enabled: gym.Enabled.Ptr(),
ExRaidEligible: gym.ExRaidEligible.Ptr(),
InBattle: gym.InBattle.Ptr(),
RaidPokemonMove1: gym.RaidPokemonMove1.Ptr(),
RaidPokemonMove2: gym.RaidPokemonMove2.Ptr(),
RaidPokemonForm: gym.RaidPokemonForm.Ptr(),
RaidPokemonAlignment: gym.RaidPokemonAlignment.Ptr(),
RaidPokemonCp: gym.RaidPokemonCp.Ptr(),
RaidIsExclusive: gym.RaidIsExclusive.Ptr(),
CellId: gym.CellId.Ptr(),
Deleted: gym.Deleted,
TotalCp: gym.TotalCp.Ptr(),
FirstSeenTimestamp: gym.FirstSeenTimestamp,
RaidPokemonGender: gym.RaidPokemonGender.Ptr(),
SponsorId: gym.SponsorId.Ptr(),
PartnerId: gym.PartnerId.Ptr(),
RaidPokemonCostume: gym.RaidPokemonCostume.Ptr(),
RaidPokemonEvolution: gym.RaidPokemonEvolution.Ptr(),
ArScanEligible: gym.ArScanEligible.Ptr(),
PowerUpLevel: gym.PowerUpLevel.Ptr(),
PowerUpPoints: gym.PowerUpPoints.Ptr(),
PowerUpEndTimestamp: gym.PowerUpEndTimestamp.Ptr(),
Description: gym.Description.Ptr(),
Defenders: gym.Defenders.Ptr(),
Rsvps: gym.Rsvps.Ptr(),
Id: gym.Id,
Lat: gym.Lat,
Lon: gym.Lon,
Name: gym.Name.Ptr(),
Url: gym.Url.Ptr(),
LastModifiedTimestamp: gym.LastModifiedTimestamp.Ptr(),
RaidEndTimestamp: gym.RaidEndTimestamp.Ptr(),
RaidSpawnTimestamp: gym.RaidSpawnTimestamp.Ptr(),
RaidBattleTimestamp: gym.RaidBattleTimestamp.Ptr(),
Updated: gym.Updated,
RaidPokemonId: gym.RaidPokemonId.Ptr(),
GuardingPokemonId: gym.GuardingPokemonId.Ptr(),
GuardingPokemonDisplay: gym.GuardingPokemonDisplay.Ptr(),
AvailableSlots: gym.AvailableSlots.Ptr(),
TeamId: gym.TeamId.Ptr(),
RaidLevel: gym.RaidLevel.Ptr(),
Enabled: gym.Enabled.Ptr(),
ExRaidEligible: gym.ExRaidEligible.Ptr(),
InBattle: gym.InBattle.Ptr(),
RaidPokemonMove1: gym.RaidPokemonMove1.Ptr(),
RaidPokemonMove2: gym.RaidPokemonMove2.Ptr(),
RaidPokemonForm: gym.RaidPokemonForm.Ptr(),
RaidPokemonAlignment: gym.RaidPokemonAlignment.Ptr(),
RaidPokemonCp: gym.RaidPokemonCp.Ptr(),
RaidIsExclusive: gym.RaidIsExclusive.Ptr(),
CellId: gym.CellId.Ptr(),
Deleted: gym.Deleted,
TotalCp: gym.TotalCp.Ptr(),
FirstSeenTimestamp: gym.FirstSeenTimestamp,
RaidPokemonGender: gym.RaidPokemonGender.Ptr(),
SponsorId: gym.SponsorId.Ptr(),
PartnerId: gym.PartnerId.Ptr(),
RaidPokemonCostume: gym.RaidPokemonCostume.Ptr(),
RaidPokemonEvolution: gym.RaidPokemonEvolution.Ptr(),
RaidSeed: gym.RaidSeed.Ptr(),
RaidPokemonStamina: gym.RaidPokemonStamina.Ptr(),
RaidPokemonCpMultiplier: gym.RaidPokemonCpMultiplier.Ptr(),
ArScanEligible: gym.ArScanEligible.Ptr(),
PowerUpLevel: gym.PowerUpLevel.Ptr(),
PowerUpPoints: gym.PowerUpPoints.Ptr(),
PowerUpEndTimestamp: gym.PowerUpEndTimestamp.Ptr(),
Description: gym.Description.Ptr(),
Defenders: gym.Defenders.Ptr(),
Rsvps: gym.Rsvps.Ptr(),
}
}

Expand Down
17 changes: 10 additions & 7 deletions decoder/api_gym_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,15 @@ func goldenSnapshotGym() *Gym {
FirstSeenTimestamp: 1699990000,
RaidPokemonGender: null.IntFrom(1),
// SponsorId intentionally left null
PartnerId: null.StringFrom("partner-1"),
RaidPokemonCostume: null.IntFrom(0),
RaidPokemonEvolution: null.IntFrom(0),
ArScanEligible: null.IntFrom(1),
PowerUpLevel: null.IntFrom(2),
PowerUpPoints: null.IntFrom(50),
PartnerId: null.StringFrom("partner-1"),
RaidPokemonCostume: null.IntFrom(0),
RaidPokemonEvolution: null.IntFrom(0),
RaidSeed: null.IntFrom(123456789012345),
RaidPokemonStamina: null.IntFrom(15000),
RaidPokemonCpMultiplier: null.FloatFrom(0.79),
ArScanEligible: null.IntFrom(1),
PowerUpLevel: null.IntFrom(2),
PowerUpPoints: null.IntFrom(50),
// PowerUpEndTimestamp intentionally left null
Description: null.StringFrom("A test gym"),
// Defenders intentionally left null
Expand All @@ -67,7 +70,7 @@ func TestBuildGymResult_GoldenSnapshot(t *testing.T) {
t.Fatalf("marshal: %v", err)
}

const want = `{"id":"gym-abc","lat":12.3456,"lon":-65.4321,"name":"Test Gym","url":"https://example.com/gym.png","last_modified_timestamp":1699990000,"raid_end_timestamp":1700003600,"raid_spawn_timestamp":null,"raid_battle_timestamp":1700000000,"updated":1699999999,"raid_pokemon_id":150,"guarding_pokemon_id":143,"guarding_pokemon_display":null,"available_slots":3,"team_id":2,"raid_level":5,"enabled":1,"ex_raid_eligible":0,"in_battle":0,"raid_pokemon_move_1":216,"raid_pokemon_move_2":94,"raid_pokemon_form":0,"raid_pokemon_alignment":0,"raid_pokemon_cp":3500,"raid_is_exclusive":0,"cell_id":1234567890123,"deleted":false,"total_cp":12000,"first_seen_timestamp":1699990000,"raid_pokemon_gender":1,"sponsor_id":null,"partner_id":"partner-1","raid_pokemon_costume":0,"raid_pokemon_evolution":0,"ar_scan_eligible":1,"power_up_level":2,"power_up_points":50,"power_up_end_timestamp":null,"description":"A test gym","defenders":null,"rsvps":"[]"}`
const want = `{"id":"gym-abc","lat":12.3456,"lon":-65.4321,"name":"Test Gym","url":"https://example.com/gym.png","last_modified_timestamp":1699990000,"raid_end_timestamp":1700003600,"raid_spawn_timestamp":null,"raid_battle_timestamp":1700000000,"updated":1699999999,"raid_pokemon_id":150,"guarding_pokemon_id":143,"guarding_pokemon_display":null,"available_slots":3,"team_id":2,"raid_level":5,"enabled":1,"ex_raid_eligible":0,"in_battle":0,"raid_pokemon_move_1":216,"raid_pokemon_move_2":94,"raid_pokemon_form":0,"raid_pokemon_alignment":0,"raid_pokemon_cp":3500,"raid_is_exclusive":0,"cell_id":1234567890123,"deleted":false,"total_cp":12000,"first_seen_timestamp":1699990000,"raid_pokemon_gender":1,"sponsor_id":null,"partner_id":"partner-1","raid_pokemon_costume":0,"raid_pokemon_evolution":0,"raid_seed":123456789012345,"raid_pokemon_stamina":15000,"raid_pokemon_cp_multiplier":0.79,"ar_scan_eligible":1,"power_up_level":2,"power_up_points":50,"power_up_end_timestamp":null,"description":"A test gym","defenders":null,"rsvps":"[]"}`

if string(got) != want {
t.Errorf("wire format changed.\n got: %s\nwant: %s", got, want)
Expand Down
Loading
Loading