336 lines
11 KiB
TypeScript
336 lines
11 KiB
TypeScript
import type { Match3DAgentSessionSnapshot } from '../../../packages/shared/src/contracts/match3dAgent';
|
|
import type { Match3DRunSnapshot } from '../../../packages/shared/src/contracts/match3dRuntime';
|
|
import type {
|
|
Match3DGeneratedBackgroundAsset,
|
|
Match3DGeneratedItemAsset,
|
|
Match3DWorkProfile,
|
|
Match3DWorkSummary,
|
|
} from '../../../packages/shared/src/contracts/match3dWorks';
|
|
import {
|
|
hasMatch3DGeneratedImageAsset,
|
|
mergeMatch3DGeneratedItemAssetsForRuntime,
|
|
normalizeMatch3DGeneratedItemAssetsForRuntime,
|
|
} from '../../services/match3dGeneratedModelCache';
|
|
import {
|
|
isMatch3DGalleryEntry,
|
|
mapMatch3DWorkToPlatformGalleryCard,
|
|
type PlatformPublicGalleryCard,
|
|
} from '../rpg-entry/rpgEntryWorldPresentation';
|
|
|
|
export function mapMatch3DWorkToPublicWorkDetail(
|
|
item: Match3DWorkSummary,
|
|
): PlatformPublicGalleryCard {
|
|
return mapMatch3DWorkToPlatformGalleryCard(
|
|
normalizeMatch3DWorkForRuntimeUi(item),
|
|
);
|
|
}
|
|
|
|
export function mapPublicWorkDetailToMatch3DWork(
|
|
entry: PlatformPublicGalleryCard,
|
|
): Match3DWorkSummary | null {
|
|
if (!isMatch3DGalleryEntry(entry)) {
|
|
return null;
|
|
}
|
|
|
|
return promoteMatch3DGeneratedBackgroundAsset({
|
|
workId: entry.workId,
|
|
profileId: entry.profileId,
|
|
ownerUserId: entry.ownerUserId,
|
|
sourceSessionId:
|
|
'sourceSessionId' in entry && typeof entry.sourceSessionId === 'string'
|
|
? entry.sourceSessionId
|
|
: null,
|
|
gameName: entry.worldName,
|
|
themeText: entry.themeTags[0] ?? '经典消除',
|
|
summary: entry.summaryText,
|
|
tags: entry.themeTags,
|
|
coverImageSrc: entry.coverImageSrc,
|
|
referenceImageSrc: null,
|
|
clearCount: 12,
|
|
difficulty: 4,
|
|
publicationStatus: 'published',
|
|
playCount: entry.playCount ?? 0,
|
|
updatedAt: entry.updatedAt,
|
|
publishedAt: entry.publishedAt,
|
|
publishReady: true,
|
|
backgroundPrompt: entry.backgroundPrompt ?? null,
|
|
backgroundImageSrc: entry.backgroundImageSrc ?? null,
|
|
backgroundImageObjectKey: entry.backgroundImageObjectKey ?? null,
|
|
generatedBackgroundAsset:
|
|
entry.generatedBackgroundAsset ??
|
|
findMatch3DGeneratedBackgroundAsset(entry.generatedItemAssets) ??
|
|
null,
|
|
generatedItemAssets: normalizeMatch3DGeneratedItemAssetsForRuntime(
|
|
entry.generatedItemAssets ?? [],
|
|
),
|
|
});
|
|
}
|
|
|
|
export function findMatch3DGeneratedBackgroundAsset(
|
|
generatedItemAssets: readonly Match3DGeneratedItemAsset[] | null | undefined,
|
|
): Match3DGeneratedBackgroundAsset | null {
|
|
return (
|
|
generatedItemAssets
|
|
?.map((asset) => asset.backgroundAsset ?? null)
|
|
.find(Boolean) ?? null
|
|
);
|
|
}
|
|
|
|
export function promoteMatch3DGeneratedBackgroundAsset<
|
|
T extends Pick<
|
|
Match3DWorkSummary,
|
|
| 'backgroundPrompt'
|
|
| 'backgroundImageSrc'
|
|
| 'backgroundImageObjectKey'
|
|
| 'generatedBackgroundAsset'
|
|
| 'generatedItemAssets'
|
|
>,
|
|
>(profile: T): T {
|
|
const backgroundAsset =
|
|
profile.generatedBackgroundAsset ??
|
|
findMatch3DGeneratedBackgroundAsset(profile.generatedItemAssets);
|
|
if (!backgroundAsset) {
|
|
return profile;
|
|
}
|
|
|
|
return {
|
|
...profile,
|
|
backgroundPrompt:
|
|
profile.backgroundPrompt ?? backgroundAsset.prompt ?? null,
|
|
backgroundImageSrc:
|
|
profile.backgroundImageSrc ??
|
|
backgroundAsset.imageSrc ??
|
|
backgroundAsset.imageObjectKey ??
|
|
null,
|
|
backgroundImageObjectKey:
|
|
profile.backgroundImageObjectKey ??
|
|
backgroundAsset.imageObjectKey ??
|
|
backgroundAsset.imageSrc ??
|
|
null,
|
|
generatedBackgroundAsset:
|
|
profile.generatedBackgroundAsset ?? backgroundAsset,
|
|
};
|
|
}
|
|
|
|
export function normalizeMatch3DWorkForRuntimeUi<T extends Match3DWorkSummary>(
|
|
profile: T,
|
|
): T {
|
|
return promoteMatch3DGeneratedBackgroundAsset({
|
|
...profile,
|
|
generatedItemAssets: normalizeMatch3DGeneratedItemAssetsForRuntime(
|
|
profile.generatedItemAssets,
|
|
),
|
|
});
|
|
}
|
|
|
|
export function mapMatch3DWorksForRuntimeUi<T extends Match3DWorkSummary>(
|
|
profiles: readonly T[],
|
|
): T[] {
|
|
return profiles.map(normalizeMatch3DWorkForRuntimeUi);
|
|
}
|
|
|
|
export function buildMatch3DProfileFromSession(
|
|
session: Match3DAgentSessionSnapshot | null,
|
|
): Match3DWorkProfile | null {
|
|
const draft = session?.draft;
|
|
if (!session || !draft?.profileId) {
|
|
return null;
|
|
}
|
|
|
|
const now = session.updatedAt || new Date().toISOString();
|
|
const generatedItemAssets = normalizeMatch3DGeneratedItemAssetsForRuntime(
|
|
draft.generatedItemAssets,
|
|
);
|
|
return promoteMatch3DGeneratedBackgroundAsset({
|
|
workId: draft.profileId,
|
|
profileId: draft.profileId,
|
|
ownerUserId: 'current-user',
|
|
sourceSessionId: session.sessionId,
|
|
gameName: draft.gameName,
|
|
themeText: draft.themeText,
|
|
summary: draft.summary ?? draft.summaryText ?? '',
|
|
tags: draft.tags,
|
|
coverImageSrc: draft.coverImageSrc ?? draft.referenceImageSrc ?? null,
|
|
referenceImageSrc: draft.referenceImageSrc ?? null,
|
|
clearCount: draft.clearCount,
|
|
difficulty: draft.difficulty,
|
|
publicationStatus: 'draft',
|
|
playCount: 0,
|
|
updatedAt: now,
|
|
publishedAt: null,
|
|
publishReady: Boolean(draft.publishReady),
|
|
backgroundPrompt: draft.backgroundPrompt ?? null,
|
|
backgroundImageSrc: draft.backgroundImageSrc ?? null,
|
|
backgroundImageObjectKey: draft.backgroundImageObjectKey ?? null,
|
|
generatedBackgroundAsset: draft.generatedBackgroundAsset ?? null,
|
|
generatedItemAssets,
|
|
});
|
|
}
|
|
|
|
export function hasMatch3DRuntimeAsset(
|
|
assets: readonly Match3DGeneratedItemAsset[] | null | undefined,
|
|
) {
|
|
return hasMatch3DGeneratedImageAsset(assets);
|
|
}
|
|
|
|
export function hasMatch3DRuntimeBackgroundAsset(
|
|
profile: Pick<
|
|
Match3DWorkSummary,
|
|
| 'backgroundImageSrc'
|
|
| 'backgroundImageObjectKey'
|
|
| 'generatedBackgroundAsset'
|
|
| 'generatedItemAssets'
|
|
>,
|
|
) {
|
|
return Boolean(
|
|
profile.backgroundImageSrc?.trim() ||
|
|
profile.backgroundImageObjectKey?.trim() ||
|
|
profile.generatedBackgroundAsset?.imageSrc?.trim() ||
|
|
profile.generatedBackgroundAsset?.imageObjectKey?.trim() ||
|
|
profile.generatedBackgroundAsset?.containerImageSrc?.trim() ||
|
|
profile.generatedBackgroundAsset?.containerImageObjectKey?.trim() ||
|
|
profile.generatedItemAssets?.some(
|
|
(asset) =>
|
|
asset.backgroundAsset?.imageSrc?.trim() ||
|
|
asset.backgroundAsset?.imageObjectKey?.trim() ||
|
|
asset.backgroundAsset?.containerImageSrc?.trim() ||
|
|
asset.backgroundAsset?.containerImageObjectKey?.trim(),
|
|
),
|
|
);
|
|
}
|
|
|
|
export function resolveMatch3DRuntimeGeneratedItemAssets(
|
|
run: Match3DRunSnapshot | null,
|
|
profile: Match3DWorkProfile | null,
|
|
publicWorkDetail: PlatformPublicGalleryCard | null,
|
|
) {
|
|
const runProfileId = run?.profileId?.trim() ?? '';
|
|
const profileAssets = profile?.generatedItemAssets ?? [];
|
|
const publicDetailAssets =
|
|
publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail)
|
|
? (publicWorkDetail.generatedItemAssets ?? [])
|
|
: [];
|
|
|
|
if (runProfileId && profile?.profileId === runProfileId) {
|
|
if (hasMatch3DRuntimeAsset(profileAssets)) {
|
|
return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets);
|
|
}
|
|
|
|
if (
|
|
publicWorkDetail &&
|
|
isMatch3DGalleryEntry(publicWorkDetail) &&
|
|
publicWorkDetail.profileId === runProfileId
|
|
) {
|
|
return hasMatch3DRuntimeAsset(publicDetailAssets)
|
|
? mergeMatch3DGeneratedItemAssetsForRuntime(
|
|
publicDetailAssets,
|
|
profileAssets,
|
|
)
|
|
: normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets);
|
|
}
|
|
|
|
return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets);
|
|
}
|
|
|
|
if (
|
|
runProfileId &&
|
|
publicWorkDetail &&
|
|
isMatch3DGalleryEntry(publicWorkDetail) &&
|
|
publicWorkDetail.profileId === runProfileId
|
|
) {
|
|
return normalizeMatch3DGeneratedItemAssetsForRuntime(publicDetailAssets);
|
|
}
|
|
|
|
if (hasMatch3DRuntimeAsset(profileAssets)) {
|
|
return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets);
|
|
}
|
|
return publicDetailAssets.length > 0
|
|
? normalizeMatch3DGeneratedItemAssetsForRuntime(publicDetailAssets)
|
|
: normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets);
|
|
}
|
|
|
|
export function resolveMatch3DRuntimeGeneratedBackgroundAsset(
|
|
run: Match3DRunSnapshot | null,
|
|
profile: Match3DWorkProfile | null,
|
|
publicWorkDetail: PlatformPublicGalleryCard | null,
|
|
) {
|
|
const runProfileId = run?.profileId?.trim() ?? '';
|
|
const profileBackground = profile
|
|
? (promoteMatch3DGeneratedBackgroundAsset(profile)
|
|
.generatedBackgroundAsset ?? null)
|
|
: null;
|
|
const publicBackground =
|
|
publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail)
|
|
? (promoteMatch3DGeneratedBackgroundAsset(publicWorkDetail)
|
|
.generatedBackgroundAsset ?? null)
|
|
: null;
|
|
|
|
if (runProfileId && profile?.profileId === runProfileId) {
|
|
return profileBackground ?? publicBackground;
|
|
}
|
|
if (
|
|
runProfileId &&
|
|
publicWorkDetail &&
|
|
isMatch3DGalleryEntry(publicWorkDetail) &&
|
|
publicWorkDetail.profileId === runProfileId
|
|
) {
|
|
return publicBackground ?? profileBackground;
|
|
}
|
|
return profileBackground ?? publicBackground;
|
|
}
|
|
|
|
export function resolveActiveMatch3DRuntimeProfile(
|
|
run: Match3DRunSnapshot | null,
|
|
runtimeProfile: Match3DWorkProfile | null,
|
|
profile: Match3DWorkProfile | null,
|
|
) {
|
|
const runProfileId = run?.profileId?.trim() ?? '';
|
|
if (runProfileId && runtimeProfile?.profileId === runProfileId) {
|
|
return runtimeProfile;
|
|
}
|
|
if (runProfileId && profile?.profileId === runProfileId) {
|
|
return profile;
|
|
}
|
|
return runtimeProfile ?? profile;
|
|
}
|
|
|
|
export function resolveMatch3DRuntimeBackgroundImageSrc(
|
|
run: Match3DRunSnapshot | null,
|
|
profile: Match3DWorkProfile | null,
|
|
publicWorkDetail: PlatformPublicGalleryCard | null,
|
|
) {
|
|
const runProfileId = run?.profileId?.trim() ?? '';
|
|
const resolvedProfile = profile
|
|
? promoteMatch3DGeneratedBackgroundAsset(profile)
|
|
: null;
|
|
const resolvedPublicWork =
|
|
publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail)
|
|
? promoteMatch3DGeneratedBackgroundAsset(publicWorkDetail)
|
|
: null;
|
|
const profileBackground =
|
|
resolvedProfile?.backgroundImageSrc?.trim() ||
|
|
resolvedProfile?.generatedBackgroundAsset?.imageSrc?.trim() ||
|
|
resolvedProfile?.backgroundImageObjectKey?.trim() ||
|
|
resolvedProfile?.generatedBackgroundAsset?.imageObjectKey?.trim() ||
|
|
'';
|
|
const publicBackground =
|
|
resolvedPublicWork?.backgroundImageSrc?.trim() ||
|
|
resolvedPublicWork?.generatedBackgroundAsset?.imageSrc?.trim() ||
|
|
resolvedPublicWork?.backgroundImageObjectKey?.trim() ||
|
|
resolvedPublicWork?.generatedBackgroundAsset?.imageObjectKey?.trim() ||
|
|
'';
|
|
|
|
if (runProfileId && profile?.profileId === runProfileId) {
|
|
return profileBackground || publicBackground || null;
|
|
}
|
|
if (
|
|
runProfileId &&
|
|
publicWorkDetail &&
|
|
isMatch3DGalleryEntry(publicWorkDetail) &&
|
|
publicWorkDetail.profileId === runProfileId
|
|
) {
|
|
return publicBackground || profileBackground || null;
|
|
}
|
|
return profileBackground || publicBackground || null;
|
|
}
|