docker-minecraft-server icon indicating copy to clipboard operation
docker-minecraft-server copied to clipboard

Additional mode for automatic CurseForge pack updates to download server pack rather than each mod individually

Open jschenke488 opened this issue 2 years ago • 1 comments

Enhancement Type

Improve an existing feature

Describe the enhancement

Most modpacks on CurseForge have mods that require manual downloads, so what if there was another mode for the automatic CurseForge updater to download the server pack instead? Environment variables could include pack ID, name of start script (possibly default to startserver.sh?), and whether Forge needs to be downloaded separately or if it's included. Example code to download the latest server pack in Node.js is below.

const axios = require('axios')
const fs = require('fs')
const { curseforgeAPIKey, packID } = require('./config.json') // tested with pack ID of 715572 (All the Mods 9)

// https://stackoverflow.com/a/18650828
function formatBytes(bytes, decimals = 2) {
    if (!+bytes) return '0 Bytes'

    const k = 1024
    const dm = decimals < 0 ? 0 : decimals
    const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']

    const i = Math.floor(Math.log(bytes) / Math.log(k))

    return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}

function downloadServerPack(downloadUrl) {
    axios.get(downloadUrl, {
        responseType: 'stream'
    }).then(response => {
        if (fs.existsSync('server-pack.zip')) fs.unlinkSync('server-pack.zip')
        response.data.pipe(fs.createWriteStream('server-pack.zip'))
    }).catch(err => console.error(err))
}

axios.get(`https://api.curseforge.com/v1/mods/${packID}`, {
        headers: {'x-api-key': curseforgeAPIKey}
    })
    .then(response => {
        const mainFileId = response.data.data.mainFileId
        axios.get(`https://api.curseforge.com/v1/mods/${packID}/files/${mainFileId}`, {
            headers: {'x-api-key': curseforgeAPIKey}
        }).then(response => {
            axios.get(`https://api.curseforge.com/v1/mods/${packID}/files/${response.data.data.serverPackFileId}`, {
                headers: {'x-api-key': curseforgeAPIKey}
            }).then(response => {
                console.log(`Downloading server pack (${formatBytes(Number(response.data.data.fileLength))})...`)
                downloadServerPack(response.data.data.downloadUrl)
            }).catch(err => console.error(err))
        }).catch(err => console.error(err))
    }).catch(err => console.error(err))

jschenke488 avatar Jul 24 '23 01:07 jschenke488

I have purposely decided to move away from server modpacks. They're already "supported" but I consider that feature deprecated

https://docker-minecraft-server.readthedocs.io/types-and-platforms/mod-platforms/curseforge/

Maintenance of that support is extremely frustrating since there is little consistency between the server file zip contents. Some don't even contain the mod files and instead implement their own custom download.

Be aware that the requirement of manually downloading is not a technical problem but rather honoring the requests of the mod authors in order for them to be able to make a little bit of money from the hard work they do. Using and maintaining a work around is just cheating them and creating more work for me...that I do for free.

itzg avatar Jul 24 '23 12:07 itzg