summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Philipp15b/go-steam/economy/inventory/partial.go
blob: bcaad1747b755184b5ed89cefd828df477c904a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package inventory

import (
	"bytes"
	"encoding/json"
	"errors"
	"net/http"
)

// A partial inventory as sent by the Steam API.
type PartialInventory struct {
	Success bool
	Error   string
	Inventory
	More      bool
	MoreStart MoreStart `json:"more_start"`
}

type MoreStart uint

func (m *MoreStart) UnmarshalJSON(data []byte) error {
	if bytes.Equal(data, []byte("false")) {
		return nil
	}
	return json.Unmarshal(data, (*uint)(m))
}

func DoInventoryRequest(client *http.Client, req *http.Request) (*PartialInventory, error) {
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	inv := new(PartialInventory)
	err = json.NewDecoder(resp.Body).Decode(inv)
	if err != nil {
		return nil, err
	}
	return inv, nil
}

func GetFullInventory(getFirst func() (*PartialInventory, error), getNext func(start uint) (*PartialInventory, error)) (*Inventory, error) {
	first, err := getFirst()
	if err != nil {
		return nil, err
	}
	if !first.Success {
		return nil, errors.New("GetFullInventory API call failed: " + first.Error)
	}

	result := &first.Inventory
	var next *PartialInventory
	for latest := first; latest.More; latest = next {
		next, err := getNext(uint(latest.MoreStart))
		if err != nil {
			return nil, err
		}
		if !next.Success {
			return nil, errors.New("GetFullInventory API call failed: " + next.Error)
		}

		result = Merge(result, &next.Inventory)
	}

	return result, nil
}

// Merges the given Inventory into a single Inventory.
// The given slice must have at least one element. The first element of the slice is used
// and modified.
func Merge(p ...*Inventory) *Inventory {
	inv := p[0]
	for idx, i := range p {
		if idx == 0 {
			continue
		}

		for key, value := range i.Items {
			inv.Items[key] = value
		}
		for key, value := range i.Descriptions {
			inv.Descriptions[key] = value
		}
		for key, value := range i.Currencies {
			inv.Currencies[key] = value
		}
	}

	return inv
}