import { randomUUID } from "node:crypto"; import { siteSettings } from "@/lib/services/site-settings"; export interface CloneSource { id: string; name: string; furnidataUrl: string; nitroBaseUrl: string; iconBaseUrl: string; hotel: string; } const KEY = "clone_sources"; /** * Verified sources. Used as the default list and as the fallback when the * `clone_sources` site setting is empty. */ export const DEFAULT_SOURCES: CloneSource[] = [ { id: "default-habbo", name: "Habbo (IT)", furnidataUrl: "https://raw.githubusercontent.com/Izzxt/habbo-resource/master/gamedata/furnidata.json", nitroBaseUrl: "", iconBaseUrl: "", hotel: "it", }, { id: "default-habbo-com", name: "Habbo (COM)", furnidataUrl: "https://www.habbo.com/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "com", }, { id: "default-habbo-nl", name: "Habbo (NL)", furnidataUrl: "https://www.habbo.nl/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "nl", }, { id: "default-habbo-de", name: "Habbo (DE)", furnidataUrl: "https://www.habbo.de/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "de", }, { id: "default-habbo-fr", name: "Habbo (FR)", furnidataUrl: "https://www.habbo.fr/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "fr", }, { id: "default-habbo-es", name: "Habbo (ES)", furnidataUrl: "https://www.habbo.es/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "es", }, { id: "default-habbo-fi", name: "Habbo (FI)", furnidataUrl: "https://www.habbo.fi/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "fi", }, { id: "default-habbo-br", name: "Habbo (BR)", furnidataUrl: "https://www.habbo.com.br/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "com.br", }, { id: "default-habbo-tr", name: "Habbo (TR)", furnidataUrl: "https://www.habbo.com.tr/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "com.tr", }, { id: "default-wibbo", name: "Wibbo", furnidataUrl: "https://assets.wibbo.org/gamedata/FurnitureData.json", nitroBaseUrl: "https://assets.wibbo.org/bundled/furniture", iconBaseUrl: "https://assets.wibbo.org/icons", hotel: "com", }, { id: "default-hubba", name: "Hubba.cc", furnidataUrl: "https://nitro.hubba.cc/gamedata/FurnitureData.json", nitroBaseUrl: "https://nitro.hubba.cc/bundled/furniture", iconBaseUrl: "", hotel: "com", }, { id: "default-sodaho", name: "Soda Ho", furnidataUrl: "https://assets.sodaho.tel/gamedata/FurnitureData.json", nitroBaseUrl: "", iconBaseUrl: "", hotel: "com", }, { id: "default-leet", name: "Leet", furnidataUrl: "https://www.leet.ws/gamedata/furnidata.json", nitroBaseUrl: "https://www.leet.ws/nitro/bundled/furniture", iconBaseUrl: "https://www.leet.ws/nitro/icons", hotel: "com", }, { id: "default-hubbly", name: "Hubbly", furnidataUrl: "https://www.hubbly.pw/gamedata/furnidata.json", nitroBaseUrl: "https://www.hubbly.pw/nitro/bundled/furniture", iconBaseUrl: "https://www.hubbly.pw/nitro/icons", hotel: "com", }, { id: "default-habbletcity", name: "Habblet City", furnidataUrl: "https://www.habblet.city/gamedata/furnidata.json", nitroBaseUrl: "https://www.habblet.city/nitro/bundled/furniture", iconBaseUrl: "https://www.habblet.city/nitro/icons", hotel: "com", }, { id: "default-habbo-se", name: "Habbo (SE)", furnidataUrl: "https://www.habbo.se/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "se", }, { id: "default-habbo-no", name: "Habbo (NO)", furnidataUrl: "https://www.habbo.no/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "no", }, { id: "default-habbo-dk", name: "Habbo (DK)", furnidataUrl: "https://www.habbo.dk/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "dk", }, { id: "default-habbo-pt", name: "Habbo (PT)", furnidataUrl: "https://www.habbo.pt/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "pt", }, { id: "default-habbo-pl", name: "Habbo (PL)", furnidataUrl: "https://www.habbo.pl/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "pl", }, { id: "default-habbo-cz", name: "Habbo (CZ)", furnidataUrl: "https://www.habbo.cz/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "cz", }, { id: "default-habbo-hu", name: "Habbo (HU)", furnidataUrl: "https://www.habbo.hu/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "hu", }, { id: "default-habbo-ro", name: "Habbo (RO)", furnidataUrl: "https://www.habbo.ro/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ro", }, { id: "default-habbo-bg", name: "Habbo (BG)", furnidataUrl: "https://www.habbo.bg/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "bg", }, { id: "default-habbo-gr", name: "Habbo (GR)", furnidataUrl: "https://www.habbo.gr/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "gr", }, { id: "default-habbo-ie", name: "Habbo (IE)", furnidataUrl: "https://www.habbo.ie/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ie", }, { id: "default-habbo-uk", name: "Habbo (UK)", furnidataUrl: "https://www.habbo.co.uk/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "co.uk", }, { id: "default-habbo-au", name: "Habbo (AU)", furnidataUrl: "https://www.habbo.com.au/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "com.au", }, { id: "default-habbo-nz", name: "Habbo (NZ)", furnidataUrl: "https://www.habbo.co.nz/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "co.nz", }, { id: "default-habbo-za", name: "Habbo (ZA)", furnidataUrl: "https://www.habbo.co.za/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "co.za", }, { id: "default-habbo-jp", name: "Habbo (JP)", furnidataUrl: "https://www.habbo.jp/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "jp", }, { id: "default-habbo-kr", name: "Habbo (KR)", furnidataUrl: "https://www.habbo.kr/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "kr", }, { id: "default-habbo-ph", name: "Habbo (PH)", furnidataUrl: "https://www.habbo.ph/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ph", }, { id: "default-habbo-id", name: "Habbo (ID)", furnidataUrl: "https://www.habbo.co.id/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "co.id", }, { id: "default-habbo-my", name: "Habbo (MY)", furnidataUrl: "https://www.habbo.my/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "my", }, { id: "default-habbo-th", name: "Habbo (TH)", furnidataUrl: "https://www.habbo.th/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "th", }, { id: "default-habbo-vn", name: "Habbo (VN)", furnidataUrl: "https://www.habbo.vn/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "vn", }, { id: "default-habbo-sa", name: "Habbo (SA)", furnidataUrl: "https://www.habbo.sa/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "sa", }, { id: "default-habbo-ae", name: "Habbo (AE)", furnidataUrl: "https://www.habbo.ae/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ae", }, { id: "default-habbo-in", name: "Habbo (IN)", furnidataUrl: "https://www.habbo.in/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "in", }, { id: "default-habbo-mx", name: "Habbo (MX)", furnidataUrl: "https://www.habbo.mx/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "mx", }, { id: "default-habbo-ar", name: "Habbo (AR)", furnidataUrl: "https://www.habbo.ar/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ar", }, { id: "default-habbo-cl", name: "Habbo (CL)", furnidataUrl: "https://www.habbo.cl/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "cl", }, { id: "default-habbo-co", name: "Habbo (CO)", furnidataUrl: "https://www.habbo.co/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "co", }, { id: "default-habbo-pe", name: "Habbo (PE)", furnidataUrl: "https://www.habbo.pe/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "pe", }, { id: "default-habbo-ru", name: "Habbo (RU)", furnidataUrl: "https://www.habbo.ru/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ru", }, { id: "default-habbo-ua", name: "Habbo (UA)", furnidataUrl: "https://www.habbo.ua/gamedata/furnidata_json/1", nitroBaseUrl: "", iconBaseUrl: "", hotel: "ua", }, ]; export const DEFAULT_ICON_SOURCES: CloneSource[] = DEFAULT_SOURCES.filter( (s) => s.iconBaseUrl, ); export const DEFAULT_NITRO_SOURCES: CloneSource[] = DEFAULT_SOURCES.filter( (s) => s.nitroBaseUrl, ); export async function listSources(): Promise { const raw = (await siteSettings.get(KEY, "[]")) ?? "[]"; try { const arr = JSON.parse(raw); return Array.isArray(arr) && arr.length > 0 ? arr : DEFAULT_SOURCES; } catch { return DEFAULT_SOURCES; } } export async function upsertSource( src: Omit & { id?: string }, ): Promise { const sources = await listSources(); const entry: CloneSource = { id: src.id || randomUUID(), name: src.name.trim(), furnidataUrl: src.furnidataUrl.trim(), nitroBaseUrl: src.nitroBaseUrl.trim().replace(/\/+$/, ""), iconBaseUrl: src.iconBaseUrl.trim().replace(/\/+$/, ""), hotel: (src.hotel ?? "").trim(), }; const idx = sources.findIndex((s) => s.id === entry.id); if (idx >= 0) sources[idx] = entry; else sources.push(entry); await siteSettings.update(KEY, JSON.stringify(sources)); return entry; } export async function deleteSource(id: string): Promise { const sources = (await listSources()).filter((s) => s.id !== id); await siteSettings.update(KEY, JSON.stringify(sources)); } export async function getSource(id: string): Promise { return (await listSources()).find((s) => s.id === id) ?? null; }