Skip to content

Commit

Permalink
add support for curseforge downloads
Browse files Browse the repository at this point in the history
  • Loading branch information
PssbleTrngle committed Aug 2, 2024
1 parent 3567603 commit 8e7c1a0
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
- name: Generate Data
if: steps.cache.outputs.cache-hit != 'true'
run: pnpm run gen
env:
CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }}

- name: Upload generated data as artifact
uses: actions/upload-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion pack/index.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ metafile = true

[[files]]
file = "mods/supplementaries.pw.toml"
hash = "1e6efbcc9bc0653d549548285eadab162435855b484fd4846adc2c38fade5aba"
hash = "35ac53f97504b5d71b607335d8560d41d11b4adba0f93db1fa1204132661be56"
metafile = true

[[files]]
Expand Down
8 changes: 4 additions & 4 deletions pack/mods/supplementaries.pw.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ filename = "supplementaries-1.20-2.8.17.jar"
side = "both"

[download]
url = "https://cdn.modrinth.com/data/fFEIiSDQ/versions/KAx6eLAF/supplementaries-1.20-2.8.17.jar"
hash-format = "sha1"
hash = "55ab43a1a9fc1f5ca4273c8c05403586f0c42fb6"
mode = "metadata:curseforge"

[update]
[update.curseforge]
file-id = 5458843
project-id = 412082
[update.modrinth]
mod-id = "fFEIiSDQ"
version = "KAx6eLAF"
2 changes: 1 addition & 1 deletion pack/pack.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pack-format = "packwiz:1.1.0"
[index]
file = "index.toml"
hash-format = "sha256"
hash = "74428f0139bec01afecb3a70f390e75ef514908305ecd8e95c81225c82dd7a9a"
hash = "c09ebcf220aa1bf3dcbddd9fac0293e6825a5155946e7bfa181fb10e3b0de795"

[versions]
forge = "47.3.0"
Expand Down
66 changes: 54 additions & 12 deletions src/install.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,51 @@ function verifySha(name, content, checksum) {
}
}

async function fetchFromCurseforge(endpoint) {
const token = process.env.CURSEFORGE_TOKEN

if (!token) throw new Error(`Unable to download from curseforge without passing a token`)

const response = await fetch(`https://api.curseforge.com/${endpoint}`, {
headers: {
'x-api-key': token,
},
})
if (!response.ok) throw new Error(response.statusText)

return response
}

async function getUrlFrom({ download, name, update }) {
if (download.url) return download.url
if (download.mode === 'metadata:curseforge' && update.curseforge) {
const response = await fetchFromCurseforge(
`v1/mods/${update.curseforge['project-id']}/files/${update.curseforge['file-id']}/download-url`
)
const { data } = await response.json()
return data
}

throw new Error(`unable to find url for ${name}`)
}

async function downloadFile(definition, outPath) {
if (!existsSync(dirname(outPath))) mkdirSync(dirname(outPath), { recursive: true })

const url = await getUrlFrom(definition)
const response = await fetch(url)
if (!response.ok) throw new Error(response.statusText)

const out = createWriteStream(outPath)

await new Promise((res, rej) => {
const readable = Readable.fromWeb(response.body)
readable.pipe(out)
readable.on('error', rej)
readable.on('end', res)
})
}

async function installPack(from, to, options) {
if (!from) throw new Error('input argument missing')
if (!to) throw new Error('output argument missing')
Expand All @@ -41,7 +86,7 @@ async function installPack(from, to, options) {

const index = readToml(join(packDir, pack.index.file))

await Promise.all(
const results = await Promise.allSettled(
index.files.map(async ({ file }) => {
const definition = readToml(join(packDir, file))

Expand All @@ -50,24 +95,21 @@ async function installPack(from, to, options) {
const outPath = join(to, dirname(file), definition.filename)

if (!existsSync(outPath) || options.includes('--overwrite')) {
if (!existsSync(dirname(outPath))) mkdirSync(dirname(outPath), { recursive: true })

const out = createWriteStream(outPath)
const response = await fetch(definition.download.url)

await new Promise((res, rej) => {
const readable = Readable.fromWeb(response.body)
readable.pipe(out)
readable.on('error', rej)
readable.on('end', res)
})
await downloadFile(definition, outPath)
} else {
console.log(` using cached file for ${outPath}`)
}

verifyFileSha(outPath, definition.download.hash)
})
)

const errors = results.filter(it => it.status === 'rejected')

if (errors.length > 0) {
errors.forEach(it => console.error(it.reason))
throw new Error(`${errors.length} files failed to download`)
}
}

const args = process.argv.slice(2)
Expand Down

0 comments on commit 8e7c1a0

Please sign in to comment.