fix: use configured furni source and catalog assets

This commit is contained in:
Simo committed 2026-08-02 14:22:05 +02:00
1 parent aed70db81f
commit c78f8812ad
25 files changed
+368 -129

No files matched your search

+13 -22
View File
@@ -1,16 +1,11 @@
import { promises as fs } from "node:fs";
import path from "node:path";
import { withAdmin } from "@/lib/api-handler";
import { apiOk } from "@/lib/api-response";
import { PERMS } from "@/lib/permissions";
const CATALOGUE_DIR = path.join(
/*turbopackIgnore: true*/ process.cwd(),
"public",
"swf",
"c_images",
"catalogue",
);
import {
catalogueAssetDirectories,
readCatalogueAssetFiles,
} from "@/lib/services/catalog-assets";
import { getGamedataRoot } from "@/lib/services/furni-asset-dirs";
export const GET = withAdmin(
{ permission: PERMS.CATALOG_VIEW },
@@ -23,18 +18,14 @@ export const GET = withAdmin(
const offset = Math.max(Number(sp.get("offset") || 0) || 0, 0);
const search = (sp.get("search") || "").trim().toLowerCase();
let icons: number[] = [];
try {
const files = await fs.readdir(CATALOGUE_DIR);
icons = files
.map((f) => /^icon_(\d+)\.(?:png|gif)$/i.exec(f))
.filter((m): m is RegExpExecArray => Boolean(m))
.map((m) => Number(m[1]))
.filter((n) => Number.isFinite(n))
.sort((a, b) => a - b);
} catch {
icons = [];
}
const directories = catalogueAssetDirectories(await getGamedataRoot());
const files = await readCatalogueAssetFiles(directories);
let icons = files
.map((f) => /^icon_(\d+)\.(?:png|gif)$/i.exec(f))
.filter((m): m is RegExpExecArray => Boolean(m))
.map((m) => Number(m[1]))
.filter((n) => Number.isFinite(n))
.sort((a, b) => a - b);
if (search) {
icons = icons.filter((id) => String(id).includes(search));
+15 -23
View File
@@ -1,16 +1,11 @@
import { promises as fs } from "node:fs";
import path from "node:path";
import { withAdmin } from "@/lib/api-handler";
import { apiOk } from "@/lib/api-response";
import { PERMS } from "@/lib/permissions";
const CATALOGUE_DIR = path.join(
/*turbopackIgnore: true*/ process.cwd(),
"public",
"swf",
"c_images",
"catalogue",
);
import {
catalogueAssetDirectories,
readCatalogueAssetFiles,
} from "@/lib/services/catalog-assets";
import { getGamedataRoot } from "@/lib/services/furni-asset-dirs";
export const GET = withAdmin(
{ permission: PERMS.CATALOG_VIEW },
@@ -25,20 +20,17 @@ export const GET = withAdmin(
const type = sp.get("type") || "all";
let names: string[] = [];
try {
const files = await fs.readdir(CATALOGUE_DIR);
const seen = new Set<string>();
for (const file of files) {
if (/^icon_\d+\./i.test(file)) continue;
const base = file.replace(/\.(png|gif|jpg|jpeg|webp)$/i, "");
if (!base || seen.has(base)) continue;
seen.add(base);
names.push(base);
}
names.sort((a, b) => a.localeCompare(b));
} catch {
names = [];
const directories = catalogueAssetDirectories(await getGamedataRoot());
const files = await readCatalogueAssetFiles(directories);
const seen = new Set<string>();
for (const file of files) {
if (/^icon_\d+\./i.test(file)) continue;
const base = file.replace(/\.(png|gif|jpg|jpeg|webp)$/i, "");
if (!base || seen.has(base)) continue;
seen.add(base);
names.push(base);
}
names.sort((a, b) => a.localeCompare(b));
if (type === "header") {
names = names.filter((n) => /header/i.test(n));
@@ -12,7 +12,7 @@ import {
readFurniData,
} from "@/lib/services/furni-data";
import { downloadFile, ensureDirectories } from "@/lib/services/furni-import";
import { getHabboItFurnidata } from "@/lib/services/habbo-furnidata-cache";
import { getOfficialHabboFurnidata } from "@/lib/services/habbo-furnidata-cache";
import { rcon } from "@/lib/services/rcon";
import { convertSwfToNitro } from "@/lib/services/swf-to-nitro";
@@ -62,7 +62,7 @@ export const POST = withAdmin(
}> = [];
// Load furnidata once for all items
const furnidata = await getHabboItFurnidata();
const furnidata = await getOfficialHabboFurnidata();
// Load existing FurnitureData.json classnames for dedup
const existingFD = (await readFurniData()) as {
@@ -204,7 +204,7 @@ export const POST = withAdmin(
spriteId: dbItem?.spriteId || 0,
dims: conversion.dimensions || { x: 1, y: 1, z: 1 },
metadata: conversion.metadata || null,
habboIt: fd || null,
officialHabbo: fd || null,
});
furniDataEntries.push({ entry, itemType });
fdClassnames.add(baseClassname);
@@ -10,7 +10,7 @@ import {
getFurnitureDataPath,
readFurniData,
} from "@/lib/services/furni-data";
import { lookupHabboIt } from "@/lib/services/habbo-furnidata-cache";
import { lookupOfficialHabboFurni } from "@/lib/services/habbo-furnidata-cache";
import { rcon } from "@/lib/services/rcon";
/**
@@ -86,9 +86,9 @@ export const POST = withAdmin(
for (const row of rows) {
try {
const classname = row.itemName;
let habboIt = null;
let officialHabbo = null;
try {
habboIt = await lookupHabboIt(classname);
officialHabbo = await lookupOfficialHabboFurni(classname);
} catch {
/* optional */
}
@@ -96,10 +96,10 @@ export const POST = withAdmin(
const entry = buildFurniEntry({
id: row.id,
classname,
revision: habboIt?.revision ?? 0,
category: habboIt?.category || "unknown",
name: row.publicName || habboIt?.name || classname,
description: habboIt?.description || "",
revision: officialHabbo?.revision ?? 0,
category: officialHabbo?.category || "unknown",
name: row.publicName || officialHabbo?.name || classname,
description: officialHabbo?.description || "",
spriteId: row.spriteId,
dims: {
x: row.width,
@@ -107,7 +107,7 @@ export const POST = withAdmin(
z: Math.round(Number(row.stackHeight)),
},
metadata: null,
habboIt,
officialHabbo,
});
entries.push({ entry, itemType: row.type === "i" ? "i" : "s" });
+5 -5
View File
@@ -18,7 +18,7 @@ import {
IMPORTED_PAGE_CAPTION_SAVE,
importSingleFurni,
} from "@/lib/services/furni-import";
import { getHabboItFurnidata } from "@/lib/services/habbo-furnidata-cache";
import { getOfficialHabboFurnidata } from "@/lib/services/habbo-furnidata-cache";
import { listFurniture } from "@/lib/services/habbofurni";
import { rcon } from "@/lib/services/rcon";
import { convertSwfToNitro } from "@/lib/services/swf-to-nitro";
@@ -183,7 +183,7 @@ export const GET = withAdmin(
const pageItems = missing.slice(start, start + perPage);
// Enrich with revision from official furnidata
const furnidata = await getHabboItFurnidata();
const furnidata = await getOfficialHabboFurnidata();
const items = pageItems.map((item) => {
const fd =
furnidata.get(item.item_name) ||
@@ -434,7 +434,7 @@ export const PATCH = withAdmin(
// Resolve revision: try furnidata first, then spriteId as fallback
let rev = item.revision || 0;
if (rev === 0) {
const furnidata = await getHabboItFurnidata();
const furnidata = await getOfficialHabboFurnidata();
const fd =
furnidata.get(item.classname) ||
furnidata.get(baseClassname) ||
@@ -516,7 +516,7 @@ export const PATCH = withAdmin(
.from(ItemsBase)
.where(eq(ItemsBase.itemName, item.classname))
.limit(1);
const furnidata = await getHabboItFurnidata();
const furnidata = await getOfficialHabboFurnidata();
const fd =
furnidata.get(item.classname) || furnidata.get(baseClassname);
const itemType = dbItem?.type === "i" ? "i" : "s";
@@ -531,7 +531,7 @@ export const PATCH = withAdmin(
spriteId: dbItem?.spriteId || 0,
dims: conversion.dimensions || { x: 1, y: 1, z: 1 },
metadata: conversion.metadata || null,
habboIt: fd || null,
officialHabbo: fd || null,
});
await appendFurniEntry(entry, itemType);
}