Henry_Du
a6d9b6c418
fix(server): 修复 serve-static 不接受数组 root、改为按请求逐个挂载,避免启动时 TypeError: root path must be a string
...
上一轮把 getBeepAudioDirs() 这个数组直接塞进 express.static(),
但 serve-static 签名要求 root 必须是字符串,会在 app 启动注册
中间件时直接抛错(甚至在接收请求前)。
修复方式:
- /media/audio/general 和 /media/audio/beep 改为动态中间件:
请求进来时再依次对每个目录调用一次 express.static(root, {fallthrough})
- 单目录的 music/voice/line/station/temp 保留 express.static
但统一包一层 String(xxx || '') 保证就算路径解析异常也是空
字符串而不是 undefined
- 后备的 7 条 app.get(':path(*)') 路由不变,仍然负责 sendBinaryFile /
sendBinaryFileFromCandidates 兜底(含 range、Content-Length 等头)
客户端 bump v1.0.102 -> v1.0.103
2026-08-17 15:44:38 +08:00
Henry_Du
5c462a4d09
fix(server): 改用 Express 5 + path-to-regexp v7 兼容的通配写法,避免路由启动崩溃
...
Express 5 内置的 path-to-regexp v7 不再支持裸 '*',也不支持
自定义正则 '.*'(会报 Missing parameter name)。Express 5
官方兼容的单段全通写是 ':name(*)',并且路由注册会在 app 启动
第一时间完成(出错会直接崩)。
同时为了兼容旧 URL 行为,保留 express.static 前置挂载 +
显式 app.get 后备两条路径,因为 Audio 模块可能需要带
Cache-Control / Range / Content-Type 等头的 custom sendBinaryFile
处理(例如 station 动态裁剪音频),所以不能直接用 static 替代。
修复 7 条路由:
/media/audio/general/:path(*)
/media/audio/beep/:path(*)
/media/audio/music/:path(*)
/media/audio/voice/:path(*)
/media/audio/line/:path(*)
/media/audio/station/:path(*)
/media/temp/:path(*)
参数解码加 decodeURIComponent(),兼容中文/空格文件名。
客户端 bump v1.0.101 -> v1.0.102
2026-08-17 15:41:36 +08:00
Henry_Du
fc66e43379
fix: 修复新版 path-to-regexp 不兼容 '*' 通配符导致启动崩溃
...
新版 express/router 依赖的 path-to-regexp 不再接受裸 '*' 路径语法,
改为命名通配参数 :relPath(.*),并同步把 req.params[0] 改为
req.params.relPath。涉及 7 条 /media/* 静态路由:
- /media/audio/general/*
- /media/audio/beep/*
- /media/audio/music/*
- /media/audio/voice/*
- /media/audio/line/*
- /media/audio/station/*
- /media/temp/*
客户端版本号 bump v1.0.100 -> v1.0.101
2026-08-17 15:38:41 +08:00
Henry_Du
6ac05d3a84
feat(server): 实施 A1 方案 - 多连接存储、站台分组 Master 选举、audioCableGroup 互斥令牌机制
...
- stations 存储改造:stations[name] = { name, code, platform, audioCableGroup, version, lastSeen, nodes: [] } 结构,每个 node 含 ws/hasStationPeripheral/stationPeripheralSide/hasBlockReader/hasCreateTarget/identityMode/nodeId/wsId/connectedAt
- 新增 audioCableGroups:{ id, name, color, description, stationNames: [] } 分组,及 audioCableTokens 互斥令牌 Map(cableGroupId -> { holderStationName, holderAudioId, holderPriority, acquiredAt, cancelToken })
- 新增核心函数:upsertStationNode(按 wsId 去重更新 node、聚合计时表级 schedule)、removeStationWs(WS 关闭时清理 node + 释放令牌 + 下发 group_state)、getStationMaster(hasStationPeripheral=1000加权 + lastSeen小数加权 两轮选举 OPEN ws)、getAllStationConnections、getGroupKeyForStation(纯 stationName 分组,不再 code@@platform)、acquireCableToken(无持者直给/同 holder 更新/高优先级 audio_preempt + 200ms 延迟抢占/低优先级拒绝+denied 消息)、releaseCableToken
- 发送策略改造:sendAudioControl 遍历组内所有节点 ws 全发(同名站同步 stop 等指令);sendAudioBufferToStation/sendLiveWavChunksToStation 只发送 master ws,发送前后 acquire/release token,durationSec 后 setTimeout 延迟释放,audio_start 消息新增 cableGroupId 字段
- enqueueStationAudioQueue 增加 cableGrp 兜底释放;loadData 兼容旧 stations 单值结构导入 nodes=[] 数组新结构 + audioCableGroups 双向回填;saveData 剥离 nodes 中 ws 对象后保存,新增 audioCableGroups 字段持久化
- WS 层改造:wss close 事件调用 removeStationWs;console_connect init_state 增加 audioCableGroups 数组;handleStationRegister/handleHeartbeat/handleScheduleSync 改为调用 upsertStationNode;station_register_ack 返回 nodeId/audioCableGroup
- broadcastUpdate state_update 增加 audioCableGroups 字段;新增 WS 下行 audio_preempt / cable_token_granted / cable_token_denied / station_group_state 四种消息类型
- getStationGroups 完全重写:按 stationName 精确分组,返回 members/nodes 数组(每个 node 带 nodeId/wsId/online/isMaster/connectedAt/lastSeen/hasStationPeripheral/hasBlockReader/hasCreateTarget/identityMode/tickRate/memberTags),增加 masterNodeId、audioCableGroup{id,name,color}、cableGroupId 字段;resolveStationGroup memberNames 返回 nodeId 列表
- REST API 新增 9 个路由:GET/POST/PUT/DELETE /api/audio-cable-groups,POST /api/audio-cable-groups/:id/stations(批量加站台,含 prev cableGroup 自动清理)、DELETE /api/audio-cable-groups/:id/stations/:stationName、PUT /api/stations/:name/cable-group(stations.audioCableGroup 与 group.stationNames 双向同步),stations DELETE 自动同步 cable group 清理
- 兼容性:旧 stations[name].ws 统一改为 getStationMaster(name).ws;TTS、HLS、temp-broadcast、音乐播放、version 管理等功能不受破坏;Lua 客户端版本号提升至 v1.0.99
2026-08-17 15:15:23 +08:00
Henry_Du
55f0312314
feat(audio): 支持斜杠格式的车站编号和模糊搜索匹配
...
- 修改TTS音频导入逻辑,保留编号中的斜杠(/)格式(如 CH-01/CE-12),自动创建子目录
- 移除generator.html中单文件和批量导入时的斜杠转横杠逻辑
- 新增sanitizeStationCode和ensureDirForFile辅助函数,确保路径安全
- 重写findFileCaseInsensitive,支持递归子目录搜索与末尾段模糊匹配
- 新增listAllFilesRecursive和resolveAudioPathWithFuzzy工具函数
- 修改getPlaybackAudioByBaseName/findWavByBaseName支持模糊搜索查找
- 修改resolveManagedPath允许子路径访问,getManagedFiles递归扫描子目录
- 媒体路由从:file参数改为通配符/*形式,safeRelativeToBase确保路径安全
- 升级版本号至v1.0.98
2026-08-17 14:54:21 +08:00
Henry_Du
ae213a84a1
feat: 从机站台吸附识别与时刻表自动同步 v1.0.73
...
- Lua端: 新增定期外设重扫描(PERIPHERAL_SCAN_INTERVAL=15s),支持热插拔站台方块
- Lua端: 新增定期身份同步,站台外设热插/热拔时自动刷新身份并重新register
- Lua端: 新增独立的schedule sync coroutine与station_schedule_sync消息类型(SCHEDULE_SYNC_INTERVAL=10s)
- Lua端: 扩展heartbeat携带hasStationPeripheral/stationPeripheralSide/hasBlockReader/hasCreateTarget/identityMode/upcomingTrains/currentTrain等字段
- 从机若吸附有站台方块(train_station外设),则自动进入主机逻辑: 识别到发、停靠列车检测,数据通过WS推送到服务器
- server端: 新增assignDeviceFields工具函数统一写入设备字段与时刻表
- server端: 新增handleScheduleSync处理station_schedule_sync消息,数据写入stations[name]并broadcast
- server端: 扩展handleHeartbeat与handleStationRegister,均调用assignDeviceFields存储设备状态和时刻表摘要
- server端: 扩展getStationGroups分组视图,新增hostCount/slaveCount/hasAnyStationPeripheral/upcomingTrains/currentTrain/members详细信息
- 时刻表合并: 同一站台组多节点的upcomingTrains按trainName@@dest@@platform去重合并; currentTrain优先主机数据
- 版本升级: v1.0.72 -> v1.0.73
2026-08-16 13:33:10 +08:00
Henry_Du
ae96c86288
feat: departure广播新增下一站播报 + 客户端预解析station code
2026-08-16 13:01:32 +08:00
Henry_Du
32b2c8ce9d
fix: 终点站到达时下一站广播播放异常 + getNextStation 不回绕起点
...
1. Utils.getNextStation: 移除终点站回绕到起点的逻辑(非环线)
- 此前当前站是 END 时会从 schedule.entries 开头再找,把起点当下一站
- 修复后在终点站返回 nil,明确表示无后续站
2. 服务端 handleTrainArrival: 智能区分普通站/终点站广播序列
- 新增 hasNextStation / finalNextCode 判断:只有当下一站有效时
才在 seq 中插入 ch-nextsta + ch- 片段
- 终点站(finalNextCode 为 null):直接删除 nextsta 和下一站代码,
仅保留 站台-站台-线路-方向-终点站-警示 片段
- 避免 ch-UNK 等无效资源或回绕起点站名被播放
3. 日志增强:arrival 处理时额外打印 nextStation 和 nextCode,
便于快速确认服务端是否收到正确的下一站信息
版本号 v1.0.69 -> v1.0.70
2026-08-16 12:41:19 +08:00
Henry_Du
34d9ed00d6
fix: 解决自动更新无限重启循环 + 终点站列车不显示在预测列表
...
1. CloudServer: publishStationUpdate 发布时同步 Gitea 最新脚本到本地副本
- 新增 fetchGiteaScript() 一次下载全文
- 发布更新时将 Gitea 脚本内容写入 stationScriptPath
- 保证 targetVersion 与 /downloads/station_broadcast.lua 内容版本一致
2. 客户端 AutoUpdate.apply: 下载后校验版本一致性
- 从下载内容正则提取 APP_VERSION_TEXT
- 若 downloadedVersion ~= targetVersion 则中止更新,防止 reboot loop
- 写入错误日志便于排查
3. 预测显示: 在站列车(尤其终点站)强制插入 upcomingTrains 列表头部
- CRN 可能从 TrainStops 提前移除终点站列车
- 使用 normalizeUpcomingKey 去重避免重复条目
- 固定 ETA=0,确保 CURREN T TRAIN 对应列车能在 UPCOMING 中可见
版本号 v1.0.68 -> v1.0.69
2026-08-16 12:32:11 +08:00
Henry_Du
af00d57e68
feat: 发布更新时优先使用远程 Gitea 仓库的版本号
2026-08-16 11:54:29 +08:00
Henry_Du
b74eb252e3
feat: 在后端增加解析远程 Gitea 最新版本号的接口并展示在前端
2026-08-16 11:40:47 +08:00
Henry_Du
d8eee041c8
feat: 明确音频优先级,优化发车音频触发时机
...
- 到达与发车最高优先级(3),其次是进站预告(2),然后是延误警告(1),最低为背景音乐(0)
- 将发车音乐的触发时机从固定时间改为动态计算(音频时长+1.5秒补偿),确保音频结束时列车刚好发车
- 拆分 handleTrainApproaching 与 handleTrainAlert 逻辑,解耦进站与延误的优先级
- 版本号提升至 v1.0.59
2026-08-04 13:00:04 +08:00
Henry_Du
aa10f0ebe1
chore(server): 屏蔽 HLS RTMP 推流失败的错误日志
...
由于当前环境未配置 RTMP 服务器,当 ffmpeg 尝试推送音频流到 127.0.0.1:1935 时会一直报错 `Connection refused` 从而导致控制台刷屏。
现将该错误日志注释屏蔽,使控制台保持清爽。
2026-08-03 12:35:16 +08:00
Henry_Du
a36b21cfaf
fix(server): 完善列车接近音频的处理与日志记录
...
新增列车接近音频入队和构建失败的日志输出
调整音频任务优先级为1,中断模式改为ifLower
修复音频构建为空时的静默失败问题
2026-08-03 10:22:04 +08:00
Henry_Du
101d392840
fix(CloudServer/server): 修复列车接近处理的ch序列遗漏的站台编号参数
2026-08-03 09:59:58 +08:00
Henry_Du
aef63ca444
fix: install updater alongside startup script
...
Download the update helper during install and expose it from the cloud server so new hosts can run manual updates immediately.
2026-08-02 21:20:28 +08:00
Henry_Du
10d15dfddc
feat: add station auto update publishing
...
Publish the latest station script from the console so online hosts download and reboot immediately while offline hosts update on their next load.
2026-08-02 20:04:55 +08:00
Henry_Du
906594008a
fix: remove ch-min from delay announcement
2026-08-02 19:06:20 +08:00
Henry_Du
39dc446958
功能(站点广播): 实现延误与停运列车的双语广播功能
...
添加所有中日文广播所需的音频资源文件
将应用版本更新至v1.0.37
修复列车状态原因映射逻辑,补充广播所需的缺失字段
实现根据延误、停运状态生成对应双语广播序列的逻辑
更新测试脚本以适配区块阅读器并正确解析CRN的NBT数据
添加示例NBT转储文件作为参考
2026-08-02 18:50:49 +08:00
Henry_Du
f922ace154
fix: trigger approaching broadcast under 30 seconds
2026-08-02 17:42:49 +08:00
Henry_Du
712d8bb84d
fix: Ensure platform is stripped of non-digit chars for audio file matching
2026-08-02 11:52:27 +08:00
Henry_Du
ef75671527
feat: Add train pre-arrival broadcast via CRN create_target
2026-08-02 11:37:41 +08:00
Henry_Du
ac8405e300
fix: use pcall to uncapped AUDIO_VOLUME for HQ speakers while keeping 3.0 fallback for vanilla speakers
2026-08-02 08:53:49 +08:00
Henry_Du
832658ad58
feat: apply 5x volume boost to all FFmpeg audio processing (broadcast sequences, HLS, DFPWM) to maximize loudness
2026-08-02 08:50:28 +08:00
Henry_Du
90c108b1d7
Update: remove ja-xl and ch-line from train arrival broadcast sequence
2026-08-01 23:05:39 +08:00
Henry_Du
4b3bd91023
Fix: implement case-insensitive file matching for broadcast audio sequences to fix missing uppercase line and station names
2026-08-01 22:54:10 +08:00
Henry_Du
2fae7305f6
Fix: use filter_complex for sequence concatenation to fix sample rate mismatch causing speed up and noise
2026-08-01 22:46:23 +08:00
Henry_Du
e009f05a61
Fix: use wav-stream-live for train arrivals and departures to fix CC client audio playback
2026-08-01 22:34:29 +08:00
Henry_Du
81f58b58bb
Fix: Lua client config screen overwritten by logs, and fix temp broadcast preview URL
2026-08-01 22:15:59 +08:00
Henry_Du
5c78b20163
Fix: include audioLineDir and audioVoiceDir when building broadcast sequence
2026-08-01 22:09:40 +08:00
Henry_Du
1043d46fb8
Fix: correctly setup line audio directory, routing, and upload handling
2026-08-01 18:41:29 +08:00
Henry_Du
495b3cedb9
Fix: save line audio to voice directory instead of beep
2026-08-01 18:30:59 +08:00
Henry_Du
2741b2d321
Revert TTS generation to backend with fixed local proxy 127.0.0.1:7890
2026-08-01 18:25:50 +08:00
Henry_Du
c76538e4bd
feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions
2026-08-01 17:58:20 +08:00
Henry_Du
a516976e35
Revert "feat: use pure direct connection to official api.fish.audio without any forced proxies"
...
This reverts commit 3ecae7b0bc .
2026-08-01 17:57:00 +08:00
Henry_Du
3ecae7b0bc
feat: use pure direct connection to official api.fish.audio without any forced proxies
2026-08-01 17:55:30 +08:00
Henry_Du
b8aee4d766
fix: revert to server proxy logic and add resilient fallback for win32 to prevent 500 errors
2026-08-01 17:51:08 +08:00
Henry_Du
038662c15e
Revert "feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions"
...
This reverts commit dedb37e22b .
2026-08-01 17:49:57 +08:00
Henry_Du
dedb37e22b
feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions
2026-08-01 17:45:48 +08:00
Henry_Du
1b6a2b7e33
feat: switch Fish Audio API endpoint to user's custom proxy domain (fishaudio.fse-media.group)
2026-08-01 17:42:24 +08:00
Henry_Du
7bfff51919
revert: switch back to direct Fish Audio API due to Vercel IP block
2026-08-01 17:37:52 +08:00
Henry_Du
f4c22cb713
feat: switch Fish Audio API endpoint to Vercel proxy to resolve ETIMEDOUT issues on server
2026-08-01 17:34:55 +08:00
Henry_Du
52ecdc8a16
Revert "fix: remove hardcoded windows proxy fallback that causes 500 error when proxy is unavailable"
...
This reverts commit 62ecf5642b .
2026-08-01 16:00:00 +08:00
Henry_Du
62ecf5642b
fix: remove hardcoded windows proxy fallback that causes 500 error when proxy is unavailable
2026-08-01 15:57:30 +08:00
Henry_Du
6150050f69
revert: move TTS generation back to server-side due to CORS issues
2026-08-01 12:01:38 +08:00
Henry_Du
6f122c7a2c
feat: add FISH_AUDIO_BASE env support for reverse proxy
2026-08-01 11:59:15 +08:00
Henry_Du
e3a88acf9b
Revert "feat: migrate TTS generation to frontend to utilize local browser proxy"
...
This reverts commit 5e600bb75d .
2026-08-01 11:58:20 +08:00
Henry_Du
5e600bb75d
feat: migrate TTS generation to frontend to utilize local browser proxy
2026-08-01 11:55:31 +08:00
Henry_Du
1d0c0e0703
fix: fallback to 127.0.0.1:7890 proxy on windows for local TTS generation
2026-08-01 11:50:18 +08:00
Henry_Du
c0f100a833
fix(console): map Beep files to Audio/beep
...
Store and present Beep assets under Audio/beep while keeping legacy Audio/general reads working so existing files remain accessible during the directory transition.
2026-08-01 11:42:38 +08:00