사용자가 서버 폴더를 configs(복수)로 정리하기로 해, 단수 config 로 바꿨던
것을 원복. resolveManifestRelative subDir 'configs', 타입 주석/로케일 힌트/
리포지토리 폴더(file/configs)/버전(0.4.30) 모두 복수로 통일.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
이전 커밋(082dae5)은 file/configs→config 폴더 rename 만 담기고 실제 소스
변경이 누락됐다. resolveManifestRelative subDir 를 'config' 로, 관련
타입 주석/로케일 힌트/버전(0.4.29)까지 반영.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
관리자 편집기 platformLoaderHint 가 아직 "fabric-installer CLI 설치"라고
설명하고 있었으나, 실제 설치기는 자바 없이 Fabric Meta profile JSON 을 받아
.minecraft/versions 에 직접 저장한다. UI 설명을 실제 동작에 맞춤.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
관리자 편집기에서 맵 파일과 서버 파일 사이에 "config 파일 (.zip)" 필드를
추가하고, 간편설치기가 /file/configs/<name> zip 을 받아 게임 폴더(.mc_custom)
루트에 그대로 풀도록 했다(zip 안의 config/ 가 .mc_custom/config/ 로 배치).
- PackDefinition.configPath 추가 + store 정규화/기본값
- 설치기 downloadConfigZip 헬퍼 + client:install 흐름 반영
- 편집기 필드, op 저장 파싱, 로케일 키(server/installer)
- docs/installer.md 다운로드 단계 갱신, file/configs/ 폴더 생성
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- pack.finalResourcepackPath 추가(/file/resourcepacks/outputs/, "."=없음, 기본 ".").
편집기에 "최종 리소스팩 (.zip)" 입력 필드 추가.
- 약관 표시대상에 showInFinalResourcepack("최종 리소스팩에 표시") 3번째 토글 추가
(스키마/시드/마이그레이션/편집기 체크박스·배지·저장 라우트, index.json 노출).
- 간편설치기 완료 단계: 기존 "직접 적용" 경고 제거 → 최종 리소스팩이 "."이 아니면
"리소스팩을 설치하시겠습니까?" 예/아니요. 아니요→완료, 예→최종 리소스팩 약관
(showInFinalResourcepack) 동의→/file/resourcepacks/outputs/ 에서 다운로드→완료.
"." 이면 이 페이지 자체를 건너뜀.
- 0.4.15→0.4.16.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 하드코딩 [8,11,17,21,25] 대신 Adoptium(Temurin) API 에서 실제 배포 버전을 가져와
편집기 드롭다운을 채운다. 브라우저 CORS 차단이라 서버가 프록시:
GET /op/jdk-versions (메이저 목록), GET /op/jdk-versions/:major (GA/EA 릴리스명).
6h 캐시 + 네트워크 실패 시 정적 폴백.
- 편집기: 기본은 LTS(25/21/17/11/8)만 표시, "자세히 보기" 체크 시 비-LTS 메이저까지
펼치고 선택 메이저의 GA/EA 스냅샷 릴리스명을 함께 보여준다.
- normalizeRecommendedJdk 를 고정 목록 대신 8~99 범위로 완화(동적 메이저 허용).
- 버전 0.4.7→0.4.8.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- pack 에 recommendedJdk 추가(shared/types, store 정규화, 기본 25, 허용목록
[8,11,17,21,25]). 사이트 편집기에 JDK 버전 드롭다운 추가(직접 입력 X).
- 설치기 JDK 탐색 순서 변경: ① 권장 JDK 자동설치 위치(temurin-<권장>) 우선 →
② 없으면 컴퓨터 JDK(JAVA_HOME/Program Files, 권장 버전 이상만 인정).
- 자동 설치/버전 검증도 pack 의 권장 버전을 사용(하드코딩 25 제거).
- 렌더러에 권장 JDK 표시, 관련 안내/문서 갱신. 버전 0.4.5→0.4.6.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
리뷰 지적 4건 반영(서버 전용, exe 영향 없음).
- 로그인 IP 기준 실패 제한(15분 창 10회 → 15분 차단). 브루트포스 + scrypt CPU
남용 방지. 인메모리, 무한 성장 가드 포함.
- 운영 계정을 gitignore 된 account.local.json 으로 이전. readAccounts 는 local
우선, 없으면 추적되는 account.json 을 시드로 읽음. writeAccounts 는 local 에만
기록 → 첫 로그인 자동 해시 업그레이드부터는 추적 평문 파일을 더 쓰지 않음.
(account.json 을 git rm --cached 하면 서버 pull 시 삭제되는 위험이 있어 추적 자체는
건드리지 않고, 실질 사용 파일만 분리.)
- 세션 쿠키 secure 를 SESSION_COOKIE_SECURE=true 로 켤 수 있게(HTTPS 배포용).
- 평문→해시 자동 업그레이드 저장 실패를 조용히 무시하지 않고 console.error 로 기록.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
전체 코드 재검토 기반의 안전한 개선 1차 배치.
- 메인 설치기에 전역 uncaughtException/unhandledRejection 가드 추가. nat-upnp
(detectExternalIpUpnp)의 비동기 소켓 오류로 앱이 조용히 종료되던 잠재 크래시
방지(포트포워딩 도구 v0.3.18 과 동일 대비).
- 서버: fetchVideoMeta/fetchPlaylistEntries 에 http(s) URL 검증 추가(운영자 입력이
yt-dlp 플래그로 오인되는 인자 주입 차단). /file/mods/:folder/index.json 의 async
throw → next(error) 로 위임(unhandledRejection 방지). index 라우트 pack 정의
병렬 로드.
- 죽은 i18n 키 정리: installer 로케일의 UPnP/run.bat 관련 19개 + pf 로케일 2개
제거(코드에서 미참조 확인). 크래시 가드용 log.internalError, youtube.invalidUrl 추가.
v0.3.23.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Each music list row now shows a 설명 button immediately to the left of
the 별칭 button. Click opens a modal with a multi-line textarea; on
close the value is persisted into MusicListEntry.description and saved
to the same pack list JSON. The button gets a hasDesc visual indicator
when filled. Description is stored but intentionally not consumed by
datapack export or alias matching — purely informational metadata.
- types.ts: add description: string to MusicListEntry
- store.ts: normalize entry.description via sanitizeStr (defaults to '')
- listEditor.ejs: new #descModal alongside aliasModal
- listEditor.js: render descBtn left of aliasBtn, attach handlers,
also set description: '' on playlist-fetched entries
- styles.css: extend trackRow grid to 6 cols, reuse aliasBtn styling
for descBtn, add descTextarea sizing
- locale (ko-kr): descBtn / descModalTitle / descBack / descPlaceholder
/ descHint
Backwards-compatible: existing list JSON files without description
field normalize to ''.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
probeVersion() now captures stderr/exit-code/signal/spawn-error instead of
returning a bare boolean, and ensureYtDlp() tries the bundled binary first,
falls back to `yt-dlp(.exe)` on PATH if the bundled one won't execute (AV
block, missing libc symbol, broken download), and only then re-downloads.
The final user-facing error includes the per-attempt diagnostics so we can
actually see WHY verification failed instead of the opaque
"yt-dlp 다운로드는 됐지만 실행 검증에 실패했습니다." message.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- _meta.json: customLabels -> terms.{label,showInInstaller,showInInstallerRp}
- Drop builtin protection; any term kind can be deleted/added/toggled
- New public route /manifest/terms/<pack>/index.json for installer term lists
- Installers fetch terms:list dynamically; skip agreement step if list empty
- Term editor: 2 visibility checkboxes (설치기 / 리소스팩 설치기), multi-select
- Migration from old schema preserves custom labels (default: visible in both)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- store.ts: 약관을 manifest/terms/<packKey>/ 폴더별로 저장. 첫 접근 시
legacy 전역 .md 파일을 시드로 자동 복사한다.
- importTerms() 추가: 다른 음악퀴즈의 .md + _meta.json 을 현재 pack 으로
복사한다. 동일 kind 는 source 값으로 덮어쓴다.
- /op/agreement 라우트를 세 단계로 분리:
· /op/agreement → 음악퀴즈 카드 선택 페이지
· /op/agreement/:packName → 해당 pack 의 약관 목록 + 추가 + 불러오기
· /op/agreement/:packName/:kind → 에디터
- 공개 라우트도 /manifest/terms/:packKey/:fileName 으로 변경.
- 설치기 main.ts: state.selectedKey 를 약관 URL 에 포함하도록 수정 (메인 +
rp 양쪽). pack 미선택 상태에서는 에러 반환.
- termsEditor.js: PACK_KEY 를 받아 저장 URL 에 포함.
- 다른 음악퀴즈 후보 select + 확인 모달 + locale 추가.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 약관 편집기 배경/슬래시 메뉴를 사이트 다크 팔레트로 통일 (흰 배경 + 흰 글씨 가시성 문제 해결)
- 약관 목록을 가로 풀폭 1줄씩 세로로 쌓이는 레이아웃으로 변경
- 사용자 정의 약관 추가/삭제 지원
- manifest/terms/_meta.json 에 라벨 저장
- builtin 5종(map/resourcepack/mod/installer/installer-rp)은 삭제 불가, "기본" 배지 표시
- kind 식별자 규칙: 소문자/숫자/하이픈 32자 이내
- 공개 라우트 /manifest/terms/<file>.md 는 isPublicTermsFile() 로 _meta.json 차단
- 0.3.0 → 0.3.1
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 5종 약관(map/resourcepack/mod/installer/installer-rp) markdown 시드 + manifest/terms/ 노출
- 사이트 /op/agreement 목록 + Notion 스타일 markdown 에디터 (슬래시 명령어, 미리보기)
- 메인 installer: 음악퀴즈 선택 직후 약관 동의 페이지(맵·모드·설치기) 추가
- rp installer: 음악퀴즈 선택 직후 약관 동의 페이지(리소스팩·설치기) 추가
- rp installer 취소 버그 수정: buildResourcepackZip 단계간 + archive.abort() 폴링
- rp installer 취소 UX: 즉시 "취소 중…" 표시, 취소 시 installFailed 알림 생략
- 0.2.6 → 0.3.0 (큰 기능)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per user request: when outputPackName is empty, fall back to
`<packKey>_resourcepack` instead of `<packKey>_musicquiz`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a new "생성되는 리소스팩 이름" admin field saved to the pack
manifest and consumed by the rp installer when naming the final zip.
Empty value falls back to <packKey>_musicquiz; Windows-invalid chars
are sanitized to '_'. Bumps version 0.1.1 → 0.2.0 (new feature).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
데이터팩 수정 페이지에 "이미지.zip 출력" 버튼과 크기 입력(기본 4, 1~16)
을 추가. 누르면 GET /op/datapack/:key/images-zip?size=N 으로 음악 개수만큼
cover_NN.json (asset_id, width=size, height=size, title, author) 을 zip 으로
스트리밍해서 내려준다. 사용자가 맵 데이터팩의 data/musicquiz/painting_variant/
에 그대로 풀어 넣을 수 있다.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
운영자가 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 로케일 라벨을 "코드 출력 / 복사 / 출력 완료" 로 정리.
가이드 (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 다운로드용으로 정리.
- MusicListEntry 에 aliases: string[] 필드 추가, 저장 시 trim·중복 제거.
- 목록 행에 "별칭" 버튼 표시(개수 있으면 강조), 클릭 시 모달 오픈.
- 모달에서 "별칭 추가" → 입력행 생성, "−" 버튼 → 해당 행 삭제,
좌상단 "← 돌아가기" 또는 오버레이 클릭으로 저장 후 닫기.
- src/shared/i18n.ts: 공용 i18n 로더 (dotted-key + {{placeholder}} 보간)
- locales/server/ko-kr.json: 사이트 + 라우터 + 데이터팩 출력 사전
- EJS 뷰는 res.locals.t 미들웨어로 일괄 적용
- listEditor.js 등 클라이언트 JS 는 사전을 inline <script> 로 주입받아 tt() 헬퍼 사용