145 lines
4.2 KiB
TypeScript
145 lines
4.2 KiB
TypeScript
import { existsSync } from "node:fs";
|
|
import path from "node:path";
|
|
import { siteSettings } from "@/lib/services/site-settings";
|
|
|
|
export const DEFAULT_NITRO_FILES_ROOT = path.join(
|
|
/*turbopackIgnore: true*/ path.dirname(process.cwd()),
|
|
"DEV",
|
|
"Nitro-Files",
|
|
);
|
|
export const DEFAULT_FURNI_ICON_DIR = path.join(
|
|
/*turbopackIgnore: true*/ process.cwd(),
|
|
"public/swf/dcr/hof_furni/icons",
|
|
);
|
|
export const DEFAULT_FURNI_SWF_DIR = path.join(
|
|
/*turbopackIgnore: true*/ process.cwd(),
|
|
"public/swf/dcr/hof_furni/swf",
|
|
);
|
|
export const DEFAULT_FURNI_NITRO_DIR = path.join(
|
|
/*turbopackIgnore: true*/ process.cwd(),
|
|
"public/nitro-assets/bundled/furniture",
|
|
);
|
|
|
|
export interface FurniAssetDirs {
|
|
swfDir: string;
|
|
iconDir: string;
|
|
nitroDir: string;
|
|
}
|
|
|
|
export interface FurniAssetWriteTargets extends FurniAssetDirs {
|
|
mirrorDirs: FurniAssetDirs[];
|
|
}
|
|
|
|
function normalizeDir(value: string | undefined, fallback: string): string {
|
|
const raw = value?.trim() || fallback;
|
|
let normalized = path.normalize(raw);
|
|
const root = path.parse(normalized).root;
|
|
while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
|
|
normalized = normalized.slice(0, -1);
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
function uniqueDirs(dirs: string[]): string[] {
|
|
const seen = new Set<string>();
|
|
const out: string[] = [];
|
|
for (const dir of dirs) {
|
|
const normalized = normalizeDir(dir, dir);
|
|
const key =
|
|
process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
if (seen.has(key)) continue;
|
|
seen.add(key);
|
|
out.push(normalized);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
export async function getNitroFilesRoot(): Promise<string> {
|
|
const configured = (await siteSettings.get("nitro_files_root", "")) ?? "";
|
|
if (configured.trim()) return normalizeDir(configured, configured);
|
|
|
|
return existsSync(/*turbopackIgnore: true*/ DEFAULT_NITRO_FILES_ROOT)
|
|
? normalizeDir(DEFAULT_NITRO_FILES_ROOT, DEFAULT_NITRO_FILES_ROOT)
|
|
: "";
|
|
}
|
|
|
|
function dirsFromNitroFilesRoot(root: string): FurniAssetDirs {
|
|
return {
|
|
swfDir: path.join(/*turbopackIgnore: true*/ root, "swf/dcr/hof_furni"),
|
|
iconDir: path.join(
|
|
/*turbopackIgnore: true*/ root,
|
|
"swf/dcr/hof_furni/icons",
|
|
),
|
|
nitroDir: path.join(
|
|
/*turbopackIgnore: true*/ root,
|
|
"nitro-assets/bundled/furniture",
|
|
),
|
|
};
|
|
}
|
|
|
|
export async function getFurniAssetDirs(): Promise<FurniAssetDirs> {
|
|
const [swfDir, iconDir, nitroDir] = await Promise.all([
|
|
siteSettings
|
|
.get("furni_swf_dir", DEFAULT_FURNI_SWF_DIR)
|
|
.then((v) => v ?? DEFAULT_FURNI_SWF_DIR),
|
|
siteSettings
|
|
.get("furni_icon_dir", DEFAULT_FURNI_ICON_DIR)
|
|
.then((v) => v ?? DEFAULT_FURNI_ICON_DIR),
|
|
siteSettings
|
|
.get("furni_nitro_dir", DEFAULT_FURNI_NITRO_DIR)
|
|
.then((v) => v ?? DEFAULT_FURNI_NITRO_DIR),
|
|
]);
|
|
|
|
return {
|
|
swfDir: normalizeDir(swfDir, DEFAULT_FURNI_SWF_DIR),
|
|
iconDir: normalizeDir(iconDir, DEFAULT_FURNI_ICON_DIR),
|
|
nitroDir: normalizeDir(nitroDir, DEFAULT_FURNI_NITRO_DIR),
|
|
};
|
|
}
|
|
|
|
export async function getFurniAssetWriteTargets(): Promise<FurniAssetWriteTargets> {
|
|
const primary = await getFurniAssetDirs();
|
|
const nitroFilesRoot = await getNitroFilesRoot();
|
|
const mirrorCandidates = nitroFilesRoot
|
|
? [dirsFromNitroFilesRoot(nitroFilesRoot)]
|
|
: [];
|
|
|
|
const primaryKey = {
|
|
swfDir:
|
|
process.platform === "win32"
|
|
? primary.swfDir.toLowerCase()
|
|
: primary.swfDir,
|
|
iconDir:
|
|
process.platform === "win32"
|
|
? primary.iconDir.toLowerCase()
|
|
: primary.iconDir,
|
|
nitroDir:
|
|
process.platform === "win32"
|
|
? primary.nitroDir.toLowerCase()
|
|
: primary.nitroDir,
|
|
};
|
|
|
|
const mirrorDirs = mirrorCandidates.filter((dirs) => {
|
|
const swfDir = normalizeDir(dirs.swfDir, dirs.swfDir);
|
|
const iconDir = normalizeDir(dirs.iconDir, dirs.iconDir);
|
|
const nitroDir = normalizeDir(dirs.nitroDir, dirs.nitroDir);
|
|
return (
|
|
(process.platform === "win32" ? swfDir.toLowerCase() : swfDir) !==
|
|
primaryKey.swfDir ||
|
|
(process.platform === "win32" ? iconDir.toLowerCase() : iconDir) !==
|
|
primaryKey.iconDir ||
|
|
(process.platform === "win32" ? nitroDir.toLowerCase() : nitroDir) !==
|
|
primaryKey.nitroDir
|
|
);
|
|
});
|
|
|
|
return {
|
|
...primary,
|
|
mirrorDirs: mirrorDirs.map((dirs) => ({
|
|
swfDir: uniqueDirs([dirs.swfDir])[0],
|
|
iconDir: uniqueDirs([dirs.iconDir])[0],
|
|
nitroDir: uniqueDirs([dirs.nitroDir])[0],
|
|
})),
|
|
};
|
|
}
|