Spaces:
Sleeping
Sleeping
| import path from "node:path"; | |
| import { listFiles, downloadFile } from "@huggingface/hub"; | |
| import { sha256 } from "../utils/sha256"; | |
| import { Mod } from "./mod"; | |
| import { Server } from "../server/server"; | |
| import { ModMetadata } from "./mod-metadata"; | |
| export class ModManager { | |
| private server: Server; | |
| private bucketId = "buckets/NSMP/NSMP-Server-Storage"; | |
| private bucketFolder = "mods"; | |
| constructor(server: Server) { | |
| this.server = server; | |
| } | |
| public async createModEndpoints(): Promise<void> { | |
| const mods: Mod[] = await this.getModList(); | |
| this.server.get("/mods/", (_req, res) => { | |
| res.send(JSON.stringify(mods)); | |
| }); | |
| this.server.get("/files/mods/:filename", async (req, res) => { | |
| try { | |
| const filename = req.params.filename; | |
| const mod = mods.find(m => m.filename === filename); | |
| if (!mod) { | |
| res.status(404).send("Mod not found in index"); | |
| return; | |
| } | |
| const blob = await downloadFile({ | |
| repo: this.bucketId, | |
| path: mod.path, | |
| accessToken: process.env.HF_TOKEN | |
| }); | |
| if (!blob) { | |
| res.status(404).send("Mod not found"); | |
| return; | |
| } | |
| const buffer = Buffer.from(await blob.arrayBuffer()); | |
| res.setHeader( | |
| "Content-Disposition", | |
| `attachment; filename="${filename}"` | |
| ); | |
| res.setHeader("Content-Type", "application/java-archive"); | |
| res.send(buffer); | |
| } catch (err) { | |
| console.error(err); | |
| res.status(500).send("Failed to fetch mod from bucket"); | |
| } | |
| }); | |
| } | |
| private async getModList(): Promise<Mod[]> { | |
| const mods: Mod[] = []; | |
| for await (const item of listFiles({ | |
| repo: this.bucketId, | |
| path: this.bucketFolder, | |
| recursive: true, | |
| accessToken: process.env.HF_TOKEN | |
| })) { | |
| if (item.type !== "file" || !item.path.toLowerCase().endsWith(".jar")) { | |
| continue; | |
| } | |
| const jarPath = item.path; | |
| const jsonPath = `${jarPath}.json`; | |
| const [jarBlob, metadataBlob] = await Promise.all([ | |
| downloadFile({ repo: this.bucketId, path: jarPath }), | |
| downloadFile({ repo: this.bucketId, path: jsonPath }), | |
| ]); | |
| if (!jarBlob || !metadataBlob) { | |
| continue; | |
| } | |
| const jarBuffer = Buffer.from(await jarBlob.arrayBuffer()); | |
| const metadataContent = Buffer.from(await metadataBlob.arrayBuffer()).toString("utf-8"); | |
| const metadata = JSON.parse(metadataContent) as ModMetadata; | |
| const hash = sha256(jarBuffer); | |
| const filename = path.basename(jarPath); | |
| mods.push({ | |
| name: metadata.name, | |
| filename, | |
| path: jarPath, | |
| sha256: hash, | |
| url: `https://NSMP-NSMP-Server.hf.space/files/mods/${encodeURIComponent(filename)}`, | |
| }); | |
| } | |
| return mods; | |
| } | |
| } |