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
71 changes: 71 additions & 0 deletions decoder/fort_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package decoder

import (
"context"
"fmt"
"sync"
"time"

Expand Down Expand Up @@ -409,6 +410,76 @@ func GetFortTracker() *FortTracker {
return fortTracker
}

// CellFortInfo holds information about forts in a cell for API response
type CellFortInfo struct {
CellId string `json:"cell_id"`
LastSeen int64 `json:"last_seen"`
Pokestops []string `json:"pokestops"`
Gyms []string `json:"gyms"`
}

// FortTrackerInfo holds information about a fort for API response
type FortTrackerInfo struct {
FortId string `json:"fort_id"`
CellId string `json:"cell_id"`
LastSeen int64 `json:"last_seen"`
IsGym bool `json:"is_gym"`
}

// GetCellInfo returns information about a specific cell
func (ft *FortTracker) GetCellInfo(cellId uint64) *CellFortInfo {
if ft == nil {
return nil
}

ft.mu.RLock()
defer ft.mu.RUnlock()

cell, exists := ft.cells[cellId]
if !exists {
return nil
}

pokestops := make([]string, 0, len(cell.pokestops))
for stopId := range cell.pokestops {
pokestops = append(pokestops, stopId)
}

gyms := make([]string, 0, len(cell.gyms))
for gymId := range cell.gyms {
gyms = append(gyms, gymId)
}

return &CellFortInfo{
CellId: fmt.Sprintf("%d", cellId),
LastSeen: cell.lastSeen,
Pokestops: pokestops,
Gyms: gyms,
}
}

// GetFortInfo returns information about a specific fort
func (ft *FortTracker) GetFortInfo(fortId string) *FortTrackerInfo {
if ft == nil {
return nil
}

ft.mu.RLock()
defer ft.mu.RUnlock()

fort, exists := ft.forts[fortId]
if !exists {
return nil
}

return &FortTrackerInfo{
FortId: fortId,
CellId: fmt.Sprintf("%d", fort.cellId),
LastSeen: fort.lastSeen,
IsGym: fort.isGym,
}
}

// clearGymWithLock marks a gym as deleted while holding the striped mutex
func clearGymWithLock(ctx context.Context, dbDetails db.DbDetails, gymId string, cellId uint64, removeFromTracker bool) {
gymMutex, _ := gymStripedMutex.GetLock(gymId)
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ func main() {
apiGroup.GET("/tappable/id/:tappable_id", GetTappable)

apiGroup.GET("/devices/all", GetDevices)
apiGroup.GET("/fort-tracker/cell/:cell_id", GetFortTrackerCell)
apiGroup.GET("/fort-tracker/forts/:fort_id", GetFortTrackerFort)

debugGroup := r.Group("/debug")

Expand Down
41 changes: 41 additions & 0 deletions routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,3 +739,44 @@ func GetTappable(c *gin.Context) {
func GetDevices(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"devices": GetAllDevices()})
}

func GetFortTrackerCell(c *gin.Context) {
cellIdStr := c.Param("cell_id")
cellId, err := strconv.ParseUint(cellIdStr, 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid cell ID"})
return
}

fortTracker := decoder.GetFortTracker()
if fortTracker == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "FortTracker not initialized"})
return
}

cellInfo := fortTracker.GetCellInfo(cellId)
if cellInfo == nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Cell not found"})
return
}

c.JSON(http.StatusOK, cellInfo)
}

func GetFortTrackerFort(c *gin.Context) {
fortId := c.Param("fort_id")

fortTracker := decoder.GetFortTracker()
if fortTracker == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "FortTracker not initialized"})
return
}

fortInfo := fortTracker.GetFortInfo(fortId)
if fortInfo == nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Fort not found"})
return
}

c.JSON(http.StatusOK, fortInfo)
}