From 86d59195ec3260c6c6868311cee10e11f1041424 Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 3 Aug 2026 21:23:13 +0200 Subject: [PATCH] Exclude badge items from catalog audit and repair checks Badge items use .gif files, not .nitro bundles, so they should not be flagged as missing .nitro or missing catalog entries. Also add badge logicType handling in furni-import.ts so badges get the correct interaction_type when imported. --- src/lib/services/catalog-audit.ts | 12 ++++++++++-- src/lib/services/furni-import.ts | 1 + src/lib/services/repair-icons.ts | 17 ++++++++++++----- src/lib/services/repair-nitros.ts | 17 ++++++++++++----- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/lib/services/catalog-audit.ts b/src/lib/services/catalog-audit.ts index 843e353c..a62e060e 100644 --- a/src/lib/services/catalog-audit.ts +++ b/src/lib/services/catalog-audit.ts @@ -154,16 +154,18 @@ export async function runCatalogAudit( item_name: string; public_name: string; type: string; + interaction_type: string; }>; try { const [rows] = (await db.execute(sql` - SELECT id, item_name, public_name, type FROM items_base ORDER BY id + SELECT id, item_name, public_name, type, interaction_type FROM items_base ORDER BY id `)) as unknown as [ Array<{ id: number; item_name: string; public_name: string; type: string; + interaction_type: string; }>, unknown, ]; @@ -242,7 +244,11 @@ export async function runCatalogAudit( }); // Only include items that actually have a .nitro asset — a catalog // entry for a furni without a bundle would be un-placeable in-game. - if (nitroSet.has(`${item.item_name}.nitro`)) { + // Badge items use .gif files, not .nitro bundles. + if ( + item.interaction_type !== "badge" && + nitroSet.has(`${item.item_name}.nitro`) + ) { missingCatalogEntries.push({ classname: item.item_name, itemId: item.id, @@ -311,6 +317,8 @@ export async function runCatalogAudit( const missingNitroClassnames: string[] = []; for (let i = 0; i < items.length; i++) { const item = items[i]; + // Badge items use .gif files, not .nitro bundles. + if (item.interaction_type === "badge") continue; if (!nitroSet.has(`${item.item_name}.nitro`)) { missingNitroClassnames.push(item.item_name); issues.push({ diff --git a/src/lib/services/furni-import.ts b/src/lib/services/furni-import.ts index 66dc0d04..ab3f626d 100644 --- a/src/lib/services/furni-import.ts +++ b/src/lib/services/furni-import.ts @@ -620,6 +620,7 @@ export async function importSingleFurni(params: { else if (logicType.includes("exchange")) interactionType = "exchange"; else if (logicType.includes("habbowheel")) interactionType = "habbowheel"; else if (logicType.includes("soundmachine")) interactionType = "jukebox"; + else if (logicType.includes("badge")) interactionType = "badge"; if (interactionType === "default" && /^wf_/.test(classname)) { interactionType = classname; diff --git a/src/lib/services/repair-icons.ts b/src/lib/services/repair-icons.ts index fa81ad13..1651b0cc 100644 --- a/src/lib/services/repair-icons.ts +++ b/src/lib/services/repair-icons.ts @@ -140,11 +140,14 @@ export async function repairMissingIcons( ...targets.mirrorDirs.map((d) => d.nitroDir), ]); - let items: Array<{ id: number; item_name: string }>; + let items: Array<{ id: number; item_name: string; interaction_type: string }>; try { const [rows] = (await db.execute(sql` - SELECT id, item_name FROM items_base ORDER BY id - `)) as unknown as [Array<{ id: number; item_name: string }>, unknown]; + SELECT id, item_name, interaction_type FROM items_base ORDER BY id + `)) as unknown as [ + Array<{ id: number; item_name: string; interaction_type: string }>, + unknown, + ]; items = rows; } catch (err) { onEvent?.({ @@ -157,7 +160,11 @@ export async function repairMissingIcons( const total = items.length; onEvent?.({ type: "started", total }); - const processItem = async (classname: string) => { + const processItem = async (classname: string, interactionType: string) => { + // Badge items use .gif icons, not .png icons. + if (interactionType === "badge") { + return { status: "skipped" } as const; + } const fileName = `${classname}_icon.png`; // A dir may already have the icon (e.g. the full gamedata) while the @@ -326,7 +333,7 @@ export async function repairMissingIcons( await runPool(items, REPAIR_CONCURRENCY, async (item, i) => { const classname = item.item_name; - const result = await processItem(classname); + const result = await processItem(classname, item.interaction_type); if (result.status === "skipped") { skipped++; onEvent?.({ diff --git a/src/lib/services/repair-nitros.ts b/src/lib/services/repair-nitros.ts index 8717402d..235f74a3 100644 --- a/src/lib/services/repair-nitros.ts +++ b/src/lib/services/repair-nitros.ts @@ -136,11 +136,14 @@ export async function repairMissingNitros( ...targets.mirrorDirs.map((d) => d.nitroDir), ]); - let items: Array<{ id: number; item_name: string }>; + let items: Array<{ id: number; item_name: string; interaction_type: string }>; try { const [rows] = (await db.execute(sql` - SELECT id, item_name FROM items_base ORDER BY id - `)) as unknown as [Array<{ id: number; item_name: string }>, unknown]; + SELECT id, item_name, interaction_type FROM items_base ORDER BY id + `)) as unknown as [ + Array<{ id: number; item_name: string; interaction_type: string }>, + unknown, + ]; items = rows; } catch (err) { onEvent?.({ @@ -153,7 +156,11 @@ export async function repairMissingNitros( const total = items.length; onEvent?.({ type: "started", total }); - const processItem = async (classname: string) => { + const processItem = async (classname: string, interactionType: string) => { + // Badge items use .gif files, not .nitro bundles. + if (interactionType === "badge") { + return { status: "skipped" } as const; + } const fileName = `${classname}.nitro`; const presentDirs = nitroDirs.filter((dir) => @@ -259,7 +266,7 @@ export async function repairMissingNitros( await runPool(items, REPAIR_CONCURRENCY, async (item, i) => { const classname = item.item_name; - const result = await processItem(classname); + const result = await processItem(classname, item.interaction_type); if (result.status === "skipped") { skipped++; onEvent?.({