draft/mlp/set.go

134 lines
2.7 KiB
Go

package mlp
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strings"
"git.fromouter.space/mcg/draft"
)
// Set is a set/expansion of MLP:CCG
type Set struct {
ID SetID
Name string
CardList []draft.Card
CardData map[string]Card
}
// jsonSet is the set as serialized in the JSON files
type jsonSet struct {
ID SetID
Name string
Cards []Card
}
func (j *jsonSet) toSet() (s Set) {
s.Name = j.Name
s.CardData = make(map[string]Card)
s.CardList = make([]draft.Card, len(j.Cards))
for i, card := range j.Cards {
s.CardData[card.ID] = card
s.CardList[i] = draft.Card{ID: card.ID}
}
return
}
var loadedSets = make(map[SetID]*Set)
// Errors
var (
ErrSetNotLoaded = errors.New("set not loaded")
)
// CleanSetCache removes all loaded sets from memory
func CleanSetCache() {
loadedSets = make(map[SetID]*Set)
}
// LoadSetData loads sets from data
func LoadSetData(sets map[SetID][]byte) error {
for setid, setdata := range sets {
_, err := LoadSetBytes(setid, setdata)
if err != nil {
return err
}
}
return nil
}
// LoadSetMemory loads a set from memory (must have been previously loaded with LoadSetData or other functions)
func LoadSetMemory(id SetID) (*Set, error) {
// Check if set is already loaded
if set, ok := loadedSets[id]; ok {
return set, nil
}
// Not loaded, return error
return nil, ErrSetNotLoaded
}
// LoadSetBytes loads a set with a specified ID from JSON
func LoadSetBytes(id SetID, setdata []byte) (*Set, error) {
// Check if set is already loaded
if set, ok := loadedSets[id]; ok {
return set, nil
}
var jsonset jsonSet
err := json.Unmarshal(setdata, &jsonset)
if err != nil {
return nil, err
}
set := jsonset.toSet()
set.ID = id
loadedSets[set.ID] = &set
return &set, err
}
// HTTPClient is the HTTP client used in LoadSetHTTP
var HTTPClient = http.DefaultClient
// HTTPSource is the base URL for fetching sets remotely via HTTP
var HTTPSource = "https://mcg.zyg.ovh/setdata/"
// LoadSetHTTP loads a set using MCG's remote server
func LoadSetHTTP(id SetID) (*Set, error) {
// Check if set is already loaded
if set, ok := loadedSets[id]; ok {
return set, nil
}
// Get SetID as string and make it lowercase
setid := strings.ToLower(string(id))
resp, err := HTTPClient.Get(HTTPSource + setid + ".json")
if err != nil || resp.StatusCode != 200 {
if err == nil {
err = fmt.Errorf("server returned non-200 response code (%d)", resp.StatusCode)
}
return nil, err
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return LoadSetBytes(id, data)
}
// LoadAllSets just loads all sets from the web
func LoadAllSets() error {
for _, set := range allSets {
_, err := LoadSetHTTP(set)
if err != nil {
return err
}
}
return nil
}