Files
EpicNext-Cms/src/types/furni.ts
T
openhands 4b7cb519df fix: furniture interaction detection and automatic catalog offer_id rebuild
Interaction detection:
- Trust SWF-derived sit/lay/stand flags only when the logic XML actually
  contains action data (new hasActions metadata); otherwise fall back to
  keyword detection so custom furni without <action> nodes are still
  classified correctly
- Add French/Dutch/German/Spanish/Italian keywords (chaise, banquette,
  stoel, silla, sedia, stuhl, tafel, mesa, ...) to sit/lay/stand detection
  with token-boundary matching to avoid false positives like bedside_table
- Unify interaction_modes_count priority: mechanic fixed modes, then raw
  animation state count, then sit/lay fallback, then keyword default
- Detect mechanic type even when real flags are not used

Catalog integrity:
- Skip duplicate catalog_items inserts in clone and upload imports
- Re-check live catalog rows before applying generated repair SQL
- Add rebuildCatalogOfferIds() which rebuilds every catalog_items.offer_id
  from the local FurnitureData.json (matched by entry id, then classname)
  and run it after every import path (single, batch, batch-regen, clone)
2026-08-21 13:39:21 +02:00

105 lines
2.1 KiB
TypeScript

export interface HabboFurniItem {
id: number;
classname: string;
type: string;
name: string;
description: string;
revision: number;
category: string;
}
export interface FurniListResult {
items: HabboFurniItem[];
meta: {
currentPage: number;
lastPage: number;
total: number;
perPage: number;
};
}
export interface FurniMetadata {
visualizationType: string;
logicType: string;
canstandon: boolean;
cansiton: boolean;
canlayon: boolean;
/** True when the SWF logic XML declared <action> nodes (flags authoritative). */
hasActions?: boolean;
specialtype: number;
defaultdir: number;
partcolors: { color: string[] };
}
export interface ConversionResult {
bundle: Buffer;
classname: string;
dimensions: { x: number; y: number; z: number };
directions: number[];
spriteCount: number;
warnings: string[];
metadata: FurniMetadata;
}
export interface BatchConversionItem {
swfBuffer: Buffer;
classname: string;
}
export interface BatchConversionResult {
classname: string;
success: boolean;
bundle?: Buffer;
dimensions?: { x: number; y: number; z: number };
directions?: number[];
spriteCount?: number;
warnings: string[];
error?: string;
}
export interface OfficialHabboFurniEntry {
id: number;
classname: string;
revision: number;
category: string;
defaultdir: number;
xdim: number;
ydim: number;
partcolors: { color: string[] };
name: string;
description: string;
specialtype: number;
canstandon: boolean;
cansiton: boolean;
canlayon: boolean;
furniline: string;
environment: string;
rare: boolean;
tradeable?: boolean;
bc?: boolean;
customparams?: string | null;
itemType: "s" | "i";
}
export interface HabboAssetBadge {
id: number;
code: string;
name: string;
description: string;
hotel: string;
url_habbo: string;
url_habboassets: string;
}
export interface ImportSingleResult {
ok: boolean;
itemId?: number;
catalogItemId?: number | null;
catalogUpdated?: boolean;
dimensions?: { x: number; y: number; z: number };
spriteCount?: number;
warnings: string[];
error?: string;
furniDataEntry?: { entry: Record<string, unknown>; itemType: string };
}