운영자가 mc_datapack 의 init/songs.mcfunction 파일에 직접 복사해 붙여넣
는 워크플로로 단순화. 전체 데이터팩을 패키징할 필요가 없다.
- /op/datapack/:packName/generate 가 buildSongsMcfunction(list) 결과를
text/plain 으로 반환 (zip 스트리밍 제거).
- file/datapacks/music_quiz_template/ 정적 사본 제거.
- datapack.ejs 에 코드블록·복사 버튼 복원, 안내 문구 추가
("data/mq/function/init/songs.mcfunction 에 그대로 덮어쓰세요").
- datapack 로케일 라벨을 "코드 출력 / 복사 / 출력 완료" 로 정리.
46 lines
2.2 KiB
TypeScript
46 lines
2.2 KiB
TypeScript
import type { MusicListEntry, PackList } from '../shared/types.js'
|
|
|
|
/** SNBT 문자열 리터럴 안에 들어갈 문자열을 escape. */
|
|
function escapeSnbtString(input: string): string {
|
|
return input.replace(/\\/g, '\\\\').replace(/"/g, '\\"')
|
|
}
|
|
|
|
/** alias 배열을 SNBT 리스트 리터럴로 변환. 빈 배열도 `[]` 로 출력. */
|
|
function aliasListSnbt(aliases: string[]): string {
|
|
if (!Array.isArray(aliases) || aliases.length === 0) return '[]'
|
|
const parts = aliases.map((a) => `"${escapeSnbtString(a)}"`)
|
|
return `[${parts.join(',')}]`
|
|
}
|
|
|
|
/** 한 곡(MusicListEntry) → `{title:"...", author:"...", alias:[...]}` SNBT. */
|
|
function entrySnbt(entry: MusicListEntry): string {
|
|
const title = escapeSnbtString(entry.title ?? '')
|
|
// launcher 의 artist → 데이터팩 SNBT 의 author. 빈 값은 빈 문자열로 그대로 둔다.
|
|
const author = escapeSnbtString(entry.artist ?? '')
|
|
const alias = aliasListSnbt(entry.aliases ?? [])
|
|
return `{title:"${title}", author:"${author}", alias:${alias}}`
|
|
}
|
|
|
|
/**
|
|
* list.music 으로부터 `data/mq/function/init/songs.mcfunction` 본문을 생성.
|
|
* 운영자는 mc_datapack 의 music_quiz 데이터팩에서 이 파일만 이 내용으로
|
|
* 덮어쓰면 된다 — 나머지 파일은 launcher 가 관여하지 않는다.
|
|
*/
|
|
export function buildSongsMcfunction(list: PackList): string {
|
|
const lines: string[] = []
|
|
lines.push('# 곡 한 개 = 한 줄.')
|
|
lines.push('# 필수 — title, author, alias')
|
|
lines.push('# 선택 — volume (이 곡만의 /playsound 음량. 미지정시 init/config.mcfunction')
|
|
lines.push('# 의 audio.volume 사용)')
|
|
lines.push('# 곡 순서가 리소스팩의 track_NN / cover_NN 인덱스와 1:1 매칭된다.')
|
|
lines.push('# 예) {title:"Quiet Song", author:"...", alias:[...], volume:2.0}')
|
|
lines.push('data modify storage mq:main songs set value []')
|
|
for (const entry of list.music) {
|
|
lines.push(`data modify storage mq:main songs append value ${entrySnbt(entry)}`)
|
|
}
|
|
lines.push('')
|
|
lines.push('# 곡 개수는 songs 배열 길이에서 자동 계산됨')
|
|
lines.push('execute store result storage mq:main max_index int 1 run data get storage mq:main songs')
|
|
return lines.join('\n') + '\n'
|
|
}
|