games-screenshot-manager/pkg/providers/steam/steam.go

189 lines
4.7 KiB
Go
Raw Normal View History

2020-10-29 12:50:27 +00:00
package steam
import (
"encoding/json"
"errors"
2021-05-08 09:37:52 +00:00
"fmt"
2020-10-29 12:50:27 +00:00
"io/ioutil"
"log"
"os"
2020-11-14 10:39:48 +00:00
"path/filepath"
2020-10-29 12:50:27 +00:00
"runtime"
"strconv"
"strings"
2021-04-12 20:43:10 +00:00
"github.com/fmartingr/games-screenshot-manager/pkg/helpers"
2021-05-08 09:37:52 +00:00
"github.com/fmartingr/games-screenshot-manager/pkg/providers"
2020-10-29 12:50:27 +00:00
)
const providerName string = "steam"
2020-11-19 19:27:37 +00:00
const gameListURL string = "https://api.steampowered.com/ISteamApps/GetAppList/v2/"
2021-05-08 09:37:52 +00:00
const baseGameHeaderURL string = "https://cdn.cloudflare.steamstatic.com/steam/apps/%s/header.jpg"
2020-10-29 12:50:27 +00:00
type SteamApp struct {
AppID uint64 `json:"appid"`
Name string `json:"name"`
}
type SteamAppList struct {
Apps []SteamApp `json:"apps"`
}
2020-11-19 22:05:14 +00:00
func (appList SteamAppList) FindID(id string) (SteamApp, error) {
2021-05-08 09:37:52 +00:00
GameIDNotFound := errors.New("game ID not found")
2020-10-29 12:50:27 +00:00
for _, game := range appList.Apps {
2020-11-19 22:05:14 +00:00
uintGameID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
log.Panic(err)
}
if game.AppID == uintGameID {
2020-10-29 12:50:27 +00:00
return game, nil
}
}
return SteamApp{}, GameIDNotFound
}
type SteamAppListResponse struct {
AppList SteamAppList `json:"applist"`
}
2020-11-14 10:39:48 +00:00
func getBasePathForOS() string {
var path string
switch runtime.GOOS {
case "darwin":
path = helpers.ExpandUser("~/Library/Application Support/Steam")
case "linux":
path = helpers.ExpandUser("~/.local/share/Steam")
case "windows":
path = "C:\\Program Files (x86)\\Steam"
default:
log.Panic("Unsupported OS: ", runtime.GOOS)
}
return path
}
2020-11-19 19:27:37 +00:00
func getSteamAppList(c chan SteamAppList) {
2020-10-29 12:50:27 +00:00
log.Println("Updating steam game list...")
2020-11-19 19:27:37 +00:00
response, err := helpers.DoRequest("GET", gameListURL)
2020-10-29 12:50:27 +00:00
if err != nil {
panic(err)
}
if response.Body != nil {
defer response.Body.Close()
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
panic(err)
}
steamListResponse := SteamAppListResponse{}
jsonErr := json.Unmarshal(body, &steamListResponse)
if jsonErr != nil {
log.Fatal(jsonErr)
}
2021-05-08 09:37:52 +00:00
log.Printf("Updated Steam game list. Found %d apps.", len(steamListResponse.AppList.Apps))
2020-10-29 12:50:27 +00:00
c <- steamListResponse.AppList
}
func downloadGameHeaderImage(appId string) (string, error) {
2021-05-08 09:37:52 +00:00
url := fmt.Sprintf(baseGameHeaderURL, appId)
coverURL, err := helpers.DownloadURLIntoTempFile(url)
if err != nil {
return "", err
}
return coverURL, nil
}
2020-10-29 12:50:27 +00:00
func GuessUsers() []string {
var users []string
2020-11-14 10:39:48 +00:00
var path string = filepath.Join(getBasePathForOS(), "userdata")
2020-10-29 12:50:27 +00:00
2020-11-14 10:39:48 +00:00
if _, err := os.Stat(path); !os.IsNotExist(err) {
files, err := ioutil.ReadDir(path)
if err != nil {
log.Fatal(err)
}
2020-10-29 12:50:27 +00:00
2020-11-14 10:39:48 +00:00
for _, file := range files {
if _, err := strconv.ParseInt(file.Name(), 10, 64); err == nil {
log.Printf("Found local install Steam user: %s", file.Name())
users = append(users, file.Name())
2020-10-29 12:50:27 +00:00
}
}
}
return users
}
2020-11-19 22:05:14 +00:00
func GetGamesFromUser(user string) []string {
2020-10-29 12:50:27 +00:00
log.Println("Getting Steam games for user: " + user)
2020-11-19 22:05:14 +00:00
var userGames []string
2020-11-14 10:39:48 +00:00
var path string = filepath.Join(getBasePathForOS(), "userdata", user, "760", "remote")
2020-10-29 12:50:27 +00:00
2020-11-14 10:39:48 +00:00
if _, err := os.Stat(path); !os.IsNotExist(err) {
files, err := ioutil.ReadDir(path)
if err != nil {
log.Fatal(err)
}
2020-10-29 12:50:27 +00:00
2020-11-14 10:39:48 +00:00
for _, file := range files {
// len(file.Name()) == 20 -> Custom added Game to steam
2020-11-19 22:05:14 +00:00
userGames = append(userGames, file.Name())
2020-10-29 12:50:27 +00:00
}
}
2020-11-14 10:39:48 +00:00
2020-10-29 12:50:27 +00:00
return userGames
}
2021-05-08 09:37:52 +00:00
func GetScreenshotsForGame(user string, game *providers.Game) {
2020-11-19 22:05:14 +00:00
path := filepath.Join(getBasePathForOS(), "userdata", user, "/760/remote/", game.ID, "screenshots")
2020-10-29 12:50:27 +00:00
files, err := ioutil.ReadDir(path)
if err != nil {
log.Fatal(err)
}
for _, file := range files {
if strings.Contains(file.Name(), ".jpg") {
2021-05-08 09:37:52 +00:00
game.Screenshots = append(game.Screenshots, providers.Screenshot{Path: path + "/" + file.Name()})
2020-10-29 12:50:27 +00:00
// log.Printf("Found screenshot for user %s and game %d: %s", user, game.ID, path+"/"+file.Name())
}
}
if len(game.Screenshots) > 0 {
log.Printf("Found %d screenshots", len(game.Screenshots))
}
}
2021-05-08 09:37:52 +00:00
func GetGames(cliOptions providers.ProviderOptions) []providers.Game {
var localGames []providers.Game
2020-10-29 12:50:27 +00:00
c := make(chan SteamAppList)
2020-11-19 19:27:37 +00:00
go getSteamAppList(c)
2020-10-29 12:50:27 +00:00
users := GuessUsers()
steamApps := <-c
for _, userID := range users {
userGames := GetGamesFromUser(userID)
for _, userGameID := range userGames {
steamGame, err := steamApps.FindID(userGameID)
if err != nil {
log.Print("[ERROR] Steam game ID not found: ", userGameID)
}
2021-05-08 09:37:52 +00:00
userGame := providers.Game{ID: userGameID, Name: steamGame.Name, Provider: providerName, Platform: "PC"}
if *cliOptions.DownloadCovers {
coverPath, err := downloadGameHeaderImage(userGameID)
if err == nil {
2021-05-08 09:37:52 +00:00
userGame.Cover = providers.Screenshot{Path: coverPath, DestinationName: ".cover"}
}
}
log.Printf("Found Steam game for user %s: %s (%s)", userID, userGame.Name, userGame.ID)
2020-10-29 12:50:27 +00:00
GetScreenshotsForGame(userID, &userGame)
localGames = append(localGames, userGame)
}
}
return localGames
}