Add /op/list, /op/list/:pack, /op/datapack web admin + spec lock

docs/add.md
 - 사진 PNG 규격을 1024×1024 (4×4 블록 슬롯 × ×16 배율) 로 못박음
 - 짧은 변 기준 가운데 정사각 크롭 + 1024 초과 시만 축소, 미만은 native 유지

신규 라우트 (모두 requireAuth):
 - GET  /op/list                          → manifest 카드 목록
 - GET  /op/list/:pack                    → 음악목록·사진목록 탭 편집기
 - POST /op/list/:pack                    → file/list/<pack>.json 저장 (JSON)
 - POST /op/list/:pack/playlist           → yt-dlp 로 플레이리스트 펼치기
 - GET  /op/datapack                      → 음악퀴즈 선택 + 출력
 - GET  /op/datapack/:pack/generate       → 임시 포맷 mcfunction 텍스트

shared/types.ts: PackList / MusicListEntry / ImageListEntry
shared/store.ts: loadPackList, savePackList, normalizePackList
shared/paths.ts: fileListDirPath = file/list/
server/youtube.ts: yt-dlp 플레이리스트 펼치기 (--flat-playlist --dump-json),
  설치 안 됐을 때 NO_YTDLP 코드로 503.

UI:
 - views/op/list.ejs: 가로 카드 목록 + 돌아가기 버튼
 - views/op/listEditor.ejs + public/listEditor.js: 탭 전환, 드래그 정렬,
   우클릭 컨텍스트 메뉴(수정/삭제), 사진 수정 모달의 [유튜브 / 이미지] 토글,
   목록 저장·초기화·플레이리스트 불러오기 확인 팝업
 - views/op/datapack.ejs: 음악퀴즈 카드 선택 팝업 → 데이터팩 출력 + 복사
 - views/op/dashboard.ejs: 상단에 [음악목록 수정] [데이터팩 수정] 버튼
 - public/styles.css: 탭, 트랙 로우, 이미지 그리드, 컨텍스트 메뉴, 모달, 코드블록

.gitignore: conversations/ 추가.

스모크: login → /op/list 렌더, POST 저장 라운드트립 OK,
/op/datapack/.../generate 텍스트 출력 OK, 플레이리스트 fetch는 yt-dlp 미설치
환경에서 503 NO_YTDLP 메시지 정상.

Section 1 (리소스팩 설치기 EXE: yt-dlp 음악 다운로드, painting variant
텍스처 패키징, 리소스팩 zip 배치) 은 후속 커밋에서 작업.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-11 11:38:30 +09:00
parent 26cc625de6
commit a2817c921d
14 changed files with 1034 additions and 9 deletions

View File

@@ -49,11 +49,15 @@ yt-dlp로 음악 다운로드, 별도 경로로 사진 다운로드 → 리소
다운로드 후 painting variant 슬롯 규격에 맞춰 정규화한다 (자세한 슬롯 구조는
`docs/painting-variant.md` 참고).
- 데이터팩에 슬롯 `cover_01 … cover_N` 이 미리 등록돼 있음. 각 슬롯의 가로·세로(블록 단위)는 고정.
- 설치기는 이미지 N장을 받아 슬롯 N개의 PNG 로 변환:
- 목표 해상도 = `width * 16 × height * 16` (또는 그 정수배).
- 비율이 다르면 letterbox(투명 패딩)로 맞춰 잘림 방지.
- 파일명은 `cover_<NN>.png`, 저장 경로는 `resourcepack/assets/musicquiz/textures/painting/`.
- **슬롯 규격(고정, 데이터팩 측)**: `4 × 4` 블록 정사각, `cover_01 … cover_N`.
- **최종 PNG 규격(리소스팩 측)**: 정사각 1:1, 최대 `1024 × 1024` px.
- `4 × 4` 블록 × 블록당 `256` px (×16 배율) → 1024×1024 가 픽셀 그리드와 정확히 일치.
- **정규화 알고리즘**:
1. 가운데 정사각 크롭: `s = min(원본 가로, 원본 세로)``s × s`.
2. `s > 1024` 이면 `1024 × 1024` 로 축소 (Lanczos 권장).
3. `s ≤ 1024` 이면 그대로 `s × s` 유지 (업스케일 없음).
- 파일명: `cover_<NN>.png` (`NN` 은 2자리 0패딩).
- 저장 경로: `resourcepack/assets/musicquiz/textures/painting/`.
- 패키지 완성된 리소스팩을 `%appdata%/.minecraft/resourcepacks/` 에 zip 으로 배치.
### 3) 설치 완료