feat: 新增物理弹球实验室及配套功能

1. 新增物理弹球游戏全套代码,包含物理引擎、规则、渲染、游戏逻辑、存档、音效、UI
2. 新增物理弹球相关调试与单元测试脚本
3. 优化私有剪贴上传功能:增加200MB上传限制与错误提示
4. 修复复古弹球桌的光滑面防粘附与休眠逻辑
This commit is contained in:
yangxiangyuan
2026-08-08 22:31:33 +08:00
parent 4492b4106a
commit 91148fe064
17 changed files with 2690 additions and 22 deletions
+15
View File
@@ -221,6 +221,7 @@ const groupItemsFromRows = (rows) => {
const AUTH_COOKIE = 'private_clipboard_auth'
const AUTH_MAX_AGE_MS = 24 * 3600 * 1000 // 1天
const AUTH_HMAC_SECRET = process.env.PRIVATE_CLIPBOARD_AUTH_SECRET || 'pc-auth-secret-change-me'
const UPLOAD_LIMIT_MB = 200
const signAuthPayload = (username) => {
const payload = { sub: username, iat: Date.now() }
@@ -660,6 +661,20 @@ const createRouter = () => {
}
})
router.use((err, req, res, next) => {
if (!err) return next()
if (req && req.path === '/upload') {
if (err.type === 'entity.too.large') {
return res.status(413).json({ ok: false, error: 'file_too_large', limit_mb: UPLOAD_LIMIT_MB })
}
if (err.type === 'request.aborted') {
return res.status(400).json({ ok: false, error: 'upload_aborted' })
}
return res.status(500).json({ ok: false, error: 'upload_failed' })
}
return next(err)
})
router.delete('/:id', (req, res) => {
try {
const id = parseInt(req.params.id, 10)
@@ -0,0 +1,15 @@
{
"_comment": "思想实验室 · 物理弹球(Web 复刻版):竖向场地 + 顶部漏斗待发球 + 拖拽瞄准连发弹球 + 数字砖块刚体堆叠 + 侧边输送带回收 + 回合上升机制。学术研究用途,玩法复刻自同名手游。多文件前端:pb_physics(刚体引擎)/pb_rules(规则)/pb_render(渲染)/pb_game(状态机)/pb_ui(界面)/pb_storage(存档)/pb_audio(音效)。本 lab 完全独立;未来若需要后台逻辑,统一放在本文件夹内。",
"id_comment": "lab 唯一标识(snake_case),与文件夹名保持一致",
"id": "physics_balls",
"name_comment": "首页卡片显示名称",
"name": "物理弹球",
"icon_comment": "首页卡片图标(emoji)",
"icon": "🎾",
"desc_comment": "一句话简介,作为卡片 tooltip 展示",
"desc": "打砖块式弹球 · 刚体物理 · 拖拽瞄准连发 · 回合上升",
"sort_order_comment": "卡片排序,数值越小越靠前",
"sort_order": 97,
"enabled_comment": "是否启用(false 时列表接口不返回该 lab)",
"enabled": true
}