Skip to content

Commit

Permalink
feat: add support for achievement progress
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Gleich <[email protected]>
  • Loading branch information
gleich committed Jul 19, 2024
1 parent 88062b0 commit 7bd975e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 31 deletions.
32 changes: 20 additions & 12 deletions pkg/apis/steam/achievements.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Achievement struct {
UnlockTime *time.Time `json:"unlock_time"`
}

func FetchGameAchievements(appID int32) *[]Achievement {
func FetchGameAchievements(appID int32) (*float32, *[]Achievement) {
params := url.Values{
"key": {secrets.SECRETS.SteamKey},
"steamid": {secrets.SECRETS.SteamID},
Expand All @@ -55,33 +55,33 @@ func FetchGameAchievements(appID int32) *[]Achievement {
resp, err := http.Get("https://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v0001?" + params.Encode())
if err != nil {
lumber.Error(err, "sending request for player achievements from", appID, "failed")
return nil
return nil, nil
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
lumber.Error(err, "reading response body for player achievements from", appID, "failed")
return nil
return nil, nil
}
if string(body) == `{"playerstats":{"error":"Requested app has no stats","success":false}}` {
return nil
return nil, nil
}
if resp.StatusCode != http.StatusOK {
lumber.ErrorMsg(resp.StatusCode, "when trying to get player achievements for", appID, string(body))
return nil
return nil, nil
}

var playerAchievements playerAchievementsResponse
err = json.Unmarshal(body, &playerAchievements)
if err != nil {
lumber.Error(err, "failed to parse json for player achievements for", appID)
lumber.Debug("body:", string(body))
return nil
return nil, nil
}

if playerAchievements.PlayerStats.Achievements == nil {
return nil
return nil, nil
}

params = url.Values{
Expand All @@ -92,26 +92,26 @@ func FetchGameAchievements(appID int32) *[]Achievement {
resp, err = http.Get("https://api.steampowered.com/ISteamUserStats/GetSchemaForGame/v2?" + params.Encode())
if err != nil {
lumber.Error(err, "sending request for owned games failed")
return nil
return nil, nil
}
defer resp.Body.Close()

body, err = io.ReadAll(resp.Body)
if err != nil {
lumber.Error(err, "reading response body for game schema failed for", appID)
return nil
return nil, nil
}
if resp.StatusCode != http.StatusOK {
lumber.ErrorMsg(resp.StatusCode, "when trying to get player achievements for", appID, string(body))
return nil
return nil, nil
}

var gameSchema schemaGameResponse
err = json.Unmarshal(body, &gameSchema)
if err != nil {
lumber.Error(err, "failed to parse json for game schema for", appID)
lumber.Debug("body:", string(body))
return nil
return nil, nil
}

var achievements []Achievement
Expand All @@ -134,6 +134,14 @@ func FetchGameAchievements(appID int32) *[]Achievement {
}
}

var totalAchieved int
for _, achievement := range achievements {
if achievement.Achieved {
totalAchieved++
}
}
achievementPercentage := (float32(totalAchieved) / float32(len(achievements))) * 100.0

sort.Slice(achievements, func(i, j int) bool {
if achievements[i].UnlockTime == nil && achievements[j].UnlockTime == nil {
return false
Expand All @@ -151,5 +159,5 @@ func FetchGameAchievements(appID int32) *[]Achievement {
achievements = achievements[:20]
}

return &achievements
return &achievementPercentage, &achievements
}
40 changes: 22 additions & 18 deletions pkg/apis/steam/games.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ type ownedGamesResponse struct {
}

type Game struct {
Name string `json:"name"`
AppID int32 `json:"app_id"`
ImgIconURL string `json:"img_icon_url"`
RTimeLastPlayed time.Time `json:"rtime_last_played"`
PlaytimeForever int32 `json:"playtime_forever"`
URL string `json:"url"`
HeaderURL string `json:"header_url"`
LibraryURL *string `json:"library_url"`
Achievements *[]Achievement `json:"achievements"`
Name string `json:"name"`
AppID int32 `json:"app_id"`
IconURL string `json:"icon_url"`
RTimeLastPlayed time.Time `json:"rtime_last_played"`
PlaytimeForever int32 `json:"playtime_forever"`
URL string `json:"url"`
HeaderURL string `json:"header_url"`
LibraryURL *string `json:"library_url"`
AchievementProgress *float32 `json:"achievement_progress"`
Achievements *[]Achievement `json:"achievements"`
}

func FetchRecentlyPlayedGames() []Game {
Expand Down Expand Up @@ -89,16 +90,19 @@ func FetchRecentlyPlayedGames() []Game {
libraryURLPtr = &libraryURL
}

achievementPercentage, achievements := FetchGameAchievements(g.AppID)

games = append(games, Game{
Name: g.Name,
AppID: g.AppID,
ImgIconURL: fmt.Sprintf("https://media.steampowered.com/steamcommunity/public/images/apps/%d/%s.jpg", g.AppID, g.ImgIconURL),
RTimeLastPlayed: time.Unix(g.RTimeLastPlayed, 0),
PlaytimeForever: g.PlaytimeForever,
URL: fmt.Sprintf("https://store.steampowered.com/app/%d/", g.AppID),
HeaderURL: fmt.Sprintf("https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/%d/header.jpg", g.AppID),
LibraryURL: libraryURLPtr,
Achievements: FetchGameAchievements(g.AppID),
Name: g.Name,
AppID: g.AppID,
IconURL: fmt.Sprintf("https://media.steampowered.com/steamcommunity/public/images/apps/%d/%s.jpg", g.AppID, g.ImgIconURL),
RTimeLastPlayed: time.Unix(g.RTimeLastPlayed, 0),
PlaytimeForever: g.PlaytimeForever,
URL: fmt.Sprintf("https://store.steampowered.com/app/%d/", g.AppID),
HeaderURL: fmt.Sprintf("https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/%d/header.jpg", g.AppID),
LibraryURL: libraryURLPtr,
AchievementProgress: achievementPercentage,
Achievements: achievements,
})
}

Expand Down
4 changes: 3 additions & 1 deletion pkg/apis/strava/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package strava
import (
"encoding/json"
"io"
"log"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -74,5 +75,6 @@ func (t *Tokens) RefreshIfNeeded() {
os.Setenv("STRAVA_REFRESH_TOKEN_EXPIRATION", strconv.FormatInt(tokens.ExpiresAt, 10))
*t = tokens

lumber.Success("loaded new strava token data. access:", t.Access, "refresh:", t.Refresh)
lumber.Success("loaded new strava token data")
log.Println("access:", t.Access, "refresh:", t.Refresh)
}

0 comments on commit 7bd975e

Please sign in to comment.