package crawler import ( "encoding/json" "errors" "fmt" "net/url" "regexp" "strconv" "strings" "pcgamedb/cache" "pcgamedb/constant" "pcgamedb/model" "pcgamedb/utils" ) func GetSteamAppDetail(id int) (*model.SteamAppDetail, error) { key := fmt.Sprintf("steam_game:%d", id) val, exist := cache.Get(key) if exist { var detail model.SteamAppDetail if err := json.Unmarshal([]byte(val), &detail); err != nil { return nil, err } return &detail, nil } baseURL, _ := url.Parse(constant.SteamAppDetailURL) params := url.Values{} params.Add("appids", strconv.Itoa(id)) // params.Add("l", "schinese") baseURL.RawQuery = params.Encode() resp, err := utils.Request().SetHeaders(map[string]string{ "User-Agent": "", }).Get(baseURL.String()) if err != nil { return nil, err } var detail map[string]*model.SteamAppDetail if err = json.Unmarshal(resp.Body(), &detail); err != nil { return nil, err } if _, ok := detail[strconv.Itoa(id)]; !ok { return nil, fmt.Errorf("steam App not found: %d", id) } if detail[strconv.Itoa(id)] == nil { return nil, fmt.Errorf("steam App not found: %d", id) } jsonBytes, err := json.Marshal(detail[strconv.Itoa(id)]) if err == nil { _ = cache.Set(key, string(jsonBytes)) } return detail[strconv.Itoa(id)], nil } func GenerateSteamGameInfo(id int) (*model.GameInfo, error) { item := &model.GameInfo{} detail, err := GetSteamAppDetail(id) if err != nil { return nil, err } item.SteamID = id item.Name = detail.Data.Name item.Description = detail.Data.ShortDescription item.Cover = fmt.Sprintf("https://shared.cloudflare.steamstatic.com/store_item_assets/steam/apps/%v/library_600x900_2x.jpg", id) item.Developers = detail.Data.Developers item.Publishers = detail.Data.Publishers var screenshots []string for _, screenshot := range detail.Data.Screenshots { screenshots = append(screenshots, screenshot.PathFull) } item.Screenshots = screenshots return item, nil } func GetSteamIDByIGDBID(IGDBID int) (int, error) { key := fmt.Sprintf("steam_game:%d", IGDBID) val, exist := cache.Get(key) if exist { id, err := strconv.Atoi(val) if err != nil { return 0, err } return id, nil } var err error resp, err := igdbRequest(constant.IGDBWebsitesURL, fmt.Sprintf(`where game = %v; fields *; limit 500;`, IGDBID)) if err != nil { return 0, err } var data []struct { Game int `json:"game"` Url string `json:"url"` } if err = json.Unmarshal(resp.Body(), &data); err != nil { return 0, err } if len(data) == 0 { return 0, errors.New("not found") } for _, v := range data { if strings.HasPrefix(v.Url, "https://store.steampowered.com/app/") { regex := regexp.MustCompile(`https://store.steampowered.com/app/(\d+)/?`) idStr := regex.FindStringSubmatch(v.Url) if len(idStr) < 2 { return 0, errors.New("failed parse") } steamID, err := strconv.Atoi(idStr[1]) if err != nil { return 0, err } _ = cache.Set(key, strconv.Itoa(steamID)) return steamID, nil } } return 0, errors.New("not found") }