You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

86 lines
3.0 KiB

import type { RefRecord, StaticAssetKind } from '../shared/types.js';
import { membershipDedupeArray } from '../shared/MembershipSet.js';
import { fileNameFromUrl } from './asset-tree.js';
import { getAssetKind, readJsonFile } from './file-util.js';
import { extractFlatJsonRefs, extractSceneRefs } from './scene-parser.js';
interface ScanMeta {
uuid: string;
url: string;
file: string;
kind: StaticAssetKind;
}
export async function scanAssetFile(fsPath: string): Promise<RefRecord[]> {
const url = await Editor.Message.request('asset-db', 'query-url', fsPath);
if (!url || String(url).includes('db://internal')) {
return [];
}
const uuid = await Editor.Message.request('asset-db', 'query-uuid', url);
if (!uuid) {
return [];
}
const kind = getAssetKind(fsPath);
if (!kind) {
return [];
}
const data = await readJsonFile(fsPath);
if (!data) {
return [];
}
const meta: ScanMeta = { uuid, url: String(url).split('@')[0], file: fsPath, kind };
if (kind === 'prefab' || kind === 'scene') {
return extractSceneRefs(data as never[], meta);
}
return extractFlatJsonRefs(data, meta);
}
/** 填充 targetUrl/targetName(批量,减少 asset-db 调用) */
export async function hydrateRefRecords(records: RefRecord[]): Promise<void> {
const uuids = membershipDedupeArray(records.map((r) => r.targetUuid));
const infoMap = new Map<string, { url: string; name: string }>();
for (const uuid of uuids) {
try {
const info = await Editor.Message.request('asset-db', 'query-asset-info', uuid);
if (info?.url) {
const mainUrl = String(info.url).split('@')[0];
infoMap.set(uuid, { url: mainUrl, name: fileNameFromUrl(mainUrl) });
}
} catch {
// ignore missing assets
}
}
for (const record of records) {
const info = infoMap.get(record.targetUuid);
if (info) {
record.targetUrl = info.url;
record.targetName = info.name;
} else {
record.targetUrl = '';
record.targetName = record.targetUuid.slice(0, 8);
}
}
}
export async function hydrateSourceNames(records: RefRecord[]): Promise<void> {
const uuids = membershipDedupeArray(records.map((r) => r.sourceUuid));
const infoMap = new Map<string, { url: string; name: string }>();
for (const uuid of uuids) {
try {
const info = await Editor.Message.request('asset-db', 'query-asset-info', uuid);
if (info?.url) {
const mainUrl = String(info.url).split('@')[0];
infoMap.set(uuid, { url: mainUrl, name: fileNameFromUrl(mainUrl) });
}
} catch {
// ignore
}
}
for (const record of records) {
const info = infoMap.get(record.sourceUuid);
if (info) {
record.sourceUrl = info.url;
record.sourceName = info.name;
}
}
}