这是一个基于 Next.js 和 Go 的 Project Sekai 查看器项目。
⚠️ 注意 / Note作者能力有限,本项目仅作为个人练习与探索。代码中可能存在大量非最佳实践,敬请包涵。 The author has limited capabilities; this project is for personal practice and exploration. Please be aware that the code may contain non-optimal practices.
本项目参考了 Sekai Viewer 的设计与实现。 Sekai Viewer 采用 GPLv3 开源协议。
This project is inspired by and references Sekai Viewer. Sekai Viewer is licensed under GPLv3.
sekai-calculator 项目提供的组卡算法支持 sekai-calculator 采用 LGPL-2.1 开源协议。
项目算法也参考了Luna茶的相关组卡代码实现sekai-deck-recommend-cpp
表情包制作器参考了Parallel-SEKAI的PJSK-Sticker仓库 以及 TheOriginalAyaka的sekai-stickers仓库 PJSK-Sticker sekai-stickers
歌词页面中的外部歌唱者头像均为小尺寸头像裁切图,版权归各自权利人所有。官方来源与署名集中记录如下:
- GUMI — © Internet Co., Ltd. — 官方页面
- Kasane Teto / 重音テト —
重音テト © 線 / 小山乃舞世 / TWINDRILL— 官方插画 · 角色指南 - flower — © Gynoid — 官方素材页
- Nenerobo — 暂无已确认的独立官方头像素材,当前保留文字回退头像
- Kamui Gakupo — © Internet Co., Ltd. / 三浦建太郎 — 官方角色页
- KAFU — © Musical Isotope — 官方条款
- Gekiyaku — © KAMITSUBAKI STUDIO / Musical Isotope — 官方条款
- SEKAI — © Musical Isotope — 官方条款
- Zundamon / ずんだもん — © 東北ずん子・ずんだもんプロジェクト — 官方指南
- Kaai Yuki — © AH-Software Co. Ltd. — 官方角色页
- Adachi Rei — © m1namo — 官方页面
- RIME — © KAMITSUBAKI STUDIO / Musical Isotope — 官方条款
- Hanakuma Chifuyu — © TOKYO6 ENTERTAINMENT — 官方页面
- VY1 — © Yamaha Corporation — 官方指南
- SOLARIA — © Eclipsed Sounds — 官方页面
- Kotonoha Aoi / 琴葉葵 — © AHS Co. Ltd. — 官方页面
- Kotonoha Akane / 琴葉茜 — © AHS Co. Ltd. — 官方页面
以上已列出的身份均已使用对应公开素材裁切为歌词页头像;Nenerobo 因暂未找到可确认的独立官方头像素材,仍保留文字回退。
头像只做裁切、缩放和页面显示用途,不代表本项目拥有上述角色或素材的版权。
可核对来源见 docs/lyrics-external-avatar-sources.json。
谱面预览器参考了watagashi-uni的sekai-mmw-preview-web 及 mikumikuworld 的相关实现 sekai-mmw-preview-web MikuMikuWorld
本项目包含大量由人工智能(AI)辅助生成的代码。
- 代码可能包含潜在的错误、逻辑漏洞或非最佳实践。
- 使用者请自行承担风险,建议在生产环境部署前进行充分的审查和测试。
- 维护者不对因使用本项目代码而导致的任何问题负责。
This project contains a significant amount of code generated with the assistance of Artificial Intelligence (AI).
- The code may contain potential errors, logical flaws, or non-best practices.
- Users should use it at their own risk and are advised to conduct thorough review and testing before deploying in a production environment.
- The maintainers are not responsible for any issues arising from the use of this project's code.
本项目的开源协议遵循所参考项目的要求(如适用),当前采用 AGPL-3.0。 AGPL-3.0
- PORT: 后端监听端口(默认
8080) - REDIS_URL: Redis 地址(默认
localhost:6379) - MASTER_DATA_PATH: 可选本地 masterdata 缓存路径(默认
./data/master)。仓库不再提交完整 masterdata;本地文件缺失时 Go API 会从远端数据源加载。 - STATIC_ARCHIVE_DIR: Next.js 静态文件归档持久化目录(默认
./data/static_archive)。在全量 Docker 容器部署时,启动脚本会自动将新构建的.next/static产物增量归档保存至该目录,防止新版本部署导致未刷新的在线客户端加载旧 Chunk JS 出现 404 错误。 - STATIC_CACHE_MAX_DAYS: 静态归档产物保留天数(默认
30);设为0禁用过期清理,其他值必须是非负整数。 - HTML_CACHE_DIR: HTML 响应缓存目录;留空时回落到默认目录(容器内
/app/data/html_cache,否则./data/html_cache)。没有关闭磁盘 HTML 缓存的开关。 - MOESEKAI_API_URL: moesekai-api(登录与猜歌曲)的内网地址,例如
http://moesekai-api.zeabur.internal:8080。设置后/api/auth/与/api/guess-music/由 Go 后端同源转发:Cookie、Set-Cookie 与跳转地址原样透传,响应边收边发,X-Forwarded-For末尾追加上一跳地址,CF-Connecting-IP保持不变;上游不可达时返回 502{"error":"upstream_unavailable"}。未设置时这两组路径返回 503{"error":"unavailable"}。 - NEXTJS_PORT: 全量镜像内部 Next.js 监听端口(默认
3000),必须与外部 GoPORT不同。
- NEXT_PUBLIC_API_URL: 关联活动/卡池等 API 的后端基准地址;使用当前 standalone + 内置反向代理部署时通常无需配置,前后端分离部署时可设为例如
https://api.pjsk.moe。登录(/api/auth/)与猜歌曲(/api/guess-music/)的请求不受这个变量影响,始终发往页面自身的域名:登录会话 Cookie 只属于页面域名,发往api.pjsk.moe的请求带不上它。所以分离部署时,页面域名也要把这两组路径转给 Go 后端(Next 内置的/api/*转发会发往INTERNAL_API_BASE_URL),再由设置了MOESEKAI_API_URL的 Go 后端转发到 moesekai-api。 - NEXT_PUBLIC_MOLY_RESOURCE_BASE: 烤森对话资源目录的可选覆盖;不设置或留空时使用源码中的默认目录
https://assets.pjsk.moe/sekai-extra-assets/,常规 Docker / Zeabur 自动部署无需配置此变量。覆盖值包含 bucket 路径并以/结尾,例如https://assets.example.com/bucket/;只接受不含凭据、query 或 fragment 的 HTTPS 目录。Next.js 在构建时写入客户端代码:需要覆盖时,Docker 用--build-arg NEXT_PUBLIC_MOLY_RESOURCE_BASE="$NEXT_PUBLIC_MOLY_RESOURCE_BASE",直接 Next 构建在构建前设置,开发 compose 从根目录.env透传。运行已有生产镜像时设置docker run -e不会改变它。站内/moly/<路径>由 Next 代理到<资源目录><路径>,不需要 CDN 路径映射;manifest、SDK、iframe shell 和 cache worker 继续同源。完整部署要求见 Moly 接入文档。 - NEXT_PUBLIC_LYRICS_BASE_URL: 可选覆盖。未设置时,页面、sitemap 与生产镜像都使用编码里的已发布歌词目录
https://translation.exmeaning.com/files/translation/lyrics(与DockerfileARG 默认值相同)。生产运行与构建只接受不含凭据、query 或 fragment 的 HTTPS URL;开发环境还允许显式配置本机回环 HTTP URL。页面与 sitemap 都从该目录读取同一份index.json,避免发布视图分叉。显式配置无效时会直接失败,不会改去其他源。CI 和明确隔离的非生产环境可通过--build-arg NEXT_PUBLIC_LYRICS_BASE_URL="$NEXT_PUBLIC_LYRICS_BASE_URL"覆盖,docker-compose.dev.yml继续只透传开发变量。Required PR CI 使用仅在 job 生命周期内存在的一首 strict Public Lyrics v3 Full-only synthetic HTTPS index/detail fixture 验证生产 Docker/Next build contract,临时 CA 通过 BuildKit secret 只挂载到构建步骤且不会进入镜像;这不证明真实生产源可达。不要把令牌或个人配置提交到仓库。 - NEXT_PUBLIC_TRANSLATION_ORIGIN: 可选覆盖翻译文件来源,只填 origin(例如本地开发时的
http://localhost:8081),不带/files/...。未设置时使用https://translation.exmeaning.com。影响全部翻译文件(启动时加载的分类译文、活动剧情、卡牌剧情cardStory/card_<cardId>.json、区域对话areaTalk/group_<floor(JP actionSet id / 100)>.json、卡池简介与说明gachaInfo.json);卡牌剧情与区域对话的译文按日文原文匹配,只在服务器为 JP、界面语言为 zh-CN 或 en-US 且开启翻译时请求,文件不存在时页面保持原文;启动集合缓存在 IndexedDB,切换来源后需要清除站点数据才能看到新来源的内容。
全量部署镜像内置 Go 服务与 Next.js standalone 服务。建议使用挂载到 /app/data 的命名卷,使 masterdata、HTML 缓存和旧版静态 Chunk 归档可以跨容器更新保留:
docker build \
-t pjsk-viewer -f Dockerfile .
docker volume create pjsk-viewer-data
docker run -d \
-p 8080:8080 \
--name pjsk-viewer \
--restart unless-stopped \
-e PORT=8080 \
-v pjsk-viewer-data:/app/data \
pjsk-viewer容器以非 root 用户运行;若改用宿主机 bind mount,宿主目录必须允许容器 UID/GID 1000 写入。生产 HTTPS 应在可信反向代理或负载均衡器终止,只向外暴露 Go 的 8080 端口,不应暴露内部 Next.js 端口。
/healthz检查 Go 入口及内部 Next.js 服务是否可用。/readyz仅在首份完整 masterdata 加载完成后返回成功;依赖业务 API 的流量应使用此端点作为就绪探针。/internal-healthz/是容器内部 Next.js 专用端点,不应作为公网部署探针。
当前端部署在 Pages 等独立平台时,可以使用 Dockerfile.backend 构建纯 Go API 服务。Dockerfile 不使用 .go 后缀,避免 Go 工具链将其误判为源码。
docker build -t pjsk-go-backend -f Dockerfile.backend .
docker run -d \
-p 8080:8080 \
--name pjsk-backend \
-e PORT=8080 \
-e REDIS_URL=localhost:6379 \
-v "$(pwd)/data:/app/data" \
pjsk-go-backend