feat: updated music and background handling to support _form_x type background

This commit is contained in:
Haoyu Xu
2025-10-05 20:26:10 +08:00
parent 49a49e5210
commit 33c7553506
8 changed files with 39 additions and 32 deletions

View File

@@ -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) => {

View File

@@ -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"

View File

@@ -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)
}

View File

@@ -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,

View File

@@ -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"

View File

@@ -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

View File

@@ -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 = {

View File

@@ -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