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 }