You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.9 KiB
Go

package steam
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
)
// a steam API client, not tied to any particular game
type Client struct {
key string
}
func NewClient(key string) *Client {
return &Client{key: key}
}
func (c *Client) Get(iface, method, version string) (*http.Response, error) {
url := fmt.Sprintf("https://api.steampowered.com/%s/%s/%s/?key=%s", iface, method, version, c.key)
return http.Get(url)
}
func (c *Client) GetFriendList(userid uint64) ([]PlayerFriend, error) {
url := fmt.Sprintf("https://api.steampowered.com/ISteamUser/GetFriendList/v1/?key=%s&steamid=%d", c.key, userid)
res, err := http.Get(url)
if err != nil {
return nil, errorf(err, "unable to get friend list")
}
var response struct {
V struct {
Friends []PlayerFriend `json:"friends"`
} `json:"friendslist"`
}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, errorf(err, "unable to parse friends list response")
}
return response.V.Friends, nil
}
func (c *Client) ResolveVanityUrl(vanity string) (uint64, error) {
var v struct {
V struct {
Id uint64 `json:"steamid,string"`
Success int `json:"success"`
} `json:"response"`
}
url := fmt.Sprintf("https://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key=%s&vanityurl=%s", c.key, vanity)
res, err := http.Get(url)
if err != nil {
return 0, errorf(err, "unable to resolve vanity url")
}
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return 0, errorf(err, "unable to decode vanity url response")
}
if v.V.Success != 1 {
return 0, errorf(err, "resolving vanity url returned non-1 status")
}
return v.V.Id, nil
}
func (c *Client) GetPlayerSummaries(steamids ...uint64) ([]PlayerSummary, error) {
if len(steamids) > 100 {
return nil, errorf(nil, "GetPlayerSummaries accepts a max of 100 ids, saw %d", len(steamids))
}
ids_s := make([]string, len(steamids))
for i := range steamids {
ids_s[i] = strconv.FormatUint(steamids[i], 10)
}
ids := strings.Join(ids_s, ",")
url := fmt.Sprintf("https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s", c.key, ids)
res, err := http.Get(url)
if err != nil {
return nil, errorf(err, "unable to call GetPlayerSummaries API")
}
var response struct {
V struct {
Players []PlayerSummary `json:"players"`
} `json:"response"`
}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, errorf(err, "unable to parse GetPlayerSummaries response")
}
return response.V.Players, nil
}
func (c *Client) DotaMatchSequence(lastId uint64, n int) ([]DotaMatch, error) {
// http://api.steampowered.com/IDOTA2Match_<ID>/GetMatchHistoryBySequenceNum/v1
url := fmt.Sprintf("https://api.steampowered.com/IDOTA2Match_570/GetMatchHistoryBySequenceNum/v1/?key=%s", c.key)
if lastId > 0 {
url = fmt.Sprintf("%s&start_at_match_seq_num=%d", url, lastId)
}
if n > 0 {
url = fmt.Sprintf("%s&matches_requested=%d", url, n)
}
fmt.Println(url)
var response struct {
V struct {
Status int `json:"status"`
NumResults int `json:"num_results"`
Total int `json:"total_results"`
Remaining int `json:"results_remaining"`
Matches []DotaMatch `json:"matches"`
} `json:"result"`
}
res, err := http.Get(url)
if err != nil {
return nil, errorf(err, "unable to get match history")
}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, errorf(err, "unable to parse match history response")
}
return response.V.Matches, nil
}
func (c *Client) DotaMatchHistory(lastId uint64, n int) ([]DotaMatch, error) {
url := fmt.Sprintf("https://api.steampowered.com/IDOTA2Match_570/GetMatchHistory/v0001/?key=%s", c.key)
if lastId > 0 {
url = fmt.Sprintf("%s&last_match_id=%d", url, lastId)
}
if n > 0 {
url = fmt.Sprintf("%s&matches_requested=%d", url, n)
}
fmt.Println(url)
var response struct {
V struct {
Status int `json:"status"`
NumResults int `json:"num_results"`
Total int `json:"total_results"`
Remaining int `json:"results_remaining"`
Matches []DotaMatch `json:"matches"`
} `json:"result"`
}
res, err := http.Get(url)
if err != nil {
return nil, errorf(err, "unable to get match history")
}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, errorf(err, "unable to parse match history response")
}
return response.V.Matches, nil
}
func (c *Client) DotaMatchDetails(id uint64) (*DotaMatchDetails, error) {
url := fmt.Sprintf("https://api.steampowered.com/IDOTA2Match_570/GetMatchDetails/v0001/?key=%s&match_id=%d", c.key, id)
res, err := http.Get(url)
if err != nil {
return nil, errorf(err, "unable to get match details")
}
var result struct {
V DotaMatchDetails `json:"result"`
}
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, errorf(err, "unable to parse match details")
}
return &result.V, nil
}