hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/updater/cli.js
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2025-12-09 23:02:55 +0100
committerhachem <im@hachem.wtf>2025-12-09 23:02:55 +0100
commit5cc4c5a689e124e3951c80f0cfda0de4a797fec7 (patch)
tree7cb412c67f54636a4926161f4c948b68d87e74e8 /updater/cli.js
parent50e62e246fef7975866c244e08ead7c681d50349 (diff)
[add]: merging and refactor
Diffstat (limited to 'updater/cli.js')
-rw-r--r--updater/cli.js393
1 files changed, 0 insertions, 393 deletions
diff --git a/updater/cli.js b/updater/cli.js
deleted file mode 100644
index 8731ab6..0000000
--- a/updater/cli.js
+++ /dev/null
@@ -1,393 +0,0 @@
-#!/usr/bin/env node
-
-const readline = require("readline")
-const fs = require("fs-extra")
-const path = require("path")
-const { spawn } = require("child_process")
-
-const { LoadConfig } = require("../lib/config")
-const { GetModVersions, GetCompatibleVersion, DownloadFile } = require("../lib/modrinth")
-
-const pkg = require("../package.json")
-const config = LoadConfig()
-
-const
-{
- minecraft_version,
- fabric_loader_version,
- loader_meta_version,
- java_path,
- modrinth_mods
-} = config
-
-const javaCmd = java_path || "java"
-
-const serverDir = path.join(__dirname, "../server")
-const modsDir = path.join(serverDir, "mods")
-
-const deleteList =
-[
- "audioplayer_uploads",
- "config",
- "cache",
- "world",
- "logs",
- "banned-players.json",
- "server.properties",
- "banned-ips.json",
- "usercache.json",
- "whitelist.json",
- "ops.json",
- "eula.txt"
-]
-
-
-const EnsureDirs = async () =>
-{
- await fs.ensureDir(serverDir)
- await fs.ensureDir(modsDir)
-}
-
-const DownloadModrinthMods = async (modList, mcVersion) =>
-{
- const downloadedFiles = []
- const failedMods = []
-
- for (const slug of modList)
- {
- try
- {
- const versions = await GetModVersions(slug)
- if (!versions)
- {
- console.log(` [Modrinth] Could not get versions for ${slug}`)
- failedMods.push(slug)
- continue
- }
-
- const compatible = GetCompatibleVersion(versions, mcVersion, "fabric")
- if (!compatible)
- {
- console.log(` [Modrinth] No Fabric version for ${slug} on MC ${mcVersion}`)
- failedMods.push(slug)
- continue
- }
-
- const fileInfo = compatible.files[0]
- const jarUrl = fileInfo.url
- const filename = fileInfo.filename
- const destPath = path.join(modsDir, filename)
-
- console.log(` [Modrinth] Downloading ${slug} -> ${filename} ...`)
-
- const success = await DownloadFile(jarUrl, destPath)
- if (!success)
- {
- console.log(` [Modrinth] Couldn't download jar for ${slug}`)
- failedMods.push(slug)
- continue
- }
-
- downloadedFiles.push(destPath)
- console.log(` [Modrinth] Downloaded: ${filename}`)
- }
- catch (err)
- {
- console.error(` [Modrinth] Error downloading ${slug}:`, err.message)
- failedMods.push(slug)
- }
- }
-
- return { downloadedFiles, failedMods }
-}
-
-const DownloadFabricServer = async (mcVersion, loaderVersion, metaVersion) =>
-{
- const url = `https://meta.fabricmc.net/v2/versions/loader/${mcVersion}/${loaderVersion}/${metaVersion}/server/jar`
- const filename = "server.jar"
- const destPath = path.join(serverDir, filename)
-
- console.log(` [Fabric] Downloading Fabric server for MC ${mcVersion} ...`)
-
- const success = await DownloadFile(url, destPath)
- if (!success)
- {
- console.log(` [Fabric] Failed to download Fabric server JAR`)
- return null
- }
-
- console.log(` [Fabric] Downloaded: ${filename}`)
- return destPath
-}
-
-const RunServerAutoStop = (rl) =>
-{
- return new Promise((resolve) =>
- {
- const jarPath = path.join(serverDir, "server.jar")
-
- if (!fs.existsSync(jarPath))
- {
- console.log(" Server JAR not found.")
- resolve(false)
- return
- }
-
- const eulaPath = path.join(serverDir, "eula.txt")
- if (!fs.existsSync(eulaPath))
- {
- console.log(" Accepting EULA...")
- fs.writeFileSync(eulaPath, "eula=true\n")
- }
-
- console.log(" Starting server (will auto-stop after loading)...\n")
-
- rl.pause()
-
- let hadError = false
-
- const serverProcess = spawn(javaCmd, ["-jar", "server.jar", "nogui"],
- {
- cwd: serverDir,
- stdio: ["pipe", "pipe", "pipe"]
- })
-
- serverProcess.stdout.on("data", (data) =>
- {
- const line = data.toString()
- process.stdout.write(line)
-
- if (line.includes("Done"))
- {
- console.log("\n Server loaded, stopping...")
- serverProcess.stdin.write("stop\n")
- }
- })
-
- serverProcess.stderr.on("data", (data) =>
- {
- process.stderr.write(data.toString())
- })
-
- serverProcess.on("error", err =>
- {
- hadError = true
- console.error(" Failed to start server:", err.message)
- rl.resume()
- resolve(false)
- })
-
- serverProcess.on("close", () =>
- {
- if (!hadError)
- {
- console.log("\n Server stopped.")
- rl.resume()
- resolve(true)
- }
- })
- })
-}
-
-const DeletePostGenerate = async () =>
-{
- console.log(" Cleaning up server-generated files...")
-
- let removed = 0
- for (const item of deleteList)
- {
- const itemPath = path.join(serverDir, item)
-
- try
- {
- if (await fs.pathExists(itemPath))
- {
- await fs.remove(itemPath)
- removed++
- }
- }
- catch (err)
- {
- console.error(` Failed to remove ${item}:`, err.message)
- }
- }
-
- console.log(` Removed ${removed} items.`)
-}
-
-const CleanGenerated = async () =>
-{
- try
- {
- if (await fs.pathExists(serverDir))
- {
- await fs.remove(serverDir)
- console.log(" Removed server directory.")
- }
- else
- {
- console.log(" Server directory doesn't exist.")
- }
- }
- catch (err)
- {
- console.error(" Failed to remove server directory:", err.message)
- }
-}
-
-const CleanAll = async () =>
-{
- // Placeholder - will be implemented later
- console.log(" clean all - not implemented yet")
-}
-
-const ListMods = () =>
-{
- console.log(`\n Mods for MC ${minecraft_version}:\n`)
- for (const slug of modrinth_mods)
- console.log(` - ${slug}`)
- console.log(`\n Total: ${modrinth_mods.length} mods\n`)
-}
-
-const Generate = async (rl) =>
-{
- await EnsureDirs()
-
- console.log(`\n Generating server for MC ${minecraft_version}...\n`)
-
- const { downloadedFiles, failedMods } = await DownloadModrinthMods(modrinth_mods, minecraft_version)
- console.log(`\n ✅ Downloaded ${downloadedFiles.length} mods`)
- if (failedMods.length)
- console.log(` ❌ Failed: ${failedMods.join(", ")}`)
-
- const serverFile = await DownloadFabricServer(minecraft_version, fabric_loader_version, loader_meta_version)
-
- if (serverFile)
- {
- console.log("")
- await RunServerAutoStop(rl)
- await DeletePostGenerate()
- }
-
- console.log("")
-}
-
-const Merge = async () =>
-{
- // Placeholder - will be implemented later
- console.log(" merge - not implemented yet")
-}
-
-const ShowHelp = () =>
-{
- console.log(`
- Commands:
-
- list-mods List configured mods
- generate Download mods + server, run to generate files
- merge (coming soon)
- clean generated Remove generated server files
- clean all (coming soon)
- help Show this help
- exit Exit
-`)
-}
-
-const ProcessCommand = async (input, rl) =>
-{
- const parts = input.trim().toLowerCase().split(/\s+/)
- const cmd = parts[0]
- const arg = parts[1]
-
- switch (cmd)
- {
- case "list-mods":
- ListMods()
- break
-
- case "generate":
- await Generate(rl)
- break
-
- case "merge":
- await Merge()
- break
-
- case "clean":
- if (arg === "generated")
- await CleanGenerated()
- else if (arg === "all")
- await CleanAll()
- else
- console.log(" Usage: clean generated | clean all")
- break
-
- case "help":
- case "?":
- ShowHelp()
- break
-
- case "exit":
- case "quit":
- case "q":
- console.log(" Goodbye!\n")
- process.exit(0)
-
- case "":
- break
-
- default:
- console.log(` Unknown command: ${cmd}. Type 'help' for commands.`)
- }
-}
-
-const DrawBox = (lines) =>
-{
- const maxLen = Math.max(...lines.map(l => l.length))
- const pad = (str) => str + " ".repeat(maxLen - str.length)
-
- const top = "╔" + "═".repeat(maxLen + 2) + "╗"
- const bot = "╚" + "═".repeat(maxLen + 2) + "╝"
- const mid = lines.map(l => "║ " + pad(l) + " ║").join("\n ")
-
- return ` ${top}\n ${mid}\n ${bot}`
-}
-
-const Main = () =>
-{
- const title = `BENSON CLI v${pkg.version}`
- const subtitle = `Fabric Server for MC ${minecraft_version}`
-
- const box = DrawBox([title, subtitle])
-
- console.log(`
-${box}
-
- Type 'help' for commands.
-`)
-
- const rl = readline.createInterface
- ({
- input: process.stdin,
- output: process.stdout
- })
-
- const Prompt = () =>
- {
- rl.question("benson> ", async (input) =>
- {
- await ProcessCommand(input, rl)
- Prompt()
- })
- }
-
- rl.on("close", () =>
- {
- console.log("\n Goodbye!\n")
- process.exit(0)
- })
-
- Prompt()
-}
-
-Main()