347 lines
11 KiB
TypeScript
347 lines
11 KiB
TypeScript
import path from 'node:path'
|
|
import { DIST_DIR as ASSETS_DIST_DIR } from '@aklive2d/assets'
|
|
import { files as backgroundFiles } from '@aklive2d/background'
|
|
import { defaultRegion } from '@aklive2d/charword-table'
|
|
import config from '@aklive2d/config'
|
|
import { env, file } from '@aklive2d/libs'
|
|
import { mapping as musicMapping } from '@aklive2d/music'
|
|
import operators, {
|
|
generateAssetsJson,
|
|
OPERATOR_SOURCE_FOLDER,
|
|
} from '@aklive2d/operator'
|
|
import {
|
|
findSkel,
|
|
getActualFilename,
|
|
getExtractedFolder,
|
|
} from '@aklive2d/operator/libs/utils'
|
|
import type { OperatorConfig } from '@aklive2d/operator/types'
|
|
import type { ProjectJSON } from '@aklive2d/project-json/types'
|
|
|
|
interface DirectoryOperatorConfig extends OperatorConfig {
|
|
workshopId: string | null
|
|
}
|
|
|
|
const SPINE_FILENAME_PREFIX = 'dyn_illust_'
|
|
|
|
export const copyShowcaseData = (
|
|
name: string,
|
|
{
|
|
dataDir,
|
|
publicAssetsDir,
|
|
mode,
|
|
}: { dataDir: string; publicAssetsDir: string; mode: string }
|
|
) => {
|
|
file.mkdir(publicAssetsDir)
|
|
const operatorAssetsDir = path.join(
|
|
ASSETS_DIST_DIR,
|
|
config.module.operator.operator,
|
|
name
|
|
)
|
|
const spineFilenames = file
|
|
.readdirSync(operatorAssetsDir)
|
|
.filter((item) =>
|
|
item.startsWith(
|
|
operators[name].isSP
|
|
? `${config.module.operator.sp_filename_prefix}${SPINE_FILENAME_PREFIX}`
|
|
: SPINE_FILENAME_PREFIX
|
|
)
|
|
)
|
|
const q = [
|
|
{
|
|
fn: file.symlink,
|
|
source: path.resolve(
|
|
ASSETS_DIST_DIR,
|
|
config.module.assets.background
|
|
),
|
|
target: path.resolve(
|
|
publicAssetsDir,
|
|
config.module.assets.background
|
|
),
|
|
condition: mode !== 'build:directory',
|
|
},
|
|
{
|
|
fn: file.symlink,
|
|
source: path.resolve(ASSETS_DIST_DIR, config.module.assets.music),
|
|
target: path.resolve(publicAssetsDir, config.module.assets.music),
|
|
condition: mode !== 'build:directory',
|
|
},
|
|
{
|
|
fn: file.symlinkAll,
|
|
source: path.resolve(
|
|
ASSETS_DIST_DIR,
|
|
config.dir_name.voice.main,
|
|
name
|
|
),
|
|
target: path.resolve(publicAssetsDir, config.dir_name.voice.main),
|
|
},
|
|
{
|
|
fn: file.symlink,
|
|
filename: `${operators[name].portrait_filename}.png`,
|
|
source: path.resolve(
|
|
ASSETS_DIST_DIR,
|
|
config.module.operator.operator,
|
|
name
|
|
),
|
|
target: path.resolve(publicAssetsDir),
|
|
},
|
|
{
|
|
fn: file.symlink,
|
|
filename: `${operators[name].logo}.png`,
|
|
source: path.resolve(ASSETS_DIST_DIR, config.module.operator.logos),
|
|
target: path.resolve(publicAssetsDir),
|
|
condition: mode !== 'build:directory',
|
|
},
|
|
{
|
|
fn: file.symlink,
|
|
filename: config.module.charword_table.charword_table_json,
|
|
source: path.resolve(
|
|
ASSETS_DIST_DIR,
|
|
config.module.assets.charword_table,
|
|
name
|
|
),
|
|
target: path.resolve(publicAssetsDir),
|
|
},
|
|
]
|
|
spineFilenames.map((filename) => {
|
|
q.push({
|
|
fn: file.symlink,
|
|
filename,
|
|
source: operatorAssetsDir,
|
|
target: path.resolve(publicAssetsDir),
|
|
})
|
|
})
|
|
q.map(({ fn, filename, source, target, condition = true }) => {
|
|
if (condition) {
|
|
if (filename) {
|
|
source = path.resolve(source, filename)
|
|
target = path.resolve(target, filename)
|
|
}
|
|
fn(source, target)
|
|
}
|
|
})
|
|
const filename = getActualFilename(
|
|
operators[name].filename,
|
|
getExtractedFolder(name),
|
|
operators[name].isSP
|
|
)
|
|
const buildConfig = {
|
|
insight_id: config.insight.id,
|
|
link: operators[name].link,
|
|
filename: filename.replace(/#/g, '%23'),
|
|
logo_filename: operators[name].logo,
|
|
portrait_filename: operators[name].portrait_filename.replace(
|
|
/#/g,
|
|
'%23'
|
|
),
|
|
viewport_left: operators[name].viewport_left,
|
|
viewport_right: operators[name].viewport_right,
|
|
viewport_top: operators[name].viewport_top,
|
|
viewport_bottom: operators[name].viewport_bottom,
|
|
invert_filter: operators[name].invert_filter,
|
|
image_width: 2048,
|
|
image_height: 2048,
|
|
default_background: config.module.background.operator_bg_png,
|
|
background_files: backgroundFiles,
|
|
background_folder: config.module.assets.background,
|
|
voice_default_region: defaultRegion,
|
|
voice_folders: config.dir_name.voice,
|
|
music_folder: config.module.assets.music,
|
|
music_mapping: musicMapping.musicFileMapping,
|
|
use_json: findSkel(filename, getExtractedFolder(name)).endsWith('json'),
|
|
default_assets_dir: `${config.app.showcase.assets}/`,
|
|
logo_dir:
|
|
mode === 'build:directory'
|
|
? `${config.module.operator.logos}/`
|
|
: '',
|
|
build_assets_dir:
|
|
mode === 'build:directory'
|
|
? `../${config.app.directory.assets}/`
|
|
: `${config.app.showcase.assets}/`, // default is assets/, on build:directory mode is ../_assets
|
|
}
|
|
file.writeSync(
|
|
JSON.stringify(buildConfig),
|
|
path.join(path.resolve(dataDir), config.module.vite_helpers.config_json)
|
|
)
|
|
file.writeSync(
|
|
env.generate([
|
|
{
|
|
key: 'app_title',
|
|
value: operators[name].title,
|
|
},
|
|
{
|
|
key: 'insight_url',
|
|
value: config.insight.url,
|
|
},
|
|
]),
|
|
path.join(path.resolve(dataDir), '.env')
|
|
)
|
|
|
|
return buildConfig
|
|
}
|
|
|
|
export const copyProjectJSON = (
|
|
name: string,
|
|
{ releaseDir }: { releaseDir: string }
|
|
) => {
|
|
file.cpSync(
|
|
path.resolve(ASSETS_DIST_DIR, config.module.assets.project_json, name),
|
|
path.resolve(releaseDir),
|
|
{
|
|
dereference: true,
|
|
}
|
|
)
|
|
}
|
|
|
|
export const copyDirectoryData = async ({
|
|
dataDir,
|
|
publicDir,
|
|
}: {
|
|
dataDir: string
|
|
publicDir: string
|
|
}) => {
|
|
file.mkdir(publicDir)
|
|
const extractedFolder = path.join(
|
|
OPERATOR_SOURCE_FOLDER,
|
|
config.module.operator.directory_assets
|
|
)
|
|
const targetFolder = path.join(publicDir, config.app.directory.assets)
|
|
const sourceFolder = path.join(ASSETS_DIST_DIR)
|
|
const operatorFilesToCopy = Object.keys(operators)
|
|
const operatorConfig = Object.values(
|
|
Object.values(operators).reduce(
|
|
(acc, cur) => {
|
|
const curD = cur as DirectoryOperatorConfig
|
|
curD.filename = getActualFilename(
|
|
operators[curD.link].filename,
|
|
getExtractedFolder(curD.link),
|
|
operators[curD.link].isSP
|
|
)
|
|
curD.use_json = findSkel(
|
|
curD.filename,
|
|
getExtractedFolder(curD.link)
|
|
).endsWith('json')
|
|
const date = curD.date
|
|
|
|
curD.workshopId = null
|
|
const text = file.readSync(
|
|
path.join(
|
|
ASSETS_DIST_DIR,
|
|
config.module.assets.project_json,
|
|
cur.link,
|
|
config.module.project_json.project_json
|
|
)
|
|
) as string
|
|
if (!text) {
|
|
console.log(`No workshop id for ${cur.link}!`)
|
|
} else {
|
|
curD.workshopId = (
|
|
JSON.parse(text) as ProjectJSON
|
|
).workshopid
|
|
}
|
|
|
|
if (acc[date]) {
|
|
acc[date].push(curD)
|
|
} else {
|
|
acc[date] = [curD]
|
|
}
|
|
|
|
return acc
|
|
},
|
|
{} as {
|
|
[date: string]: DirectoryOperatorConfig[]
|
|
}
|
|
)
|
|
).sort((a, b) => Date.parse(b[0].date) - Date.parse(a[0].date))
|
|
await Promise.all(
|
|
config.app.directory.error.files.map(async (key) => {
|
|
await generateAssetsJson(key.key, extractedFolder, targetFolder, {
|
|
useSymLink: false,
|
|
})
|
|
})
|
|
)
|
|
|
|
const directoryConfig = {
|
|
insight_id: config.insight.id,
|
|
app_voice_url: config.app.directory.voice,
|
|
voice_folders: config.dir_name.voice,
|
|
directory_folder: config.app.directory.assets,
|
|
default_background: config.module.background.operator_bg_png,
|
|
background_files: backgroundFiles,
|
|
background_folder: config.module.assets.background,
|
|
available_operators: Object.keys(operators),
|
|
error_files: config.app.directory.error,
|
|
music_folder: config.module.assets.music,
|
|
music_mapping: musicMapping.musicFileMapping,
|
|
operators: operatorConfig,
|
|
default_assets_dir: `${config.app.showcase.assets}/`,
|
|
logo_dir: `${config.module.operator.logos}/`,
|
|
portraits: `${config.app.directory.portraits}/`,
|
|
}
|
|
file.writeSync(
|
|
JSON.stringify(directoryConfig),
|
|
path.join(dataDir, config.module.vite_helpers.config_json)
|
|
)
|
|
|
|
file.writeSync(
|
|
env.generate([
|
|
{
|
|
key: 'app_title',
|
|
value: config.app.directory.title,
|
|
},
|
|
{
|
|
key: 'insight_url',
|
|
value: config.insight.url,
|
|
},
|
|
]),
|
|
path.join(dataDir, '.env')
|
|
)
|
|
|
|
const filesToCopy = [
|
|
{
|
|
src: path.join(
|
|
extractedFolder,
|
|
config.app.directory.error.voice.file
|
|
),
|
|
dest: path.join(
|
|
targetFolder,
|
|
config.app.directory.error.voice.target
|
|
),
|
|
},
|
|
{
|
|
src: path.resolve(ASSETS_DIST_DIR, config.module.assets.background),
|
|
dest: path.resolve(targetFolder, config.module.assets.background),
|
|
},
|
|
{
|
|
src: path.resolve(ASSETS_DIST_DIR, config.module.assets.music),
|
|
dest: path.resolve(targetFolder, config.module.assets.music),
|
|
},
|
|
{
|
|
src: path.resolve(ASSETS_DIST_DIR, config.module.operator.logos),
|
|
dest: path.resolve(targetFolder, config.module.operator.logos),
|
|
},
|
|
]
|
|
|
|
operatorFilesToCopy.map((key) => {
|
|
const portraitName = `${operators[key].portrait_filename}.png`
|
|
filesToCopy.push({
|
|
src: path.join(
|
|
sourceFolder,
|
|
config.module.operator.operator,
|
|
key,
|
|
portraitName
|
|
),
|
|
dest: path.join(
|
|
targetFolder,
|
|
config.app.directory.portraits,
|
|
portraitName
|
|
),
|
|
})
|
|
})
|
|
|
|
filesToCopy.forEach((item) => {
|
|
file.symlink(item.src, item.dest)
|
|
})
|
|
|
|
return directoryConfig
|
|
}
|