From 33c7553506f70dffd686e2486c78d4dc21debc4e Mon Sep 17 00:00:00 2001 From: Haoyu Xu Date: Sun, 5 Oct 2025 20:26:10 +0800 Subject: [PATCH] feat: updated music and background handling to support _form_x type background --- packages/background/index.ts | 19 ------------------- packages/background/package.json | 5 ++--- packages/libs/libs/error.ts | 2 +- packages/music/index.ts | 25 +++++++++++++++++++++++++ packages/music/package.json | 5 +++-- packages/operator/index.ts | 8 ++++---- packages/operator/libs/builder.ts | 6 +++--- packages/operator/types.ts | 1 + 8 files changed, 39 insertions(+), 32 deletions(-) diff --git a/packages/background/index.ts b/packages/background/index.ts index 7ad3b5c..0238564 100644 --- a/packages/background/index.ts +++ b/packages/background/index.ts @@ -1,7 +1,6 @@ import path from 'node:path' import config from '@aklive2d/config' import { file } from '@aklive2d/libs' -import { mapping as musicMapping } from '@aklive2d/music' import sharp from 'sharp' export const BACKGROUND_DIR = path.join( @@ -35,7 +34,6 @@ const filesToBuild = file.readdirSync(EXTRACTED_DIR).filter((f) => { }) export const build = async () => { - const err = [] file.mkdir(DIST_DIR) await Promise.all( filesToBuild.map(async (f) => { @@ -47,23 +45,6 @@ export const build = async () => { DEFAULT_BACKGROUND_FILE, path.join(DIST_DIR, config.module.background.operator_bg_png) ) - - const { musicFiles, musicFileMapping } = musicMapping - - for (const e of musicFiles) { - const musicPath = path.join(e.source, e.filename) - if (!file.exists(musicPath)) { - err.push(`Music file ${e.filename} is not found in music folder.`) - } - } - files = getFiles() - for (const e of Object.keys(musicFileMapping)) { - if (!files.includes(e)) { - err.push(`Background file ${e} is not found in background folder.`) - } - } - - return err } const composite = async (filenamePrefix: string, fileExt: string) => { diff --git a/packages/background/package.json b/packages/background/package.json index fc28144..4ce7abd 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -7,8 +7,7 @@ "dependencies": { "sharp": "^0.34.4", "@aklive2d/libs": "workspace:*", - "@aklive2d/config": "workspace:*", - "@aklive2d/music": "workspace:*" + "@aklive2d/config": "workspace:*" }, "peerDependencies": { "typescript": ">=5.9.3" @@ -19,4 +18,4 @@ "lint:fix": "biome check --write .", "build:cleanup": "rm -rf ./dist ./data" } -} \ No newline at end of file +} diff --git a/packages/libs/libs/error.ts b/packages/libs/libs/error.ts index 6181f64..d4778b4 100644 --- a/packages/libs/libs/error.ts +++ b/packages/libs/libs/error.ts @@ -1,5 +1,5 @@ export const handle = (err: string[]) => { - if (err.length > 0) { + if (err?.length > 0) { const str = `${err.length} error${err.length > 1 ? 's were' : ' was'} found:\n${err.join('\n')}` throw new Error(str) } diff --git a/packages/music/index.ts b/packages/music/index.ts index a51a5c5..7422628 100644 --- a/packages/music/index.ts +++ b/packages/music/index.ts @@ -1,6 +1,7 @@ import path from 'node:path' import config from '@aklive2d/config' import { githubDownload } from '@aklive2d/downloader' +import {files as backgroundFiles} from "@aklive2d/background" import { file } from '@aklive2d/libs' import type { AudioDataTable, @@ -85,6 +86,30 @@ const generateMapping = () => { } } + for (const e of musicFiles) { + const musicPath = path.join(e.source, e.filename) + if (!file.exists(musicPath)) { + throw new Error(`Music file ${e.filename} is not found in music folder.`) + } + } + + for (const e of Object.keys(musicFileMapping)) { + if (!backgroundFiles.includes(e)) { + throw new Error(`Background file ${e} is not found in background folder.`) + } + } + + for (const background of backgroundFiles) { + if (!musicFileMapping[background]) { + const alternativeMatch = background.replace(/_(form)(.*)(\.png)$/, "$3") + if (musicFileMapping[alternativeMatch]){ + musicFileMapping[background] = structuredClone(musicFileMapping[alternativeMatch]) + } else { + throw new Error(`Music mapping for background file ${background} is not found in music mapping.`) + } + } + } + return { musicFiles, musicFileMapping, diff --git a/packages/music/package.json b/packages/music/package.json index 1030136..afce015 100644 --- a/packages/music/package.json +++ b/packages/music/package.json @@ -7,7 +7,8 @@ "dependencies": { "@aklive2d/libs": "workspace:*", "@aklive2d/config": "workspace:*", - "@aklive2d/downloader": "workspace:*" + "@aklive2d/downloader": "workspace:*", + "@aklive2d/background": "workspace:*" }, "peerDependencies": { "typescript": ">=5.9.3" @@ -18,4 +19,4 @@ "lint:fix": "biome check --write .", "build:cleanup": "rm -rf ./data" } -} \ No newline at end of file +} diff --git a/packages/operator/index.ts b/packages/operator/index.ts index a43b4d3..f322b2a 100644 --- a/packages/operator/index.ts +++ b/packages/operator/index.ts @@ -158,10 +158,10 @@ const generateMapping = () => { : operatorInfo.skinName['en-US'] const skinEntry = findSkinEntry(skinTable, name, type) operator.filename = skinEntry.dynIllustId.replace(/_2$/, '') - operator.fallback_name = - type === 'skin' - ? skinEntry.skinId.replace(/@/, '_') - : `${skinEntry.charId}_2` + operator.portrait_filename = type === 'skin' + ? skinEntry.skinId.replace(/@/, '_') + : `${skinEntry.charId}_2` + operator.fallback_name = `${operator.portrait_filename}${operator.isSP ? '_sp' : ''}` const regions = Object.keys( operator.codename diff --git a/packages/operator/libs/builder.ts b/packages/operator/libs/builder.ts index 53cd70f..ecbdae9 100644 --- a/packages/operator/libs/builder.ts +++ b/packages/operator/libs/builder.ts @@ -73,9 +73,9 @@ const generateAssets = async (name: string) => { ) as string if (!portraitHubContent) throw new Error('portrait_hub.json not found') const portraitHub: PortraitHub = JSON.parse(portraitHubContent) - const fallback_name_lowerCase = fallback_name.toLowerCase() + const portrait_filename_lowerCase = operators[name].portrait_filename.toLowerCase() const portraitItem = portraitHub._sprites.find( - (item) => item.name.toLowerCase() === fallback_name_lowerCase + (item) => item.name.toLowerCase() === portrait_filename_lowerCase ) if (!portraitItem) throw new Error(`portrait ${fallback_name} not found`) const portraitAtlas = portraitItem.atlas @@ -90,7 +90,7 @@ const generateAssets = async (name: string) => { throw new Error(`portrait ${fallback_name} json not found`) const portraitJson: PortraitJson = JSON.parse(portraitJsonText) const item = portraitJson._sprites.find( - (item) => item.name.toLowerCase() === fallback_name_lowerCase + (item) => item.name.toLowerCase() === portrait_filename_lowerCase ) if (!item) throw new Error(`portrait ${fallback_name} not found`) const rect = { diff --git a/packages/operator/types.ts b/packages/operator/types.ts index 1f4c715..c773f4e 100644 --- a/packages/operator/types.ts +++ b/packages/operator/types.ts @@ -6,6 +6,7 @@ export interface OperatorConfig { filename: string logo: string fallback_name: string + portrait_filename: string viewport_left: number // should be default to 0 in the future viewport_right: number viewport_top: number