op: 데이터팩 출력을 zip 대신 songs.mcfunction 코드 텍스트로 변경

운영자가 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 로케일 라벨을 "코드 출력 / 복사 / 출력 완료" 로 정리.
This commit is contained in:
2026-05-13 16:41:25 +09:00
parent af884706d4
commit de08f9a810
65 changed files with 44 additions and 817 deletions

View File

@@ -17,6 +17,8 @@
</div>
</section>
<p class="muted"><%= t('datapack.hint') %></p>
<section class="dpControls">
<button type="button" class="primaryButton" id="pickPackBtn"><%= t('datapack.pickPack') %></button>
<span class="muted" id="pickedLabel"><%= t('datapack.pickedNone') %></span>
@@ -26,8 +28,11 @@
<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>
<!-- 음악퀴즈 선택 팝업 -->
@@ -85,16 +90,36 @@
document.getElementById('dpActions').hidden = false
document.getElementById('dp-status').textContent = ''
document.getElementById('dp-status').classList.remove('error')
document.getElementById('codeOut').hidden = true
document.getElementById('codeOut').textContent = ''
})
})
document.getElementById('exportBtn').addEventListener('click', function () {
if (!pickedKey) return
var s = document.getElementById('dp-status')
s.textContent = I18N.exporting; s.classList.remove('error')
// zip 다운로드를 트리거하기 위해 location 으로 이동시킨다.
window.location.href = '/op/datapack/' + encodeURIComponent(pickedKey) + '/generate'
// 다운로드는 비동기 / 별도 응답이므로 약간의 지연 후 "완료" 표시.
setTimeout(function () { s.textContent = I18N.exported }, 500)
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
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')
})
})
})()
</script>