package roblox import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "regexp" "strconv" ) // Item struct containing data on retrieved items type Item struct { ProductID string ItemID string AssetID string UserID string UserName string Type string Name string CopyLocked bool Owned bool } // ItemInfo return info of selected item func (s *Session) ItemInfo(url string) (Item, error) { var item Item resp, err := s.client.Get(url) if err != nil { return item, err } defer resp.Body.Close() if resp.StatusCode != 200 { return item, fmt.Errorf("Failed to get item info. Status %d", resp.StatusCode) } body, _ := ioutil.ReadAll(resp.Body) page := string(body) pItem := regexp.MustCompile("data-product-id=\"(.+)\"").FindStringSubmatch(page) if len(pItem) > 0 { item.ProductID, err = safeRetrieve("data-product-id=\"(.+)\"", page) if err != nil { return item, err } item.CopyLocked = false item.UserID, err = safeRetrieve("data-expected-seller-id=\"(.+)\"", page) if err != nil { return item, err } item.UserName, err = safeRetrieve("data-seller-name=\"(.+)\"", page) if err != nil { return item, err } } else { item.ProductID = "locked" item.CopyLocked = true item.UserID = "" item.UserName = "" item.AssetID = "" } asset := regexp.MustCompile("data-userasset-id=\"(.+)\"").FindStringSubmatch(page) if len(asset) > 0 { item.AssetID, err = safeRetrieve("data-userasset-id=\"(.+)\"", page) if err != nil { return item, err } item.Owned = true } else { item.AssetID = "" item.Owned = false } item.ItemID, err = safeRetrieve("data-item-id=\"(.+)\"", page) if err != nil { return item, err } item.Name, err = safeRetrieve("data-item-name=\"(.+)\"", page) if err != nil { return item, err } item.Type, err = safeRetrieve("data-asset-type=\"(.+)\"", page) if err != nil { return item, err } return item, nil } // AddItem add item by id to inventory func (s *Session) AddItem(id string, seller string) error { v := url.Values{} v.Set("rqtype", "purchase") v.Set("productID", id) v.Set("expectedCurrency", "1") v.Set("expectedPrice", "0") v.Set("expectedSellerID", seller) v.Set("userAssetID", "") resp, err := s.client.Post("https://www.roblox.com/api/item.ashx?"+v.Encode(), "application/json", bytes.NewBufferString("")) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode == 403 { req, err := http.NewRequest("POST", "https://www.roblox.com/api/item.ashx?"+v.Encode(), bytes.NewBufferString("")) req.Header.Set("X-Csrf-Token", resp.Header["X-Csrf-Token"][0]) req.Header.Set("Content-Type", "application/json") resp, err := s.client.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { return fmt.Errorf("Failed to add item. Status %d", resp.StatusCode) } } return nil } // RemoveItem will remove item from inventory func (s *Session) RemoveItem(id string) error { v := url.Values{} v.Set("assetId", id) resp, err := s.client.Post("https://www.roblox.com/asset/delete-from-inventory", "application/x-www-form-urlencoded", bytes.NewBufferString(v.Encode())) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode == 403 { req, err := http.NewRequest("POST", "https://www.roblox.com/asset/delete-from-inventory", bytes.NewBufferString(v.Encode())) req.Header.Set("X-Csrf-Token", resp.Header["X-Csrf-Token"][0]) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := s.client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() if resp.StatusCode != 200 { return fmt.Errorf("Failed to remove item. Status %d", resp.StatusCode) } } return nil } // GetModels will list models in inventory func (s *Session) GetModels(user string) ([]Item, error) { var Data []Item resp, err := s.client.Get("https://www.roblox.com/users/inventory/list-json?assetTypeId=10&userId=" + user) if err != nil { return Data, fmt.Errorf("Could not get list: %s", err) } if resp.StatusCode == 200 { var dat map[string]interface{} defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) if err := json.Unmarshal(body, &dat); err != nil { panic(err) } set := dat["Data"].(map[string]interface{}) ilist := set["Items"].([]interface{}) for _, obj := range ilist { itm := obj.(map[string]interface{}) iInfo := itm["Item"].(map[string]interface{}) iCreator := itm["Creator"].(map[string]interface{}) Data = append(Data, Item{"", strconv.Itoa(int(iInfo["AssetId"].(float64))), "", strconv.Itoa(int(iCreator["Id"].(float64))), iCreator["Name"].(string), "Model", iInfo["Name"].(string), false, true}) } return Data, nil } return Data, fmt.Errorf("Could not get models. Status: %d", resp.StatusCode) } func safeRetrieve(pattern string, source string) (string, error) { pItem := regexp.MustCompile(pattern).FindStringSubmatch(source) if len(pItem) > 0 { return pItem[1], nil } return "", fmt.Errorf("Could not find item on in string") }