Skip to content

Instantly share code, notes, and snippets.

@shizeeg
Created June 13, 2024 15:17
Show Gist options
  • Save shizeeg/373fc70dfcf2709a45b3d62f6784dbbe to your computer and use it in GitHub Desktop.
Save shizeeg/373fc70dfcf2709a45b3d62f6784dbbe to your computer and use it in GitHub Desktop.
show Steam Online player count
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"strings"
"time"
"unicode"
)
const (
SEARCH_URI = "https://steamcommunity.com/actions/SearchApps"
BASEURL = "https://api.steampowered.com/"
API = BASEURL + "/ISteamUserStats/GetNumberOfCurrentPlayers/v1/?appid="
SPYAPI = "https://steamspy.com/api.php?request=appdetails&appid="
)
type Apps struct {
Appid string
Name string
Icon string
Logo string
}
type AppDetailsData struct {
AppID int `json:"appid,omitempty"`
Name string `json:"name,omitempty"`
Developer string `json:"developer,omitempty"`
Publisher string `json:"publisher,omitempty"`
ScoreRank string `json:"score_rank,omitempty"`
Positive int `json:"positive,omitempty"`
Negative int `json:"negative,omitempty"`
Userscore int `json:"userscore,omitempty"`
Owners string `json:"owners,omitempty"`
AverageForever int `json:"average_forever,omitempty"`
Average2Weeks int `json:"average_2weeks,omitempty"`
MedianForever int `json:"median_forever,omitempty"`
Median2Weeks int `json:"median_2weeks,omitempty"`
Price string `json:"price,omitempty"`
Initialprice string `json:"initialprice,omitempty"`
Discount string `json:"discount,omitempty"`
Ccu int `json:"ccu,omitempty"`
Languages string `json:"languages,omitempty"`
Genre string `json:"genre,omitempty"`
Tags struct {
TwoDFighter int `json:"2D Fighter,omitempty"`
Fighting int `json:"Fighting,omitempty"`
CharacterCustomization int `json:"Character Customization,omitempty"`
Action int `json:"Action,omitempty"`
Arcade int `json:"Arcade,omitempty"`
Multiplayer int `json:"Multiplayer,omitempty"`
Adventure int `json:"Adventure,omitempty"`
Competitive int `json:"Competitive,omitempty"`
PvP int `json:"PvP,omitempty"`
OpenWorld int `json:"Open World,omitempty"`
ESports int `json:"e-sports,omitempty"`
Singleplayer int `json:"Singleplayer,omitempty"`
LocalMultiplayer int `json:"Local Multiplayer,omitempty"`
ActionRPG int `json:"Action RPG,omitempty"`
Controller int `json:"Controller,omitempty"`
ThreeD int `json:"3D,omitempty"`
GreatSoundtrack int `json:"Great Soundtrack,omitempty"`
Sandbox int `json:"Sandbox,omitempty"`
MartialArts int `json:"Martial Arts,omitempty"`
Anime int `json:"Anime,omitempty"`
} `json:"tags,omitempty"`
}
type PlayerCount struct {
Response struct {
PlayerCount int `json:"player_count,omitempty"`
Result int `json:"result,omitempty"`
} `json:"response,omitempty"`
}
func main() {
DEFAULT_GAME := []string{"307780", "976310", "1971870", "1778820", "1384160", "1364780"}
var query = DEFAULT_GAME
if len(os.Args) > 1 {
query = os.Args
}
for _, SteamID := range query {
if appid, err := ToAppID(SteamID); err == nil {
if players, err := FetchPlayerCount(appid); err == nil {
game, _ := AppDetails(appid)
fmt.Printf("%s: %d\n", game.Name, players)
} else {
log.Fatal(err)
}
} else if err != nil /* || len(body) == 2 */ {
continue
}
}
var apps []Apps
for _, game := range apps {
appid, _ := strconv.ParseInt(game.Appid, 10, 64)
if players, err := FetchPlayerCount(appid); err == nil {
fmt.Printf("%s: %d\n", game.Name, players)
} else {
log.Fatal(err)
}
}
fmt.Println("press <Enter> to quit.")
fmt.Scanln()
}
func FetchPlayerCount(appid int64) (count int, err error) {
c := http.Client{Timeout: time.Duration(1) * time.Second}
resp, err := c.Get(fmt.Sprintf("%s%d", API, appid))
if err != nil {
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
var cnt PlayerCount
if err = json.Unmarshal(body, &cnt); err != nil {
return
}
return cnt.Response.PlayerCount, nil
}
func Search(game string) (body []byte, err error) {
c := http.Client{Timeout: time.Duration(1) * time.Second}
resp, err := c.Get(fmt.Sprintf("%s/%s", SEARCH_URI, strings.ReplaceAll(game, " ", "_")))
if err != nil {
fmt.Printf("Error %s", err)
return
}
defer resp.Body.Close()
body, err = io.ReadAll(resp.Body)
var apps []Apps
if err := json.Unmarshal(body, &apps); err != nil {
log.Fatal(err)
}
return
}
func ToAppID(s string) (appid int64, err error) {
out := fmt.Sprint(strings.TrimFunc(s, func(r rune) bool {
return !unicode.IsNumber(r)
}))
return strconv.ParseInt(out, 10, 64)
}
func AppDetails(appid int64) (app AppDetailsData, err error) {
c := http.Client{Timeout: time.Duration(1) * time.Second}
resp, err := c.Get(fmt.Sprintf("%s%d", SPYAPI, appid))
if err != nil {
fmt.Printf("Error %s", err)
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err := json.Unmarshal(body, &app); err != nil {
log.Fatal(err)
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment