diff --git a/curseforge/curseforge.go b/curseforge/curseforge.go index 5501705..8df8fe4 100644 --- a/curseforge/curseforge.go +++ b/curseforge/curseforge.go @@ -117,7 +117,7 @@ var urlRegexes = [...]*regexp.Regexp{ regexp.MustCompile("^(?P[a-z][\\da-z\\-_]{0,127})$"), } -func parseSlugOrUrl(url string) (game string, category string, slug string, fileID int, err error) { +func parseSlugOrUrl(url string) (game string, category string, slug string, fileID uint32, err error) { for _, r := range urlRegexes { matches := r.FindStringSubmatch(url) if matches != nil { @@ -132,7 +132,9 @@ func parseSlugOrUrl(url string) (game string, category string, slug string, file } if i := r.SubexpIndex("fileID"); i >= 0 { if matches[i] != "" { - fileID, err = strconv.Atoi(matches[i]) + var f uint64 + f, err = strconv.ParseUint(matches[i], 10, 32) + fileID = uint32(f) } } return @@ -214,7 +216,7 @@ func createModFile(modInfo modInfo, fileInfo modFileInfo, index *core.Index, opt return index.RefreshFileWithHash(path, format, hash, true) } -func getSearchLoaderType(pack core.Pack) int { +func getSearchLoaderType(pack core.Pack) modloaderType { dependencies := pack.Versions _, hasFabric := dependencies["fabric"] @@ -235,7 +237,7 @@ func getSearchLoaderType(pack core.Pack) int { } } -func matchLoaderType(packLoaders []string, modLoaderType int) bool { +func matchLoaderType(packLoaders []string, modLoaderType modloaderType) bool { if len(packLoaders) == 0 || modLoaderType == modloaderTypeAny { return true } else { @@ -290,8 +292,8 @@ func matchGameVersions(mcVersion string, modMcVersions []string) bool { } type cfUpdateData struct { - ProjectID int `mapstructure:"project-id"` - FileID int `mapstructure:"file-id"` + ProjectID uint32 `mapstructure:"project-id"` + FileID uint32 `mapstructure:"file-id"` } func (u cfUpdateData) ToMap() (map[string]interface{}, error) { @@ -311,13 +313,13 @@ func (u cfUpdater) ParseUpdate(updateUnparsed map[string]interface{}) (interface type cachedStateStore struct { modInfo hasFileInfo bool - fileID int + fileID uint32 fileInfo modFileInfo } func (u cfUpdater) CheckUpdate(mods []core.Mod, mcVersion string, pack core.Pack) ([]core.UpdateCheck, error) { results := make([]core.UpdateCheck, len(mods)) - modIDs := make([]int, len(mods)) + modIDs := make([]uint32, len(mods)) modInfos := make([]modInfo, len(mods)) for i, v := range mods { @@ -438,7 +440,7 @@ func (u cfUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error { } type cfExportData struct { - ProjectID int `mapstructure:"project-id"` + ProjectID uint32 `mapstructure:"project-id"` } func (e cfExportData) ToMap() (map[string]interface{}, error) { @@ -461,9 +463,9 @@ func (c cfDownloader) GetFilesMetadata(mods []*core.Mod) ([]core.MetaDownloaderD } downloaderData := make([]core.MetaDownloaderData, len(mods)) - indexMap := make(map[int]int) + indexMap := make(map[uint32]int) projectMetadata := make([]cfUpdateData, len(mods)) - fileIDs := make([]int, len(mods)) + fileIDs := make([]uint32, len(mods)) for i, v := range mods { updateData, ok := v.GetParsedUpdateData("curseforge") if !ok { @@ -480,7 +482,7 @@ func (c cfDownloader) GetFilesMetadata(mods []*core.Mod) ([]core.MetaDownloaderD return nil, fmt.Errorf("failed to get CurseForge file metadata: %w", err) } - modIDsToLookup := make([]int, 0) + modIDsToLookup := make([]uint32, 0) fileNames := make([]string, len(mods)) for _, file := range fileData { if _, ok := indexMap[file.ModID]; !ok { @@ -509,7 +511,7 @@ func (c cfDownloader) GetFilesMetadata(mods []*core.Mod) ([]core.MetaDownloaderD downloaderData[indexMap[mod.ID]] = &cfDownloadMetadata{ noDistribution: true, // Inverted so the default value is not this (probably doesn't matter) name: mod.Name, - websiteUrl: mod.Links.WebsiteURL + "/files/" + strconv.Itoa(fileIDs[indexMap[mod.ID]]), + websiteUrl: mod.Links.WebsiteURL + "/files/" + strconv.FormatUint(uint64(fileIDs[indexMap[mod.ID]]), 10), fileName: fileNames[indexMap[mod.ID]], } } diff --git a/curseforge/detect.go b/curseforge/detect.go index a70b48a..3286a17 100644 --- a/curseforge/detect.go +++ b/curseforge/detect.go @@ -32,8 +32,8 @@ var detectCmd = &cobra.Command{ } // Walk files in the mods folder - var hashes []int - modPaths := make(map[int]string) + var hashes []uint32 + modPaths := make(map[uint32]string) err = filepath.Walk("mods", func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -51,8 +51,8 @@ var detectCmd = &cobra.Command{ return err } hash := getByteArrayHash(bytes) - hashes = append(hashes, int(hash)) - modPaths[int(hash)] = path + hashes = append(hashes, hash) + modPaths[hash] = path return nil }) if err != nil { @@ -132,8 +132,8 @@ func init() { curseforgeCmd.AddCommand(detectCmd) } -func getByteArrayHash(bytes []byte) uint64 { - return uint64(murmur.MurmurHash2(computeNormalizedArray(bytes), 1)) +func getByteArrayHash(bytes []byte) uint32 { + return murmur.MurmurHash2(computeNormalizedArray(bytes), 1) } func computeNormalizedArray(bytes []byte) []byte { diff --git a/curseforge/export.go b/curseforge/export.go index 168fb09..e09cbbe 100644 --- a/curseforge/export.go +++ b/curseforge/export.go @@ -238,7 +238,7 @@ func createModlist(zw *zip.Writer, mods []*core.Mod) error { continue } project := projectRaw.(cfUpdateData) - _, err = w.WriteString("
  • " + mod.Name + "
  • \r\n") + _, err = w.WriteString("
  • " + mod.Name + "
  • \r\n") if err != nil { return err } diff --git a/curseforge/import.go b/curseforge/import.go index b20ebb1..80cbbcd 100644 --- a/curseforge/import.go +++ b/curseforge/import.go @@ -185,7 +185,7 @@ var importCmd = &cobra.Command{ } modsList := packImport.Mods() - modIDs := make([]int, len(modsList)) + modIDs := make([]uint32, len(modsList)) for i, v := range modsList { modIDs[i] = v.ProjectID } @@ -198,17 +198,17 @@ var importCmd = &cobra.Command{ os.Exit(1) } - modInfosMap := make(map[int]modInfo) + modInfosMap := make(map[uint32]modInfo) for _, v := range modInfos { modInfosMap[v.ID] = v } // TODO: multithreading???? - modFileInfosMap := make(map[int]modFileInfo) + modFileInfosMap := make(map[uint32]modFileInfo) referencedModPaths := make([]string, 0, len(modsList)) successes := 0 - remainingFileIDs := make([]int, 0, len(modsList)) + remainingFileIDs := make([]uint32, 0, len(modsList)) // 1st pass: query mod metadata for every CurseForge file for _, v := range modsList { diff --git a/curseforge/install.go b/curseforge/install.go index 47d3714..7a7c80a 100644 --- a/curseforge/install.go +++ b/curseforge/install.go @@ -46,7 +46,7 @@ var installCmd = &cobra.Command{ game := gameFlag category := categoryFlag - var modID, fileID int + var modID, fileID uint32 var slug string // If mod/file IDs are provided in command line, use those @@ -122,7 +122,7 @@ var installCmd = &cobra.Command{ if len(fileInfoData.Dependencies) > 0 { var depsInstallable []installableDep - var depIDPendingQueue []int + var depIDPendingQueue []uint32 for _, dep := range fileInfoData.Dependencies { if dep.Type == dependencyTypeRequired { depIDPendingQueue = append(depIDPendingQueue, dep.ModID) @@ -133,7 +133,7 @@ var installCmd = &cobra.Command{ fmt.Println("Finding dependencies...") cycles := 0 - var installedIDList []int + var installedIDList []uint32 for len(depIDPendingQueue) > 0 && cycles < maxCycles { if installedIDList == nil { // Get modids of all mods @@ -278,14 +278,14 @@ func (r modResultsList) Len() int { return len(r) } -func searchCurseforgeInternal(searchTerm string, isSlug bool, game string, category string, mcVersion string, searchLoaderType int) (bool, modInfo) { +func searchCurseforgeInternal(searchTerm string, isSlug bool, game string, category string, mcVersion string, searchLoaderType modloaderType) (bool, modInfo) { if isSlug { fmt.Println("Looking up CurseForge slug...") } else { fmt.Println("Searching CurseForge...") } - var gameID, categoryID, classID int + var gameID, categoryID, classID uint32 if game == "minecraft" { gameID = 432 } @@ -308,7 +308,7 @@ func searchCurseforgeInternal(searchTerm string, isSlug bool, game string, categ fmt.Printf("Failed to lookup game %s: selected game does not have a public API!\n", game) os.Exit(1) } - gameID = int(v.ID) + gameID = v.ID break } } @@ -409,7 +409,7 @@ func searchCurseforgeInternal(searchTerm string, isSlug bool, game string, categ } } -func getLatestFile(modInfoData modInfo, mcVersion string, fileID int, packLoaders []string) (modFileInfo, error) { +func getLatestFile(modInfoData modInfo, mcVersion string, fileID uint32, packLoaders []string) (modFileInfo, error) { if fileID == 0 { var fileInfoData modFileInfo fileInfoObtained := false @@ -455,8 +455,8 @@ func getLatestFile(modInfoData modInfo, mcVersion string, fileID int, packLoader return fileInfoData, nil } -var addonIDFlag int -var fileIDFlag int +var addonIDFlag uint32 +var fileIDFlag uint32 var gameFlag string var categoryFlag string @@ -464,8 +464,8 @@ var categoryFlag string func init() { curseforgeCmd.AddCommand(installCmd) - installCmd.Flags().IntVar(&addonIDFlag, "addon-id", 0, "The CurseForge project ID to use") - installCmd.Flags().IntVar(&fileIDFlag, "file-id", 0, "The CurseForge file ID to use") + installCmd.Flags().Uint32Var(&addonIDFlag, "addon-id", 0, "The CurseForge project ID to use") + installCmd.Flags().Uint32Var(&fileIDFlag, "file-id", 0, "The CurseForge file ID to use") installCmd.Flags().StringVar(&gameFlag, "game", "minecraft", "The game to add files from (slug, as stored in URLs); the game in the URL takes precedence") installCmd.Flags().StringVar(&categoryFlag, "category", "", "The category to add files from (slug, as stored in URLs); the category in the URL takes precedence") } diff --git a/curseforge/open.go b/curseforge/open.go index fadb920..b929381 100644 --- a/curseforge/open.go +++ b/curseforge/open.go @@ -52,7 +52,7 @@ var openCmd = &cobra.Command{ } cfUpdateData := updateData.(cfUpdateData) fmt.Println("Opening browser...") - url := "https://www.curseforge.com/projects/" + strconv.Itoa(cfUpdateData.ProjectID) + url := "https://www.curseforge.com/projects/" + strconv.FormatUint(uint64(cfUpdateData.ProjectID), 10) err = open.Start(url) if err != nil { fmt.Println("Opening page failed, direct link:") diff --git a/curseforge/packinterop/manifest.go b/curseforge/packinterop/manifest.go index cd0c43c..eabfc3d 100644 --- a/curseforge/packinterop/manifest.go +++ b/curseforge/packinterop/manifest.go @@ -8,15 +8,15 @@ type cursePackMeta struct { ModLoaders []modLoaderDef `json:"modLoaders"` } `json:"minecraft"` ManifestType string `json:"manifestType"` - ManifestVersion int `json:"manifestVersion"` + ManifestVersion uint32 `json:"manifestVersion"` NameInternal string `json:"name"` Version string `json:"version"` Author string `json:"author"` - ProjectID int `json:"projectID"` + ProjectID uint32 `json:"projectID"` Files []struct { - ProjectID int `json:"projectID"` - FileID int `json:"fileID"` - Required bool `json:"required"` + ProjectID uint32 `json:"projectID"` + FileID uint32 `json:"fileID"` + Required bool `json:"required"` } `json:"files"` Overrides string `json:"overrides"` importSrc ImportPackSource diff --git a/curseforge/packinterop/minecraftinstance.go b/curseforge/packinterop/minecraftinstance.go index 6473534..f0a1802 100644 --- a/curseforge/packinterop/minecraftinstance.go +++ b/curseforge/packinterop/minecraftinstance.go @@ -17,10 +17,10 @@ type twitchInstalledPackMeta struct { } `json:"baseModLoader"` ModpackOverrides []string `json:"modpackOverrides"` ModsInternal []struct { - ID int `json:"addonID"` + ID uint32 `json:"addonID"` File struct { // I've given up on using this cached data, just going to re-request it - ID int `json:"id"` + ID uint32 `json:"id"` // Used to determine if the mod is optional-disabled FileNameOnDisk string } `json:"installedFile"` diff --git a/curseforge/packinterop/translation.go b/curseforge/packinterop/translation.go index 37f2e7c..f6e3091 100644 --- a/curseforge/packinterop/translation.go +++ b/curseforge/packinterop/translation.go @@ -63,23 +63,23 @@ func ReadMetadata(s ImportPackSource) ImportPackMetadata { // AddonFileReference is a struct to reference a single file on CurseForge type AddonFileReference struct { - ProjectID int - FileID int + ProjectID uint32 + FileID uint32 // OptionalDisabled is true if the file is optional and disabled (turned off in Twitch launcher) OptionalDisabled bool } -func WriteManifestFromPack(pack core.Pack, fileRefs []AddonFileReference, projectID int, out io.Writer) error { +func WriteManifestFromPack(pack core.Pack, fileRefs []AddonFileReference, projectID uint32, out io.Writer) error { files := make([]struct { - ProjectID int `json:"projectID"` - FileID int `json:"fileID"` - Required bool `json:"required"` + ProjectID uint32 `json:"projectID"` + FileID uint32 `json:"fileID"` + Required bool `json:"required"` }, len(fileRefs)) for i, fr := range fileRefs { files[i] = struct { - ProjectID int `json:"projectID"` - FileID int `json:"fileID"` - Required bool `json:"required"` + ProjectID uint32 `json:"projectID"` + FileID uint32 `json:"fileID"` + Required bool `json:"required"` }{ProjectID: fr.ProjectID, FileID: fr.FileID, Required: !fr.OptionalDisabled} } diff --git a/curseforge/request.go b/curseforge/request.go index e367796..977b1fa 100644 --- a/curseforge/request.go +++ b/curseforge/request.go @@ -85,16 +85,20 @@ func (c *cfApiClient) makePost(endpoint string, body io.Reader) (*http.Response, return resp, nil } +type fileType uint8 + //noinspection GoUnusedConst const ( - fileTypeRelease int = iota + 1 + fileTypeRelease fileType = iota + 1 fileTypeBeta fileTypeAlpha ) +type dependencyType uint8 + //noinspection GoUnusedConst const ( - dependencyTypeEmbedded int = iota + 1 + dependencyTypeEmbedded dependencyType = iota + 1 dependencyTypeOptional dependencyTypeRequired dependencyTypeTool @@ -102,10 +106,12 @@ const ( dependencyTypeInclude ) +type modloaderType uint8 + //noinspection GoUnusedConst const ( // modloaderTypeAny should not be passed to the API - it does not work - modloaderTypeAny int = iota + modloaderTypeAny modloaderType = iota modloaderTypeForge modloaderTypeCauldron modloaderTypeLiteloader @@ -131,9 +137,11 @@ var modloaderIds = [...]string{ "quilt", } +type hashAlgo uint8 + //noinspection GoUnusedConst const ( - hashAlgoSHA1 int = iota + 1 + hashAlgoSHA1 hashAlgo = iota + 1 hashAlgoMD5 ) @@ -142,7 +150,7 @@ type modInfo struct { Name string `json:"name"` Summary string `json:"summary"` Slug string `json:"slug"` - ID int `json:"id"` + ID uint32 `json:"id"` GameID uint32 `json:"gameId"` PrimaryCategoryID uint32 `json:"primaryCategoryId"` ClassID uint32 `json:"classId"` @@ -150,11 +158,11 @@ type modInfo struct { GameVersionLatestFiles []struct { // TODO: check how twitch launcher chooses which one to use, when you are on beta/alpha channel?! // or does it not have the concept of release channels?! - GameVersion string `json:"gameVersion"` - ID int `json:"fileId"` - Name string `json:"filename"` - FileType int `json:"releaseType"` - Modloader int `json:"modLoader"` + GameVersion string `json:"gameVersion"` + ID uint32 `json:"fileId"` + Name string `json:"filename"` + FileType fileType `json:"releaseType"` + Modloader modloaderType `json:"modLoader"` } `json:"latestFilesIndexes"` ModLoaders []string `json:"modLoaders"` Links struct { @@ -162,12 +170,12 @@ type modInfo struct { } `json:"links"` } -func (c *cfApiClient) getModInfo(modID int) (modInfo, error) { +func (c *cfApiClient) getModInfo(modID uint32) (modInfo, error) { var infoRes struct { Data modInfo `json:"data"` } - idStr := strconv.Itoa(modID) + idStr := strconv.FormatUint(uint64(modID), 10) resp, err := c.makeGet("/v1/mods/" + idStr) if err != nil { return modInfo{}, fmt.Errorf("failed to request addon data for ID %d: %w", modID, err) @@ -185,13 +193,13 @@ func (c *cfApiClient) getModInfo(modID int) (modInfo, error) { return infoRes.Data, nil } -func (c *cfApiClient) getModInfoMultiple(modIDs []int) ([]modInfo, error) { +func (c *cfApiClient) getModInfoMultiple(modIDs []uint32) ([]modInfo, error) { var infoRes struct { Data []modInfo `json:"data"` } modIDsData, err := json.Marshal(struct { - ModIDs []int `json:"modIds"` + ModIDs []uint32 `json:"modIds"` }{ ModIDs: modIDs, }) @@ -214,32 +222,31 @@ func (c *cfApiClient) getModInfoMultiple(modIDs []int) ([]modInfo, error) { // modFileInfo is a subset of the deserialised JSON response from the Curse API for mod files type modFileInfo struct { - ID int `json:"id"` - ModID int `json:"modId"` + ID uint32 `json:"id"` + ModID uint32 `json:"modId"` FileName string `json:"fileName"` FriendlyName string `json:"displayName"` Date time.Time `json:"fileDate"` - Length int `json:"fileLength"` - FileType int `json:"releaseType"` - // fileStatus? means latest/preferred? + Length uint64 `json:"fileLength"` + FileType fileType `json:"releaseType"` // According to the CurseForge API T&Cs, this must not be saved or cached DownloadURL string `json:"downloadUrl"` GameVersions []string `json:"gameVersions"` - Fingerprint int `json:"fileFingerprint"` + Fingerprint uint32 `json:"fileFingerprint"` Dependencies []struct { - ModID int `json:"modId"` - Type int `json:"relationType"` + ModID uint32 `json:"modId"` + Type dependencyType `json:"relationType"` } `json:"dependencies"` Hashes []struct { - Value string `json:"value"` - Algorithm int `json:"algo"` + Value string `json:"value"` + Algorithm hashAlgo `json:"algo"` } `json:"hashes"` } func (i modFileInfo) getBestHash() (hash string, hashFormat string) { // TODO: check if the hash is invalid (e.g. 0) - hash = strconv.Itoa(i.Fingerprint) + hash = strconv.FormatUint(uint64(i.Fingerprint), 10) hashFormat = "murmur2" hashPreferred := 0 @@ -263,13 +270,13 @@ func (i modFileInfo) getBestHash() (hash string, hashFormat string) { return } -func (c *cfApiClient) getFileInfo(modID int, fileID int) (modFileInfo, error) { +func (c *cfApiClient) getFileInfo(modID uint32, fileID uint32) (modFileInfo, error) { var infoRes struct { Data modFileInfo `json:"data"` } - modIDStr := strconv.Itoa(modID) - fileIDStr := strconv.Itoa(fileID) + modIDStr := strconv.FormatUint(uint64(modID), 10) + fileIDStr := strconv.FormatUint(uint64(fileID), 10) resp, err := c.makeGet("/v1/mods/" + modIDStr + "/files/" + fileIDStr) if err != nil { @@ -288,13 +295,13 @@ func (c *cfApiClient) getFileInfo(modID int, fileID int) (modFileInfo, error) { return infoRes.Data, nil } -func (c *cfApiClient) getFileInfoMultiple(fileIDs []int) ([]modFileInfo, error) { +func (c *cfApiClient) getFileInfoMultiple(fileIDs []uint32) ([]modFileInfo, error) { var infoRes struct { Data []modFileInfo `json:"data"` } fileIDsData, err := json.Marshal(struct { - FileIDs []int `json:"fileIds"` + FileIDs []uint32 `json:"fileIds"` }{ FileIDs: fileIDs, }) @@ -315,16 +322,16 @@ func (c *cfApiClient) getFileInfoMultiple(fileIDs []int) ([]modFileInfo, error) return infoRes.Data, nil } -func (c *cfApiClient) getSearch(searchTerm string, slug string, gameID int, classID int, categoryID int, gameVersion string, modloaderType int) ([]modInfo, error) { +func (c *cfApiClient) getSearch(searchTerm string, slug string, gameID uint32, classID uint32, categoryID uint32, gameVersion string, modloaderType modloaderType) ([]modInfo, error) { var infoRes struct { Data []modInfo `json:"data"` } q := url.Values{} - q.Set("gameId", strconv.Itoa(gameID)) + q.Set("gameId", strconv.FormatUint(uint64(gameID), 10)) q.Set("pageSize", "10") if classID != 0 { - q.Set("classId", strconv.Itoa(classID)) + q.Set("classId", strconv.FormatUint(uint64(classID), 10)) } if slug != "" { q.Set("slug", slug) @@ -332,7 +339,7 @@ func (c *cfApiClient) getSearch(searchTerm string, slug string, gameID int, clas // If classID and slug are provided, don't bother filtering by anything else (should be unique) if classID == 0 && slug == "" { if categoryID != 0 { - q.Set("categoryId", strconv.Itoa(categoryID)) + q.Set("categoryId", strconv.FormatUint(uint64(categoryID), 10)) } if searchTerm != "" { q.Set("searchFilter", searchTerm) @@ -341,7 +348,7 @@ func (c *cfApiClient) getSearch(searchTerm string, slug string, gameID int, clas q.Set("gameVersion", gameVersion) } if modloaderType != modloaderTypeAny { - q.Set("modLoaderType", strconv.Itoa(modloaderType)) + q.Set("modLoaderType", strconv.FormatUint(uint64(modloaderType), 10)) } } @@ -358,9 +365,11 @@ func (c *cfApiClient) getSearch(searchTerm string, slug string, gameID int, clas return infoRes.Data, nil } +type gameStatus uint8 + //noinspection GoUnusedConst const ( - gameStatusDraft int = iota + 1 + gameStatusDraft gameStatus = iota + 1 gameStatusTest gameStatusPendingReview gameStatusRejected @@ -368,18 +377,20 @@ const ( gameStatusLive ) +type gameApiStatus uint8 + //noinspection GoUnusedConst const ( - gameApiStatusPrivate int = iota + 1 + gameApiStatusPrivate gameApiStatus = iota + 1 gameApiStatusPublic ) type cfGame struct { - ID uint32 `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - Status int `json:"status"` - APIStatus int `json:"apiStatus"` + ID uint32 `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Status gameStatus `json:"status"` + APIStatus gameApiStatus `json:"apiStatus"` } func (c *cfApiClient) getGames() ([]cfGame, error) { @@ -401,18 +412,18 @@ func (c *cfApiClient) getGames() ([]cfGame, error) { } type cfCategory struct { - ID int `json:"id"` + ID uint32 `json:"id"` Slug string `json:"slug"` IsClass bool `json:"isClass"` - ClassID int `json:"classId"` + ClassID uint32 `json:"classId"` } -func (c *cfApiClient) getCategories(gameID int) ([]cfCategory, error) { +func (c *cfApiClient) getCategories(gameID uint32) ([]cfCategory, error) { var infoRes struct { Data []cfCategory `json:"data"` } - resp, err := c.makeGet("/v1/categories?gameId=" + strconv.Itoa(gameID)) + resp, err := c.makeGet("/v1/categories?gameId=" + strconv.FormatUint(uint64(gameID), 10)) if err != nil { return []cfCategory{}, fmt.Errorf("failed to retrieve category list for game %v: %w", gameID, err) } @@ -428,24 +439,24 @@ func (c *cfApiClient) getCategories(gameID int) ([]cfCategory, error) { type addonFingerprintResponse struct { IsCacheBuilt bool `json:"isCacheBuilt"` ExactMatches []struct { - ID int `json:"id"` + ID uint32 `json:"id"` File modFileInfo `json:"file"` LatestFiles []modFileInfo `json:"latestFiles"` } `json:"exactMatches"` - ExactFingerprints []int `json:"exactFingerprints"` - PartialMatches []int `json:"partialMatches"` + ExactFingerprints []uint32 `json:"exactFingerprints"` + PartialMatches []uint32 `json:"partialMatches"` PartialMatchFingerprints struct{} `json:"partialMatchFingerprints"` - InstalledFingerprints []int `json:"installedFingerprints"` - UnmatchedFingerprints []int `json:"unmatchedFingerprints"` + InstalledFingerprints []uint32 `json:"installedFingerprints"` + UnmatchedFingerprints []uint32 `json:"unmatchedFingerprints"` } -func (c *cfApiClient) getFingerprintInfo(hashes []int) (addonFingerprintResponse, error) { +func (c *cfApiClient) getFingerprintInfo(hashes []uint32) (addonFingerprintResponse, error) { var infoRes struct { Data addonFingerprintResponse `json:"data"` } hashesData, err := json.Marshal(struct { - Fingerprints []int `json:"fingerprints"` + Fingerprints []uint32 `json:"fingerprints"` }{ Fingerprints: hashes, }) diff --git a/modrinth/modrinth.go b/modrinth/modrinth.go index 8141621..51f3341 100644 --- a/modrinth/modrinth.go +++ b/modrinth/modrinth.go @@ -56,7 +56,7 @@ type Mod struct { } `json:"license"` ClientSide string `json:"client_side"` //The support range for the client mod - required, optional, unsupported, or unknown ServerSide string `json:"server_side"` //The support range for the server mod - required, optional, unsupported, or unknown - Downloads int `json:"downloads"` //The total number of downloads the mod has + Downloads uint32 `json:"downloads"` //The total number of downloads the mod has Categories []string `json:"categories"` //A list of the categories that the mod is in Versions []string `json:"versions"` //A list of ids for versions of the mod IconUrl string `json:"icon_url"` //The URL of the icon of the mod (Optional) @@ -74,7 +74,7 @@ type ModResult struct { Description string `json:"description"` //A short description of the mod Categories []string `json:"categories"` //A list of the categories the mod is in Versions []string `json:"versions"` //A list of the minecraft versions supported by the mod - Downloads int `json:"downloads"` //The total number of downloads for the mod + Downloads uint32 `json:"downloads"` //The total number of downloads for the mod PageUrl string `json:"page_url"` //A link to the mod's main page; IconUrl string `json:"icon_url"` //The url of the mod's icon AuthorUrl string `json:"author_url"` //The url of the mod's author @@ -89,9 +89,9 @@ type ModResult struct { type ModSearchResult struct { Hits []ModResult `json:"hits"` //The list of results - Offset int `json:"offset"` //The number of results that were skipped by the query - Limit int `json:"limit"` //The number of mods returned by the query - TotalHits int `json:"total_hits"` //The total number of mods that the query found + Offset uint32 `json:"offset"` //The number of results that were skipped by the query + Limit uint32 `json:"limit"` //The number of mods returned by the query + TotalHits uint32 `json:"total_hits"` //The total number of mods that the query found } type Version struct { @@ -103,7 +103,7 @@ type Version struct { VersionNumber string `json:"version_number"` //The version number. Ideally will follow semantic versioning Changelog string `json:"changelog"` //The changelog for this version of the mod. (Optional) DatePublished string `json:"date_published"` //The date that this version was published - Downloads int `json:"downloads"` //The number of downloads this specific version has + Downloads uint32 `json:"downloads"` //The number of downloads this specific version has VersionType string `json:"version_type"` //The type of the release - alpha, beta, or release Files []VersionFile `json:"files"` //A list of files available for download for this version //Dependencies []string `json:"dependencies"` //A list of specific versions of mods that this version depends on diff --git a/modrinth/pack.go b/modrinth/pack.go index 02050dd..874eaab 100644 --- a/modrinth/pack.go +++ b/modrinth/pack.go @@ -1,7 +1,7 @@ package modrinth type Pack struct { - FormatVersion int `json:"formatVersion"` + FormatVersion uint32 `json:"formatVersion"` Game string `json:"game"` VersionID string `json:"versionId"` Name string `json:"name"`