Previous version only deleted platform-cache at the very end of the
success path. If anything between platform install and launcher
profile update failed, the cache jar stuck around. Move the rm into
a finally block so the directory is always cleaned up.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- yt-dlp.exe, ffmpeg.exe now live in %appdata%/.mc_custom/installer/ so
the .mc_custom root stays a clean Minecraft game folder. Existing
binaries at the old location are migrated on first run.
- After a successful install, the platform-cache (downloaded fabric /
forge / neoforge installer jars) is deleted — it's regenerable and
was just wasting disk space.
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>
The rp installer's `index.html` references `../installer/styles.css`,
which works in dev because both source directories sit side by side.
The packaged exe's `files` list only included `installer-rp/**`, so
inside the asar the stylesheet path resolved to nothing and the UI
rendered completely unstyled (per user screenshot).
Add the single shared file `installer/styles.css` to the rp build's
file list. The cross-directory `<link>` reference now resolves inside
the asar, and we avoid duplicating the stylesheet.
Bump to 0.1.1 — small patch-level fix.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The packaged installer-rp crashed on launch with
"Could not load the 'sharp' module using the win32-x64 runtime" because
electron-builder ran on Linux and only the Linux sharp variants were
present in node_modules.
- Add `preinstall:sharp-win32` script that force-installs
`@img/sharp-win32-x64@0.34.5` into the local node_modules (npm refuses
it on Linux without --force due to its os/cpu restrictions).
- Chain that script before both `dist:win` and `dist:win:rp` so future
Windows builds always have the native prebuilt available.
- Exclude `@img/sharp-{,libvips-}linux*` from the packaged files list in
both electron-builder configs so the unused Linux variants don't bloat
the portable exe.
Verified `release/win-unpacked/resources/app.asar.unpacked/node_modules/
@img/sharp-win32-x64/lib/sharp-win32-x64.node` is present and that no
linux sharp variants ship inside the asar.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Reviewer follow-ups:
1) Preserve mods/ for vanilla packs. `downloadModsFolder` now checks
`!pack.modsFolder` BEFORE wiping — vanilla packs (no modsFolder) no
longer clobber a user's hand-curated mods directory. Wipe still runs
for modded packs to keep different MC versions from colliding.
2) Always rename the extracted map to `saves/<퀴즈이름>/`, regardless of
the zip's top-level layout. The zip is now extracted into a temp
directory under saves/, and:
- if the temp has a single subdirectory, that subdirectory's content
becomes the world;
- otherwise the temp dir itself (e.g. level.dat + region/ at root) is
the world.
In either case, it is renamed atomically to `saves/<sanitized name>`
(or `<name>_2` etc. if a user world collides). Marker tracks the
final folder name for participant cleanup.
User request: replace both .exe icons.
- Added build/icon.ico (multi-size 16/32/48/64/128/256) and build/icon.png
generated from the new music-note artwork.
- electron-builder.yml: set win.icon, nsis installer/uninstaller icons,
buildResources=build, include build/icon.* in files for runtime use.
- New electron-builder-rp.yml + dist:win:rp script so the resourcepack
installer also packages with the same icon.
- BrowserWindow({ icon }) wired in both installer and installer-rp main
processes so the running window's titlebar/taskbar icon matches.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- dotenv 도입, src/shared/env.ts 추가
- loadEnv() 가 프로젝트 루트 .env 를 로드 (override=false: 쉘 env 우선)
- getSiteBaseUrl() / getManifestUrl() 헬퍼
- 서버/설치기/리소스팩설치기 진입점에서 loadEnv() 호출
- 설치기 두 종의 기본 MANIFEST_URL 을 SITE_BASE_URL 기반으로 변경
(운영 도메인을 한 곳에서만 바꾸면 됨)
- .env.example 템플릿 + .gitignore 에 .env 추가
- README / docs/admin-site.md 에 환경변수 표·사용법 추가
- installer/renderer.js: 4단계 완료 후 자동 종료 다시 활성화
Add archiver dep (v7 — v8 dropped the function-style default export
that the @types still describe) and a new src/installer-rp/pack.ts
that assembles the resource pack tree under tempDir/resourcepack/
and zips it to %appdata%/.minecraft/resourcepacks/<key>_musicquiz.zip.
The tree matches Minecraft 1.21+ painting variant + custom sound
conventions:
pack.mcmeta pack_format 34,
supported 34..75
assets/musicquiz/sounds.json stream:true per track
assets/musicquiz/sounds/track_NN.ogg from tempDir/music
assets/musicquiz/textures/painting/cover_NN.png from tempDir/painting
Music NN.ogg is renamed to track_NN.ogg at copy time so the sound
event ids stay readable. The painting_variant JSON definitions are
intentionally NOT generated here — those live in the data pack and
are owned by /op/datapack on the website.
Wire step 2-4 of the install IPC to call buildResourcepackZip with
the now-populated music/painting temp dirs. Step 2-5 is now just a
log line since buildResourcepackZip writes directly to the final
path.
Verified by a node smoke test: tempDir of two stub ogg files plus
two 256x256 PNGs produces a valid zip with the expected entries
and UTF-8 Korean strings in pack.mcmeta description.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add sharp dep (libvips bindings) — fastest option for the per-image
center-crop + Lanczos resize step. Pure-JS alternatives (jimp) and
spawning ffmpeg per image were both ~5-10x slower in this hot loop.
Add src/installer-rp/images.ts:
- ytIdFromUrl: extracts the video ID from watch?v=, youtu.be/, and
/shorts|embed/ URL forms
- downloadImage: for YouTube URLs tries i.ytimg.com/vi/<id>/
maxresdefault.jpg first, falls back to hqdefault.jpg; plain image
URLs go through a generic HTTP/HTTPS GET that follows 302s
- normalizeToCover: center-crop to min(w,h), Lanczos resize down to
1024x1024 when larger, never upscales, writes PNG
- coverFileName: returns cover_NN.png with zero-padded NN
Wire step 2-3 of the install handler to download + normalize each
image into <tempDir>/painting/cover_NN.png. Zip build (step 2-4)
will pick those up next.
Verified with synthetic 1200x800 and 2000x1500 buffers: small
input stays 800x800 (no upscale), large input becomes 1024x1024.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a second Electron entry under src/installer-rp/ + installer-rp/
launched by `npm run installer:rp`. It is structurally separate from
the music quiz installer (own tsconfig, own preload, own renderer),
shares the existing styles via a relative link, and exposes a
three-step UI: pick a 음악퀴즈, run the install, then a 완료 page that
can open the resourcepacks folder or quit.
The install IPC handler currently scaffolds the flow per docs/add.md
(yt-dlp prep → music download → image normalize → zip build → place
at %appdata%/.minecraft/resourcepacks/) but the actual work is still
TODO. Cancel/cleanup of %appdata%/.mc_custom/.temp/ is wired up so
that future iterations can plug each step in without rewiring.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>