op: 데이터팩 출력을 실제 music_quiz zip 으로 교체
가이드 (mc_datapack/launcher_datapack_연동_가이드.txt) 에 따라:
- file/datapacks/music_quiz_template/ 에 mc_datapack 의 music_quiz/ 정적
파일을 미리 동봉 (data/mq/function/init/songs.mcfunction 제외).
- src/server/datapack.ts: list.music → SNBT (`{title, author, alias}`)
songs.mcfunction 빌더와 archiver 기반 zip 스트리머 추가.
- /op/datapack/:packName/generate 가 텍스트 placeholder 대신
music_quiz_<key>.zip 을 Content-Disposition attachment 로 내려준다.
- datapack.ejs 의 코드블록·복사 UI 제거, 곡 수는 서버 렌더 시점에 표시.
- 더 이상 쓰이지 않는 locales 의 datapackOutput.* 키 제거, datapack
버튼 라벨/상태 문구를 zip 다운로드용으로 정리.
This commit is contained in:
@@ -26,11 +26,8 @@
|
||||
|
||||
<section class="dpActions" hidden id="dpActions">
|
||||
<button type="button" class="secondaryButton" id="exportBtn"><%= t('datapack.export') %></button>
|
||||
<button type="button" class="secondaryButton" id="copyBtn"><%= t('datapack.copy') %></button>
|
||||
<span class="statusText" id="dp-status"></span>
|
||||
</section>
|
||||
|
||||
<pre class="codeBlock" id="codeOut" hidden></pre>
|
||||
</main>
|
||||
|
||||
<!-- 음악퀴즈 선택 팝업 -->
|
||||
@@ -42,7 +39,10 @@
|
||||
<div class="modalBody">
|
||||
<div class="cardRow horizontalScroll" id="pickList">
|
||||
<% items.forEach(function (item) { %>
|
||||
<article class="packCard pickable" data-key="<%= item.key %>" data-name="<%= item.definition ? item.definition.name : item.key %>">
|
||||
<article class="packCard pickable"
|
||||
data-key="<%= item.key %>"
|
||||
data-name="<%= item.definition ? item.definition.name : item.key %>"
|
||||
data-music-count="<%= item.musicCount %>">
|
||||
<h2><%= item.definition ? item.definition.name : item.key %></h2>
|
||||
<p class="muted"><%= item.key %>.json</p>
|
||||
<% if (item.definition) { %>
|
||||
@@ -60,8 +60,6 @@
|
||||
|
||||
<script>
|
||||
var I18N = <%- JSON.stringify(localeDict.datapack) %>;
|
||||
// 데이터팩 출력 본문의 "총 N곡" 패턴은 datapackOutput.summary 와 동일.
|
||||
var SUMMARY_PATTERN = <%- JSON.stringify(localeDict.datapackOutput.summary) %>;
|
||||
</script>
|
||||
<script>
|
||||
(function () {
|
||||
@@ -80,43 +78,23 @@
|
||||
card.addEventListener('click', function () {
|
||||
pickedKey = card.getAttribute('data-key')
|
||||
var name = card.getAttribute('data-name')
|
||||
var count = card.getAttribute('data-music-count') || '0'
|
||||
document.getElementById('pickedLabel').textContent = I18N.pickedLabel.replace('{{name}}', name)
|
||||
document.getElementById('countLabel').textContent = I18N.totalCount.replace('{{count}}', count)
|
||||
pickModal.hidden = true
|
||||
document.getElementById('dpActions').hidden = false
|
||||
fetch('/op/list/' + encodeURIComponent(pickedKey)).catch(function () {})
|
||||
document.getElementById('countLabel').textContent = ''
|
||||
document.getElementById('codeOut').hidden = true
|
||||
document.getElementById('dp-status').textContent = ''
|
||||
document.getElementById('dp-status').classList.remove('error')
|
||||
})
|
||||
})
|
||||
document.getElementById('exportBtn').addEventListener('click', function () {
|
||||
if (!pickedKey) return
|
||||
var s = document.getElementById('dp-status')
|
||||
s.textContent = I18N.exporting; s.classList.remove('error')
|
||||
fetch('/op/datapack/' + encodeURIComponent(pickedKey) + '/generate')
|
||||
.then(function (r) { return r.text().then(function (t) { return { ok: r.ok, text: t } }) })
|
||||
.then(function (res) {
|
||||
if (!res.ok) {
|
||||
s.textContent = I18N.failed.replace('{{message}}', res.text); s.classList.add('error')
|
||||
return
|
||||
}
|
||||
var out = document.getElementById('codeOut')
|
||||
out.textContent = res.text
|
||||
out.hidden = false
|
||||
// 첫줄/둘째줄에서 곡 개수를 추출해 카운트 라벨에 표시.
|
||||
var m = res.text.match(/총\s+(\d+)곡/)
|
||||
if (m) document.getElementById('countLabel').textContent = I18N.totalCount.replace('{{count}}', m[1])
|
||||
s.textContent = I18N.exported
|
||||
})
|
||||
.catch(function (err) { s.textContent = I18N.failed.replace('{{message}}', err.message); s.classList.add('error') })
|
||||
})
|
||||
document.getElementById('copyBtn').addEventListener('click', function () {
|
||||
var out = document.getElementById('codeOut')
|
||||
if (out.hidden) return
|
||||
navigator.clipboard.writeText(out.textContent).then(function () {
|
||||
var s = document.getElementById('dp-status')
|
||||
s.textContent = I18N.copied
|
||||
s.classList.remove('error')
|
||||
})
|
||||
// zip 다운로드를 트리거하기 위해 location 으로 이동시킨다.
|
||||
window.location.href = '/op/datapack/' + encodeURIComponent(pickedKey) + '/generate'
|
||||
// 다운로드는 비동기 / 별도 응답이므로 약간의 지연 후 "완료" 표시.
|
||||
setTimeout(function () { s.textContent = I18N.exported }, 500)
|
||||
})
|
||||
})()
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user