# 관리 사이트 운영 가이드 음악퀴즈 정의(`/manifest/*.json`), 음악·사진 목록(`/file/list/*.json`), 데이터팩 출력을 한 곳에서 관리하는 Express + EJS 사이트입니다. ## 실행 ```bash npm install cp .env.example .env # 처음 한 번만. 운영 도메인이면 SITE_BASE_URL 만 바꾸면 됩니다. npm start # 기본 포트 3000. ``` 배포 시에는 시스템 서비스(systemd 등) 로 등록해 두면 됩니다. ### 환경변수 (`.env`) | 키 | 기본값 | 설명 | | --- | --- | --- | | `PORT` | `3000` | Express 서버 listen 포트. | | `HOST` | `127.0.0.1` | 바인드 주소. 외부 노출하려면 `0.0.0.0`. | | `SESSION_SECRET` | dev secret | `/op` 세션 쿠키 서명 키. 운영에서는 반드시 임의값으로 교체. | | `SITE_BASE_URL` | `http://127.0.0.1:3000` | 설치기 두 종이 첫 화면에서 자동으로 채우는 manifest 호스트. 운영 도메인으로 바꿔두면 manifest URL 도 자동으로 따라갑니다. | | `MANIFEST_URL` | — | 특별히 다른 경로를 쓰고 싶을 때만 지정. 비우면 `${SITE_BASE_URL}/manifest.json`. | | `MUSIC_CONCURRENCY` | (자동) | 리소스팩 설치기 yt-dlp 동시 다운로드 수(1~8). | `.env` 는 `.gitignore` 로 제외되어 있습니다. 새 환경을 셋업할 때 `.env.example` 을 복사해서 시작하세요. 쉘에서 직접 환경변수를 지정한 경우에는 `.env` 값을 덮어쓰지 않습니다. ## 도메인 / 경로 구성 | 경로 | 내용 | | --- | --- | | `/` | 음악퀴즈 카드 한 줄 목록(공개). 카드 클릭 시 해당 음악퀴즈 페이지. | | `/manifest.json` | 사이트 루트 매니페스트(공개). 설치기가 첫 화면에서 로드. | | `/file/...` | 정적 파일 호스팅. `servers/`, `maps/`, `mods/<폴더>/`, `resourcepacks/`, `platforms/`, `list/`. | | `/op` | 관리자 로그인. 미들웨어로 `/op/*` 전체를 보호. | | `/op/dashboard` | 음악퀴즈 카드 목록 + 추가/삭제 + 편집 진입. | | `/op/dashboard/:packKey` | 음악퀴즈 정의(JSON) 편집기. | | `/op/list` | 카드 목록(음악·사진 편집 진입). | | `/op/list/:packKey` | 음악퀴즈의 음악·사진 목록 편집(드래그/우클릭). | | `/op/datapack` | 데이터팩 mcfunction 출력. | | `/op/datapack/:packKey/generate` | 텍스트 한 덩어리로 mcfunction 반환. | ## 계정 `account.json` 에 정의합니다(루트 디렉터리). **외부 HTTP 로 절대 노출되지 않도록 라우팅에서 제외돼 있습니다.** ```json [ { "id": "admin", "password": "비번" } ] ``` > 운영 환경에서는 평문 비밀번호 대신 해시를 쓰도록 추후 보강할 여지가 있습니다. ## 대시보드 (`/op/dashboard`) - 상단 메뉴: 좌측 로고 = 대시보드로 이동, 우측 아이디 드롭다운에 **로그아웃**. - 상단 버튼: `[음악목록 수정]` → `/op/list`, `[데이터팩 수정]` → `/op/datapack`. - 카드 목록: `manifest.json` 의 음악퀴즈를 가로 한 줄 카드로 표시. - **음악퀴즈 추가** — `/manifest/new.json` 생성. 이미 있으면 `new2.json`, `new3.json` … 으로 증가. 동시에 `manifest.json` 갱신. - **음악퀴즈 삭제** — 카드에 체크박스가 뜨고, 확인 시 선택한 JSON 과 매니페스트 항목을 삭제. ## 음악퀴즈 정의 편집 (`/op/dashboard/:packKey`) 폼 필드: | 필드 | 설명 | | --- | --- | | 음악퀴즈 이름 | 사용자에게 보이는 표시명. | | JSON 파일 이름 | URL 키. 영문/숫자/`_`/`-` 만 허용. 변경 시 파일명 + 매니페스트가 동시에 갱신되며 URL 도 새 키로 리다이렉트. | | 마인크래프트 버전 | Mojang 공식 API 에서 정식 릴리즈만 드롭다운으로 표시. | | 모드 플랫폼 | `vanilla` / `forge` / `fabric` / `neoforge`. | | 플랫폼 설치파일 URL | `forge` / `neoforge` 용. 도메인 없이 입력하면 `/file/platforms/<파일명>` 으로 해석. | | Fabric Loader 버전 | `fabric` 선택 시 자동 표시. Fabric Meta API 에서 선택한 mcVersion 의 로더 목록을 가져옴. 설치기는 최신 fabric-installer 로 CLI 자동 설치. | | 서버 최소/최대 램 (MB) | 설치기 RAM 검사 및 `run.bat` 의 `-Xms/-Xmx`. | | 클라이언트 최소/권장 램 (MB) | 사용자 PC 요구치 + 마인크래프트 런처 JVM 인수에 사용. | | 맵 파일 (.zip) | `/file/maps/` 아래 zip 파일명. `.mc_custom/saves/` 로 압축 해제. | | 서버 파일 (.zip) | `/file/servers/` 아래 zip. 멀티 전용. | | 모드 폴더 이름 | `/file/mods/<폴더>/` 아래 모든 `.jar` 자동 다운로드. 빈 값이면 받지 않음. | | 리소스팩 (.zip) | `/file/resourcepacks/` 아래 zip 파일명. | 저장 시 `clientMinRam ≤ clientRecommendedRam` 검증이 들어갑니다. ## 음악·사진 목록 편집 (`/op/list/:packKey`) 상단 탭: **음악목록** / **사진목록**. ### 음악목록 탭 - `[목록 저장]`, `[목록 초기화]`. - 플레이리스트 주소 + `[플레이리스트 불러오기]`. 확인 팝업에서 동의해야 기존 순서를 덮어씀. - 항목 표시: 좌측 번호 배지, 썸네일, 제목 / 가수 / 길이. - 드래그로 순서 변경. 우클릭: **수정** / **삭제**. - **수정** → 새 유튜브 주소를 입력하면 yt-dlp 가 메타데이터를 가져와 자동 채움. ### 사진목록 탭 - `[목록 저장]`, `[목록 초기화]`, 플레이리스트 불러오기는 동일. - 카드 그리드(반응형) 로 표시. 우클릭에서 수정/삭제. 수정 팝업은 [유튜브 주소] / [이미지 주소] 토글. 저장 포맷은 `/file/list/.json` (README 데이터 포맷 참고). > yt-dlp 메타데이터/플레이리스트 조회를 위해 서버에 yt-dlp 가 설치되어 있어야 합니다. ([`yt-dlp-setup.md`](yt-dlp-setup.md)) ## 데이터팩 (`/op/datapack`) - `[음악퀴즈 선택]` → 팝업에서 음악퀴즈 선택. - "총 N개의 음악을 찾았습니다." 와 `[데이터팩 출력]` 버튼. - 출력 클릭 시 코드 영역에 mcfunction(임시 포맷) + 복사 버튼. 실제 포맷은 추후 확정. ``` # === musicquiz: === # 총 N곡 / 사진 M장 say [musicquiz] 데이터팩 초기화 # 곡별 placeholder. 실제 포맷 확정되면 교체 예정. # 1. - <artist> (<duration>s) ``` ## 파일 업로드 / 정리 운영 | 카테고리 | 위치 | 비고 | | --- | --- | --- | | 서버 zip | `file/servers/<이름>.zip` | EULA / `run.bat` 포함 권장. 설치기가 `run.bat` 에 UPnP/JVM 후처리 자동 주입. | | 맵 zip | `file/maps/<이름>.zip` | 압축 해제 시 `.mc_custom/saves/` 아래에 풀림. | | 모드 jar | `file/mods/<폴더>/...jar` | 해당 폴더의 `index.json` 이 자동 생성됩니다. 신규 jar 를 넣은 뒤에는 사이트가 인덱스를 다시 만들도록 한 번 호출. | | 리소스팩 zip | `file/resourcepacks/<이름>.zip` | — | | 플랫폼 설치 jar | `file/platforms/<이름>.jar` | forge/neoforge 용. fabric 은 사이트에 둘 필요 없음(자동 다운로드). | ## 보안 주의 - `account.json` 은 라우팅에서 차단되어 있으나, 디스크 권한도 운영자만 접근 가능하게 두는 것이 안전합니다. - 관리자 비밀번호는 충분히 강하게 설정. - 모든 `/op/*` 라우트는 세션 기반 인증 미들웨어를 거칩니다. 세션 만료 시 자동으로 로그인 페이지로 리다이렉트.