Documentation
¶
Overview ¶
Package curseforge is a client for the CurseForge Core API (v1): mod search, mods, files, categories and classes, download addresses, and curseforge:// install links.
The API key rides in the X-Api-Key header only, so no error or log line quotes it. A file whose author forbids distribution outside CurseForge has no download address; Mod.Restricted and the ErrNoDownload result of Client.DownloadURL report it, and this package never fetches around it. Mod files are never downloaded here.
Index ¶
- Constants
- Variables
- func AuthorFilesURL(projectID int) string
- func Denied(err error) bool
- type Asset
- type Category
- type Client
- func (c *Client) Categories(ctx context.Context, gameID, classID int) ([]Category, error)
- func (c *Client) Changelog(ctx context.Context, modID, fileID int) (string, error)
- func (c *Client) Classes(ctx context.Context, gameID int) ([]Category, error)
- func (c *Client) Description(ctx context.Context, id int) (string, error)
- func (c *Client) DownloadURL(ctx context.Context, modID, fileID int) (string, error)
- func (c *Client) File(ctx context.Context, modID, fileID int) (File, error)
- func (c *Client) Files(ctx context.Context, modID int, q FilesQuery) (FilesResult, error)
- func (c *Client) Mod(ctx context.Context, id int) (Mod, error)
- func (c *Client) Mods(ctx context.Context, ids []int) ([]Mod, error)
- func (c *Client) Search(ctx context.Context, q SearchQuery) (SearchResult, error)
- type Config
- type Dependency
- type File
- type FilesQuery
- type FilesResult
- type Hash
- type Mod
- type Pagination
- type Ref
- type SearchQuery
- type SearchResult
- type UploadConfig
- type Uploader
Constants ¶
const ( // BaseURL is the real API. BaseURL = "https://api.curseforge.com/v1" // MaxWindow is how deep the API pages: Index plus PageSize may not pass it. MaxWindow = 10000 // MaxPageSize is the most mods one Search request returns. MaxPageSize = 50 )
const ( SortFeatured = 1 SortPopularity = 2 SortLastUpdated = 3 SortName = 4 SortAuthor = 5 SortTotalDownloads = 6 SortCategory = 7 SortGameVersion = 8 SortEarlyAccess = 9 SortFeaturedRelease = 10 SortReleasedDate = 11 SortRating = 12 )
Values of ModsSearchSortField (https://docs.curseforge.com/rest-api/#tocS_ModsSearchSortField).
const ( ReleaseStable = 1 ReleaseBeta = 2 ReleaseAlpha = 3 )
Values of FileReleaseType.
const ( RelationEmbeddedLibrary = 1 RelationOptional = 2 RelationRequired = 3 RelationTool = 4 RelationIncompatible = 5 RelationInclude = 6 )
Values of FileRelationType.
const ( HashSHA1 = 1 HashMD5 = 2 )
Values of HashAlgo.
const ( StatusNew = 1 StatusChangesRequired = 2 StatusUnderSoftReview = 3 StatusApproved = 4 StatusRejected = 5 StatusChangesMade = 6 StatusInactive = 7 StatusAbandoned = 8 StatusDeleted = 9 StatusUnderReview = 10 )
Values of ModStatus.
const Scheme = "curseforge"
Scheme is the scheme of the site's Install button.
Variables ¶
var ( // ErrNoKey means the Client has no API key; nothing is sent. ErrNoKey = errors.New("curseforge: no API key") // ErrBeyondWindow means a search asked past MaxWindow. ErrBeyondWindow = errors.New("curseforge: search window exceeded") // ErrNoDownload means the API gave no download address for a file: its author forbids downloads outside // CurseForge. ErrNoDownload = errors.New("curseforge: file has no download address") )
Functions ¶
func AuthorFilesURL ¶ added in v0.3.0
AuthorFilesURL is the author-site page that lists a project's files.
Types ¶
type Asset ¶
type Asset struct {
ID int `json:"id"`
ModID int `json:"modId"`
Title string `json:"title"`
Description string `json:"description"`
ThumbnailURL string `json:"thumbnailUrl"`
URL string `json:"url"`
}
Asset is an image of a mod.
type Category ¶
type Category struct {
ID int `json:"id"`
GameID int `json:"gameId"`
Name string `json:"name"`
Slug string `json:"slug"`
URL string `json:"url"`
IconURL string `json:"iconUrl"`
DateModified string `json:"dateModified"`
IsClass bool `json:"isClass"`
ClassID int `json:"classId"`
ParentCategoryID int `json:"parentCategoryId"`
DisplayIndex int `json:"displayIndex"`
}
Category is a category, or when IsClass is true a class (a top-level kind of content such as "Mods").
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client calls the CurseForge API. It holds no state beyond its configuration, so it is safe for concurrent use and cheap to build again when the key changes.
func (*Client) Categories ¶
Categories lists the categories of one class of a game.
func (*Client) Classes ¶
Classes lists a game's classes (top-level kinds of content, such as "Mods").
func (*Client) Description ¶
Description reads a project's long description, which is HTML.
func (*Client) DownloadURL ¶
DownloadURL asks the API for a file's address. A refusal (see Denied) or an empty answer means the author forbids downloads outside CurseForge; the empty answer is ErrNoDownload.
func (*Client) Files ¶
func (c *Client) Files(ctx context.Context, modID int, q FilesQuery) (FilesResult, error)
Files lists a project's files. A zero PageSize is 50, the API's maximum.
func (*Client) Mods ¶
Mods reads many projects with their latest files in one request (POST /mods). The API caps the batch; split long lists. A mod the API does not know is absent from the answer.
func (*Client) Search ¶
func (c *Client) Search(ctx context.Context, q SearchQuery) (SearchResult, error)
Search lists mods. A ClassID restricts the search to that class.
type Config ¶
type Config struct {
// APIKey is sent in the X-Api-Key header. Empty makes every call fail with ErrNoKey.
APIKey string
// HTTP sends every request; nil means http.DefaultClient. Redirects to another origin are refused so the key
// stays with the API.
HTTP *http.Client
// BaseURL is the API; empty means BaseURL.
BaseURL string
// UserAgent is sent with every request when set.
UserAgent string
}
Config is what a Client is built from.
type Dependency ¶
type Dependency struct {
ModID int `json:"modId"`
// RelationType is one of the Relation constants.
RelationType int `json:"relationType"`
}
Dependency is a relation between a file and another mod.
type File ¶
type File struct {
ID int `json:"id"`
GameID int `json:"gameId"`
ModID int `json:"modId"`
IsAvailable bool `json:"isAvailable"`
DisplayName string `json:"displayName"`
FileName string `json:"fileName"`
// ReleaseType is ReleaseStable, ReleaseBeta or ReleaseAlpha.
ReleaseType int `json:"releaseType"`
FileStatus int `json:"fileStatus"`
Hashes []Hash `json:"hashes"`
FileDate string `json:"fileDate"`
FileLength int64 `json:"fileLength"`
DownloadCount int64 `json:"downloadCount"`
// DownloadURL is empty when the author forbids distribution outside CurseForge.
DownloadURL string `json:"downloadUrl"`
GameVersions []string `json:"gameVersions"`
Dependencies []Dependency `json:"dependencies"`
}
File is one published file of a mod.
func Newest ¶
Newest picks the newest available file, keeping to files for one of gameVersions when it names any. With maxRelease ReleaseStable a stable file wins over a newer beta, and a mod with no stable file yields its newest other one; a higher maxRelease takes the newest file whose release type is at most maxRelease.
type FilesQuery ¶
FilesQuery narrows Files. Zero fields are not sent.
type FilesResult ¶
type FilesResult struct {
Files []File `json:"data"`
Pagination Pagination `json:"pagination"`
}
FilesResult is one page of a mod's files.
type Hash ¶
type Hash struct {
Value string `json:"value"`
// Algo is HashSHA1 or HashMD5.
Algo int `json:"algo"`
}
Hash is one checksum of a file.
type Mod ¶
type Mod struct {
ID int `json:"id"`
GameID int `json:"gameId"`
Name string `json:"name"`
Slug string `json:"slug"`
Summary string `json:"summary"`
Status int `json:"status"`
DownloadCount int `json:"downloadCount"`
ThumbsUpCount int `json:"thumbsUpCount"`
PrimaryCategoryID int `json:"primaryCategoryId"`
ClassID int `json:"classId"`
MainFileID int `json:"mainFileId"`
DateCreated string `json:"dateCreated"`
DateModified string `json:"dateModified"`
DateReleased string `json:"dateReleased"`
// AllowModDistribution is nil when the API did not say; false forbids downloads outside CurseForge.
AllowModDistribution *bool `json:"allowModDistribution"`
// IsAvailable is what the API said, or true when it omitted the field. Use Available.
IsAvailable bool `json:"isAvailable"`
IsFeatured bool `json:"isFeatured"`
Links struct {
WebsiteURL string `json:"websiteUrl"`
WikiURL string `json:"wikiUrl"`
IssuesURL string `json:"issuesUrl"`
SourceURL string `json:"sourceUrl"`
} `json:"links"`
Authors []struct {
ID int `json:"id"`
Name string `json:"name"`
URL string `json:"url"`
} `json:"authors"`
Logo Asset `json:"logo"`
Screenshots []Asset `json:"screenshots"`
Categories []Category `json:"categories"`
LatestFiles []File `json:"latestFiles"`
// contains filtered or unexported fields
}
Mod is a CurseForge project. Dates are the API's RFC 3339 strings, which compare correctly as text.
func (Mod) Available ¶ added in v0.2.0
Available reports that the mod can be used: false only when the API said isAvailable: false. A mod built in code without that answer is available.
func (Mod) CategoryNames ¶
CategoryNames lists the names of the mod's categories.
func (Mod) Restricted ¶
Restricted reports that the author forbids downloads outside CurseForge. An unknown flag is not restricted.
func (*Mod) UnmarshalJSON ¶ added in v0.2.0
UnmarshalJSON reads a Mod and remembers whether the API sent isAvailable.
type Pagination ¶
type Pagination struct {
Index int `json:"index"`
PageSize int `json:"pageSize"`
ResultCount int `json:"resultCount"`
TotalCount int `json:"totalCount"`
}
Pagination is the position of a page within a result.
type Ref ¶
type Ref struct {
Project, File int
}
Ref names one file of a project in an install link.
type SearchQuery ¶
type SearchQuery struct {
GameID int
ClassID int
// CategoryIDs keeps mods in every listed category (the API ANDs them; at most 10).
CategoryIDs []int
GameVersion string
Text string
// SortField is one of the Sort constants; zero keeps the API's default.
SortField int
// Ascending reverses the API's default descending order.
Ascending bool
// Index is the offset of the first mod and PageSize the page length, at most MaxPageSize; zero PageSize is 50.
Index, PageSize int
}
SearchQuery is one /mods/search request. GameID is required; zero fields are not sent.
type SearchResult ¶
type SearchResult struct {
Mods []Mod `json:"data"`
Pagination Pagination `json:"pagination"`
}
SearchResult is one page of mods.
type UploadConfig ¶ added in v0.3.0
type UploadConfig struct {
// Token is the author's upload token, sent in the X-Api-Token header. It is not the API key of Config.
Token string
// BaseURL is the origin of the game's upload API, such as https://minecraft.curseforge.com; it has no default
// because each game answers on its own host.
BaseURL string
// HTTP sends every request; nil means http.DefaultClient. Redirects to another origin are refused so the token
// stays with the upload host.
HTTP *http.Client
// UserAgent is sent with every request when set.
UserAgent string
}
UploadConfig is what an Uploader is built from.
type Uploader ¶ added in v0.3.0
type Uploader struct {
// contains filtered or unexported fields
}
Uploader publishes a file to a CurseForge project through the author upload API.
func NewUploader ¶ added in v0.3.0
func NewUploader(cfg UploadConfig) *Uploader
NewUploader builds an Uploader.
func (*Uploader) Upload ¶ added in v0.3.0
func (u *Uploader) Upload(ctx context.Context, path string, projectID int, displayName, changelog string) (int, error)
Upload sends the zip at path to the project as a release named displayName, with changelog as markdown, and returns the new file's id. A 401 or 403 is a *httpkit.StatusError that Denied matches, and a 429 a *httpkit.RateLimitError.