diff --git a/decoder/gym.go b/decoder/gym.go index ce66a965..43cffe86 100644 --- a/decoder/gym.go +++ b/decoder/gym.go @@ -329,22 +329,24 @@ func hasChangesGym(old *Gym, new *Gym) bool { } type GymDetailsWebhook struct { - Id string `json:"id"` - Name string `json:"name"` - Url string `json:"url"` - Latitude float64 `json:"latitude"` - Longitude float64 `json:"longitude"` - Team int64 `json:"team"` - GuardPokemonId int64 `json:"guard_pokemon_id"` - SlotsAvailable int64 `json:"slots_available"` - ExRaidEligible int64 `json:"ex_raid_eligible"` - InBattle bool `json:"in_battle"` - SponsorId int64 `json:"sponsor_id"` - PartnerId int64 `json:"partner_id"` - PowerUpPoints int64 `json:"power_up_points"` - PowerUpLevel int64 `json:"power_up_level"` - PowerUpEndTimestamp int64 `json:"power_up_end_timestamp"` - ArScanEligible int64 `json:"ar_scan_eligible"` + Id string `json:"id"` + Name string `json:"name"` + Url string `json:"url"` + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` + Team int64 `json:"team"` + GuardPokemonId int64 `json:"guard_pokemon_id"` + SlotsAvailable int64 `json:"slots_available"` + ExRaidEligible int64 `json:"ex_raid_eligible"` + InBattle bool `json:"in_battle"` + SponsorId int64 `json:"sponsor_id"` + PartnerId int64 `json:"partner_id"` + PowerUpPoints int64 `json:"power_up_points"` + PowerUpLevel int64 `json:"power_up_level"` + PowerUpEndTimestamp int64 `json:"power_up_end_timestamp"` + ArScanEligible int64 `json:"ar_scan_eligible"` + LobbyPlayerCount int32 `json:"lobby_player_count"` + LobbyJoinEndTimestamp int64 `json:"lobby_join_end_timestamp"` //"id": id, //"name": name ?? "Unknown", @@ -374,30 +376,45 @@ func createGymFortWebhooks(oldGym *Gym, gym *Gym) { } } +func makeGymWebhook(gym *Gym) *GymDetailsWebhook { + return &GymDetailsWebhook{ + Id: gym.Id, + Name: gym.Name.ValueOrZero(), + Url: gym.Url.ValueOrZero(), + Latitude: gym.Lat, + Longitude: gym.Lon, + Team: gym.TeamId.ValueOrZero(), + GuardPokemonId: gym.GuardingPokemonId.ValueOrZero(), + SlotsAvailable: func() int64 { + if gym.AvailableSlots.Valid { + return gym.AvailableSlots.Int64 + } else { + return 6 + } + }(), + ExRaidEligible: gym.ExRaidEligible.ValueOrZero(), + InBattle: func() bool { return gym.InBattle.ValueOrZero() != 0 }(), + } +} + +func CreateGymLobbyPlayerCountWebhooks(ctx context.Context, db db.DbDetails, lobby *pogo.RaidLobbyPlayerCountProto) bool { + gym, _ := getGymRecord(ctx, db, lobby.GymId) + if gym == nil { // skip reporting for unseen gyms + return false + } + gymDetails := makeGymWebhook(gym) + gymDetails.LobbyPlayerCount = lobby.PlayerCount + gymDetails.LobbyJoinEndTimestamp = lobby.LobbyJoinUntilMs + areas := MatchStatsGeofence(gym.Lat, gym.Lon) + webhooks.AddMessage(webhooks.RaidLobby, gymDetails, areas) + return true +} + func createGymWebhooks(oldGym *Gym, gym *Gym) { areas := MatchStatsGeofence(gym.Lat, gym.Lon) if oldGym == nil || (oldGym.AvailableSlots != gym.AvailableSlots || oldGym.TeamId != gym.TeamId || oldGym.InBattle != gym.InBattle) { - gymDetails := GymDetailsWebhook{ - Id: gym.Id, - Name: gym.Name.ValueOrZero(), - Url: gym.Url.ValueOrZero(), - Latitude: gym.Lat, - Longitude: gym.Lon, - Team: gym.TeamId.ValueOrZero(), - GuardPokemonId: gym.GuardingPokemonId.ValueOrZero(), - SlotsAvailable: func() int64 { - if gym.AvailableSlots.Valid { - return gym.AvailableSlots.Int64 - } else { - return 6 - } - }(), - ExRaidEligible: gym.ExRaidEligible.ValueOrZero(), - InBattle: func() bool { return gym.InBattle.ValueOrZero() != 0 }(), - } - - webhooks.AddMessage(webhooks.GymDetails, gymDetails, areas) + webhooks.AddMessage(webhooks.GymDetails, makeGymWebhook(gym), areas) } if gym.RaidSpawnTimestamp.ValueOrZero() > 0 && diff --git a/main.go b/main.go index d860f399..19ac328e 100644 --- a/main.go +++ b/main.go @@ -267,6 +267,9 @@ func decode(ctx context.Context, method int, protoData *ProtoData) { case pogo.Method_METHOD_GET_MAP_FORTS: result = decodeGetMapForts(ctx, protoData.Data) processed = true + case pogo.Method_METHOD_GET_RAID_LOBBY_COUNTER: + result = decodeGetRaidLobbyCounter(ctx, protoData.Data) + processed = true default: log.Debugf("Did not process hook type %s", pogo.Method(method)) } @@ -436,6 +439,32 @@ func decodeGetMapForts(ctx context.Context, sDec []byte) string { return "No forts updated" } +func decodeGetRaidLobbyCounter(ctx context.Context, sDec []byte) string { + decodedRaidLobbyCounter := &pogo.GetRaidLobbyCounterOutProto{} + if err := proto.Unmarshal(sDec, decodedRaidLobbyCounter); err != nil { + log.Errorf("Failed to parse %s", err) + return fmt.Sprintf("Failed to parse %s", err) + } + + if decodedRaidLobbyCounter.Result != pogo.GetRaidLobbyCounterOutProto_SUCCESS { + return fmt.Sprintf(`GetRaidLobbyCounterOutProto: Ignored non-success value %d:%s`, + decodedRaidLobbyCounter.Result, + pogo.GetRaidLobbyCounterOutProto_Result_name[int32(decodedRaidLobbyCounter.Result)]) + } + + processedLobbies := 0 + for _, lobby := range decodedRaidLobbyCounter.RaidLobbyPlayerCount { + if decoder.CreateGymLobbyPlayerCountWebhooks(ctx, dbDetails, lobby) { + processedLobbies += 1 + } + } + + if processedLobbies > 0 { + return fmt.Sprintf("Updated %d lobbies", processedLobbies) + } + return "No lobbies updated" +} + func decodeGetGymInfo(ctx context.Context, sDec []byte) string { decodedGymInfo := &pogo.GymGetInfoOutProto{} if err := proto.Unmarshal(sDec, decodedGymInfo); err != nil { diff --git a/webhooks/collector.go b/webhooks/collector.go index 438fca3b..8d2eb263 100644 --- a/webhooks/collector.go +++ b/webhooks/collector.go @@ -27,6 +27,7 @@ var webhookCollections map[string]*WebhookList const GymDetails = "gym_details" const Raid = "raid" +const RaidLobby = "raid_lobby" const Pokemon = "pokemon" const Quest = "quest" const Pokestop = "pokestop"